wl12xx: Initial contribution for mac80211 based wl12xx solution

Initial contribution (suplicant lib and conf files)

Change-Id: I019a88d27abdb8ad79c4b755a079158c32fe009b
Signed-off-by: Vishal Mahaveer <vishalm@ti.com>
diff --git a/mac80211/Android.mk b/mac80211/Android.mk
new file mode 100644
index 0000000..4ddcd2b
--- /dev/null
+++ b/mac80211/Android.mk
@@ -0,0 +1,3 @@
+ifeq ($(BOARD_WLAN_DEVICE),wl12xx_mac80211)
+    include $(call all-subdir-makefiles)
+endif
diff --git a/mac80211/config/Android.mk b/mac80211/config/Android.mk
new file mode 100644
index 0000000..6a5a62b
--- /dev/null
+++ b/mac80211/config/Android.mk
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+########################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := wpa_supplicant.conf
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/wifi
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+########################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := hostapd.conf
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/wifi
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+
+########################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := dhcpcd.conf
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/dhcpcd
+LOCAL_SRC_FILES := android_dhcpcd.conf
+include $(BUILD_PREBUILT)
+
+########################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := TQS_D_1.7.ini
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/wifi
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+########################
diff --git a/mac80211/config/TQS_D_1.7.ini b/mac80211/config/TQS_D_1.7.ini
new file mode 100644
index 0000000..4a1a769
--- /dev/null
+++ b/mac80211/config/TQS_D_1.7.ini
@@ -0,0 +1,85 @@
+# INI Generator version 0.5; Aligned to TS version 7.1.2.0.26
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1:   Non FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.1: General parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+TXBiPFEMAutoDetect  = 00 # Length: 1; Unit: Options (0: Manual Mode, 1: Automatic mode); Format: Unsigned; Source: Customer; Comment: This parameter is used by the FW to decide if the front-end is determined automatically or manually
+TXBiPFEMManufacturer  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit1,0: used to determine which FEM vendor type is used on the platform (0: RFMD, 1: TQS, 2:SKW, 3:HP), Bit3,2: unused, Bit7-4:External/internal load (4-SKW SB, 5-SKW HB, 6-HP SB, 7-HP HB)
+RefClk  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: 5'bXX000 : Bit 0,1,2 - 0: 19.2MHz, 1: 26MHz, 2: 38.4MHz  [Default], 3: 52MHz,  4: 38.4MHz XTAL, 5: 26MHz XTAL ,  5'bX0XXX : Bit 3 - CLK_REQ type,  0 = wired-OR [Default], 1= push-pull ,  5'b0XXXX : Bit 4 - CLK_REQ polarity, 0 = Normal [Default], 1=Inverted
+SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid FREF clock on the device inputs
+ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the FREF clock is valid on wakeup
+TCXO_Clk  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: 5'bXX000 : Bit 0,1,2 - 0: 19.2MHz, 1: 26MHz, 2: 38.4MHz  [Default], 3: 52MHz, 4: 16.368Mhz, 5: 32.736 Mhz
+TCXO_SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid TCXO clock on the device inputs
+TCXO_ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the TCXO clock is valid on wakeup
+TCXO_LDO_Voltage = 00 # Length: 1; Unit: Options (0:2.5v, 1:2.55v, 2:2.6v); Format: Unsigned; Source: Customer; Comment: TCXO LDO Voltage
+Platform_configuration = 02 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer ; Comment: Bit 0: Levelshifter support (0: No LS, 1: With LS), Bit 1,2:Configure IO's [SDIO/wspi] (00- 8mA, 01- 4mA (default), 10- 6mA, 11 - 2mA), Bit 3:Eeprom (0-No Eeprom), Bit 4: SDIO IB Enable sync, Bit 5: SDIO IB Enable async, Bit 6: SDIO IB Enable BlockMode, Bit 7: SDIO High-Speed support
+Single_Dual_Band_Solution  = 01 # Length: 1; Unit: Options (0: 2.5v, 1: 2.55v, 2: 2.6v); Format: Unsigned; Source: Customer; Comment: This field notifies the FW whether the solution is a single-band or dual-band
+Settings  = 3c 00 00 00 # Length: 4; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit0: NBI (0: Off, 1: On), Bit1: Telec channel 14 (0: Off, 1: On), Bit2: FEM0-LB, Bit3: FEM0-HB, Bit4: FEM1-LB, Bit5: FEM1-HB - TX BiP load (0: Internal, 1: External), Bit6: LPD Low band, Bit7: LPD High band
+XTALItrimVal = 04 # Length: 1; Unit: Current trimming for XTAL; Format: Unsigned; Source: TI; Comment: Current trimming for XTAL
+SRState = 00 # Length: 1; Unit: Options (0: Disabled, 1: Enabled); Format: Decimal; Source: TI; Comment: Smart Reflax (proprietary mechanism of TI that identify the silicon process specific params) state
+SRF1 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 0F 3F  # Length: 16; Unit: SRF1 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF2 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SRF2 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF3 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SRF3 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+#SR_Debug_Table = 09 04 19 10 01 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SR_Debug_Table values; Format: Signed; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P = 11 # Length: 1; Unit: SR_SEN_N_P values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P_Gain = AA # Length: 1; Unit: SR_SEN_N_P_GAIN values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_NRN = B6 # Length: 1; Unit: SR_SEN_NRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#SR_SEN_PRN = F0 # Length: 1; Unit: SR_SEN_PRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2: Band-dependant parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TxTraceLoss_2_4G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 14; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_5G  = 00 00 00 00 00 00 00 # Length: 7; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TxTraceLoss_5G  = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 35; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2:     FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1:   FEM parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FemVendorAndOptions  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit 0..1 - 0: RFMD, 1: TQS, 2: SKWS,  Bit 4..7 [Version control] -  0: TQS-S1.0, 1: TQS-S2.0, 2: TQS-S2.5, 3: TQS-D1.0, 4: TQS-D1.5, 5: RFMD-S1.5, 6: RFMD-S2.9, 7: RFMD-S3.0, 8: RFMD-D1.5, 9: RFMD-S2.9.5, 10: RFMD-D3.0.1, 11: TQS-S2.6, 12: TQS-D1.7
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM1_TxBiPReferencePDvoltage_2_4G = 01D9 # Length: 1; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM1_TxBiPReferencePower_2_4G  = 80 # Length: 1; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage . The TX BiP reference power is linked to the TX BiP reference PD voltage
+FEM1_TxBiPOffsetdB_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM1_TxPerRatePowerLimits_2_4G_Normal = 1D 1F 22 26 27 29 25 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Degraded = 1D 1F 22 26 27 27 24 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Extreme = 16 1D 1E 20 24 25 22 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_DegradedLowToNormalThr_2_4G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_NormalToDegradedHighThr_2_4G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerChannelPowerLimits_2_4G_11b = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPerChannelPowerLimits_2_4G_OFDM = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPDVsRateOffsets_2_4G = 01 02 02 02 02 00 02 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM1_TxPDVsChannelOffsets_2_4G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 14; Unit: 1/8dB; Format: Signed; Source: TI/Customer; Comment: This parameter is a power detector offset value used to correct the power detector curve for each channel
+FEM1_TxPDVsTemperature_2_4G = 00 00 # Length: 2; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each temperture
+FEM1_TxIbiasTable_2_4G  = 17 17 17 1a 16 17 1a 17 # Length: 8; Unit: Codeword ; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM. Options (MCS7, 54/48, 36/24, 18/12, 9/6, 11b, MCS0, 11bCh14)
+FEM1_RxFemInsertionLoss_2_4G  = 10 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL128x
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM1_TxBiPReferencePDvoltage_5G  = 019A 01AE 01C2 01CC 01DB 01DB 01D1 # Length: 7; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM1_TxBiPReferencePower_5G = 80 80 80 80 80 80 80 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage . The TX BiP reference power is linked to the TX BiP reference PD voltage
+FEM1_TxBiPOffsetdB_5G = 00 00 00 00 00 00 00 # Length: 7; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM1_TxPerRatePowerLimits_5G_Normal  = 1C 1E 21 23 25 50 25 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_5G_Degraded  = 18 1E 21 23 25 50 24 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_5G_Extreme = 16 1C 1E 20 20 50 1E # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_DegradedLowToNormalThr_5G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_NormalToDegradedHighThr_5G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerChannelPowerLimits_5G_OFDM  = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 35; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPDVsRateOffsets_5G  = 01 02 02 02 02 00 02 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM1_TxPDVsChannelOffsets_5G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 35; Unit: 1/8dB; Format: Signed; Source: TI/Customer; Comment: This parameter is a power detector offset value used to correct the power detector curve for each channel
+FEM1_TxPDVsTemperature_5G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 14; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each temperture
+FEM1_TxIbiasTable_5G  = 10 10 10 10 10 10 10 # Length: 7; Unit: Codeword; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM
+FEM1_RxFemInsertionLoss_5G  = 10 10 10 10 10 10 10 # Length: 7; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL128x
+
diff --git a/mac80211/config/android_dhcpcd.conf b/mac80211/config/android_dhcpcd.conf
new file mode 100644
index 0000000..54006c7
--- /dev/null
+++ b/mac80211/config/android_dhcpcd.conf
@@ -0,0 +1,6 @@
+# dhcpcd configuration for Android Wi-Fi interface
+# See dhcpcd.conf(5) for details.
+
+interface wlan0
+# dhcpcd-run-hooks uses these options.
+option subnet_mask, routers, domain_name_servers
diff --git a/mac80211/config/hostapd.conf b/mac80211/config/hostapd.conf
new file mode 100644
index 0000000..ae257a8
--- /dev/null
+++ b/mac80211/config/hostapd.conf
@@ -0,0 +1,35 @@
+driver=nl80211
+logger_syslog=-1
+logger_syslog_level=2
+logger_stdout=-1
+logger_stdout_level=2
+dump_file=/data/misc/wifi/hostapd.dump
+ctrl_interface=/dev/socket
+ctrl_interface_group=0
+hw_mode=g
+channel=11
+beacon_int=100
+dtim_period=2
+max_num_sta=5
+supported_rates=10 20 55 110 60 90 120 180 240 360 480 540
+preamble=1
+macaddr_acl=0
+auth_algs=1
+ignore_broadcast_ssid=0
+wme_enabled=0
+wep_rekey_period=0
+eap_server=0
+own_ip_addr=127.0.0.1
+wpa_group_rekey=0
+wpa_gmk_rekey=0
+wpa_ptk_rekey=0
+interface=wlan1
+ssid=AndroidAP
+country_code=US
+ieee80211d=1
+ap_table_max_size=255
+ap_table_expiration_time=3600
+tx_queue_data2_aifs=2
+tx_queue_data2_cwmin=15
+tx_queue_data2_cwmax=63
+tx_queue_data2_burst=0
diff --git a/mac80211/config/wpa_supplicant.conf b/mac80211/config/wpa_supplicant.conf
new file mode 100644
index 0000000..434ce74
--- /dev/null
+++ b/mac80211/config/wpa_supplicant.conf
@@ -0,0 +1,5 @@
+##### wpa_supplicant configuration file template #####
+update_config=1
+ctrl_interface=wlan0
+ap_scan=1
+fast_reauth=1
diff --git a/mac80211/ti-utils/Android.mk b/mac80211/ti-utils/Android.mk
new file mode 100644
index 0000000..187b706
--- /dev/null
+++ b/mac80211/ti-utils/Android.mk
@@ -0,0 +1,42 @@
+LOCAL_PATH:= $(call my-dir)
+
+#
+# Calibrator
+#
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+        nvs.c \
+        misc_cmds.c \
+        calibrator.c \
+        plt.c \
+        ini.c
+
+LOCAL_CFLAGS := -DCONFIG_LIBNL20
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH) \
+    external/libnl-headers
+
+LOCAL_STATIC_LIBRARIES := libnl_2
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE := calibrator
+
+include $(BUILD_EXECUTABLE)
+
+#
+# UIM Application
+#
+#include $(CLEAR_VARS)
+
+#LOCAL_C_INCLUDES:= \
+#    $(LOCAL_PATH)/uim_rfkill/ \
+#    external/bluetooth/bluez/
+
+#LOCAL_SRC_FILES:= \
+#    uim_rfkill/uim.c
+#LOCAL_CFLAGS:= -g -c -W -Wall -O2 -D_POSIX_SOURCE
+#LOCAL_SHARED_LIBRARIES:= libnetutils
+#LOCAL_MODULE_TAGS := eng
+#LOCAL_MODULE:=uim-util
+
+#include $(BUILD_EXECUTABLE)
diff --git a/mac80211/ti-utils/COPYING b/mac80211/ti-utils/COPYING
new file mode 100644
index 0000000..def0d30
--- /dev/null
+++ b/mac80211/ti-utils/COPYING
@@ -0,0 +1,36 @@
+/*
+ * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.
+ * All rights reserved.
+ *
+ * Base on code from
+ *  Copyright (c) 2007, 2008, Johannes Berg <johannes@sipsolutions.net>
+ *  Copyright (c) 2007,	Andy Lutomirski
+ *  Copyright (c) 2007, Mike Kershaw
+ *  Copyright (c) 2008-2009, Luis R. Rodriguez <mcgrof@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Texas Instruments nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/mac80211/ti-utils/Makefile b/mac80211/ti-utils/Makefile
new file mode 100644
index 0000000..5dc754f
--- /dev/null
+++ b/mac80211/ti-utils/Makefile
@@ -0,0 +1,28 @@
+CC = $(CROSS_COMPILE)gcc
+CFLAGS = -O2 -Wall
+CFLAGS += -DCONFIG_LIBNL20 -I$(NFSROOT)/usr/include -I$(NFSROOT)/include
+
+LDFLAGS += -L$(NFSROOT)/lib
+LIBS += -lnl -lnl-genl -lm
+
+OBJS = nvs.o misc_cmds.o calibrator.o plt.o ini.o
+
+%.o: %.c calibrator.h nl80211.h plt.h nvs_dual_band.h
+    $(CC) $(CFLAGS) -c -o $@ $<
+
+all: $(OBJS) 
+    $(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o calibrator
+
+uim:
+    $(CC) $(CFLAGS) $(LDFLAGS) uim_rfkill/$@.c -o $@
+
+static: $(OBJS) 
+    $(CC) $(LDFLAGS) --static $(OBJS) $(LIBS) -o calibrator
+
+install:
+    @echo Copy files to $(NFSROOT)/home/root
+    @cp -f ./calibrator $(NFSROOT)/home/root
+    @cp -f ./scripts/go.sh $(NFSROOT)/home/root
+
+clean:
+    @rm -f *.o calibrator uim
diff --git a/mac80211/ti-utils/README b/mac80211/ti-utils/README
new file mode 100644
index 0000000..04f4d9e
--- /dev/null
+++ b/mac80211/ti-utils/README
@@ -0,0 +1,278 @@
+
+The calibrator and other useful utilities for TI wireless solution,
+based on wl12xx driver.
+
+Calibration is a process in which specific radio configuration parameters are
+generated and saved into the NVS file, later to be used by the wl12xx driver
+upon initialization.
+These configuration parameters are specific to the chip on the specific design
+and therefore are sent back to the driver to store in non-volatile memory for
+later use. Upon initialization, the wl12xx driver will load an NVS file where
+it expects to read those parameters and send them to the chip.
+
+The NVS file contains 2 main parts - one stores the calibration parameters and
+the other one stores initialization information required for the wl12xx driver.
+
+--- Build procedure
+
+Kernel configuration.
+Make sure your kernel is configured to support nl80211 testmode commands
+(NL80211_TESTMODE=y). Also enable following configurations:
+CRC7=m
+FW_LOADER=m
+
+In userspace there is dependent on libnl v2.x package. It can be downloaded
+from http://www.infradead.org/~tgr/libnl/files/libnl-2.0.tar.gz
+
+Set follow environment variables:
+export NFSROOT=<path to roofs of a target where installed libnl library>
+export CROSS_COMPILE=arm-none-linux-gnueabi-
+make
+make install
+
+Make sure that calibrator utility and go.sh script placed in the same dir.
+
+--- How to calibrate
+
+Native Linux calibration procedure.
+
+    ./go.sh -c <path to INI file> [<path to firmware directory>]
+
+Android calibration procedure.
+
+    Based on adb utility which comes native with Android SDK
+
+    adb shell "echo Going to stop GUI"
+    adb shell "stop"
+
+    adb shell "echo Create reference NVS"
+    adb shell "calibrator set ref_nvs /data/TQS_D_1.7.ini"
+
+    adb shell "echo Copy reference NVS file"
+    adb shell "cat ./new-nvs.bin > /system/etc/firmware/ti-connectivity/wl1271-nvs.bin"
+
+    adb shell "echo Insert wl12xx SDIO module"
+    adb shell "insmod /system/lib/modules/wl12xx_sdio.ko"
+
+    adb shell "echo Calibrate device"
+    adb shell "calibrator wlan0 plt power_mode on"
+    adb shell "calibrator wlan0 plt tune_channel 0 7"
+    adb shell "calibrator wlan0 plt tx_bip 1 1 1 1 1 1 1 1"
+    adb shell "calibrator wlan0 plt power_mode off"
+
+    adb shell "echo Set MAC address in NVS file"
+    adb shell "calibrator set nvs_mac ./new-nvs.bin 08:00:28:90:64:31"
+
+    adb shell "echo Remove wl12xx modules"
+    adb shell "rmmod wl12xx_sdio wl12xx"
+    adb shell "rmmod wl12xx"
+
+    adb shell "echo Copy calibrated NVS file"
+    adb shell "cat ./new-nvs.bin > /system/etc/firmware/ti-connectivity/wl1271-nvs.bin"
+    adb shell "insmod /system/lib/modules/wl12xx.ko"
+
+    adb shell "echo Going to start GUI"
+    adb shell "start"
+
+--- How to calibrate with AutoFEM
+
+The wl12xx driver has ability to use it's NVS file with radio parameters for 2
+different frontend modules. The driver requires firmware at boot time which
+FEM parameters it needs and provides radio parameters according to answer.
+
+There is also scenario when driver decides which radio parameters to give
+to firmware. In such case, 2 parameters should be set. The autofem should be
+0 and fem_manuf should be 0 or 1, depends on FEM manufacturer.
+
+In order to prepare NVS file with radio parameters for 2 FEMs, do follows
+
+    ./go.sh -c2 <path to INI file> [<path to INI file>]
+
+There is option to use the feature manualy. In such case, there is need to set
+AutoFEM flag to 0 and explicitly set fem_manuf flag.
+
+    ./calibrator set autofem <0-manual|1-auto> [<nvs file>]
+    ./calibrator set fem_manuf <0|1> [<nvs file>]
+
+--- How to choose INI file
+
+It is very important to select INI file according to the firmware (see below).
+Those files organized in 3 directories:
+station - currently supported station firmware (wl1271-fw.bin)
+access_point - currently supported access point (wl1271-fw-ap.bin)
+
+For Beagle board and Panda board use ini_files/station/127x/TQS_S_2.6.ini
+For Blaze board with ES2.1 or ES2.1 use ini_files/station/128x/TQS_D_1.7.ini
+
+
+--- How to change MAC address in calibrated NVS
+
+./calibrator set nvs_mac <nvs file> [<mac addr xx:xx:xx:xx:xx:xx>]
+
+If the MAC address missing, the random valid value will be added.
+
+
+--- How to dump NVS file
+
+calibrator get dump_nvs [<nvs filename>]
+
+
+--- Firmware files
+
+The firmware files can be reached from git repository
+git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git
+under directory ti-connectivity.
+There are 2 firmware files there:
+wl1271-fw.bin    - station firmware
+wl1271-fw-ap.bin    - access point firmware
+
+
+--- Detailed instructions for calibrator procedures
+
+The following detailed instructions are collection of commands done by
+default calibration procedure.
+
+    TxBip procedure (calibration)
+
+It is important to set MAC address to an interface before the procedure.
+For example, `ifconfig wlan0 hw ether xx:xx:xx:xx:xx:xx'
+There are 2 ways to do it - short where all parameters has default values and
+full where you have to set all parameters manually.
+
+Short way:
+calibrator plt calibrate
+
+Full way:
+calibrator wlan0 plt power_mode on
+calibrator wlan0 plt tx_bip <0|1> <0|1> <0|1> <0|1> <0|1> <0|1> <0|1> <0|1>
+calibrator wlan0 plt power_mode off
+
+Result of this procedure is new NVS file created locally ./new-nvs.bin
+In order to use it, copy the file to /lib/firmware/wl1271-nvs.bin and reload.
+
+    TxCont procedure
+
+calibrator wlan0 plt power_mode on
+calibrator wlan0 plt tune_channel <band> <channel>
+calibrator wlan0 plt tx_cont <delay> <rate> <size> <amount> <power> <seed> <pkt mode> <DC on/off> <gi> <preamble> <type> <scramble> <clpc> <seq nbr mode> <dest mac>
+calibrator wlan0 plt tx_stop
+calibrator wlan0 plt power_mode off
+
+Description: This test sends packets of data directly to air. It receives
+several parameters as described bellow, to enable diversity of
+operational modes.
+It is mostly used to see Energy and radio impact on Air.
+Content of Packet can be Random, or Zero, One, Zero, one...
+
+Packets send are configurable with following parameters:
+  Delay between packets in microseconds
+  Rate
+    1 Mbps -   0x00000001       MCS_0 - 0x00002000
+    2 Mbps -   0x00000002       MCS_1 - 0x00004000
+    5.5 Mbps - 0x00000004       MCS_2 - 0x00008000
+    6 Mbps -   0x00000008       MCS_3 - 0x00010000
+    9 Mbps -   0x00000010       MCS_4 - 0x00020000
+    11 Mbps -  0x00000020       MCS_5 - 0x00040000
+    12 Mbps -  0x00000040       MCS_6 - 0x00080000
+    18 Mbps -  0x00000080       MCS_7 - 0x00100000
+    24 Mbps -  0x00000200
+    36 Mbps -  0x00000400
+    48 Mbps -  0x00000800
+    54 Mbps -  0x00001000
+  Size of data field in MPDU (in bytes, 0 - 2284)
+  Amount - number of packets in case of using series mode
+  Power - output power in dBm*1000
+  Seed - value for the scrambler
+  Packet mode - 0-single, 1-multipile, 3-continuous, 4-FCC
+  DC on/off - activate DCF
+  gi - guard interval on/off for 11n rates
+  Preamble
+    1 Mbps - long preamble mode=0
+    2, 5.5, 11 Mbps - long preamble mode=0, short preamble mode=1
+    6, 9, 12, 18, 24, 36, 48, 54 Mbps - ofdm preamble mode=4
+    from MCS_0 to MCS_7 - n mixed mode preamble mode=6, greenfield preamble mode=7
+  Type is 0-data packet, 1-ack, 2-probe req, 3-random data, 4-user data
+  Scrambler - on/off
+  CLPC
+    range 0-100 is disable calibration
+  Sequence number mode (incremented or fixed)
+  Destination Mac address
+
+    RxStat procedure
+
+There are 2 ways to do it - short where all parameters has default values and
+full where you have to set all parameters manually.
+
+Short way:
+calibrator plt rx_statistics
+
+In the short way each time the statistics will be reseted.
+
+Full way:
+calibrator wlan0 plt power_mode on
+calibrator wlan0 plt start_rx_statcs
+calibrator wlan0 plt get_rx_statcs
+calibrator wlan0 plt stop_rx_statcs
+calibrator wlan0 plt power_mode off
+
+While willing to reset the statistic run:
+calibrator wlan0 plt reset_rx_statcs
+
+    Update NVS file procedure
+
+This is procedure changes ini part of NVS file. It helps when there is need
+to change ini part of NVS which already calibrated.
+
+calibrator set upd_nvs <ini file> [<nvs file>]
+
+If NVS filename parameter not provided the current NVS file will be used from
+destination directory (usually /lib/firmware).
+
+
+--- Miscellaneous procedures
+
+    Read MAC address from NVS file
+
+calibrator get nvs_mac <nvs filename>
+
+
+    Push local NVS to the system:
+
+calibrator phy <phyname> set push_nvs <nvs filename>
+
+
+    Set NVS to use auto FEM detection
+
+calibrator set autofem 1
+
+
+    Set FEM manufacturer
+
+calibrator set fem_manuf 0|1
+
+
+    Tone transmission testing
+Get in PLT mode
+calibrator wlan0 plt power_mode on
+
+Run TxTone transmission
+calibrator set plt_tx_tone <power> <tone type>
+Power
+Tone type
+ 1 - Single tone
+ 2 - Carrier FeedThrough
+
+Stop transmission
+calibrator wlan0 plt tx_stop
+
+Get out from PLT mode
+calibrator wlan0 plt power_mode off
+
+-------------------------------------------------------------------------------
+
+The project can be accessed from git repository:
+    git clone git://github.com/gxk/ti-utils.git
+
+Please send all patches to Gery Kahn <geryk@ti.com>
+and CC linux-wireless@vger.kernel.org for community review.
+
diff --git a/mac80211/ti-utils/calibrator.c b/mac80211/ti-utils/calibrator.c
new file mode 100644
index 0000000..73ce1e0
--- /dev/null
+++ b/mac80211/ti-utils/calibrator.c
@@ -0,0 +1,561 @@
+/*
+ * PLT utility for wireless chip supported by TI's driver wl12xx
+ *
+ * See README and COPYING for more details.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <net/if.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+#include "nl80211.h"
+#include "calibrator.h"
+#include "plt.h"
+#include "ini.h"
+
+char calibrator_version[] = "0.71";
+#ifndef CONFIG_LIBNL20
+/* libnl 2.0 compatibility code */
+
+static inline struct nl_handle *nl_socket_alloc(void)
+{
+    return nl_handle_alloc();
+}
+
+static inline void nl_socket_free(struct nl_sock *h)
+{
+    nl_handle_destroy(h);
+}
+
+static inline int __genl_ctrl_alloc_cache(struct nl_sock *h,
+    struct nl_cache **cache)
+{
+    struct nl_cache *tmp = genl_ctrl_alloc_cache(h);
+    if (!tmp) {
+        return -ENOMEM;
+    }
+    *cache = tmp;
+    return 0;
+}
+#define genl_ctrl_alloc_cache __genl_ctrl_alloc_cache
+#endif /* CONFIG_LIBNL20 */
+
+int calibrator_debug;
+
+static int nl80211_init(struct nl80211_state *state)
+{
+    int err;
+
+    state->nl_sock = nl_socket_alloc();
+    if (!state->nl_sock) {
+        fprintf(stderr, "Failed to allocate netlink socket.\n");
+        return -ENOMEM;
+    }
+
+    if (genl_connect(state->nl_sock)) {
+        fprintf(stderr, "Failed to connect to generic netlink.\n");
+        err = -ENOLINK;
+        goto out_handle_destroy;
+    }
+
+    if (genl_ctrl_alloc_cache(state->nl_sock, &state->nl_cache)) {
+        fprintf(stderr, "Failed to allocate generic netlink cache.\n");
+        err = -ENOMEM;
+        goto out_handle_destroy;
+    }
+
+    state->nl80211 = genl_ctrl_search_by_name(state->nl_cache, "nl80211");
+    if (!state->nl80211) {
+        fprintf(stderr, "nl80211 not found.\n");
+        err = -ENOENT;
+        goto out_cache_free;
+    }
+
+    return 0;
+
+ out_cache_free:
+    nl_cache_free(state->nl_cache);
+ out_handle_destroy:
+    nl_socket_free(state->nl_sock);
+    return err;
+}
+
+static void nl80211_cleanup(struct nl80211_state *state)
+{
+    genl_family_put(state->nl80211);
+    nl_cache_free(state->nl_cache);
+    nl_socket_free(state->nl_sock);
+}
+
+static int cmd_size;
+
+extern struct cmd __start___cmd;
+extern struct cmd __stop___cmd;
+
+#define for_each_cmd(_cmd)                    \
+    for (_cmd = &__start___cmd; _cmd < &__stop___cmd;        \
+         _cmd = (const struct cmd *)((char *)_cmd + cmd_size))
+
+
+static void __usage_cmd(const struct cmd *cmd, char *indent, bool full)
+{
+    const char *start, *lend, *end;
+
+    printf("%s", indent);
+
+    switch (cmd->idby) {
+    case CIB_NONE:
+        break;
+    case CIB_PHY:
+        printf("phy <phyname> ");
+        break;
+    case CIB_NETDEV:
+        printf("dev <devname> ");
+        break;
+    }
+    if (cmd->parent && cmd->parent->name) {
+        printf("%s ", cmd->parent->name);
+    }
+    printf("%s", cmd->name);
+    if (cmd->args) {
+        printf(" %s", cmd->args);
+    }
+    printf("\n");
+
+    if (!full || !cmd->help) {
+        return;
+    }
+
+    /* hack */
+    if (strlen(indent)) {
+        indent = "\t\t";
+    }
+    else {
+        printf("\n");
+    }
+
+    /* print line by line */
+    start = cmd->help;
+    end = strchr(start, '\0');
+    do {
+        lend = strchr(start, '\n');
+        if (!lend) {
+            lend = end;
+        }
+        printf("%s", indent);
+        printf("%.*s\n", (int)(lend - start), start);
+        start = lend + 1;
+    } while (end != lend);
+
+    printf("\n");
+}
+
+static void usage_options(void)
+{
+    printf("Options:\n");
+    printf("\t--debug\t\tenable netlink debugging\n");
+}
+
+static const char *argv0;
+
+static void usage(bool full)
+{
+    const struct cmd *section, *cmd;
+
+    printf("Usage:\t%s [options] command\n", argv0);
+    usage_options();
+    printf("\t--version\tshow version (%s)\n", calibrator_version);
+    printf("Commands:\n");
+    for_each_cmd(section) {
+        if (section->parent) {
+            continue;
+        }
+
+        if (section->handler && !section->hidden) {
+            __usage_cmd(section, "\t", full);
+        }
+
+        for_each_cmd(cmd) {
+            if (section != cmd->parent) {
+                continue;
+            }
+            if (!cmd->handler || cmd->hidden) {
+                continue;
+            }
+            __usage_cmd(cmd, "\t", full);
+        }
+    }
+#if 0
+    printf("\nYou can omit the 'phy' or 'dev' if "
+            "the identification is unique,\n"
+            "e.g. \"iw wlan0 info\" or \"iw phy0 info\". "
+            "(Don't when scripting.)\n\n"
+            "Do NOT screenscrape this tool, we don't "
+            "consider its output stable.\n\n");
+#endif
+}
+
+static int print_help(struct nl80211_state *state,
+              struct nl_cb *cb,
+              struct nl_msg *msg,
+              int argc, char **argv)
+{
+    exit(3);
+}
+TOPLEVEL(help, NULL, 0, 0, CIB_NONE, print_help,
+     "Print usage for each command.");
+
+static void usage_cmd(const struct cmd *cmd)
+{
+    printf("\nUsage:\t%s [options] ", argv0);
+    __usage_cmd(cmd, "", true);
+    usage_options();
+}
+
+static void version(void)
+{
+    printf("calibrator version %s\n", calibrator_version);
+}
+
+static int phy_lookup(char *name)
+{
+    char buf[200];
+    int fd, pos;
+
+    snprintf(buf, sizeof(buf), "/sys/class/ieee80211/%s/index", name);
+
+    fd = open(buf, O_RDONLY);
+    if (fd < 0) {
+        return -1;
+    }
+    pos = read(fd, buf, sizeof(buf) - 1);
+    if (pos < 0) {
+        close(fd);
+        return -1;
+    }
+    buf[pos] = '\0';
+    close(fd);
+    return atoi(buf);
+}
+
+static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
+             void *arg)
+{
+    int *ret = arg;
+    *ret = err->error;
+
+    return NL_STOP;
+}
+
+static int finish_handler(struct nl_msg *msg, void *arg)
+{
+    int *ret = arg;
+    *ret = 0;
+
+    return NL_SKIP;
+}
+
+static int ack_handler(struct nl_msg *msg, void *arg)
+{
+    int *ret = arg;
+    *ret = 0;
+
+    return NL_STOP;
+}
+
+static int __handle_cmd(struct nl80211_state *state, enum id_input idby,
+            int argc, char **argv, const struct cmd **cmdout)
+{
+    const struct cmd *cmd, *match = NULL, *sectcmd;
+    struct nl_cb *cb;
+    struct nl_msg *msg;
+    int devidx = 0;
+    int err, o_argc;
+    const char *command, *section;
+    char *tmp, **o_argv;
+    enum command_identify_by command_idby = CIB_NONE;
+#if 0
+    if (file_exist(CURRENT_NVS_NAME) < 0) {
+        fprintf(stderr, "\n\tUnable to find NVS file (%s).\n\t"
+            "Make sure to use reference-nvs.bin instead.\n\n",
+            CURRENT_NVS_NAME);
+        return 2;
+    }
+#endif
+    if (argc <= 1) {
+        return 1;
+    }
+
+    o_argc = argc;
+    o_argv = argv;
+
+    switch (idby) {
+    case II_PHY_IDX:
+        command_idby = CIB_PHY;
+        devidx = strtoul(*argv + 4, &tmp, 0);
+        if (*tmp != '\0') {
+            return 1;
+        }
+        argc--;
+        argv++;
+        break;
+    case II_PHY_NAME:
+        command_idby = CIB_PHY;
+        devidx = phy_lookup(*argv);
+        argc--;
+        argv++;
+        break;
+    case II_NETDEV:
+        command_idby = CIB_NETDEV;
+        devidx = if_nametoindex(*argv);
+        if (devidx == 0) {
+            devidx = -1;
+        }
+        argc--;
+        argv++;
+        break;
+    default:
+        break;
+    }
+
+    if (devidx < 0) {
+        return -errno;
+    }
+
+    section = *argv;
+    argc--;
+    argv++;
+
+    for_each_cmd(sectcmd) {
+        if (sectcmd->parent) {
+            continue;
+        }
+        /* ok ... bit of a hack for the dupe 'info' section */
+        if (match && sectcmd->idby != command_idby) {
+            continue;
+        }
+
+        if (strcmp(sectcmd->name, section) == 0) {
+            match = sectcmd;
+        }
+    }
+
+    sectcmd = match;
+    match = NULL;
+    if (!sectcmd) {
+        return 1;
+    }
+
+    if (argc > 0) {
+        command = *argv;
+
+        for_each_cmd(cmd) {
+            if (!cmd->handler) {
+                continue;
+            }
+            if (cmd->parent != sectcmd) {
+                continue;
+            }
+            if (cmd->idby != command_idby) {
+                continue;
+            }
+            if (strcmp(cmd->name, command)) {
+                continue;
+            }
+            if (argc > 1 && !cmd->args) {
+                continue;
+            }
+            match = cmd;
+            break;
+        }
+
+        if (match) {
+            argc--;
+            argv++;
+        }
+    }
+
+
+    if (match) {
+        cmd = match;
+    } else {
+        /* Use the section itself, if possible. */
+        cmd = sectcmd;
+        if (argc && !cmd->args) {
+            return 1;
+        }
+        if (cmd->idby != command_idby) {
+            return 1;
+        }
+        if (!cmd->handler) {
+            return 1;
+        }
+    }
+
+    if (cmdout) {
+        *cmdout = cmd;
+    }
+
+    if (!cmd->cmd) {
+        argc = o_argc;
+        argv = o_argv;
+        return cmd->handler(state, NULL, NULL, argc, argv);
+    }
+
+    msg = nlmsg_alloc();
+    if (!msg) {
+        fprintf(stderr, "failed to allocate netlink message\n");
+        return 2;
+    }
+
+    cb = nl_cb_alloc(calibrator_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
+    if (!cb) {
+        fprintf(stderr, "failed to allocate netlink callbacks\n");
+        err = 2;
+        goto out_free_msg;
+    }
+
+    genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
+            cmd->nl_msg_flags, cmd->cmd, 0);
+
+    switch (command_idby) {
+    case CIB_PHY:
+        NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, devidx);
+        break;
+    case CIB_NETDEV:
+        NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);
+        break;
+    default:
+        break;
+    }
+
+    err = cmd->handler(state, cb, msg, argc, argv);
+    if (err) {
+        fprintf(stderr, "failed to handle\n");
+        goto out;
+    }
+
+    err = nl_send_auto_complete(state->nl_sock, msg);
+    if (err < 0) {
+        fprintf(stderr, "failed to autocomplete\n");
+        goto out;
+    }
+
+    err = 1;
+
+    nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
+    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
+    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
+
+    while (err > 0)
+        nl_recvmsgs(state->nl_sock, cb);
+
+ out:
+    nl_cb_put(cb);
+ out_free_msg:
+    nlmsg_free(msg);
+    return err;
+
+ nla_put_failure:
+    fprintf(stderr, "building message failed\n");
+    return 2;
+}
+
+int handle_cmd(struct nl80211_state *state, enum id_input idby,
+           int argc, char **argv)
+{
+    return __handle_cmd(state, idby, argc, argv, NULL);
+}
+
+int main(int argc, char **argv)
+{
+    struct nl80211_state nlstate;
+    int err;
+    const struct cmd *cmd = NULL;
+
+    /* calculate command size including padding */
+    cmd_size = abs((long)&__section_set - (long)&__section_get);
+    /* strip off self */
+    argc--;
+    argv0 = *argv++;
+
+    if (argc > 0 && strcmp(*argv, "--debug") == 0) {
+        calibrator_debug = 1;
+        argc--;
+        argv++;
+    }
+
+    if (argc > 0 && strcmp(*argv, "--version") == 0) {
+        version();
+        return 0;
+    }
+
+    /* need to treat "help" command specially so it works w/o nl80211 */
+    if (argc == 0 || strcmp(*argv, "help") == 0) {
+        usage(argc != 0);
+        return 0;
+    }
+
+    err = nl80211_init(&nlstate);
+    if (err) {
+        return 1;
+    }
+
+    if (strcmp(*argv, "dev") == 0 && argc > 1) {
+        argc--;
+        argv++;
+        err = __handle_cmd(&nlstate, II_NETDEV, argc, argv, &cmd);
+    } else if (strncmp(*argv, "phy", 3) == 0 && argc > 1) {
+        if (strlen(*argv) == 3) {
+            argc--;
+            argv++;
+            err = __handle_cmd(&nlstate, II_PHY_NAME,
+                argc, argv, &cmd);
+        } else if (*(*argv + 3) == '#')
+            err = __handle_cmd(&nlstate, II_PHY_IDX,
+                argc, argv, &cmd);
+        else
+            goto detect;
+    } else {
+        int idx;
+        enum id_input idby = II_NONE;
+ detect:
+        idx = if_nametoindex(argv[0]);
+        if (idx != 0) {
+            idby = II_NETDEV;
+        } else {
+            idx = phy_lookup(argv[0]);
+            if (idx >= 0) {
+                idby = II_PHY_NAME;
+            }
+        }
+
+        err = __handle_cmd(&nlstate, idby, argc, argv, &cmd);
+    }
+
+    if (err == 1) {
+        if (cmd) {
+            usage_cmd(cmd);
+        }
+        else
+            usage(false);
+    } else if (err < 0)
+        fprintf(stderr, "command failed: %s (%d)\n",
+            strerror(-err), err);
+
+    nl80211_cleanup(&nlstate);
+
+    return err;
+}
diff --git a/mac80211/ti-utils/calibrator.h b/mac80211/ti-utils/calibrator.h
new file mode 100644
index 0000000..f43fac4
--- /dev/null
+++ b/mac80211/ti-utils/calibrator.h
@@ -0,0 +1,156 @@
+#ifndef __CALIBRATOR_H
+#define __CALIBRATOR_H
+
+#include <stdbool.h>
+#include <netlink/netlink.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+
+#include "nl80211.h"
+
+#define ETH_ALEN 6
+
+#ifndef CONFIG_LIBNL20
+#  define nl_sock nl_handle
+#endif
+
+struct nl80211_state {
+    struct nl_sock *nl_sock;
+    struct nl_cache *nl_cache;
+    struct genl_family *nl80211;
+};
+
+enum command_identify_by {
+    CIB_NONE,
+    CIB_PHY,
+    CIB_NETDEV,
+};
+
+enum id_input {
+    II_NONE,
+    II_NETDEV,
+    II_PHY_NAME,
+    II_PHY_IDX,
+};
+
+struct cmd {
+    const char *name;
+    const char *args;
+    const char *help;
+    const enum nl80211_commands cmd;
+    int nl_msg_flags;
+    int hidden;
+    const enum command_identify_by idby;
+    /*
+     * The handler should return a negative error code,
+     * zero on success, 1 if the arguments were wrong
+     * and the usage message should and 2 otherwise.
+     */
+    int (*handler)(struct nl80211_state *state,
+               struct nl_cb *cb,
+               struct nl_msg *msg,
+               int argc, char **argv);
+    const struct cmd *parent;
+};
+
+#define ARRAY_SIZE(ar) (sizeof(ar)/sizeof(ar[0]))
+
+#define __COMMAND(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler, _help)\
+    static struct cmd                        \
+    __cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden\
+    __attribute__((used)) __attribute__((section("__cmd")))    = {    \
+        .name = (_name),                    \
+        .args = (_args),                    \
+        .cmd = (_nlcmd),                    \
+        .nl_msg_flags = (_flags),                \
+        .hidden = (_hidden),                    \
+        .idby = (_idby),                    \
+        .handler = (_handler),                    \
+        .help = (_help),                    \
+        .parent = _section,                    \
+     }
+#define COMMAND(section, name, args, cmd, flags, idby, handler, help)    \
+    __COMMAND(&(__section ## _ ## section), name, #name, args, cmd, flags, 0, idby, handler, help)
+#define HIDDEN(section, name, args, cmd, flags, idby, handler)        \
+    __COMMAND(&(__section ## _ ## section), name, #name, args, cmd, flags, 1, idby, handler, NULL)
+
+#define TOPLEVEL(_name, _args, _nlcmd, _flags, _idby, _handler, _help)    \
+    struct cmd                            \
+    __section ## _ ## _name                        \
+    __attribute__((used)) __attribute__((section("__cmd")))    = {    \
+        .name = (#_name),                    \
+        .args = (_args),                    \
+        .cmd = (_nlcmd),                    \
+        .nl_msg_flags = (_flags),                \
+        .idby = (_idby),                    \
+        .handler = (_handler),                    \
+        .help = (_help),                    \
+     }
+#define SECTION(_name)                            \
+    struct cmd __section ## _ ## _name                \
+    __attribute__((used)) __attribute__((section("__cmd"))) = {    \
+        .name = (#_name),                    \
+        .hidden = 1,                        \
+    }
+
+#define DECLARE_SECTION(_name)                        \
+    extern struct cmd __section ## _ ## _name;
+
+extern int calibrator_debug;
+
+int handle_cmd(struct nl80211_state *state, enum id_input idby,
+           int argc, char **argv);
+
+struct print_event_args {
+    bool frame, time;
+};
+
+__u32 listen_events(struct nl80211_state *state,
+            const int n_waits, const __u32 *waits);
+__u32 __listen_events(struct nl80211_state *state,
+              const int n_waits, const __u32 *waits,
+              struct print_event_args *args);
+
+
+int mac_addr_a2n(unsigned char *mac_addr, char *arg);
+void mac_addr_n2a(char *mac_addr, unsigned char *arg);
+
+int parse_keys(struct nl_msg *msg, char **argv, int argc);
+
+void print_ht_mcs(const __u8 *mcs);
+void print_ampdu_length(__u8 exponent);
+void print_ampdu_spacing(__u8 spacing);
+void print_ht_capability(__u16 cap);
+
+const char *iftype_name(enum nl80211_iftype iftype);
+const char *command_name(enum nl80211_commands cmd);
+int ieee80211_channel_to_frequency(int chan);
+int ieee80211_frequency_to_channel(int freq);
+
+void print_ssid_escaped(const uint8_t len, const uint8_t *data);
+
+int nl_get_multicast_id(struct nl_sock *sock, const char *family,
+    const char *group);
+
+char *reg_initiator_to_string(__u8 initiator);
+
+const char *get_reason_str(uint16_t reason);
+const char *get_status_str(uint16_t status);
+
+enum print_ie_type {
+    PRINT_SCAN,
+    PRINT_LINK,
+};
+
+#define BIT(x) (1ULL<<(x))
+
+void print_ies(unsigned char *ie, int ielen, bool unknown,
+           enum print_ie_type ptype);
+
+
+DECLARE_SECTION(set);
+DECLARE_SECTION(get);
+DECLARE_SECTION(plt);
+
+#endif /* __CALIBRATOR_H */
diff --git a/mac80211/ti-utils/ini.c b/mac80211/ti-utils/ini.c
new file mode 100644
index 0000000..eea0a1c
--- /dev/null
+++ b/mac80211/ti-utils/ini.c
@@ -0,0 +1,1113 @@
+/*
+ * PLT utility for wireless chip supported by TI's driver wl12xx
+ *
+ * See README and COPYING for more details.
+ */
+
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+#include <linux/wireless.h>
+#include "nl80211.h"
+
+#include "calibrator.h"
+#include "plt.h"
+#include "ini.h"
+#include "nvs.h"
+
+static char *ini_get_line(char *s, int size, FILE *stream, int *line,
+				  char **_pos)
+{
+	char *pos, *end, *sstart;
+
+	while (fgets(s, size, stream)) {
+		s[size - 1] = '\0';
+		pos = s;
+
+		/* Skip white space from the beginning of line. */
+		while (*pos == ' ' || *pos == '\t' || *pos == '\r') {
+			pos++;
+                }
+
+		/* Skip comment lines and empty lines */
+		if (*pos == '#' || *pos == '\n' || *pos == '\0') {
+			continue;
+                }
+
+		/*
+		 * Remove # comments unless they are within a double quoted
+		 * string.
+		 */
+		sstart = strchr(pos, '"');
+		if (sstart) {
+			sstart = strrchr(sstart + 1, '"');
+                }
+		if (!sstart) {
+			sstart = pos;
+                }
+		end = strchr(sstart, '#');
+		if (end) {
+			*end-- = '\0';
+                } else {
+			end = pos + strlen(pos) - 1;
+                }
+
+		/* Remove trailing white space. */
+		while (end > pos &&
+		       (*end == '\n' || *end == ' ' || *end == '\t' ||
+			*end == '\r')) {
+			*end-- = '\0';
+                }
+
+		if (*pos == '\0') {
+			continue;
+                }
+
+		(*line)++;
+
+		if (_pos) {
+			*_pos = pos;
+                }
+		return pos;
+	}
+
+	if (_pos) {
+		*_pos = NULL;
+        }
+
+	return NULL;
+}
+
+static int split_line(char *line, char **name, char **value)
+{
+	char *pos = line;
+
+	*value = strchr(pos, '=');
+	if (!*value) {
+		fprintf(stderr, "Wrong format of line\n");
+		return 1;
+	}
+
+	*name = *value;
+
+	(*name)--;
+	while (**name == ' ' || **name == '\t' || **name == '\r') {
+		(*name)--;
+        }
+
+	*++(*name) = '\0';
+
+	(*value)++;
+	while (**value == ' ' || **value == '\t' || **value == '\r') {
+		(*value)++;
+        }
+
+	return 0;
+}
+
+#define COMPARE_N_ADD(temp, str, val, ptr, size)		\
+	if (strncmp(temp, str, sizeof(temp)) == 0) {		\
+		int i;						\
+		unsigned char *p = ptr;				\
+		for (i = 0; i < size; i++) {			\
+			*p = strtol(val, NULL, 16);		\
+			if (i != sizeof(ptr)-1) {		\
+				val += 3; p++;			\
+			}					\
+		}						\
+		return 0;					\
+	}
+
+#define DBG_COMPARE_N_ADD(temp, str, val, ptr, size)		\
+	if (strncmp(temp, str, sizeof(temp)) == 0) {		\
+		int i;						\
+		unsigned char *p = ptr;				\
+		for (i = 0; i < size; i++) {			\
+			*p = strtol(val, NULL, 16);		\
+			if (i != sizeof(ptr)-1) {		\
+				val += 3; p++;			\
+			}					\
+		}						\
+		p = ptr;					\
+		printf("%s ", temp);				\
+		for (i = 0; i < size; i++) {			\
+			printf("%02X ", *p);			\
+			p++;					\
+		}						\
+		printf("\n");					\
+		return 0;					\
+	}
+
+#define COMPARE_N_ADD2(temp, str, val, ptr, size)		\
+	if (strncmp(temp, str, sizeof(temp)) == 0) {		\
+		int i;						\
+		unsigned short *p = ptr;			\
+		for (i = 0; i < size; i++) {			\
+			*p = strtol(val, NULL, 16);		\
+			if (i != sizeof(ptr)-1) {		\
+				val += 5; p++;			\
+			}					\
+		}						\
+		return 0;					\
+	}
+
+#define DBG_COMPARE_N_ADD2(temp, str, val, ptr, size)		\
+	if (strncmp(temp, str, sizeof(temp)) == 0) {		\
+		int i;						\
+		unsigned short *p = ptr;			\
+		for (i = 0; i < size; i++) {			\
+			*p = strtol(val, NULL, 16);		\
+			if (i != sizeof(ptr)-1) {		\
+				val += 5; p++;			\
+			}					\
+		}						\
+		p = ptr;					\
+		printf("%s ", temp);				\
+		for (i = 0; i < size; i++) {			\
+			printf("%04X ", *p);			\
+			p++;					\
+		}						\
+		printf("\n");					\
+		return 0;					\
+	}
+
+static int parse_general_prms(char *l, struct wl12xx_common *cmn,
+	struct wl12xx_ini *p)
+{
+	char *name, *val;
+	struct wl1271_ini_general_params *gp = &(p->ini1271.general_params);
+
+	if (split_line(l, &name, &val)) {
+		return 1;
+        }
+
+	COMPARE_N_ADD("TXBiPFEMAutoDetect", l, val,
+		&gp->tx_bip_fem_auto_detect, 1);
+
+	COMPARE_N_ADD("TXBiPFEMManufacturer", l, val,
+		&gp->tx_bip_fem_manufacturer, 1);
+
+	COMPARE_N_ADD("RefClk", l, val, &gp->ref_clock, 1);
+
+	COMPARE_N_ADD("SettlingTime", l, val, &gp->settling_time, 1);
+
+	COMPARE_N_ADD("ClockValidOnWakeup", l, val,
+		&gp->clk_valid_on_wakeup, 1);
+
+	COMPARE_N_ADD("DC2DCMode", l, val, &gp->dc2dc_mode, 1);
+
+	COMPARE_N_ADD("Single_Dual_Band_Solution", l, val,
+		&gp->dual_mode_select, 1);
+
+	if (cmn->dual_mode == DUAL_MODE_UNSET) {
+		cmn->dual_mode = gp->dual_mode_select;
+        }
+	else if (cmn->dual_mode != gp->dual_mode_select) {
+		fprintf(stderr, "Error, FEMs with different dual modes\n");
+		return 1;
+	}
+
+	COMPARE_N_ADD("Settings", l, val, &gp->general_settings, 1);
+
+	COMPARE_N_ADD("SRState", l, val, &gp->sr_state, 1);
+
+	COMPARE_N_ADD("SRF1", l, val,
+		gp->srf1, WL1271_INI_MAX_SMART_REFLEX_PARAM);
+
+	COMPARE_N_ADD("SRF2", l, val,
+		gp->srf2, WL1271_INI_MAX_SMART_REFLEX_PARAM);
+
+	COMPARE_N_ADD("SRF3", l, val,
+		gp->srf3, WL1271_INI_MAX_SMART_REFLEX_PARAM);
+
+	fprintf(stderr, "Unable to parse: (%s)\n", l);
+
+	return 1;
+}
+
+static int parse_general_prms_128x(char *l, struct wl12xx_common *cmn,
+	struct wl12xx_ini *p)
+{
+	char *name, *val;
+	struct wl128x_ini_general_params *gp =
+		&(p->ini128x.general_params);
+
+	if (split_line(l, &name, &val)) {
+		return 1;
+        }
+
+	COMPARE_N_ADD("TXBiPFEMAutoDetect", l, val,
+		&gp->tx_bip_fem_auto_detect, 1);
+
+	COMPARE_N_ADD("TXBiPFEMManufacturer", l, val,
+		&gp->tx_bip_fem_manufacturer, 1);
+
+	COMPARE_N_ADD("RefClk", l, val, &gp->ref_clock, 1);
+
+	COMPARE_N_ADD("SettlingTime", l, val, &gp->settling_time, 1);
+
+	COMPARE_N_ADD("ClockValidOnWakeup", l, val,
+		&gp->clk_valid_on_wakeup, 1);
+
+	COMPARE_N_ADD("TCXO_Clk", l, val, &gp->tcxo_ref_clock, 1);
+
+	COMPARE_N_ADD("TCXO_SettlingTime", l, val, &gp->tcxo_settling_time, 1);
+
+	COMPARE_N_ADD("TCXO_ClockValidOnWakeup", l, val,
+		&gp->tcxo_valid_on_wakeup, 1);
+
+	COMPARE_N_ADD("TCXO_LDO_Voltage", l, val,
+		&gp->tcxo_ldo_voltage, 1);
+
+	COMPARE_N_ADD("Platform_configuration", l, val,
+		&gp->platform_conf, 1);
+
+	COMPARE_N_ADD("Single_Dual_Band_Solution", l, val,
+		&gp->dual_mode_select, 1);
+
+	if (cmn->dual_mode == DUAL_MODE_UNSET) {
+		cmn->dual_mode = gp->dual_mode_select;
+        } else if (cmn->dual_mode != gp->dual_mode_select) {
+		fprintf(stderr, "Error, FEMs with diferent dual modes\n");
+		return 1;
+	}
+
+	COMPARE_N_ADD("Settings", l, val,
+		gp->general_settings, WL128X_INI_MAX_SETTINGS_PARAM);
+
+	COMPARE_N_ADD("XTALItrimVal", l, val, &gp->xtal_itrim_val, 1);
+
+	COMPARE_N_ADD("SRState", l, val, &gp->sr_state, 1);
+
+	COMPARE_N_ADD("SRF1", l, val,
+		gp->srf1, WL1271_INI_MAX_SMART_REFLEX_PARAM);
+
+	COMPARE_N_ADD("SRF2", l, val,
+		gp->srf2, WL1271_INI_MAX_SMART_REFLEX_PARAM);
+
+	COMPARE_N_ADD("SRF3", l, val,
+		gp->srf3, WL1271_INI_MAX_SMART_REFLEX_PARAM);
+
+	fprintf(stderr, "Unable to parse: (%s)\n", l);
+
+	return 1;
+}
+
+static int parse_band2_prms(char *l, struct wl12xx_ini *p)
+{
+	char *name, *val;
+	struct wl1271_ini_band_params_2 *gp =
+		&(p->ini1271.stat_radio_params_2);
+
+	if (split_line(l, &name, &val)) {
+		return 1;
+        }
+
+	COMPARE_N_ADD("RxTraceInsertionLoss_2_4G", l, val,
+		&gp->rx_trace_insertion_loss, 1);
+
+	COMPARE_N_ADD("TXTraceLoss_2_4G", l, val,
+		&gp->tx_trace_loss, 1);
+
+	COMPARE_N_ADD("RxRssiAndProcessCompensation_2_4G", l, val,
+		gp->rx_rssi_process_compens,
+		WL1271_INI_RSSI_PROCESS_COMPENS_SIZE);
+
+	fprintf(stderr, "Unable to parse: (%s)\n", l);
+
+	return 1;
+}
+
+static int parse_band2_prms_128x(char *l, struct wl12xx_ini *p)
+{
+	char *name, *val;
+	struct wl128x_ini_band_params_2 *gp = &(p->ini128x.stat_radio_params_2);
+
+	if (split_line(l, &name, &val)) {
+		return 1;
+        }
+
+	COMPARE_N_ADD("RxTraceInsertionLoss_2_4G", l, val,
+		&gp->rx_trace_insertion_loss, 1);
+
+	COMPARE_N_ADD("TxTraceLoss_2_4G", l, val,
+		gp->tx_trace_loss, WL1271_INI_CHANNEL_COUNT_2);
+
+	fprintf(stderr, "Unable to parse: (%s)\n", l);
+
+	return 1;
+}
+
+static int parse_band5_prms(char *l, struct wl12xx_ini *p)
+{
+	char *name, *val;
+	struct wl1271_ini_band_params_5 *gp =
+		&(p->ini1271.stat_radio_params_5);
+
+	if (split_line(l, &name, &val)) {
+		return 1;
+        }
+
+	COMPARE_N_ADD("RxTraceInsertionLoss_5G", l, val,
+		gp->rx_trace_insertion_loss, 7);
+
+	COMPARE_N_ADD("TXTraceLoss_5G", l, val,
+		gp->tx_trace_loss, 7);
+
+	COMPARE_N_ADD("RxRssiAndProcessCompensation_5G", l, val,
+		gp->rx_rssi_process_compens,
+		WL1271_INI_RSSI_PROCESS_COMPENS_SIZE);
+
+	fprintf(stderr, "Unable to parse: (%s)\n", l);
+
+	return 1;
+}
+
+static int parse_band5_prms_128x(char *l, struct wl12xx_ini *p)
+{
+	char *name, *val;
+	struct wl128x_ini_band_params_5 *gp = &(p->ini128x.stat_radio_params_5);
+
+	if (split_line(l, &name, &val)) {
+		return 1;
+        }
+
+	COMPARE_N_ADD("RxTraceInsertionLoss_5G", l, val,
+		gp->rx_trace_insertion_loss, 7);
+
+	COMPARE_N_ADD("TxTraceLoss_5G", l, val,
+		gp->tx_trace_loss, 7);
+
+	fprintf(stderr, "Unable to parse: (%s)\n", l);
+
+	return 1;
+}
+
+static int parse_fem0_band2_prms(char *l, struct wl12xx_ini *p)
+{
+	char *name, *val;
+	struct wl1271_ini_fem_params_2 *gp =
+		&(p->ini1271.dyn_radio_params_2[0].params);
+
+	if (split_line(l, &name, &val)) {
+		return 1;
+        }
+
+	COMPARE_N_ADD2("FEM0_TXBiPReferencePDvoltage_2_4G", l, val,
+		&gp->tx_bip_ref_pd_voltage, 1);
+
+	COMPARE_N_ADD("FEM0_TxBiPReferencePower_2_4G", l, val,
+		&gp->tx_bip_ref_power, 1);
+
+	COMPARE_N_ADD("FEM0_TxBiPOffsetdB_2_4G", l, val,
+		&gp->tx_bip_ref_offset, 1);
+
+	COMPARE_N_ADD("FEM0_TxPerRatePowerLimits_2_4G_Normal", l, val,
+		gp->tx_per_rate_pwr_limits_normal,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM0_TxPerRatePowerLimits_2_4G_Degraded", l, val,
+		gp->tx_per_rate_pwr_limits_degraded,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM0_TxPerRatePowerLimits_2_4G_Extreme", l, val,
+		gp->tx_per_rate_pwr_limits_extreme,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM0_DegradedLowToNormalThr_2_4G", l, val,
+		&gp->degraded_low_to_normal_thr, 1);
+
+	COMPARE_N_ADD("FEM0_NormalToDegradedHighThr_2_4G", l, val,
+		&gp->normal_to_degraded_high_thr, 1);
+
+	COMPARE_N_ADD("FEM0_TxPerChannelPowerLimits_2_4G_11b", l, val,
+		gp->tx_per_chan_pwr_limits_11b,
+		WL1271_INI_CHANNEL_COUNT_2);
+
+	COMPARE_N_ADD("FEM0_TxPerChannelPowerLimits_2_4G_OFDM", l, val,
+		gp->tx_per_chan_pwr_limits_ofdm,
+		WL1271_INI_CHANNEL_COUNT_2);
+
+	COMPARE_N_ADD("FEM0_TxPDVsRateOffsets_2_4G", l, val,
+		gp->tx_pd_vs_rate_offsets,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM0_TxIbiasTable_2_4G", l, val,
+		gp->tx_ibias,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM0_RxFemInsertionLoss_2_4G", l, val,
+		&gp->rx_fem_insertion_loss, 1);
+
+	fprintf(stderr, "Unable to parse: (%s)\n", l);
+
+	return 1;
+}
+
+static int parse_fem0_band2_prms_128x(char *l, struct wl12xx_ini *p)
+{
+	char *name, *val;
+	struct wl128x_ini_fem_params_2 *gp =
+		&(p->ini128x.dyn_radio_params_2[0].params);
+
+	if (split_line(l, &name, &val)) {
+		return 1;
+        }
+
+	COMPARE_N_ADD2("FEM0_TxBiPReferencePDvoltage_2_4G", l, val,
+		&gp->tx_bip_ref_pd_voltage, 1);
+
+	COMPARE_N_ADD("FEM0_TxBiPReferencePower_2_4G", l, val,
+		&gp->tx_bip_ref_power, 1);
+
+	COMPARE_N_ADD("FEM0_TxBiPOffsetdB_2_4G", l, val,
+		&gp->tx_bip_ref_offset, 1);
+
+	COMPARE_N_ADD("FEM0_TxPerRatePowerLimits_2_4G_Normal", l, val,
+		gp->tx_per_rate_pwr_limits_normal,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM0_TxPerRatePowerLimits_2_4G_Degraded", l, val,
+		gp->tx_per_rate_pwr_limits_degraded,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM0_TxPerRatePowerLimits_2_4G_Extreme", l, val,
+		gp->tx_per_rate_pwr_limits_extreme,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM0_DegradedLowToNormalThr_2_4G", l, val,
+		&gp->degraded_low_to_normal_thr, 1);
+
+	COMPARE_N_ADD("FEM0_NormalToDegradedHighThr_2_4G", l, val,
+		&gp->normal_to_degraded_high_thr, 1);
+
+	COMPARE_N_ADD("FEM0_TxPerChannelPowerLimits_2_4G_11b", l, val,
+		gp->tx_per_chan_pwr_limits_11b,
+		WL1271_INI_CHANNEL_COUNT_2);
+
+	COMPARE_N_ADD("FEM0_TxPerChannelPowerLimits_2_4G_OFDM", l, val,
+		gp->tx_per_chan_pwr_limits_ofdm,
+		WL1271_INI_CHANNEL_COUNT_2);
+
+	COMPARE_N_ADD("FEM0_TxPDVsRateOffsets_2_4G", l, val,
+		gp->tx_pd_vs_rate_offsets,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM0_TxPDVsChannelOffsets_2_4G", l, val,
+		gp->tx_pd_vs_chan_offsets,
+		WL1271_INI_CHANNEL_COUNT_2);
+
+	COMPARE_N_ADD("FEM0_TxPDVsTemperature_2_4G", l, val,
+		gp->tx_pd_vs_temperature,
+		WL128X_INI_PD_VS_TEMPERATURE_RANGES);
+
+	COMPARE_N_ADD("FEM0_TxIbiasTable_2_4G", l, val,
+		gp->tx_ibias,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM0_RxFemInsertionLoss_2_4G", l, val,
+		&gp->rx_fem_insertion_loss, 1);
+
+	fprintf(stderr, "Unable to parse: (%s)\n", l);
+
+	return 1;
+}
+
+static int parse_fem1_band2_prms(char *l, struct wl12xx_ini *p)
+{
+	char *name, *val;
+	struct wl1271_ini_fem_params_2 *gp =
+		&(p->ini1271.dyn_radio_params_2[1].params);
+
+	if (split_line(l, &name, &val)) {
+		return 1;
+        }
+
+	COMPARE_N_ADD2("FEM1_TXBiPReferencePDvoltage_2_4G", l, val,
+		&gp->tx_bip_ref_pd_voltage, 1);
+
+	COMPARE_N_ADD("FEM1_TxBiPReferencePower_2_4G", l, val,
+		&gp->tx_bip_ref_power, 1);
+
+	COMPARE_N_ADD("FEM1_TxBiPOffsetdB_2_4G", l, val,
+		&gp->tx_bip_ref_offset, 1);
+
+	COMPARE_N_ADD("FEM1_TxPerRatePowerLimits_2_4G_Normal", l, val,
+		gp->tx_per_rate_pwr_limits_normal,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_TxPerRatePowerLimits_2_4G_Degraded", l, val,
+		gp->tx_per_rate_pwr_limits_degraded,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_TxPerRatePowerLimits_2_4G_Extreme", l, val,
+		gp->tx_per_rate_pwr_limits_extreme,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_DegradedLowToNormalThr_2_4G", l, val,
+		&gp->degraded_low_to_normal_thr, 1);
+
+	COMPARE_N_ADD("FEM1_NormalToDegradedHighThr_2_4G", l, val,
+		&gp->normal_to_degraded_high_thr, 1);
+
+	COMPARE_N_ADD("FEM1_TxPerChannelPowerLimits_2_4G_11b", l, val,
+		gp->tx_per_chan_pwr_limits_11b,
+		WL1271_INI_CHANNEL_COUNT_2);
+
+	COMPARE_N_ADD("FEM1_TxPerChannelPowerLimits_2_4G_OFDM", l, val,
+		gp->tx_per_chan_pwr_limits_ofdm,
+		WL1271_INI_CHANNEL_COUNT_2);
+
+	COMPARE_N_ADD("FEM1_TxPDVsRateOffsets_2_4G", l, val,
+		gp->tx_pd_vs_rate_offsets,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_TxIbiasTable_2_4G", l, val,
+		gp->tx_ibias,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_RxFemInsertionLoss_2_4G", l, val,
+		&gp->rx_fem_insertion_loss, 1);
+
+	fprintf(stderr, "Unable to parse: (%s)\n", l);
+
+	return 1;
+}
+
+static int parse_fem1_band2_prms_128x(char *l, struct wl12xx_ini *p)
+{
+	char *name, *val;
+	struct wl128x_ini_fem_params_2 *gp =
+		&(p->ini128x.dyn_radio_params_2[1].params);
+
+	if (split_line(l, &name, &val)) {
+		return 1;
+        }
+
+	COMPARE_N_ADD2("FEM1_TxBiPReferencePDvoltage_2_4G", l, val,
+		&gp->tx_bip_ref_pd_voltage, 1);
+
+	COMPARE_N_ADD("FEM1_TxBiPReferencePower_2_4G", l, val,
+		&gp->tx_bip_ref_power, 1);
+
+	COMPARE_N_ADD("FEM1_TxBiPOffsetdB_2_4G", l, val,
+		&gp->tx_bip_ref_offset, 1);
+
+	COMPARE_N_ADD("FEM1_TxPerRatePowerLimits_2_4G_Normal", l, val,
+		gp->tx_per_rate_pwr_limits_normal,
+		WL128X_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_TxPerRatePowerLimits_2_4G_Degraded", l, val,
+		gp->tx_per_rate_pwr_limits_degraded,
+		WL128X_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_TxPerRatePowerLimits_2_4G_Extreme", l, val,
+		gp->tx_per_rate_pwr_limits_extreme,
+		WL128X_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_DegradedLowToNormalThr_2_4G", l, val,
+		&gp->degraded_low_to_normal_thr, 1);
+
+	COMPARE_N_ADD("FEM1_NormalToDegradedHighThr_2_4G", l, val,
+		&gp->normal_to_degraded_high_thr, 1);
+
+	COMPARE_N_ADD("FEM1_TxPerChannelPowerLimits_2_4G_11b", l, val,
+		gp->tx_per_chan_pwr_limits_11b,
+		WL1271_INI_CHANNEL_COUNT_2);
+
+	COMPARE_N_ADD("FEM1_TxPerChannelPowerLimits_2_4G_OFDM", l, val,
+		gp->tx_per_chan_pwr_limits_ofdm,
+		WL1271_INI_CHANNEL_COUNT_2);
+
+	COMPARE_N_ADD("FEM1_TxPDVsRateOffsets_2_4G", l, val,
+		gp->tx_pd_vs_rate_offsets,
+		WL128X_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_TxPDVsChannelOffsets_2_4G", l, val,
+		gp->tx_pd_vs_chan_offsets,
+		WL1271_INI_CHANNEL_COUNT_2);
+
+	COMPARE_N_ADD("FEM1_TxPDVsTemperature_2_4G", l, val,
+		gp->tx_pd_vs_temperature,
+		WL128X_INI_PD_VS_TEMPERATURE_RANGES);
+
+	COMPARE_N_ADD("FEM1_TxIbiasTable_2_4G", l, val,
+		gp->tx_ibias,
+		WL128X_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_RxFemInsertionLoss_2_4G", l, val,
+		&gp->rx_fem_insertion_loss, 1);
+
+	fprintf(stderr, "Unable to parse: (%s)\n", l);
+
+	return 1;
+}
+
+static int parse_fem1_band5_prms(char *l, struct wl12xx_ini *p)
+{
+	char *name, *val;
+	struct wl1271_ini_fem_params_5 *gp =
+		&(p->ini1271.dyn_radio_params_5[1].params);
+
+	if (split_line(l, &name, &val)) {
+		return 1;
+        }
+
+	COMPARE_N_ADD2("FEM1_TXBiPReferencePDvoltage_5G", l, val,
+		gp->tx_bip_ref_pd_voltage, WL1271_INI_SUB_BAND_COUNT_5);
+
+	COMPARE_N_ADD("FEM1_TxBiPReferencePower_5G", l, val,
+		gp->tx_bip_ref_power, WL1271_INI_SUB_BAND_COUNT_5);
+
+	COMPARE_N_ADD("FEM1_TxBiPOffsetdB_5G", l, val,
+		gp->tx_bip_ref_offset, WL1271_INI_SUB_BAND_COUNT_5);
+
+	COMPARE_N_ADD("FEM1_TxPerRatePowerLimits_5G_Normal", l, val,
+		gp->tx_per_rate_pwr_limits_normal,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_TxPerRatePowerLimits_5G_Degraded", l, val,
+		gp->tx_per_rate_pwr_limits_degraded,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_TxPerRatePowerLimits_5G_Extreme", l, val,
+		gp->tx_per_rate_pwr_limits_extreme,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_DegradedLowToNormalThr_5G", l, val,
+		&gp->degraded_low_to_normal_thr, 1);
+
+	COMPARE_N_ADD("FEM1_NormalToDegradedHighThr_5G", l, val,
+		&gp->normal_to_degraded_high_thr, 1);
+
+	COMPARE_N_ADD("FEM1_TxPerChannelPowerLimits_5G_OFDM", l, val,
+		gp->tx_per_chan_pwr_limits_ofdm,
+		WL1271_INI_CHANNEL_COUNT_5);
+
+	COMPARE_N_ADD("FEM1_TxPDVsRateOffsets_5G", l, val,
+		gp->tx_pd_vs_rate_offsets,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_TxIbiasTable_5G", l, val,
+		gp->tx_ibias,
+		WL1271_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_RxFemInsertionLoss_5G", l, val,
+		gp->rx_fem_insertion_loss, WL1271_INI_SUB_BAND_COUNT_5);
+
+	fprintf(stderr, "Unable to parse: (%s)\n", l);
+
+	return 1;
+}
+
+static int parse_fem1_band5_prms_128x(char *l, struct wl12xx_ini *p)
+{
+	char *name, *val;
+	struct wl128x_ini_fem_params_5 *gp =
+		&(p->ini128x.dyn_radio_params_5[1].params);
+
+	if (split_line(l, &name, &val)) {
+		return 1;
+        }        
+
+	COMPARE_N_ADD2("FEM1_TxBiPReferencePDvoltage_5G", l, val,
+		gp->tx_bip_ref_pd_voltage, WL1271_INI_SUB_BAND_COUNT_5);
+
+	COMPARE_N_ADD("FEM1_TxBiPReferencePower_5G", l, val,
+		gp->tx_bip_ref_power, WL1271_INI_SUB_BAND_COUNT_5);
+
+	COMPARE_N_ADD("FEM1_TxBiPOffsetdB_5G", l, val,
+		gp->tx_bip_ref_offset, WL1271_INI_SUB_BAND_COUNT_5);
+
+	COMPARE_N_ADD("FEM1_TxPerRatePowerLimits_5G_Normal", l, val,
+		gp->tx_per_rate_pwr_limits_normal,
+		WL128X_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_TxPerRatePowerLimits_5G_Degraded", l, val,
+		gp->tx_per_rate_pwr_limits_degraded,
+		WL128X_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_TxPerRatePowerLimits_5G_Extreme", l, val,
+		gp->tx_per_rate_pwr_limits_extreme,
+		WL128X_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_DegradedLowToNormalThr_5G", l, val,
+		&gp->degraded_low_to_normal_thr, 1);
+
+	COMPARE_N_ADD("FEM1_NormalToDegradedHighThr_5G", l, val,
+		&gp->normal_to_degraded_high_thr, 1);
+
+	COMPARE_N_ADD("FEM1_TxPerChannelPowerLimits_5G_OFDM", l, val,
+		gp->tx_per_chan_pwr_limits_ofdm,
+		WL1271_INI_CHANNEL_COUNT_5);
+
+	COMPARE_N_ADD("FEM1_TxPDVsRateOffsets_5G", l, val,
+		gp->tx_pd_vs_rate_offsets,
+		WL128X_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_TxPDVsChannelOffsets_5G", l, val,
+		gp->tx_pd_vs_chan_offsets,
+		WL1271_INI_CHANNEL_COUNT_5);
+
+	COMPARE_N_ADD("FEM1_TxPDVsTemperature_5G", l, val,
+		gp->tx_pd_vs_temperature,
+		WL1271_INI_SUB_BAND_COUNT_5 * WL128X_INI_PD_VS_TEMPERATURE_RANGES);
+
+	COMPARE_N_ADD("FEM1_TxIbiasTable_5G", l, val,
+		gp->tx_ibias,
+		WL128X_INI_RATE_GROUP_COUNT);
+
+	COMPARE_N_ADD("FEM1_RxFemInsertionLoss_5G", l, val,
+		gp->rx_fem_insertion_loss, WL1271_INI_SUB_BAND_COUNT_5);
+
+	fprintf(stderr, "Unable to parse: (%s)\n", l);
+
+	return 1;
+}
+
+static int parse_fem_prms_128x(char *l, struct wl12xx_ini *p)
+{
+	char *name, *val;
+	struct wl128x_ini *gp = &p->ini128x;
+
+	if (split_line(l, &name, &val)) {
+		return 1;
+        }
+
+	COMPARE_N_ADD("FemVendorAndOptions", l, val,
+		&gp->fem_vendor_and_options, 1);
+
+	fprintf(stderr, "Unable to parse: (%s)\n", l);
+
+	return 1;
+}
+
+static int find_section(const char *l, enum wl1271_ini_section *st, int *cntr,
+	enum wl12xx_arch arch)
+{
+	if (strncmp("TXBiPFEMAutoDetect", l, 18) == 0) {
+		*st = GENERAL_PRMS;
+		if (arch == WL128X_ARCH) {
+			*cntr = 17;
+                } else {
+			*cntr = 12;
+                }
+
+		return 0;
+	}
+
+	if (strncmp("RxTraceInsertionLoss_2_4G", l, 25) == 0) {
+		*st = BAND2_PRMS;
+		if (arch == WL128X_ARCH){
+			*cntr = 2;
+                } else {
+			*cntr = 3;
+                }
+
+		return 0;
+	}
+
+	if (strncmp("FemVendorAndOptions", l, 19) == 0) {
+		*st = FEM_PRMS;
+		*cntr = 1;
+		return 0;
+	}
+
+	if (strncmp("RxTraceInsertionLoss_5G", l, 23) == 0) {
+		*st = BAND5_PRMS;
+		if (arch == WL128X_ARCH) {
+			*cntr = 2;
+		} else {
+			*cntr = 3;
+                }
+
+		return 0;
+	}
+
+	if (strncmp("FEM0_TXBiPReferencePDvoltage_2_4G", l, 33) == 0 ||
+		strncmp("FEM0_TxBiPReferencePDvoltage_2_4G", l, 33) == 0) {
+		*st = FEM0_BAND2_PRMS;
+		if (arch == WL128X_ARCH) {
+			*cntr = 15;
+		} else {
+			*cntr = 13;
+                }
+
+		return 0;
+	}
+
+	if (strncmp("FEM1_TXBiPReferencePDvoltage_2_4G", l, 33) == 0 ||
+		strncmp("FEM1_TxBiPReferencePDvoltage_2_4G", l, 33) == 0) {
+		*st = FEM1_BAND2_PRMS;
+		if (arch == WL128X_ARCH) {
+			*cntr = 15;
+                } else {
+			*cntr = 13;
+                }
+
+		return 0;
+	}
+
+	if (strncmp("FEM1_TXBiPReferencePDvoltage_5G", l, 31) == 0 ||
+		strncmp("FEM1_TxBiPReferencePDvoltage_5G", l, 31) == 0) {
+		*st = FEM1_BAND5_PRMS;
+		if (arch == WL128X_ARCH) {
+			*cntr = 14;
+		} else {
+			*cntr = 12;
+                }
+
+		return 0;
+	}
+
+	return 1;
+}
+
+static int ini_parse_line(char *l, int nbr, struct wl12xx_common *cmn)
+{
+	static enum wl1271_ini_section status;
+	static int cntr;
+
+	if (!cntr && find_section(l, &status, &cntr, cmn->arch)) {
+		fprintf(stderr, "Uknown ini section %s\n", l);
+		return 1;
+	}
+
+	switch (status) {
+	case GENERAL_PRMS:	/* general parameters */
+		cntr--;
+		return cmn->parse_ops->prs_general_prms(l, cmn, &cmn->ini);
+	case FEM_PRMS:	/* FEM parameters */
+		if (cmn->arch == WL1271_ARCH) {
+			fprintf(stderr, "The parameter not from 127x architecture\n");
+			return 1;
+		}
+		cntr--;
+		return parse_fem_prms_128x(l, &cmn->ini);
+	case BAND2_PRMS:	/* band 2.4GHz parameters */
+		cntr--;
+		return cmn->parse_ops->prs_band2_prms(l, &cmn->ini);
+	case BAND5_PRMS:	/* band 5GHz parameters */
+		cntr--;
+		return cmn->parse_ops->prs_band5_prms(l, &cmn->ini);
+	case FEM0_BAND2_PRMS:	/* FEM0 band 2.4GHz parameters */
+		cntr--;
+		return cmn->parse_ops->prs_fem0_band2_prms(l, &cmn->ini);
+	case FEM1_BAND2_PRMS:	/* FEM1 band 2.4GHz parameters */
+		cntr--;
+		return cmn->parse_ops->prs_fem1_band2_prms(l, &cmn->ini);
+	case FEM1_BAND5_PRMS:	/* FEM1 band 5GHz parameters */
+		cntr--;
+		return cmn->parse_ops->prs_fem1_band5_prms(l, &cmn->ini);
+	case UKNOWN_SECTION:
+		/* added because of compilation warning. handeled in find_section() */
+		break;
+	}
+
+	return 1;
+}
+
+#if 0
+static void ini_dump(struct wl1271_ini *ini)
+{
+	int i;
+
+	printf("\n");
+	printf("General params:\n");
+	printf("ref clock:                 %02X\n",
+		ini->general_params.ref_clock);
+	printf("settling time:             %02X\n",
+		ini->general_params.settling_time);
+	printf("clk valid on wakeup:       %02X\n",
+		ini->general_params.clk_valid_on_wakeup);
+	printf("dc2dc mode:                %02X\n",
+		ini->general_params.dc2dc_mode);
+	printf("dual band mode:            %02X\n",
+		ini->general_params.dual_mode_select);
+	printf("tx bip fem auto detect:    %02X\n",
+		ini->general_params.tx_bip_fem_auto_detect);
+	printf("tx bip fem manufacturer:   %02X\n",
+		ini->general_params.tx_bip_fem_manufacturer);
+	printf("general settings:          %02X\n",
+		ini->general_params.general_settings);
+	printf("sr state:                  %02X\n",
+		ini->general_params.sr_state);
+
+	printf("srf1:");
+	for (i = 0; i < WL1271_INI_MAX_SMART_REFLEX_PARAM; i++)
+		printf(" %02X", ini->general_params.srf1[i]);
+	printf("\n");
+
+	printf("srf2:");
+	for (i = 0; i < WL1271_INI_MAX_SMART_REFLEX_PARAM; i++)
+		printf(" %02X", ini->general_params.srf2[i]);
+	printf("\n");
+
+	printf("srf3:");
+	for (i = 0; i < WL1271_INI_MAX_SMART_REFLEX_PARAM; i++)
+		printf(" %02X", ini->general_params.srf3[i]);
+	printf("\n");
+
+	printf("Static 2.4 band params:\n");
+
+	printf("rx trace insertion loss: %02X\n",
+		ini->stat_radio_params_2.rx_trace_insertion_loss);
+
+	printf("rx rssi n process compensation:");
+	for (i = 0; i < WL1271_INI_RSSI_PROCESS_COMPENS_SIZE; i++)
+		printf(" %02X",
+			ini->stat_radio_params_2.rx_rssi_process_compens[i]);
+	printf("\n");
+
+	printf("tx trace: %02X\n",
+		ini->stat_radio_params_2.tx_trace_loss);
+
+	printf("Dynamic 2.4 band params for FEM\n");
+
+	printf("Static 5 band params:\n");
+
+	printf("rx trace insertion loss:");
+	for (i = 0; i < WL1271_INI_SUB_BAND_COUNT_5; i++)
+		printf(" %02X",
+			ini->stat_radio_params_5.rx_rssi_process_compens[i]);
+	printf("\n");
+
+	printf("rx rssi n process compensation:");
+	for (i = 0; i < WL1271_INI_RSSI_PROCESS_COMPENS_SIZE; i++)
+		printf(" %02X",
+			ini->stat_radio_params_5.rx_rssi_process_compens[i]);
+	printf("\n");
+
+	printf("tx trace:");
+	for (i = 0; i < WL1271_INI_SUB_BAND_COUNT_5; i++)
+		printf(" %02X",
+			ini->stat_radio_params_5.tx_trace_loss[i]);
+	printf("\n");
+
+	printf("Dynamic 5 band params for FEM\n");
+
+}
+#endif
+
+static struct wl12xx_parse_ops wl1271_parse_ops = {
+	.prs_general_prms       = parse_general_prms,
+	.prs_band2_prms         = parse_band2_prms,
+	.prs_band5_prms         = parse_band5_prms,
+	.prs_fem0_band2_prms    = parse_fem0_band2_prms,
+	.prs_fem1_band2_prms    = parse_fem1_band2_prms,
+	.prs_fem1_band5_prms    = parse_fem1_band5_prms,
+};
+
+static struct wl12xx_parse_ops wl128x_parse_ops = {
+	.prs_general_prms       = parse_general_prms_128x,
+	.prs_band2_prms         = parse_band2_prms_128x,
+	.prs_band5_prms         = parse_band5_prms_128x,
+	.prs_fem0_band2_prms    = parse_fem0_band2_prms_128x,
+	.prs_fem1_band2_prms    = parse_fem1_band2_prms_128x,
+	.prs_fem1_band5_prms    = parse_fem1_band5_prms_128x,
+};
+
+int nvs_get_arch(int file_size, struct wl12xx_common *cmn)
+{
+	enum wl12xx_arch arch = UNKNOWN_ARCH;
+
+	switch (file_size) {
+		case WL127X_NVS_FILE_SZ:
+			arch = WL1271_ARCH;
+			cmn->parse_ops = &wl1271_parse_ops;
+			break;
+		case WL128X_NVS_FILE_SZ:
+			arch = WL128X_ARCH;
+			cmn->parse_ops = &wl128x_parse_ops;
+			break;
+	}
+
+	if (cmn->arch != UNKNOWN_ARCH && cmn->arch != arch) {
+		cmn->parse_ops = NULL;
+		return 1;
+	}
+
+	cmn->arch = arch;
+
+	return 0;
+}
+
+static int ini_get_arch(FILE *f, struct wl12xx_common *cmn)
+{
+	char buf[1024], *pos;
+	int line = 0;
+	enum wl12xx_arch arch = UNKNOWN_ARCH;
+
+	while (ini_get_line(buf, sizeof(buf), f, &line, &pos)) {
+		if (strncmp("TCXO_Clk", pos, 8) == 0) {
+			arch = WL128X_ARCH;
+			break;
+		}
+	}
+
+	if (arch == UNKNOWN_ARCH) {
+		arch = WL1271_ARCH;
+        }
+
+	if (cmn->arch != UNKNOWN_ARCH && cmn->arch != arch) {
+		return 1;
+        }
+
+	cmn->arch = arch;
+
+	if (cmn->arch == WL1271_ARCH) {
+		cmn->parse_ops = &wl1271_parse_ops;
+        } else {
+		cmn->parse_ops = &wl128x_parse_ops;
+        }
+
+	fseek(f, 0L, SEEK_SET);
+
+	return 0;
+}
+
+int read_ini(const char *filename, struct wl12xx_common *cmn)
+{
+	FILE *f;
+	char buf[1024], *pos;
+	int ret = 0, line = 0;
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		fprintf(stderr, "Unable to open file %s (%s)\n",
+			filename, strerror(errno));
+		return 1;
+	}
+
+	/* check if it 127x or 128x */
+	if (ini_get_arch(f, cmn)) {
+		fprintf(stderr, "Unable to define wireless architecture\n");
+		ret = 1;
+		goto out;
+	}
+
+	/* start parsing */
+	while (ini_get_line(buf, sizeof(buf), f, &line, &pos)) {
+		ret = ini_parse_line(pos, line, cmn);
+		if (ret) break;
+	}
+
+out:
+	fclose(f);
+#if 0
+	ini_dump(ini);
+#endif
+	return ret;
+}
diff --git a/mac80211/ti-utils/ini.h b/mac80211/ti-utils/ini.h
new file mode 100644
index 0000000..9bc34d0
--- /dev/null
+++ b/mac80211/ti-utils/ini.h
@@ -0,0 +1,327 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __INI_H__
+#define __INI_H__
+
+#include <linux/limits.h>
+
+#define WL1271_INI_MAX_SMART_REFLEX_PARAM 16
+
+struct wl1271_ini_general_params {
+unsigned char ref_clock;
+unsigned char settling_time;
+unsigned char clk_valid_on_wakeup;
+unsigned char dc2dc_mode;
+unsigned char dual_mode_select;
+unsigned char tx_bip_fem_auto_detect;
+unsigned char tx_bip_fem_manufacturer;
+unsigned char general_settings;
+unsigned char sr_state;
+unsigned char srf1[WL1271_INI_MAX_SMART_REFLEX_PARAM];
+unsigned char srf2[WL1271_INI_MAX_SMART_REFLEX_PARAM];
+unsigned char srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM];
+} __attribute__((packed));
+
+#define WL128X_INI_MAX_SETTINGS_PARAM 4
+
+struct wl128x_ini_general_params {
+unsigned char ref_clock;
+unsigned char settling_time;
+unsigned char clk_valid_on_wakeup;
+unsigned char tcxo_ref_clock;
+unsigned char tcxo_settling_time;
+unsigned char tcxo_valid_on_wakeup;
+unsigned char tcxo_ldo_voltage;
+unsigned char xtal_itrim_val;
+unsigned char platform_conf;
+unsigned char dual_mode_select;
+unsigned char tx_bip_fem_auto_detect;
+unsigned char tx_bip_fem_manufacturer;
+unsigned char general_settings[WL128X_INI_MAX_SETTINGS_PARAM];
+unsigned char sr_state;
+unsigned char srf1[WL1271_INI_MAX_SMART_REFLEX_PARAM];
+unsigned char srf2[WL1271_INI_MAX_SMART_REFLEX_PARAM];
+unsigned char srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM];
+} __attribute__((packed));
+
+#define WL1271_INI_RSSI_PROCESS_COMPENS_SIZE 15
+
+struct wl1271_ini_band_params_2 {
+unsigned char rx_trace_insertion_loss;
+unsigned char tx_trace_loss;
+unsigned char
+rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
+} __attribute__((packed));
+
+#define WL1271_INI_CHANNEL_COUNT_2 14
+
+struct wl128x_ini_band_params_2 {
+unsigned char rx_trace_insertion_loss;
+unsigned char tx_trace_loss[WL1271_INI_CHANNEL_COUNT_2];
+unsigned char
+rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
+} __attribute__((packed));
+
+#define WL1271_INI_RATE_GROUP_COUNT 6
+
+struct wl1271_ini_fem_params_2 {
+__le16 tx_bip_ref_pd_voltage;
+unsigned char tx_bip_ref_power;
+unsigned char tx_bip_ref_offset;
+unsigned char
+tx_per_rate_pwr_limits_normal[WL1271_INI_RATE_GROUP_COUNT];
+unsigned char
+tx_per_rate_pwr_limits_degraded[WL1271_INI_RATE_GROUP_COUNT];
+unsigned char
+tx_per_rate_pwr_limits_extreme[WL1271_INI_RATE_GROUP_COUNT];
+unsigned char tx_per_chan_pwr_limits_11b[WL1271_INI_CHANNEL_COUNT_2];
+unsigned char tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_2];
+unsigned char tx_pd_vs_rate_offsets[WL1271_INI_RATE_GROUP_COUNT];
+unsigned char tx_ibias[WL1271_INI_RATE_GROUP_COUNT];
+unsigned char rx_fem_insertion_loss;
+unsigned char degraded_low_to_normal_thr;
+unsigned char normal_to_degraded_high_thr;
+} __attribute__((packed));
+
+#define WL128X_INI_RATE_GROUP_COUNT 7
+/* low and high temperatures*/
+#define WL128X_INI_PD_VS_TEMPERATURE_RANGES 2
+
+struct wl128x_ini_fem_params_2 {
+__le16 tx_bip_ref_pd_voltage;
+unsigned char tx_bip_ref_power;
+unsigned char tx_bip_ref_offset;
+unsigned char
+tx_per_rate_pwr_limits_normal [WL128X_INI_RATE_GROUP_COUNT];
+unsigned char
+tx_per_rate_pwr_limits_degraded [WL128X_INI_RATE_GROUP_COUNT];
+unsigned char
+tx_per_rate_pwr_limits_extreme [WL128X_INI_RATE_GROUP_COUNT];
+unsigned char tx_per_chan_pwr_limits_11b[WL1271_INI_CHANNEL_COUNT_2];
+unsigned char tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_2];
+unsigned char tx_pd_vs_rate_offsets[WL128X_INI_RATE_GROUP_COUNT];
+unsigned char tx_ibias[WL128X_INI_RATE_GROUP_COUNT + 1];
+unsigned char tx_pd_vs_chan_offsets[WL1271_INI_CHANNEL_COUNT_2];
+unsigned char tx_pd_vs_temperature[WL128X_INI_PD_VS_TEMPERATURE_RANGES];
+unsigned char rx_fem_insertion_loss;
+unsigned char degraded_low_to_normal_thr;
+unsigned char normal_to_degraded_high_thr;
+} __attribute__((packed));
+
+#define WL1271_INI_CHANNEL_COUNT_5 35
+#define WL1271_INI_SUB_BAND_COUNT_5 7
+
+struct wl1271_ini_band_params_5 {
+unsigned char rx_trace_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5];
+unsigned char tx_trace_loss[WL1271_INI_SUB_BAND_COUNT_5];
+unsigned char
+rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
+} __attribute__((packed));
+
+struct wl128x_ini_band_params_5 {
+unsigned char rx_trace_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5];
+unsigned char tx_trace_loss[WL1271_INI_CHANNEL_COUNT_5];
+unsigned char
+rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
+} __attribute__((packed));
+
+struct wl1271_ini_fem_params_5 {
+__le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5];
+unsigned char tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5];
+unsigned char tx_bip_ref_offset[WL1271_INI_SUB_BAND_COUNT_5];
+unsigned char
+tx_per_rate_pwr_limits_normal[WL1271_INI_RATE_GROUP_COUNT];
+unsigned char
+tx_per_rate_pwr_limits_degraded[WL1271_INI_RATE_GROUP_COUNT];
+unsigned char
+tx_per_rate_pwr_limits_extreme[WL1271_INI_RATE_GROUP_COUNT];
+unsigned char tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_5];
+unsigned char tx_pd_vs_rate_offsets[WL1271_INI_RATE_GROUP_COUNT];
+unsigned char tx_ibias[WL1271_INI_RATE_GROUP_COUNT];
+unsigned char rx_fem_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5];
+unsigned char degraded_low_to_normal_thr;
+unsigned char normal_to_degraded_high_thr;
+} __attribute__((packed));
+
+struct wl128x_ini_fem_params_5 {
+__le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5];
+unsigned char tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5];
+unsigned char tx_bip_ref_offset[WL1271_INI_SUB_BAND_COUNT_5];
+unsigned char
+tx_per_rate_pwr_limits_normal [WL128X_INI_RATE_GROUP_COUNT];
+unsigned char
+tx_per_rate_pwr_limits_degraded [WL128X_INI_RATE_GROUP_COUNT];
+unsigned char
+tx_per_rate_pwr_limits_extreme [WL128X_INI_RATE_GROUP_COUNT];
+unsigned char tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_5];
+unsigned char tx_pd_vs_rate_offsets[WL128X_INI_RATE_GROUP_COUNT];
+unsigned char tx_ibias[WL128X_INI_RATE_GROUP_COUNT];
+unsigned char tx_pd_vs_chan_offsets[WL1271_INI_CHANNEL_COUNT_5];
+unsigned char tx_pd_vs_temperature[WL1271_INI_SUB_BAND_COUNT_5 *
+WL128X_INI_PD_VS_TEMPERATURE_RANGES];
+unsigned char rx_fem_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5];
+unsigned char degraded_low_to_normal_thr;
+unsigned char normal_to_degraded_high_thr;
+} __attribute__((packed));
+
+/* NVS data structure */
+#define WL1271_INI_NVS_SECTION_SIZE     468
+#define WL1271_INI_FEM_MODULE_COUNT                  2
+
+#define WL1271_INI_LEGACY_NVS_FILE_SIZE              800
+
+struct wl1271_nvs_file {
+/* NVS section */
+unsigned char nvs[WL1271_INI_NVS_SECTION_SIZE];
+
+/* INI section */
+struct wl1271_ini_general_params general_params;
+unsigned char padding1;
+struct wl1271_ini_band_params_2 stat_radio_params_2;
+unsigned char padding2;
+struct {
+struct wl1271_ini_fem_params_2 params;
+unsigned char padding;
+} dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT];
+struct wl1271_ini_band_params_5 stat_radio_params_5;
+unsigned char padding3;
+struct {
+struct wl1271_ini_fem_params_5 params;
+unsigned char padding;
+} dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT];
+} __attribute__((packed));
+
+struct wl128x_nvs_file {
+/* NVS section */
+unsigned char nvs[WL1271_INI_NVS_SECTION_SIZE];
+
+/* INI section */
+struct wl128x_ini_general_params general_params;
+unsigned char fem_vendor_and_options;
+struct wl128x_ini_band_params_2 stat_radio_params_2;
+unsigned char padding2;
+struct {
+struct wl128x_ini_fem_params_2 params;
+unsigned char padding;
+} dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT];
+struct wl128x_ini_band_params_5 stat_radio_params_5;
+unsigned char padding3;
+struct {
+struct wl128x_ini_fem_params_5 params;
+unsigned char padding;
+} dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT];
+} __attribute__((packed));
+
+struct wl1271_ini {
+struct wl1271_ini_general_params general_params;
+unsigned char padding1;
+struct wl1271_ini_band_params_2 stat_radio_params_2;
+unsigned char padding2;
+struct {
+struct wl1271_ini_fem_params_2 params;
+unsigned char padding;
+} dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT];
+struct wl1271_ini_band_params_5 stat_radio_params_5;
+unsigned char padding3;
+struct {
+struct wl1271_ini_fem_params_5 params;
+unsigned char padding;
+} dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT];
+} __attribute__((packed));
+
+struct wl128x_ini {
+struct wl128x_ini_general_params general_params;
+unsigned char fem_vendor_and_options;
+struct wl128x_ini_band_params_2 stat_radio_params_2;
+unsigned char padding2;
+struct {
+struct wl128x_ini_fem_params_2 params;
+unsigned char padding;
+} dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT];
+struct wl128x_ini_band_params_5 stat_radio_params_5;
+unsigned char padding3;
+struct {
+struct wl128x_ini_fem_params_5 params;
+unsigned char padding;
+} dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT];
+} __attribute__((packed));
+
+enum wl1271_ini_section {
+UKNOWN_SECTION,
+GENERAL_PRMS,
+FEM_PRMS,
+BAND2_PRMS,
+BAND5_PRMS,
+FEM0_BAND2_PRMS,
+FEM1_BAND2_PRMS,
+FEM1_BAND5_PRMS
+};
+
+enum wl12xx_arch {
+UNKNOWN_ARCH,
+WL1271_ARCH,
+WL128X_ARCH
+};
+
+struct wl12xx_ini {
+union {
+struct wl1271_ini ini1271;
+struct wl128x_ini ini128x;
+};
+};
+
+#define DUAL_MODE_UNSET    0xff
+#define NO_FEM_PARSED      0xff
+
+struct wl12xx_common {
+enum wl12xx_arch arch;
+unsigned char dual_mode;
+unsigned char done_fem; /* Number of FEM already parsed */
+struct wl12xx_parse_ops *parse_ops;
+struct wl12xx_nvs_ops   *nvs_ops;
+struct wl12xx_ini ini;
+};
+
+struct wl12xx_parse_ops {
+int (*prs_general_prms)(char *l, struct wl12xx_common *cmn,
+struct wl12xx_ini *p);
+/* int (*prs_fem_prms)(char *l, void *gp); */
+int (*prs_band2_prms)(char *l, struct wl12xx_ini *p);
+int (*prs_band5_prms)(char *l, struct wl12xx_ini *p);
+int (*prs_fem0_band2_prms)(char *l, struct wl12xx_ini *p);
+int (*prs_fem1_band2_prms)(char *l, struct wl12xx_ini *p);
+int (*prs_fem1_band5_prms)(char *l, struct wl12xx_ini *p);
+};
+
+struct wl12xx_nvs_ops {
+int (*nvs_fill_radio_prms)(int fd, struct wl12xx_ini *p, char *buf);
+int (*nvs_set_autofem)(int fd, char *buf, unsigned char val);
+int (*nvs_set_fem_manuf)(int fd, char *buf, unsigned char val);
+};
+
+int nvs_get_arch(int file_size, struct wl12xx_common *cmn);
+
+int read_ini(const char *filename, struct wl12xx_common *cmn);
+
+#endif
diff --git a/mac80211/ti-utils/ini_files/127x/RFMD_S_3.5.ini b/mac80211/ti-utils/ini_files/127x/RFMD_S_3.5.ini
new file mode 100755
index 0000000..4587369
--- /dev/null
+++ b/mac80211/ti-utils/ini_files/127x/RFMD_S_3.5.ini
@@ -0,0 +1,63 @@
+# INI Generator version 1.4; Aligned to TS version 6.1.2.0.27
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1:   Non FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.1: General parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+TXBiPFEMAutoDetect  = 00 # Length: 1; Unit: Options (0: Manual Mode, 1: Automatic mode); Format: Unsigned; Source: Customer; Comment: This parameter is used by the FW to decide if the front-end is determined automatically or manually
+TXBiPFEMManufacturer  = 00 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit1,0: used to determine which FEM vendor type is used on the platform (0: RFMD, 1: TQS, 2:SKW, 3:HP), Bit3,2: unused, Bit7-4:External/internal load (4-SKW SB, 5-SKW HB, 6-HP SB, 7-HP HB)
+RefClk  = 02 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit 0,1,2-0:19.2MHz,1:26MHz,2:38.4MHz[Default],3:52MHz,4:38.4MHz XTAL,5:26MHz XTAL, Bit 3-CLK_REQ type, 0=wired-OR, 1=push-pull, Bit 4-CLK_REQ polarity
+SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid FREF clock on the device inputs
+ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the FREF clock is valid on wakeup
+DC2DCMode  = 00 # Length: 1; Unit: Bit_Options; Format: Unsigned, Source: Customer; Comment: Bit0 - DC2DC mode (0: btSPI is not used;1: btSPI used mux DC2DC to BT_FUNC2), Bit1- Level shifter support (0: No LS, 1: With LS)
+Single_Dual_Band_Solution  = 00 # Length: 1; Unit: Options (0: Single band, 1: Dual band); Format: Unsigned; Source: Customer; Comment: This parameter indicates if the solution is single band (2.4GHz only) or dual band (2.4GHz & 5GHz)
+Settings  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit0-NBI(0:Off,1:On),Bit1-Telec ch14(0:Off,1:On),Bit2-FEM0-LB,Bit3-FEM0-HB,Bit4-FEM1-LB,Bit5-FEM1-HB-TX BiP load(0:Int.,1:Ext.),Bit6-LPD LB,Bit7-LPD HB
+SRState = 00 # Length: 1; Unit: Options (0: Disabled, 1: Enabled); Format: Decimal; Source: TI; Comment: Smart Reflax (proprietary mechanism of TI that identify the silicon process specific params) state
+SRF1 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 0F 3F  # Length: 16; Unit: SRF1 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF2 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SRF2 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF3 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SRF3 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+#SR_Debug_Table = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SR_Debug_Table values; Format: Signed; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P = 22 # Length: 1; Unit: SR_SEN_N_P values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P_Gain = a9 # Length: 1; Unit: SR_SEN_N_P_GAIN values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_NRN = c1 # Length: 1; Unit: SR_SEN_NRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#SR_SEN_PRN = 8d # Length: 1; Unit: SR_SEN_PRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2: Band-dependant parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TXTraceLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+RxRssiAndProcessCompensation_2_4G  = EC F6 00 0C 18 F8 FC 00 08 10 F0 F8 00 0A 14 # Length: 15; Unit: 1/8dB; Format: Signed; Source: TI; Comment: The RSSI corner points are determined during RSSI temperature and process characterization
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2:     FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1:   FEM parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM0_TXBiPReferencePDvoltage_2_4G = 0136 # Length: 1; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM0_TxBiPReferencePower_2_4G  = 80 # Length: 1; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage .
+FEM0_TxBiPOffsetdB_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM0_TxPerRatePowerLimits_2_4G_Normal = 1D 1F 22 26 27 29 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM0_TxPerRatePowerLimits_2_4G_Degraded = 19 1F 22 25 25 27 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM0_TxPerRatePowerLimits_2_4G_Extreme = 16 1D 1E 20 24 25 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM0_DegradedLowToNormalThr_2_4G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM0_NormalToDegradedHighThr_2_4G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM0_TxPerChannelPowerLimits_2_4G_11b = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM0_TxPerChannelPowerLimits_2_4G_OFDM = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM0_TxPDVsRateOffsets_2_4G = 01 02 02 02 02 00 # Length: 6; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM0_TxIbiasTable_2_4G  = 31 31 36 36 3b 3b # Length: 6; Unit: Codeword ; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM. Options (MCS7, 54/48, 36/24, 18/12, 9/6, 11b)
+FEM0_RxFemInsertionLoss_2_4G  = 0E # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL127x
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+
diff --git a/mac80211/ti-utils/ini_files/127x/TQS_D_1.0.ini b/mac80211/ti-utils/ini_files/127x/TQS_D_1.0.ini
new file mode 100755
index 0000000..a908c6d
--- /dev/null
+++ b/mac80211/ti-utils/ini_files/127x/TQS_D_1.0.ini
@@ -0,0 +1,78 @@
+# INI Generator version 1.4; Aligned to TS version 6.1.2.0.27
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1:   Non FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.1: General parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+TXBiPFEMAutoDetect  = 00 # Length: 1; Unit: Options (0: Manual Mode, 1: Automatic mode); Format: Unsigned; Source: Customer; Comment: This parameter is used by the FW to decide if the front-end is determined automatically or manually
+TXBiPFEMManufacturer  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit1,0: used to determine which FEM vendor type is used on the platform (0: RFMD, 1: TQS, 2:SKW, 3:HP), Bit3,2: unused, Bit7-4:External/internal load (4-SKW SB, 5-SKW HB, 6-HP SB, 7-HP HB)
+RefClk  = 02 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit 0,1,2-0:19.2MHz,1:26MHz,2:38.4MHz[Default],3:52MHz,4:38.4MHz XTAL,5:26MHz XTAL, Bit 3-CLK_REQ type, 0=wired-OR, 1=push-pull, Bit 4-CLK_REQ polarity
+SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid FREF clock on the device inputs
+ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the FREF clock is valid on wakeup
+DC2DCMode  = 00 # Length: 1; Unit: Bit_Options; Format: Unsigned, Source: Customer; Comment: Bit0 - DC2DC mode (0: btSPI is not used;1: btSPI used mux DC2DC to BT_FUNC2), Bit1- Level shifter support (0: No LS, 1: With LS)
+Single_Dual_Band_Solution  = 01 # Length: 1; Unit: Options (0: Single band, 1: Dual band); Format: Unsigned; Source: Customer; Comment: This parameter indicates if the solution is single band (2.4GHz only) or dual band (2.4GHz & 5GHz)
+Settings  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit0-NBI(0:Off,1:On),Bit1-Telec ch14(0:Off,1:On),Bit2-FEM0-LB,Bit3-FEM0-HB,Bit4-FEM1-LB,Bit5-FEM1-HB-TX BiP load(0:Int.,1:Ext.),Bit6-LPD LB,Bit7-LPD HB
+SRState = 00 # Length: 1; Unit: Options (0: Disabled, 1: Enabled); Format: Decimal; Source: TI; Comment: Smart Reflax (proprietary mechanism of TI that identify the silicon process specific params) state
+SRF1 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 0F 3F  # Length: 16; Unit: SRF1 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF2 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SRF2 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF3 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SRF3 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+#SR_Debug_Table = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SR_Debug_Table values; Format: Signed; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P = 22 # Length: 1; Unit: SR_SEN_N_P values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P_Gain = a9 # Length: 1; Unit: SR_SEN_N_P_GAIN values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_NRN = c1 # Length: 1; Unit: SR_SEN_NRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#SR_SEN_PRN = 8d # Length: 1; Unit: SR_SEN_PRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2: Band-dependant parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TXTraceLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+RxRssiAndProcessCompensation_2_4G  = EC F6 00 0C 18 F8 FC 00 08 10 F0 F8 00 0A 14 # Length: 15; Unit: 1/8dB; Format: Signed; Source: TI; Comment: The RSSI corner points are determined during RSSI temperature and process characterization
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_5G  = 00 00 00 00 00 00 00 # Length: 7; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TXTraceLoss_5G  = 00 00 00 00 00 00 00 # Length: 7; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+RxRssiAndProcessCompensation_5G  = EE F4 F8 FE 05 EA F3 FA 01 06 E5 F1 FA 02 07  # Length: 15; Unit: 1/8dB; Format: Signed; Source: TI; Comment: The RSSI corner points are determined during RSSI temperature and process characterization
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2:     FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1:   FEM parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM1_TXBiPReferencePDvoltage_2_4G = 01E0 # Length: 1; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM1_TxBiPReferencePower_2_4G  = 80 # Length: 1; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage .
+FEM1_TxBiPOffsetdB_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM1_TxPerRatePowerLimits_2_4G_Normal = 1D 1F 22 26 28 29 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Degraded = 1A 1F 22 24 26 28 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Extreme = 16 1D 1E 20 24 25 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_DegradedLowToNormalThr_2_4G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_NormalToDegradedHighThr_2_4G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerChannelPowerLimits_2_4G_11b = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPerChannelPowerLimits_2_4G_OFDM = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPDVsRateOffsets_2_4G = 01 02 02 02 02 00 # Length: 6; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM1_TxIbiasTable_2_4G  = 15 15 15 19 19 15 # Length: 6; Unit: Codeword ; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM. Options (MCS7, 54/48, 36/24, 18/12, 9/6, 11b)
+FEM1_RxFemInsertionLoss_2_4G  = 10 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL127x
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM1_TXBiPReferencePDvoltage_5G  = 0173 0188 0187 018B 018A 0186 018C # Length: 7; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM1_TxBiPReferencePower_5G = 80 80 80 80 80 80 80 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage .
+FEM1_TxBiPOffsetdB_5G = 00 00 00 00 00 00 00 # Length: 7; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM1_TxPerRatePowerLimits_5G_Normal  = 1C 1F 22 24 24 50 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_5G_Degraded  = 18 1F 22 22 22 50 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_5G_Extreme = 16 1C 1E 20 20 50 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_DegradedLowToNormalThr_5G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_NormalToDegradedHighThr_5G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerChannelPowerLimits_5G_OFDM  = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 35; Unit: 1/2dB; Format: Signed; Source: Customer;
+FEM1_TxPDVsRateOffsets_5G  = 01 02 02 02 02 00 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM1_TxIbiasTable_5G  = 10 10 10 10 10 10 # Length: 6; Unit: Codeword; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM
+FEM1_RxFemInsertionLoss_5G  = 10 10 10 10 10 10 10 # Length: 7; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL127x
+
diff --git a/mac80211/ti-utils/ini_files/127x/TQS_D_1.7.ini b/mac80211/ti-utils/ini_files/127x/TQS_D_1.7.ini
new file mode 100755
index 0000000..ea986f9
--- /dev/null
+++ b/mac80211/ti-utils/ini_files/127x/TQS_D_1.7.ini
@@ -0,0 +1,78 @@
+# INI Generator version 1.4; Aligned to TS version 6.1.2.0.27
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1:   Non FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.1: General parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+TXBiPFEMAutoDetect  = 00 # Length: 1; Unit: Options (0: Manual Mode, 1: Automatic mode); Format: Unsigned; Source: Customer; Comment: This parameter is used by the FW to decide if the front-end is determined automatically or manually
+TXBiPFEMManufacturer  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit1,0: used to determine which FEM vendor type is used on the platform (0: RFMD, 1: TQS, 2:SKW, 3:HP), Bit3,2: unused, Bit7-4:External/internal load (4-SKW SB, 5-SKW HB, 6-HP SB, 7-HP HB)
+RefClk  = 02 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit 0,1,2-0:19.2MHz,1:26MHz,2:38.4MHz[Default],3:52MHz,4:38.4MHz XTAL,5:26MHz XTAL, Bit 3-CLK_REQ type, 0=wired-OR, 1=push-pull, Bit 4-CLK_REQ polarity
+SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid FREF clock on the device inputs
+ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the FREF clock is valid on wakeup
+DC2DCMode  = 00 # Length: 1; Unit: Bit_Options; Format: Unsigned, Source: Customer; Comment: Bit0 - DC2DC mode (0: btSPI is not used;1: btSPI used mux DC2DC to BT_FUNC2), Bit1- Level shifter support (0: No LS, 1: With LS)
+Single_Dual_Band_Solution  = 01 # Length: 1; Unit: Options (0: Single band, 1: Dual band); Format: Unsigned; Source: Customer; Comment: This parameter indicates if the solution is single band (2.4GHz only) or dual band (2.4GHz & 5GHz)
+Settings  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit0-NBI(0:Off,1:On),Bit1-Telec ch14(0:Off,1:On),Bit2-FEM0-LB,Bit3-FEM0-HB,Bit4-FEM1-LB,Bit5-FEM1-HB-TX BiP load(0:Int.,1:Ext.),Bit6-LPD LB,Bit7-LPD HB
+SRState = 00 # Length: 1; Unit: Options (0: Disabled, 1: Enabled); Format: Decimal; Source: TI; Comment: Smart Reflax (proprietary mechanism of TI that identify the silicon process specific params) state
+SRF1 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 0F 3F  # Length: 16; Unit: SRF1 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF2 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SRF2 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF3 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SRF3 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+#SR_Debug_Table = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SR_Debug_Table values; Format: Signed; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P = 22 # Length: 1; Unit: SR_SEN_N_P values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P_Gain = a9 # Length: 1; Unit: SR_SEN_N_P_GAIN values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_NRN = c1 # Length: 1; Unit: SR_SEN_NRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#SR_SEN_PRN = 8d # Length: 1; Unit: SR_SEN_PRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2: Band-dependant parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TXTraceLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+RxRssiAndProcessCompensation_2_4G  = EC F6 00 0C 18 F8 FC 00 08 10 F0 F8 00 0A 14 # Length: 15; Unit: 1/8dB; Format: Signed; Source: TI; Comment: The RSSI corner points are determined during RSSI temperature and process characterization
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_5G  = 00 00 00 00 00 00 00 # Length: 7; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TXTraceLoss_5G  = 00 00 00 00 00 00 00 # Length: 7; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+RxRssiAndProcessCompensation_5G  = EE F4 F8 FE 05 EA F3 FA 01 06 E5 F1 FA 02 07  # Length: 15; Unit: 1/8dB; Format: Signed; Source: TI; Comment: The RSSI corner points are determined during RSSI temperature and process characterization
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2:     FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1:   FEM parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM1_TXBiPReferencePDvoltage_2_4G = 01D9 # Length: 1; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM1_TxBiPReferencePower_2_4G  = 80 # Length: 1; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage .
+FEM1_TxBiPOffsetdB_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM1_TxPerRatePowerLimits_2_4G_Normal = 1D 1F 22 26 27 29 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Degraded = 1D 1F 22 26 27 27 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Extreme = 16 1D 1E 20 24 25 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_DegradedLowToNormalThr_2_4G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_NormalToDegradedHighThr_2_4G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerChannelPowerLimits_2_4G_11b = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPerChannelPowerLimits_2_4G_OFDM = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPDVsRateOffsets_2_4G = 01 02 02 02 02 00 # Length: 6; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM1_TxIbiasTable_2_4G  = 15 15 15 19 19 15 # Length: 6; Unit: Codeword ; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM. Options (MCS7, 54/48, 36/24, 18/12, 9/6, 11b)
+FEM1_RxFemInsertionLoss_2_4G  = 10 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL127x
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM1_TXBiPReferencePDvoltage_5G  = 019A 01AE 01C2 01CC 01DB 01DB 01D1 # Length: 7; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM1_TxBiPReferencePower_5G = 80 80 80 80 80 80 80 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage .
+FEM1_TxBiPOffsetdB_5G = 00 00 00 00 00 00 00 # Length: 7; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM1_TxPerRatePowerLimits_5G_Normal  = 1C 1E 21 23 25 50 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_5G_Degraded  = 18 1E 21 23 25 50 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_5G_Extreme = 16 1C 1E 20 20 50 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_DegradedLowToNormalThr_5G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_NormalToDegradedHighThr_5G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerChannelPowerLimits_5G_OFDM  = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 35; Unit: 1/2dB; Format: Signed; Source: Customer;
+FEM1_TxPDVsRateOffsets_5G  = 01 02 02 02 02 00 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM1_TxIbiasTable_5G  = 10 10 10 10 10 10 # Length: 6; Unit: Codeword; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM
+FEM1_RxFemInsertionLoss_5G  = 10 10 10 10 10 10 10 # Length: 7; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL127x
+
diff --git a/mac80211/ti-utils/ini_files/127x/TQS_S_2.5.ini b/mac80211/ti-utils/ini_files/127x/TQS_S_2.5.ini
new file mode 100755
index 0000000..f1813cf
--- /dev/null
+++ b/mac80211/ti-utils/ini_files/127x/TQS_S_2.5.ini
@@ -0,0 +1,63 @@
+# INI Generator version 1.4; Aligned to TS version 6.1.2.0.27
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1:   Non FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.1: General parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+TXBiPFEMAutoDetect  = 00 # Length: 1; Unit: Options (0: Manual Mode, 1: Automatic mode); Format: Unsigned; Source: Customer; Comment: This parameter is used by the FW to decide if the front-end is determined automatically or manually
+TXBiPFEMManufacturer  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit1,0: used to determine which FEM vendor type is used on the platform (0: RFMD, 1: TQS, 2:SKW, 3:HP), Bit3,2: unused, Bit7-4:External/internal load (4-SKW SB, 5-SKW HB, 6-HP SB, 7-HP HB)
+RefClk  = 02 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit 0,1,2-0:19.2MHz,1:26MHz,2:38.4MHz[Default],3:52MHz,4:38.4MHz XTAL,5:26MHz XTAL, Bit 3-CLK_REQ type, 0=wired-OR, 1=push-pull, Bit 4-CLK_REQ polarity
+SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid FREF clock on the device inputs
+ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the FREF clock is valid on wakeup
+DC2DCMode  = 00 # Length: 1; Unit: Bit_Options; Format: Unsigned, Source: Customer; Comment: Bit0 - DC2DC mode (0: btSPI is not used;1: btSPI used mux DC2DC to BT_FUNC2), Bit1- Level shifter support (0: No LS, 1: With LS)
+Single_Dual_Band_Solution  = 00 # Length: 1; Unit: Options (0: Single band, 1: Dual band); Format: Unsigned; Source: Customer; Comment: This parameter indicates if the solution is single band (2.4GHz only) or dual band (2.4GHz & 5GHz)
+Settings  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit0-NBI(0:Off,1:On),Bit1-Telec ch14(0:Off,1:On),Bit2-FEM0-LB,Bit3-FEM0-HB,Bit4-FEM1-LB,Bit5-FEM1-HB-TX BiP load(0:Int.,1:Ext.),Bit6-LPD LB,Bit7-LPD HB
+SRState = 00 # Length: 1; Unit: Options (0: Disabled, 1: Enabled); Format: Decimal; Source: TI; Comment: Smart Reflax (proprietary mechanism of TI that identify the silicon process specific params) state
+SRF1 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 0F 3F  # Length: 16; Unit: SRF1 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF2 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SRF2 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF3 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SRF3 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+#SR_Debug_Table = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SR_Debug_Table values; Format: Signed; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P = 22 # Length: 1; Unit: SR_SEN_N_P values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P_Gain = a9 # Length: 1; Unit: SR_SEN_N_P_GAIN values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_NRN = c1 # Length: 1; Unit: SR_SEN_NRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#SR_SEN_PRN = 8d # Length: 1; Unit: SR_SEN_PRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2: Band-dependant parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TXTraceLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+RxRssiAndProcessCompensation_2_4G  = EC F6 00 0C 18 F8 FC 00 08 10 F0 F8 00 0A 14 # Length: 15; Unit: 1/8dB; Format: Signed; Source: TI; Comment: The RSSI corner points are determined during RSSI temperature and process characterization
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2:     FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1:   FEM parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM1_TXBiPReferencePDvoltage_2_4G = 0177 # Length: 1; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM1_TxBiPReferencePower_2_4G  = 80 # Length: 1; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage .
+FEM1_TxBiPOffsetdB_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM1_TxPerRatePowerLimits_2_4G_Normal = 1D 1F 22 26 28 29 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Degraded = 1A 1F 22 24 26 28 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Extreme = 16 1D 1E 20 24 25 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_DegradedLowToNormalThr_2_4G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_NormalToDegradedHighThr_2_4G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerChannelPowerLimits_2_4G_11b = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPerChannelPowerLimits_2_4G_OFDM = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPDVsRateOffsets_2_4G = 01 02 02 02 02 00 # Length: 6; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM1_TxIbiasTable_2_4G  = 11 11 15 11 15 0F # Length: 6; Unit: Codeword ; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM. Options (MCS7, 54/48, 36/24, 18/12, 9/6, 11b)
+FEM1_RxFemInsertionLoss_2_4G  = 0E # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL127x
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+
diff --git a/mac80211/ti-utils/ini_files/127x/TQS_S_2.6.ini b/mac80211/ti-utils/ini_files/127x/TQS_S_2.6.ini
new file mode 100755
index 0000000..d5b0877
--- /dev/null
+++ b/mac80211/ti-utils/ini_files/127x/TQS_S_2.6.ini
@@ -0,0 +1,63 @@
+# INI Generator version 1.4; Aligned to TS version 6.1.2.0.27
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1:   Non FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.1: General parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+TXBiPFEMAutoDetect  = 00 # Length: 1; Unit: Options (0: Manual Mode, 1: Automatic mode); Format: Unsigned; Source: Customer; Comment: This parameter is used by the FW to decide if the front-end is determined automatically or manually
+TXBiPFEMManufacturer  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit1,0: used to determine which FEM vendor type is used on the platform (0: RFMD, 1: TQS, 2:SKW, 3:HP), Bit3,2: unused, Bit7-4:External/internal load (4-SKW SB, 5-SKW HB, 6-HP SB, 7-HP HB)
+RefClk  = 02 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit 0,1,2-0:19.2MHz,1:26MHz,2:38.4MHz[Default],3:52MHz,4:38.4MHz XTAL,5:26MHz XTAL, Bit 3-CLK_REQ type, 0=wired-OR, 1=push-pull, Bit 4-CLK_REQ polarity
+SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid FREF clock on the device inputs
+ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the FREF clock is valid on wakeup
+DC2DCMode  = 00 # Length: 1; Unit: Bit_Options; Format: Unsigned, Source: Customer; Comment: Bit0 - DC2DC mode (0: btSPI is not used;1: btSPI used mux DC2DC to BT_FUNC2), Bit1- Level shifter support (0: No LS, 1: With LS)
+Single_Dual_Band_Solution  = 00 # Length: 1; Unit: Options (0: Single band, 1: Dual band); Format: Unsigned; Source: Customer; Comment: This parameter indicates if the solution is single band (2.4GHz only) or dual band (2.4GHz & 5GHz)
+Settings  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit0-NBI(0:Off,1:On),Bit1-Telec ch14(0:Off,1:On),Bit2-FEM0-LB,Bit3-FEM0-HB,Bit4-FEM1-LB,Bit5-FEM1-HB-TX BiP load(0:Int.,1:Ext.),Bit6-LPD LB,Bit7-LPD HB
+SRState = 00 # Length: 1; Unit: Options (0: Disabled, 1: Enabled); Format: Decimal; Source: TI; Comment: Smart Reflax (proprietary mechanism of TI that identify the silicon process specific params) state
+SRF1 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 0F 3F  # Length: 16; Unit: SRF1 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF2 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SRF2 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF3 = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SRF3 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+#SR_Debug_Table = 09 04 18 10 08 00 F7 EF E7 DF 00 00 00 00 00 00  # Length: 16; Unit: SR_Debug_Table values; Format: Signed; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P = 22 # Length: 1; Unit: SR_SEN_N_P values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P_Gain = a9 # Length: 1; Unit: SR_SEN_N_P_GAIN values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_NRN = c1 # Length: 1; Unit: SR_SEN_NRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#SR_SEN_PRN = 8d # Length: 1; Unit: SR_SEN_PRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2: Band-dependant parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TXTraceLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+RxRssiAndProcessCompensation_2_4G  = EC F6 00 0C 18 F8 FC 00 08 10 F0 F8 00 0A 14 # Length: 15; Unit: 1/8dB; Format: Signed; Source: TI; Comment: The RSSI corner points are determined during RSSI temperature and process characterization
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2:     FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1:   FEM parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM1_TXBiPReferencePDvoltage_2_4G = 0177 # Length: 1; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM1_TxBiPReferencePower_2_4G  = 80 # Length: 1; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage .
+FEM1_TxBiPOffsetdB_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM1_TxPerRatePowerLimits_2_4G_Normal = 1D 1F 22 26 27 29 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Degraded = 1A 1F 22 25 25 27 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Extreme = 16 1D 1E 20 24 25 # Length: 6; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_DegradedLowToNormalThr_2_4G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_NormalToDegradedHighThr_2_4G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temp range in which the FEM is operating
+FEM1_TxPerChannelPowerLimits_2_4G_11b = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPerChannelPowerLimits_2_4G_OFDM = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPDVsRateOffsets_2_4G = 01 02 02 02 02 00 # Length: 6; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM1_TxIbiasTable_2_4G  = 15 15 15 11 15 15 # Length: 6; Unit: Codeword ; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM. Options (MCS7, 54/48, 36/24, 18/12, 9/6, 11b)
+FEM1_RxFemInsertionLoss_2_4G  = 0E # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL127x
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+
diff --git a/mac80211/ti-utils/ini_files/128x/RFMD_S_3.5.ini b/mac80211/ti-utils/ini_files/128x/RFMD_S_3.5.ini
new file mode 100755
index 0000000..f220b17
--- /dev/null
+++ b/mac80211/ti-utils/ini_files/128x/RFMD_S_3.5.ini
@@ -0,0 +1,69 @@
+# INI Generator version 0.5; Aligned to TS version 7.1.2.0.26
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1:   Non FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.1: General parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+TXBiPFEMAutoDetect  = 00 # Length: 1; Unit: Options (0: Manual Mode, 1: Automatic mode); Format: Unsigned; Source: Customer; Comment: This parameter is used by the FW to decide if the front-end is determined automatically or manually
+TXBiPFEMManufacturer  = 00 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit1,0: used to determine which FEM vendor type is used on the platform (0: RFMD, 1: TQS, 2:SKW, 3:HP), Bit3,2: unused, Bit7-4:External/internal load (4-SKW SB, 5-SKW HB, 6-HP SB, 7-HP HB)
+RefClk  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: 5'bXX000 : Bit 0,1,2 - 0: 19.2MHz, 1: 26MHz, 2: 38.4MHz  [Default], 3: 52MHz,  4: 38.4MHz XTAL, 5: 26MHz XTAL ,  5'bX0XXX : Bit 3 - CLK_REQ type,  0 = wired-OR [Default], 1= push-pull ,  5'b0XXXX : Bit 4 - CLK_REQ polarity, 0 = Normal [Default], 1=Inverted
+SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid FREF clock on the device inputs
+ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the FREF clock is valid on wakeup
+TCXO_Clk  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: 5'bXX000 : Bit 0,1,2 - 0: 19.2MHz, 1: 26MHz, 2: 38.4MHz  [Default], 3: 52MHz, 4: 16.368Mhz, 5: 32.736 Mhz 
+TCXO_SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid TCXO clock on the device inputs
+TCXO_ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the TCXO clock is valid on wakeup 
+TCXO_LDO_Voltage = 00 # Length: 1; Unit: Options (0:2.5v, 1:2.55v, 2:2.6v); Format: Unsigned; Source: Customer; Comment: TCXO LDO Voltage 
+Platform_configuration = 02 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer ; Comment: Bit 0: Levelshifter support (0: No LS, 1: With LS), Bit 1,2:Configure IO's [SDIO/wspi] (00- 8mA, 01- 4mA (default), 10- 6mA, 11 - 2mA), Bit 3:Eeprom (0-No Eeprom), Bit 4: SDIO IB Enable sync, Bit 5: SDIO IB Enable async, Bit 6: SDIO IB Enable BlockMode, Bit 7: SDIO High-Speed support
+Single_Dual_Band_Solution  = 00 # Length: 1; Unit: Options (0: 2.5v, 1: 2.55v, 2: 2.6v); Format: Unsigned; Source: Customer; Comment: This field notifies the FW whether the solution is a single-band or dual-band
+Settings  = 00 00 00 00 # Length: 4; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit0: NBI (0: Off, 1: On), Bit1: Telec channel 14 (0: Off, 1: On), Bit2: FEM0-LB, Bit3: FEM0-HB, Bit4: FEM1-LB, Bit5: FEM1-HB - TX BiP load (0: Internal, 1: External), Bit6: LPD Low band, Bit7: LPD High band 
+XTALItrimVal = 04 # Length: 1; Unit: Current trimming for XTAL; Format: Unsigned; Source: TI; Comment: Current trimming for XTAL
+SRState = 00 # Length: 1; Unit: Options (0: Disabled, 1: Enabled); Format: Decimal; Source: TI; Comment: Smart Reflax (proprietary mechanism of TI that identify the silicon process specific params) state
+SRF1 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 0F 3F  # Length: 16; Unit: SRF1 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF2 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SRF2 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF3 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SRF3 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+#SR_Debug_Table = 09 04 19 10 00 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SR_Debug_Table values; Format: Signed; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P = 11 # Length: 1; Unit: SR_SEN_N_P values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P_Gain = AA # Length: 1; Unit: SR_SEN_N_P_GAIN values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_NRN = B6 # Length: 1; Unit: SR_SEN_NRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#SR_SEN_PRN = F0 # Length: 1; Unit: SR_SEN_PRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2: Band-dependant parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TxTraceLoss_2_4G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 14; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2:     FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1:   FEM parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FemVendorAndOptions  = 00 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit 0..1 - 0: RFMD, 1: TQS, 2: SKWS,  Bit 4..7 [Version control] -  0: TQS-S1.0, 1: TQS-S2.0, 2: TQS-S2.5, 3: TQS-D1.0, 4: TQS-D1.5, 5: RFMD-S1.5, 6: RFMD-S2.9, 7: RFMD-S3.0, 8: RFMD-D1.5, 9: RFMD-S2.9.5, 10: RFMD-D3.0.1, 11: TQS-S2.6, 12: TQS-D1.7
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM0_TxBiPReferencePDvoltage_2_4G = 0136 # Length: 1; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM0_TxBiPReferencePower_2_4G  = 80 # Length: 1; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage . The TX BiP reference power is linked to the TX BiP reference PD voltage
+FEM0_TxBiPOffsetdB_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM0_TxPerRatePowerLimits_2_4G_Normal = 1D 1F 22 26 27 29 25 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM0_TxPerRatePowerLimits_2_4G_Degraded = 19 1F 22 25 25 27 23 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM0_TxPerRatePowerLimits_2_4G_Extreme = 16 1D 1E 20 24 25 22 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM0_DegradedLowToNormalThr_2_4G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM0_NormalToDegradedHighThr_2_4G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM0_TxPerChannelPowerLimits_2_4G_11b = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM0_TxPerChannelPowerLimits_2_4G_OFDM = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM0_TxPDVsRateOffsets_2_4G = 01 02 02 02 02 00 02 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM0_TxPDVsChannelOffsets_2_4G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 14; Unit: 1/8dB; Format: Signed; Source: TI/Customer; Comment: This parameter is a power detector offset value used to correct the power detector curve for each channel
+FEM0_TxPDVsTemperature_2_4G = 00 00 # Length: 2; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each temperture
+FEM0_TxIbiasTable_2_4G  = 33 33 38 38 3d 3d 3d 3d # Length: 8; Unit: Codeword ; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM. Options (MCS7, 54/48, 36/24, 18/12, 9/6, 11b, MCS0, 11bCh14)
+FEM0_RxFemInsertionLoss_2_4G  = 0E # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL128x
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+
diff --git a/mac80211/ti-utils/ini_files/128x/TQS_D_1.0.ini b/mac80211/ti-utils/ini_files/128x/TQS_D_1.0.ini
new file mode 100755
index 0000000..3db403e
--- /dev/null
+++ b/mac80211/ti-utils/ini_files/128x/TQS_D_1.0.ini
@@ -0,0 +1,85 @@
+# INI Generator version 0.5; Aligned to TS version 7.1.2.0.26
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1:   Non FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.1: General parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+TXBiPFEMAutoDetect  = 00 # Length: 1; Unit: Options (0: Manual Mode, 1: Automatic mode); Format: Unsigned; Source: Customer; Comment: This parameter is used by the FW to decide if the front-end is determined automatically or manually
+TXBiPFEMManufacturer  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit1,0: used to determine which FEM vendor type is used on the platform (0: RFMD, 1: TQS, 2:SKW, 3:HP), Bit3,2: unused, Bit7-4:External/internal load (4-SKW SB, 5-SKW HB, 6-HP SB, 7-HP HB)
+RefClk  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: 5'bXX000 : Bit 0,1,2 - 0: 19.2MHz, 1: 26MHz, 2: 38.4MHz  [Default], 3: 52MHz,  4: 38.4MHz XTAL, 5: 26MHz XTAL ,  5'bX0XXX : Bit 3 - CLK_REQ type,  0 = wired-OR [Default], 1= push-pull ,  5'b0XXXX : Bit 4 - CLK_REQ polarity, 0 = Normal [Default], 1=Inverted
+SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid FREF clock on the device inputs
+ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the FREF clock is valid on wakeup
+TCXO_Clk  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: 5'bXX000 : Bit 0,1,2 - 0: 19.2MHz, 1: 26MHz, 2: 38.4MHz  [Default], 3: 52MHz, 4: 16.368Mhz, 5: 32.736 Mhz 
+TCXO_SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid TCXO clock on the device inputs
+TCXO_ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the TCXO clock is valid on wakeup 
+TCXO_LDO_Voltage = 00 # Length: 1; Unit: Options (0:2.5v, 1:2.55v, 2:2.6v); Format: Unsigned; Source: Customer; Comment: TCXO LDO Voltage 
+Platform_configuration = 02 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer ; Comment: Bit 0: Levelshifter support (0: No LS, 1: With LS), Bit 1,2:Configure IO's [SDIO/wspi] (00- 8mA, 01- 4mA (default), 10- 6mA, 11 - 2mA), Bit 3:Eeprom (0-No Eeprom), Bit 4: SDIO IB Enable sync, Bit 5: SDIO IB Enable async, Bit 6: SDIO IB Enable BlockMode, Bit 7: SDIO High-Speed support
+Single_Dual_Band_Solution  = 01 # Length: 1; Unit: Options (0: 2.5v, 1: 2.55v, 2: 2.6v); Format: Unsigned; Source: Customer; Comment: This field notifies the FW whether the solution is a single-band or dual-band
+Settings  = 00 00 00 00 # Length: 4; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit0: NBI (0: Off, 1: On), Bit1: Telec channel 14 (0: Off, 1: On), Bit2: FEM0-LB, Bit3: FEM0-HB, Bit4: FEM1-LB, Bit5: FEM1-HB - TX BiP load (0: Internal, 1: External), Bit6: LPD Low band, Bit7: LPD High band 
+XTALItrimVal = 04 # Length: 1; Unit: Current trimming for XTAL; Format: Unsigned; Source: TI; Comment: Current trimming for XTAL
+SRState = 00 # Length: 1; Unit: Options (0: Disabled, 1: Enabled); Format: Decimal; Source: TI; Comment: Smart Reflax (proprietary mechanism of TI that identify the silicon process specific params) state
+SRF1 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 0F 3F  # Length: 16; Unit: SRF1 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF2 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SRF2 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF3 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SRF3 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+#SR_Debug_Table = 09 04 19 10 01 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SR_Debug_Table values; Format: Signed; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P = 11 # Length: 1; Unit: SR_SEN_N_P values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P_Gain = AA # Length: 1; Unit: SR_SEN_N_P_GAIN values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_NRN = B6 # Length: 1; Unit: SR_SEN_NRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#SR_SEN_PRN = F0 # Length: 1; Unit: SR_SEN_PRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2: Band-dependant parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TxTraceLoss_2_4G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 14; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_5G  = 00 00 00 00 00 00 00 # Length: 7; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TxTraceLoss_5G  = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 35; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2:     FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1:   FEM parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FemVendorAndOptions  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit 0..1 - 0: RFMD, 1: TQS, 2: SKWS,  Bit 4..7 [Version control] -  0: TQS-S1.0, 1: TQS-S2.0, 2: TQS-S2.5, 3: TQS-D1.0, 4: TQS-D1.5, 5: RFMD-S1.5, 6: RFMD-S2.9, 7: RFMD-S3.0, 8: RFMD-D1.5, 9: RFMD-S2.9.5, 10: RFMD-D3.0.1, 11: TQS-S2.6, 12: TQS-D1.7
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM1_TxBiPReferencePDvoltage_2_4G = 01A7 # Length: 1; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM1_TxBiPReferencePower_2_4G  = 80 # Length: 1; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage . The TX BiP reference power is linked to the TX BiP reference PD voltage
+FEM1_TxBiPOffsetdB_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM1_TxPerRatePowerLimits_2_4G_Normal = 1D 1F 22 26 27 29 25 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Degraded = 1D 1F 22 26 27 27 24 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Extreme = 16 1D 1E 20 24 25 22 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_DegradedLowToNormalThr_2_4G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_NormalToDegradedHighThr_2_4G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerChannelPowerLimits_2_4G_11b = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPerChannelPowerLimits_2_4G_OFDM = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPDVsRateOffsets_2_4G = 01 02 02 02 02 00 02 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM1_TxPDVsChannelOffsets_2_4G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 14; Unit: 1/8dB; Format: Signed; Source: TI/Customer; Comment: This parameter is a power detector offset value used to correct the power detector curve for each channel
+FEM1_TxPDVsTemperature_2_4G = 00 00 # Length: 2; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each temperture
+FEM1_TxIbiasTable_2_4G  = 15 15 15 19 19 15 19 15 # Length: 8; Unit: Codeword ; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM. Options (MCS7, 54/48, 36/24, 18/12, 9/6, 11b, MCS0, 11bCh14)
+FEM1_RxFemInsertionLoss_2_4G  = 10 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL128x
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM1_TxBiPReferencePDvoltage_5G  = 0173 0188 0187 018B 018A 0186 018C # Length: 7; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM1_TxBiPReferencePower_5G = 80 80 80 80 80 80 80 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage . The TX BiP reference power is linked to the TX BiP reference PD voltage
+FEM1_TxBiPOffsetdB_5G = 00 00 00 00 00 00 00 # Length: 7; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM1_TxPerRatePowerLimits_5G_Normal  = 1C 1E 21 23 25 50 25 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_5G_Degraded  = 18 1E 21 23 25 50 24 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_5G_Extreme = 16 1C 1E 20 20 50 1E # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_DegradedLowToNormalThr_5G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_NormalToDegradedHighThr_5G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerChannelPowerLimits_5G_OFDM  = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 35; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPDVsRateOffsets_5G  = 01 02 02 02 02 00 02 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM1_TxPDVsChannelOffsets_5G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 35; Unit: 1/8dB; Format: Signed; Source: TI/Customer; Comment: This parameter is a power detector offset value used to correct the power detector curve for each channel
+FEM1_TxPDVsTemperature_5G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 14; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each temperture
+FEM1_TxIbiasTable_5G  = 10 10 10 10 10 10 10 # Length: 7; Unit: Codeword; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM
+FEM1_RxFemInsertionLoss_5G  = 10 10 10 10 10 10 10 # Length: 7; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL128x
+
diff --git a/mac80211/ti-utils/ini_files/128x/TQS_D_1.7.ini b/mac80211/ti-utils/ini_files/128x/TQS_D_1.7.ini
new file mode 100755
index 0000000..fb5903c
--- /dev/null
+++ b/mac80211/ti-utils/ini_files/128x/TQS_D_1.7.ini
@@ -0,0 +1,85 @@
+# INI Generator version 0.5; Aligned to TS version 7.1.2.0.26
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1:   Non FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.1: General parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+TXBiPFEMAutoDetect  = 00 # Length: 1; Unit: Options (0: Manual Mode, 1: Automatic mode); Format: Unsigned; Source: Customer; Comment: This parameter is used by the FW to decide if the front-end is determined automatically or manually
+TXBiPFEMManufacturer  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit1,0: used to determine which FEM vendor type is used on the platform (0: RFMD, 1: TQS, 2:SKW, 3:HP), Bit3,2: unused, Bit7-4:External/internal load (4-SKW SB, 5-SKW HB, 6-HP SB, 7-HP HB)
+RefClk  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: 5'bXX000 : Bit 0,1,2 - 0: 19.2MHz, 1: 26MHz, 2: 38.4MHz  [Default], 3: 52MHz,  4: 38.4MHz XTAL, 5: 26MHz XTAL ,  5'bX0XXX : Bit 3 - CLK_REQ type,  0 = wired-OR [Default], 1= push-pull ,  5'b0XXXX : Bit 4 - CLK_REQ polarity, 0 = Normal [Default], 1=Inverted
+SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid FREF clock on the device inputs
+ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the FREF clock is valid on wakeup
+TCXO_Clk  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: 5'bXX000 : Bit 0,1,2 - 0: 19.2MHz, 1: 26MHz, 2: 38.4MHz  [Default], 3: 52MHz, 4: 16.368Mhz, 5: 32.736 Mhz 
+TCXO_SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid TCXO clock on the device inputs
+TCXO_ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the TCXO clock is valid on wakeup 
+TCXO_LDO_Voltage = 00 # Length: 1; Unit: Options (0:2.5v, 1:2.55v, 2:2.6v); Format: Unsigned; Source: Customer; Comment: TCXO LDO Voltage 
+Platform_configuration = 02 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer ; Comment: Bit 0: Levelshifter support (0: No LS, 1: With LS), Bit 1,2:Configure IO's [SDIO/wspi] (00- 8mA, 01- 4mA (default), 10- 6mA, 11 - 2mA), Bit 3:Eeprom (0-No Eeprom), Bit 4: SDIO IB Enable sync, Bit 5: SDIO IB Enable async, Bit 6: SDIO IB Enable BlockMode, Bit 7: SDIO High-Speed support
+Single_Dual_Band_Solution  = 01 # Length: 1; Unit: Options (0: 2.5v, 1: 2.55v, 2: 2.6v); Format: Unsigned; Source: Customer; Comment: This field notifies the FW whether the solution is a single-band or dual-band
+Settings  = 00 00 00 00 # Length: 4; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit0: NBI (0: Off, 1: On), Bit1: Telec channel 14 (0: Off, 1: On), Bit2: FEM0-LB, Bit3: FEM0-HB, Bit4: FEM1-LB, Bit5: FEM1-HB - TX BiP load (0: Internal, 1: External), Bit6: LPD Low band, Bit7: LPD High band 
+XTALItrimVal = 04 # Length: 1; Unit: Current trimming for XTAL; Format: Unsigned; Source: TI; Comment: Current trimming for XTAL
+SRState = 00 # Length: 1; Unit: Options (0: Disabled, 1: Enabled); Format: Decimal; Source: TI; Comment: Smart Reflax (proprietary mechanism of TI that identify the silicon process specific params) state
+SRF1 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 0F 3F  # Length: 16; Unit: SRF1 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF2 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SRF2 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF3 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SRF3 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+#SR_Debug_Table = 09 04 19 10 01 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SR_Debug_Table values; Format: Signed; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P = 11 # Length: 1; Unit: SR_SEN_N_P values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P_Gain = AA # Length: 1; Unit: SR_SEN_N_P_GAIN values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_NRN = B6 # Length: 1; Unit: SR_SEN_NRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#SR_SEN_PRN = F0 # Length: 1; Unit: SR_SEN_PRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2: Band-dependant parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TxTraceLoss_2_4G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 14; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_5G  = 00 00 00 00 00 00 00 # Length: 7; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TxTraceLoss_5G  = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 35; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2:     FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1:   FEM parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FemVendorAndOptions  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit 0..1 - 0: RFMD, 1: TQS, 2: SKWS,  Bit 4..7 [Version control] -  0: TQS-S1.0, 1: TQS-S2.0, 2: TQS-S2.5, 3: TQS-D1.0, 4: TQS-D1.5, 5: RFMD-S1.5, 6: RFMD-S2.9, 7: RFMD-S3.0, 8: RFMD-D1.5, 9: RFMD-S2.9.5, 10: RFMD-D3.0.1, 11: TQS-S2.6, 12: TQS-D1.7
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM1_TxBiPReferencePDvoltage_2_4G = 01D9 # Length: 1; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM1_TxBiPReferencePower_2_4G  = 80 # Length: 1; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage . The TX BiP reference power is linked to the TX BiP reference PD voltage
+FEM1_TxBiPOffsetdB_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM1_TxPerRatePowerLimits_2_4G_Normal = 1D 1F 22 26 27 29 25 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Degraded = 1D 1F 22 26 27 27 24 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Extreme = 16 1D 1E 20 24 25 22 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_DegradedLowToNormalThr_2_4G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_NormalToDegradedHighThr_2_4G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerChannelPowerLimits_2_4G_11b = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPerChannelPowerLimits_2_4G_OFDM = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPDVsRateOffsets_2_4G = 01 02 02 02 02 00 02 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM1_TxPDVsChannelOffsets_2_4G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 14; Unit: 1/8dB; Format: Signed; Source: TI/Customer; Comment: This parameter is a power detector offset value used to correct the power detector curve for each channel
+FEM1_TxPDVsTemperature_2_4G = 00 00 # Length: 2; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each temperture
+FEM1_TxIbiasTable_2_4G  = 17 17 17 1a 16 17 1a 17 # Length: 8; Unit: Codeword ; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM. Options (MCS7, 54/48, 36/24, 18/12, 9/6, 11b, MCS0, 11bCh14)
+FEM1_RxFemInsertionLoss_2_4G  = 10 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL128x
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM1_TxBiPReferencePDvoltage_5G  = 019A 01AE 01C2 01CC 01DB 01DB 01D1 # Length: 7; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM1_TxBiPReferencePower_5G = 80 80 80 80 80 80 80 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage . The TX BiP reference power is linked to the TX BiP reference PD voltage
+FEM1_TxBiPOffsetdB_5G = 00 00 00 00 00 00 00 # Length: 7; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM1_TxPerRatePowerLimits_5G_Normal  = 1C 1E 21 23 25 50 25 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_5G_Degraded  = 18 1E 21 23 25 50 24 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_5G_Extreme = 16 1C 1E 20 20 50 1E # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_DegradedLowToNormalThr_5G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_NormalToDegradedHighThr_5G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerChannelPowerLimits_5G_OFDM  = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 35; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPDVsRateOffsets_5G  = 01 02 02 02 02 00 02 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM1_TxPDVsChannelOffsets_5G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 35; Unit: 1/8dB; Format: Signed; Source: TI/Customer; Comment: This parameter is a power detector offset value used to correct the power detector curve for each channel
+FEM1_TxPDVsTemperature_5G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 14; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each temperture
+FEM1_TxIbiasTable_5G  = 10 10 10 10 10 10 10 # Length: 7; Unit: Codeword; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM
+FEM1_RxFemInsertionLoss_5G  = 10 10 10 10 10 10 10 # Length: 7; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL128x
+
diff --git a/mac80211/ti-utils/ini_files/128x/TQS_S_2.6.ini b/mac80211/ti-utils/ini_files/128x/TQS_S_2.6.ini
new file mode 100755
index 0000000..a3d0f24
--- /dev/null
+++ b/mac80211/ti-utils/ini_files/128x/TQS_S_2.6.ini
@@ -0,0 +1,69 @@
+# INI Generator version 0.5; Aligned to TS version 7.1.2.0.26
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1:   Non FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.1: General parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+TXBiPFEMAutoDetect  = 00 # Length: 1; Unit: Options (0: Manual Mode, 1: Automatic mode); Format: Unsigned; Source: Customer; Comment: This parameter is used by the FW to decide if the front-end is determined automatically or manually
+TXBiPFEMManufacturer  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit1,0: used to determine which FEM vendor type is used on the platform (0: RFMD, 1: TQS, 2:SKW, 3:HP), Bit3,2: unused, Bit7-4:External/internal load (4-SKW SB, 5-SKW HB, 6-HP SB, 7-HP HB)
+RefClk  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: 5'bXX000 : Bit 0,1,2 - 0: 19.2MHz, 1: 26MHz, 2: 38.4MHz  [Default], 3: 52MHz,  4: 38.4MHz XTAL, 5: 26MHz XTAL ,  5'bX0XXX : Bit 3 - CLK_REQ type,  0 = wired-OR [Default], 1= push-pull ,  5'b0XXXX : Bit 4 - CLK_REQ polarity, 0 = Normal [Default], 1=Inverted
+SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid FREF clock on the device inputs
+ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the FREF clock is valid on wakeup
+TCXO_Clk  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: 5'bXX000 : Bit 0,1,2 - 0: 19.2MHz, 1: 26MHz, 2: 38.4MHz  [Default], 3: 52MHz, 4: 16.368Mhz, 5: 32.736 Mhz 
+TCXO_SettlingTime  = 05 # Length: 1; Unit: ms (0-15); Format: Unsigned; Source: Customer; Comment: The time from asserting CLK_REQ (low to high) to valid TCXO clock on the device inputs
+TCXO_ClockValidOnWakeup  = 00 # Length: 1; Unit: Options (0: Reference clock not valid, 1: Reference clock is valid and stable); Format: Unsigned; Source: Customer; Comment: This parameter indicates whether the TCXO clock is valid on wakeup 
+TCXO_LDO_Voltage = 00 # Length: 1; Unit: Options (0:2.5v, 1:2.55v, 2:2.6v); Format: Unsigned; Source: Customer; Comment: TCXO LDO Voltage 
+Platform_configuration = 02 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer ; Comment: Bit 0: Levelshifter support (0: No LS, 1: With LS), Bit 1,2:Configure IO's [SDIO/wspi] (00- 8mA, 01- 4mA (default), 10- 6mA, 11 - 2mA), Bit 3:Eeprom (0-No Eeprom), Bit 4: SDIO IB Enable sync, Bit 5: SDIO IB Enable async, Bit 6: SDIO IB Enable BlockMode, Bit 7: SDIO High-Speed support
+Single_Dual_Band_Solution  = 00 # Length: 1; Unit: Options (0: 2.5v, 1: 2.55v, 2: 2.6v); Format: Unsigned; Source: Customer; Comment: This field notifies the FW whether the solution is a single-band or dual-band
+Settings  = 00 00 00 00 # Length: 4; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit0: NBI (0: Off, 1: On), Bit1: Telec channel 14 (0: Off, 1: On), Bit2: FEM0-LB, Bit3: FEM0-HB, Bit4: FEM1-LB, Bit5: FEM1-HB - TX BiP load (0: Internal, 1: External), Bit6: LPD Low band, Bit7: LPD High band 
+XTALItrimVal = 04 # Length: 1; Unit: Current trimming for XTAL; Format: Unsigned; Source: TI; Comment: Current trimming for XTAL
+SRState = 00 # Length: 1; Unit: Options (0: Disabled, 1: Enabled); Format: Decimal; Source: TI; Comment: Smart Reflax (proprietary mechanism of TI that identify the silicon process specific params) state
+SRF1 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 0F 3F  # Length: 16; Unit: SRF1 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF2 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SRF2 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+SRF3 = 09 04 19 10 08 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SRF3 values; Format: Signed; Source: TI; Comment: The table holds the specific parameters for using the SmartReflex mechanism
+#SR_Debug_Table = 09 04 19 10 01 00 F7 EF E6 DE 00 00 00 00 00 00  # Length: 16; Unit: SR_Debug_Table values; Format: Signed; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P = 11 # Length: 1; Unit: SR_SEN_N_P values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_N_P_Gain = AA # Length: 1; Unit: SR_SEN_N_P_GAIN values; Format: Unsigned; Source: TI; Comment: SR Debug values – for TI internal use only
+#SR_SEN_NRN = B6 # Length: 1; Unit: SR_SEN_NRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#SR_SEN_PRN = F0 # Length: 1; Unit: SR_SEN_PRN values; Format: Unsigned; Source: TI ; Comment: SR Debug values – for TI internal use only
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2: Band-dependant parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+RxTraceInsertionLoss_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter indicates the printed circuit board (PCB) trace insertion loss
+TxTraceLoss_2_4G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 14; Unit: 1/8dB; Format: Unsigned; Source: Customer; Comment: This parameter is used to align the output power to a different location on the board
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 1.2.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2:     FEM-dependant section
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1:   FEM parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FemVendorAndOptions  = 01 # Length: 1; Unit: Bit_Options; Format: Unsigned; Source: Customer; Comment: Bit 0..1 - 0: RFMD, 1: TQS, 2: SKWS,  Bit 4..7 [Version control] -  0: TQS-S1.0, 1: TQS-S2.0, 2: TQS-S2.5, 3: TQS-D1.0, 4: TQS-D1.5, 5: RFMD-S1.5, 6: RFMD-S2.9, 7: RFMD-S3.0, 8: RFMD-D1.5, 9: RFMD-S2.9.5, 10: RFMD-D3.0.1, 11: TQS-S2.6, 12: TQS-D1.7
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.1: 2.4G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+FEM1_TxBiPReferencePDvoltage_2_4G = 0177 # Length: 1; Unit: 1mV; Format: Unsigned; Source: TI; Comment: This parameter define the reference point of the FEM power detector
+FEM1_TxBiPReferencePower_2_4G  = 80 # Length: 1; Unit: 1/8dB; Format: Signed; Source: TI; Comment: Reference output power that produces given reference power detector output voltage . The TX BiP reference power is linked to the TX BiP reference PD voltage
+FEM1_TxBiPOffsetdB_2_4G = 00 # Length: 1; Unit: 1/8dB; Format: Signed; Source: Customer; Comment: This field is used to fine-tune the TX BiP by the customer
+FEM1_TxPerRatePowerLimits_2_4G_Normal = 1D 1F 22 26 27 29 25 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Degraded = 1A 1F 22 25 25 27 23 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerRatePowerLimits_2_4G_Extreme = 16 1D 1E 20 24 25 22 # Length: 7; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_DegradedLowToNormalThr_2_4G = 1E # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_NormalToDegradedHighThr_2_4G = 2D # Length: 1; Unit: 1/10 volts; Format: Unsigned; Source: TI; Comment: The limits are applied to the power control process according to the VBAT and temperature range in which the FEM is operating
+FEM1_TxPerChannelPowerLimits_2_4G_11b = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPerChannelPowerLimits_2_4G_OFDM = 50 50 50 50 50 50 50 50 50 50 50 50 50 50 # Length: 14; Unit: 1/2dB; Format: Signed; Source: Customer; Comment: The purpose of this table is to allow clipping of the maximum output power on certain channels
+FEM1_TxPDVsRateOffsets_2_4G = 01 02 02 02 02 00 02 # Length: 7; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each rate group
+FEM1_TxPDVsChannelOffsets_2_4G = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Length: 14; Unit: 1/8dB; Format: Signed; Source: TI/Customer; Comment: This parameter is a power detector offset value used to correct the power detector curve for each channel
+FEM1_TxPDVsTemperature_2_4G = 00 00 # Length: 2; Unit: 1/8dB; Format: Signed; Source: TI; Comment: This parameter is a power detector offset value used to correct the power detector curve for each temperture
+FEM1_TxIbiasTable_2_4G  = 17 17 17 13 17 17 17 17 # Length: 8; Unit: Codeword ; Format: Unsigned; Source: TI; Comment: This parameter sets the bias current provided by the SoC to the PA in the FEM. Options (MCS7, 54/48, 36/24, 18/12, 9/6, 11b, MCS0, 11bCh14)
+FEM1_RxFemInsertionLoss_2_4G  = 0E # Length: 1; Unit: 1/8dB; Format: Unsigned; Source: TI; Comment: This parameter specifies the received insertion loss of the WL128x
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+# SECTION 2.1.2: 5G parameters
+#------------------------------------------------------------------------------------------------------------------------------------------------------------
+
diff --git a/mac80211/ti-utils/misc_cmds.c b/mac80211/ti-utils/misc_cmds.c
new file mode 100644
index 0000000..ac2ebc6
--- /dev/null
+++ b/mac80211/ti-utils/misc_cmds.c
@@ -0,0 +1,442 @@
+#include <stdbool.h>
+#include <errno.h>
+#include <time.h>
+#include <net/if.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include "calibrator.h"
+#include "plt.h"
+#include "ini.h"
+#include "nvs.h"
+
+SECTION(get);
+SECTION(set);
+
+static int handle_push_nvs(struct nl80211_state *state,
+            struct nl_cb *cb,
+            struct nl_msg *msg,
+            int argc, char **argv)
+{
+    void *map = MAP_FAILED;
+    int fd, retval = 0;
+    struct nlattr *key;
+    struct stat filestat;
+
+    if (argc != 1) {
+        return 1;
+    }
+
+    fd = open(argv[0], O_RDONLY);
+    if (fd < 0) {
+        perror("Error opening file for reading");
+        return 1;
+    }
+
+    if (fstat(fd, &filestat) < 0) {
+        perror("Error stating file");
+        return 1;
+    }
+
+    map = mmap(0, filestat.st_size, PROT_READ, MAP_SHARED, fd, 0);
+    if (map == MAP_FAILED) {
+        perror("Error mmapping the file");
+        goto nla_put_failure;
+    }
+
+    key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+    if (!key) {
+        goto nla_put_failure;
+    }
+
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_NVS_PUSH);
+    NLA_PUT(msg, WL1271_TM_ATTR_DATA, filestat.st_size, map);
+
+    nla_nest_end(msg, key);
+
+    goto cleanup;
+
+nla_put_failure:
+    retval = -ENOBUFS;
+
+cleanup:
+    if (map != MAP_FAILED) {
+        munmap(map, filestat.st_size);
+    }
+
+    close(fd);
+
+    return retval;
+}
+
+COMMAND(set, push_nvs, "<nvs filename>",
+    NL80211_CMD_TESTMODE, 0, CIB_PHY, handle_push_nvs,
+    "Push NVS file into the system");
+
+#if 0
+static int handle_fetch_nvs(struct nl80211_state *state,
+            struct nl_cb *cb,
+            struct nl_msg *msg,
+            int argc, char **argv)
+{
+    char *end;
+    void *map = MAP_FAILED;
+    int fd, retval = 0;
+    struct nlattr *key;
+    struct stat filestat;
+
+    if (argc != 0)
+        return 1;
+
+    key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+    if (!key)
+        goto nla_put_failure;
+
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_NVS_PUSH);
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_IE_ID, WL1271_TM_CMD_NVS_PUSH);
+
+    nla_nest_end(msg, key);
+
+    goto cleanup;
+
+nla_put_failure:
+    retval = -ENOBUFS;
+
+cleanup:
+    if (map != MAP_FAILED)
+        munmap(map, filestat.st_size);
+
+    close(fd);
+
+    return retval;
+}
+
+COMMAND(set, fetch_nvs, NULL,
+    NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_fetch_nvs,
+    "Send command to fetch NVS file");
+#endif
+static int get_nvs_mac(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    unsigned char mac_buff[12];
+    int fd;
+
+    argc -= 2;
+    argv += 2;
+
+    if (argc != 1) {
+        return 2;
+    }
+
+    fd = open(argv[0], O_RDONLY);
+    if (fd < 0) {
+        perror("Error opening file for reading");
+        return 1;
+    }
+
+    read(fd, mac_buff, 12);
+
+    printf("MAC addr from NVS: %02x:%02x:%02x:%02x:%02x:%02x\n",
+        mac_buff[11], mac_buff[10], mac_buff[6],
+        mac_buff[5], mac_buff[4], mac_buff[3]);
+
+    close(fd);
+
+    return 0;
+}
+
+COMMAND(get, nvs_mac, "<nvs filename>", 0, 0, CIB_NONE, get_nvs_mac,
+    "Get MAC addr from NVS file (offline)");
+
+/*
+ * Sets MAC address in NVS.
+ * The default value for MAC is random where 1 byte zero.
+ */
+static int set_nvs_mac(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    unsigned char mac_buff[12];
+    unsigned char in_mac[6];
+    int fd;
+
+    argc -= 2;
+    argv += 2;
+
+    if (argc < 1 || (argc == 2 && (strlen(argv[1]) != 17))) {
+        return 2;
+    }
+
+    if (argc == 2) {
+        sscanf(argv[1], "%2x:%2x:%2x:%2x:%2x:%2x",
+        (unsigned int *)&in_mac[0], (unsigned int *)&in_mac[1],
+        (unsigned int *)&in_mac[2], (unsigned int *)&in_mac[3],
+        (unsigned int *)&in_mac[4], (unsigned int *)&in_mac[5]);
+    } else {
+        srand((unsigned)time(NULL));
+
+        in_mac[0] = 0x0;
+        in_mac[1] = rand()%256;
+        in_mac[2] = rand()%256;
+        in_mac[3] = rand()%256;
+        in_mac[4] = rand()%256;
+        in_mac[5] = rand()%256;
+    }
+
+    fd = open(argv[0], O_RDWR);
+    if (fd < 0) {
+        perror("Error opening file for reading");
+        return 1;
+    }
+
+    read(fd, mac_buff, 12);
+#if 0
+    printf("Got MAC addr for NVS: %02x:%02x:%02x:%02x:%02x:%02x\n",
+        in_mac[0], in_mac[1], in_mac[2],
+        in_mac[3], in_mac[4], in_mac[5]);
+
+    printf("Got MAC addr from NVS: %02x:%02x:%02x:%02x:%02x:%02x\n",
+        mac_buff[11], mac_buff[10], mac_buff[6],
+        mac_buff[5], mac_buff[4], mac_buff[3]);
+#endif
+    mac_buff[11] = in_mac[0];
+    mac_buff[10] = in_mac[1];
+    mac_buff[6]  = in_mac[2];
+    mac_buff[5]  = in_mac[3];
+    mac_buff[4]  = in_mac[4];
+    mac_buff[3]  = in_mac[5];
+
+    lseek(fd, 0L, 0);
+
+    write(fd, mac_buff, 12);
+
+    close(fd);
+
+    return 0;
+}
+
+COMMAND(set, nvs_mac, "<nvs file> [<mac addr>]", 0, 0, CIB_NONE, set_nvs_mac,
+    "Set MAC addr in NVS file (offline), like XX:XX:XX:XX:XX:XX");
+
+static int set_ref_nvs(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    struct wl12xx_common cmn = {
+        .arch = UNKNOWN_ARCH,
+        .parse_ops = NULL,
+        .dual_mode = DUAL_MODE_UNSET,
+        .done_fem = NO_FEM_PARSED
+    };
+
+    argc -= 2;
+    argv += 2;
+
+    if (argc != 1) {
+        return 1;
+    }
+
+    if (read_ini(*argv, &cmn)) {
+        fprintf(stderr, "Fail to read ini file\n");
+        return 1;
+    }
+
+    cfg_nvs_ops(&cmn);
+
+    if (create_nvs_file(&cmn)) {
+        fprintf(stderr, "Fail to create reference NVS file\n");
+        return 1;
+    }
+#if 0
+    printf("\n\tThe NVS file (%s) is ready\n\tCopy it to %s and "
+        "reboot the system\n\n",
+        NEW_NVS_NAME, CURRENT_NVS_NAME);
+#endif
+    return 0;
+}
+
+COMMAND(set, ref_nvs, "<ini file>", 0, 0, CIB_NONE, set_ref_nvs,
+    "Create reference NVS file");
+
+static int set_ref_nvs2(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    struct wl12xx_common cmn = {
+        .arch = UNKNOWN_ARCH,
+        .parse_ops = NULL,
+        .dual_mode = DUAL_MODE_UNSET,
+        .done_fem = NO_FEM_PARSED
+    };
+
+    argc -= 2;
+    argv += 2;
+
+    if (argc != 2) {
+        return 1;
+    }
+
+    if (read_ini(*argv, &cmn)) {
+        return 1;
+    }
+
+    argv++;
+    if (read_ini(*argv, &cmn)) {
+        return 1;
+    }
+
+    cfg_nvs_ops(&cmn);
+
+    if (create_nvs_file(&cmn)) {
+        fprintf(stderr, "Fail to create reference NVS file\n");
+        return 1;
+    }
+#if 0
+    printf("\n\tThe NVS file (%s) is ready\n\tCopy it to %s and "
+        "reboot the system\n\n",
+        NEW_NVS_NAME, CURRENT_NVS_NAME);
+#endif
+    return 0;
+}
+
+COMMAND(set, ref_nvs2, "<ini file> <ini file>", 0, 0, CIB_NONE, set_ref_nvs2,
+    "Create reference NVS file for 2 FEMs");
+
+static int set_upd_nvs(struct nl80211_state *state, struct nl_cb *cb,
+    struct nl_msg *msg, int argc, char **argv)
+{
+    char *fname = NULL;
+    struct wl12xx_common cmn = {
+        .arch = UNKNOWN_ARCH,
+        .parse_ops = NULL
+    };
+
+    argc -= 2;
+    argv += 2;
+
+    if (argc < 1) {
+        return 1;
+    }
+
+    if (read_ini(*argv, &cmn)) {
+        fprintf(stderr, "Fail to read ini file\n");
+        return 1;
+    }
+
+    cfg_nvs_ops(&cmn);
+
+    if (argc == 2) {
+        fname = *++argv;
+    }
+
+    if (update_nvs_file(fname, &cmn)) {
+        fprintf(stderr, "Fail to update NVS file\n");
+        return 1;
+    }
+#if 0
+    printf("\n\tThe updated NVS file (%s) is ready\n\tCopy it to %s and "
+        "reboot the system\n\n", NEW_NVS_NAME, CURRENT_NVS_NAME);
+#endif
+    return 0;
+}
+
+COMMAND(set, upd_nvs, "<ini file> [<nvs file>]", 0, 0, CIB_NONE, set_upd_nvs,
+    "Update values of a NVS from INI file");
+
+static int get_dump_nvs(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    char *fname = NULL;
+    struct wl12xx_common cmn = {
+        .arch = UNKNOWN_ARCH,
+        .parse_ops = NULL
+    };
+
+    argc -= 2;
+    argv += 2;
+
+    if (argc > 0) {
+        fname = *argv;
+    }
+
+    if (dump_nvs_file(fname, &cmn)) {
+        fprintf(stderr, "Fail to dump NVS file\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+COMMAND(get, dump_nvs, "[<nvs file>]", 0, 0, CIB_NONE, get_dump_nvs,
+    "Dump NVS file, specified by option or current");
+
+static int set_autofem(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    char *fname = NULL;
+    unsigned char val;
+    struct wl12xx_common cmn = {
+        .arch = UNKNOWN_ARCH,
+        .parse_ops = NULL
+    };
+
+    argc -= 2;
+    argv += 2;
+
+    if (argc < 1) {
+        fprintf(stderr, "Missing argument\n");
+        return 2;
+    }
+
+    sscanf(argv[0], "%2x", (unsigned int *)&val);
+
+    if (argc == 2) {
+        fname = argv[1];
+    }
+
+    if (set_nvs_file_autofem(fname, val, &cmn)) {
+        fprintf(stderr, "Fail to set AutoFEM\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+COMMAND(set, autofem, "<0-manual|1-auto> [<nvs file>]", 0, 0, CIB_NONE, set_autofem,
+    "Set Auto FEM detection, where 0 - manual, 1 - auto detection");
+
+static int set_fem_manuf(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    char *fname = NULL;
+    unsigned char val;
+    struct wl12xx_common cmn = {
+        .arch = UNKNOWN_ARCH,
+        .parse_ops = NULL
+    };
+
+    argc -= 2;
+    argv += 2;
+
+    if (argc < 1) {
+        fprintf(stderr, "Missing argument\n");
+        return 2;
+    }
+
+    sscanf(argv[0], "%2x", (unsigned int *)&val);
+
+    if (argc == 2) {
+        fname = argv[1];
+    }
+
+    if (set_nvs_file_fem_manuf(fname, val, &cmn)) {
+        fprintf(stderr, "Fail to set AutoFEM\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+COMMAND(set, fem_manuf, "<0|1> [<nvs file>]", 0, 0, CIB_NONE, set_fem_manuf,
+    "Set FEM manufacturer");
+
diff --git a/mac80211/ti-utils/nl80211.h b/mac80211/ti-utils/nl80211.h
new file mode 100644
index 0000000..1db3b7d
--- /dev/null
+++ b/mac80211/ti-utils/nl80211.h
@@ -0,0 +1,1434 @@
+#ifndef __LINUX_NL80211_H
+#define __LINUX_NL80211_H
+/*
+ * 802.11 netlink interface public header
+ *
+ * Copyright 2006, 2007, 2008 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2008 Michael Wu <flamingice@sourmilk.net>
+ * Copyright 2008 Luis Carlos Cobo <luisca@cozybit.com>
+ * Copyright 2008 Michael Buesch <mb@bu3sch.de>
+ * Copyright 2008, 2009 Luis R. Rodriguez <lrodriguez@atheros.com>
+ * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com>
+ * Copyright 2008 Colin McCabe <colin@cozybit.com>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/types.h>
+
+/**
+ * DOC: Station handling
+ *
+ * Stations are added per interface, but a special case exists with VLAN
+ * interfaces. When a station is bound to an AP interface, it may be moved
+ * into a VLAN identified by a VLAN interface index (%NL80211_ATTR_STA_VLAN).
+ * The station is still assumed to belong to the AP interface it was added
+ * to.
+ *
+ * TODO: need more info?
+ */
+
+/**
+ * enum nl80211_commands - supported nl80211 commands
+ *
+ * @NL80211_CMD_UNSPEC: unspecified command to catch errors
+ *
+ * @NL80211_CMD_GET_WIPHY: request information about a wiphy or dump request
+ *   to get a list of all present wiphys.
+ * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or
+ *   %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME,
+ *   %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ,
+ *   %NL80211_ATTR_WIPHY_CHANNEL_TYPE, %NL80211_ATTR_WIPHY_RETRY_SHORT,
+ *   %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+ *   and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD.
+ * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request
+ *   or rename notification. Has attributes %NL80211_ATTR_WIPHY and
+ *   %NL80211_ATTR_WIPHY_NAME.
+ * @NL80211_CMD_DEL_WIPHY: Wiphy deleted. Has attributes
+ *   %NL80211_ATTR_WIPHY and %NL80211_ATTR_WIPHY_NAME.
+ *
+ * @NL80211_CMD_GET_INTERFACE: Request an interface's configuration;
+ *   either a dump request on a %NL80211_ATTR_WIPHY or a specific get
+ *   on an %NL80211_ATTR_IFINDEX is supported.
+ * @NL80211_CMD_SET_INTERFACE: Set type of a virtual interface, requires
+ *   %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE.
+ * @NL80211_CMD_NEW_INTERFACE: Newly created virtual interface or response
+ *   to %NL80211_CMD_GET_INTERFACE. Has %NL80211_ATTR_IFINDEX,
+ *   %NL80211_ATTR_WIPHY and %NL80211_ATTR_IFTYPE attributes. Can also
+ *   be sent from userspace to request creation of a new virtual interface,
+ *   then requires attributes %NL80211_ATTR_WIPHY, %NL80211_ATTR_IFTYPE and
+ *   %NL80211_ATTR_IFNAME.
+ * @NL80211_CMD_DEL_INTERFACE: Virtual interface was deleted, has attributes
+ *   %NL80211_ATTR_IFINDEX and %NL80211_ATTR_WIPHY. Can also be sent from
+ *   userspace to request deletion of a virtual interface, then requires
+ *   attribute %NL80211_ATTR_IFINDEX.
+ *
+ * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified
+ *   by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC.
+ * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT,
+ *   %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD.
+ * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA,
+ *   %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER,
+ *   and %NL80211_ATTR_KEY_SEQ attributes.
+ * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
+ *   or %NL80211_ATTR_MAC.
+ *
+ * @NL80211_CMD_GET_BEACON: retrieve beacon information (returned in a
+ *   %NL80222_CMD_NEW_BEACON message)
+ * @NL80211_CMD_SET_BEACON: set the beacon on an access point interface
+ *   using the %NL80211_ATTR_BEACON_INTERVAL, %NL80211_ATTR_DTIM_PERIOD,
+ *   %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL attributes.
+ * @NL80211_CMD_NEW_BEACON: add a new beacon to an access point interface,
+ *   parameters are like for %NL80211_CMD_SET_BEACON.
+ * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it
+ *
+ * @NL80211_CMD_GET_STATION: Get station attributes for station identified by
+ *   %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_SET_STATION: Set station attributes for station identified by
+ *   %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_NEW_STATION: Add a station with given attributes to the
+ *   the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC
+ *   or, if no MAC address given, all stations, on the interface identified
+ *   by %NL80211_ATTR_IFINDEX.
+ *
+ * @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to
+ *   destination %NL80211_ATTR_MAC on the interface identified by
+ *   %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_SET_MPATH:  Set mesh path attributes for mesh path to
+ *   destination %NL80211_ATTR_MAC on the interface identified by
+ *   %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the
+ *   the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC
+ *   or, if no MAC address given, all mesh paths, on the interface identified
+ *   by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by
+ *   %NL80211_ATTR_IFINDEX.
+ *
+ * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
+ *   regulatory domain.
+ * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
+ *   after being queried by the kernel. CRDA replies by sending a regulatory
+ *   domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
+ *   current alpha2 if it found a match. It also provides
+ *   NL80211_ATTR_REG_RULE_FLAGS, and a set of regulatory rules. Each
+ *   regulatory rule is a nested set of attributes  given by
+ *   %NL80211_ATTR_REG_RULE_FREQ_[START|END] and
+ *   %NL80211_ATTR_FREQ_RANGE_MAX_BW with an attached power rule given by
+ *   %NL80211_ATTR_REG_RULE_POWER_MAX_ANT_GAIN and
+ *   %NL80211_ATTR_REG_RULE_POWER_MAX_EIRP.
+ * @NL80211_CMD_REQ_SET_REG: ask the wireless core to set the regulatory domain
+ *   to the the specified ISO/IEC 3166-1 alpha2 country code. The core will
+ *   store this as a valid request and then query userspace for it.
+ *
+ * @NL80211_CMD_GET_MESH_PARAMS: Get mesh networking properties for the
+ *   interface identified by %NL80211_ATTR_IFINDEX
+ *
+ * @NL80211_CMD_SET_MESH_PARAMS: Set mesh networking properties for the
+ *      interface identified by %NL80211_ATTR_IFINDEX
+ *
+ * @NL80211_CMD_SET_MGMT_EXTRA_IE: Set extra IEs for management frames. The
+ *   interface is identified with %NL80211_ATTR_IFINDEX and the management
+ *   frame subtype with %NL80211_ATTR_MGMT_SUBTYPE. The extra IE data to be
+ *   added to the end of the specified management frame is specified with
+ *   %NL80211_ATTR_IE. If the command succeeds, the requested data will be
+ *   added to all specified management frames generated by
+ *   kernel/firmware/driver.
+ *   Note: This command has been removed and it is only reserved at this
+ *   point to avoid re-using existing command number. The functionality this
+ *   command was planned for has been provided with cleaner design with the
+ *   option to specify additional IEs in NL80211_CMD_TRIGGER_SCAN,
+ *   NL80211_CMD_AUTHENTICATE, NL80211_CMD_ASSOCIATE,
+ *   NL80211_CMD_DEAUTHENTICATE, and NL80211_CMD_DISASSOCIATE.
+ *
+ * @NL80211_CMD_GET_SCAN: get scan results
+ * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters
+ * @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to
+ *   NL80211_CMD_GET_SCAN and on the "scan" multicast group)
+ * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
+ *   partial scan results may be available
+ *
+ * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation
+ *      or noise level
+ * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to
+ *   NL80211_CMD_GET_SURVEY and on the "scan" multicast group)
+ *
+ * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain
+ *   has been changed and provides details of the request information
+ *   that caused the change such as who initiated the regulatory request
+ *   (%NL80211_ATTR_REG_INITIATOR), the wiphy_idx
+ *   (%NL80211_ATTR_REG_ALPHA2) on which the request was made from if
+ *   the initiator was %NL80211_REGDOM_SET_BY_COUNTRY_IE or
+ *   %NL80211_REGDOM_SET_BY_DRIVER, the type of regulatory domain
+ *   set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is
+ *   %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on
+ *   to (%NL80211_ATTR_REG_ALPHA2).
+ * @NL80211_CMD_REG_BEACON_HINT: indicates to userspace that an AP beacon
+ *   has been found while world roaming thus enabling active scan or
+ *   any mode of operation that initiates TX (beacons) on a channel
+ *   where we would not have been able to do either before. As an example
+ *   if you are world roaming (regulatory domain set to world or if your
+ *   driver is using a custom world roaming regulatory domain) and while
+ *   doing a passive scan on the 5 GHz band you find an AP there (if not
+ *   on a DFS channel) you will now be able to actively scan for that AP
+ *   or use AP mode on your card on that same channel. Note that this will
+ *   never be used for channels 1-11 on the 2 GHz band as they are always
+ *   enabled world wide. This beacon hint is only sent if your device had
+ *   either disabled active scanning or beaconing on a channel. We send to
+ *   userspace the wiphy on which we removed a restriction from
+ *   (%NL80211_ATTR_WIPHY) and the channel on which this occurred
+ *   before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER)
+ *   the beacon hint was processed.
+ *
+ * @NL80211_CMD_AUTHENTICATE: authentication request and notification.
+ *   This command is used both as a command (request to authenticate) and
+ *   as an event on the "mlme" multicast group indicating completion of the
+ *   authentication process.
+ *   When used as a command, %NL80211_ATTR_IFINDEX is used to identify the
+ *   interface. %NL80211_ATTR_MAC is used to specify PeerSTAAddress (and
+ *   BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify
+ *   the SSID (mainly for association, but is included in authentication
+ *   request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ is used
+ *   to specify the frequence of the channel in MHz. %NL80211_ATTR_AUTH_TYPE
+ *   is used to specify the authentication type. %NL80211_ATTR_IE is used to
+ *   define IEs (VendorSpecificInfo, but also including RSN IE and FT IEs)
+ *   to be added to the frame.
+ *   When used as an event, this reports reception of an Authentication
+ *   frame in station and IBSS modes when the local MLME processed the
+ *   frame, i.e., it was for the local STA and was received in correct
+ *   state. This is similar to MLME-AUTHENTICATE.confirm primitive in the
+ *   MLME SAP interface (kernel providing MLME, userspace SME). The
+ *   included %NL80211_ATTR_FRAME attribute contains the management frame
+ *   (including both the header and frame body, but not FCS). This event is
+ *   also used to indicate if the authentication attempt timed out. In that
+ *   case the %NL80211_ATTR_FRAME attribute is replaced with a
+ *   %NL80211_ATTR_TIMED_OUT flag (and %NL80211_ATTR_MAC to indicate which
+ *   pending authentication timed out).
+ * @NL80211_CMD_ASSOCIATE: association request and notification; like
+ *   NL80211_CMD_AUTHENTICATE but for Association and Reassociation
+ *   (similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request,
+ *   MLME-ASSOCIATE.confirm or MLME-REASSOCIATE.confirm primitives).
+ * @NL80211_CMD_DEAUTHENTICATE: deauthentication request and notification; like
+ *   NL80211_CMD_AUTHENTICATE but for Deauthentication frames (similar to
+ *   MLME-DEAUTHENTICATION.request and MLME-DEAUTHENTICATE.indication
+ *   primitives).
+ * @NL80211_CMD_DISASSOCIATE: disassociation request and notification; like
+ *   NL80211_CMD_AUTHENTICATE but for Disassociation frames (similar to
+ *   MLME-DISASSOCIATE.request and MLME-DISASSOCIATE.indication primitives).
+ *
+ * @NL80211_CMD_MICHAEL_MIC_FAILURE: notification of a locally detected Michael
+ *   MIC (part of TKIP) failure; sent on the "mlme" multicast group; the
+ *   event includes %NL80211_ATTR_MAC to describe the source MAC address of
+ *   the frame with invalid MIC, %NL80211_ATTR_KEY_TYPE to show the key
+ *   type, %NL80211_ATTR_KEY_IDX to indicate the key identifier, and
+ *   %NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this
+ *   event matches with MLME-MICHAELMICFAILURE.indication() primitive
+ *
+ * @NL80211_CMD_JOIN_IBSS: Join a new IBSS -- given at least an SSID and a
+ *   FREQ attribute (for the initial frequency if no peer can be found)
+ *   and optionally a MAC (as BSSID) and FREQ_FIXED attribute if those
+ *   should be fixed rather than automatically determined. Can only be
+ *   executed on a network interface that is UP, and fixed BSSID/FREQ
+ *   may be rejected. Another optional parameter is the beacon interval,
+ *   given in the %NL80211_ATTR_BEACON_INTERVAL attribute, which if not
+ *   given defaults to 100 TU (102.4ms).
+ * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is
+ *   determined by the network interface.
+ *
+ * @NL80211_CMD_TESTMODE: testmode command, takes a wiphy (or ifindex) attribute
+ *   to identify the device, and the TESTDATA blob attribute to pass through
+ *   to the driver.
+ *
+ * @NL80211_CMD_CONNECT: connection request and notification; this command
+ *   requests to connect to a specified network but without separating
+ *   auth and assoc steps. For this, you need to specify the SSID in a
+ *   %NL80211_ATTR_SSID attribute, and can optionally specify the association
+ *   IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_MAC,
+ *   %NL80211_ATTR_WIPHY_FREQ and %NL80211_ATTR_CONTROL_PORT.
+ *   It is also sent as an event, with the BSSID and response IEs when the
+ *   connection is established or failed to be established. This can be
+ *   determined by the STATUS_CODE attribute.
+ * @NL80211_CMD_ROAM: request that the card roam (currently not implemented),
+ *   sent as an event when the card/driver roamed by itself.
+ * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify
+ *   userspace that a connection was dropped by the AP or due to other
+ *   reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and
+ *   %NL80211_ATTR_REASON_CODE attributes are used.
+ *
+ * @NL80211_CMD_SET_WIPHY_NETNS: Set a wiphy's netns. Note that all devices
+ *   associated with this wiphy must be down and will follow.
+ *
+ * @NL80211_CMD_MAX: highest used command number
+ * @__NL80211_CMD_AFTER_LAST: internal use
+ */
+enum nl80211_commands {
+/* don't change the order or add anything inbetween, this is ABI! */
+   NL80211_CMD_UNSPEC,
+
+   NL80211_CMD_GET_WIPHY,      /* can dump */
+   NL80211_CMD_SET_WIPHY,
+   NL80211_CMD_NEW_WIPHY,
+   NL80211_CMD_DEL_WIPHY,
+
+   NL80211_CMD_GET_INTERFACE,   /* can dump */
+   NL80211_CMD_SET_INTERFACE,
+   NL80211_CMD_NEW_INTERFACE,
+   NL80211_CMD_DEL_INTERFACE,
+
+   NL80211_CMD_GET_KEY,
+   NL80211_CMD_SET_KEY,
+   NL80211_CMD_NEW_KEY,
+   NL80211_CMD_DEL_KEY,
+
+   NL80211_CMD_GET_BEACON,
+   NL80211_CMD_SET_BEACON,
+   NL80211_CMD_NEW_BEACON,
+   NL80211_CMD_DEL_BEACON,
+
+   NL80211_CMD_GET_STATION,
+   NL80211_CMD_SET_STATION,
+   NL80211_CMD_NEW_STATION,
+   NL80211_CMD_DEL_STATION,
+
+   NL80211_CMD_GET_MPATH,
+   NL80211_CMD_SET_MPATH,
+   NL80211_CMD_NEW_MPATH,
+   NL80211_CMD_DEL_MPATH,
+
+   NL80211_CMD_SET_BSS,
+
+   NL80211_CMD_SET_REG,
+   NL80211_CMD_REQ_SET_REG,
+
+   NL80211_CMD_GET_MESH_PARAMS,
+   NL80211_CMD_SET_MESH_PARAMS,
+
+   NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */,
+
+   NL80211_CMD_GET_REG,
+
+   NL80211_CMD_GET_SCAN,
+   NL80211_CMD_TRIGGER_SCAN,
+   NL80211_CMD_NEW_SCAN_RESULTS,
+   NL80211_CMD_SCAN_ABORTED,
+
+   NL80211_CMD_REG_CHANGE,
+
+   NL80211_CMD_AUTHENTICATE,
+   NL80211_CMD_ASSOCIATE,
+   NL80211_CMD_DEAUTHENTICATE,
+   NL80211_CMD_DISASSOCIATE,
+
+   NL80211_CMD_MICHAEL_MIC_FAILURE,
+
+   NL80211_CMD_REG_BEACON_HINT,
+
+   NL80211_CMD_JOIN_IBSS,
+   NL80211_CMD_LEAVE_IBSS,
+
+   NL80211_CMD_TESTMODE,
+
+   NL80211_CMD_CONNECT,
+   NL80211_CMD_ROAM,
+   NL80211_CMD_DISCONNECT,
+
+   NL80211_CMD_SET_WIPHY_NETNS,
+
+   NL80211_CMD_GET_SURVEY,
+   NL80211_CMD_NEW_SURVEY_RESULTS,
+
+   /* add new commands above here */
+
+   /* used to define NL80211_CMD_MAX below */
+   __NL80211_CMD_AFTER_LAST,
+   NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
+};
+
+/*
+ * Allow user space programs to use #ifdef on new commands by defining them
+ * here
+ */
+#define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS
+#define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE
+#define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE
+#define NL80211_CMD_AUTHENTICATE NL80211_CMD_AUTHENTICATE
+#define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE
+#define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE
+#define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE
+#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT
+
+/**
+ * enum nl80211_attrs - nl80211 netlink attributes
+ *
+ * @NL80211_ATTR_UNSPEC: unspecified attribute to catch errors
+ *
+ * @NL80211_ATTR_WIPHY: index of wiphy to operate on, cf.
+ *   /sys/class/ieee80211/<phyname>/index
+ * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming)
+ * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters
+ * @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz
+ * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ
+ *   if HT20 or HT40 are allowed (i.e., 802.11n disabled if not included):
+ *   NL80211_CHAN_NO_HT = HT not allowed (i.e., same as not including
+ *      this attribute)
+ *   NL80211_CHAN_HT20 = HT20 only
+ *   NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel
+ *   NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel
+ * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is
+ *   less than or equal to the RTS threshold; allowed range: 1..255;
+ *   dot11ShortRetryLimit; u8
+ * @NL80211_ATTR_WIPHY_RETRY_LONG: TX retry limit for frames whose length is
+ *   greater than the RTS threshold; allowed range: 1..255;
+ *   dot11ShortLongLimit; u8
+ * @NL80211_ATTR_WIPHY_FRAG_THRESHOLD: fragmentation threshold, i.e., maximum
+ *   length in octets for frames; allowed range: 256..8000, disable
+ *   fragmentation with (u32)-1; dot11FragmentationThreshold; u32
+ * @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length
+ *   larger than or equal to this use RTS/CTS handshake); allowed range:
+ *   0..65536, disable with (u32)-1; dot11RTSThreshold; u32
+ *
+ * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
+ * @NL80211_ATTR_IFNAME: network interface name
+ * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype
+ *
+ * @NL80211_ATTR_MAC: MAC address (various uses)
+ *
+ * @NL80211_ATTR_KEY_DATA: (temporal) key data; for TKIP this consists of
+ *   16 bytes encryption key followed by 8 bytes each for TX and RX MIC
+ *   keys
+ * @NL80211_ATTR_KEY_IDX: key ID (u8, 0-3)
+ * @NL80211_ATTR_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11
+ *   section 7.3.2.25.1, e.g. 0x000FAC04)
+ * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and
+ *   CCMP keys, each six bytes in little endian
+ *
+ * @NL80211_ATTR_BEACON_INTERVAL: beacon interval in TU
+ * @NL80211_ATTR_DTIM_PERIOD: DTIM period for beaconing
+ * @NL80211_ATTR_BEACON_HEAD: portion of the beacon before the TIM IE
+ * @NL80211_ATTR_BEACON_TAIL: portion of the beacon after the TIM IE
+ *
+ * @NL80211_ATTR_STA_AID: Association ID for the station (u16)
+ * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of
+ *   &enum nl80211_sta_flags (deprecated, use %NL80211_ATTR_STA_FLAGS2)
+ * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by
+ *   IEEE 802.11 7.3.1.6 (u16).
+ * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported
+ *   rates as defined by IEEE 802.11 7.3.2.2 but without the length
+ *   restriction (at most %NL80211_MAX_SUPP_RATES).
+ * @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station
+ *   to, or the AP interface the station was originally added to to.
+ * @NL80211_ATTR_STA_INFO: information about a station, part of station info
+ *   given for %NL80211_CMD_GET_STATION, nested attribute containing
+ *   info as possible, see &enum nl80211_sta_info.
+ *
+ * @NL80211_ATTR_WIPHY_BANDS: Information about an operating bands,
+ *   consisting of a nested array.
+ *
+ * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes).
+ * @NL80211_ATTR_PLINK_ACTION: action to perform on the mesh peer link.
+ * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path.
+ * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path
+ *   info given for %NL80211_CMD_GET_MPATH, nested attribute described at
+ *   &enum nl80211_mpath_info.
+ *
+ * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of
+ *   &enum nl80211_mntr_flags.
+ *
+ * @NL80211_ATTR_REG_ALPHA2: an ISO-3166-alpha2 country code for which the
+ *   current regulatory domain should be set to or is already set to.
+ *   For example, 'CR', for Costa Rica. This attribute is used by the kernel
+ *   to query the CRDA to retrieve one regulatory domain. This attribute can
+ *   also be used by userspace to query the kernel for the currently set
+ *   regulatory domain. We chose an alpha2 as that is also used by the
+ *   IEEE-802.11d country information element to identify a country.
+ *   Users can also simply ask the wireless core to set regulatory domain
+ *   to a specific alpha2.
+ * @NL80211_ATTR_REG_RULES: a nested array of regulatory domain regulatory
+ *   rules.
+ *
+ * @NL80211_ATTR_BSS_CTS_PROT: whether CTS protection is enabled (u8, 0 or 1)
+ * @NL80211_ATTR_BSS_SHORT_PREAMBLE: whether short preamble is enabled
+ *   (u8, 0 or 1)
+ * @NL80211_ATTR_BSS_SHORT_SLOT_TIME: whether short slot time enabled
+ *   (u8, 0 or 1)
+ * @NL80211_ATTR_BSS_BASIC_RATES: basic rates, array of basic
+ *   rates in format defined by IEEE 802.11 7.3.2.2 but without the length
+ *   restriction (at most %NL80211_MAX_SUPP_RATES).
+ *
+ * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from
+ *   association request when used with NL80211_CMD_NEW_STATION)
+ *
+ * @NL80211_ATTR_SUPPORTED_IFTYPES: nested attribute containing all
+ *   supported interface types, each a flag attribute with the number
+ *   of the interface mode.
+ *
+ * @NL80211_ATTR_MGMT_SUBTYPE: Management frame subtype for
+ *   %NL80211_CMD_SET_MGMT_EXTRA_IE.
+ *
+ * @NL80211_ATTR_IE: Information element(s) data (used, e.g., with
+ *   %NL80211_CMD_SET_MGMT_EXTRA_IE).
+ *
+ * @NL80211_ATTR_MAX_NUM_SCAN_SSIDS: number of SSIDs you can scan with
+ *   a single scan request, a wiphy attribute.
+ * @NL80211_ATTR_MAX_SCAN_IE_LEN: maximum length of information elements
+ *   that can be added to a scan request
+ *
+ * @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz)
+ * @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive
+ *   scanning and include a zero-length SSID (wildcard) for wildcard scan
+ * @NL80211_ATTR_BSS: scan result BSS
+ *
+ * @NL80211_ATTR_REG_INITIATOR: indicates who requested the regulatory domain
+ *   currently in effect. This could be any of the %NL80211_REGDOM_SET_BY_*
+ * @NL80211_ATTR_REG_TYPE: indicates the type of the regulatory domain currently
+ *   set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*)
+ *
+ * @NL80211_ATTR_SUPPORTED_COMMANDS: wiphy attribute that specifies
+ *   an array of command numbers (i.e. a mapping index to command number)
+ *   that the driver for the given wiphy supports.
+ *
+ * @NL80211_ATTR_FRAME: frame data (binary attribute), including frame header
+ *   and body, but not FCS; used, e.g., with NL80211_CMD_AUTHENTICATE and
+ *   NL80211_CMD_ASSOCIATE events
+ * @NL80211_ATTR_SSID: SSID (binary attribute, 0..32 octets)
+ * @NL80211_ATTR_AUTH_TYPE: AuthenticationType, see &enum nl80211_auth_type,
+ *   represented as a u32
+ * @NL80211_ATTR_REASON_CODE: ReasonCode for %NL80211_CMD_DEAUTHENTICATE and
+ *   %NL80211_CMD_DISASSOCIATE, u16
+ *
+ * @NL80211_ATTR_KEY_TYPE: Key Type, see &enum nl80211_key_type, represented as
+ *   a u32
+ *
+ * @NL80211_ATTR_FREQ_BEFORE: A channel which has suffered a regulatory change
+ *   due to considerations from a beacon hint. This attribute reflects
+ *   the state of the channel _before_ the beacon hint processing. This
+ *   attributes consists of a nested attribute containing
+ *   NL80211_FREQUENCY_ATTR_*
+ * @NL80211_ATTR_FREQ_AFTER: A channel which has suffered a regulatory change
+ *   due to considerations from a beacon hint. This attribute reflects
+ *   the state of the channel _after_ the beacon hint processing. This
+ *   attributes consists of a nested attribute containing
+ *   NL80211_FREQUENCY_ATTR_*
+ *
+ * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported
+ *   cipher suites
+ *
+ * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look
+ *   for other networks on different channels
+ *
+ * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this
+ *   is used, e.g., with %NL80211_CMD_AUTHENTICATE event
+ *
+ * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
+ *   used for the association (&enum nl80211_mfp, represented as a u32);
+ *   this attribute can be used
+ *   with %NL80211_CMD_ASSOCIATE request
+ *
+ * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
+ *   &struct nl80211_sta_flag_update.
+ *
+ * @NL80211_ATTR_CONTROL_PORT: A flag indicating whether user space controls
+ *   IEEE 802.1X port, i.e., sets/clears %NL80211_STA_FLAG_AUTHORIZED, in
+ *   station mode. If the flag is included in %NL80211_CMD_ASSOCIATE
+ *   request, the driver will assume that the port is unauthorized until
+ *   authorized by user space. Otherwise, port is marked authorized by
+ *   default in station mode.
+ *
+ * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver.
+ *   We recommend using nested, driver-specific attributes within this.
+ *
+ * @NL80211_ATTR_DISCONNECTED_BY_AP: A flag indicating that the DISCONNECT
+ *   event was due to the AP disconnecting the station, and not due to
+ *   a local disconnect request.
+ * @NL80211_ATTR_STATUS_CODE: StatusCode for the %NL80211_CMD_CONNECT
+ *   event (u16)
+ * @NL80211_ATTR_PRIVACY: Flag attribute, used with connect(), indicating
+ *   that protected APs should be used.
+ *
+ * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT and ASSOCIATE to
+ *   indicate which unicast key ciphers will be used with the connection
+ *   (an array of u32).
+ * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT and ASSOCIATE to indicate
+ *   which group key cipher will be used with the connection (a u32).
+ * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT and ASSOCIATE to indicate
+ *   which WPA version(s) the AP we want to associate with is using
+ *   (a u32 with flags from &enum nl80211_wpa_versions).
+ * @NL80211_ATTR_AKM_SUITES: Used with CONNECT and ASSOCIATE to indicate
+ *   which key management algorithm(s) to use (an array of u32).
+ *
+ * @NL80211_ATTR_REQ_IE: (Re)association request information elements as
+ *   sent out by the card, for ROAM and successful CONNECT events.
+ * @NL80211_ATTR_RESP_IE: (Re)association response information elements as
+ *   sent by peer, for ROAM and successful CONNECT events.
+ *
+ * @NL80211_ATTR_PREV_BSSID: previous BSSID, to be used by in ASSOCIATE
+ *   commands to specify using a reassociate frame
+ *
+ * @NL80211_ATTR_KEY: key information in a nested attribute with
+ *   %NL80211_KEY_* sub-attributes
+ * @NL80211_ATTR_KEYS: array of keys for static WEP keys for connect()
+ *   and join_ibss(), key information is in a nested attribute each
+ *   with %NL80211_KEY_* sub-attributes
+ *
+ * @NL80211_ATTR_PID: Process ID of a network namespace.
+ *
+ * @NL80211_ATTR_GENERATION: Used to indicate consistent snapshots for
+ *   dumps. This number increases whenever the object list being
+ *   dumped changes, and as such userspace can verify that it has
+ *   obtained a complete and consistent snapshot by verifying that
+ *   all dump messages contain the same generation number. If it
+ *   changed then the list changed and the dump should be repeated
+ *   completely from scratch.
+ *
+ * @NL80211_ATTR_4ADDR: Use 4-address frames on a virtual interface
+ *
+ * @NL80211_ATTR_SURVEY_INFO: survey information about a channel, part of
+ *      the survey response for %NL80211_CMD_GET_SURVEY, nested attribute
+ *      containing info as possible, see &enum survey_info.
+ *
+ * @NL80211_ATTR_MAX: highest attribute number currently defined
+ * @__NL80211_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_attrs {
+/* don't change the order or add anything inbetween, this is ABI! */
+   NL80211_ATTR_UNSPEC,
+
+   NL80211_ATTR_WIPHY,
+   NL80211_ATTR_WIPHY_NAME,
+
+   NL80211_ATTR_IFINDEX,
+   NL80211_ATTR_IFNAME,
+   NL80211_ATTR_IFTYPE,
+
+   NL80211_ATTR_MAC,
+
+   NL80211_ATTR_KEY_DATA,
+   NL80211_ATTR_KEY_IDX,
+   NL80211_ATTR_KEY_CIPHER,
+   NL80211_ATTR_KEY_SEQ,
+   NL80211_ATTR_KEY_DEFAULT,
+
+   NL80211_ATTR_BEACON_INTERVAL,
+   NL80211_ATTR_DTIM_PERIOD,
+   NL80211_ATTR_BEACON_HEAD,
+   NL80211_ATTR_BEACON_TAIL,
+
+   NL80211_ATTR_STA_AID,
+   NL80211_ATTR_STA_FLAGS,
+   NL80211_ATTR_STA_LISTEN_INTERVAL,
+   NL80211_ATTR_STA_SUPPORTED_RATES,
+   NL80211_ATTR_STA_VLAN,
+   NL80211_ATTR_STA_INFO,
+
+   NL80211_ATTR_WIPHY_BANDS,
+
+   NL80211_ATTR_MNTR_FLAGS,
+
+   NL80211_ATTR_MESH_ID,
+   NL80211_ATTR_STA_PLINK_ACTION,
+   NL80211_ATTR_MPATH_NEXT_HOP,
+   NL80211_ATTR_MPATH_INFO,
+
+   NL80211_ATTR_BSS_CTS_PROT,
+   NL80211_ATTR_BSS_SHORT_PREAMBLE,
+   NL80211_ATTR_BSS_SHORT_SLOT_TIME,
+
+   NL80211_ATTR_HT_CAPABILITY,
+
+   NL80211_ATTR_SUPPORTED_IFTYPES,
+
+   NL80211_ATTR_REG_ALPHA2,
+   NL80211_ATTR_REG_RULES,
+
+   NL80211_ATTR_MESH_PARAMS,
+
+   NL80211_ATTR_BSS_BASIC_RATES,
+
+   NL80211_ATTR_WIPHY_TXQ_PARAMS,
+   NL80211_ATTR_WIPHY_FREQ,
+   NL80211_ATTR_WIPHY_CHANNEL_TYPE,
+
+   NL80211_ATTR_KEY_DEFAULT_MGMT,
+
+   NL80211_ATTR_MGMT_SUBTYPE,
+   NL80211_ATTR_IE,
+
+   NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
+
+   NL80211_ATTR_SCAN_FREQUENCIES,
+   NL80211_ATTR_SCAN_SSIDS,
+   NL80211_ATTR_GENERATION, /* replaces old SCAN_GENERATION */
+   NL80211_ATTR_BSS,
+
+   NL80211_ATTR_REG_INITIATOR,
+   NL80211_ATTR_REG_TYPE,
+
+   NL80211_ATTR_SUPPORTED_COMMANDS,
+
+   NL80211_ATTR_FRAME,
+   NL80211_ATTR_SSID,
+   NL80211_ATTR_AUTH_TYPE,
+   NL80211_ATTR_REASON_CODE,
+
+   NL80211_ATTR_KEY_TYPE,
+
+   NL80211_ATTR_MAX_SCAN_IE_LEN,
+   NL80211_ATTR_CIPHER_SUITES,
+
+   NL80211_ATTR_FREQ_BEFORE,
+   NL80211_ATTR_FREQ_AFTER,
+
+   NL80211_ATTR_FREQ_FIXED,
+
+
+   NL80211_ATTR_WIPHY_RETRY_SHORT,
+   NL80211_ATTR_WIPHY_RETRY_LONG,
+   NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+   NL80211_ATTR_WIPHY_RTS_THRESHOLD,
+
+   NL80211_ATTR_TIMED_OUT,
+
+   NL80211_ATTR_USE_MFP,
+
+   NL80211_ATTR_STA_FLAGS2,
+
+   NL80211_ATTR_CONTROL_PORT,
+
+   NL80211_ATTR_TESTDATA,
+
+   NL80211_ATTR_PRIVACY,
+
+   NL80211_ATTR_DISCONNECTED_BY_AP,
+   NL80211_ATTR_STATUS_CODE,
+
+   NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
+   NL80211_ATTR_CIPHER_SUITE_GROUP,
+   NL80211_ATTR_WPA_VERSIONS,
+   NL80211_ATTR_AKM_SUITES,
+
+   NL80211_ATTR_REQ_IE,
+   NL80211_ATTR_RESP_IE,
+
+   NL80211_ATTR_PREV_BSSID,
+
+   NL80211_ATTR_KEY,
+   NL80211_ATTR_KEYS,
+
+   NL80211_ATTR_PID,
+
+   NL80211_ATTR_4ADDR,
+
+   NL80211_ATTR_SURVEY_INFO,
+
+   /* add attributes here, update the policy in nl80211.c */
+
+   __NL80211_ATTR_AFTER_LAST,
+   NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
+};
+
+/* source-level API compatibility */
+#define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION
+
+/*
+ * Allow user space programs to use #ifdef on new attributes by defining them
+ * here
+ */
+#define NL80211_CMD_CONNECT NL80211_CMD_CONNECT
+#define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY
+#define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES
+#define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS
+#define NL80211_ATTR_WIPHY_FREQ NL80211_ATTR_WIPHY_FREQ
+#define NL80211_ATTR_WIPHY_CHANNEL_TYPE NL80211_ATTR_WIPHY_CHANNEL_TYPE
+#define NL80211_ATTR_MGMT_SUBTYPE NL80211_ATTR_MGMT_SUBTYPE
+#define NL80211_ATTR_IE NL80211_ATTR_IE
+#define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR
+#define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE
+#define NL80211_ATTR_FRAME NL80211_ATTR_FRAME
+#define NL80211_ATTR_SSID NL80211_ATTR_SSID
+#define NL80211_ATTR_AUTH_TYPE NL80211_ATTR_AUTH_TYPE
+#define NL80211_ATTR_REASON_CODE NL80211_ATTR_REASON_CODE
+#define NL80211_ATTR_CIPHER_SUITES_PAIRWISE NL80211_ATTR_CIPHER_SUITES_PAIRWISE
+#define NL80211_ATTR_CIPHER_SUITE_GROUP NL80211_ATTR_CIPHER_SUITE_GROUP
+#define NL80211_ATTR_WPA_VERSIONS NL80211_ATTR_WPA_VERSIONS
+#define NL80211_ATTR_AKM_SUITES NL80211_ATTR_AKM_SUITES
+#define NL80211_ATTR_KEY NL80211_ATTR_KEY
+#define NL80211_ATTR_KEYS NL80211_ATTR_KEYS
+
+#define NL80211_MAX_SUPP_RATES         32
+#define NL80211_MAX_SUPP_REG_RULES      32
+#define NL80211_TKIP_DATA_OFFSET_ENCR_KEY   0
+#define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY   16
+#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY   24
+#define NL80211_HT_CAPABILITY_LEN      26
+
+#define NL80211_MAX_NR_CIPHER_SUITES      5
+#define NL80211_MAX_NR_AKM_SUITES      2
+
+/**
+ * enum nl80211_iftype - (virtual) interface types
+ *
+ * @NL80211_IFTYPE_UNSPECIFIED: unspecified type, driver decides
+ * @NL80211_IFTYPE_ADHOC: independent BSS member
+ * @NL80211_IFTYPE_STATION: managed BSS member
+ * @NL80211_IFTYPE_AP: access point
+ * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points
+ * @NL80211_IFTYPE_WDS: wireless distribution interface
+ * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames
+ * @NL80211_IFTYPE_MESH_POINT: mesh point
+ * @NL80211_IFTYPE_MAX: highest interface type number currently defined
+ * @__NL80211_IFTYPE_AFTER_LAST: internal use
+ *
+ * These values are used with the %NL80211_ATTR_IFTYPE
+ * to set the type of an interface.
+ *
+ */
+enum nl80211_iftype {
+   NL80211_IFTYPE_UNSPECIFIED,
+   NL80211_IFTYPE_ADHOC,
+   NL80211_IFTYPE_STATION,
+   NL80211_IFTYPE_AP,
+   NL80211_IFTYPE_AP_VLAN,
+   NL80211_IFTYPE_WDS,
+   NL80211_IFTYPE_MONITOR,
+   NL80211_IFTYPE_MESH_POINT,
+
+   /* keep last */
+   __NL80211_IFTYPE_AFTER_LAST,
+   NL80211_IFTYPE_MAX = __NL80211_IFTYPE_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_sta_flags - station flags
+ *
+ * Station flags. When a station is added to an AP interface, it is
+ * assumed to be already associated (and hence authenticated.)
+ *
+ * @NL80211_STA_FLAG_AUTHORIZED: station is authorized (802.1X)
+ * @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames
+ *   with short barker preamble
+ * @NL80211_STA_FLAG_WME: station is WME/QoS capable
+ * @NL80211_STA_FLAG_MFP: station uses management frame protection
+ */
+enum nl80211_sta_flags {
+   __NL80211_STA_FLAG_INVALID,
+   NL80211_STA_FLAG_AUTHORIZED,
+   NL80211_STA_FLAG_SHORT_PREAMBLE,
+   NL80211_STA_FLAG_WME,
+   NL80211_STA_FLAG_MFP,
+
+   /* keep last */
+   __NL80211_STA_FLAG_AFTER_LAST,
+   NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1
+};
+
+/**
+ * struct nl80211_sta_flag_update - station flags mask/set
+ * @mask: mask of station flags to set
+ * @set: which values to set them to
+ *
+ * Both mask and set contain bits as per &enum nl80211_sta_flags.
+ */
+struct nl80211_sta_flag_update {
+   __u32 mask;
+   __u32 set;
+} __attribute__((packed));
+
+/**
+ * enum nl80211_rate_info - bitrate information
+ *
+ * These attribute types are used with %NL80211_STA_INFO_TXRATE
+ * when getting information about the bitrate of a station.
+ *
+ * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s)
+ * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8)
+ * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate
+ * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval
+ * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined
+ * @__NL80211_RATE_INFO_AFTER_LAST: internal use
+ */
+enum nl80211_rate_info {
+   __NL80211_RATE_INFO_INVALID,
+   NL80211_RATE_INFO_BITRATE,
+   NL80211_RATE_INFO_MCS,
+   NL80211_RATE_INFO_40_MHZ_WIDTH,
+   NL80211_RATE_INFO_SHORT_GI,
+
+   /* keep last */
+   __NL80211_RATE_INFO_AFTER_LAST,
+   NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_sta_info - station information
+ *
+ * These attribute types are used with %NL80211_ATTR_STA_INFO
+ * when getting information about a station.
+ *
+ * @__NL80211_STA_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs)
+ * @NL80211_STA_INFO_RX_BYTES: total received bytes (u32, from this station)
+ * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station)
+ * @__NL80211_STA_INFO_AFTER_LAST: internal
+ * @NL80211_STA_INFO_MAX: highest possible station info attribute
+ * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm)
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute
+ *   containing info as possible, see &enum nl80211_sta_info_txrate.
+ * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station)
+ * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this
+ *   station)
+ */
+enum nl80211_sta_info {
+   __NL80211_STA_INFO_INVALID,
+   NL80211_STA_INFO_INACTIVE_TIME,
+   NL80211_STA_INFO_RX_BYTES,
+   NL80211_STA_INFO_TX_BYTES,
+   NL80211_STA_INFO_LLID,
+   NL80211_STA_INFO_PLID,
+   NL80211_STA_INFO_PLINK_STATE,
+   NL80211_STA_INFO_SIGNAL,
+   NL80211_STA_INFO_TX_BITRATE,
+   NL80211_STA_INFO_RX_PACKETS,
+   NL80211_STA_INFO_TX_PACKETS,
+
+   /* keep last */
+   __NL80211_STA_INFO_AFTER_LAST,
+   NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_mpath_flags - nl80211 mesh path flags
+ *
+ * @NL80211_MPATH_FLAG_ACTIVE: the mesh path is active
+ * @NL80211_MPATH_FLAG_RESOLVING: the mesh path discovery process is running
+ * @NL80211_MPATH_FLAG_SN_VALID: the mesh path contains a valid SN
+ * @NL80211_MPATH_FLAG_FIXED: the mesh path has been manually set
+ * @NL80211_MPATH_FLAG_RESOLVED: the mesh path discovery process succeeded
+ */
+enum nl80211_mpath_flags {
+   NL80211_MPATH_FLAG_ACTIVE =   1<<0,
+   NL80211_MPATH_FLAG_RESOLVING =   1<<1,
+   NL80211_MPATH_FLAG_SN_VALID =   1<<2,
+   NL80211_MPATH_FLAG_FIXED =   1<<3,
+   NL80211_MPATH_FLAG_RESOLVED =   1<<4,
+};
+
+/**
+ * enum nl80211_mpath_info - mesh path information
+ *
+ * These attribute types are used with %NL80211_ATTR_MPATH_INFO when getting
+ * information about a mesh path.
+ *
+ * @__NL80211_MPATH_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_ATTR_MPATH_FRAME_QLEN: number of queued frames for this destination
+ * @NL80211_ATTR_MPATH_SN: destination sequence number
+ * @NL80211_ATTR_MPATH_METRIC: metric (cost) of this mesh path
+ * @NL80211_ATTR_MPATH_EXPTIME: expiration time for the path, in msec from now
+ * @NL80211_ATTR_MPATH_FLAGS: mesh path flags, enumerated in
+ *   &enum nl80211_mpath_flags;
+ * @NL80211_ATTR_MPATH_DISCOVERY_TIMEOUT: total path discovery timeout, in msec
+ * @NL80211_ATTR_MPATH_DISCOVERY_RETRIES: mesh path discovery retries
+ */
+enum nl80211_mpath_info {
+   __NL80211_MPATH_INFO_INVALID,
+   NL80211_MPATH_INFO_FRAME_QLEN,
+   NL80211_MPATH_INFO_SN,
+   NL80211_MPATH_INFO_METRIC,
+   NL80211_MPATH_INFO_EXPTIME,
+   NL80211_MPATH_INFO_FLAGS,
+   NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
+   NL80211_MPATH_INFO_DISCOVERY_RETRIES,
+
+   /* keep last */
+   __NL80211_MPATH_INFO_AFTER_LAST,
+   NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_band_attr - band attributes
+ * @__NL80211_BAND_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_BAND_ATTR_FREQS: supported frequencies in this band,
+ *   an array of nested frequency attributes
+ * @NL80211_BAND_ATTR_RATES: supported bitrates in this band,
+ *   an array of nested bitrate attributes
+ * @NL80211_BAND_ATTR_HT_MCS_SET: 16-byte attribute containing the MCS set as
+ *   defined in 802.11n
+ * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE
+ * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n
+ * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n
+ */
+enum nl80211_band_attr {
+   __NL80211_BAND_ATTR_INVALID,
+   NL80211_BAND_ATTR_FREQS,
+   NL80211_BAND_ATTR_RATES,
+
+   NL80211_BAND_ATTR_HT_MCS_SET,
+   NL80211_BAND_ATTR_HT_CAPA,
+   NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
+   NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
+
+   /* keep last */
+   __NL80211_BAND_ATTR_AFTER_LAST,
+   NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1
+};
+
+#define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA
+
+/**
+ * enum nl80211_frequency_attr - frequency attributes
+ * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz
+ * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current
+ *   regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_PASSIVE_SCAN: Only passive scanning is
+ *   permitted on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted
+ *   on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory
+ *   on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm
+ *   (100 * dBm).
+ */
+enum nl80211_frequency_attr {
+   __NL80211_FREQUENCY_ATTR_INVALID,
+   NL80211_FREQUENCY_ATTR_FREQ,
+   NL80211_FREQUENCY_ATTR_DISABLED,
+   NL80211_FREQUENCY_ATTR_PASSIVE_SCAN,
+   NL80211_FREQUENCY_ATTR_NO_IBSS,
+   NL80211_FREQUENCY_ATTR_RADAR,
+   NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
+
+   /* keep last */
+   __NL80211_FREQUENCY_ATTR_AFTER_LAST,
+   NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1
+};
+
+#define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER
+
+/**
+ * enum nl80211_bitrate_attr - bitrate attributes
+ * @NL80211_BITRATE_ATTR_RATE: Bitrate in units of 100 kbps
+ * @NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE: Short preamble supported
+ *   in 2.4 GHz band.
+ */
+enum nl80211_bitrate_attr {
+   __NL80211_BITRATE_ATTR_INVALID,
+   NL80211_BITRATE_ATTR_RATE,
+   NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE,
+
+   /* keep last */
+   __NL80211_BITRATE_ATTR_AFTER_LAST,
+   NL80211_BITRATE_ATTR_MAX = __NL80211_BITRATE_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_initiator - Indicates the initiator of a reg domain request
+ * @NL80211_REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world
+ *   regulatory domain.
+ * @NL80211_REGDOM_SET_BY_USER: User asked the wireless core to set the
+ *   regulatory domain.
+ * @NL80211_REGDOM_SET_BY_DRIVER: a wireless drivers has hinted to the
+ *   wireless core it thinks its knows the regulatory domain we should be in.
+ * @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an
+ *   802.11 country information element with regulatory information it
+ *   thinks we should consider.
+ */
+enum nl80211_reg_initiator {
+   NL80211_REGDOM_SET_BY_CORE,
+   NL80211_REGDOM_SET_BY_USER,
+   NL80211_REGDOM_SET_BY_DRIVER,
+   NL80211_REGDOM_SET_BY_COUNTRY_IE,
+};
+
+/**
+ * enum nl80211_reg_type - specifies the type of regulatory domain
+ * @NL80211_REGDOM_TYPE_COUNTRY: the regulatory domain set is one that pertains
+ *   to a specific country. When this is set you can count on the
+ *   ISO / IEC 3166 alpha2 country code being valid.
+ * @NL80211_REGDOM_TYPE_WORLD: the regulatory set domain is the world regulatory
+ *   domain.
+ * @NL80211_REGDOM_TYPE_CUSTOM_WORLD: the regulatory domain set is a custom
+ *   driver specific world regulatory domain. These do not apply system-wide
+ *   and are only applicable to the individual devices which have requested
+ *   them to be applied.
+ * @NL80211_REGDOM_TYPE_INTERSECTION: the regulatory domain set is the product
+ *   of an intersection between two regulatory domains -- the previously
+ *   set regulatory domain on the system and the last accepted regulatory
+ *   domain request to be processed.
+ */
+enum nl80211_reg_type {
+   NL80211_REGDOM_TYPE_COUNTRY,
+   NL80211_REGDOM_TYPE_WORLD,
+   NL80211_REGDOM_TYPE_CUSTOM_WORLD,
+   NL80211_REGDOM_TYPE_INTERSECTION,
+};
+
+/**
+ * enum nl80211_reg_rule_attr - regulatory rule attributes
+ * @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional
+ *   considerations for a given frequency range. These are the
+ *   &enum nl80211_reg_rule_flags.
+ * @NL80211_ATTR_FREQ_RANGE_START: starting frequencry for the regulatory
+ *   rule in KHz. This is not a center of frequency but an actual regulatory
+ *   band edge.
+ * @NL80211_ATTR_FREQ_RANGE_END: ending frequency for the regulatory rule
+ *   in KHz. This is not a center a frequency but an actual regulatory
+ *   band edge.
+ * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this
+ *   frequency range, in KHz.
+ * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain
+ *   for a given frequency range. The value is in mBi (100 * dBi).
+ *   If you don't have one then don't send this.
+ * @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for
+ *   a given frequency range. The value is in mBm (100 * dBm).
+ */
+enum nl80211_reg_rule_attr {
+   __NL80211_REG_RULE_ATTR_INVALID,
+   NL80211_ATTR_REG_RULE_FLAGS,
+
+   NL80211_ATTR_FREQ_RANGE_START,
+   NL80211_ATTR_FREQ_RANGE_END,
+   NL80211_ATTR_FREQ_RANGE_MAX_BW,
+
+   NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
+   NL80211_ATTR_POWER_RULE_MAX_EIRP,
+
+   /* keep last */
+   __NL80211_REG_RULE_ATTR_AFTER_LAST,
+   NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_reg_rule_flags - regulatory rule flags
+ *
+ * @NL80211_RRF_NO_OFDM: OFDM modulation not allowed
+ * @NL80211_RRF_NO_CCK: CCK modulation not allowed
+ * @NL80211_RRF_NO_INDOOR: indoor operation not allowed
+ * @NL80211_RRF_NO_OUTDOOR: outdoor operation not allowed
+ * @NL80211_RRF_DFS: DFS support is required to be used
+ * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links
+ * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links
+ * @NL80211_RRF_PASSIVE_SCAN: passive scan is required
+ * @NL80211_RRF_NO_IBSS: no IBSS is allowed
+ */
+enum nl80211_reg_rule_flags {
+   NL80211_RRF_NO_OFDM      = 1<<0,
+   NL80211_RRF_NO_CCK      = 1<<1,
+   NL80211_RRF_NO_INDOOR      = 1<<2,
+   NL80211_RRF_NO_OUTDOOR      = 1<<3,
+   NL80211_RRF_DFS         = 1<<4,
+   NL80211_RRF_PTP_ONLY      = 1<<5,
+   NL80211_RRF_PTMP_ONLY      = 1<<6,
+   NL80211_RRF_PASSIVE_SCAN   = 1<<7,
+   NL80211_RRF_NO_IBSS      = 1<<8,
+};
+
+/**
+ * enum nl80211_survey_info - survey information
+ *
+ * These attribute types are used with %NL80211_ATTR_SURVEY_INFO
+ * when getting information about a survey.
+ *
+ * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel
+ * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm)
+ */
+enum nl80211_survey_info {
+   __NL80211_SURVEY_INFO_INVALID,
+   NL80211_SURVEY_INFO_FREQUENCY,
+   NL80211_SURVEY_INFO_NOISE,
+
+   /* keep last */
+   __NL80211_SURVEY_INFO_AFTER_LAST,
+   NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_mntr_flags - monitor configuration flags
+ *
+ * Monitor configuration flags.
+ *
+ * @__NL80211_MNTR_FLAG_INVALID: reserved
+ *
+ * @NL80211_MNTR_FLAG_FCSFAIL: pass frames with bad FCS
+ * @NL80211_MNTR_FLAG_PLCPFAIL: pass frames with bad PLCP
+ * @NL80211_MNTR_FLAG_CONTROL: pass control frames
+ * @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering
+ * @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing.
+ *   overrides all other flags.
+ *
+ * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use
+ * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag
+ */
+enum nl80211_mntr_flags {
+   __NL80211_MNTR_FLAG_INVALID,
+   NL80211_MNTR_FLAG_FCSFAIL,
+   NL80211_MNTR_FLAG_PLCPFAIL,
+   NL80211_MNTR_FLAG_CONTROL,
+   NL80211_MNTR_FLAG_OTHER_BSS,
+   NL80211_MNTR_FLAG_COOK_FRAMES,
+
+   /* keep last */
+   __NL80211_MNTR_FLAG_AFTER_LAST,
+   NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_meshconf_params - mesh configuration parameters
+ *
+ * Mesh configuration parameters
+ *
+ * @__NL80211_MESHCONF_INVALID: internal use
+ *
+ * @NL80211_MESHCONF_RETRY_TIMEOUT: specifies the initial retry timeout in
+ * millisecond units, used by the Peer Link Open message
+ *
+ * @NL80211_MESHCONF_CONFIRM_TIMEOUT: specifies the inital confirm timeout, in
+ * millisecond units, used by the peer link management to close a peer link
+ *
+ * @NL80211_MESHCONF_HOLDING_TIMEOUT: specifies the holding timeout, in
+ * millisecond units
+ *
+ * @NL80211_MESHCONF_MAX_PEER_LINKS: maximum number of peer links allowed
+ * on this mesh interface
+ *
+ * @NL80211_MESHCONF_MAX_RETRIES: specifies the maximum number of peer link
+ * open retries that can be sent to establish a new peer link instance in a
+ * mesh
+ *
+ * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh
+ * point.
+ *
+ * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically
+ * open peer links when we detect compatible mesh peers.
+ *
+ * @NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: the number of action frames
+ * containing a PREQ that an MP can send to a particular destination (path
+ * target)
+ *
+ * @NL80211_MESHCONF_PATH_REFRESH_TIME: how frequently to refresh mesh paths
+ * (in milliseconds)
+ *
+ * @NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT: minimum length of time to wait
+ * until giving up on a path discovery (in milliseconds)
+ *
+ * @NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT: The time (in TUs) for which mesh
+ * points receiving a PREQ shall consider the forwarding information from the
+ * root to be valid. (TU = time unit)
+ *
+ * @NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL: The minimum interval of time (in
+ * TUs) during which an MP can send only one action frame containing a PREQ
+ * reference element
+ *
+ * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs)
+ * that it takes for an HWMP information element to propagate across the mesh
+ *
+ * @NL80211_MESHCONF_ROOTMODE: whether root mode is enabled or not
+ *
+ * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
+ *
+ * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_meshconf_params {
+   __NL80211_MESHCONF_INVALID,
+   NL80211_MESHCONF_RETRY_TIMEOUT,
+   NL80211_MESHCONF_CONFIRM_TIMEOUT,
+   NL80211_MESHCONF_HOLDING_TIMEOUT,
+   NL80211_MESHCONF_MAX_PEER_LINKS,
+   NL80211_MESHCONF_MAX_RETRIES,
+   NL80211_MESHCONF_TTL,
+   NL80211_MESHCONF_AUTO_OPEN_PLINKS,
+   NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
+   NL80211_MESHCONF_PATH_REFRESH_TIME,
+   NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
+   NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
+   NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
+   NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
+   NL80211_MESHCONF_HWMP_ROOTMODE,
+
+   /* keep last */
+   __NL80211_MESHCONF_ATTR_AFTER_LAST,
+   NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_txq_attr - TX queue parameter attributes
+ * @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved
+ * @NL80211_TXQ_ATTR_QUEUE: TX queue identifier (NL80211_TXQ_Q_*)
+ * @NL80211_TXQ_ATTR_TXOP: Maximum burst time in units of 32 usecs, 0 meaning
+ *   disabled
+ * @NL80211_TXQ_ATTR_CWMIN: Minimum contention window [a value of the form
+ *   2^n-1 in the range 1..32767]
+ * @NL80211_TXQ_ATTR_CWMAX: Maximum contention window [a value of the form
+ *   2^n-1 in the range 1..32767]
+ * @NL80211_TXQ_ATTR_AIFS: Arbitration interframe space [0..255]
+ * @__NL80211_TXQ_ATTR_AFTER_LAST: Internal
+ * @NL80211_TXQ_ATTR_MAX: Maximum TXQ attribute number
+ */
+enum nl80211_txq_attr {
+   __NL80211_TXQ_ATTR_INVALID,
+   NL80211_TXQ_ATTR_QUEUE,
+   NL80211_TXQ_ATTR_TXOP,
+   NL80211_TXQ_ATTR_CWMIN,
+   NL80211_TXQ_ATTR_CWMAX,
+   NL80211_TXQ_ATTR_AIFS,
+
+   /* keep last */
+   __NL80211_TXQ_ATTR_AFTER_LAST,
+   NL80211_TXQ_ATTR_MAX = __NL80211_TXQ_ATTR_AFTER_LAST - 1
+};
+
+enum nl80211_txq_q {
+   NL80211_TXQ_Q_VO,
+   NL80211_TXQ_Q_VI,
+   NL80211_TXQ_Q_BE,
+   NL80211_TXQ_Q_BK
+};
+
+enum nl80211_channel_type {
+   NL80211_CHAN_NO_HT,
+   NL80211_CHAN_HT20,
+   NL80211_CHAN_HT40MINUS,
+   NL80211_CHAN_HT40PLUS
+};
+
+/**
+ * enum nl80211_bss - netlink attributes for a BSS
+ *
+ * @__NL80211_BSS_INVALID: invalid
+ * @NL80211_BSS_FREQUENCY: frequency in MHz (u32)
+ * @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64)
+ * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16)
+ * @NL80211_BSS_CAPABILITY: capability field (CPU order, u16)
+ * @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the
+ *   raw information elements from the probe response/beacon (bin)
+ * @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon
+ *   in mBm (100 * dBm) (s32)
+ * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon
+ *   in unspecified units, scaled to 0..100 (u8)
+ * @NL80211_BSS_STATUS: status, if this BSS is "used"
+ * @NL80211_BSS_SEEN_MS_AGO: age of this BSS entry in ms
+ * @__NL80211_BSS_AFTER_LAST: internal
+ * @NL80211_BSS_MAX: highest BSS attribute
+ */
+enum nl80211_bss {
+   __NL80211_BSS_INVALID,
+   NL80211_BSS_BSSID,
+   NL80211_BSS_FREQUENCY,
+   NL80211_BSS_TSF,
+   NL80211_BSS_BEACON_INTERVAL,
+   NL80211_BSS_CAPABILITY,
+   NL80211_BSS_INFORMATION_ELEMENTS,
+   NL80211_BSS_SIGNAL_MBM,
+   NL80211_BSS_SIGNAL_UNSPEC,
+   NL80211_BSS_STATUS,
+   NL80211_BSS_SEEN_MS_AGO,
+
+   /* keep last */
+   __NL80211_BSS_AFTER_LAST,
+   NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_bss_status - BSS "status"
+ */
+enum nl80211_bss_status {
+   NL80211_BSS_STATUS_AUTHENTICATED,
+   NL80211_BSS_STATUS_ASSOCIATED,
+   NL80211_BSS_STATUS_IBSS_JOINED,
+};
+
+/**
+ * enum nl80211_auth_type - AuthenticationType
+ *
+ * @NL80211_AUTHTYPE_OPEN_SYSTEM: Open System authentication
+ * @NL80211_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only)
+ * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r)
+ * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP)
+ * @__NL80211_AUTHTYPE_NUM: internal
+ * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm
+ * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by
+ *   trying multiple times); this is invalid in netlink -- leave out
+ *   the attribute for this on CONNECT commands.
+ */
+enum nl80211_auth_type {
+   NL80211_AUTHTYPE_OPEN_SYSTEM,
+   NL80211_AUTHTYPE_SHARED_KEY,
+   NL80211_AUTHTYPE_FT,
+   NL80211_AUTHTYPE_NETWORK_EAP,
+
+   /* keep last */
+   __NL80211_AUTHTYPE_NUM,
+   NL80211_AUTHTYPE_MAX = __NL80211_AUTHTYPE_NUM - 1,
+   NL80211_AUTHTYPE_AUTOMATIC
+};
+
+/**
+ * enum nl80211_key_type - Key Type
+ * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key
+ * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key
+ * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS)
+ */
+enum nl80211_key_type {
+   NL80211_KEYTYPE_GROUP,
+   NL80211_KEYTYPE_PAIRWISE,
+   NL80211_KEYTYPE_PEERKEY,
+};
+
+/**
+ * enum nl80211_mfp - Management frame protection state
+ * @NL80211_MFP_NO: Management frame protection not used
+ * @NL80211_MFP_REQUIRED: Management frame protection required
+ */
+enum nl80211_mfp {
+   NL80211_MFP_NO,
+   NL80211_MFP_REQUIRED,
+};
+
+enum nl80211_wpa_versions {
+   NL80211_WPA_VERSION_1 = 1 << 0,
+   NL80211_WPA_VERSION_2 = 1 << 1,
+};
+
+/**
+ * enum nl80211_key_attributes - key attributes
+ * @__NL80211_KEY_INVALID: invalid
+ * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of
+ *   16 bytes encryption key followed by 8 bytes each for TX and RX MIC
+ *   keys
+ * @NL80211_KEY_IDX: key ID (u8, 0-3)
+ * @NL80211_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11
+ *   section 7.3.2.25.1, e.g. 0x000FAC04)
+ * @NL80211_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and
+ *   CCMP keys, each six bytes in little endian
+ * @NL80211_KEY_DEFAULT: flag indicating default key
+ * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key
+ * @__NL80211_KEY_AFTER_LAST: internal
+ * @NL80211_KEY_MAX: highest key attribute
+ */
+enum nl80211_key_attributes {
+   __NL80211_KEY_INVALID,
+   NL80211_KEY_DATA,
+   NL80211_KEY_IDX,
+   NL80211_KEY_CIPHER,
+   NL80211_KEY_SEQ,
+   NL80211_KEY_DEFAULT,
+   NL80211_KEY_DEFAULT_MGMT,
+
+   /* keep last */
+   __NL80211_KEY_AFTER_LAST,
+   NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1
+};
+
+#endif /* __LINUX_NL80211_H */
diff --git a/mac80211/ti-utils/nvs.c b/mac80211/ti-utils/nvs.c
new file mode 100644
index 0000000..dcd36a3
--- /dev/null
+++ b/mac80211/ti-utils/nvs.c
@@ -0,0 +1,836 @@
+/*
+ * PLT utility for wireless chip supported by TI's driver wl12xx
+ *
+ * See README and COPYING for more details.
+ */
+
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <netinet/in.h>
+
+#include <netlink/netlink.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+#include <linux/wireless.h>
+#include "nl80211.h"
+
+#include "calibrator.h"
+#include "plt.h"
+#include "ini.h"
+/* 2048 - it should be enough for any chip, until... 22dec2010 */
+#define BUF_SIZE_4_NVS_FILE    2048
+
+static const char if_name_fmt[] = "wlan%d";
+
+int nvs_fill_radio_params(int fd, struct wl12xx_ini *ini, char *buf)
+{
+    int size;
+    struct wl1271_ini *gp;
+
+    if (ini) {
+        gp = &ini->ini1271;
+    }
+
+    size  = sizeof(struct wl1271_ini);
+
+    if (ini) {    /* for reference NVS */
+        unsigned char *c = (unsigned char *)gp;
+        int i;
+
+        for (i = 0; i < size; i++) {
+            write(fd, c++, 1);
+        }
+    } else {
+        char *p = buf + 0x1D4;
+        write(fd, (const void *)p, size);
+    }
+
+    return 0;
+}
+
+static int nvs_fill_radio_params_128x(int fd, struct wl12xx_ini *ini, char *buf)
+{
+    int size;
+    struct wl128x_ini *gp = &ini->ini128x;
+
+    size  = sizeof(struct wl128x_ini);
+
+    if (ini) {    /* for reference NVS */
+        unsigned char *c = (unsigned char *)gp;
+        int i;
+
+        for (i = 0; i < size; i++) {
+            write(fd, c++, 1);
+        }
+
+    } else {
+        char *p = buf + 0x1D4;
+        write(fd, p, size);
+    }
+
+    return 0;
+}
+
+int nvs_set_autofem(int fd, char *buf, unsigned char val)
+{
+    int size;
+    struct wl1271_ini *gp;
+    unsigned char *c;
+    int i;
+
+    if (buf == NULL) {
+        return 1;
+    }
+
+    gp = (struct wl1271_ini *)(buf+0x1d4);
+    gp->general_params.tx_bip_fem_auto_detect = val;
+
+    size  = sizeof(struct wl1271_ini);
+
+    c = (unsigned char *)gp;
+
+    for (i = 0; i < size; i++) {
+        write(fd, c++, 1);
+    }
+
+    return 0;
+}
+
+int nvs_set_autofem_128x(int fd, char *buf, unsigned char val)
+{
+    int size;
+    struct wl128x_ini *gp;
+    unsigned char *c;
+    int i;
+
+    if (buf == NULL) {
+        return 1;
+    }
+
+    gp = (struct wl128x_ini *)(buf+0x1d4);
+    gp->general_params.tx_bip_fem_auto_detect = val;
+
+    size  = sizeof(struct wl128x_ini);
+
+    c = (unsigned char *)gp;
+
+    for (i = 0; i < size; i++) {
+        write(fd, c++, 1);
+    }
+
+    return 0;
+}
+
+int nvs_set_fem_manuf(int fd, char *buf, unsigned char val)
+{
+    int size;
+    struct wl1271_ini *gp;
+    unsigned char *c;
+    int i;
+
+    if (buf == NULL) {
+        return 1;
+    }
+
+    gp = (struct wl1271_ini *)(buf+0x1d4);
+    gp->general_params.tx_bip_fem_manufacturer = val;
+
+    size  = sizeof(struct wl1271_ini);
+
+    c = (unsigned char *)gp;
+
+    for (i = 0; i < size; i++) {
+        write(fd, c++, 1);
+    }
+
+    return 0;
+}
+
+int nvs_set_fem_manuf_128x(int fd, char *buf, unsigned char val)
+{
+    int size;
+    struct wl128x_ini *gp;
+    unsigned char *c;
+    int i;
+
+    if (buf == NULL) {
+        return 1;
+    }
+
+    gp = (struct wl128x_ini *)(buf+0x1d4);
+    gp->general_params.tx_bip_fem_manufacturer = val;
+
+    size  = sizeof(struct wl128x_ini);
+
+    c = (unsigned char *)gp;
+
+    for (i = 0; i < size; i++) {
+        write(fd, c++, 1);
+    }
+
+    return 0;
+}
+
+static struct wl12xx_nvs_ops wl1271_nvs_ops = {
+    .nvs_fill_radio_prms = nvs_fill_radio_params,
+    .nvs_set_autofem = nvs_set_autofem,
+    .nvs_set_fem_manuf = nvs_set_fem_manuf,
+};
+
+static struct wl12xx_nvs_ops wl128x_nvs_ops = {
+    .nvs_fill_radio_prms = nvs_fill_radio_params_128x,
+    .nvs_set_autofem = nvs_set_autofem_128x,
+    .nvs_set_fem_manuf = nvs_set_fem_manuf_128x,
+};
+
+int get_mac_addr(int ifc_num, unsigned char *mac_addr)
+{
+    int s;
+    struct ifreq ifr;
+#if 0
+    if (ifc_num < 0 || ifc_num >= ETH_DEV_MAX)
+        return 1;
+#endif
+    s = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+    if (s < 0) {
+        fprintf(stderr, "unable to socket (%s)\n", strerror(errno));
+        return 1;
+    }
+
+    memset(&ifr, 0, sizeof(struct ifreq));
+    sprintf(ifr.ifr_name, if_name_fmt, ifc_num) ;
+    if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
+        fprintf(stderr, "unable to ioctl (%s)\n", strerror(errno));
+        close(s);
+        return 1;
+    }
+
+    close(s);
+
+    memcpy(mac_addr, &ifr.ifr_ifru.ifru_hwaddr.sa_data[0], 6);
+
+    return 0;
+}
+
+int file_exist(const char *filename)
+{
+    struct stat buf;
+    int ret;
+
+    if (filename == NULL) {
+        fprintf(stderr, "wrong parameter\n");
+        return -1;
+    }
+
+    ret = stat(filename, &buf);
+    if (ret != 0) {
+        fprintf(stderr, "fail to stat file %s (%s)\n", filename,
+            strerror(errno));
+        return -1;
+    }
+
+    return (int)buf.st_size;
+}
+
+void cfg_nvs_ops(struct wl12xx_common *cmn)
+{
+    if (cmn->arch == WL1271_ARCH) {
+        cmn->nvs_ops = &wl1271_nvs_ops;
+    } else {
+        cmn->nvs_ops = &wl128x_nvs_ops;
+    }
+}
+
+static int read_from_current_nvs(const char *nvs_file,
+    char *buf, int size, int *nvs_sz)
+{
+    int curr_nvs, ret;
+
+    curr_nvs = open(nvs_file, O_RDONLY, S_IRUSR | S_IWUSR);
+    if (curr_nvs < 0) {
+        fprintf(stderr, "%s> Unable to open NVS file for reference "
+            "(%s)\n", __func__, strerror(errno));
+        return 1;
+    }
+
+    ret = read(curr_nvs, buf, size);
+    if (ret < 0) {
+        fprintf(stderr, "Fail to read file %s (%s)", nvs_file,
+            strerror(errno));
+        close(curr_nvs);
+        return 1;
+    }
+
+    if (nvs_sz) {
+        *nvs_sz = ret;
+    }
+
+    close(curr_nvs);
+
+    //printf("Read NVS file (%s) of size %d\n", nvs_file, ret);
+
+    return 0;
+}
+
+static int read_nvs(const char *nvs_file, char *buf,
+    int size, int *nvs_sz)
+{
+    int fl_sz;
+    char file2read[FILENAME_MAX];
+
+    if (nvs_file == NULL || strlen(nvs_file) < 2) {
+        printf("\nThe path to NVS file not provided, "
+            "use default (%s)\n", CURRENT_NVS_NAME);
+
+        strncpy(file2read, CURRENT_NVS_NAME, strlen(CURRENT_NVS_NAME));
+
+    } else
+        strncpy(file2read, nvs_file, strlen(nvs_file));
+
+    fl_sz = file_exist(file2read);
+    if (fl_sz < 0) {
+        fprintf(stderr, "File %s not exists\n", CURRENT_NVS_NAME);
+        return 1;
+    }
+
+    return read_from_current_nvs(file2read, buf, size, nvs_sz);
+}
+
+static int fill_nvs_def_rx_params(int fd)
+{
+    unsigned char type = eNVS_RADIO_RX_PARAMETERS;
+    unsigned short length = NVS_RX_PARAM_LENGTH;
+    int i;
+
+    /* Rx type */
+    write(fd, &type, 1);
+
+    /* Rx length */
+    write(fd, &length, 2);
+
+    type = DEFAULT_EFUSE_VALUE; /* just reuse of var */
+    for (i = 0; i < NVS_RX_PARAM_LENGTH; i++) {
+        write(fd, &type, 1);
+    }
+
+    return 0;
+}
+
+static void nvs_parse_data(const unsigned char *buf,
+    struct wl1271_cmd_cal_p2g *pdata, unsigned int *pver)
+{
+#define BUFFER_INDEX    (buf_idx + START_PARAM_INDEX + info_idx)
+    unsigned short buf_idx;
+    unsigned char tlv_type;
+    unsigned short tlv_len;
+    unsigned short info_idx;
+    unsigned int nvsTypeInfo;
+    unsigned char nvs_ver_oct_idx;
+    unsigned char shift;
+
+    for (buf_idx = 0; buf_idx < NVS_TOTAL_LENGTH;) {
+        tlv_type = buf[buf_idx];
+
+        /* fill the correct mode to fill the NVS struct buffer */
+        /* if the tlv_type is the last type break from the loop */
+        switch (tlv_type) {
+        case eNVS_RADIO_TX_PARAMETERS:
+            nvsTypeInfo = eNVS_RADIO_TX_TYPE_PARAMETERS_INFO;
+            break;
+        case eNVS_RADIO_RX_PARAMETERS:
+            nvsTypeInfo = eNVS_RADIO_RX_TYPE_PARAMETERS_INFO;
+            break;
+        case eNVS_VERSION:
+            for (*pver = 0, nvs_ver_oct_idx = 0;
+                nvs_ver_oct_idx < NVS_VERSION_PARAMETER_LENGTH;
+                nvs_ver_oct_idx++) {
+                shift = 8 * (NVS_VERSION_PARAMETER_LENGTH -
+                    1 - nvs_ver_oct_idx);
+                *pver += ((buf[buf_idx + START_PARAM_INDEX +
+                    nvs_ver_oct_idx]) << shift);
+            }
+            break;
+        case eTLV_LAST:
+        default:
+            return;
+        }
+
+        tlv_len = (buf[buf_idx + START_LENGTH_INDEX  + 1] << 8) +
+            buf[buf_idx + START_LENGTH_INDEX];
+
+        /* if TLV type is not NVS ver fill the NVS according */
+        /* to the mode TX/RX */
+        if ((eNVS_RADIO_TX_PARAMETERS == tlv_type) ||
+            (eNVS_RADIO_RX_PARAMETERS == tlv_type)) {
+            pdata[nvsTypeInfo].type = tlv_type;
+            pdata[nvsTypeInfo].len = tlv_len;
+
+            for (info_idx = 0; (info_idx < tlv_len) &&
+                (BUFFER_INDEX < NVS_TOTAL_LENGTH);
+                    info_idx++) {
+                pdata[nvsTypeInfo].buf[info_idx] =
+                    buf[BUFFER_INDEX];
+            }
+        }
+
+        /* increment to the next TLV */
+        buf_idx += START_PARAM_INDEX + tlv_len;
+    }
+}
+
+static int nvs_fill_version(int fd, unsigned int *pdata)
+{
+    unsigned char tmp = eNVS_VERSION;
+    unsigned short tmp2 = NVS_VERSION_PARAMETER_LENGTH;
+
+    write(fd, &tmp, 1);
+
+    write(fd, &tmp2, 2);
+
+    tmp = (*pdata >> 16) & 0xff;
+    write(fd, &tmp, 1);
+
+    tmp = (*pdata >> 8) & 0xff;
+    write(fd, &tmp, 1);
+
+    tmp = *pdata & 0xff;
+    write(fd, &tmp, 1);
+
+    return 0;
+}
+
+static int nvs_fill_old_rx_data(int fd, const unsigned char *buf,
+    unsigned short len)
+{
+    unsigned short idx;
+    unsigned char rx_type;
+
+    /* RX BiP type */
+    rx_type = eNVS_RADIO_RX_PARAMETERS;
+    write(fd, &rx_type, 1);
+
+    /* RX BIP Length */
+    write(fd, &len, 2);
+
+    for (idx = 0; idx < len; idx++) {
+        write(fd, &(buf[idx]), 1);
+    }
+
+    return 0;
+}
+
+static int nvs_upd_nvs_part(int fd, char *buf)
+{
+    char *p = buf;
+
+    write(fd, p, 0x1D4);
+
+    return 0;
+}
+
+static int nvs_fill_nvs_part(int fd)
+{
+    int i;
+    unsigned char mac_addr[MAC_ADDR_LEN] = {
+         0x0b, 0xad, 0xde, 0xad, 0xbe, 0xef
+    };
+    __le16 nvs_tx_sz = NVS_TX_PARAM_LENGTH;
+    __le32 nvs_ver = 0x0;
+    const unsigned char vals[] = {
+        0x0, 0x1, 0x6d, 0x54, 0x71, eTLV_LAST, eNVS_RADIO_TX_PARAMETERS
+    };
+
+    write(fd, &vals[1], 1);
+    write(fd, &vals[2], 1);
+    write(fd, &vals[3], 1);
+#if 0
+    if (get_mac_addr(0, mac_addr)) {
+        fprintf(stderr, "%s> Fail to get mac address\n", __func__);
+        return 1;
+    }
+#endif
+    /* write down MAC address in new NVS file */
+    write(fd, &mac_addr[5], 1);
+    write(fd, &mac_addr[4], 1);
+    write(fd, &mac_addr[3], 1);
+    write(fd, &mac_addr[2], 1);
+
+    write(fd, &vals[1], 1);
+    write(fd, &vals[4], 1);
+    write(fd, &vals[3], 1);
+
+    write(fd, &mac_addr[1], 1);
+    write(fd, &mac_addr[0], 1);
+
+    write(fd, &vals[0], 1);
+    write(fd, &vals[0], 1);
+
+    /* fill end burst transaction zeros */
+    for (i = 0; i < NVS_END_BURST_TRANSACTION_LENGTH; i++) {
+        write(fd, &vals[0], 1);
+    }
+
+    /* fill zeros to Align TLV start address */
+    for (i = 0; i < NVS_ALING_TLV_START_ADDRESS_LENGTH; i++) {
+        write(fd, &vals[0], 1);
+    } 
+
+    /* Fill Tx calibration part */
+    write(fd, &vals[6], 1);
+    write(fd, &nvs_tx_sz, 2);
+
+    for (i = 0; i < nvs_tx_sz; i++) {
+        write(fd, &vals[0], 1);
+    }
+
+    /* Fill Rx calibration part */
+    fill_nvs_def_rx_params(fd);
+
+    /* fill NVS version */
+    if (nvs_fill_version(fd, &nvs_ver)) {
+        fprintf(stderr, "Fail to fill version\n");
+    }
+
+    /* fill end of NVS */
+    write(fd, &vals[5], 1); /* eTLV_LAST */
+    write(fd, &vals[5], 1); /* eTLV_LAST */
+    write(fd, &vals[0], 1);
+    write(fd, &vals[0], 1);
+
+    return 0;
+}
+
+int prepare_nvs_file(void *arg, char *file_name)
+{
+    int new_nvs, i, nvs_size;
+    unsigned char mac_addr[MAC_ADDR_LEN];
+    struct wl1271_cmd_cal_p2g *pdata;
+    struct wl1271_cmd_cal_p2g old_data[eNUMBER_RADIO_TYPE_PARAMETERS_INFO];
+    char buf[2048];
+    unsigned char *p;
+    struct wl12xx_common cmn = {
+        .arch = UNKNOWN_ARCH,
+        .parse_ops = NULL
+    };
+
+    const unsigned char vals[] = {
+        0x0, 0x1, 0x6d, 0x54, 0x71, eTLV_LAST, eNVS_RADIO_TX_PARAMETERS
+    };
+
+    if (arg == NULL) {
+        fprintf(stderr, "%s> Missing args\n", __func__);
+        return 1;
+    }
+
+    if (read_nvs(file_name, buf, BUF_SIZE_4_NVS_FILE, &nvs_size)) {
+        return 1;
+    }
+
+    switch (nvs_size) {
+        case NVS_FILE_SIZE_127X:
+            cmn.arch = WL1271_ARCH;
+        break;
+        case NVS_FILE_SIZE_128X:
+            cmn.arch = WL128X_ARCH;
+        break;
+        default:
+            fprintf(stderr, "%s> Wrong file size\n", __func__);
+        return 1;
+    }
+
+    cfg_nvs_ops(&cmn);
+
+    /* create new NVS file */
+    new_nvs = open(NEW_NVS_NAME,
+        O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+    if (new_nvs < 0) {
+        fprintf(stderr, "%s> Unable to open new NVS file\n", __func__);
+        return 1;
+    }
+
+    write(new_nvs, &vals[1], 1);
+    write(new_nvs, &vals[2], 1);
+    write(new_nvs, &vals[3], 1);
+
+    if (get_mac_addr(0, mac_addr)) {
+        fprintf(stderr, "%s> Fail to get mac addr\n", __func__);
+        close(new_nvs);
+        return 1;
+    }
+
+    /* write down MAC address in new NVS file */
+    write(new_nvs, &mac_addr[5], 1);
+    write(new_nvs, &mac_addr[4], 1);
+    write(new_nvs, &mac_addr[3], 1);
+    write(new_nvs, &mac_addr[2], 1);
+
+    write(new_nvs, &vals[1], 1);
+    write(new_nvs, &vals[4], 1);
+    write(new_nvs, &vals[3], 1);
+
+    write(new_nvs, &mac_addr[1], 1);
+    write(new_nvs, &mac_addr[0], 1);
+
+    write(new_nvs, &vals[0], 1);
+    write(new_nvs, &vals[0], 1);
+
+    /* fill end burst transaction zeros */
+    for (i = 0; i < NVS_END_BURST_TRANSACTION_LENGTH; i++) {
+        write(new_nvs, &vals[0], 1);
+    }
+
+    /* fill zeros to Align TLV start address */
+    for (i = 0; i < NVS_ALING_TLV_START_ADDRESS_LENGTH; i++) {
+        write(new_nvs, &vals[0], 1);
+    }
+
+    /* Fill TxBip */
+    pdata = (struct wl1271_cmd_cal_p2g *)arg;
+
+    write(new_nvs, &vals[6], 1);
+    write(new_nvs, &pdata->len, 2);
+
+    p = (unsigned char *)&(pdata->buf);
+    for (i = 0; i < pdata->len; i++) {
+        write(new_nvs, p++, 1);
+    }
+
+    {
+        unsigned int old_ver;
+#if 0
+        {
+            unsigned char *p = (unsigned char *)buf;
+            for (old_ver = 0; old_ver < 1024; old_ver++) {
+                if (old_ver%16 == 0)
+                    printf("\n");
+                printf("%02x ", *p++);
+            }
+        }
+#endif
+        memset(old_data, 0,
+            sizeof(struct wl1271_cmd_cal_p2g)*
+                eNUMBER_RADIO_TYPE_PARAMETERS_INFO);
+        nvs_parse_data((const unsigned char *)&buf[NVS_PRE_PARAMETERS_LENGTH],
+            old_data, &old_ver);
+
+        nvs_fill_old_rx_data(new_nvs,
+            old_data[eNVS_RADIO_RX_TYPE_PARAMETERS_INFO].buf,
+            old_data[eNVS_RADIO_RX_TYPE_PARAMETERS_INFO].len);
+    }
+
+    /* fill NVS version */
+    if (nvs_fill_version(new_nvs, &pdata->ver)) {
+        fprintf(stderr, "Fail to fill version\n");
+    }
+
+    /* fill end of NVS */
+    write(new_nvs, &vals[5], 1); /* eTLV_LAST */
+    write(new_nvs, &vals[5], 1); /* eTLV_LAST */
+    write(new_nvs, &vals[0], 1);
+    write(new_nvs, &vals[0], 1);
+
+    /* fill radio params */
+    if (cmn.nvs_ops->nvs_fill_radio_prms(new_nvs, NULL, buf)) {
+        fprintf(stderr, "Fail to fill radio params\n");
+    }
+
+    close(new_nvs);
+
+    return 0;
+}
+
+int create_nvs_file(struct wl12xx_common *cmn)
+{
+    int new_nvs, res = 0;
+    char buf[2048];
+
+    /* create new NVS file */
+    new_nvs = open(NEW_NVS_NAME,
+        O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+    if (new_nvs < 0) {
+        fprintf(stderr, "%s> Unable to open new NVS file\n", __func__);
+        return 1;
+    }
+
+    /* fill nvs part */
+    if (nvs_fill_nvs_part(new_nvs)) {
+        fprintf(stderr, "Fail to fill NVS part\n");
+        res = 1;
+
+        goto out;
+    }
+
+    /* fill radio params */
+    if (cmn->nvs_ops->nvs_fill_radio_prms(new_nvs, &cmn->ini, buf)) {
+        fprintf(stderr, "Fail to fill radio params\n");
+        res = 1;
+    }
+
+out:
+    close(new_nvs);
+
+    return res;
+}
+
+int update_nvs_file(const char *nvs_file, struct wl12xx_common *cmn)
+{
+    int new_nvs, res = 0;
+    char buf[2048];
+
+    res = read_nvs(nvs_file, buf, BUF_SIZE_4_NVS_FILE, NULL);
+    if (res) {
+        return 1;
+    }
+
+    /* create new NVS file */
+    new_nvs = open(NEW_NVS_NAME,
+        O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+    if (new_nvs < 0) {
+        fprintf(stderr, "%s> Unable to open new NVS file\n", __func__);
+        return 1;
+    }
+
+    /* fill nvs part */
+    if (nvs_upd_nvs_part(new_nvs, buf)) {
+        fprintf(stderr, "Fail to fill NVS part\n");
+        res = 1;
+
+        goto out;
+    }
+
+    /* fill radio params */
+    if (cmn->nvs_ops->nvs_fill_radio_prms(new_nvs, &cmn->ini, buf)) {
+        printf("Fail to fill radio params\n");
+        res = 1;
+    }
+
+out:
+    close(new_nvs);
+
+    return res;
+}
+
+int dump_nvs_file(const char *nvs_file, struct wl12xx_common *cmn)
+{
+    int sz=0, size;
+    char buf[2048];
+    unsigned char *p = (unsigned char *)buf;
+
+    if (read_nvs(nvs_file, buf, BUF_SIZE_4_NVS_FILE, &size)) {
+        return 1;
+    }
+
+    printf("\nThe size is %d bytes\n", size);
+
+    for ( ; sz < size; sz++) {
+        if (sz%16 == 0) {
+            printf("\n %04X ", sz);
+        }
+        printf("%02x ", *p++);
+    }
+    printf("\n");
+
+    return 0;
+}
+
+int set_nvs_file_autofem(const char *nvs_file, unsigned char val,
+    struct wl12xx_common *cmn)
+{
+    int new_nvs, res = 0;
+    char buf[2048];
+    int nvs_file_sz;
+
+    res = read_nvs(nvs_file, buf, BUF_SIZE_4_NVS_FILE, &nvs_file_sz);
+    if (res) {
+        return 1;
+    }
+
+    if (nvs_get_arch(nvs_file_sz, cmn)) {
+        fprintf(stderr, "Fail to define architecture\n");
+        return 1;
+    }
+
+    cfg_nvs_ops(cmn);
+
+    /* create new NVS file */
+    new_nvs = open(NEW_NVS_NAME,
+        O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+    if (new_nvs < 0) {
+        fprintf(stderr, "%s> Unable to open new NVS file\n", __func__);
+        return 1;
+    }
+
+    /* fill nvs part */
+    if (nvs_upd_nvs_part(new_nvs, buf)) {
+        fprintf(stderr, "Fail to fill NVS part\n");
+        res = 1;
+
+        goto out;
+    }
+
+    /* fill radio params */
+    if (cmn->nvs_ops->nvs_set_autofem(new_nvs, buf, val)) {
+        printf("Fail to fill radio params\n");
+        res = 1;
+    }
+
+out:
+    close(new_nvs);
+
+    return res;
+}
+
+int set_nvs_file_fem_manuf(const char *nvs_file, unsigned char val,
+    struct wl12xx_common *cmn)
+{
+    int new_nvs, res = 0;
+    char buf[2048];
+    int nvs_file_sz;
+
+    res = read_nvs(nvs_file, buf, BUF_SIZE_4_NVS_FILE, &nvs_file_sz);
+    if (res) {
+        return 1;
+    }
+
+    if (nvs_get_arch(nvs_file_sz, cmn)) {
+        fprintf(stderr, "Fail to define architecture\n");
+        return 1;
+    }
+
+    cfg_nvs_ops(cmn);
+
+    /* create new NVS file */
+    new_nvs = open(NEW_NVS_NAME,
+        O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+    if (new_nvs < 0) {
+        fprintf(stderr, "%s> Unable to open new NVS file\n", __func__);
+        return 1;
+    }
+
+    /* fill nvs part */
+    if (nvs_upd_nvs_part(new_nvs, buf)) {
+        fprintf(stderr, "Fail to fill NVS part\n");
+        res = 1;
+
+        goto out;
+    }
+
+    /* fill radio params */
+    if (cmn->nvs_ops->nvs_set_fem_manuf(new_nvs, buf, val)) {
+        printf("Fail to fill radio params\n");
+        res = 1;
+    }
+
+out:
+    close(new_nvs);
+
+    return res;
+}
+
diff --git a/mac80211/ti-utils/nvs.h b/mac80211/ti-utils/nvs.h
new file mode 100644
index 0000000..4043983
--- /dev/null
+++ b/mac80211/ti-utils/nvs.h
@@ -0,0 +1,23 @@
+#ifndef __NVS_H
+#define __NVS_H
+
+#define WL127X_NVS_FILE_SZ        912
+#define WL128X_NVS_FILE_SZ        1113
+
+int prepare_nvs_file(void *arg, char *file_name);
+
+void cfg_nvs_ops(struct wl12xx_common *cmn);
+
+int create_nvs_file(struct wl12xx_common *cmn);
+
+int update_nvs_file(const char *nvs_file, struct wl12xx_common *cmn);
+
+int dump_nvs_file(const char *nvs_file, struct wl12xx_common *cmn);
+
+int set_nvs_file_autofem(const char *nvs_file, unsigned char val,
+    struct wl12xx_common *cmn);
+
+int set_nvs_file_fem_manuf(const char *nvs_file, unsigned char val,
+    struct wl12xx_common *cmn);
+
+#endif /* __NVS_H */
diff --git a/mac80211/ti-utils/plt.c b/mac80211/ti-utils/plt.c
new file mode 100644
index 0000000..96153d4
--- /dev/null
+++ b/mac80211/ti-utils/plt.c
@@ -0,0 +1,723 @@
+/*
+ * PLT utility for wireless chip supported by TI's driver wl12xx
+ *
+ * See README and COPYING for more details.
+ */
+
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+#include <linux/wireless.h>
+#include "nl80211.h"
+
+#include "calibrator.h"
+#include "plt.h"
+#include "ini.h"
+#include "nvs.h"
+
+SECTION(plt);
+
+static void str2mac(unsigned char *pmac, char *pch)
+{
+    int i;
+
+    for (i = 0; i < MAC_ADDR_LEN; i++) {
+        pmac[i] = (unsigned char)strtoul(pch, &pch, 16);
+        pch++;
+    }
+}
+
+static int plt_power_mode(struct nl80211_state *state, struct nl_cb *cb,
+              struct nl_msg *msg, int argc, char **argv)
+{
+    struct nlattr *key;
+    unsigned int pmode;
+
+    if (argc != 1) {
+        fprintf(stderr, "%s> Missing arguments\n", __func__);
+        return 2;
+    }
+
+    if (strcmp(argv[0], "on") == 0) {
+        pmode = 1;
+    } else if (strcmp(argv[0], "off") == 0) {
+        pmode = 0;
+    } else {
+        fprintf(stderr, "%s> Invalid parameter\n", __func__);
+        return 2;
+    }
+
+    key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+    if (!key) {
+        fprintf(stderr, "%s> fail to nla_nest_start()\n", __func__);
+        return 1;
+    }
+
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_SET_PLT_MODE);
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_PLT_MODE, pmode);
+
+    nla_nest_end(msg, key);
+
+    return 0;
+
+nla_put_failure:
+    fprintf(stderr, "%s> building message failed\n", __func__);
+    return 2;
+}
+
+COMMAND(plt, power_mode, "<on|off>",
+    NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_power_mode,
+    "Set PLT power mode\n");
+
+static int plt_tune_channel(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    struct nlattr *key;
+    struct wl1271_cmd_cal_channel_tune prms;
+
+    if (argc < 1 || argc > 2) {
+        return 1;
+    }
+
+    prms.test.id = TEST_CMD_CHANNEL_TUNE;
+    prms.band = (unsigned char)atoi(argv[0]);
+    prms.channel = (unsigned char)atoi(argv[1]);
+
+    key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+    if (!key) {
+        fprintf(stderr, "fail to nla_nest_start()\n");
+        return 1;
+    }
+
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
+    NLA_PUT(msg, WL1271_TM_ATTR_DATA,
+        sizeof(struct wl1271_cmd_cal_channel_tune),
+        &prms);
+
+    nla_nest_end(msg, key);
+
+    return 0;
+
+nla_put_failure:
+    fprintf(stderr, "%s> building message failed\n", __func__);
+    return 2;
+}
+
+COMMAND(plt, tune_channel, "<band> <channel>",
+    NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_tune_channel,
+    "Set band and channel for PLT\n");
+
+static int plt_ref_point(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    struct nlattr *key;
+    struct wl1271_cmd_cal_update_ref_point prms;
+
+    if (argc < 1 || argc > 3){
+        return 1;
+    }
+
+    prms.test.id = TEST_CMD_UPDATE_PD_REFERENCE_POINT;
+    prms.ref_detector = atoi(argv[0]);
+    prms.ref_power = atoi(argv[1]);
+    prms.sub_band = atoi(argv[2]);
+
+    key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+    if (!key) {
+        fprintf(stderr, "fail to nla_nest_start()\n");
+        return 1;
+    }
+
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
+    NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
+
+    nla_nest_end(msg, key);
+
+    return 0;
+
+nla_put_failure:
+    fprintf(stderr, "%s> building message failed\n", __func__);
+    return 2;
+}
+
+COMMAND(plt, ref_point, "<voltage> <power> <subband>",
+    NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_ref_point,
+    "Set reference point for PLT\n");
+
+static int calib_valid_handler(struct nl_msg *msg, void *arg)
+{
+    struct nlattr *tb[NL80211_ATTR_MAX + 1];
+    struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+    struct nlattr *td[WL1271_TM_ATTR_MAX + 1];
+    struct wl1271_cmd_cal_p2g *prms;
+#if 0
+    int i; unsigned char *pc;
+#endif
+    nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+        genlmsg_attrlen(gnlh, 0), NULL);
+
+    if (!tb[NL80211_ATTR_TESTDATA]) {
+        fprintf(stderr, "no data!\n");
+        return NL_SKIP;
+    }
+
+    nla_parse(td, WL1271_TM_ATTR_MAX, nla_data(tb[NL80211_ATTR_TESTDATA]),
+        nla_len(tb[NL80211_ATTR_TESTDATA]), NULL);
+
+    prms = (struct wl1271_cmd_cal_p2g *)nla_data(td[WL1271_TM_ATTR_DATA]);
+
+    if (prms->radio_status) {
+        fprintf(stderr, "Fail to calibrate ith radio status (%d)\n",
+            (signed short)prms->radio_status);
+        return 2;
+    }
+#if 0
+    printf("%s> id %04x status %04x\ntest id %02x ver %08x len %04x=%d\n",
+        __func__,
+        prms->header.id, prms->header.status, prms->test.id,
+        prms->ver, prms->len, prms->len);
+
+        pc = (unsigned char *)prms->buf;
+        printf("++++++++++++++++++++++++\n");
+        for (i = 0; i < prms->len; i++) {
+            if (i%0xf == 0)
+                printf("\n");
+
+            printf("%02x ", *(unsigned char *)pc);
+            pc += 1;
+        }
+        printf("++++++++++++++++++++++++\n");
+#endif
+    if (prepare_nvs_file(prms, arg)) {
+        fprintf(stderr, "Fail to prepare calibrated NVS file\n");
+        return 2;
+    }
+#if 0
+    printf("\n\tThe NVS file (%s) is ready\n\tCopy it to %s and "
+        "reboot the system\n\n",
+        NEW_NVS_NAME, CURRENT_NVS_NAME);
+#endif
+    return NL_SKIP;
+}
+
+static int plt_tx_bip(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    struct nlattr *key;
+    struct wl1271_cmd_cal_p2g prms;
+    int i;
+    char nvs_path[PATH_MAX];
+
+    if (argc < 8) {
+        fprintf(stderr, "%s> Missing arguments\n", __func__);
+        return 2;
+    }
+
+    if (argc > 8) {
+        strncpy(nvs_path, argv[8], strlen(argv[8]));
+    } else {
+        nvs_path[0] = '\0';
+    }
+
+    memset(&prms, 0, sizeof(struct wl1271_cmd_cal_p2g));
+
+    prms.test.id = TEST_CMD_P2G_CAL;
+    for (i = 0; i < 8; i++) {
+        prms.sub_band_mask |= (atoi(argv[i]) & 0x1)<<i;
+    }
+
+    key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+    if (!key) {
+        fprintf(stderr, "fail to nla_nest_start()\n");
+        return 1;
+    }
+
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
+    NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
+    NLA_PUT_U8(msg, WL1271_TM_ATTR_ANSWER, 1);
+
+    nla_nest_end(msg, key);
+
+    nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, calib_valid_handler, nvs_path);
+
+    return 0;
+
+nla_put_failure:
+    fprintf(stderr, "%s> building message failed\n", __func__);
+    return 2;
+}
+
+COMMAND(plt, tx_bip,
+    "<0|1> <0|1> <0|1> <0|1> <0|1> <0|1> <0|1> <0|1> [<nvs file>]",
+    NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_tx_bip,
+    "Do calibrate\n");
+
+static int plt_tx_tone(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    struct nlattr *key;
+    struct wl1271_cmd_cal_tx_tone prms;
+
+    if (argc < 2) {
+        fprintf(stderr, "%s> Missing arguments\n", __func__);
+        return 2;
+    }
+
+    memset(&prms, 0, sizeof(struct wl1271_cmd_cal_tx_tone));
+
+    prms.test.id = TEST_CMD_TELEC;
+    prms.power = atoi(argv[0]);
+    prms.tone_type = atoi(argv[1]);
+
+    key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+    if (!key) {
+        fprintf(stderr, "fail to nla_nest_start()\n");
+        return 1;
+    }
+
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
+    NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
+
+    nla_nest_end(msg, key);
+
+    return 0;
+
+nla_put_failure:
+    fprintf(stderr, "%s> building message failed\n", __func__);
+    return 2;
+}
+
+COMMAND(plt, tx_tone, "<power> <tone type>",
+    NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_tx_tone,
+    "Do command tx_tone to transmit a tone\n");
+
+static int plt_tx_cont(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    struct nlattr *key;
+    struct wl1271_cmd_pkt_params prms = {
+        .src_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
+    };
+
+    if (argc != 15) {
+        return 1;
+    }
+#if 0
+    printf("%s> delay (%d) rate (%08x) size (%d) amount (%d) power (%d) "
+        "seed (%d) pkt_mode (%d) DCF (%d) GI (%d) preamble (%d) type "
+        "(%d) scramble (%d) CLPC (%d), SeqNbrMode (%d) DestMAC (%s)\n",
+        __func__,
+        atoi(argv[0]),  atoi(argv[1]),  atoi(argv[2]),  atoi(argv[3]),
+        atoi(argv[4]),  atoi(argv[5]),  atoi(argv[6]),  atoi(argv[7]),
+        atoi(argv[8]),  atoi(argv[9]),  atoi(argv[10]), atoi(argv[11]),
+        atoi(argv[12]), atoi(argv[13]), argv[14]
+    );
+#endif
+    memset((void *)&prms, 0, sizeof(struct wl1271_cmd_pkt_params));
+
+    prms.test.id = TEST_CMD_FCC;
+    prms.delay = atoi(argv[0]);
+    prms.rate = atoi(argv[1]);
+    prms.size = (unsigned short)atoi(argv[2]);
+    prms.amount = (unsigned short)atoi(argv[3]);
+    prms.power = atoi(argv[4]);
+    prms.seed = (unsigned short)atoi(argv[5]);
+    prms.pkt_mode = (unsigned char)atoi(argv[6]);
+    prms.dcf_enable = (unsigned char)atoi(argv[7]);
+    prms.g_interval = (unsigned char)atoi(argv[8]);
+    prms.preamble = (unsigned char)atoi(argv[9]);
+    prms.type = (unsigned char)atoi(argv[10]);
+    prms.scramble = (unsigned char)atoi(argv[11]);
+    prms.clpc_enable = (unsigned char)atoi(argv[12]);
+    prms.seq_nbr_mode = (unsigned char)atoi(argv[13]);
+    str2mac(prms.dst_mac, argv[14]);
+
+    if (get_mac_addr(0, prms.src_mac)) {
+        fprintf(stderr, "fail to get MAC addr\n");
+    }
+
+    printf("%02X:%02X:%02X:%02X:%02X:%02X\n",
+        prms.src_mac[0], prms.src_mac[1], prms.src_mac[2],
+        prms.src_mac[3], prms.src_mac[4], prms.src_mac[5]);
+
+    key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+    if (!key) {
+        fprintf(stderr, "fail to nla_nest_start()\n");
+        return 1;
+    }
+
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
+    NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
+
+    nla_nest_end(msg, key);
+
+    return 0;
+
+nla_put_failure:
+    fprintf(stderr, "%s> building message failed\n", __func__);
+    return 2;
+}
+
+COMMAND(plt, tx_cont, "<delay> <rate> <size> <amount> <power>\n\t\t<seed> "
+    "<pkt mode> <DC on/off> <gi> <preamble>\n\t\t<type> <scramble> "
+    "<clpc> <seq nbr mode> <dest mac>",
+    NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_tx_cont,
+    "Start Tx Cont\n");
+
+static int plt_tx_stop(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    struct nlattr *key;
+    struct wl1271_cmd_pkt_params prms;
+
+    prms.test.id = TEST_CMD_STOP_TX;
+
+    key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+    if (!key) {
+        fprintf(stderr, "fail to nla_nest_start()\n");
+        return 1;
+    }
+
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
+    NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
+
+    nla_nest_end(msg, key);
+
+    return 0;
+
+nla_put_failure:
+    fprintf(stderr, "%s> building message failed\n", __func__);
+    return 2;
+}
+
+COMMAND(plt, tx_stop, NULL,
+    NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_tx_stop,
+    "Stop Tx Cont\n");
+
+static int plt_start_rx_statcs(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    struct nlattr *key;
+    struct wl1271_cmd_pkt_params prms;
+
+    prms.test.id = TEST_CMD_RX_STAT_START;
+
+    key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+    if (!key) {
+        fprintf(stderr, "%s> fail to nla_nest_start()\n", __func__);
+        return 1;
+    }
+
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
+    NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
+
+    nla_nest_end(msg, key);
+
+    return 0;
+
+nla_put_failure:
+    fprintf(stderr, "%s> building message failed\n", __func__);
+    return 2;
+}
+
+COMMAND(plt, start_rx_statcs, NULL,
+    NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_start_rx_statcs,
+    "Start Rx statistics collection\n");
+
+static int plt_stop_rx_statcs(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    struct nlattr *key;
+    struct wl1271_cmd_pkt_params prms;
+
+    prms.test.id = TEST_CMD_RX_STAT_STOP;
+
+    key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+    if (!key) {
+        fprintf(stderr, "%s> fail to nla_nest_start()\n", __func__);
+        return 1;
+    }
+
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
+    NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
+
+    nla_nest_end(msg, key);
+
+    return 0;
+
+nla_put_failure:
+    fprintf(stderr, "%s> building message failed\n", __func__);
+    return 2;
+}
+
+COMMAND(plt, stop_rx_statcs, NULL,
+    NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_stop_rx_statcs,
+    "Stop Rx statistics collection\n");
+
+static int plt_reset_rx_statcs(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    struct nlattr *key;
+    struct wl1271_cmd_pkt_params prms;
+
+    prms.test.id = TEST_CMD_RX_STAT_RESET;
+
+    key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+    if (!key) {
+        fprintf(stderr, "%s> fail to nla_nest_start()\n", __func__);
+        return 1;
+    }
+
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
+    NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
+
+    nla_nest_end(msg, key);
+
+    return 0;
+
+nla_put_failure:
+    fprintf(stderr, "%s> building message failed\n", __func__);
+    return 2;
+}
+
+COMMAND(plt, reset_rx_statcs, NULL,
+    NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_reset_rx_statcs,
+    "Reset Rx statistics collection\n");
+
+static int display_rx_statcs(struct nl_msg *msg, void *arg)
+{
+    struct nlattr *tb[NL80211_ATTR_MAX + 1];
+    struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+    struct nlattr *td[WL1271_TM_ATTR_MAX + 1];
+    struct wl1271_radio_rx_statcs *prms;
+
+    nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+        genlmsg_attrlen(gnlh, 0), NULL);
+
+    if (!tb[NL80211_ATTR_TESTDATA]) {
+        fprintf(stderr, "no data!\n");
+        return NL_SKIP;
+    }
+
+    nla_parse(td, WL1271_TM_ATTR_MAX, nla_data(tb[NL80211_ATTR_TESTDATA]),
+        nla_len(tb[NL80211_ATTR_TESTDATA]), NULL);
+
+    prms =
+        (struct wl1271_radio_rx_statcs *)
+            nla_data(td[WL1271_TM_ATTR_DATA]);
+
+    printf("\n\tTotal number of pkts\t- %d\n\tAccepted pkts\t\t- %d\n\t"
+        "FCS error pkts\t\t- %d\n\tAddress mismatch pkts\t- %d\n\t"
+        "Average SNR\t\t- % d dBm\n\tAverage RSSI\t\t- % d dBm\n\n",
+        prms->base_pkt_id, prms->rx_path_statcs.nbr_rx_valid_pkts,
+        prms->rx_path_statcs.nbr_rx_fcs_err_pkts,
+        prms->rx_path_statcs.nbr_rx_plcp_err_pkts,
+        (signed short)prms->rx_path_statcs.ave_snr/8,
+        (signed short)prms->rx_path_statcs.ave_rssi/8);
+
+    return NL_SKIP;
+}
+
+static int plt_get_rx_statcs(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    struct nlattr *key;
+    struct wl1271_radio_rx_statcs prms;
+
+    prms.test.id = TEST_CMD_RX_STAT_GET;
+
+    key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+    if (!key) {
+        fprintf(stderr, "%s> fail to nla_nest_start()\n", __func__);
+        return 1;
+    }
+
+    NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
+    NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
+    NLA_PUT_U8(msg, WL1271_TM_ATTR_ANSWER, 1);
+
+    nla_nest_end(msg, key);
+
+    nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, display_rx_statcs, NULL);
+
+    /* Important: needed gap between tx_start and tx_get */
+    sleep(2);
+
+    return 0;
+
+nla_put_failure:
+    fprintf(stderr, "%s> building message failed\n", __func__);
+    return 2;
+}
+
+COMMAND(plt, get_rx_statcs, NULL,
+    NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_get_rx_statcs,
+    "Get Rx statistics\n");
+
+static int plt_rx_statistics(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    int ret;
+
+    /* power mode on */
+    {
+        char *prms[4] = { "wlan0", "plt", "power_mode", "on" };
+
+        ret = handle_cmd(state, II_NETDEV, 4, prms);
+        if (ret < 0) {
+            fprintf(stderr, "Fail to set PLT power mode on\n");
+            return 1;
+        }
+    }
+
+    /* start_rx_statcs */
+    {
+        char *prms[3] = { "wlan0", "plt", "start_rx_statcs" };
+
+        ret = handle_cmd(state, II_NETDEV, 3, prms);
+        if (ret < 0) {
+            fprintf(stderr, "Fail to start Rx statistics\n");
+            goto fail_out;
+        }
+    }
+
+    /* get_rx_statcs */
+    {
+        int err;
+        char *prms[3] = { "wlan0", "plt", "get_rx_statcs" };
+
+        err = handle_cmd(state, II_NETDEV, 3, prms);
+        if (err < 0) {
+            fprintf(stderr, "Fail to get Rx statistics\n");
+            ret = err;
+        }
+    }
+
+
+    /* stop_rx_statcs */
+    {
+        int err;
+        char *prms[3] = { "wlan0", "plt", "stop_rx_statcs" };
+
+        err = handle_cmd(state, II_NETDEV, 3, prms);
+        if (err < 0) {
+            fprintf(stderr, "Fail to stop Rx statistics\n");
+            ret = err;
+        }
+    }
+
+fail_out:
+    /* power mode off */
+    {
+        int err;
+        char *prms[4] = { "wlan0", "plt", "power_mode", "off"};
+
+        err = handle_cmd(state, II_NETDEV, 4, prms);
+        if (err < 0) {
+            fprintf(stderr, "Fail to set PLT power mode on\n");
+            return 1;
+        }
+    }
+
+    if (ret < 0) {
+        return 1;
+    }
+
+    return 0;
+}
+
+COMMAND(plt, rx_statistics, NULL, 0, 0, CIB_NONE, plt_rx_statistics,
+    "Get Rx statistics\n");
+
+static int plt_calibrate(struct nl80211_state *state, struct nl_cb *cb,
+            struct nl_msg *msg, int argc, char **argv)
+{
+    int ret = 0, err;
+    int single_dual = 0;
+
+    if (argc > 2 && (strncmp(argv[2], "dual", 4) ==  0)) {
+        single_dual = 1;    /* going for dual band calibration */
+    } else {
+        single_dual = 0;    /* going for single band calibration */
+    }
+
+    /* power mode on */
+    {
+        char *pm_on[4] = { "wlan0", "plt", "power_mode", "on" };
+
+        err = handle_cmd(state, II_NETDEV, 4, pm_on);
+        if (err < 0) {
+            fprintf(stderr, "Fail to set PLT power mode on\n");
+            ret = err;
+            goto fail_out_final;
+        }
+    }
+
+    /* tune channel */
+    {
+        char *pm_on[5] = {
+            "wlan0", "plt", "tune_channel", "0", "7"
+        };
+
+        err = handle_cmd(state, II_NETDEV, 5, pm_on);
+        if (err < 0) {
+            fprintf(stderr, "Fail to tune channel\n");
+            ret = err;
+            goto fail_out;
+        }
+    }
+
+    /* calibrate it */
+    {
+        char *prms[11] = {
+            "wlan0", "plt", "tx_bip", "1", "0", "0", "0",
+            "0", "0", "0", "0"
+        };
+
+        /* set flags in case of dual band */
+        if (single_dual) {
+            prms[4] = prms[5] = prms[6] = prms[7] = prms[8] =
+                prms[9] = prms[10] = "1";
+        }
+
+        err = handle_cmd(state, II_NETDEV, 11, prms);
+        if (err < 0) {
+            fprintf(stderr, "Fail to calibrate\n");
+            ret = err;
+        }
+    }
+
+fail_out:
+    /* power mode off */
+    {
+        char *prms[4] = { "wlan0", "plt", "power_mode", "off"};
+
+        err = handle_cmd(state, II_NETDEV, 4, prms);
+        if (err < 0) {
+            fprintf(stderr, "Fail to set PLT power mode on\n");
+            ret = err;
+        }
+    }
+
+fail_out_final:
+    if (ret < 0) {
+        return 1;
+    }
+
+    return 0;
+}
+
+COMMAND(plt, calibrate, "[<single|dual>]", 0, 0, CIB_NONE,
+    plt_calibrate, "Do calibrate for single or dual band chip\n");
diff --git a/mac80211/ti-utils/plt.h b/mac80211/ti-utils/plt.h
new file mode 100644
index 0000000..8b9bca4
--- /dev/null
+++ b/mac80211/ti-utils/plt.h
@@ -0,0 +1,372 @@
+#ifndef __PLT_H
+#define __PLT_H
+
+#ifdef ANDROID
+#define CURRENT_NVS_NAME    "/system/etc/firmware/ti-connectivity/wl1271-nvs.bin"
+#else
+#define CURRENT_NVS_NAME    "/lib/firmware/ti-connectivity/wl1271-nvs.bin"
+#endif
+#define NEW_NVS_NAME        "./new-nvs.bin"
+#define NVS_FILE_SIZE_127X    0x390
+#define NVS_FILE_SIZE_128X    0x459
+
+/* NVS definition start here */
+
+#define NVS_TX_TYPE_INDEX               0
+
+#define START_TYPE_INDEX_IN_TLV        0
+#define TLV_TYPE_LENGTH                 1
+#define START_LENGTH_INDEX              \
+(START_TYPE_INDEX_IN_TLV + TLV_TYPE_LENGTH) /* 1 */
+#define TLV_LENGTH_LENGTH               2
+#define START_PARAM_INDEX               \
+(START_LENGTH_INDEX + TLV_LENGTH_LENGTH) /* 3 */
+
+#define NVS_VERSION_1                   1
+#define NVS_VERSION_2                   2
+
+#define NVS_MAC_FIRST_LENGTH_INDEX      0
+#define NVS_MAC_FIRST_LENGHT_VALUE      1
+
+#define NVS_MAC_L_ADDRESS_INDEX         \
+((NVS_MAC_FIRST_LENGTH_INDEX) + 1) /* 1*/
+#define NVS_MAC_L_ADDRESS_LENGTH        2
+
+#define NVS_MAC_L_VALUE_INDEX \
+((NVS_MAC_L_ADDRESS_INDEX) + (NVS_MAC_L_ADDRESS_LENGTH)) /* 3 */
+
+#define NVS_MAC_L_VALUE_LENGTH          4
+
+#define NVS_MAC_SECONDE_LENGTH_INDEX    \
+((NVS_MAC_L_VALUE_INDEX) + 4) /* 7 */
+#define NVS_MAC_SECONDE_LENGHT_VALUE    1
+
+#define NVS_MAC_H_ADDRESS_INDEX         \
+((NVS_MAC_SECONDE_LENGTH_INDEX) + 1) /* 8*/
+#define NVS_MAC_H_ADDRESS_LENGTH        2
+
+#define NVS_MAC_H_VALUE_INDEX           \
+((NVS_MAC_H_ADDRESS_INDEX) + (NVS_MAC_H_ADDRESS_LENGTH)) /* 10 */
+#define NVS_MAC_H_VALUE_LENGTH          4
+
+#define NVS_END_BURST_TRANSACTION_INDEX         \
+((NVS_MAC_H_VALUE_INDEX) + (NVS_MAC_H_VALUE_LENGTH))    /* 14 */
+#define NVS_END_BURST_TRANSACTION_VALUE         0
+#define NVS_END_BURST_TRANSACTION_LENGTH        7
+
+#define NVS_ALING_TLV_START_ADDRESS_INDEX       \
+((NVS_END_BURST_TRANSACTION_INDEX) + \
+(NVS_END_BURST_TRANSACTION_LENGTH)) /* 21 */
+#define NVS_ALING_TLV_START_ADDRESS_VALUE       0
+#define NVS_ALING_TLV_START_ADDRESS_LENGTH      3
+
+
+/* NVS pre TLV length */
+#define NVS_PRE_PARAMETERS_LENGTH               \
+((NVS_ALING_TLV_START_ADDRESS_INDEX) + \
+(NVS_ALING_TLV_START_ADDRESS_LENGTH)) /* 24 */
+
+/* NVS P2G table */
+#define NVS_TX_P2G_TABLE_LENGTH                 \
+((NUMBER_OF_SUB_BANDS_E) * 1 /* byte */) /* 8 */
+
+/* NVS PPA table */
+#define NVS_TX_PPA_STEPS_TABLE_LENGTH   \
+((NUMBER_OF_SUB_BANDS_E) * ((TXPWR_CFG0__VGA_STEP__NUMBER_OF_STEPS_E) \
+- 1) * 1 /* byte */)  /* 32 */
+
+/* NVS version 1 TX PD curve table length */
+#define NVS_TX_PD_TABLE_LENGTH_NVS_V1   (1 /* byte to set size of table */ + \
+((NUMBER_OF_SUB_BANDS_E) * (2 /* 1 byte offset, 1 byte low range */ + \
+2 /* first index in table */ + (((SIZE_OF_POWER_DETECTOR_TABLE) - 1) * \
+1 /* 1 byte */)))) /* 233 */
+
+/* NVS version 2 TX PD curve table length */
+#define NVS_TX_PD_TABLE_LENGTH_NVS_V2   \
+((NUMBER_OF_SUB_BANDS_E) * (12 /* 12index of one byte -2 dBm - 9dBm */ +\
+28 /* 14 indexes of 2 byte -3dBm, 10dBm - 22 dBm */)) /* 320 */
+
+/* NVS version 1 TX parameters Length */
+#define NVS_TX_PARAM_LENGTH_NVS_V1      \
+((NVS_TX_P2G_TABLE_LENGTH) + (NVS_TX_PPA_STEPS_TABLE_LENGTH) +\
+(NVS_TX_PD_TABLE_LENGTH_NVS_V1)) /* 273 */
+
+/* NVS version 2 TX parameters Length */
+#define NVS_TX_PARAM_LENGTH_NVS_V2       \
+((NVS_TX_P2G_TABLE_LENGTH) + (NVS_TX_PPA_STEPS_TABLE_LENGTH) +\
+(NVS_TX_PD_TABLE_LENGTH_NVS_V2) +\
+(NUMBER_OF_RADIO_CHANNEL_INDEXS_E /* for Per Channel power Gain Offset tabl */))
+
+/* NVS TX version */
+/* #define NVS_TX_PARAM_LENGTH     NVS_TX_PARAM_LENGTH_NVS_V2 */
+#define NVS_TX_PARAM_LENGTH     0x199
+
+/* NVS RX version */
+#define NVS_RX_PARAM_LENGTH    NUMBER_OF_RX_BIP_EFUSE_PARAMETERS_E /* 19 */
+
+/* NVS version parameter length */
+#define NVS_VERSION_PARAMETER_LENGTH    3
+
+/* NVS max length */
+/* original ((NVS_TOTAL_LENGTH) + 4 - ((NVS_TOTAL_LENGTH) % 4)) */
+#define NVS_TOTAL_LENGTH    500
+
+/* TLV max length */
+#define  MAX_TLV_LENGTH                                 NVS_TOTAL_LENGTH
+
+#define  MAX_NVS_VERSION_LENGTH                 12
+
+enum wl1271_tm_commands {
+    WL1271_TM_CMD_UNSPEC,
+    WL1271_TM_CMD_TEST,
+    WL1271_TM_CMD_INTERROGATE,
+    WL1271_TM_CMD_CONFIGURE,
+    WL1271_TM_CMD_NVS_PUSH,
+    WL1271_TM_CMD_SET_PLT_MODE,
+    __WL1271_TM_CMD_AFTER_LAST
+};
+
+enum wl1271_tm_attrs {
+    WL1271_TM_ATTR_UNSPEC,
+    WL1271_TM_ATTR_CMD_ID,
+    WL1271_TM_ATTR_ANSWER,
+    WL1271_TM_ATTR_DATA,
+    WL1271_TM_ATTR_IE_ID,
+    WL1271_TM_ATTR_PLT_MODE,
+    __WL1271_TM_ATTR_AFTER_LAST
+};
+
+#define WL1271_TM_ATTR_MAX (__WL1271_TM_ATTR_AFTER_LAST - 1)
+
+enum wl1271_test_cmds {
+    TEST_CMD_PD_BUFFER_CAL = 0x1, /* TX PLT */
+    TEST_CMD_P2G_CAL,             /* TX BiP */
+    TEST_CMD_RX_PLT_ENTER,
+    TEST_CMD_RX_PLT_CAL,          /* RSSI Cal */
+    TEST_CMD_RX_PLT_EXIT,
+    TEST_CMD_RX_PLT_GET,
+    TEST_CMD_FCC,                 /* Continuous TX */
+    TEST_CMD_TELEC,  /* Carrier wave in a specific channel and band */
+    TEST_CMD_STOP_TX,             /* Stop FCC or TELEC */
+    TEST_CMD_PLT_TEMPLATE,        /* define Template for TX */
+    TEST_CMD_PLT_GAIN_ADJUST,
+    TEST_CMD_PLT_GAIN_GET,
+    TEST_CMD_CHANNEL_TUNE,
+    TEST_CMD_FREE_RUN_RSSI,        /* Free running RSSI measurement */
+    TEST_CMD_DEBUG,     /* test command for debug using the struct: */
+    TEST_CMD_CLPC_COMMANDS,
+    RESERVED_4,
+    TEST_CMD_RX_STAT_STOP,
+    TEST_CMD_RX_STAT_START,
+    TEST_CMD_RX_STAT_RESET,
+    TEST_CMD_RX_STAT_GET,
+    TEST_CMD_LOOPBACK_START,       /* for FW Test Debug */
+    TEST_CMD_LOOPBACK_STOP,        /* for FW Test Debug */
+    TEST_CMD_GET_FW_VERSIONS,
+    TEST_CMD_INI_FILE_RADIO_PARAM,
+    TEST_CMD_RUN_CALIBRATION_TYPE,
+    TEST_CMD_TX_GAIN_ADJUST,
+    TEST_CMD_UPDATE_PD_BUFFER_ERRORS,
+    TEST_CMD_UPDATE_PD_REFERENCE_POINT,
+    TEST_CMD_INI_FILE_GENERAL_PARAM,
+    TEST_CMD_SET_EFUSE,
+    TEST_CMD_GET_EFUSE,
+    TEST_CMD_TEST_TONE,
+    TEST_CMD_POWER_MODE,
+    TEST_CMD_SMART_REFLEX,
+    TEST_CMD_CHANNEL_RESPONSE,
+    TEST_CMD_DCO_ITRIM_FEATURE,
+    MAX_TEST_CMD_ID = 0xFF
+};
+
+struct wl1271_cmd_header {
+    __u16 id;
+    __u16 status;
+    /* payload */
+    unsigned char data[0];
+} __attribute__((packed));
+
+struct wl1271_cmd_test_header {
+    unsigned char id;
+    unsigned char padding[3];
+} __attribute__((packed));
+
+struct wl1271_cmd_cal_channel_tune {
+    struct wl1271_cmd_header header;
+
+    struct wl1271_cmd_test_header test;
+
+    unsigned char band;
+    unsigned char channel;
+
+    __le16 radio_status;
+} __attribute__((packed));
+
+struct wl1271_cmd_cal_update_ref_point {
+    struct wl1271_cmd_header header;
+
+    struct wl1271_cmd_test_header test;
+
+    __le32 ref_power;
+    __le32 ref_detector;
+    unsigned char  sub_band;
+    unsigned char  padding[3];
+} __attribute__((packed));
+
+struct wl1271_cmd_cal_tx_tone {
+    struct wl1271_cmd_header header;
+
+    struct wl1271_cmd_test_header test;
+
+    __le32 power;
+    __le32 tone_type;
+} __attribute__((packed));
+
+struct wl1271_cmd_cal_p2g {
+    struct wl1271_cmd_header header;
+
+    struct wl1271_cmd_test_header test;
+
+    __le32 ver;
+    __le16 len;
+    unsigned char  buf[MAX_TLV_LENGTH];
+    unsigned char  type;
+    unsigned char  padding;
+
+    __le16 radio_status;
+
+    unsigned char  sub_band_mask;
+    unsigned char  padding2;
+} __attribute__((packed));
+
+#define MAC_ADDR_LEN  6
+
+struct wl1271_cmd_pkt_params {
+    struct wl1271_cmd_header header;
+
+    struct wl1271_cmd_test_header test;
+
+    __le16 radio_status;
+    unsigned char padding[2];
+    __le32 delay;
+    __le32 rate;
+    __le16 size;
+    __le16 amount;
+    __le32 power;
+    __le16 seed;
+    unsigned char pkt_mode;
+    unsigned char dcf_enable;
+    unsigned char g_interval;
+    unsigned char preamble;
+    unsigned char type;
+    unsigned char scramble;
+    unsigned char clpc_enable;
+    unsigned char seq_nbr_mode;
+    unsigned char src_mac[MAC_ADDR_LEN];
+    unsigned char dst_mac[MAC_ADDR_LEN];
+    unsigned char padding1[2];
+} __attribute__((packed));
+
+struct wl1271_rx_path_statcs {
+    __le32 nbr_rx_valid_pkts;
+    __le32 nbr_rx_fcs_err_pkts;
+    __le32 nbr_rx_plcp_err_pkts;
+    __le32 seq_nbr_miss_cnt; /* For PER calculation */
+    __le16 ave_snr; /* average SNR */
+    __le16 ave_rssi; /* average RSSI */
+    __le16 ave_evm;
+    unsigned char padding[2];
+} __attribute__((packed));
+
+struct wl1271_rx_pkt_statcs {
+    __le32 length;
+    __le32 evm;
+    __le32 rssi;
+    __le16 freq_delta;
+    __le16 flags;
+    char type;
+    unsigned char rate;
+    unsigned char noise;
+    unsigned char agc_gain;
+    unsigned char padding[2];
+} __attribute__((packed));
+
+#define RX_STAT_PACKETS_PER_MESSAGE        (20)
+
+struct wl1271_radio_rx_statcs {
+    struct wl1271_cmd_header header;
+
+    struct wl1271_cmd_test_header test;
+
+    struct wl1271_rx_path_statcs rx_path_statcs;
+    __le32 base_pkt_id;
+    __le32 nbr_pkts; /* input/output: number of following packets */
+    __le32 nbr_miss_pkts;
+    __le16 radio_status;
+    unsigned char padding[2];
+} __attribute__((packed));
+
+enum wl1271_nvs_type {
+    eNVS_VERSION = 0xaa,
+    eNVS_RADIO_TX_PARAMETERS = 1,
+    eNVS_RADIO_RX_PARAMETERS = 2,
+    eNVS_RADIO_INI = 16,
+    eNVS_NON_FILE = 0xFE,
+    eTLV_LAST = 0xFF /* last TLV type */
+};
+
+#define DEFAULT_EFUSE_VALUE            (0)
+
+enum wl1271_nvs_type_info {
+    eFIRST_RADIO_TYPE_PARAMETERS_INFO,
+    eNVS_RADIO_TX_TYPE_PARAMETERS_INFO = eFIRST_RADIO_TYPE_PARAMETERS_INFO,
+    eNVS_RADIO_RX_TYPE_PARAMETERS_INFO,
+    eLAST_RADIO_TYPE_PARAMETERS_INFO = eNVS_RADIO_RX_TYPE_PARAMETERS_INFO,
+    UNUSED_RADIO_TYPE_PARAMETERS_INFO,
+    eNUMBER_RADIO_TYPE_PARAMETERS_INFO = UNUSED_RADIO_TYPE_PARAMETERS_INFO,
+    LAST_RADIO_TYPE_PARAMETERS_INFO =
+        (eNUMBER_RADIO_TYPE_PARAMETERS_INFO - 1)
+};
+
+enum EFUSE_PARAMETER_TYPE_ENMT {
+    EFUSE_FIRST_PARAMETER_E,
+    /* RX PARAMETERS */
+    EFUSE_FIRST_RX_PARAMETER_E = EFUSE_FIRST_PARAMETER_E,
+    RX_BIP_MAX_GAIN_ERROR_BAND_B_E = EFUSE_FIRST_RX_PARAMETER_E,
+
+    RX_BIP_MAX_GAIN_ERROR_J_LOW_MID_E,
+    RX_BIP_MAX_GAIN_ERROR_J_HIGH_E,
+
+    RX_BIP_MAX_GAIN_ERROR_5G_1ST_E,
+    RX_BIP_MAX_GAIN_ERROR_5G_2ND_E,
+    RX_BIP_MAX_GAIN_ERROR_5G_3RD_E,
+    RX_BIP_MAX_GAIN_ERROR_5G_4TH_E,
+
+    RX_BIP_LNA_STEP_CORR_BAND_B_4TO3_E,
+    RX_BIP_LNA_STEP_CORR_BAND_B_3TO2_E,
+    RX_BIP_LNA_STEP_CORR_BAND_B_2TO1_E,
+    RX_BIP_LNA_STEP_CORR_BAND_B_1TO0_E,
+
+    RX_BIP_LNA_STEP_CORR_BAND_A_4TO3_E,
+    RX_BIP_LNA_STEP_CORR_BAND_A_3TO2_E,
+    RX_BIP_LNA_STEP_CORR_BAND_A_2TO1_E,
+    RX_BIP_LNA_STEP_CORR_BAND_A_1TO0_E,
+
+    RX_BIP_TA_STEP_CORR_BAND_B_2TO1_E,
+    RX_BIP_TA_STEP_CORR_BAND_B_1TO0_E,
+    RX_BIP_TA_STEP_CORR_BAND_A_2TO1_E,
+    RX_BIP_TA_STEP_CORR_BAND_A_1TO0_E,
+    NUMBER_OF_RX_BIP_EFUSE_PARAMETERS_E,
+
+    /* TX PARAMETERS */
+    TX_BIP_PD_BUFFER_GAIN_ERROR_E = NUMBER_OF_RX_BIP_EFUSE_PARAMETERS_E,
+    TX_BIP_PD_BUFFER_VBIAS_ERROR_E,
+    EFUSE_NUMBER_OF_PARAMETERS_E,
+    EFUSE_LAST_PARAMETER_E = (EFUSE_NUMBER_OF_PARAMETERS_E - 1)
+} EFUSE_PARAMETER_TYPE_ENM;
+
+int get_mac_addr(int ifc_num, unsigned char *mac_addr);
+
+int file_exist(const char *filename);
+
+#endif /* __PLT_H */
diff --git a/mac80211/ti-utils/scripts/go.sh b/mac80211/ti-utils/scripts/go.sh
new file mode 100755
index 0000000..45da67e
--- /dev/null
+++ b/mac80211/ti-utils/scripts/go.sh
@@ -0,0 +1,529 @@
+#!/bin/sh
+
+# Bootlevels
+#   1 - start only inetd            0000 0001
+#   2 - load mav80211                0000 0010
+#   4 - load driver                0000 0100
+#   8 - up dev, load wpa_supplicant        0000 1000
+#  16 - Settings for Android                0001 0000
+#  32 - running AP                0010 0000
+#  64 - 1-command calibration            0100 0000
+
+go_version="0.91"
+usage()
+{
+    echo -e "\tUSAGE:\n\t    `basename $0` <option> [value]"
+    echo -e "\t\t-b <value> - bootlevel, where\n\t\t\t7-PLT boot"
+    echo -e "\t\t\t15-full boot"
+    echo -e "\t\t-c <path to INI file> [path to install NVS] -" \
+"run calibration"
+    echo -e "\t\t-c2 <path to INI file> <path to INI file> -" \
+"run calibration with 2 FEMs"
+    echo -e "\t\t\twhere the default value for install path is "
+    echo -e "\t\t\t/lib/firmware/ti-connectivity/wl1271-nvs.bin"
+    echo -e "\t\t-d <value> - debuglevel, where"
+    echo -e "\t\t\t  -1      - shows current value
+\t\t\tDEBUG_IRQ       = BIT(0)
+\t\t\tDEBUG_SPI       = BIT(1)
+\t\t\tDEBUG_BOOT      = BIT(2)
+\t\t\tDEBUG_MAILBOX   = BIT(3)
+\t\t\tDEBUG_TESTMODE  = BIT(4)
+\t\t\tDEBUG_EVENT     = BIT(5)
+\t\t\tDEBUG_TX        = BIT(6)
+\t\t\tDEBUG_RX        = BIT(7)
+\t\t\tDEBUG_SCAN      = BIT(8)
+\t\t\tDEBUG_CRYPT     = BIT(9)
+\t\t\tDEBUG_PSM       = BIT(10)
+\t\t\tDEBUG_MAC80211  = BIT(11)
+\t\t\tDEBUG_CMD       = BIT(12)
+\t\t\tDEBUG_ACX       = BIT(13)
+\t\t\tDEBUG_SDIO      = BIT(14)
+\t\t\tDEBUG_FILTERS   = BIT(15)
+\t\t\tDEBUG_ADHOC     = BIT(16)
+\t\t\tDEBUG_ALL       = ~0"
+    echo -e "\t\t-m <value> - set MAC address"
+    echo -e "\t\t-ip [value] - set IP address"
+    echo -e "\t\t-v - get script version"
+    echo -e "\t\t-h - get this help"
+}
+
+i=0
+nbr_args=$#
+bootlevel=0
+dbg_lvl=0
+ref_clk=0
+mac_addr="08:00:28:90:64:31"
+ip_addr="192.168.1.1"
+set_ip_addr=0
+have_path_to_ini=0
+path_to_ini=""
+path_to_ini2=""
+have_path_to_install=0
+path_to_install="/lib/firmware/ti-connectivity/wl1271-nvs.bin"
+is_android=0
+prefix_path2modules=
+while [ "$i" -lt "$nbr_args" ]
+do
+    case $1 in
+        -b) bootlevel=$2
+        nbr_args=`expr $nbr_args - 1`
+        shift
+        ;;
+        #-r) ref_clk=$2
+        #nbr_args=`expr $nbr_args - 1`
+        #shift
+        #;;
+        -c)
+            if [ "$nbr_args" -lt "2" ]; then
+                echo -e "missing arguments"
+                exit 1
+            fi
+
+            bootlevel=66
+            have_path_to_ini=`expr $have_path_to_ini + 1`
+            path_to_ini=$2
+            if [ "$nbr_args" -eq "2" ]; then
+                echo -e "    The install path not provided"
+                echo -e "    Use default ($path_to_install)"
+                nbr_args=`expr $nbr_args - 1`
+                shift
+                break
+            fi
+
+            have_path_to_install=`expr $have_path_to_install + 1`
+            path_to_install=$3
+            nbr_args=`expr $nbr_args - 2`
+            shift
+            shift
+        ;;
+        -c2)    # calibration with 2 FEMs
+            if [ "$nbr_args" -lt "3" ]; then
+                echo -e "missing arguments"
+                exit 1
+            fi
+
+            bootlevel=34
+            have_path_to_ini=`expr $have_path_to_ini + 1`
+            path_to_ini=$2
+            path_to_ini2=$3
+            nbr_args=`expr $nbr_args - 2`
+            shift
+            shift
+        ;;
+        -d) dbg_lvl=$2
+        nbr_args=`expr $nbr_args - 1`
+        shift
+        ;;
+        -m) mac_addr=$2
+        nbr_args=`expr $nbr_args - 1`
+        shift
+        ;;
+        -ip) set_ip_addr=`expr $set_ip_addr + 1`
+            case $2 in
+                "") echo -e "using default ip address"
+                ;;
+                -*) echo -e "this is another option"
+                ;;
+                *) ip_addr=$2
+                nbr_args=`expr $nbr_args - 1`
+                shift
+                ;;
+            esac
+        ;;
+        -ini)
+            have_path_to_ini=`expr $have_path_to_ini + 1`
+            path_to_ini=$2
+            nbr_args=`expr $nbr_args - 1`
+            shift
+        ;;
+        -v)
+        echo -e "\tgo.sh version $go_version"
+        ;;
+        -h) usage
+        exit 0
+        ;;
+        *) echo -e "\tNothing to do"
+        ;;
+    esac
+    i=`expr $i + 1`
+    shift
+done
+
+stage_uno=0
+stage_due=0
+stage_quattro=0
+stage_otto=0
+stage_sedici=0
+stage_trentadue=0
+stage_sessanta_quattro=0
+case $bootlevel in
+    1) stage_uno=`expr $stage_uno + 1`
+    ;;
+    2) stage_due=`expr $stage_due + 1`
+    ;;
+    3) stage_uno=`expr $stage_uno + 1`
+       stage_due=`expr $stage_due + 1`
+    ;;
+    4) stage_quattro=`expr $stage_quattro + 1`
+    ;;
+    5) stage_uno=`expr $stage_uno + 1`
+       stage_quattro=`expr $stage_quattro + 1`
+    ;;
+    6) stage_due=`expr $stage_due + 1`
+       stage_quattro=`expr $stage_quattro + 1`
+    ;;
+    7) stage_uno=`expr $stage_uno + 1`
+       stage_due=`expr $stage_due + 1`
+       stage_quattro=`expr $stage_quattro + 1`
+    ;;
+    8) stage_otto=`expr $stage_otto + 1`
+    ;;
+    12) stage_quattro=`expr $stage_quattro + 1`
+            stage_otto=`expr $stage_otto + 1`
+    ;;
+    15) stage_uno=`expr $stage_uno + 1`
+        stage_due=`expr $stage_due + 1`
+        stage_quattro=`expr $stage_quattro + 1`
+        stage_otto=`expr $stage_otto + 1`
+    ;;
+    16) stage_sedici=`expr $stage_sedici + 1`
+    ;;
+    32) stage_trentadue=`expr $stage_trentadue + 1`
+    ;;
+    34)
+        stage_due=`expr $stage_due + 1`
+        stage_trentadue=`expr $stage_trentadue + 1`
+    ;;
+    64) stage_sessanta_quattro=`expr $stage_sessanta_quattro + 1`
+    ;;
+    66)
+        stage_due=`expr $stage_due + 1`
+        stage_sessanta_quattro=`expr $stage_sessanta_quattro + 1`
+    ;;
+esac
+
+echo -e "\t------------         ------------\n"
+echo -e "\t---===<<<((( WELCOME )))>>>===---\n"
+echo -e "\t------------         ------------\n"
+
+insmod_path=
+rmmod_path=
+
+if [ $ANDROID_ROOT ]; then
+    is_android=`expr $is_android + 1`
+    prefix_path2modules="/system/"
+    insmod_path="/system/bin/"
+    rmmod_path="/system/bin/"
+fi
+
+if [ "$stage_uno" -ne "0" ]; then
+    echo -e "+++ Mount the debugfs on /sys/kernel/debug"
+
+    echo 8 > /proc/sys/kernel/printk
+
+    if [ -e /libexec/inetd ]; then
+        /libexec/inetd /etc/inetd.conf &
+    fi
+
+    if [ ! -e /sys/kernel/debug/tracing ]; then
+        mount -t debugfs none /sys/kernel/debug/
+    fi
+fi
+
+if [ "$stage_due" -ne "0" ]; then
+    echo -e "+++ Load mac80211, cfg80211, crc7 and firmware_class"
+
+    run_it=`cat /proc/modules | grep "cfg80211"`
+    if [ "$run_it" == "" ]; then
+        "$insmod_path"insmod /lib/modules/`uname -r`/kernel/net/wireless/cfg80211.ko
+    fi
+    run_it=`cat /proc/modules | grep "mac80211"`
+    if [ "$run_it" == "" ]; then
+        insmod /lib/modules/`uname -r`/kernel/net/mac80211/mac80211.ko
+    fi
+    run_it=`cat /proc/modules | grep "crc7"`
+    if [ "$run_it" == "" ]; then
+        insmod /lib/modules/`uname -r`/kernel/lib/crc7.ko
+    fi
+    run_it=`cat /proc/modules | grep "firmware_class"`
+    if [ "$run_it" == "" ]; then
+        insmod /lib/modules/`uname -r`/kernel/drivers/base/firmware_class.ko
+    fi
+fi
+
+if [ "$stage_quattro" -ne "0" ]; then
+    echo -e "+++ Load wl12xx driver, enable mac80211 tracing"
+
+    run_it=`cat /proc/modules | grep "wl12xx"`
+    if [ "$run_it" == "" ]; then
+        if [ "$is_android" -eq "0" ]; then
+            "$insmod_path"insmod /lib/modules/`uname -r`/kernel/drivers/net/wireless/wl12xx/wl12xx.ko
+        else
+            "$insmod_path"insmod /system/lib/modules/wl12xx.ko
+        fi
+        if [ "$?" != "0" ]; then
+            echo -e "Fail to load wl12xx"
+            exit 1
+        fi
+    fi
+
+    run_it=`cat /proc/modules | grep "wl12xx_sdio"`
+    if [ "$run_it" == "" ]; then
+        if [ "$is_android" -eq "0" ]; then
+            "$insmod_path"insmod /lib/modules/`uname -r`/kernel/drivers/net/wireless/wl12xx/wl12xx_sdio.ko
+        else
+            insmod /system/lib/modules/wl12xx_sdio.ko
+        fi
+        if [ "$?" != "0" ]; then
+            echo -e "Fail to load wl12xx_sdio"
+            exit 1
+        fi
+    fi
+
+    sleep 1
+    if [ -e /sys/kernel/debug/tracing ]; then
+        echo 1 > /sys/kernel/debug/tracing/events/mac80211/enable
+    fi
+
+    #ifconfig wlan0 hw ether $mac_addr
+    #cat /sys/kernel/debug/mmc2/ios
+fi
+
+if [ "$stage_otto" -ne "0" ]; then
+    echo -e "+++ Start interface, enable monitoring events, run wpa_supplicant"
+
+    ifconfig wlan0 up
+    if [ "$?" != "0" ]; then
+        echo -e "Fail to start iface"
+        exit 1
+    fi
+
+    sleep 1
+    iw event > /var/log/iwevents &
+
+    #wpa_supplicant -P/var/run/wpa_supplicant.pid -iwlan0
+    #    -c/etc/wpa_supplicant.conf -Dnl80211 -f/var/log/wpa_supplicant.log &
+    #iw wlan0 cqm rssi -55 2
+    #wpa_supplicant -ddt -iwlan0 -c/etc/wpa_supplicant.conf -Dnl80211 -f/var/log/wpa.log &
+    wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf -Dnl80211 &
+    #python /usr/share/peripherals-test-autom/dut.py -v &
+fi
+
+if [ "$stage_sedici" -ne "0" ]; then
+    echo manual_lock > /sys/power/wake_lock
+    echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
+    echo 1 > /sys/devices/system/cpu/cpu1/online
+    echo performance > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
+fi
+
+if [ "$stage_trentadue" -ne "0" ]; then
+
+    if [ "$have_path_to_ini" -eq "0" ]; then
+        echo -e "Missing ini file parameter"
+        exit 1
+    fi
+
+    # 1. unload wl12xx kernel modules
+    echo -e "+++ Unload wl12xx driver"
+    run_it=`cat /proc/modules | grep "wl12xx_sdio"`
+    if [ "$run_it" != "" ]; then
+        rmmod wl12xx_sdio
+    fi
+    run_it=`cat /proc/modules | grep "wl12xx"`
+    if [ "$run_it" != "" ]; then
+        rmmod wl12xx
+    fi
+
+    # 2. create reference NVS file with default MAC
+    echo -e "+++ Create reference NVS with $path_to_ini $path_to_ini2"
+    ./calibrator set ref_nvs2 $path_to_ini $path_to_ini2
+    if [ "$?" != "0" ]; then
+        echo -e "Fail to tune channel"
+        exit 1
+    fi
+
+    # 3. Set AutoFEM detection to auto
+    echo -e "+++ Set Auto FEM detection to auto"
+    run_it=`./calibrator set nvs_autofem 1 ./new-nvs.bin`
+
+    # 4. copy NVS to proper place
+    echo -e "+++ Copy reference NVS file to $path_to_install"
+    run_it=`cp -f ./new-nvs.bin $path_to_install`
+
+    # 5. load wl12xx kernel modules
+    sh $0 -b 4
+
+    # 6. calibrate
+    echo -e "+++ Calibrate"
+    ./calibrator wlan0 plt power_mode on
+    if [ "$?" != "0" ]; then
+        echo -e "Fail to set power mode to on"
+        exit 1
+    fi
+
+    ./calibrator wlan0 plt tune_channel 0 7
+    if [ "$?" != "0" ]; then
+        echo -e "Fail to tune channel"
+        exit 1
+    fi
+
+    run_it=`cat $path_to_ini | grep "RxTraceInsertionLoss_5G"`
+    if [ "$run_it" != "" ]; then
+        ./calibrator wlan0 plt tx_bip 1 1 1 1 1 1 1 1 $path_to_install
+        if [ "$?" != "0" ]; then
+            echo -e "Fail to calibrate"
+            exit 1
+        fi
+    else
+        ./calibrator wlan0 plt tx_bip 1 0 0 0 0 0 0 0 $path_to_install
+        if [ "$?" != "0" ]; then
+            echo -e "Fail to calibrate"
+            exit 1
+        fi
+    fi
+
+    ./calibrator wlan0 plt power_mode off
+    if [ "$?" != "0" ]; then
+        echo -e "Fail to set power mode to off"
+        exit 1
+    fi
+
+    # 7. unload wl12xx kernel modules
+    rmmod wl12xx_sdio wl12xx
+
+    # 8. update NVS file with random and valid MAC address
+    echo -e "+++ Update NVS file with random valid MAC address"
+    ./calibrator set nvs_mac ./new-nvs.bin
+    if [ "$?" != "0" ]; then
+        echo -e "Fail to set NVS MAC address"
+        exit 1
+    fi
+
+    # 9. copy calibrated NVS file to proper place
+    echo -e "+++ Copy calibrated NVS file to $path_to_install"
+    run_it=`cp -f ./new-nvs.bin $path_to_install`
+
+    # 10. load wl12xx kernel modules
+    if [ ! -e /sys/kernel/debug/tracing ]; then
+        mount -t debugfs none /sys/kernel/debug/
+    fi
+    sh $0 -b 4
+
+    echo -e "\n\tDear Customer, you are ready to use our calibrated device\n"
+fi
+
+#
+# 1-command calibration
+# parameters are INI file, path where to install NVS (default /lib/firmware)
+#
+
+if [ "$stage_sessanta_quattro" -ne "0" ]; then
+
+    if [ "$have_path_to_ini" -eq "0" ]; then
+        echo -e "Missing ini file parameter"
+        exit 1
+    fi
+
+    # 1. unload wl12xx kernel modules
+    echo -e "+++ Unload wl12xx driver"
+    run_it=`cat /proc/modules | grep "wl12xx_sdio"`
+    if [ "$run_it" != "" ]; then
+        rmmod wl12xx_sdio
+    fi
+    run_it=`cat /proc/modules | grep "wl12xx"`
+    if [ "$run_it" != "" ]; then
+        rmmod wl12xx
+    fi
+
+    # 2. create reference NVS file with default MAC
+    echo -e "+++ Create reference NVS with INI $path_to_ini"
+    ./calibrator set ref_nvs $path_to_ini
+    if [ "$?" != "0" ]; then
+        echo -e "Fail to tune channel"
+        exit 1
+    fi
+
+    # 3. copy NVS to proper place
+    echo -e "+++ Copy reference NVS file to $path_to_install"
+    run_it=`cp -f ./new-nvs.bin $path_to_install`
+
+    # 4. load wl12xx kernel modules
+    sh $0 -b 4
+
+    # 5. calibrate
+    echo -e "+++ Calibrate"
+    ./calibrator wlan0 plt power_mode on
+    if [ "$?" != "0" ]; then
+        echo -e "Fail to set power mode to on"
+        exit 1
+    fi
+
+    ./calibrator wlan0 plt tune_channel 0 7
+    if [ "$?" != "0" ]; then
+        echo -e "Fail to tune channel"
+        exit 1
+    fi
+
+    run_it=`cat $path_to_ini | grep "RxTraceInsertionLoss_5G"`
+    if [ "$run_it" != "" ]; then
+        ./calibrator wlan0 plt tx_bip 1 1 1 1 1 1 1 1 $path_to_install
+        if [ "$?" != "0" ]; then
+            echo -e "Fail to calibrate"
+            exit 1
+        fi
+    else
+        ./calibrator wlan0 plt tx_bip 1 0 0 0 0 0 0 0 $path_to_install
+        if [ "$?" != "0" ]; then
+            echo -e "Fail to calibrate"
+            exit 1
+        fi
+    fi
+
+    ./calibrator wlan0 plt power_mode off
+    if [ "$?" != "0" ]; then
+        echo -e "Fail to set power mode to off"
+        exit 1
+    fi
+
+    # 6. unload wl12xx kernel modules
+    rmmod wl12xx_sdio wl12xx
+
+    # 7. update NVS file with random and valid MAC address
+    echo -e "+++ Update NVS file with random valid MAC address"
+    ./calibrator set nvs_mac ./new-nvs.bin
+    if [ "$?" != "0" ]; then
+        echo -e "Fail to set NVS MAC address"
+        exit 1
+    fi
+
+    # 8. copy calibrated NVS file to proper place
+    echo -e "+++ Copy calibrated NVS file to $path_to_install"
+    run_it=`cp -f ./new-nvs.bin $path_to_install`
+
+    # 9. load wl12xx kernel modules
+    if [ ! -e /sys/kernel/debug/tracing ]; then
+        mount -t debugfs none /sys/kernel/debug/
+    fi
+    sh $0 -b 4
+
+    echo -e "\n\tDear Customer, you are ready to use our calibrated device\n"
+fi
+
+if [ "$dbg_lvl" -eq "-1" ] && [ -e /sys/module/wl12xx/parameters/debug_level ]; then
+    dbg_lvl=`cat /sys/module/wl12xx/parameters/debug_level`
+    echo -e "\ndbg lvl: $dbg_lvl\n"
+elif [ "$dbg_lvl" -ne "0" ] && [ -e /sys/module/wl12xx/parameters/debug_level ]; then
+    echo "$dbg_lvl" > /sys/module/wl12xx/parameters/debug_level
+
+    echo 'module cfg80211 +p' > /sys/kernel/debug/dynamic_debug/control
+    echo 'module mac80211 +p' > /sys/kernel/debug/dynamic_debug/control
+    echo 'module wl12xx +p' > /sys/kernel/debug/dynamic_debug/control
+    echo 'module wl12xx_sdio +p' > /sys/kernel/debug/dynamic_debug/control
+fi
+
+if [ "$set_ip_addr" -ne "0" ]; then
+    echo -e "Going to set IP $ip_addr"
+    ifconfig wlan0 $ip_addr up
+fi
+
+exit 0
diff --git a/mac80211/ti-utils/scripts/mkcard.sh b/mac80211/ti-utils/scripts/mkcard.sh
new file mode 100755
index 0000000..e00779e
--- /dev/null
+++ b/mac80211/ti-utils/scripts/mkcard.sh
@@ -0,0 +1,22 @@
+#! /bin/sh
+
+DRIVE=$1
+
+dd if=/dev/zero of=$DRIVE bs=1024 count=1024
+
+SIZE=`fdisk -l $DRIVE | grep Disk | awk '{print $5}'`
+
+echo DISK SIZE - $SIZE bytes
+
+CYLINDERS=`echo $SIZE/255/63/512 | bc`
+
+echo CYLINDERS - $CYLINDERS
+
+{
+echo ,9,0x0C,*
+echo ,,,-
+} | sfdisk -D -H 255 -S 63 -C $CYLINDERS $DRIVE
+
+mkfs.vfat -F 32 -n "boot" ${DRIVE}1
+mke2fs -j -L "rootfs" ${DRIVE}2
+
diff --git a/mac80211/ti-utils/uim_rfkill/readme.txt b/mac80211/ti-utils/uim_rfkill/readme.txt
new file mode 100644
index 0000000..9d108a3
--- /dev/null
+++ b/mac80211/ti-utils/uim_rfkill/readme.txt
@@ -0,0 +1,25 @@
+This is UIM utility required for TI's shared transport driver in order
+to open UART and to deliver the control of it to the driver.
+
+The author of the utility is Pavan Savoy <pavan_savoy@ti.com>
+
+--- Running UIM utility
+
+It needs to be run at boot, Since linux flavors might require Bluetooth or
+GPS to be turned on at boot. For this have the UIM entry in your either one
+of your rc.S files or you can have special udev rule based on the platform
+driver addition of device "kim".
+
+For Android, the following entry in init.rc should suffice,
+service uim /system/bin/uim-sysfs
+    user root
+    group media bluetooth
+    oneshot
+[edit]
+
+For Angstrom, the following command should be done,
+./uim /dev/ttyO1 3686400 none 22 &
+
+--- Building UIM utility
+make uim
+
diff --git a/mac80211/ti-utils/uim_rfkill/uim.c b/mac80211/ti-utils/uim_rfkill/uim.c
new file mode 100644
index 0000000..c4ea68c
--- /dev/null
+++ b/mac80211/ti-utils/uim_rfkill/uim.c
@@ -0,0 +1,938 @@
+/*
+ *  User Mode Init manager - For TI shared transport
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program;if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <poll.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/utsname.h>
+#ifdef ANDROID
+#include <private/android_filesystem_config.h>
+#include <cutils/log.h>
+#endif
+
+#ifdef ANDROID
+#include <common/ppoll.h> /* for ppoll */
+#endif
+#include "uim.h"
+
+#ifndef ANDROID
+#define INCLUDE_FM 0
+#endif
+
+/* Maintains the exit state of UIM*/
+static int exiting;
+
+/* UART configuration parameters*/
+int uart_flow_control;
+int cust_baud_rate;
+char uart_dev_name[15];
+unsigned int uart_baud_rate;
+struct termios ti;
+int line_discipline;
+
+/* BD address as string and a pointer to array of hex bytes */
+char uim_bd_address[17];
+bdaddr_t *bd_addr;
+
+/* File descriptor for the UART device*/
+int dev_fd;
+
+/* Maintains the state of N_TI_WL line discipline installation*/
+unsigned char st_state = UNINSTALL_N_TI_WL;
+unsigned char prev_st_state = UNINSTALL_N_TI_WL;
+
+/* from kernel's include/linux/rfkill.h
+ * the header in itself not included because of the
+ * version mismatch of android kernel headers project
+ */
+
+/**
+ * enum rfkill_operation - operation types
+ * @RFKILL_OP_ADD: a device was added
+ * @RFKILL_OP_DEL: a device was removed
+ * @RFKILL_OP_CHANGE: a device's state changed -- userspace changes one device
+ * @RFKILL_OP_CHANGE_ALL: userspace changes all devices (of a type, or all)
+ */
+enum rfkill_operation {
+    RFKILL_OP_ADD = 0,
+    RFKILL_OP_DEL,
+    RFKILL_OP_CHANGE,
+    RFKILL_OP_CHANGE_ALL,
+};
+
+/**
+ * struct rfkill_event - events for userspace on /dev/rfkill
+ * @idx: index of dev rfkill
+ * @type: type of the rfkill struct
+ * @op: operation code
+ * @hard: hard state (0/1)
+ * @soft: soft state (0/1)
+ *
+ * Structure used for userspace communication on /dev/rfkill,
+ * used for events from the kernel and control to the kernel.
+ */
+#ifdef ANDROID
+struct rfkill_event {
+    __u32 idx;
+    __u8  type;
+    __u8  op;
+    __u8  soft, hard;
+} __packed;
+#else
+struct rfkill_event {
+    uint32_t idx;
+    uint8_t  type;
+    uint8_t  op;
+    uint8_t  soft, hard;
+} __packed;
+#endif /* ANDROID */
+
+/* to read events and filter notifications for us */
+struct rfkill_event rf_event;
+unsigned int   rfkill_idx;
+
+/*****************************************************************************/
+#ifdef UIM_DEBUG
+/*  Function to Read the firmware version
+ *  module into the system. Currently used for
+ *  debugging purpose, whenever the baud rate is changed
+ */
+void read_firmware_version()
+{
+    int index = 0;
+    char resp_buffer[20] = { 0 };
+    unsigned char buffer[] = { 0x01, 0x01, 0x10, 0x00 };
+
+    UIM_START_FUNC();
+    UIM_VER(" wrote %d bytes", (int)write(dev_fd, buffer, 4));
+    UIM_VER(" reading %d bytes", (int)read(dev_fd, resp_buffer, 15));
+
+    for (index = 0; index < 15; index++) {
+        UIM_VER(" %x ", resp_buffer[index]);
+    }
+
+    printf("\n");
+}
+#endif
+
+/*****************************************************************************/
+#ifdef ANDROID                 /* library for android to do insmod/rmmod  */
+
+/* Function to insert the kernel module into the system*/
+static int insmod(const char *filename, const char *args)
+{
+    void *module;
+    unsigned int size;
+    int ret = -1;
+
+    UIM_START_FUNC();
+
+    module = (void *)load_file(filename, &size);
+    if (!module) {
+        return ret;
+    }
+
+    ret = init_module(module, size, args);
+    free(module);
+
+    return ret;
+}
+
+/* Function to remove the kernel module from the system*/
+static int rmmod(const char *modname)
+{
+    int ret = -1;
+    int maxtry = MAX_TRY;
+
+    UIM_START_FUNC();
+
+    /* Retry MAX_TRY number of times in case of
+     * failure
+     */
+    while (maxtry-- > 0) {
+        ret = delete_module(modname, O_NONBLOCK | O_EXCL);
+        if (ret < 0 && errno == EAGAIN) {
+            sleep(1);
+        }
+        else
+            break;
+    }
+
+    /* Failed to remove the module
+    */
+    if (ret != 0) {
+        UIM_ERR("Unable to unload driver module \"%s\": %s",
+                modname, strerror(errno));
+    }
+    return ret;
+}
+#endif /*ANDROID*/
+
+/*****************************************************************************/
+/* Function to read the HCI event from the given file descriptor
+ *
+ * This will parse the response received and returns error
+ * if the required response is not received
+ */
+int read_hci_event(int fd, unsigned char *buf, int size)
+{
+    int remain, rd;
+    int count = 0;
+    int reading = 1;
+    int rd_retry_count = 0;
+    struct timespec tm = {0, 50*1000*1000};
+
+    UIM_START_FUNC();
+
+    UIM_VER(" read_hci_event");
+    if (size <= 0) {
+        return -1;
+    }
+
+    /* The first byte identifies the packet type. For HCI event packets, it
+     * should be 0x04, so we read until we get to the 0x04. */
+    while (reading) {
+        rd = read(fd, buf, 1);
+        if (rd <= 0 && rd_retry_count++ < 4) {
+            nanosleep(&tm, NULL);
+            continue;
+        } else if (rd_retry_count >= 4) {
+            return -1;
+        }
+
+        if (buf[0] == RESP_PREFIX) {
+            break;
+        }
+    }
+    count++;
+
+    /* The next two bytes are the event code and parameter total length. */
+    while (count < 3) {
+        rd = read(fd, buf + count, 3 - count);
+        if (rd <= 0) {
+            return -1;
+        }
+        count += rd;
+    }
+
+    /* Now we read the parameters. */
+    if (buf[2] < (size - 3)) {
+        remain = buf[2];
+    } else {
+        remain = size - 3;
+    }
+
+    while ((count - 3) < remain) {
+        rd = read(fd, buf + count, remain - (count - 3));
+        if (rd <= 0) {
+            return -1;
+        }
+        count += rd;
+    }
+
+    return count;
+}
+
+/* Function to read the Command complete event
+ *
+ * This will read the response for the change speed
+ * command that was sent to configure the UART speed
+ * with the custom baud rate
+ */
+static int read_command_complete(int fd, unsigned short opcode)
+{
+    command_complete_t resp;
+
+    UIM_START_FUNC();
+
+    UIM_VER(" Command complete started");
+    if (read_hci_event(fd, (unsigned char *)&resp, sizeof(resp)) < 0) {
+        UIM_ERR(" Invalid response");
+        return -1;
+    }
+
+    /* Response should be an event packet */
+    if (resp.uart_prefix != HCI_EVENT_PKT) {
+        UIM_ERR
+            (" Error in response: not an event packet, but 0x%02x!",
+             resp.uart_prefix);
+        return -1;
+    }
+
+    /* Response should be a command complete event */
+    if (resp.hci_hdr.evt != EVT_CMD_COMPLETE) {
+        /* event must be event-complete */
+        UIM_ERR
+            (" Error in response: not a cmd-complete event,but 0x%02x!",
+             resp.hci_hdr.evt);
+        return -1;
+    }
+
+    if (resp.hci_hdr.plen < 4) {
+        /* plen >= 4 for EVT_CMD_COMPLETE */
+        UIM_ERR(" Error in response: plen is not >= 4, but 0x%02x!",
+                resp.hci_hdr.plen);
+        return -1;
+    }
+
+    if (resp.cmd_complete.opcode != (unsigned short)opcode) {
+        UIM_ERR(" Error in response: opcode is 0x%04x, not 0x%04x!",
+                resp.cmd_complete.opcode, opcode);
+        return -1;
+    }
+
+    UIM_DBG(" Command complete done");
+    return resp.status == 0 ? 0 : -1;
+}
+
+/* Function to set the default baud rate
+ *
+ * The default baud rate of 115200 is set to the UART from the host side
+ * by making a call to this function.This function is also called before
+ * making a call to set the custom baud rate
+ */
+static int set_baud_rate()
+{
+    UIM_START_FUNC();
+
+    tcflush(dev_fd, TCIOFLUSH);
+
+    /* Get the attributes of UART */
+    if (tcgetattr(dev_fd, &ti) < 0) {
+        UIM_ERR(" Can't get port settings");
+        return -1;
+    }
+
+    /* Change the UART attributes before
+     * setting the default baud rate*/
+    cfmakeraw(&ti);
+
+    ti.c_cflag |= 1;
+    ti.c_cflag |= CRTSCTS;
+
+    /* Set the attributes of UART after making
+     * the above changes
+     */
+    tcsetattr(dev_fd, TCSANOW, &ti);
+
+    /* Set the actual default baud rate */
+    cfsetospeed(&ti, B115200);
+    cfsetispeed(&ti, B115200);
+    tcsetattr(dev_fd, TCSANOW, &ti);
+
+    tcflush(dev_fd, TCIOFLUSH);
+    UIM_DBG(" set_baud_rate() done");
+
+    return 0;
+}
+
+/* Function to set the UART custom baud rate.
+ *
+ * The UART baud rate has already been
+ * set to default value 115200 before calling this function.
+ * The baud rate is then changed to custom baud rate by this function*/
+static int set_custom_baud_rate()
+{
+    UIM_START_FUNC();
+
+    struct termios2 ti2;
+
+    UIM_VER(" Changing baud rate to %u, flow control to %u",
+            cust_baud_rate, uart_flow_control);
+
+    /* Flush non-transmitted output data,
+     * non-read input data or both*/
+    tcflush(dev_fd, TCIOFLUSH);
+
+    /*Set the UART flow control */
+    if (uart_flow_control) {
+        ti.c_cflag |= CRTSCTS;
+    } else {
+        ti.c_cflag &= ~CRTSCTS;
+    }
+
+    /*
+     * Set the parameters associated with the UART
+     * The change will occur immediately by using TCSANOW
+     */
+    if (tcsetattr(dev_fd, TCSANOW, &ti) < 0) {
+        UIM_ERR(" Can't set port settings");
+        return -1;
+    }
+
+    tcflush(dev_fd, TCIOFLUSH);
+
+    /*Set the actual baud rate */
+    ioctl(dev_fd, TCGETS2, &ti2);
+    ti2.c_cflag &= ~CBAUD;
+    ti2.c_cflag |= BOTHER;
+    ti2.c_ospeed = cust_baud_rate;
+    ioctl(dev_fd, TCSETS2, &ti2);
+
+    UIM_DBG(" set_custom_baud_rate() done");
+    return 0;
+}
+
+/*
+ * Handling the Signals sent from the Kernel Init Manager.
+ * After receiving the signals, configure the baud rate, flow
+ * control and Install the N_TI_WL line discipline
+ */
+int st_sig_handler(int signo)
+{
+    int ldisc, len;
+    uim_speed_change_cmd cmd;
+
+    uim_bdaddr_change_cmd addr_cmd;
+
+    UIM_START_FUNC();
+
+    /* Raise a signal after when UIM is killed.
+     * This will exit UIM, and remove the inserted kernel
+     * modules
+     */
+    if (signo == SIGINT) {
+        UIM_DBG(" Exiting. . .");
+        exiting = 1;
+        return -1;
+    }
+
+    /* Install the line discipline when the signal is received by UIM.
+     * Whenever the first protocol tries to register with the ST core, the
+     * ST KIM will send a signal SIGUSR2 to the UIM to install the N_TI_WL
+     * line discipline and do the host side UART configurations.
+     *
+     * On failure, ST KIM's line discipline installation times out, and the
+     * relevant protocol register fails
+     */
+    if (st_state == INSTALL_N_TI_WL) {
+        UIM_VER(" signal received, opening %s", uart_dev_name);
+        dev_fd = open(uart_dev_name, O_RDWR);
+        if (dev_fd < 0) {
+            UIM_ERR(" Can't open %s", uart_dev_name);
+            return -1;
+        }
+        /*
+         * Set only the default baud rate.
+         * This will set the baud rate to default 115200
+         */
+        if (set_baud_rate() < 0) {
+            UIM_ERR(" set_baudrate() failed");
+            close(dev_fd);
+            return -1;
+        }
+
+        fcntl(dev_fd, F_SETFL,fcntl(dev_fd, F_GETFL) | O_NONBLOCK);
+        /* Set only thecustom baud rate */
+        if (cust_baud_rate) {
+
+            /* Forming the packet for Change speed command */
+            cmd.uart_prefix = HCI_COMMAND_PKT;
+            cmd.hci_hdr.opcode = HCI_HDR_OPCODE;
+            cmd.hci_hdr.plen = sizeof(unsigned long);
+            cmd.speed = cust_baud_rate;
+
+            /* Writing the change speed command to the UART
+             * This will change the UART speed at the controller
+             * side
+             */
+            UIM_VER(" Setting speed to %d", cust_baud_rate);
+            len = write(dev_fd, &cmd, sizeof(cmd));
+            if (len < 0) {
+                UIM_ERR(" Failed to write speed-set command");
+                close(dev_fd);
+                return -1;
+            }
+
+            /* Read the response for the Change speed command */
+            if (read_command_complete(dev_fd, HCI_HDR_OPCODE) < 0) {
+                close(dev_fd);
+                return -1;
+            }
+
+            UIM_VER(" Speed changed to %d", cust_baud_rate);
+
+            /* Set the actual custom baud rate at the host side */
+            if (set_custom_baud_rate() < 0) {
+                UIM_ERR(" set_custom_baud_rate() failed");
+                close(dev_fd);
+
+                return -1;
+            }
+
+            /* Set the uim BD address */
+            if (uim_bd_address[0] != 0) {
+
+                memset(&addr_cmd, 0, sizeof(addr_cmd));
+                /* Forming the packet for change BD address command*/
+                addr_cmd.uart_prefix = HCI_COMMAND_PKT;
+                addr_cmd.hci_hdr.opcode = WRITE_BD_ADDR_OPCODE;
+                addr_cmd.hci_hdr.plen = sizeof(bdaddr_t);
+                memcpy(&addr_cmd.addr, bd_addr, sizeof(bdaddr_t));
+
+                /* Writing the change BD address command to the UART
+                 * This will change the change BD address  at the controller
+                 * side
+                 */
+                len = write(dev_fd, &addr_cmd, sizeof(addr_cmd));
+                if (len < 0) {
+                    UIM_ERR(" Failed to write BD address command");
+                    close(dev_fd);
+                    return -1;
+                }
+
+                /* Read the response for the change BD address command */
+                if (read_command_complete(dev_fd, WRITE_BD_ADDR_OPCODE) < 0) {
+                    close(dev_fd);
+                    return -1;
+                }
+
+                UIM_VER(" BD address changed to %s", uim_bd_address);
+            }
+#ifdef UIM_DEBUG
+            read_firmware_version();
+#endif
+        }
+
+        /* After the UART speed has been changed, the IOCTL is
+         * is called to set the line discipline to N_TI_WL
+         */
+        ldisc = line_discipline;
+        if (ioctl(dev_fd, TIOCSETD, &ldisc) < 0) {
+            UIM_ERR(" Can't set line discipline");
+            close(dev_fd);
+            return -1;
+        }
+
+        UIM_DBG(" Installed N_TI_WL Line displine");
+    }
+    else {
+        UIM_DBG(" Un-Installed N_TI_WL Line displine");
+        /* UNINSTALL_N_TI_WL - When the Signal is received from KIM */
+        /* closing UART fd */
+        close(dev_fd);
+    }
+    prev_st_state = st_state;
+    return 0;
+}
+int remove_modules()
+{
+    int err = 0;
+
+#ifdef ANDROID
+    UIM_VER(" Removing gps_drv ");
+    if (rmmod("gps_drv") != 0) {
+        UIM_ERR(" Error removing gps_drv module");
+        err = -1;
+    } else {
+        UIM_DBG(" Removed gps_drv module");
+    }
+
+    UIM_VER(" Removing fm_drv ");
+    if (rmmod("fm_drv") != 0) {
+        UIM_ERR(" Error removing fm_drv module");
+        err = -1;
+    } else {
+        UIM_DBG(" Removed fm_drv module");
+    }
+    UIM_DBG(" Removed fm_drv module");
+
+    UIM_VER(" Removing bt_drv ");
+
+    if (rmmod("bt_drv") != 0) {
+        UIM_ERR(" Error removing bt_drv module");
+        err = -1;
+    } else {
+        UIM_DBG(" Removed bt_drv module");
+    }
+    UIM_DBG(" Removed bt_drv module");
+
+    /*Remove the Shared Transport */
+    UIM_VER(" Removing st_drv ");
+
+    if (rmmod("st_drv") != 0) {
+        UIM_ERR(" Error removing st_drv module");
+        err = -1;
+    } else {
+        UIM_DBG(" Removed st_drv module ");
+    }
+    UIM_DBG(" Removed st_drv module ");
+#else
+#if INCLUDE_FM
+    UIM_VER(" Removing fm_drv ");
+    if (system("rmmod fm_drv") != 0) {
+        UIM_ERR(" Error removing fm_drv module");
+        err = -1;
+    } else {
+        UIM_DBG(" Removed fm_drv module");
+    }
+#endif /* INCLUDE_FM */
+    UIM_VER(" Removing bt_drv ");
+    if (system("rmmod bt_drv") != 0) {
+        UIM_ERR(" Error removing bt_drv module");
+        err = -1;
+    } else {
+        UIM_DBG(" Removed bt_drv module");
+    }
+
+    /*Remove the Shared Transport */
+    UIM_VER(" Removing st_drv ");
+
+    if (system("rmmod st_drv") != 0) {
+        UIM_ERR(" Error removing st_drv module");
+        err = -1;
+    } else {
+        UIM_DBG(" Removed st_drv module ");
+    }
+#endif
+    return err;
+}
+
+int change_rfkill_perms(void)
+{
+    int fd, id, sz;
+    char path[64];
+    char buf[16];
+    for (id = 0; id < 50; id++) {
+        snprintf(path, sizeof(path), "/sys/class/rfkill/rfkill%d/type", id);
+        fd = open(path, O_RDONLY);
+        if (fd < 0) {
+            UIM_DBG("open(%s) failed: %s (%d)\n", path, strerror(errno), errno);
+            continue;
+        }
+        sz = read(fd, &buf, sizeof(buf));
+        close(fd);
+        if (sz >= 9 && memcmp(buf, "bluetooth", 9) == 0) {
+            UIM_DBG("found bluetooth rfkill entry @ %d\n", id);
+            rfkill_idx = id;
+            break;
+        }
+    }
+    if (id == 50) {
+        return -1;
+    }
+#ifdef ANDROID
+    sprintf(path, "/sys/class/rfkill/rfkill%d/state", id);
+    sz = chown(path, AID_BLUETOOTH, AID_BLUETOOTH);
+    if (sz < 0) {
+        UIM_ERR("change mode failed for %s (%d)\n", path, errno);
+        return -1;
+    }
+#endif /* ANDROID */
+    /*
+     * bluetooth group's user system needs write permission
+     */
+    sz = chmod(path, 0660);
+    if (sz < 0) {
+        UIM_ERR("change mode failed for %s (%d)\n", path, errno);
+        return -1;
+    }
+    UIM_DBG("changed permissions for %s(%d) \n", path, sz);
+    /* end of change_perms */
+
+    return 0;
+}
+
+void *bt_malloc(size_t size)
+{
+    return malloc(size);
+}
+
+/* Function to convert the BD address from ascii to hex value */
+bdaddr_t *strtoba(const char *str)
+{
+    const char *ptr = str;
+    int i;
+
+    uint8_t *ba = bt_malloc(sizeof(bdaddr_t));
+    if (!ba) {
+        return NULL;
+    }
+
+    for (i = 0; i < 6; i++) {
+        ba[i] = (uint8_t) strtol(ptr, NULL, 16);
+        if (i != 5 && !(ptr = strchr(ptr, ':'))) {
+            ptr = ":00:00:00:00:00";
+        }
+        ptr++;
+    }
+
+    return (bdaddr_t *) ba;
+}
+
+/*****************************************************************************/
+int main(int argc, char *argv[])
+{
+    int st_fd,err;
+    struct stat file_stat;
+#ifndef ANDROID        /* used on ubuntu */
+    char *tist_ko_path;
+    struct utsname name;
+#endif
+    struct pollfd   p;
+    sigset_t        sigs;
+
+    UIM_START_FUNC();
+    err = 0;
+
+    /* Parse the user input */
+    if ((argc == 5) || (argc == 6)) {
+        strcpy(uart_dev_name, argv[1]);
+        uart_baud_rate = atoi(argv[2]);
+        uart_flow_control = atoi(argv[3]);
+        line_discipline = atoi(argv[4]);
+
+        /* Depending upon the baud rate value, differentiate
+         * the custom baud rate and default baud rate
+         */
+        switch (uart_baud_rate) {
+            case 115200:
+                UIM_VER(" Baudrate 115200");
+                break;
+            case 9600:
+            case 19200:
+            case 38400:
+            case 57600:
+            case 230400:
+            case 460800:
+            case 500000:
+            case 576000:
+            case 921600:
+            case 1000000:
+            case 1152000:
+            case 1500000:
+            case 2000000:
+            case 2500000:
+            case 3000000:
+            case 3500000:
+            case 3686400:
+            case 4000000:
+                cust_baud_rate = uart_baud_rate;
+                UIM_VER(" Baudrate %d", cust_baud_rate);
+                break;
+            default:
+                UIM_ERR(" Inavalid Baud Rate");
+                break;
+        }
+
+        memset(&uim_bd_address, 0, sizeof(uim_bd_address));
+    } else {
+        UIM_ERR(" Invalid arguements");
+        UIM_ERR(" Usage: uim [Uart device] [Baud rate] [Flow control] [Line discipline] <bd address>");
+        return -1;
+    }
+    if (argc == 6) {
+        /* BD address passed as string in xx:xx:xx:xx:xx:xx format */
+        strcpy(uim_bd_address, argv[5]);
+        bd_addr = strtoba(uim_bd_address);
+    }
+
+
+#ifndef ANDROID
+    if (uname (&name) == -1) {
+        UIM_ERR("cannot get kernel release name");
+        return -1;
+    }
+#else  /* if ANDROID */
+
+    if (0 == lstat("/st_drv.ko", &file_stat)) {
+        if (insmod("/st_drv.ko", "") < 0) {
+            UIM_ERR(" Error inserting st_drv module");
+            return -1;
+        } else {
+            UIM_DBG(" Inserted st_drv module");
+        }
+    } else {
+        if (0 == lstat("/dev/rfkill", &file_stat)) {
+            UIM_DBG("ST built into the kernel ?");
+        } else {
+            UIM_ERR("BT/FM/GPS would be unavailable on system");
+            UIM_ERR(" rfkill device '/dev/rfkill' not found ");
+            return -1;
+        }
+    }
+#endif
+
+#ifndef ANDROID
+    /*-- Insmod of ST driver --*/
+    asprintf(&tist_ko_path,
+            "/lib/modules/%s/kernel/drivers/misc/ti-st/st_drv.ko",name.release);
+    if (0 == lstat(tist_ko_path, &file_stat)) {
+        if (system("insmod /lib/modules/`uname -r`/kernel/drivers/misc/ti-st/st_drv.ko") != 0) {
+            UIM_ERR(" Error inserting st_drv module");
+            free(tist_ko_path);
+            return -1;
+        } else {
+            UIM_DBG(" Inserted st_drv module");
+        }
+    } else {
+        UIM_ERR("ST driver built into the kernel ?");
+    }
+    free(tist_ko_path);
+#endif
+
+    if (change_rfkill_perms() < 0) {
+        /* possible error condition */
+        UIM_ERR("rfkill not enabled in st_drv - BT on from UI might fail\n");
+    }
+
+#ifndef ANDROID
+    /*-- Insmod of BT driver --*/
+    asprintf(&tist_ko_path,
+            "/lib/modules/%s/kernel/drivers/staging/ti-st/bt_drv.ko",name.release);
+    if (0 == lstat(tist_ko_path, &file_stat)) {
+        if (system("insmod /lib/modules/`uname -r`/kernel/drivers/staging/ti-st/bt_drv.ko") != 0) {
+            UIM_ERR(" Error inserting bt_drv module");
+            system("rmmod st_drv");
+            free(tist_ko_path);
+            return -1;
+        } else {
+            UIM_DBG(" Inserted bt_drv module");
+        }
+    } else {
+        UIM_ERR("BT driver built into the kernel ?");
+    }
+    free(tist_ko_path);
+
+#if INCLUDE_FM
+    /*-- Insmod of FM driver --*/
+    asprintf(&tist_ko_path,
+            "/lib/modules/%s/kernel/drivers/staging/ti-st/fm_drv.ko",name.release);
+    if (0 == lstat(tist_ko_path, &file_stat)) {
+        if (system("insmod /lib/modules/`uname -r`/kernel/drivers/staging/ti-st/fm_drv.ko") != 0) {
+            UIM_ERR(" Error inserting fm_drv module");
+            system("rmmod bt_drv");
+            system("rmmod st_drv");
+            free(tist_ko_path);
+            return -1;
+        } else {
+            UIM_DBG(" Inserted fm_drv module");
+        }
+    } else {
+        UIM_ERR("FM driver built into the kernel ?");
+    }
+    free(tist_ko_path);
+#endif /* INCLUDE_FM */
+#else  /* if ANDROID */
+    if (0 == lstat("/bt_drv.ko", &file_stat)) {
+        if (insmod("/bt_drv.ko", "") < 0) {
+            UIM_ERR(" Error inserting bt_drv module, NO BT? ");
+        } else {
+            UIM_DBG(" Inserted bt_drv module");
+        }
+    } else {
+        UIM_DBG("BT driver module un-available... ");
+        UIM_DBG("BT driver built into the kernel ?");
+    }
+
+    if (0 == lstat("/fm_drv.ko", &file_stat)) {
+        if (insmod("/fm_drv.ko", "") < 0) {
+            UIM_ERR(" Error inserting fm_drv module, NO FM? ");
+        } else {
+            UIM_DBG(" Inserted fm_drv module");
+        }
+    } else {
+        UIM_DBG("FM driver module un-available... ");
+        UIM_DBG("FM driver built into the kernel ?");
+    }
+
+    if (0 == lstat("/gps_drv.ko", &file_stat)) {
+        if (insmod("/gps_drv.ko", "") < 0) {
+            UIM_ERR(" Error inserting gps_drv module, NO GPS? ");
+        } else {
+            UIM_DBG(" Inserted gps_drv module");
+        }
+    } else {
+        UIM_DBG("GPS driver module un-available... ");
+        UIM_DBG("GPS driver built into the kernel ?");
+    }
+
+    if (chmod("/dev/tifm", 0666) < 0) {
+        UIM_ERR("unable to chmod /dev/tifm");
+    }
+#endif
+    /* rfkill device's open/poll/read */
+    st_fd = open("/dev/rfkill", O_RDONLY);
+    if (st_fd < 0) {
+        UIM_DBG("unable to open /dev/rfkill (%s)", strerror(errno));
+        remove_modules();
+        return -1;
+    }
+
+
+    p.fd = st_fd;
+    p.events = POLLERR | POLLHUP | POLLOUT | POLLIN;
+
+    sigfillset(&sigs);
+    sigdelset(&sigs, SIGCHLD);
+    sigdelset(&sigs, SIGPIPE);
+    sigdelset(&sigs, SIGTERM);
+    sigdelset(&sigs, SIGINT);
+    sigdelset(&sigs, SIGHUP);
+
+RE_POLL:
+    while (!exiting) {
+        p.revents = 0;
+#ifdef ANDROID
+        err = ppoll(&p, 1, NULL, &sigs);
+#else
+        err = poll(&p, 1, -1);
+#endif /* ANDROID */
+        if (err < 0 && errno == EINTR) {
+            continue;
+        }
+        if (err) {
+            break;
+        }
+    }
+    if (!exiting) {
+        err = read(st_fd, &rf_event, sizeof(rf_event));
+        UIM_DBG("rf_event: %d, %d, %d, %d, %d\n", rf_event.idx,
+                rf_event.type, rf_event.op ,rf_event.hard,
+                rf_event.soft);
+        if ((rf_event.op == RFKILL_OP_CHANGE) &&
+                (rf_event.idx == rfkill_idx)) {
+            if (rf_event.hard == 1) /* hard blocked */ {
+                st_state = UNINSTALL_N_TI_WL;
+            } else    /* unblocked */ {
+                st_state = INSTALL_N_TI_WL;
+            }
+
+            if (prev_st_state != st_state) {
+                st_sig_handler(SIGUSR2);
+            }
+        }
+        goto RE_POLL;
+    }
+
+    if(remove_modules() < 0) {
+        UIM_ERR(" Error removing modules ");
+        close(st_fd);
+        return -1;
+    }
+
+    close(st_fd);
+    return 0;
+}
diff --git a/mac80211/ti-utils/uim_rfkill/uim.h b/mac80211/ti-utils/uim_rfkill/uim.h
new file mode 100644
index 0000000..ec73faf
--- /dev/null
+++ b/mac80211/ti-utils/uim_rfkill/uim.h
@@ -0,0 +1,154 @@
+/*
+ *  User Mode Init manager - For shared transport
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program;if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef UIM_H
+#define UIM_H
+
+/* Paramaters to set the baud rate*/
+#define  FLOW_CTL       0x0001
+#define  BOTHER         0x00001000
+#define  ARM_NCCS       19
+
+#define TCGETS2      _IOR('T',0x2A, struct termios2)
+#define TCSETS2      _IOW('T',0x2B, struct termios2)
+
+/*HCI Command and Event information*/
+#define HCI_HDR_OPCODE          0xff36
+#define WRITE_BD_ADDR_OPCODE    0xFC06
+#define RESP_PREFIX             0x04
+#define MAX_TRY                 10
+
+/* HCI Packet types */
+#define HCI_COMMAND_PKT         0x01
+#define HCI_EVENT_PKT           0x04
+
+/* HCI command macros*/
+#define HCI_EVENT_HDR_SIZE              2
+#define HCI_COMMAND_HDR_SIZE            3
+#define UIM_WRITE_BD_ADDR_CP_SIZE       6
+
+
+/* HCI event macros*/
+#define EVT_CMD_COMPLETE_SIZE   3
+#define EVT_CMD_STATUS_SIZE     4
+#define EVT_CMD_COMPLETE        0x0E
+#define EVT_CMD_STATUS          0x0F
+
+
+#define VERBOSE
+#ifndef ANDROID
+#define LOGE printf
+#endif /* ANDROID */
+#define LOG_TAG "uim-rfkill: "
+#define UIM_ERR(fmt, arg...)  LOGE("uim:"fmt"\n" , ##arg)
+#if defined(UIM_DEBUG)          /* limited debug messages */
+#define UIM_START_FUNC()      LOGE("uim: Inside %s\n", __FUNCTION__)
+#define UIM_DBG(fmt, arg...)  LOGE("uim:"fmt"\n" , ## arg)
+#define UIM_VER(fmt, arg...)
+#elif defined(VERBOSE)          /* very verbose */
+#define UIM_START_FUNC()      LOGE("uim: Inside %s\n", __FUNCTION__)
+#define UIM_DBG(fmt, arg...)  LOGE("uim:"fmt"\n" , ## arg)
+#define UIM_VER(fmt, arg...)  LOGE("uim:"fmt"\n" , ## arg)
+#else /* error msgs only */
+#define UIM_START_FUNC()
+#define UIM_DBG(fmt, arg...)
+#define UIM_VER(fmt, arg...)
+#endif
+
+/*Termios2 structure for setting the Custom baud rate*/
+struct termios2 {
+    tcflag_t c_iflag;       /* input mode flags */
+    tcflag_t c_oflag;       /* output mode flags */
+    tcflag_t c_cflag;       /* control mode flags */
+    tcflag_t c_lflag;       /* local mode flags */
+    cc_t c_line;            /* line discipline */
+    cc_t c_cc[ARM_NCCS];    /* control characters */
+    speed_t c_ispeed;       /* input speed */
+    speed_t c_ospeed;       /* output speed */
+};
+
+/* HCI command header*/
+typedef struct {
+    uint16_t        opcode;         /* OCF & OGF */
+    uint8_t         plen;
+} __attribute__ ((packed))      hci_command_hdr;
+
+/* HCI event header*/
+typedef struct {
+    uint8_t         evt;
+    uint8_t         plen;
+} __attribute__ ((packed))      hci_event_hdr;
+
+/* HCI command complete event*/
+typedef struct {
+    uint8_t         ncmd;
+    uint16_t        opcode;
+} __attribute__ ((packed)) evt_cmd_complete;
+
+/* HCI event status*/
+typedef struct {
+    uint8_t         status;
+    uint8_t         ncmd;
+    uint16_t        opcode;
+} __attribute__ ((packed)) evt_cmd_status;
+
+/* HCI Event structure to set the cusrom baud rate*/
+typedef struct {
+    uint8_t uart_prefix;
+    hci_event_hdr hci_hdr;
+    evt_cmd_complete cmd_complete;
+    uint8_t status;
+    uint8_t data[16];
+} __attribute__ ((packed)) command_complete_t;
+
+/* HCI Command structure to set the cusrom baud rate*/
+typedef struct {
+    uint8_t uart_prefix;
+    hci_command_hdr hci_hdr;
+    uint32_t speed;
+} __attribute__ ((packed)) uim_speed_change_cmd;
+
+/* BD address structure to set the uim BD address*/
+typedef struct {
+    unsigned char b[6];
+} __attribute__((packed)) bdaddr_t;
+
+/* HCI Command structure to set the uim BD address*/
+typedef struct {
+    uint8_t uart_prefix;
+    hci_command_hdr hci_hdr;
+    bdaddr_t addr;
+} __attribute__ ((packed)) uim_bdaddr_change_cmd;
+
+/* Signal received from KIM will install line discipline at first,
+ * the next signal received from KIM will un-install the
+ * line discipline*/
+enum {
+    /* expecting signal from KIM to setup uart fd for ST */
+    INSTALL_N_TI_WL,
+
+    /* expecting signal from KIM to close uart fd */
+    UNINSTALL_N_TI_WL,
+};
+
+/* Functions to insert and remove the kernel modules from the system*/
+extern int init_module(void *, unsigned int, const char *);
+extern int delete_module(const char *, unsigned int);
+extern int load_file(const char *, unsigned int *);
+
+#endif /* UIM_H */
diff --git a/mac80211/wpa_supplicant_lib/Android.mk b/mac80211/wpa_supplicant_lib/Android.mk
new file mode 100644
index 0000000..541d8bd
--- /dev/null
+++ b/mac80211/wpa_supplicant_lib/Android.mk
@@ -0,0 +1,68 @@
+LOCAL_PATH := $(call my-dir)
+
+ifeq ($(TARGET_SIMULATOR),true)
+  $(error This makefile must not be included when building the simulator)
+endif
+
+ifeq ($(WPA_SUPPLICANT_VERSION),VER_0_6_X)
+    WPA_SUPPL_DIR = external/wpa_supplicant_6/wpa_supplicant
+endif
+
+ifeq ($(WPA_SUPPLICANT_VERSION),VER_0_8_X)
+    WPA_SUPPL_DIR = external/wpa_supplicant_8/wpa_supplicant
+endif
+
+include $(WPA_SUPPL_DIR)/.config
+
+ifneq ($(BOARD_WPA_SUPPLICANT_DRIVER),)
+  CONFIG_DRIVER_$(BOARD_WPA_SUPPLICANT_DRIVER) := y
+endif
+
+L_CFLAGS = -DCONFIG_DRIVER_CUSTOM -DWPA_SUPPLICANT_$(WPA_SUPPLICANT_VERSION)
+L_SRC :=
+
+ifdef CONFIG_NO_STDOUT_DEBUG
+L_CFLAGS += -DCONFIG_NO_STDOUT_DEBUG
+endif
+
+ifdef CONFIG_DEBUG_FILE
+L_CFLAGS += -DCONFIG_DEBUG_FILE
+endif
+
+ifdef CONFIG_ANDROID_LOG
+L_CFLAGS += -DCONFIG_ANDROID_LOG
+endif
+
+ifdef CONFIG_IEEE8021X_EAPOL
+L_CFLAGS += -DIEEE8021X_EAPOL
+endif
+
+ifdef CONFIG_WPS
+L_CFLAGS += -DCONFIG_WPS
+endif
+
+ifdef CONFIG_DRIVER_WEXT
+L_SRC += driver_mac80211.c
+endif
+
+ifdef CONFIG_DRIVER_NL80211
+L_SRC += driver_mac80211_nl.c
+endif
+
+INCLUDES = $(WPA_SUPPL_DIR) \
+    $(WPA_SUPPL_DIR)/src \
+    $(WPA_SUPPL_DIR)/src/common \
+    $(WPA_SUPPL_DIR)/src/drivers \
+    $(WPA_SUPPL_DIR)/src/l2_packet \
+    $(WPA_SUPPL_DIR)/src/utils \
+    $(WPA_SUPPL_DIR)/src/wps \
+    external/libnl-headers
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := lib_driver_cmd_wl12xx
+LOCAL_MODULE_TAGS := eng
+LOCAL_SHARED_LIBRARIES := libc libcutils libnl
+LOCAL_CFLAGS := $(L_CFLAGS)
+LOCAL_SRC_FILES := $(L_SRC)
+LOCAL_C_INCLUDES := $(INCLUDES)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/mac80211/wpa_supplicant_lib/driver_mac80211.c b/mac80211/wpa_supplicant_lib/driver_mac80211.c
new file mode 100644
index 0000000..c8d41e0
--- /dev/null
+++ b/mac80211/wpa_supplicant_lib/driver_mac80211.c
@@ -0,0 +1,2179 @@
+/*
+ * WPA Supplicant - driver interaction with generic Linux Wireless Extensions
+ * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ *
+ * This file implements a driver interface for the Linux Wireless Extensions.
+ * When used with WE-18 or newer, this interface can be used as-is with number
+ * of drivers. In addition to this, some of the common functions in this file
+ * can be used by other driver interface implementations that use generic WE
+ * ioctls, but require private ioctls for some of the functionality.
+ */
+
+#include "includes.h"
+#include <sys/ioctl.h>
+#include <net/if_arp.h>
+#include <net/if.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <cutils/properties.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+#include "nl80211.h"
+
+#include "wireless_copy.h"
+#include "common.h"
+#include "driver.h"
+#include "eloop.h"
+#include "driver_wext.h"
+#include "ieee802_11_defs.h"
+#include "wpa_common.h"
+#include "wpa_ctrl.h"
+#include "wpa_supplicant_i.h"
+#include "config_ssid.h"
+#include "wpa_debug.h"
+
+
+static int wpa_driver_wext_flush_pmkid(void *priv);
+static int wpa_driver_wext_get_range(void *priv);
+static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv);
+static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv);
+
+
+static int wpa_driver_wext_send_oper_ifla(struct wpa_driver_wext_data *drv,
+                      int linkmode, int operstate)
+{
+    struct {
+        struct nlmsghdr hdr;
+        struct ifinfomsg ifinfo;
+        char opts[16];
+    } req;
+    struct rtattr *rta;
+    static int nl_seq;
+    ssize_t ret;
+
+    os_memset(&req, 0, sizeof(req));
+
+    req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+    req.hdr.nlmsg_type = RTM_SETLINK;
+    req.hdr.nlmsg_flags = NLM_F_REQUEST;
+    req.hdr.nlmsg_seq = ++nl_seq;
+    req.hdr.nlmsg_pid = 0;
+
+    req.ifinfo.ifi_family = AF_UNSPEC;
+    req.ifinfo.ifi_type = 0;
+    req.ifinfo.ifi_index = drv->ifindex;
+    req.ifinfo.ifi_flags = 0;
+    req.ifinfo.ifi_change = 0;
+
+    if (linkmode != -1) {
+        rta = aliasing_hide_typecast(
+            ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)),
+            struct rtattr);
+        rta->rta_type = IFLA_LINKMODE;
+        rta->rta_len = RTA_LENGTH(sizeof(char));
+        *((char *) RTA_DATA(rta)) = linkmode;
+        req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) +
+            RTA_LENGTH(sizeof(char));
+    }
+    if (operstate != -1) {
+        rta = (struct rtattr *)
+            ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len));
+        rta->rta_type = IFLA_OPERSTATE;
+        rta->rta_len = RTA_LENGTH(sizeof(char));
+        *((char *) RTA_DATA(rta)) = operstate;
+        req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) +
+            RTA_LENGTH(sizeof(char));
+    }
+
+    wpa_printf(MSG_DEBUG, "WEXT: Operstate: linkmode=%d, operstate=%d",
+           linkmode, operstate);
+
+    ret = send(drv->ioctl_sock, &req, req.hdr.nlmsg_len, 0);
+    if (ret < 0) {
+        wpa_printf(MSG_DEBUG, "WEXT: Sending operstate IFLA failed: "
+               "%s (assume operstate is not supported)",
+               strerror(errno));
+    }
+
+    return ret < 0 ? -1 : 0;
+}
+
+
+static void
+wpa_driver_wext_event_wireless_custom(void *ctx, char *custom)
+{
+    union wpa_event_data data;
+
+    wpa_printf(MSG_MSGDUMP, "WEXT: Custom wireless event: '%s'",
+           custom);
+
+    os_memset(&data, 0, sizeof(data));
+    /* Host AP driver */
+    if (os_strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
+        data.michael_mic_failure.unicast =
+            os_strstr(custom, " unicast ") != NULL;
+        /* TODO: parse parameters(?) */
+        wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
+    } else if (os_strncmp(custom, "ASSOCINFO(ReqIEs=", 17) == 0) {
+        char *spos;
+        int bytes;
+
+        spos = custom + 17;
+
+        bytes = strspn(spos, "0123456789abcdefABCDEF");
+        if (!bytes || (bytes & 1)) {
+            return;
+        }
+        bytes /= 2;
+
+        data.assoc_info.req_ies = os_malloc(bytes);
+        if (data.assoc_info.req_ies == NULL) {
+            return;
+        }
+        data.assoc_info.req_ies_len = bytes;
+        hexstr2bin(spos, data.assoc_info.req_ies, bytes);
+
+        spos += bytes * 2;
+
+        data.assoc_info.resp_ies = NULL;
+        data.assoc_info.resp_ies_len = 0;
+
+        if (os_strncmp(spos, " RespIEs=", 9) == 0) {
+            spos += 9;
+
+            bytes = strspn(spos, "0123456789abcdefABCDEF");
+            if (!bytes || (bytes & 1)) {
+                goto done;
+            }
+            bytes /= 2;
+
+            data.assoc_info.resp_ies = os_malloc(bytes);
+            if (data.assoc_info.resp_ies == NULL) {
+                goto done;
+            }
+
+            data.assoc_info.resp_ies_len = bytes;
+            hexstr2bin(spos, data.assoc_info.resp_ies, bytes);
+        }
+
+        wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data);
+
+    done:
+        os_free(data.assoc_info.resp_ies);
+        os_free(data.assoc_info.req_ies);
+#ifdef CONFIG_PEERKEY
+    } else if (os_strncmp(custom, "STKSTART.request=", 17) == 0) {
+        if (hwaddr_aton(custom + 17, data.stkstart.peer)) {
+            wpa_printf(MSG_DEBUG, "WEXT: unrecognized "
+                   "STKSTART.request '%s'", custom + 17);
+            return;
+        }
+        wpa_supplicant_event(ctx, EVENT_STKSTART, &data);
+#endif /* CONFIG_PEERKEY */
+#ifdef ANDROID
+    } else if (os_strncmp(custom, "STOP", 4) == 0) {
+        wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
+    } else if (os_strncmp(custom, "START", 5) == 0) {
+        wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
+    } else if (os_strncmp(custom, "HANG", 4) == 0) {
+        wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
+#endif /* ANDROID */
+    }
+}
+
+
+static int wpa_driver_wext_event_wireless_michaelmicfailure(
+    void *ctx, const char *ev, size_t len)
+{
+    const struct iw_michaelmicfailure *mic;
+    union wpa_event_data data;
+
+    if (len < sizeof(*mic)) {
+        return -1;
+    }
+
+    mic = (const struct iw_michaelmicfailure *) ev;
+
+    wpa_printf(MSG_DEBUG, "Michael MIC failure wireless event: "
+           "flags=0x%x src_addr=" MACSTR, mic->flags,
+           MAC2STR(mic->src_addr.sa_data));
+
+    os_memset(&data, 0, sizeof(data));
+    data.michael_mic_failure.unicast = !(mic->flags & IW_MICFAILURE_GROUP);
+    wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
+
+    return 0;
+}
+
+
+static int wpa_driver_wext_event_wireless_pmkidcand(
+    struct wpa_driver_wext_data *drv, const char *ev, size_t len)
+{
+    const struct iw_pmkid_cand *cand;
+    union wpa_event_data data;
+    const u8 *addr;
+
+    if (len < sizeof(*cand)) {
+        return -1;
+    }
+
+    cand = (const struct iw_pmkid_cand *) ev;
+    addr = (const u8 *) cand->bssid.sa_data;
+
+    wpa_printf(MSG_DEBUG, "PMKID candidate wireless event: "
+           "flags=0x%x index=%d bssid=" MACSTR, cand->flags,
+           cand->index, MAC2STR(addr));
+
+    os_memset(&data, 0, sizeof(data));
+    os_memcpy(data.pmkid_candidate.bssid, addr, ETH_ALEN);
+    data.pmkid_candidate.index = cand->index;
+    data.pmkid_candidate.preauth = cand->flags & IW_PMKID_CAND_PREAUTH;
+    wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data);
+
+    return 0;
+}
+
+
+static int wpa_driver_wext_event_wireless_assocreqie(
+    struct wpa_driver_wext_data *drv, const char *ev, int len)
+{
+    if (len < 0) {
+        return -1;
+    }
+
+    wpa_hexdump(MSG_DEBUG, "AssocReq IE wireless event", (const u8 *) ev,
+            len);
+    os_free(drv->assoc_req_ies);
+    drv->assoc_req_ies = os_malloc(len);
+    if (drv->assoc_req_ies == NULL) {
+        drv->assoc_req_ies_len = 0;
+        return -1;
+    }
+    os_memcpy(drv->assoc_req_ies, ev, len);
+    drv->assoc_req_ies_len = len;
+
+    return 0;
+}
+
+
+static int wpa_driver_wext_event_wireless_assocrespie(
+    struct wpa_driver_wext_data *drv, const char *ev, int len)
+{
+    if (len < 0) {
+        return -1;
+    }
+
+    wpa_hexdump(MSG_DEBUG, "AssocResp IE wireless event", (const u8 *) ev,
+            len);
+    os_free(drv->assoc_resp_ies);
+    drv->assoc_resp_ies = os_malloc(len);
+    if (drv->assoc_resp_ies == NULL) {
+        drv->assoc_resp_ies_len = 0;
+        return -1;
+    }
+    os_memcpy(drv->assoc_resp_ies, ev, len);
+    drv->assoc_resp_ies_len = len;
+
+    return 0;
+}
+
+
+static void wpa_driver_wext_event_assoc_ies(struct wpa_driver_wext_data *drv)
+{
+    union wpa_event_data data;
+
+    if (drv->assoc_req_ies == NULL && drv->assoc_resp_ies == NULL) {
+        return;
+    }
+
+    os_memset(&data, 0, sizeof(data));
+    if (drv->assoc_req_ies) {
+        data.assoc_info.req_ies = drv->assoc_req_ies;
+        drv->assoc_req_ies = NULL;
+        data.assoc_info.req_ies_len = drv->assoc_req_ies_len;
+    }
+    if (drv->assoc_resp_ies) {
+        data.assoc_info.resp_ies = drv->assoc_resp_ies;
+        drv->assoc_resp_ies = NULL;
+        data.assoc_info.resp_ies_len = drv->assoc_resp_ies_len;
+    }
+
+    wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data);
+
+    os_free(data.assoc_info.req_ies);
+    os_free(data.assoc_info.resp_ies);
+}
+
+
+static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv,
+                       void *ctx, char *data, int len)
+{
+    struct iw_event iwe_buf, *iwe = &iwe_buf;
+    char *pos, *end, *custom, *buf;
+
+    pos = data;
+    end = data + len;
+
+    while (pos + IW_EV_LCP_LEN <= end) {
+        /* Event data may be unaligned, so make a local, aligned copy
+         * before processing. */
+        os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
+        wpa_printf(MSG_DEBUG, "Wireless event: cmd=0x%x len=%d",
+               iwe->cmd, iwe->len);
+        if (iwe->len <= IW_EV_LCP_LEN) {
+            return;
+        }
+
+        custom = pos + IW_EV_POINT_LEN;
+        if (drv->we_version_compiled > 18 &&
+            (iwe->cmd == IWEVMICHAELMICFAILURE ||
+             iwe->cmd == IWEVCUSTOM ||
+             iwe->cmd == IWEVASSOCREQIE ||
+             iwe->cmd == IWEVASSOCRESPIE ||
+             iwe->cmd == IWEVPMKIDCAND)) {
+            /* WE-19 removed the pointer from struct iw_point */
+            char *dpos = (char *) &iwe_buf.u.data.length;
+            int dlen = dpos - (char *) &iwe_buf;
+            os_memcpy(dpos, pos + IW_EV_LCP_LEN,
+                  sizeof(struct iw_event) - dlen);
+        } else {
+            os_memcpy(&iwe_buf, pos, sizeof(struct iw_event));
+            custom += IW_EV_POINT_OFF;
+        }
+
+        switch (iwe->cmd) {
+        case SIOCGIWAP:
+            wpa_printf(MSG_DEBUG, "Wireless event: new AP: "
+                   MACSTR,
+                   MAC2STR((u8 *) iwe->u.ap_addr.sa_data));
+            if (is_zero_ether_addr(
+                    (const u8 *) iwe->u.ap_addr.sa_data) ||
+                os_memcmp(iwe->u.ap_addr.sa_data,
+                      "\x44\x44\x44\x44\x44\x44", ETH_ALEN) ==
+                0) {
+                os_free(drv->assoc_req_ies);
+                drv->assoc_req_ies = NULL;
+                os_free(drv->assoc_resp_ies);
+                drv->assoc_resp_ies = NULL;
+#ifdef ANDROID
+                if (!drv->skip_disconnect) {
+                    drv->skip_disconnect = 1;
+#endif
+                    wpa_supplicant_event(ctx, EVENT_DISASSOC,
+                             NULL);
+#ifdef ANDROID
+                    wpa_driver_wext_disconnect(drv);
+                }
+#endif
+
+            } else {
+#ifdef ANDROID
+                drv->skip_disconnect = 0;
+#endif
+                wpa_driver_wext_event_assoc_ies(drv);
+                wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
+            }
+            break;
+        case IWEVMICHAELMICFAILURE:
+            if (custom + iwe->u.data.length > end) {
+                wpa_printf(MSG_DEBUG, "WEXT: Invalid "
+                       "IWEVMICHAELMICFAILURE length");
+                return;
+            }
+            wpa_driver_wext_event_wireless_michaelmicfailure(
+                ctx, custom, iwe->u.data.length);
+            break;
+        case IWEVCUSTOM:
+            if (custom + iwe->u.data.length > end) {
+                wpa_printf(MSG_DEBUG, "WEXT: Invalid "
+                       "IWEVCUSTOM length");
+                return;
+            }
+            buf = os_malloc(iwe->u.data.length + 1);
+            if (buf == NULL) {
+                return;
+            }
+            os_memcpy(buf, custom, iwe->u.data.length);
+            buf[iwe->u.data.length] = '\0';
+            wpa_driver_wext_event_wireless_custom(ctx, buf);
+            os_free(buf);
+            break;
+        case SIOCGIWSCAN:
+            drv->scan_complete_events = 1;
+            eloop_cancel_timeout(wpa_driver_wext_scan_timeout,
+                         drv, ctx);
+            wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);
+            break;
+        case IWEVASSOCREQIE:
+            if (custom + iwe->u.data.length > end) {
+                wpa_printf(MSG_DEBUG, "WEXT: Invalid "
+                       "IWEVASSOCREQIE length");
+                return;
+            }
+            wpa_driver_wext_event_wireless_assocreqie(
+                drv, custom, iwe->u.data.length);
+            break;
+        case IWEVASSOCRESPIE:
+            if (custom + iwe->u.data.length > end) {
+                wpa_printf(MSG_DEBUG, "WEXT: Invalid "
+                       "IWEVASSOCRESPIE length");
+                return;
+            }
+            wpa_driver_wext_event_wireless_assocrespie(
+                drv, custom, iwe->u.data.length);
+            break;
+        case IWEVPMKIDCAND:
+            if (custom + iwe->u.data.length > end) {
+                wpa_printf(MSG_DEBUG, "WEXT: Invalid "
+                       "IWEVPMKIDCAND length");
+                return;
+            }
+            wpa_driver_wext_event_wireless_pmkidcand(
+                drv, custom, iwe->u.data.length);
+            break;
+        }
+
+        pos += iwe->len;
+    }
+}
+
+
+static void wpa_driver_wext_event_link(struct wpa_driver_wext_data *drv,
+                       void *ctx, char *buf, size_t len,
+                       int del)
+{
+    union wpa_event_data event;
+
+    os_memset(&event, 0, sizeof(event));
+    if (len > sizeof(event.interface_status.ifname)) {
+        len = sizeof(event.interface_status.ifname) - 1;
+    }
+    os_memcpy(event.interface_status.ifname, buf, len);
+    event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED :
+        EVENT_INTERFACE_ADDED;
+
+    wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s",
+           del ? "DEL" : "NEW",
+           event.interface_status.ifname,
+           del ? "removed" : "added");
+
+    if (os_strcmp(drv->ifname, event.interface_status.ifname) == 0) {
+        if (del) {
+            drv->if_removed = 1;
+        } else {
+            drv->if_removed = 0;
+        }
+    }
+
+    wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
+}
+
+
+static int wpa_driver_wext_own_ifname(struct wpa_driver_wext_data *drv,
+                      struct nlmsghdr *h)
+{
+    struct ifinfomsg *ifi;
+    int attrlen, nlmsg_len, rta_len;
+    struct rtattr *attr;
+
+    ifi = NLMSG_DATA(h);
+
+    nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
+
+    attrlen = h->nlmsg_len - nlmsg_len;
+    if (attrlen < 0) {
+        return 0;
+    }
+
+    attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
+
+    rta_len = RTA_ALIGN(sizeof(struct rtattr));
+    while (RTA_OK(attr, attrlen)) {
+        if (attr->rta_type == IFLA_IFNAME) {
+            if (os_strcmp(((char *) attr) + rta_len, drv->ifname)
+                == 0) {
+                return 1;
+            } else {
+                break;
+            }
+        }
+        attr = RTA_NEXT(attr, attrlen);
+    }
+
+    return 0;
+}
+
+
+static int wpa_driver_wext_own_ifindex(struct wpa_driver_wext_data *drv,
+                       int ifindex, struct nlmsghdr *h)
+{
+    if (drv->ifindex == ifindex || drv->ifindex2 == ifindex) {
+        return 1;
+    }
+
+    if (drv->if_removed && wpa_driver_wext_own_ifname(drv, h)) {
+        drv->ifindex = if_nametoindex(drv->ifname);
+        wpa_printf(MSG_DEBUG, "WEXT: Update ifindex for a removed "
+               "interface");
+        wpa_driver_wext_finish_drv_init(drv);
+        return 1;
+    }
+
+    return 0;
+}
+
+
+static void wpa_driver_wext_event_rtm_newlink(struct wpa_driver_wext_data *drv,
+                          void *ctx, struct nlmsghdr *h,
+                          size_t len)
+{
+    struct ifinfomsg *ifi;
+    int attrlen, nlmsg_len, rta_len;
+    struct rtattr * attr;
+
+    if (len < sizeof(*ifi)) {
+        return;
+    }
+
+    ifi = NLMSG_DATA(h);
+
+    if (!wpa_driver_wext_own_ifindex(drv, ifi->ifi_index, h)) {
+        wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
+               ifi->ifi_index);
+        return;
+    }
+
+    wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x "
+           "(%s%s%s%s)",
+           drv->operstate, ifi->ifi_flags,
+           (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
+           (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
+           (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
+           (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
+    /*
+     * Some drivers send the association event before the operup event--in
+     * this case, lifting operstate in wpa_driver_wext_set_operstate()
+     * fails. This will hit us when wpa_supplicant does not need to do
+     * IEEE 802.1X authentication
+     */
+    if (drv->operstate == 1 &&
+        (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
+        !(ifi->ifi_flags & IFF_RUNNING)) {
+        wpa_driver_wext_send_oper_ifla(drv, -1, IF_OPER_UP);
+    }
+
+    nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
+
+    attrlen = h->nlmsg_len - nlmsg_len;
+    if (attrlen < 0) {
+        return;
+    }
+
+    attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
+
+    rta_len = RTA_ALIGN(sizeof(struct rtattr));
+    while (RTA_OK(attr, attrlen)) {
+        if (attr->rta_type == IFLA_WIRELESS) {
+            wpa_driver_wext_event_wireless(
+                drv, ctx, ((char *) attr) + rta_len,
+                attr->rta_len - rta_len);
+        } else if (attr->rta_type == IFLA_IFNAME) {
+            wpa_driver_wext_event_link(drv, ctx,
+                           ((char *) attr) + rta_len,
+                           attr->rta_len - rta_len, 0);
+        }
+        attr = RTA_NEXT(attr, attrlen);
+    }
+}
+
+
+static void wpa_driver_wext_event_rtm_dellink(struct wpa_driver_wext_data *drv,
+                          void *ctx, struct nlmsghdr *h,
+                          size_t len)
+{
+    struct ifinfomsg *ifi;
+    int attrlen, nlmsg_len, rta_len;
+    struct rtattr * attr;
+
+    if (len < sizeof(*ifi)) {
+        return;
+    }
+
+    ifi = NLMSG_DATA(h);
+
+    nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
+
+    attrlen = h->nlmsg_len - nlmsg_len;
+    if (attrlen < 0) {
+        return;
+    }
+
+    attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
+
+    rta_len = RTA_ALIGN(sizeof(struct rtattr));
+    while (RTA_OK(attr, attrlen)) {
+        if (attr->rta_type == IFLA_IFNAME) {
+            wpa_driver_wext_event_link(drv,  ctx,
+                           ((char *) attr) + rta_len,
+                           attr->rta_len - rta_len, 1);
+        }
+        attr = RTA_NEXT(attr, attrlen);
+    }
+}
+
+
+static void wpa_driver_wext_event_receive(int sock, void *eloop_ctx,
+                      void *sock_ctx)
+{
+    char buf[8192];
+    int left;
+    struct sockaddr_nl from;
+    socklen_t fromlen;
+    struct nlmsghdr *h;
+    int max_events = 10;
+
+try_again:
+    fromlen = sizeof(from);
+    left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT,
+            (struct sockaddr *) &from, &fromlen);
+    if (left < 0) {
+        if (errno != EINTR && errno != EAGAIN) {
+            wpa_printf(MSG_ERROR, "%s: recvfrom(netlink): %d", __func__, errno);        }
+        return;
+    }
+
+    h = (struct nlmsghdr *) buf;
+    while (left >= (int) sizeof(*h)) {
+        int len, plen;
+
+        len = h->nlmsg_len;
+        plen = len - sizeof(*h);
+        if (len > left || plen < 0) {
+            wpa_printf(MSG_DEBUG, "Malformed netlink message: "
+                   "len=%d left=%d plen=%d",
+                   len, left, plen);
+            break;
+        }
+
+        switch (h->nlmsg_type) {
+        case RTM_NEWLINK:
+            wpa_driver_wext_event_rtm_newlink(eloop_ctx, sock_ctx,
+                              h, plen);
+            break;
+        case RTM_DELLINK:
+            wpa_driver_wext_event_rtm_dellink(eloop_ctx, sock_ctx,
+                              h, plen);
+            break;
+        }
+
+        len = NLMSG_ALIGN(len);
+        left -= len;
+        h = (struct nlmsghdr *) ((char *) h + len);
+    }
+
+    if (left > 0) {
+        wpa_printf(MSG_DEBUG, "%d extra bytes in the end of netlink "
+               "message", left);
+    }
+
+    if (--max_events > 0) {
+        /*
+         * Try to receive all events in one eloop call in order to
+         * limit race condition on cases where AssocInfo event, Assoc
+         * event, and EAPOL frames are received more or less at the
+         * same time. We want to process the event messages first
+         * before starting EAPOL processing.
+         */
+        goto try_again;
+    }
+}
+
+
+static int wpa_driver_wext_get_ifflags_ifname(struct wpa_driver_wext_data *drv,
+                          const char *ifname, int *flags)
+{
+    struct ifreq ifr;
+
+    os_memset(&ifr, 0, sizeof(ifr));
+    os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
+    if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
+        wpa_printf(MSG_ERROR, "ioctl[SIOCGIFFLAGS]");
+        return -1;
+    }
+    *flags = ifr.ifr_flags & 0xffff;
+    return 0;
+}
+
+
+static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
+{
+    int flags;
+
+    if (wpa_driver_wext_get_ifflags(drv, &flags) != 0) {
+        printf("Could not get interface '%s' flags\n", drv->ifname);
+    } else if (!(flags & IFF_UP)) {
+        if (wpa_driver_wext_set_ifflags(drv, flags | IFF_UP) != 0) {
+            printf("Could not set interface '%s' UP\n",
+                   drv->ifname);
+        } else {
+            /*
+             * Wait some time to allow driver to initialize before
+             * starting configuring the driver. This seems to be
+             * needed at least some drivers that load firmware etc.
+             * when the interface is set up.
+             */
+            wpa_printf(MSG_DEBUG, "Interface %s set UP - waiting "
+                   "a second for the driver to complete "
+                   "initialization", drv->ifname);
+            sleep(1);
+        }
+    }
+
+    /*
+     * Make sure that the driver does not have any obsolete PMKID entries.
+     */
+    wpa_driver_wext_flush_pmkid(drv);
+
+    if (wpa_driver_wext_set_mode(drv, 0) < 0) {
+        printf("Could not configure driver to use managed mode\n");
+    }
+
+    wpa_driver_wext_get_range(drv);
+
+    /*
+     * Unlock the driver's BSSID and force to a random SSID to clear any
+     * previous association the driver might have when the supplicant
+     * starts up.
+     */
+    wpa_driver_wext_disconnect(drv);
+
+    drv->ifindex = if_nametoindex(drv->ifname);
+
+    if (os_strncmp(drv->ifname, "wlan", 4) == 0) {
+        /*
+         * Host AP driver may use both wlan# and wifi# interface in
+         * wireless events. Since some of the versions included WE-18
+         * support, let's add the alternative ifindex also from
+         * driver_wext.c for the time being. This may be removed at
+         * some point once it is believed that old versions of the
+         * driver are not in use anymore.
+         */
+        char ifname2[IFNAMSIZ + 1];
+        os_strlcpy(ifname2, drv->ifname, sizeof(ifname2));
+        os_memcpy(ifname2, "wifi", 4);
+        wpa_driver_wext_alternative_ifindex(drv, ifname2);
+    }
+
+    wpa_driver_wext_send_oper_ifla(drv, 1, IF_OPER_DORMANT);
+}
+
+
+/**
+ * wpa_driver_wext_set_scan_timeout - Set scan timeout to report scan completion
+ * @priv:  Pointer to private wext data from wpa_driver_wext_init()
+ *
+ * This function can be used to set registered timeout when starting a scan to
+ * generate a scan completed event if the driver does not report this.
+ */
+static void wpa_driver_wext_set_scan_timeout(void *priv)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    int timeout = 10; /* In case scan A and B bands it can be long */
+
+    /* Not all drivers generate "scan completed" wireless event, so try to
+     * read results after a timeout. */
+    if (drv->scan_complete_events) {
+        /*
+         * The driver seems to deliver SIOCGIWSCAN events to notify
+         * when scan is complete, so use longer timeout to avoid race
+         * conditions with scanning and following association request.
+         */
+        timeout = 30;
+    }
+    wpa_printf(MSG_DEBUG, "Scan requested - scan timeout %d seconds",
+           timeout);
+    eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx);
+    eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout, drv,
+                   drv->ctx);
+}
+
+
+static u8 * wpa_driver_wext_giwscan(struct wpa_driver_wext_data *drv,
+                    size_t *len)
+{
+    struct iwreq iwr;
+    u8 *res_buf;
+    size_t res_buf_len;
+
+    res_buf_len = IW_SCAN_MAX_DATA;
+    for (;;) {
+        res_buf = os_malloc(res_buf_len);
+        if (res_buf == NULL) {
+            return NULL;
+        }
+        os_memset(&iwr, 0, sizeof(iwr));
+        os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+        iwr.u.data.pointer = res_buf;
+        iwr.u.data.length = res_buf_len;
+
+        if (ioctl(drv->ioctl_sock, SIOCGIWSCAN, &iwr) == 0) {
+            break;
+        }
+
+        if (errno == E2BIG && res_buf_len < 65535) {
+            os_free(res_buf);
+            res_buf = NULL;
+            res_buf_len *= 2;
+            if (res_buf_len > 65535) {
+                res_buf_len = 65535; /* 16-bit length field */
+            }
+            wpa_printf(MSG_DEBUG, "Scan results did not fit - "
+                   "trying larger buffer (%lu bytes)",
+                   (unsigned long) res_buf_len);
+        } else {
+            wpa_printf(MSG_ERROR, "ioctl[SIOCGIWSCAN]: %d", errno);
+            os_free(res_buf);
+            return NULL;
+        }
+    }
+
+    if (iwr.u.data.length > res_buf_len) {
+        os_free(res_buf);
+        return NULL;
+    }
+    *len = iwr.u.data.length;
+
+    return res_buf;
+}
+
+
+/*
+ * Data structure for collecting WEXT scan results. This is needed to allow
+ * the various methods of reporting IEs to be combined into a single IE buffer.
+ */
+struct wext_scan_data {
+    struct wpa_scan_res res;
+    u8 *ie;
+    size_t ie_len;
+    u8 ssid[32];
+    size_t ssid_len;
+    int maxrate;
+};
+
+
+static void wext_get_scan_mode(struct iw_event *iwe,
+                   struct wext_scan_data *res)
+{
+    if (iwe->u.mode == IW_MODE_ADHOC) {
+        res->res.caps |= IEEE80211_CAP_IBSS;
+    } else if (iwe->u.mode == IW_MODE_MASTER ||
+             iwe->u.mode == IW_MODE_INFRA) {
+        res->res.caps |= IEEE80211_CAP_ESS;
+    }
+}
+
+
+static void wext_get_scan_ssid(struct iw_event *iwe,
+                   struct wext_scan_data *res, char *custom,
+                   char *end)
+{
+    int ssid_len = iwe->u.essid.length;
+    if (custom + ssid_len > end) {
+        return;
+    }
+    if (iwe->u.essid.flags &&
+        ssid_len > 0 &&
+        ssid_len <= IW_ESSID_MAX_SIZE) {
+        os_memcpy(res->ssid, custom, ssid_len);
+        res->ssid_len = ssid_len;
+    }
+}
+
+
+static void wext_get_scan_freq(struct iw_event *iwe,
+                   struct wext_scan_data *res)
+{
+    int divi = 1000000, i;
+
+    if (iwe->u.freq.e == 0) {
+        /*
+         * Some drivers do not report frequency, but a channel.
+         * Try to map this to frequency by assuming they are using
+         * IEEE 802.11b/g.  But don't overwrite a previously parsed
+         * frequency if the driver sends both frequency and channel,
+         * since the driver may be sending an A-band channel that we
+         * don't handle here.
+         */
+
+        if (res->res.freq) {
+            return;
+        }
+
+        if (iwe->u.freq.m >= 1 && iwe->u.freq.m <= 13) {
+            res->res.freq = 2407 + 5 * iwe->u.freq.m;
+            return;
+        } else if (iwe->u.freq.m == 14) {
+            res->res.freq = 2484;
+            return;
+        }
+    }
+
+    if (iwe->u.freq.e > 6) {
+        wpa_printf(MSG_DEBUG, "Invalid freq in scan results (BSSID="
+               MACSTR " m=%d e=%d)",
+               MAC2STR(res->res.bssid), iwe->u.freq.m,
+               iwe->u.freq.e);
+        return;
+    }
+
+    for (i = 0; i < iwe->u.freq.e; i++)
+        divi /= 10;
+    res->res.freq = iwe->u.freq.m / divi;
+}
+
+
+static void wext_get_scan_qual(struct iw_event *iwe,
+                   struct wext_scan_data *res)
+{
+    res->res.qual = iwe->u.qual.qual;
+    res->res.noise = iwe->u.qual.noise;
+    res->res.level = iwe->u.qual.level;
+}
+
+
+static void wext_get_scan_encode(struct iw_event *iwe,
+                 struct wext_scan_data *res)
+{
+    if (!(iwe->u.data.flags & IW_ENCODE_DISABLED)) {
+        res->res.caps |= IEEE80211_CAP_PRIVACY;
+    }
+}
+
+
+static void wext_get_scan_rate(struct iw_event *iwe,
+                   struct wext_scan_data *res, char *pos,
+                   char *end)
+{
+    int maxrate;
+    char *custom = pos + IW_EV_LCP_LEN;
+    struct iw_param p;
+    size_t clen;
+
+    clen = iwe->len;
+    if (custom + clen > end) {
+        return;
+    }
+    maxrate = 0;
+    while (((ssize_t) clen) >= (ssize_t) sizeof(struct iw_param)) {
+        /* Note: may be misaligned, make a local, aligned copy */
+        os_memcpy(&p, custom, sizeof(struct iw_param));
+        if (p.value > maxrate) {
+            maxrate = p.value;
+        }
+        clen -= sizeof(struct iw_param);
+        custom += sizeof(struct iw_param);
+    }
+
+    /* Convert the maxrate from WE-style (b/s units) to
+     * 802.11 rates (500000 b/s units).
+     */
+    res->maxrate = maxrate / 500000;
+}
+
+
+static void wext_get_scan_iwevgenie(struct iw_event *iwe,
+                    struct wext_scan_data *res, char *custom,
+                    char *end)
+{
+    char *genie, *gpos, *gend;
+    u8 *tmp;
+
+    if (iwe->u.data.length == 0) {
+        return;
+    }
+
+    gpos = genie = custom;
+    gend = genie + iwe->u.data.length;
+    if (gend > end) {
+        wpa_printf(MSG_INFO, "IWEVGENIE overflow");
+        return;
+    }
+
+    tmp = os_realloc(res->ie, res->ie_len + gend - gpos);
+    if (tmp == NULL) {
+        return;
+    }
+    os_memcpy(tmp + res->ie_len, gpos, gend - gpos);
+    res->ie = tmp;
+    res->ie_len += gend - gpos;
+}
+
+
+static void wext_get_scan_custom(struct iw_event *iwe,
+                 struct wext_scan_data *res, char *custom,
+                 char *end)
+{
+    size_t clen;
+    u8 *tmp;
+
+    clen = iwe->u.data.length;
+    if (custom + clen > end) {
+        return;
+    }
+
+    if (clen > 7 && os_strncmp(custom, "wpa_ie=", 7) == 0) {
+        char *spos;
+        int bytes;
+        spos = custom + 7;
+        bytes = custom + clen - spos;
+        if (bytes & 1 || bytes == 0) {
+            return;
+        }
+        bytes /= 2;
+        tmp = os_realloc(res->ie, res->ie_len + bytes);
+        if (tmp == NULL) {
+            return;
+        }
+        hexstr2bin(spos, tmp + res->ie_len, bytes);
+        res->ie = tmp;
+        res->ie_len += bytes;
+    } else if (clen > 7 && os_strncmp(custom, "rsn_ie=", 7) == 0) {
+        char *spos;
+        int bytes;
+        spos = custom + 7;
+        bytes = custom + clen - spos;
+        if (bytes & 1 || bytes == 0) {
+            return;
+        }
+        bytes /= 2;
+        tmp = os_realloc(res->ie, res->ie_len + bytes);
+        if (tmp == NULL) {
+            return;
+        }
+        hexstr2bin(spos, tmp + res->ie_len, bytes);
+        res->ie = tmp;
+        res->ie_len += bytes;
+    } else if (clen > 4 && os_strncmp(custom, "tsf=", 4) == 0) {
+        char *spos;
+        int bytes;
+        u8 bin[8];
+        spos = custom + 4;
+        bytes = custom + clen - spos;
+        if (bytes != 16) {
+            wpa_printf(MSG_INFO, "Invalid TSF length (%d)", bytes);
+            return;
+        }
+        bytes /= 2;
+        hexstr2bin(spos, bin, bytes);
+        res->res.tsf += WPA_GET_BE64(bin);
+    }
+}
+
+
+static int wext_19_iw_point(struct wpa_driver_wext_data *drv, u16 cmd)
+{
+    return drv->we_version_compiled > 18 &&
+        (cmd == SIOCGIWESSID || cmd == SIOCGIWENCODE ||
+         cmd == IWEVGENIE || cmd == IWEVCUSTOM);
+}
+
+
+static void wpa_driver_wext_add_scan_entry(struct wpa_scan_results *res,
+                       struct wext_scan_data *data)
+{
+    struct wpa_scan_res **tmp;
+    struct wpa_scan_res *r;
+    size_t extra_len;
+    u8 *pos, *end, *ssid_ie = NULL, *rate_ie = NULL;
+
+    /* Figure out whether we need to fake any IEs */
+    pos = data->ie;
+    end = pos + data->ie_len;
+    while (pos && pos + 1 < end) {
+        if (pos + 2 + pos[1] > end) {
+            break;
+        }
+        if (pos[0] == WLAN_EID_SSID) {
+            ssid_ie = pos;
+        } else if (pos[0] == WLAN_EID_SUPP_RATES) {
+            rate_ie = pos;
+        } else if (pos[0] == WLAN_EID_EXT_SUPP_RATES) {
+            rate_ie = pos;
+        }
+        pos += 2 + pos[1];
+    }
+
+    extra_len = 0;
+    if (ssid_ie == NULL) {
+        extra_len += 2 + data->ssid_len;
+    }
+    if (rate_ie == NULL && data->maxrate) {
+        extra_len += 3;
+    }
+
+    r = os_zalloc(sizeof(*r) + extra_len + data->ie_len);
+    if (r == NULL) {
+        return;
+    }
+    os_memcpy(r, &data->res, sizeof(*r));
+    r->ie_len = extra_len + data->ie_len;
+    pos = (u8 *) (r + 1);
+    if (ssid_ie == NULL) {
+        /*
+         * Generate a fake SSID IE since the driver did not report
+         * a full IE list.
+         */
+        *pos++ = WLAN_EID_SSID;
+        *pos++ = data->ssid_len;
+        os_memcpy(pos, data->ssid, data->ssid_len);
+        pos += data->ssid_len;
+    }
+    if (rate_ie == NULL && data->maxrate) {
+        /*
+         * Generate a fake Supported Rates IE since the driver did not
+         * report a full IE list.
+         */
+        *pos++ = WLAN_EID_SUPP_RATES;
+        *pos++ = 1;
+        *pos++ = data->maxrate;
+    }
+    if (data->ie) {
+        os_memcpy(pos, data->ie, data->ie_len);
+    }
+
+    tmp = os_realloc(res->res,
+             (res->num + 1) * sizeof(struct wpa_scan_res *));
+    if (tmp == NULL) {
+        os_free(r);
+        return;
+    }
+    tmp[res->num++] = r;
+    res->res = tmp;
+}
+
+
+
+static int wpa_driver_wext_get_range(void *priv)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    struct iw_range *range;
+    struct iwreq iwr;
+    int minlen;
+    size_t buflen;
+
+    /*
+     * Use larger buffer than struct iw_range in order to allow the
+     * structure to grow in the future.
+     */
+    buflen = sizeof(struct iw_range) + 500;
+    range = os_zalloc(buflen);
+    if (range == NULL) {
+        return -1;
+    }
+
+    os_memset(&iwr, 0, sizeof(iwr));
+    os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+    iwr.u.data.pointer = (caddr_t) range;
+    iwr.u.data.length = buflen;
+
+    minlen = ((char *) &range->enc_capa) - (char *) range +
+        sizeof(range->enc_capa);
+
+    if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
+        wpa_printf(MSG_ERROR, "ioctl[SIOCGIRANGE]");
+        os_free(range);
+        return -1;
+    } else if (iwr.u.data.length >= minlen &&
+           range->we_version_compiled >= 18) {
+        wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "
+               "WE(source)=%d enc_capa=0x%x",
+               range->we_version_compiled,
+               range->we_version_source,
+               range->enc_capa);
+        drv->has_capability = 1;
+        drv->we_version_compiled = range->we_version_compiled;
+        if (range->enc_capa & IW_ENC_CAPA_WPA) {
+            drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA |
+                WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK;
+        }
+        if (range->enc_capa & IW_ENC_CAPA_WPA2) {
+            drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
+                WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
+        }
+        drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 |
+            WPA_DRIVER_CAPA_ENC_WEP104;
+        if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP) {
+            drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP;
+        }
+        if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP) {
+            drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
+        }
+        if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE) {
+            drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
+        }
+        drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
+            WPA_DRIVER_AUTH_SHARED |
+            WPA_DRIVER_AUTH_LEAP;
+
+        wpa_printf(MSG_DEBUG, "  capabilities: key_mgmt 0x%x enc 0x%x "
+               "flags 0x%x",
+               drv->capa.key_mgmt, drv->capa.enc, drv->capa.flags);
+    } else {
+        wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: too old (short) data - "
+               "assuming WPA is not supported");
+    }
+
+    os_free(range);
+    return 0;
+}
+
+
+static int wpa_driver_wext_set_wpa(void *priv, int enabled)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+
+    return wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED,
+                          enabled);
+}
+
+
+static int wpa_driver_wext_set_psk(struct wpa_driver_wext_data *drv,
+                   const u8 *psk)
+{
+    struct iw_encode_ext *ext;
+    struct iwreq iwr;
+    int ret;
+
+    wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+
+    if (!(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) {
+        return 0;
+    }
+
+    if (!psk) {
+        return 0;
+    }
+
+    os_memset(&iwr, 0, sizeof(iwr));
+    os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+
+    ext = os_zalloc(sizeof(*ext) + PMK_LEN);
+    if (ext == NULL) {
+        return -1;
+    }
+
+    iwr.u.encoding.pointer = (caddr_t) ext;
+    iwr.u.encoding.length = sizeof(*ext) + PMK_LEN;
+    ext->key_len = PMK_LEN;
+    os_memcpy(&ext->key, psk, ext->key_len);
+    ext->alg = IW_ENCODE_ALG_PMK;
+
+    ret = ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr);
+    if (ret < 0) {
+        wpa_printf(MSG_ERROR, "ioctl[SIOCSIWENCODEEXT] PMK");
+    }
+    os_free(ext);
+
+    return ret;
+}
+
+
+static int wpa_driver_wext_set_key_ext(void *priv, wpa_alg alg,
+                       const u8 *addr, int key_idx,
+                       int set_tx, const u8 *seq,
+                       size_t seq_len,
+                       const u8 *key, size_t key_len)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    struct iwreq iwr;
+    int ret = 0;
+    struct iw_encode_ext *ext;
+
+    if (seq_len > IW_ENCODE_SEQ_MAX_SIZE) {
+        wpa_printf(MSG_DEBUG, "%s: Invalid seq_len %lu",
+               __FUNCTION__, (unsigned long) seq_len);
+        return -1;
+    }
+
+    ext = os_zalloc(sizeof(*ext) + key_len);
+    if (ext == NULL) {
+        return -1;
+    }
+    os_memset(&iwr, 0, sizeof(iwr));
+    os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+    iwr.u.encoding.flags = key_idx + 1;
+    iwr.u.encoding.flags |= IW_ENCODE_TEMP;
+    if (alg == WPA_ALG_NONE) {
+        iwr.u.encoding.flags |= IW_ENCODE_DISABLED;
+    }
+    iwr.u.encoding.pointer = (caddr_t) ext;
+    iwr.u.encoding.length = sizeof(*ext) + key_len;
+
+    if (addr == NULL ||
+        os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0) {
+        ext->ext_flags |= IW_ENCODE_EXT_GROUP_KEY;
+    }
+    if (set_tx) {
+        ext->ext_flags |= IW_ENCODE_EXT_SET_TX_KEY;
+    }
+
+    ext->addr.sa_family = ARPHRD_ETHER;
+    if (addr) {
+        os_memcpy(ext->addr.sa_data, addr, ETH_ALEN);
+    } else {
+        os_memset(ext->addr.sa_data, 0xff, ETH_ALEN);
+    }
+    if (key && key_len) {
+        os_memcpy(ext + 1, key, key_len);
+        ext->key_len = key_len;
+    }
+    switch (alg) {
+    case WPA_ALG_NONE:
+        ext->alg = IW_ENCODE_ALG_NONE;
+        break;
+    case WPA_ALG_WEP:
+        ext->alg = IW_ENCODE_ALG_WEP;
+        break;
+    case WPA_ALG_TKIP:
+        ext->alg = IW_ENCODE_ALG_TKIP;
+        break;
+    case WPA_ALG_CCMP:
+        ext->alg = IW_ENCODE_ALG_CCMP;
+        break;
+    case WPA_ALG_PMK:
+        ext->alg = IW_ENCODE_ALG_PMK;
+        break;
+#ifdef CONFIG_IEEE80211W
+    case WPA_ALG_IGTK:
+        ext->alg = IW_ENCODE_ALG_AES_CMAC;
+        break;
+#endif /* CONFIG_IEEE80211W */
+    default:
+        wpa_printf(MSG_DEBUG, "%s: Unknown algorithm %d",
+               __FUNCTION__, alg);
+        os_free(ext);
+        return -1;
+    }
+
+    if (seq && seq_len) {
+        ext->ext_flags |= IW_ENCODE_EXT_RX_SEQ_VALID;
+        os_memcpy(ext->rx_seq, seq, seq_len);
+    }
+
+    if (ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr) < 0) {
+        ret = errno == EOPNOTSUPP ? -2 : -1;
+        if (errno == ENODEV) {
+            /*
+             * ndiswrapper seems to be returning incorrect error
+             * code.. */
+            ret = -2;
+        }
+
+        wpa_printf(MSG_ERROR, "ioctl[SIOCSIWENCODEEXT]");
+    }
+
+    os_free(ext);
+    return ret;
+}
+
+
+static int wpa_driver_wext_set_countermeasures(void *priv,
+                           int enabled)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+    return wpa_driver_wext_set_auth_param(drv,
+                          IW_AUTH_TKIP_COUNTERMEASURES,
+                          enabled);
+}
+
+
+static int wpa_driver_wext_set_drop_unencrypted(void *priv,
+                        int enabled)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+    drv->use_crypt = enabled;
+    return wpa_driver_wext_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED,
+                          enabled);
+}
+
+
+static int wpa_driver_wext_mlme(struct wpa_driver_wext_data *drv,
+                const u8 *addr, int cmd, int reason_code)
+{
+    struct iwreq iwr;
+    struct iw_mlme mlme;
+    int ret = 0;
+
+    os_memset(&iwr, 0, sizeof(iwr));
+    os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+    os_memset(&mlme, 0, sizeof(mlme));
+    mlme.cmd = cmd;
+    mlme.reason_code = reason_code;
+    mlme.addr.sa_family = ARPHRD_ETHER;
+    os_memcpy(mlme.addr.sa_data, addr, ETH_ALEN);
+    iwr.u.data.pointer = (caddr_t) &mlme;
+    iwr.u.data.length = sizeof(mlme);
+
+    if (ioctl(drv->ioctl_sock, SIOCSIWMLME, &iwr) < 0) {
+        wpa_printf(MSG_ERROR, "ioctl[SIOCSIWMLME]");
+        ret = -1;
+    }
+
+    return ret;
+}
+
+
+static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv)
+{
+    struct iwreq iwr;
+    const u8 null_bssid[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+#ifndef ANDROID
+    u8 ssid[32];
+    int i;
+#endif
+
+    /*
+     * Only force-disconnect when the card is in infrastructure mode,
+     * otherwise the driver might interpret the cleared BSSID and random
+     * SSID as an attempt to create a new ad-hoc network.
+     */
+    os_memset(&iwr, 0, sizeof(iwr));
+    os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+    if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) {
+        wpa_printf(MSG_ERROR, "ioctl[SIOCGIWMODE]");
+        iwr.u.mode = IW_MODE_INFRA;
+    }
+
+    if (iwr.u.mode == IW_MODE_INFRA) {
+        /*
+         * Clear the BSSID selection and set a random SSID to make sure
+         * the driver will not be trying to associate with something
+         * even if it does not understand SIOCSIWMLME commands (or
+         * tries to associate automatically after deauth/disassoc).
+         */
+        wpa_driver_wext_set_bssid(drv, null_bssid);
+#ifndef ANDROID
+        for (i = 0; i < 32; i++)
+            ssid[i] = rand() & 0xFF;
+        wpa_driver_wext_set_ssid(drv, ssid, 32);
+#endif
+    }
+}
+
+
+static int wpa_driver_wext_deauthenticate(void *priv, const u8 *addr,
+                      int reason_code)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    int ret;
+    wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+    ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DEAUTH, reason_code);
+    wpa_driver_wext_disconnect(drv);
+    return ret;
+}
+
+
+static int wpa_driver_wext_disassociate(void *priv, const u8 *addr,
+                    int reason_code)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    int ret;
+    wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+    ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DISASSOC, reason_code);
+    wpa_driver_wext_disconnect(drv);
+    return ret;
+}
+
+
+static int wpa_driver_wext_set_gen_ie(void *priv, const u8 *ie,
+                      size_t ie_len)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    struct iwreq iwr;
+    int ret = 0;
+
+    os_memset(&iwr, 0, sizeof(iwr));
+    os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+    iwr.u.data.pointer = (caddr_t) ie;
+    iwr.u.data.length = ie_len;
+
+    if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) {
+        wpa_printf(MSG_ERROR, "ioctl[SIOCSIWGENIE]");
+        ret = -1;
+    }
+
+    return ret;
+}
+
+
+static int
+wpa_driver_wext_auth_alg_fallback(struct wpa_driver_wext_data *drv,
+                  struct wpa_driver_associate_params *params)
+{
+    struct iwreq iwr;
+    int ret = 0;
+
+    wpa_printf(MSG_DEBUG, "WEXT: Driver did not support "
+           "SIOCSIWAUTH for AUTH_ALG, trying SIOCSIWENCODE");
+
+    os_memset(&iwr, 0, sizeof(iwr));
+    os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+    /* Just changing mode, not actual keys */
+    iwr.u.encoding.flags = 0;
+    iwr.u.encoding.pointer = (caddr_t) NULL;
+    iwr.u.encoding.length = 0;
+
+    /*
+     * Note: IW_ENCODE_{OPEN,RESTRICTED} can be interpreted to mean two
+     * different things. Here they are used to indicate Open System vs.
+     * Shared Key authentication algorithm. However, some drivers may use
+     * them to select between open/restricted WEP encrypted (open = allow
+     * both unencrypted and encrypted frames; restricted = only allow
+     * encrypted frames).
+     */
+
+    if (!drv->use_crypt) {
+        iwr.u.encoding.flags |= IW_ENCODE_DISABLED;
+    } else {
+        if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM) {
+            iwr.u.encoding.flags |= IW_ENCODE_OPEN;
+        }
+        if (params->auth_alg & AUTH_ALG_SHARED_KEY) {
+            iwr.u.encoding.flags |= IW_ENCODE_RESTRICTED;
+        }
+    }
+
+    if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {
+        wpa_printf(MSG_ERROR, "ioctl[SIOCSIWENCODE]");
+        ret = -1;
+    }
+
+    return ret;
+}
+
+static int wpa_driver_wext_set_auth_alg(void *priv, int auth_alg)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    int algs = 0, res;
+
+    if (auth_alg & AUTH_ALG_OPEN_SYSTEM) {
+        algs |= IW_AUTH_ALG_OPEN_SYSTEM;
+    }
+    if (auth_alg & AUTH_ALG_SHARED_KEY) {
+        algs |= IW_AUTH_ALG_SHARED_KEY;
+    }
+    if (auth_alg & AUTH_ALG_LEAP) {
+        algs |= IW_AUTH_ALG_LEAP;
+    }
+    if (algs == 0) {
+        /* at least one algorithm should be set */
+        algs = IW_AUTH_ALG_OPEN_SYSTEM;
+    }
+
+    res = wpa_driver_wext_set_auth_param(drv, IW_AUTH_80211_AUTH_ALG,
+                         algs);
+    drv->auth_alg_fallback = res == -2;
+    return res;
+}
+
+static int wpa_driver_wext_pmksa(struct wpa_driver_wext_data *drv,
+                 u32 cmd, const u8 *bssid, const u8 *pmkid)
+{
+    struct iwreq iwr;
+    struct iw_pmksa pmksa;
+    int ret = 0;
+
+    os_memset(&iwr, 0, sizeof(iwr));
+    os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+    os_memset(&pmksa, 0, sizeof(pmksa));
+    pmksa.cmd = cmd;
+    pmksa.bssid.sa_family = ARPHRD_ETHER;
+    if (bssid) {
+        os_memcpy(pmksa.bssid.sa_data, bssid, ETH_ALEN);
+    }
+    if (pmkid) {
+        os_memcpy(pmksa.pmkid, pmkid, IW_PMKID_LEN);
+    }
+    iwr.u.data.pointer = (caddr_t) &pmksa;
+    iwr.u.data.length = sizeof(pmksa);
+
+    if (ioctl(drv->ioctl_sock, SIOCSIWPMKSA, &iwr) < 0) {
+        if (errno != EOPNOTSUPP) {
+            wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPMKSA]");
+        }
+        ret = -1;
+    }
+
+    return ret;
+}
+
+
+static int wpa_driver_wext_add_pmkid(void *priv, const u8 *bssid,
+                     const u8 *pmkid)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    return wpa_driver_wext_pmksa(drv, IW_PMKSA_ADD, bssid, pmkid);
+}
+
+
+static int wpa_driver_wext_remove_pmkid(void *priv, const u8 *bssid,
+                    const u8 *pmkid)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    return wpa_driver_wext_pmksa(drv, IW_PMKSA_REMOVE, bssid, pmkid);
+}
+
+
+static int wpa_driver_wext_flush_pmkid(void *priv)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    return wpa_driver_wext_pmksa(drv, IW_PMKSA_FLUSH, NULL, NULL);
+}
+
+
+#ifdef ANDROID
+
+static int wpa_driver_wext_get_mac_addr(void *priv, u8 *addr)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    struct ifreq ifr;
+    static const u8 nullmac[ETH_ALEN] = {0};
+
+    os_memset(&ifr, 0, sizeof(ifr));
+    os_strncpy(ifr.ifr_name, drv->ifname, IFNAMSIZ);
+
+    if (ioctl(drv->ioctl_sock, SIOCGIFHWADDR, &ifr) < 0) {
+        perror("ioctl[SIOCGIFHWADDR]");
+        return -1;
+    }
+    os_memcpy(addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
+    if (os_memcmp(addr, nullmac, ETH_ALEN) == 0) {
+        return -1;
+    }
+
+    return 0;
+}
+
+static int wpa_driver_wext_get_rssi(void *priv)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    struct iwreq iwr;
+    struct iw_statistics iws;
+    int sig = 0;
+
+    os_memset(&iwr, 0, sizeof(iwr));
+    iwr.u.data.pointer = (char*)&iws;
+    iwr.u.data.length  = sizeof(iws);
+    iwr.u.data.flags = 1;
+    os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+
+    if (ioctl(drv->ioctl_sock, SIOCGIWSTATS, &iwr) < 0) {
+        perror("ioctl[SIOCGIWSTATS]");
+        return -1;
+    }
+
+    sig = iws.qual.level;
+    if (sig == 0) {
+        return -1;
+    }
+    if (iws.qual.updated & IW_QUAL_DBM) {
+        sig -= 0x100;
+    }
+
+    return sig;
+}
+
+static int wpa_driver_wext_get_linkspeed(void *priv)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    struct iwreq iwr;
+    int linkspeed;
+
+    os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+
+    if (ioctl(drv->ioctl_sock, SIOCGIWRATE, &iwr) < 0) {
+        perror("ioctl[SIOCGIWRATE]");
+        return -1;
+    }
+
+    linkspeed = iwr.u.bitrate.value / 1000000;
+
+    return linkspeed;
+}
+
+static char *wpa_driver_get_country_code(int channels)
+{
+    static char *country = "US"; /* WEXT_NUMBER_SCAN_CHANNELS_FCC */
+
+    if (channels == WEXT_NUMBER_SCAN_CHANNELS_ETSI) {
+        country = "EU";
+    } else if( channels == WEXT_NUMBER_SCAN_CHANNELS_MKK1) {
+        country = "JP";
+    }
+    return country;
+}
+
+/* global NL structures */
+struct nl_handle *nl_sock;
+struct nl_cache *nl_cache;
+struct genl_family *nl80211;
+
+static int wpa_driver_init_nl() {
+    int err;
+
+    nl_sock = nl_socket_alloc();
+    if (!nl_sock) {
+        wpa_printf(MSG_DEBUG,"Failed to allocate netlink socket.");
+        return -ENOMEM;
+    }
+
+    if (genl_connect(nl_sock)) {
+        wpa_printf(MSG_DEBUG,"Failed to connect to generic netlink.");
+        err = -ENOLINK;
+        goto out_handle_destroy;
+    }
+
+    genl_ctrl_alloc_cache(nl_sock, &nl_cache);
+    if (!nl_cache) {
+        wpa_printf(MSG_DEBUG,"Failed to allocate generic netlink cache.");
+        err = -ENOMEM;
+        goto out_handle_destroy;
+    }
+
+    nl80211 = genl_ctrl_search_by_name(nl_cache, "nl80211");
+    if (!nl80211) {
+        wpa_printf(MSG_DEBUG,"nl80211 not found.");
+        err = -ENOENT;
+        goto out_cache_free;
+    }
+
+    return 0;
+
+out_cache_free:
+    nl_cache_free(nl_cache);
+out_handle_destroy:
+    nl_socket_free(nl_sock);
+    return err;
+}
+
+static void wpa_driver_deinit_nl() {
+    genl_family_put(nl80211);
+    nl_cache_free(nl_cache);
+    nl_socket_free(nl_sock);
+}
+
+static int nl_error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
+{
+    int *ret = (int *)arg;
+    *ret = err->error;
+    return NL_STOP;
+}
+
+static int nl_finish_handler(struct nl_msg *msg, void *arg)
+{
+     int *ret = (int *)arg;
+     *ret = 0;
+     return NL_SKIP;
+}
+
+static int nl_ack_handler(struct nl_msg *msg, void *arg)
+{
+    int *ret = (int *)arg;
+    *ret = 0;
+    return NL_STOP;
+}
+
+static int wpa_driver_set_power_save(char *iface, int state)
+{
+    int ret;
+    struct nl_cb *cb;
+    struct nl_msg *msg;
+    int devidx = 0;
+    int err;
+    enum nl80211_ps_state ps_state;
+
+    ret = wpa_driver_init_nl();
+    if (ret != 0) {
+        return ret;
+    }
+
+    ret = -1;
+
+        devidx = if_nametoindex(iface);
+        if (devidx == 0) {
+            wpa_printf(MSG_DEBUG,"failed to translate ifname to idx");
+            goto exit;
+        }
+
+    msg = nlmsg_alloc();
+    if (!msg) {
+        wpa_printf(MSG_DEBUG,"failed to allocate netlink message");
+        goto exit;
+    }
+
+    cb = nl_cb_alloc(NL_CB_DEFAULT);
+    if (!cb) {
+        wpa_printf(MSG_DEBUG,"failed to allocate netlink callbacks");
+        goto out_free_msg;
+    }
+
+    genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0,
+            NL80211_CMD_SET_POWER_SAVE, 0);
+
+    if (state != 0) {
+        ps_state = NL80211_PS_ENABLED;
+    } else {
+        ps_state = NL80211_PS_DISABLED;
+    }
+
+    NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);
+    NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state);
+
+    err = nl_send_auto_complete(nl_sock, msg);
+    if (err < 0) {
+        wpa_printf(MSG_DEBUG, "could not send auto_complete: %d", err);
+        goto out;
+    }
+
+    err = 1;
+
+    nl_cb_err(cb, NL_CB_CUSTOM, nl_error_handler, &err);
+    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl_finish_handler, &err);
+    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl_ack_handler, &err);
+
+    while (err > 0)
+        nl_recvmsgs(nl_sock, cb);
+
+    ret = 0;
+out:
+    nl_cb_put(cb);
+out_free_msg:
+    nlmsg_free(msg);
+nla_put_failure:
+
+exit:
+    wpa_driver_deinit_nl();
+    return ret;
+}
+
+static int wpa_driver_set_country(char *iface, char *country)
+{
+    int ret;
+    struct nl_cb *cb;
+    struct nl_msg *msg;
+    int devidx = 0;
+    int err;
+    char alpha2[3];
+    ret = wpa_driver_init_nl();
+    if (ret != 0) {
+        return ret;
+    }
+
+    ret = -1;
+
+    devidx = if_nametoindex(iface);
+    if (devidx == 0) {
+        wpa_printf(MSG_DEBUG,"failed to translate ifname to idx");
+        goto exit;
+    }
+
+    msg = nlmsg_alloc();
+    if (!msg) {
+        wpa_printf(MSG_DEBUG,"failed to allocate netlink message");
+        goto exit;
+    }
+
+    cb = nl_cb_alloc(NL_CB_DEFAULT);
+    if (!cb) {
+        wpa_printf(MSG_DEBUG,"failed to allocate netlink callbacks");
+        goto out_free_msg;
+    }
+
+    alpha2[0] = country[0];
+    alpha2[1] = country[1];
+    alpha2[2] = '\0';
+
+    genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0,
+            NL80211_CMD_REQ_SET_REG, 0);
+
+    NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);
+    NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
+
+    err = nl_send_auto_complete(nl_sock, msg);
+    if (err < 0) {
+        wpa_printf(MSG_DEBUG, "could not send auto_complete: %d", err);
+        goto out;
+    }
+
+    err = 1;
+
+    nl_cb_err(cb, NL_CB_CUSTOM, nl_error_handler, &err);
+    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl_finish_handler, &err);
+    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl_ack_handler, &err);
+
+    while (err > 0)
+        nl_recvmsgs(nl_sock, cb);
+
+    ret = 0;
+out:
+    nl_cb_put(cb);
+out_free_msg:
+    nlmsg_free(msg);
+nla_put_failure:
+
+exit:
+    wpa_driver_deinit_nl();
+    return ret;
+}
+
+static int wpa_driver_toggle_btcoex_state(char state)
+{
+    int ret;
+    int fd = open("/sys/devices/platform/wl1271/bt_coex_state", O_RDWR, 0);
+    if (fd == -1) {
+        return -1;
+    }
+
+    ret = write(fd, &state, sizeof(state));
+    close(fd);
+
+    wpa_printf(MSG_DEBUG, "%s:  set btcoex state to '%c' result = %d", __func__,
+           state, ret);
+    return ret;
+}
+
+static int wpa_driver_toggle_rx_filter(char state)
+{
+    return 0; /* not implemented yet */
+}
+
+/* we start with "auto" power mode - power_save is on */
+int g_power_mode = 0;
+
+/* currently cached scan type */
+u8 g_scan_type = IW_SCAN_TYPE_ACTIVE;
+
+/* start with "world" num of channels */
+int g_num_channels = 13;
+
+static int wpa_driver_priv_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len )
+{
+    struct wpa_driver_wext_data *drv = priv;
+    struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
+    int ret = 0, flags;
+
+    wpa_printf(MSG_DEBUG, "%s %s len = %d", __func__, cmd, buf_len);
+
+    if (os_strcasecmp(cmd, "STOP") == 0) {
+        if ((wpa_driver_wext_get_ifflags(drv, &flags) == 0) &&
+            (flags & IFF_UP)) {
+            wpa_driver_wext_set_ifflags(drv, flags & ~IFF_UP);
+        }
+        wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
+    } else if (os_strcasecmp(cmd, "START") == 0) {
+        if ((wpa_driver_wext_get_ifflags(drv, &flags) == 0) &&
+            !(flags & IFF_UP)) {
+            wpa_driver_wext_set_ifflags(drv, flags | IFF_UP);
+        }
+        wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
+    } else if (os_strcasecmp(cmd, "MACADDR") == 0) {
+        u8 macaddr[ETH_ALEN] = {};
+
+        ret = wpa_driver_wext_get_mac_addr(priv, macaddr);
+        if (ret < 0) {
+            goto out;
+        }
+
+        ret = os_snprintf(buf, buf_len, "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
+    } else if ((os_strcasecmp(cmd, "RSSI") == 0) || (os_strcasecmp(cmd, "RSSI-APPROX") == 0)) {
+        u8 ssid[MAX_SSID_LEN];
+        int rssi;
+
+        rssi = wpa_driver_wext_get_rssi(priv);
+        if ((rssi != -1) && (wpa_driver_wext_get_ssid(priv, ssid) > 0)) {
+            ret = os_snprintf(buf, buf_len, "%s rssi %d\n", ssid, rssi);
+        } else {
+            ret = -1;
+        }
+    } else if (os_strcasecmp(cmd, "LINKSPEED") == 0) {
+        int linkspeed;
+
+        linkspeed = wpa_driver_wext_get_linkspeed(priv);
+        if (linkspeed != -1) {
+            ret = os_snprintf(buf, buf_len, "LinkSpeed %d\n", linkspeed);
+        } else {
+            ret = -1;
+        }
+    } else if( os_strcasecmp(cmd, "RELOAD") == 0 ) {
+        wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
+    } else if( os_strcasecmp(cmd, "SCAN-PASSIVE") == 0 ) {
+        g_scan_type = IW_SCAN_TYPE_PASSIVE;
+        ret = 0;
+    } else if( os_strcasecmp(cmd, "SCAN-ACTIVE") == 0 ) {
+        g_scan_type = IW_SCAN_TYPE_ACTIVE;
+        ret = 0;
+    } else if( os_strcasecmp(cmd, "SCAN-MODE") == 0 ) {
+        ret = snprintf(buf, buf_len, "ScanMode = %u\n", g_scan_type);
+        if (ret < (int)buf_len) {
+            return ret;
+        }
+    } else if( os_strncasecmp(cmd, "POWERMODE", 9) == 0 ) {
+        int mode = atoi(cmd + 9);
+
+        if (mode == g_power_mode) {
+            ret = 0;
+        } else if (mode == 1) { /* active mode */
+            ret = wpa_driver_set_power_save(drv->ifname, 0);
+        } else if (mode == 0) { /* auto mode */
+            ret = wpa_driver_set_power_save(drv->ifname, 1);
+        }
+
+        if (!ret) {
+            g_power_mode = mode;
+        }
+
+        wpa_printf(MSG_DEBUG, "global POWERMODE set to %d (wanted %d), ret %d",
+               g_power_mode, mode, ret);
+    } else if( os_strcasecmp(cmd, "GETPOWER") == 0 ) {
+        ret = sprintf(buf, "powermode = %u\n", g_power_mode);
+    } else if( os_strncasecmp(cmd, "BTCOEXMODE", 10) == 0 ) {
+        int mode = atoi(cmd + 10);
+
+        wpa_printf(MSG_DEBUG, "will change btcoex mode to: %d", mode);
+
+        if (mode == 1) { /* disable BT-coex */
+            ret = wpa_driver_toggle_btcoex_state('0');
+        } else if (mode == 2) { /* enable BT-coex */
+            ret = wpa_driver_toggle_btcoex_state('1');
+        } else {
+            wpa_printf(MSG_DEBUG, "invalid btcoex mode: %d", mode);
+            ret = -1;
+        }
+    } else if( os_strcasecmp(cmd, "RXFILTER-START") == 0 ) {
+        ret = wpa_driver_toggle_rx_filter('1');
+    } else if( os_strcasecmp(cmd, "RXFILTER-STOP") == 0 ) {
+        ret = wpa_driver_toggle_rx_filter('0');
+    } else if( os_strncasecmp(cmd, "country", 7) == 0 ) {
+        wpa_printf(MSG_DEBUG, "setting country code to: %s", cmd + 8);
+        ret = wpa_driver_set_country(drv->ifname, cmd + 8);
+    } else {
+        wpa_printf(MSG_ERROR, "Unsupported command: %s", cmd);
+        ret = -1;
+    }
+
+out:
+    return ret;
+}
+
+#endif
+
+/**
+ * wpa_driver_wext_scan_custom - Request the driver to initiate scan
+ * @priv: Pointer to private wext data from wpa_driver_wext_init()
+ * @ssid: Specific SSID to scan for (ProbeReq) or %NULL to scan for
+ *    all SSIDs (either active scan with broadcast SSID or passive
+ *    scan
+ * @ssid_len: Length of the SSID
+ * Returns: 0 on success, -1 on failure
+ */
+int wpa_driver_wext_scan_custom(void *priv, const u8 *ssid, size_t ssid_len)
+{
+    struct wpa_driver_wext_data *drv = priv;
+    struct iwreq iwr;
+    int ret = 0;
+    struct iw_scan_req req;
+#ifdef ANDROID
+    struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
+    int scan_probe_flag = 0;
+#endif
+
+    if (ssid_len > IW_ESSID_MAX_SIZE) {
+        wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)",
+               __FUNCTION__, (unsigned long) ssid_len);
+        return -1;
+    }
+
+    os_memset(&iwr, 0, sizeof(iwr));
+    os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+
+    os_memset(&req, 0, sizeof(req));
+    req.scan_type = g_scan_type; /* Scan type is cached */
+    req.bssid.sa_family = ARPHRD_ETHER;
+    os_memset(req.bssid.sa_data, 0xff, ETH_ALEN);
+    iwr.u.data.pointer = (caddr_t) &req;
+    iwr.u.data.length = sizeof(req);
+    iwr.u.data.flags = IW_SCAN_THIS_ESSID;
+
+    wpa_printf(MSG_DEBUG, "%s: scanning with scan type: %s", __func__,
+           g_scan_type == IW_SCAN_TYPE_PASSIVE ? "PASSIVE" : "ACTIVE");
+
+#ifdef ANDROID
+    if (wpa_s->prev_scan_ssid != BROADCAST_SSID_SCAN) {
+        scan_probe_flag = wpa_s->prev_scan_ssid->scan_ssid;
+    }
+    wpa_printf(MSG_DEBUG, "%s: specific scan = %d", __func__,
+        (scan_probe_flag && (ssid && ssid_len)) ? 1 : 0);
+    if (scan_probe_flag && (ssid && ssid_len)) {
+#else
+    if (ssid && ssid_len) {
+#endif
+        req.essid_len = ssid_len;
+        os_memcpy(req.essid, ssid, ssid_len);
+    }
+
+    if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) {
+        wpa_printf(MSG_ERROR, "ioctl[SIOCSIWSCAN]");
+        ret = -1;
+    }
+
+    wpa_driver_wext_set_scan_timeout(priv);
+
+    return ret;
+}
+
+const struct wpa_driver_ops wpa_driver_custom_ops = {
+    .name = "mac80211_wext",
+    .desc = "mac80211 station driver for TI wl12xx",
+    .get_bssid = wpa_driver_wext_get_bssid,
+    .get_ssid = wpa_driver_wext_get_ssid,
+    .set_wpa = wpa_driver_wext_set_wpa,
+    .set_key = wpa_driver_wext_set_key,
+    .set_countermeasures = wpa_driver_wext_set_countermeasures,
+    .set_drop_unencrypted = wpa_driver_wext_set_drop_unencrypted,
+    .scan = wpa_driver_wext_scan_custom,
+    .get_scan_results2 = wpa_driver_wext_get_scan_results,
+    .deauthenticate = wpa_driver_wext_deauthenticate,
+    .disassociate = wpa_driver_wext_disassociate,
+    .set_mode = wpa_driver_wext_set_mode,
+    .associate = wpa_driver_wext_associate,
+    .set_auth_alg = wpa_driver_wext_set_auth_alg,
+    .init = wpa_driver_wext_init,
+    .deinit = wpa_driver_wext_deinit,
+    .add_pmkid = wpa_driver_wext_add_pmkid,
+    .remove_pmkid = wpa_driver_wext_remove_pmkid,
+    .flush_pmkid = wpa_driver_wext_flush_pmkid,
+    .get_capa = wpa_driver_wext_get_capa,
+    .set_operstate = wpa_driver_wext_set_operstate,
+#ifdef ANDROID
+    .driver_cmd = wpa_driver_priv_driver_cmd,
+#endif
+};
diff --git a/mac80211/wpa_supplicant_lib/driver_mac80211_nl.c b/mac80211/wpa_supplicant_lib/driver_mac80211_nl.c
new file mode 100644
index 0000000..f1fc23f
--- /dev/null
+++ b/mac80211/wpa_supplicant_lib/driver_mac80211_nl.c
@@ -0,0 +1,257 @@
+#include "includes.h"
+#include <sys/ioctl.h>
+#include <net/if_arp.h>
+#include <net/if.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+#include "wireless_copy.h"
+#include "common.h"
+#include "driver.h"
+#include "eloop.h"
+#include "driver_wext.h"
+#include "ieee802_11_defs.h"
+#include "wpa_common.h"
+#include "wpa_ctrl.h"
+#include "wpa_supplicant_i.h"
+#include "config_ssid.h"
+#include "wpa_debug.h"
+#include "linux_ioctl.h"
+#include "driver_nl80211.h"
+
+#define WPA_EVENT_DRIVER_STATE          "CTRL-EVENT-DRIVER-STATE "
+#define DRV_NUMBER_SEQUENTIAL_ERRORS     4
+
+#define WPA_PS_ENABLED   0
+#define WPA_PS_DISABLED  1
+
+#define BLUETOOTH_COEXISTENCE_MODE_ENABLED   0
+#define BLUETOOTH_COEXISTENCE_MODE_DISABLED  1
+#define BLUETOOTH_COEXISTENCE_MODE_SENSE     2
+
+
+static int g_drv_errors = 0;
+static int g_power_mode = 0;
+
+int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv, struct nl_msg *msg,
+                       int (*valid_handler)(struct nl_msg *, void *),
+                       void *valid_data);
+
+static void wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data *drv)
+{
+	g_drv_errors++;
+	if (g_drv_errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
+		g_drv_errors = 0;
+		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
+	}
+}
+
+static int get_link_signal(struct nl_msg *msg, void *arg)
+{
+	struct nlattr *tb[NL80211_ATTR_MAX + 1];
+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+	struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
+	static struct nla_policy policy[NL80211_STA_INFO_MAX + 1] = {
+		[NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
+	};
+	struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
+	static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
+		[NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
+		[NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
+		[NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
+		[NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
+	};
+	struct wpa_signal_info *sig_change = arg;
+
+	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+		  genlmsg_attrlen(gnlh, 0), NULL);
+	if (!tb[NL80211_ATTR_STA_INFO] ||
+	    nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
+			     tb[NL80211_ATTR_STA_INFO], policy))
+		return NL_SKIP;
+	if (!sinfo[NL80211_STA_INFO_SIGNAL])
+		return NL_SKIP;
+
+	sig_change->current_signal =
+		(s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
+
+	if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
+		if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
+				     sinfo[NL80211_STA_INFO_TX_BITRATE],
+				     rate_policy)) {
+			sig_change->current_txrate = 0;
+		} else {
+			if (rinfo[NL80211_RATE_INFO_BITRATE]) {
+				sig_change->current_txrate =
+					nla_get_u16(rinfo[
+					     NL80211_RATE_INFO_BITRATE]) * 100;
+			}
+		}
+	}
+
+	return NL_SKIP;
+}
+
+static int wpa_driver_get_link_signal(void *priv, struct wpa_signal_info *sig)
+{
+	struct i802_bss *bss = priv;
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *msg;
+	int ret = -1;
+
+	sig->current_signal = -9999;
+	sig->current_txrate = 0;
+
+	msg = nlmsg_alloc();
+	if (!msg)
+		return -1;
+
+	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
+		    0, NL80211_CMD_GET_STATION, 0);
+
+	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
+
+	ret = send_and_recv_msgs(drv, msg, get_link_signal, sig);
+	msg = NULL;
+	if (ret < 0)
+		wpa_printf(MSG_ERROR, "nl80211: get link signal fail: %d", ret);
+nla_put_failure:
+	nlmsg_free(msg);
+	return ret;
+}
+
+static int wpa_driver_toggle_btcoex_state(char state)
+{
+	int ret;
+	int fd = open("/sys/devices/platform/wl1271/bt_coex_state", O_RDWR, 0);
+	if (fd == -1)
+		return -1;
+
+	ret = write(fd, &state, sizeof(state));
+	close(fd);
+
+	wpa_printf(MSG_DEBUG, "%s:  set btcoex state to '%c' result = %d", __func__,
+		   state, ret);
+	return ret;
+}
+
+static int wpa_driver_set_power_save(void *priv, int state)
+{
+	struct i802_bss *bss = priv;
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *msg;
+	int ret = -1;
+	enum nl80211_ps_state ps_state;
+
+	msg = nlmsg_alloc();
+	if (!msg)
+		return -1;
+
+	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
+		    NL80211_CMD_SET_POWER_SAVE, 0);
+
+	if (state == WPA_PS_ENABLED)
+		ps_state = NL80211_PS_ENABLED;
+	else
+		ps_state = NL80211_PS_DISABLED;
+
+	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+	NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state);
+
+	ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+	msg = NULL;
+	if (ret < 0)
+		wpa_printf(MSG_ERROR, "nl80211: Set power mode fail: %d", ret);
+nla_put_failure:
+	nlmsg_free(msg);
+	return ret;
+}
+
+int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
+				  size_t buf_len )
+{
+	struct i802_bss *bss = priv;
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct ifreq ifr;
+	int ret = 0;
+
+	if (os_strcasecmp(cmd, "STOP") == 0) {
+		linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0);
+		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
+	} else if (os_strcasecmp(cmd, "START") == 0) {
+		linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1);
+		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
+	} else if (os_strcasecmp(cmd, "RELOAD") == 0) {
+		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
+	} else if (os_strncasecmp(cmd, "POWERMODE ", 10) == 0) {
+		int mode;
+		mode = atoi(cmd + 10);
+		ret = wpa_driver_set_power_save(priv, mode);
+		if (ret < 0) {
+			wpa_driver_send_hang_msg(drv);
+		} else {
+			g_power_mode = mode;
+			g_drv_errors = 0;
+		}
+	} else if (os_strncasecmp(cmd, "GETPOWER", 8) == 0) {
+		ret = os_snprintf(buf, buf_len, "POWERMODE = %d\n", g_power_mode);
+	} else if (os_strncasecmp(cmd, "BTCOEXMODE ", 11) == 0) {
+		int mode = atoi(cmd + 11);
+		if (mode == BLUETOOTH_COEXISTENCE_MODE_DISABLED) { /* disable BT-coex */
+			ret = wpa_driver_toggle_btcoex_state('0');
+		} else if (mode == BLUETOOTH_COEXISTENCE_MODE_SENSE) { /* enable BT-coex */
+			ret = wpa_driver_toggle_btcoex_state('1');
+		} else {
+			wpa_printf(MSG_DEBUG, "invalid btcoex mode: %d", mode);
+			ret = -1;
+		}
+	} else if ((os_strcasecmp(cmd, "RSSI") == 0) || (os_strcasecmp(cmd, "RSSI-APPROX") == 0)) {
+		struct wpa_signal_info sig;
+		int rssi;
+
+		if (!drv->associated)
+			return -1;
+
+		ret = wpa_driver_get_link_signal(priv, &sig);
+		if (ret < 0) {
+			wpa_driver_send_hang_msg(drv);
+		} else {
+			rssi = sig.current_signal;
+			wpa_printf(MSG_DEBUG, "%s rssi %d\n", drv->ssid, rssi);
+			ret = os_snprintf(buf, buf_len, "%s rssi %d\n", drv->ssid, rssi);
+		}
+	} else if (os_strcasecmp(cmd, "LINKSPEED") == 0) {
+		struct wpa_signal_info sig;
+		int linkspeed;
+
+		if (!drv->associated)
+			return -1;
+
+		ret = wpa_driver_get_link_signal(priv, &sig);
+		if (ret < 0) {
+			wpa_driver_send_hang_msg(drv);
+		} else {
+			linkspeed = sig.current_txrate / 1000;
+			wpa_printf(MSG_DEBUG, "LinkSpeed %d\n", linkspeed);
+			ret = os_snprintf(buf, buf_len, "LinkSpeed %d\n", linkspeed);
+		}
+	} else if (os_strcasecmp(cmd, "MACADDR") == 0) {
+		u8 macaddr[ETH_ALEN] = {};
+
+		ret = linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, macaddr);
+		if (!ret)
+			ret = os_snprintf(buf, buf_len,
+					  "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
+	} else {
+		wpa_printf(MSG_INFO, "%s: Unsupported command %s", __func__, cmd);
+	}
+	return ret;
+}
diff --git a/mac80211/wpa_supplicant_lib/driver_nl80211.h b/mac80211/wpa_supplicant_lib/driver_nl80211.h
new file mode 100644
index 0000000..0a0f3f4
--- /dev/null
+++ b/mac80211/wpa_supplicant_lib/driver_nl80211.h
@@ -0,0 +1,149 @@
+/*
+ * Driver interaction with Linux nl80211/cfg80211
+ * Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2004, Instant802 Networks, Inc.
+ * Copyright (c) 2005-2006, Devicescape Software, Inc.
+ * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright (c) 2009-2010, Atheros Communications
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef _DRIVER_NL80211_H_
+#define _DRIVER_NL80211_H_
+
+#include "includes.h"
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include "nl80211_copy.h"
+
+#include "common.h"
+#include "eloop.h"
+#include "utils/list.h"
+#include "common/ieee802_11_defs.h"
+#include "netlink.h"
+#include "linux_ioctl.h"
+#include "radiotap.h"
+#include "radiotap_iter.h"
+#include "rfkill.h"
+#include "driver.h"
+
+#ifdef CONFIG_LIBNL20
+/* libnl 2.0 compatibility code */
+#define nl_handle nl_sock
+#define nl80211_handle_alloc nl_socket_alloc_cb
+#define nl80211_handle_destroy nl_socket_free
+#endif /* CONFIG_LIBNL20 */
+
+#ifndef IFF_LOWER_UP
+#define IFF_LOWER_UP   0x10000         /* driver signals L1 up         */
+#endif
+#ifndef IFF_DORMANT
+#define IFF_DORMANT    0x20000         /* driver signals dormant       */
+#endif
+
+#ifndef IF_OPER_DORMANT
+#define IF_OPER_DORMANT 5
+#endif
+#ifndef IF_OPER_UP
+#define IF_OPER_UP 6
+#endif
+
+struct nl80211_global {
+	struct dl_list interfaces;
+};
+
+struct i802_bss {
+	struct wpa_driver_nl80211_data *drv;
+	struct i802_bss *next;
+	int ifindex;
+	char ifname[IFNAMSIZ + 1];
+	char brname[IFNAMSIZ];
+	unsigned int beacon_set:1;
+	unsigned int added_if_into_bridge:1;
+	unsigned int added_bridge:1;
+};
+
+struct wpa_driver_nl80211_data {
+	struct nl80211_global *global;
+	struct dl_list list;
+	u8 addr[ETH_ALEN];
+	char phyname[32];
+	void *ctx;
+	struct netlink_data *netlink;
+	int ioctl_sock; /* socket for ioctl() use */
+	int ifindex;
+	int if_removed;
+	int if_disabled;
+	struct rfkill_data *rfkill;
+	struct wpa_driver_capa capa;
+	int has_capability;
+
+	int operstate;
+
+	int scan_complete_events;
+
+	struct nl_handle *nl_handle;
+	struct nl_handle *nl_handle_event;
+	struct nl_handle *nl_handle_preq;
+	struct nl_cache *nl_cache;
+	struct nl_cache *nl_cache_event;
+	struct nl_cache *nl_cache_preq;
+	struct nl_cb *nl_cb;
+	struct genl_family *nl80211;
+
+	u8 auth_bssid[ETH_ALEN];
+	u8 bssid[ETH_ALEN];
+	int associated;
+	u8 ssid[32];
+	size_t ssid_len;
+	int nlmode;
+	int ap_scan_as_station;
+	unsigned int assoc_freq;
+
+	int monitor_sock;
+	int monitor_ifidx;
+	int no_monitor_iface_capab;
+	int disable_11b_rates;
+
+	unsigned int pending_remain_on_chan:1;
+
+	u64 remain_on_chan_cookie;
+	u64 send_action_cookie;
+
+	unsigned int last_mgmt_freq;
+
+	struct wpa_driver_scan_filter *filter_ssids;
+	size_t num_filter_ssids;
+
+	struct i802_bss first_bss;
+
+#ifdef HOSTAPD
+	int eapol_sock; /* socket for EAPOL frames */
+
+	int default_if_indices[16];
+	int *if_indices;
+	int num_if_indices;
+
+	int last_freq;
+	int last_freq_ht;
+#endif /* HOSTAPD */
+};
+
+#endif
diff --git a/mac80211/wpa_supplicant_lib/nl80211.h b/mac80211/wpa_supplicant_lib/nl80211.h
new file mode 100644
index 0000000..ff749b8
--- /dev/null
+++ b/mac80211/wpa_supplicant_lib/nl80211.h
@@ -0,0 +1,1813 @@
+#ifndef __LINUX_NL80211_H
+#define __LINUX_NL80211_H
+/*
+ * 802.11 netlink interface public header
+ *
+ * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2008 Michael Wu <flamingice@sourmilk.net>
+ * Copyright 2008 Luis Carlos Cobo <luisca@cozybit.com>
+ * Copyright 2008 Michael Buesch <mb@bu3sch.de>
+ * Copyright 2008, 2009 Luis R. Rodriguez <lrodriguez@atheros.com>
+ * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com>
+ * Copyright 2008 Colin McCabe <colin@cozybit.com>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/types.h>
+
+/**
+ * DOC: Station handling
+ *
+ * Stations are added per interface, but a special case exists with VLAN
+ * interfaces. When a station is bound to an AP interface, it may be moved
+ * into a VLAN identified by a VLAN interface index (%NL80211_ATTR_STA_VLAN).
+ * The station is still assumed to belong to the AP interface it was added
+ * to.
+ *
+ * TODO: need more info?
+ */
+
+/**
+ * DOC: Frame transmission/registration support
+ *
+ * Frame transmission and registration support exists to allow userspace
+ * management entities such as wpa_supplicant react to management frames
+ * that are not being handled by the kernel. This includes, for example,
+ * certain classes of action frames that cannot be handled in the kernel
+ * for various reasons.
+ *
+ * Frame registration is done on a per-interface basis and registrations
+ * cannot be removed other than by closing the socket. It is possible to
+ * specify a registration filter to register, for example, only for a
+ * certain type of action frame. In particular with action frames, those
+ * that userspace registers for will not be returned as unhandled by the
+ * driver, so that the registered application has to take responsibility
+ * for doing that.
+ *
+ * The type of frame that can be registered for is also dependent on the
+ * driver and interface type. The frame types are advertised in wiphy
+ * attributes so applications know what to expect.
+ *
+ * NOTE: When an interface changes type while registrations are active,
+ *       these registrations are ignored until the interface type is
+ *       changed again. This means that changing the interface type can
+ *       lead to a situation that couldn't otherwise be produced, but
+ *       any such registrations will be dormant in the sense that they
+ *       will not be serviced, i.e. they will not receive any frames.
+ *
+ * Frame transmission allows userspace to send for example the required
+ * responses to action frames. It is subject to some sanity checking,
+ * but many frames can be transmitted. When a frame was transmitted, its
+ * status is indicated to the sending socket.
+ *
+ * For more technical details, see the corresponding command descriptions
+ * below.
+ */
+
+/**
+ * enum nl80211_commands - supported nl80211 commands
+ *
+ * @NL80211_CMD_UNSPEC: unspecified command to catch errors
+ *
+ * @NL80211_CMD_GET_WIPHY: request information about a wiphy or dump request
+ *    to get a list of all present wiphys.
+ * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or
+ *    %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME,
+ *    %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ,
+ *    %NL80211_ATTR_WIPHY_CHANNEL_TYPE, %NL80211_ATTR_WIPHY_RETRY_SHORT,
+ *    %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+ *    and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD.
+ *    However, for setting the channel, see %NL80211_CMD_SET_CHANNEL
+ *    instead, the support here is for backward compatibility only.
+ * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request
+ *    or rename notification. Has attributes %NL80211_ATTR_WIPHY and
+ *    %NL80211_ATTR_WIPHY_NAME.
+ * @NL80211_CMD_DEL_WIPHY: Wiphy deleted. Has attributes
+ *    %NL80211_ATTR_WIPHY and %NL80211_ATTR_WIPHY_NAME.
+ *
+ * @NL80211_CMD_GET_INTERFACE: Request an interface's configuration;
+ *    either a dump request on a %NL80211_ATTR_WIPHY or a specific get
+ *    on an %NL80211_ATTR_IFINDEX is supported.
+ * @NL80211_CMD_SET_INTERFACE: Set type of a virtual interface, requires
+ *    %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE.
+ * @NL80211_CMD_NEW_INTERFACE: Newly created virtual interface or response
+ *    to %NL80211_CMD_GET_INTERFACE. Has %NL80211_ATTR_IFINDEX,
+ *    %NL80211_ATTR_WIPHY and %NL80211_ATTR_IFTYPE attributes. Can also
+ *    be sent from userspace to request creation of a new virtual interface,
+ *    then requires attributes %NL80211_ATTR_WIPHY, %NL80211_ATTR_IFTYPE and
+ *    %NL80211_ATTR_IFNAME.
+ * @NL80211_CMD_DEL_INTERFACE: Virtual interface was deleted, has attributes
+ *    %NL80211_ATTR_IFINDEX and %NL80211_ATTR_WIPHY. Can also be sent from
+ *    userspace to request deletion of a virtual interface, then requires
+ *    attribute %NL80211_ATTR_IFINDEX.
+ *
+ * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified
+ *    by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC.
+ * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT,
+ *    %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD.
+ * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA,
+ *    %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER,
+ *    and %NL80211_ATTR_KEY_SEQ attributes.
+ * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
+ *    or %NL80211_ATTR_MAC.
+ *
+ * @NL80211_CMD_GET_BEACON: retrieve beacon information (returned in a
+ *    %NL80222_CMD_NEW_BEACON message)
+ * @NL80211_CMD_SET_BEACON: set the beacon on an access point interface
+ *    using the %NL80211_ATTR_BEACON_INTERVAL, %NL80211_ATTR_DTIM_PERIOD,
+ *    %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL attributes.
+ * @NL80211_CMD_NEW_BEACON: add a new beacon to an access point interface,
+ *    parameters are like for %NL80211_CMD_SET_BEACON.
+ * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it
+ *
+ * @NL80211_CMD_GET_STATION: Get station attributes for station identified by
+ *    %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_SET_STATION: Set station attributes for station identified by
+ *    %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_NEW_STATION: Add a station with given attributes to the
+ *    the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC
+ *    or, if no MAC address given, all stations, on the interface identified
+ *    by %NL80211_ATTR_IFINDEX.
+ *
+ * @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to
+ *     destination %NL80211_ATTR_MAC on the interface identified by
+ *     %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_SET_MPATH:  Set mesh path attributes for mesh path to
+ *     destination %NL80211_ATTR_MAC on the interface identified by
+ *     %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the
+ *    the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC
+ *    or, if no MAC address given, all mesh paths, on the interface identified
+ *    by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by
+ *    %NL80211_ATTR_IFINDEX.
+ *
+ * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
+ *     regulatory domain.
+ * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
+ *    after being queried by the kernel. CRDA replies by sending a regulatory
+ *    domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
+ *    current alpha2 if it found a match. It also provides
+ *     NL80211_ATTR_REG_RULE_FLAGS, and a set of regulatory rules. Each
+ *     regulatory rule is a nested set of attributes  given by
+ *     %NL80211_ATTR_REG_RULE_FREQ_[START|END] and
+ *     %NL80211_ATTR_FREQ_RANGE_MAX_BW with an attached power rule given by
+ *     %NL80211_ATTR_REG_RULE_POWER_MAX_ANT_GAIN and
+ *     %NL80211_ATTR_REG_RULE_POWER_MAX_EIRP.
+ * @NL80211_CMD_REQ_SET_REG: ask the wireless core to set the regulatory domain
+ *     to the specified ISO/IEC 3166-1 alpha2 country code. The core will
+ *     store this as a valid request and then query userspace for it.
+ *
+ * @NL80211_CMD_GET_MESH_PARAMS: Get mesh networking properties for the
+ *    interface identified by %NL80211_ATTR_IFINDEX
+ *
+ * @NL80211_CMD_SET_MESH_PARAMS: Set mesh networking properties for the
+ *      interface identified by %NL80211_ATTR_IFINDEX
+ *
+ * @NL80211_CMD_SET_MGMT_EXTRA_IE: Set extra IEs for management frames. The
+ *    interface is identified with %NL80211_ATTR_IFINDEX and the management
+ *    frame subtype with %NL80211_ATTR_MGMT_SUBTYPE. The extra IE data to be
+ *    added to the end of the specified management frame is specified with
+ *    %NL80211_ATTR_IE. If the command succeeds, the requested data will be
+ *    added to all specified management frames generated by
+ *    kernel/firmware/driver.
+ *    Note: This command has been removed and it is only reserved at this
+ *    point to avoid re-using existing command number. The functionality this
+ *    command was planned for has been provided with cleaner design with the
+ *    option to specify additional IEs in NL80211_CMD_TRIGGER_SCAN,
+ *    NL80211_CMD_AUTHENTICATE, NL80211_CMD_ASSOCIATE,
+ *    NL80211_CMD_DEAUTHENTICATE, and NL80211_CMD_DISASSOCIATE.
+ *
+ * @NL80211_CMD_GET_SCAN: get scan results
+ * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters
+ * @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to
+ *    NL80211_CMD_GET_SCAN and on the "scan" multicast group)
+ * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
+ *    partial scan results may be available
+ *
+ * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation
+ *      or noise level
+ * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to
+ *    NL80211_CMD_GET_SURVEY and on the "scan" multicast group)
+ *
+ * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain
+ *     has been changed and provides details of the request information
+ *     that caused the change such as who initiated the regulatory request
+ *     (%NL80211_ATTR_REG_INITIATOR), the wiphy_idx
+ *     (%NL80211_ATTR_REG_ALPHA2) on which the request was made from if
+ *     the initiator was %NL80211_REGDOM_SET_BY_COUNTRY_IE or
+ *     %NL80211_REGDOM_SET_BY_DRIVER, the type of regulatory domain
+ *     set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is
+ *     %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on
+ *     to (%NL80211_ATTR_REG_ALPHA2).
+ * @NL80211_CMD_REG_BEACON_HINT: indicates to userspace that an AP beacon
+ *     has been found while world roaming thus enabling active scan or
+ *     any mode of operation that initiates TX (beacons) on a channel
+ *     where we would not have been able to do either before. As an example
+ *     if you are world roaming (regulatory domain set to world or if your
+ *     driver is using a custom world roaming regulatory domain) and while
+ *     doing a passive scan on the 5 GHz band you find an AP there (if not
+ *     on a DFS channel) you will now be able to actively scan for that AP
+ *     or use AP mode on your card on that same channel. Note that this will
+ *     never be used for channels 1-11 on the 2 GHz band as they are always
+ *     enabled world wide. This beacon hint is only sent if your device had
+ *     either disabled active scanning or beaconing on a channel. We send to
+ *     userspace the wiphy on which we removed a restriction from
+ *     (%NL80211_ATTR_WIPHY) and the channel on which this occurred
+ *     before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER)
+ *     the beacon hint was processed.
+ *
+ * @NL80211_CMD_AUTHENTICATE: authentication request and notification.
+ *    This command is used both as a command (request to authenticate) and
+ *    as an event on the "mlme" multicast group indicating completion of the
+ *    authentication process.
+ *    When used as a command, %NL80211_ATTR_IFINDEX is used to identify the
+ *    interface. %NL80211_ATTR_MAC is used to specify PeerSTAAddress (and
+ *    BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify
+ *    the SSID (mainly for association, but is included in authentication
+ *    request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ is used
+ *    to specify the frequence of the channel in MHz. %NL80211_ATTR_AUTH_TYPE
+ *    is used to specify the authentication type. %NL80211_ATTR_IE is used to
+ *    define IEs (VendorSpecificInfo, but also including RSN IE and FT IEs)
+ *    to be added to the frame.
+ *    When used as an event, this reports reception of an Authentication
+ *    frame in station and IBSS modes when the local MLME processed the
+ *    frame, i.e., it was for the local STA and was received in correct
+ *    state. This is similar to MLME-AUTHENTICATE.confirm primitive in the
+ *    MLME SAP interface (kernel providing MLME, userspace SME). The
+ *    included %NL80211_ATTR_FRAME attribute contains the management frame
+ *    (including both the header and frame body, but not FCS). This event is
+ *    also used to indicate if the authentication attempt timed out. In that
+ *    case the %NL80211_ATTR_FRAME attribute is replaced with a
+ *    %NL80211_ATTR_TIMED_OUT flag (and %NL80211_ATTR_MAC to indicate which
+ *    pending authentication timed out).
+ * @NL80211_CMD_ASSOCIATE: association request and notification; like
+ *    NL80211_CMD_AUTHENTICATE but for Association and Reassociation
+ *    (similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request,
+ *    MLME-ASSOCIATE.confirm or MLME-REASSOCIATE.confirm primitives).
+ * @NL80211_CMD_DEAUTHENTICATE: deauthentication request and notification; like
+ *    NL80211_CMD_AUTHENTICATE but for Deauthentication frames (similar to
+ *    MLME-DEAUTHENTICATION.request and MLME-DEAUTHENTICATE.indication
+ *    primitives).
+ * @NL80211_CMD_DISASSOCIATE: disassociation request and notification; like
+ *    NL80211_CMD_AUTHENTICATE but for Disassociation frames (similar to
+ *    MLME-DISASSOCIATE.request and MLME-DISASSOCIATE.indication primitives).
+ *
+ * @NL80211_CMD_MICHAEL_MIC_FAILURE: notification of a locally detected Michael
+ *    MIC (part of TKIP) failure; sent on the "mlme" multicast group; the
+ *    event includes %NL80211_ATTR_MAC to describe the source MAC address of
+ *    the frame with invalid MIC, %NL80211_ATTR_KEY_TYPE to show the key
+ *    type, %NL80211_ATTR_KEY_IDX to indicate the key identifier, and
+ *    %NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this
+ *    event matches with MLME-MICHAELMICFAILURE.indication() primitive
+ *
+ * @NL80211_CMD_JOIN_IBSS: Join a new IBSS -- given at least an SSID and a
+ *    FREQ attribute (for the initial frequency if no peer can be found)
+ *    and optionally a MAC (as BSSID) and FREQ_FIXED attribute if those
+ *    should be fixed rather than automatically determined. Can only be
+ *    executed on a network interface that is UP, and fixed BSSID/FREQ
+ *    may be rejected. Another optional parameter is the beacon interval,
+ *    given in the %NL80211_ATTR_BEACON_INTERVAL attribute, which if not
+ *    given defaults to 100 TU (102.4ms).
+ * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is
+ *    determined by the network interface.
+ *
+ * @NL80211_CMD_TESTMODE: testmode command, takes a wiphy (or ifindex) attribute
+ *    to identify the device, and the TESTDATA blob attribute to pass through
+ *    to the driver.
+ *
+ * @NL80211_CMD_CONNECT: connection request and notification; this command
+ *    requests to connect to a specified network but without separating
+ *    auth and assoc steps. For this, you need to specify the SSID in a
+ *    %NL80211_ATTR_SSID attribute, and can optionally specify the association
+ *    IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_MAC,
+ *    %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
+ *    %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and
+ *    %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT.
+ *    It is also sent as an event, with the BSSID and response IEs when the
+ *    connection is established or failed to be established. This can be
+ *    determined by the STATUS_CODE attribute.
+ * @NL80211_CMD_ROAM: request that the card roam (currently not implemented),
+ *    sent as an event when the card/driver roamed by itself.
+ * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify
+ *    userspace that a connection was dropped by the AP or due to other
+ *    reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and
+ *    %NL80211_ATTR_REASON_CODE attributes are used.
+ *
+ * @NL80211_CMD_SET_WIPHY_NETNS: Set a wiphy's netns. Note that all devices
+ *    associated with this wiphy must be down and will follow.
+ *
+ * @NL80211_CMD_REMAIN_ON_CHANNEL: Request to remain awake on the specified
+ *    channel for the specified amount of time. This can be used to do
+ *    off-channel operations like transmit a Public Action frame and wait for
+ *    a response while being associated to an AP on another channel.
+ *    %NL80211_ATTR_IFINDEX is used to specify which interface (and thus
+ *    radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the
+ *    frequency for the operation and %NL80211_ATTR_WIPHY_CHANNEL_TYPE may be
+ *    optionally used to specify additional channel parameters.
+ *    %NL80211_ATTR_DURATION is used to specify the duration in milliseconds
+ *    to remain on the channel. This command is also used as an event to
+ *    notify when the requested duration starts (it may take a while for the
+ *    driver to schedule this time due to other concurrent needs for the
+ *    radio).
+ *    When called, this operation returns a cookie (%NL80211_ATTR_COOKIE)
+ *    that will be included with any events pertaining to this request;
+ *    the cookie is also used to cancel the request.
+ * @NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL: This command can be used to cancel a
+ *    pending remain-on-channel duration if the desired operation has been
+ *    completed prior to expiration of the originally requested duration.
+ *    %NL80211_ATTR_WIPHY or %NL80211_ATTR_IFINDEX is used to specify the
+ *    radio. The %NL80211_ATTR_COOKIE attribute must be given as well to
+ *    uniquely identify the request.
+ *    This command is also used as an event to notify when a requested
+ *    remain-on-channel duration has expired.
+ *
+ * @NL80211_CMD_SET_TX_BITRATE_MASK: Set the mask of rates to be used in TX
+ *    rate selection. %NL80211_ATTR_IFINDEX is used to specify the interface
+ *    and @NL80211_ATTR_TX_RATES the set of allowed rates.
+ *
+ * @NL80211_CMD_REGISTER_FRAME: Register for receiving certain mgmt frames
+ *    (via @NL80211_CMD_FRAME) for processing in userspace. This command
+ *    requires an interface index, a frame type attribute (optional for
+ *    backward compatibility reasons, if not given assumes action frames)
+ *    and a match attribute containing the first few bytes of the frame
+ *    that should match, e.g. a single byte for only a category match or
+ *    four bytes for vendor frames including the OUI. The registration
+ *    cannot be dropped, but is removed automatically when the netlink
+ *    socket is closed. Multiple registrations can be made.
+ * @NL80211_CMD_REGISTER_ACTION: Alias for @NL80211_CMD_REGISTER_FRAME for
+ *    backward compatibility
+ * @NL80211_CMD_FRAME: Management frame TX request and RX notification. This
+ *    command is used both as a request to transmit a management frame and
+ *    as an event indicating reception of a frame that was not processed in
+ *    kernel code, but is for us (i.e., which may need to be processed in a
+ *    user space application). %NL80211_ATTR_FRAME is used to specify the
+ *    frame contents (including header). %NL80211_ATTR_WIPHY_FREQ (and
+ *    optionally %NL80211_ATTR_WIPHY_CHANNEL_TYPE) is used to indicate on
+ *    which channel the frame is to be transmitted or was received. This
+ *    channel has to be the current channel (remain-on-channel or the
+ *    operational channel). When called, this operation returns a cookie
+ *    (%NL80211_ATTR_COOKIE) that will be included with the TX status event
+ *    pertaining to the TX request.
+ * @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility.
+ * @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame
+ *    transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies
+ *    the TX command and %NL80211_ATTR_FRAME includes the contents of the
+ *    frame. %NL80211_ATTR_ACK flag is included if the recipient acknowledged
+ *    the frame.
+ * @NL80211_CMD_ACTION_TX_STATUS: Alias for @NL80211_CMD_FRAME_TX_STATUS for
+ *    backward compatibility.
+ * @NL80211_CMD_SET_CQM: Connection quality monitor configuration. This command
+ *    is used to configure connection quality monitoring notification trigger
+ *    levels.
+ * @NL80211_CMD_NOTIFY_CQM: Connection quality monitor notification. This
+ *    command is used as an event to indicate the that a trigger level was
+ *    reached.
+ * @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ
+ *    and %NL80211_ATTR_WIPHY_CHANNEL_TYPE) the given interface (identifed
+ *    by %NL80211_ATTR_IFINDEX) shall operate on.
+ *    In case multiple channels are supported by the device, the mechanism
+ *    with which it switches channels is implementation-defined.
+ *    When a monitor interface is given, it can only switch channel while
+ *    no other interfaces are operating to avoid disturbing the operation
+ *    of any other interfaces, and other interfaces will again take
+ *    precedence when they are used.
+ *
+ * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface.
+ *
+ * @NL80211_CMD_MAX: highest used command number
+ * @__NL80211_CMD_AFTER_LAST: internal use
+ */
+enum nl80211_commands {
+/* don't change the order or add anything inbetween, this is ABI! */
+    NL80211_CMD_UNSPEC,
+
+    NL80211_CMD_GET_WIPHY,        /* can dump */
+    NL80211_CMD_SET_WIPHY,
+    NL80211_CMD_NEW_WIPHY,
+    NL80211_CMD_DEL_WIPHY,
+
+    NL80211_CMD_GET_INTERFACE,    /* can dump */
+    NL80211_CMD_SET_INTERFACE,
+    NL80211_CMD_NEW_INTERFACE,
+    NL80211_CMD_DEL_INTERFACE,
+
+    NL80211_CMD_GET_KEY,
+    NL80211_CMD_SET_KEY,
+    NL80211_CMD_NEW_KEY,
+    NL80211_CMD_DEL_KEY,
+
+    NL80211_CMD_GET_BEACON,
+    NL80211_CMD_SET_BEACON,
+    NL80211_CMD_NEW_BEACON,
+    NL80211_CMD_DEL_BEACON,
+
+    NL80211_CMD_GET_STATION,
+    NL80211_CMD_SET_STATION,
+    NL80211_CMD_NEW_STATION,
+    NL80211_CMD_DEL_STATION,
+
+    NL80211_CMD_GET_MPATH,
+    NL80211_CMD_SET_MPATH,
+    NL80211_CMD_NEW_MPATH,
+    NL80211_CMD_DEL_MPATH,
+
+    NL80211_CMD_SET_BSS,
+
+    NL80211_CMD_SET_REG,
+    NL80211_CMD_REQ_SET_REG,
+
+    NL80211_CMD_GET_MESH_PARAMS,
+    NL80211_CMD_SET_MESH_PARAMS,
+
+    NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */,
+
+    NL80211_CMD_GET_REG,
+
+    NL80211_CMD_GET_SCAN,
+    NL80211_CMD_TRIGGER_SCAN,
+    NL80211_CMD_NEW_SCAN_RESULTS,
+    NL80211_CMD_SCAN_ABORTED,
+
+    NL80211_CMD_REG_CHANGE,
+
+    NL80211_CMD_AUTHENTICATE,
+    NL80211_CMD_ASSOCIATE,
+    NL80211_CMD_DEAUTHENTICATE,
+    NL80211_CMD_DISASSOCIATE,
+
+    NL80211_CMD_MICHAEL_MIC_FAILURE,
+
+    NL80211_CMD_REG_BEACON_HINT,
+
+    NL80211_CMD_JOIN_IBSS,
+    NL80211_CMD_LEAVE_IBSS,
+
+    NL80211_CMD_TESTMODE,
+
+    NL80211_CMD_CONNECT,
+    NL80211_CMD_ROAM,
+    NL80211_CMD_DISCONNECT,
+
+    NL80211_CMD_SET_WIPHY_NETNS,
+
+    NL80211_CMD_GET_SURVEY,
+    NL80211_CMD_NEW_SURVEY_RESULTS,
+
+    NL80211_CMD_SET_PMKSA,
+    NL80211_CMD_DEL_PMKSA,
+    NL80211_CMD_FLUSH_PMKSA,
+
+    NL80211_CMD_REMAIN_ON_CHANNEL,
+    NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
+
+    NL80211_CMD_SET_TX_BITRATE_MASK,
+
+    NL80211_CMD_REGISTER_FRAME,
+    NL80211_CMD_REGISTER_ACTION = NL80211_CMD_REGISTER_FRAME,
+    NL80211_CMD_FRAME,
+    NL80211_CMD_ACTION = NL80211_CMD_FRAME,
+    NL80211_CMD_FRAME_TX_STATUS,
+    NL80211_CMD_ACTION_TX_STATUS = NL80211_CMD_FRAME_TX_STATUS,
+
+    NL80211_CMD_SET_POWER_SAVE,
+    NL80211_CMD_GET_POWER_SAVE,
+
+    NL80211_CMD_SET_CQM,
+    NL80211_CMD_NOTIFY_CQM,
+
+    NL80211_CMD_SET_CHANNEL,
+    NL80211_CMD_SET_WDS_PEER,
+
+    /* add new commands above here */
+
+    /* used to define NL80211_CMD_MAX below */
+    __NL80211_CMD_AFTER_LAST,
+    NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
+};
+
+/*
+ * Allow user space programs to use #ifdef on new commands by defining them
+ * here
+ */
+#define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS
+#define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE
+#define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE
+#define NL80211_CMD_AUTHENTICATE NL80211_CMD_AUTHENTICATE
+#define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE
+#define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE
+#define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE
+#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT
+
+/**
+ * enum nl80211_attrs - nl80211 netlink attributes
+ *
+ * @NL80211_ATTR_UNSPEC: unspecified attribute to catch errors
+ *
+ * @NL80211_ATTR_WIPHY: index of wiphy to operate on, cf.
+ *    /sys/class/ieee80211/<phyname>/index
+ * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming)
+ * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters
+ * @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz
+ * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ
+ *    if HT20 or HT40 are allowed (i.e., 802.11n disabled if not included):
+ *    NL80211_CHAN_NO_HT = HT not allowed (i.e., same as not including
+ *        this attribute)
+ *    NL80211_CHAN_HT20 = HT20 only
+ *    NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel
+ *    NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel
+ * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is
+ *    less than or equal to the RTS threshold; allowed range: 1..255;
+ *    dot11ShortRetryLimit; u8
+ * @NL80211_ATTR_WIPHY_RETRY_LONG: TX retry limit for frames whose length is
+ *    greater than the RTS threshold; allowed range: 1..255;
+ *    dot11ShortLongLimit; u8
+ * @NL80211_ATTR_WIPHY_FRAG_THRESHOLD: fragmentation threshold, i.e., maximum
+ *    length in octets for frames; allowed range: 256..8000, disable
+ *    fragmentation with (u32)-1; dot11FragmentationThreshold; u32
+ * @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length
+ *    larger than or equal to this use RTS/CTS handshake); allowed range:
+ *    0..65536, disable with (u32)-1; dot11RTSThreshold; u32
+ * @NL80211_ATTR_WIPHY_COVERAGE_CLASS: Coverage Class as defined by IEEE 802.11
+ *    section 7.3.2.9; dot11CoverageClass; u8
+ *
+ * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
+ * @NL80211_ATTR_IFNAME: network interface name
+ * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype
+ *
+ * @NL80211_ATTR_MAC: MAC address (various uses)
+ *
+ * @NL80211_ATTR_KEY_DATA: (temporal) key data; for TKIP this consists of
+ *    16 bytes encryption key followed by 8 bytes each for TX and RX MIC
+ *    keys
+ * @NL80211_ATTR_KEY_IDX: key ID (u8, 0-3)
+ * @NL80211_ATTR_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11
+ *    section 7.3.2.25.1, e.g. 0x000FAC04)
+ * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and
+ *    CCMP keys, each six bytes in little endian
+ *
+ * @NL80211_ATTR_BEACON_INTERVAL: beacon interval in TU
+ * @NL80211_ATTR_DTIM_PERIOD: DTIM period for beaconing
+ * @NL80211_ATTR_BEACON_HEAD: portion of the beacon before the TIM IE
+ * @NL80211_ATTR_BEACON_TAIL: portion of the beacon after the TIM IE
+ *
+ * @NL80211_ATTR_STA_AID: Association ID for the station (u16)
+ * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of
+ *    &enum nl80211_sta_flags (deprecated, use %NL80211_ATTR_STA_FLAGS2)
+ * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by
+ *    IEEE 802.11 7.3.1.6 (u16).
+ * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported
+ *    rates as defined by IEEE 802.11 7.3.2.2 but without the length
+ *    restriction (at most %NL80211_MAX_SUPP_RATES).
+ * @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station
+ *    to, or the AP interface the station was originally added to to.
+ * @NL80211_ATTR_STA_INFO: information about a station, part of station info
+ *    given for %NL80211_CMD_GET_STATION, nested attribute containing
+ *    info as possible, see &enum nl80211_sta_info.
+ *
+ * @NL80211_ATTR_WIPHY_BANDS: Information about an operating bands,
+ *    consisting of a nested array.
+ *
+ * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes).
+ * @NL80211_ATTR_PLINK_ACTION: action to perform on the mesh peer link.
+ * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path.
+ * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path
+ *     info given for %NL80211_CMD_GET_MPATH, nested attribute described at
+ *    &enum nl80211_mpath_info.
+ *
+ * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of
+ *      &enum nl80211_mntr_flags.
+ *
+ * @NL80211_ATTR_REG_ALPHA2: an ISO-3166-alpha2 country code for which the
+ *     current regulatory domain should be set to or is already set to.
+ *     For example, 'CR', for Costa Rica. This attribute is used by the kernel
+ *     to query the CRDA to retrieve one regulatory domain. This attribute can
+ *     also be used by userspace to query the kernel for the currently set
+ *     regulatory domain. We chose an alpha2 as that is also used by the
+ *     IEEE-802.11d country information element to identify a country.
+ *     Users can also simply ask the wireless core to set regulatory domain
+ *     to a specific alpha2.
+ * @NL80211_ATTR_REG_RULES: a nested array of regulatory domain regulatory
+ *    rules.
+ *
+ * @NL80211_ATTR_BSS_CTS_PROT: whether CTS protection is enabled (u8, 0 or 1)
+ * @NL80211_ATTR_BSS_SHORT_PREAMBLE: whether short preamble is enabled
+ *    (u8, 0 or 1)
+ * @NL80211_ATTR_BSS_SHORT_SLOT_TIME: whether short slot time enabled
+ *    (u8, 0 or 1)
+ * @NL80211_ATTR_BSS_BASIC_RATES: basic rates, array of basic
+ *    rates in format defined by IEEE 802.11 7.3.2.2 but without the length
+ *    restriction (at most %NL80211_MAX_SUPP_RATES).
+ *
+ * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from
+ *    association request when used with NL80211_CMD_NEW_STATION)
+ *
+ * @NL80211_ATTR_SUPPORTED_IFTYPES: nested attribute containing all
+ *    supported interface types, each a flag attribute with the number
+ *    of the interface mode.
+ *
+ * @NL80211_ATTR_MGMT_SUBTYPE: Management frame subtype for
+ *    %NL80211_CMD_SET_MGMT_EXTRA_IE.
+ *
+ * @NL80211_ATTR_IE: Information element(s) data (used, e.g., with
+ *    %NL80211_CMD_SET_MGMT_EXTRA_IE).
+ *
+ * @NL80211_ATTR_MAX_NUM_SCAN_SSIDS: number of SSIDs you can scan with
+ *    a single scan request, a wiphy attribute.
+ * @NL80211_ATTR_MAX_SCAN_IE_LEN: maximum length of information elements
+ *    that can be added to a scan request
+ *
+ * @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz)
+ * @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive
+ *    scanning and include a zero-length SSID (wildcard) for wildcard scan
+ * @NL80211_ATTR_BSS: scan result BSS
+ *
+ * @NL80211_ATTR_REG_INITIATOR: indicates who requested the regulatory domain
+ *     currently in effect. This could be any of the %NL80211_REGDOM_SET_BY_*
+ * @NL80211_ATTR_REG_TYPE: indicates the type of the regulatory domain currently
+ *     set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*)
+ *
+ * @NL80211_ATTR_SUPPORTED_COMMANDS: wiphy attribute that specifies
+ *    an array of command numbers (i.e. a mapping index to command number)
+ *    that the driver for the given wiphy supports.
+ *
+ * @NL80211_ATTR_FRAME: frame data (binary attribute), including frame header
+ *    and body, but not FCS; used, e.g., with NL80211_CMD_AUTHENTICATE and
+ *    NL80211_CMD_ASSOCIATE events
+ * @NL80211_ATTR_SSID: SSID (binary attribute, 0..32 octets)
+ * @NL80211_ATTR_AUTH_TYPE: AuthenticationType, see &enum nl80211_auth_type,
+ *    represented as a u32
+ * @NL80211_ATTR_REASON_CODE: ReasonCode for %NL80211_CMD_DEAUTHENTICATE and
+ *    %NL80211_CMD_DISASSOCIATE, u16
+ *
+ * @NL80211_ATTR_KEY_TYPE: Key Type, see &enum nl80211_key_type, represented as
+ *    a u32
+ *
+ * @NL80211_ATTR_FREQ_BEFORE: A channel which has suffered a regulatory change
+ *     due to considerations from a beacon hint. This attribute reflects
+ *     the state of the channel _before_ the beacon hint processing. This
+ *     attributes consists of a nested attribute containing
+ *     NL80211_FREQUENCY_ATTR_*
+ * @NL80211_ATTR_FREQ_AFTER: A channel which has suffered a regulatory change
+ *     due to considerations from a beacon hint. This attribute reflects
+ *     the state of the channel _after_ the beacon hint processing. This
+ *     attributes consists of a nested attribute containing
+ *     NL80211_FREQUENCY_ATTR_*
+ *
+ * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported
+ *    cipher suites
+ *
+ * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look
+ *    for other networks on different channels
+ *
+ * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this
+ *    is used, e.g., with %NL80211_CMD_AUTHENTICATE event
+ *
+ * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
+ *    used for the association (&enum nl80211_mfp, represented as a u32);
+ *    this attribute can be used
+ *    with %NL80211_CMD_ASSOCIATE request
+ *
+ * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
+ *    &struct nl80211_sta_flag_update.
+ *
+ * @NL80211_ATTR_CONTROL_PORT: A flag indicating whether user space controls
+ *    IEEE 802.1X port, i.e., sets/clears %NL80211_STA_FLAG_AUTHORIZED, in
+ *    station mode. If the flag is included in %NL80211_CMD_ASSOCIATE
+ *    request, the driver will assume that the port is unauthorized until
+ *    authorized by user space. Otherwise, port is marked authorized by
+ *    default in station mode.
+ * @NL80211_ATTR_CONTROL_PORT_ETHERTYPE: A 16-bit value indicating the
+ *    ethertype that will be used for key negotiation. It can be
+ *    specified with the associate and connect commands. If it is not
+ *    specified, the value defaults to 0x888E (PAE, 802.1X). This
+ *    attribute is also used as a flag in the wiphy information to
+ *    indicate that protocols other than PAE are supported.
+ * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with
+ *    %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom
+ *    ethertype frames used for key negotiation must not be encrypted.
+ *
+ * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver.
+ *    We recommend using nested, driver-specific attributes within this.
+ *
+ * @NL80211_ATTR_DISCONNECTED_BY_AP: A flag indicating that the DISCONNECT
+ *    event was due to the AP disconnecting the station, and not due to
+ *    a local disconnect request.
+ * @NL80211_ATTR_STATUS_CODE: StatusCode for the %NL80211_CMD_CONNECT
+ *    event (u16)
+ * @NL80211_ATTR_PRIVACY: Flag attribute, used with connect(), indicating
+ *    that protected APs should be used.
+ *
+ * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT and ASSOCIATE to
+ *    indicate which unicast key ciphers will be used with the connection
+ *    (an array of u32).
+ * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT and ASSOCIATE to indicate
+ *    which group key cipher will be used with the connection (a u32).
+ * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT and ASSOCIATE to indicate
+ *    which WPA version(s) the AP we want to associate with is using
+ *    (a u32 with flags from &enum nl80211_wpa_versions).
+ * @NL80211_ATTR_AKM_SUITES: Used with CONNECT and ASSOCIATE to indicate
+ *    which key management algorithm(s) to use (an array of u32).
+ *
+ * @NL80211_ATTR_REQ_IE: (Re)association request information elements as
+ *    sent out by the card, for ROAM and successful CONNECT events.
+ * @NL80211_ATTR_RESP_IE: (Re)association response information elements as
+ *    sent by peer, for ROAM and successful CONNECT events.
+ *
+ * @NL80211_ATTR_PREV_BSSID: previous BSSID, to be used by in ASSOCIATE
+ *    commands to specify using a reassociate frame
+ *
+ * @NL80211_ATTR_KEY: key information in a nested attribute with
+ *    %NL80211_KEY_* sub-attributes
+ * @NL80211_ATTR_KEYS: array of keys for static WEP keys for connect()
+ *    and join_ibss(), key information is in a nested attribute each
+ *    with %NL80211_KEY_* sub-attributes
+ *
+ * @NL80211_ATTR_PID: Process ID of a network namespace.
+ *
+ * @NL80211_ATTR_GENERATION: Used to indicate consistent snapshots for
+ *    dumps. This number increases whenever the object list being
+ *    dumped changes, and as such userspace can verify that it has
+ *    obtained a complete and consistent snapshot by verifying that
+ *    all dump messages contain the same generation number. If it
+ *    changed then the list changed and the dump should be repeated
+ *    completely from scratch.
+ *
+ * @NL80211_ATTR_4ADDR: Use 4-address frames on a virtual interface
+ *
+ * @NL80211_ATTR_SURVEY_INFO: survey information about a channel, part of
+ *      the survey response for %NL80211_CMD_GET_SURVEY, nested attribute
+ *      containing info as possible, see &enum survey_info.
+ *
+ * @NL80211_ATTR_PMKID: PMK material for PMKSA caching.
+ * @NL80211_ATTR_MAX_NUM_PMKIDS: maximum number of PMKIDs a firmware can
+ *    cache, a wiphy attribute.
+ *
+ * @NL80211_ATTR_DURATION: Duration of an operation in milliseconds, u32.
+ *
+ * @NL80211_ATTR_COOKIE: Generic 64-bit cookie to identify objects.
+ *
+ * @NL80211_ATTR_TX_RATES: Nested set of attributes
+ *    (enum nl80211_tx_rate_attributes) describing TX rates per band. The
+ *    enum nl80211_band value is used as the index (nla_type() of the nested
+ *    data. If a band is not included, it will be configured to allow all
+ *    rates based on negotiated supported rates information. This attribute
+ *    is used with %NL80211_CMD_SET_TX_BITRATE_MASK.
+ *
+ * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain
+ *    at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME.
+ * @NL80211_ATTR_FRAME_TYPE: A u16 indicating the frame type/subtype for the
+ *    @NL80211_CMD_REGISTER_FRAME command.
+ * @NL80211_ATTR_TX_FRAME_TYPES: wiphy capability attribute, which is a
+ *    nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing
+ *    information about which frame types can be transmitted with
+ *    %NL80211_CMD_FRAME.
+ * @NL80211_ATTR_RX_FRAME_TYPES: wiphy capability attribute, which is a
+ *    nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing
+ *    information about which frame types can be registered for RX.
+ *
+ * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was
+ *    acknowledged by the recipient.
+ *
+ * @NL80211_ATTR_CQM: connection quality monitor configuration in a
+ *    nested attribute with %NL80211_ATTR_CQM_* sub-attributes.
+ *
+ * @NL80211_ATTR_LOCAL_STATE_CHANGE: Flag attribute to indicate that a command
+ *    is requesting a local authentication/association state change without
+ *    invoking actual management frame exchange. This can be used with
+ *    NL80211_CMD_AUTHENTICATE, NL80211_CMD_DEAUTHENTICATE,
+ *    NL80211_CMD_DISASSOCIATE.
+ *
+ * @NL80211_ATTR_AP_ISOLATE: (AP mode) Do not forward traffic between stations
+ *    connected to this BSS.
+ *
+ * @NL80211_ATTR_WIPHY_TX_POWER_SETTING: Transmit power setting type. See
+ *      &enum nl80211_tx_power_setting for possible values.
+ * @NL80211_ATTR_WIPHY_TX_POWER_LEVEL: Transmit power level in signed mBm units.
+ *      This is used in association with @NL80211_ATTR_WIPHY_TX_POWER_SETTING
+ *      for non-automatic settings.
+ *
+ * @NL80211_ATTR_SUPPORT_IBSS_RSN: The device supports IBSS RSN, which mostly
+ *    means support for per-station GTKs.
+ *
+ * @NL80211_ATTR_MAX: highest attribute number currently defined
+ * @__NL80211_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_attrs {
+/* don't change the order or add anything inbetween, this is ABI! */
+    NL80211_ATTR_UNSPEC,
+
+    NL80211_ATTR_WIPHY,
+    NL80211_ATTR_WIPHY_NAME,
+
+    NL80211_ATTR_IFINDEX,
+    NL80211_ATTR_IFNAME,
+    NL80211_ATTR_IFTYPE,
+
+    NL80211_ATTR_MAC,
+
+    NL80211_ATTR_KEY_DATA,
+    NL80211_ATTR_KEY_IDX,
+    NL80211_ATTR_KEY_CIPHER,
+    NL80211_ATTR_KEY_SEQ,
+    NL80211_ATTR_KEY_DEFAULT,
+
+    NL80211_ATTR_BEACON_INTERVAL,
+    NL80211_ATTR_DTIM_PERIOD,
+    NL80211_ATTR_BEACON_HEAD,
+    NL80211_ATTR_BEACON_TAIL,
+
+    NL80211_ATTR_STA_AID,
+    NL80211_ATTR_STA_FLAGS,
+    NL80211_ATTR_STA_LISTEN_INTERVAL,
+    NL80211_ATTR_STA_SUPPORTED_RATES,
+    NL80211_ATTR_STA_VLAN,
+    NL80211_ATTR_STA_INFO,
+
+    NL80211_ATTR_WIPHY_BANDS,
+
+    NL80211_ATTR_MNTR_FLAGS,
+
+    NL80211_ATTR_MESH_ID,
+    NL80211_ATTR_STA_PLINK_ACTION,
+    NL80211_ATTR_MPATH_NEXT_HOP,
+    NL80211_ATTR_MPATH_INFO,
+
+    NL80211_ATTR_BSS_CTS_PROT,
+    NL80211_ATTR_BSS_SHORT_PREAMBLE,
+    NL80211_ATTR_BSS_SHORT_SLOT_TIME,
+
+    NL80211_ATTR_HT_CAPABILITY,
+
+    NL80211_ATTR_SUPPORTED_IFTYPES,
+
+    NL80211_ATTR_REG_ALPHA2,
+    NL80211_ATTR_REG_RULES,
+
+    NL80211_ATTR_MESH_PARAMS,
+
+    NL80211_ATTR_BSS_BASIC_RATES,
+
+    NL80211_ATTR_WIPHY_TXQ_PARAMS,
+    NL80211_ATTR_WIPHY_FREQ,
+    NL80211_ATTR_WIPHY_CHANNEL_TYPE,
+
+    NL80211_ATTR_KEY_DEFAULT_MGMT,
+
+    NL80211_ATTR_MGMT_SUBTYPE,
+    NL80211_ATTR_IE,
+
+    NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
+
+    NL80211_ATTR_SCAN_FREQUENCIES,
+    NL80211_ATTR_SCAN_SSIDS,
+    NL80211_ATTR_GENERATION, /* replaces old SCAN_GENERATION */
+    NL80211_ATTR_BSS,
+
+    NL80211_ATTR_REG_INITIATOR,
+    NL80211_ATTR_REG_TYPE,
+
+    NL80211_ATTR_SUPPORTED_COMMANDS,
+
+    NL80211_ATTR_FRAME,
+    NL80211_ATTR_SSID,
+    NL80211_ATTR_AUTH_TYPE,
+    NL80211_ATTR_REASON_CODE,
+
+    NL80211_ATTR_KEY_TYPE,
+
+    NL80211_ATTR_MAX_SCAN_IE_LEN,
+    NL80211_ATTR_CIPHER_SUITES,
+
+    NL80211_ATTR_FREQ_BEFORE,
+    NL80211_ATTR_FREQ_AFTER,
+
+    NL80211_ATTR_FREQ_FIXED,
+
+
+    NL80211_ATTR_WIPHY_RETRY_SHORT,
+    NL80211_ATTR_WIPHY_RETRY_LONG,
+    NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+    NL80211_ATTR_WIPHY_RTS_THRESHOLD,
+
+    NL80211_ATTR_TIMED_OUT,
+
+    NL80211_ATTR_USE_MFP,
+
+    NL80211_ATTR_STA_FLAGS2,
+
+    NL80211_ATTR_CONTROL_PORT,
+
+    NL80211_ATTR_TESTDATA,
+
+    NL80211_ATTR_PRIVACY,
+
+    NL80211_ATTR_DISCONNECTED_BY_AP,
+    NL80211_ATTR_STATUS_CODE,
+
+    NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
+    NL80211_ATTR_CIPHER_SUITE_GROUP,
+    NL80211_ATTR_WPA_VERSIONS,
+    NL80211_ATTR_AKM_SUITES,
+
+    NL80211_ATTR_REQ_IE,
+    NL80211_ATTR_RESP_IE,
+
+    NL80211_ATTR_PREV_BSSID,
+
+    NL80211_ATTR_KEY,
+    NL80211_ATTR_KEYS,
+
+    NL80211_ATTR_PID,
+
+    NL80211_ATTR_4ADDR,
+
+    NL80211_ATTR_SURVEY_INFO,
+
+    NL80211_ATTR_PMKID,
+    NL80211_ATTR_MAX_NUM_PMKIDS,
+
+    NL80211_ATTR_DURATION,
+
+    NL80211_ATTR_COOKIE,
+
+    NL80211_ATTR_WIPHY_COVERAGE_CLASS,
+
+    NL80211_ATTR_TX_RATES,
+
+    NL80211_ATTR_FRAME_MATCH,
+
+    NL80211_ATTR_ACK,
+
+    NL80211_ATTR_PS_STATE,
+
+    NL80211_ATTR_CQM,
+
+    NL80211_ATTR_LOCAL_STATE_CHANGE,
+
+    NL80211_ATTR_AP_ISOLATE,
+
+    NL80211_ATTR_WIPHY_TX_POWER_SETTING,
+    NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
+
+    NL80211_ATTR_TX_FRAME_TYPES,
+    NL80211_ATTR_RX_FRAME_TYPES,
+    NL80211_ATTR_FRAME_TYPE,
+
+    NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
+    NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT,
+
+    NL80211_ATTR_SUPPORT_IBSS_RSN,
+
+    /* add attributes here, update the policy in nl80211.c */
+
+    __NL80211_ATTR_AFTER_LAST,
+    NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
+};
+
+/* source-level API compatibility */
+#define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION
+
+/*
+ * Allow user space programs to use #ifdef on new attributes by defining them
+ * here
+ */
+#define NL80211_CMD_CONNECT NL80211_CMD_CONNECT
+#define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY
+#define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES
+#define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS
+#define NL80211_ATTR_WIPHY_FREQ NL80211_ATTR_WIPHY_FREQ
+#define NL80211_ATTR_WIPHY_CHANNEL_TYPE NL80211_ATTR_WIPHY_CHANNEL_TYPE
+#define NL80211_ATTR_MGMT_SUBTYPE NL80211_ATTR_MGMT_SUBTYPE
+#define NL80211_ATTR_IE NL80211_ATTR_IE
+#define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR
+#define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE
+#define NL80211_ATTR_FRAME NL80211_ATTR_FRAME
+#define NL80211_ATTR_SSID NL80211_ATTR_SSID
+#define NL80211_ATTR_AUTH_TYPE NL80211_ATTR_AUTH_TYPE
+#define NL80211_ATTR_REASON_CODE NL80211_ATTR_REASON_CODE
+#define NL80211_ATTR_CIPHER_SUITES_PAIRWISE NL80211_ATTR_CIPHER_SUITES_PAIRWISE
+#define NL80211_ATTR_CIPHER_SUITE_GROUP NL80211_ATTR_CIPHER_SUITE_GROUP
+#define NL80211_ATTR_WPA_VERSIONS NL80211_ATTR_WPA_VERSIONS
+#define NL80211_ATTR_AKM_SUITES NL80211_ATTR_AKM_SUITES
+#define NL80211_ATTR_KEY NL80211_ATTR_KEY
+#define NL80211_ATTR_KEYS NL80211_ATTR_KEYS
+
+#define NL80211_MAX_SUPP_RATES            32
+#define NL80211_MAX_SUPP_REG_RULES        32
+#define NL80211_TKIP_DATA_OFFSET_ENCR_KEY    0
+#define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY    16
+#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY    24
+#define NL80211_HT_CAPABILITY_LEN        26
+
+#define NL80211_MAX_NR_CIPHER_SUITES        5
+#define NL80211_MAX_NR_AKM_SUITES        2
+
+/**
+ * enum nl80211_iftype - (virtual) interface types
+ *
+ * @NL80211_IFTYPE_UNSPECIFIED: unspecified type, driver decides
+ * @NL80211_IFTYPE_ADHOC: independent BSS member
+ * @NL80211_IFTYPE_STATION: managed BSS member
+ * @NL80211_IFTYPE_AP: access point
+ * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points
+ * @NL80211_IFTYPE_WDS: wireless distribution interface
+ * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames
+ * @NL80211_IFTYPE_MESH_POINT: mesh point
+ * @NL80211_IFTYPE_P2P_CLIENT: P2P client
+ * @NL80211_IFTYPE_P2P_GO: P2P group owner
+ * @NL80211_IFTYPE_MAX: highest interface type number currently defined
+ * @NUM_NL80211_IFTYPES: number of defined interface types
+ *
+ * These values are used with the %NL80211_ATTR_IFTYPE
+ * to set the type of an interface.
+ *
+ */
+enum nl80211_iftype {
+    NL80211_IFTYPE_UNSPECIFIED,
+    NL80211_IFTYPE_ADHOC,
+    NL80211_IFTYPE_STATION,
+    NL80211_IFTYPE_AP,
+    NL80211_IFTYPE_AP_VLAN,
+    NL80211_IFTYPE_WDS,
+    NL80211_IFTYPE_MONITOR,
+    NL80211_IFTYPE_MESH_POINT,
+    NL80211_IFTYPE_P2P_CLIENT,
+    NL80211_IFTYPE_P2P_GO,
+
+    /* keep last */
+    NUM_NL80211_IFTYPES,
+    NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
+};
+
+/**
+ * enum nl80211_sta_flags - station flags
+ *
+ * Station flags. When a station is added to an AP interface, it is
+ * assumed to be already associated (and hence authenticated.)
+ *
+ * @__NL80211_STA_FLAG_INVALID: attribute number 0 is reserved
+ * @NL80211_STA_FLAG_AUTHORIZED: station is authorized (802.1X)
+ * @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames
+ *    with short barker preamble
+ * @NL80211_STA_FLAG_WME: station is WME/QoS capable
+ * @NL80211_STA_FLAG_MFP: station uses management frame protection
+ * @NL80211_STA_FLAG_MAX: highest station flag number currently defined
+ * @__NL80211_STA_FLAG_AFTER_LAST: internal use
+ */
+enum nl80211_sta_flags {
+    __NL80211_STA_FLAG_INVALID,
+    NL80211_STA_FLAG_AUTHORIZED,
+    NL80211_STA_FLAG_SHORT_PREAMBLE,
+    NL80211_STA_FLAG_WME,
+    NL80211_STA_FLAG_MFP,
+
+    /* keep last */
+    __NL80211_STA_FLAG_AFTER_LAST,
+    NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1
+};
+
+/**
+ * struct nl80211_sta_flag_update - station flags mask/set
+ * @mask: mask of station flags to set
+ * @set: which values to set them to
+ *
+ * Both mask and set contain bits as per &enum nl80211_sta_flags.
+ */
+struct nl80211_sta_flag_update {
+    __u32 mask;
+    __u32 set;
+} __attribute__((packed));
+
+/**
+ * enum nl80211_rate_info - bitrate information
+ *
+ * These attribute types are used with %NL80211_STA_INFO_TXRATE
+ * when getting information about the bitrate of a station.
+ *
+ * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s)
+ * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8)
+ * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate
+ * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval
+ * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined
+ * @__NL80211_RATE_INFO_AFTER_LAST: internal use
+ */
+enum nl80211_rate_info {
+    __NL80211_RATE_INFO_INVALID,
+    NL80211_RATE_INFO_BITRATE,
+    NL80211_RATE_INFO_MCS,
+    NL80211_RATE_INFO_40_MHZ_WIDTH,
+    NL80211_RATE_INFO_SHORT_GI,
+
+    /* keep last */
+    __NL80211_RATE_INFO_AFTER_LAST,
+    NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_sta_info - station information
+ *
+ * These attribute types are used with %NL80211_ATTR_STA_INFO
+ * when getting information about a station.
+ *
+ * @__NL80211_STA_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs)
+ * @NL80211_STA_INFO_RX_BYTES: total received bytes (u32, from this station)
+ * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station)
+ * @__NL80211_STA_INFO_AFTER_LAST: internal
+ * @NL80211_STA_INFO_MAX: highest possible station info attribute
+ * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm)
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute
+ *     containing info as possible, see &enum nl80211_sta_info_txrate.
+ * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station)
+ * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this
+ *    station)
+ * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station)
+ * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station)
+ */
+enum nl80211_sta_info {
+    __NL80211_STA_INFO_INVALID,
+    NL80211_STA_INFO_INACTIVE_TIME,
+    NL80211_STA_INFO_RX_BYTES,
+    NL80211_STA_INFO_TX_BYTES,
+    NL80211_STA_INFO_LLID,
+    NL80211_STA_INFO_PLID,
+    NL80211_STA_INFO_PLINK_STATE,
+    NL80211_STA_INFO_SIGNAL,
+    NL80211_STA_INFO_TX_BITRATE,
+    NL80211_STA_INFO_RX_PACKETS,
+    NL80211_STA_INFO_TX_PACKETS,
+    NL80211_STA_INFO_TX_RETRIES,
+    NL80211_STA_INFO_TX_FAILED,
+
+    /* keep last */
+    __NL80211_STA_INFO_AFTER_LAST,
+    NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_mpath_flags - nl80211 mesh path flags
+ *
+ * @NL80211_MPATH_FLAG_ACTIVE: the mesh path is active
+ * @NL80211_MPATH_FLAG_RESOLVING: the mesh path discovery process is running
+ * @NL80211_MPATH_FLAG_SN_VALID: the mesh path contains a valid SN
+ * @NL80211_MPATH_FLAG_FIXED: the mesh path has been manually set
+ * @NL80211_MPATH_FLAG_RESOLVED: the mesh path discovery process succeeded
+ */
+enum nl80211_mpath_flags {
+    NL80211_MPATH_FLAG_ACTIVE =    1<<0,
+    NL80211_MPATH_FLAG_RESOLVING =    1<<1,
+    NL80211_MPATH_FLAG_SN_VALID =    1<<2,
+    NL80211_MPATH_FLAG_FIXED =    1<<3,
+    NL80211_MPATH_FLAG_RESOLVED =    1<<4,
+};
+
+/**
+ * enum nl80211_mpath_info - mesh path information
+ *
+ * These attribute types are used with %NL80211_ATTR_MPATH_INFO when getting
+ * information about a mesh path.
+ *
+ * @__NL80211_MPATH_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_MPATH_INFO_FRAME_QLEN: number of queued frames for this destination
+ * @NL80211_MPATH_INFO_SN: destination sequence number
+ * @NL80211_MPATH_INFO_METRIC: metric (cost) of this mesh path
+ * @NL80211_MPATH_INFO_EXPTIME: expiration time for the path, in msec from now
+ * @NL80211_MPATH_INFO_FLAGS: mesh path flags, enumerated in
+ *     &enum nl80211_mpath_flags;
+ * @NL80211_MPATH_INFO_DISCOVERY_TIMEOUT: total path discovery timeout, in msec
+ * @NL80211_MPATH_INFO_DISCOVERY_RETRIES: mesh path discovery retries
+ * @NL80211_MPATH_INFO_MAX: highest mesh path information attribute number
+ *    currently defind
+ * @__NL80211_MPATH_INFO_AFTER_LAST: internal use
+ */
+enum nl80211_mpath_info {
+    __NL80211_MPATH_INFO_INVALID,
+    NL80211_MPATH_INFO_FRAME_QLEN,
+    NL80211_MPATH_INFO_SN,
+    NL80211_MPATH_INFO_METRIC,
+    NL80211_MPATH_INFO_EXPTIME,
+    NL80211_MPATH_INFO_FLAGS,
+    NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
+    NL80211_MPATH_INFO_DISCOVERY_RETRIES,
+
+    /* keep last */
+    __NL80211_MPATH_INFO_AFTER_LAST,
+    NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_band_attr - band attributes
+ * @__NL80211_BAND_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_BAND_ATTR_FREQS: supported frequencies in this band,
+ *    an array of nested frequency attributes
+ * @NL80211_BAND_ATTR_RATES: supported bitrates in this band,
+ *    an array of nested bitrate attributes
+ * @NL80211_BAND_ATTR_HT_MCS_SET: 16-byte attribute containing the MCS set as
+ *    defined in 802.11n
+ * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE
+ * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n
+ * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n
+ * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined
+ * @__NL80211_BAND_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_band_attr {
+    __NL80211_BAND_ATTR_INVALID,
+    NL80211_BAND_ATTR_FREQS,
+    NL80211_BAND_ATTR_RATES,
+
+    NL80211_BAND_ATTR_HT_MCS_SET,
+    NL80211_BAND_ATTR_HT_CAPA,
+    NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
+    NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
+
+    /* keep last */
+    __NL80211_BAND_ATTR_AFTER_LAST,
+    NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1
+};
+
+#define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA
+
+/**
+ * enum nl80211_frequency_attr - frequency attributes
+ * @__NL80211_FREQUENCY_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz
+ * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current
+ *    regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_PASSIVE_SCAN: Only passive scanning is
+ *    permitted on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted
+ *    on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory
+ *    on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm
+ *    (100 * dBm).
+ * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
+ *    currently defined
+ * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_frequency_attr {
+    __NL80211_FREQUENCY_ATTR_INVALID,
+    NL80211_FREQUENCY_ATTR_FREQ,
+    NL80211_FREQUENCY_ATTR_DISABLED,
+    NL80211_FREQUENCY_ATTR_PASSIVE_SCAN,
+    NL80211_FREQUENCY_ATTR_NO_IBSS,
+    NL80211_FREQUENCY_ATTR_RADAR,
+    NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
+
+    /* keep last */
+    __NL80211_FREQUENCY_ATTR_AFTER_LAST,
+    NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1
+};
+
+#define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER
+
+/**
+ * enum nl80211_bitrate_attr - bitrate attributes
+ * @__NL80211_BITRATE_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_BITRATE_ATTR_RATE: Bitrate in units of 100 kbps
+ * @NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE: Short preamble supported
+ *    in 2.4 GHz band.
+ * @NL80211_BITRATE_ATTR_MAX: highest bitrate attribute number
+ *    currently defined
+ * @__NL80211_BITRATE_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_bitrate_attr {
+    __NL80211_BITRATE_ATTR_INVALID,
+    NL80211_BITRATE_ATTR_RATE,
+    NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE,
+
+    /* keep last */
+    __NL80211_BITRATE_ATTR_AFTER_LAST,
+    NL80211_BITRATE_ATTR_MAX = __NL80211_BITRATE_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_initiator - Indicates the initiator of a reg domain request
+ * @NL80211_REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world
+ *     regulatory domain.
+ * @NL80211_REGDOM_SET_BY_USER: User asked the wireless core to set the
+ *     regulatory domain.
+ * @NL80211_REGDOM_SET_BY_DRIVER: a wireless drivers has hinted to the
+ *     wireless core it thinks its knows the regulatory domain we should be in.
+ * @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an
+ *     802.11 country information element with regulatory information it
+ *     thinks we should consider.
+ */
+enum nl80211_reg_initiator {
+    NL80211_REGDOM_SET_BY_CORE,
+    NL80211_REGDOM_SET_BY_USER,
+    NL80211_REGDOM_SET_BY_DRIVER,
+    NL80211_REGDOM_SET_BY_COUNTRY_IE,
+};
+
+/**
+ * enum nl80211_reg_type - specifies the type of regulatory domain
+ * @NL80211_REGDOM_TYPE_COUNTRY: the regulatory domain set is one that pertains
+ *    to a specific country. When this is set you can count on the
+ *    ISO / IEC 3166 alpha2 country code being valid.
+ * @NL80211_REGDOM_TYPE_WORLD: the regulatory set domain is the world regulatory
+ *     domain.
+ * @NL80211_REGDOM_TYPE_CUSTOM_WORLD: the regulatory domain set is a custom
+ *     driver specific world regulatory domain. These do not apply system-wide
+ *     and are only applicable to the individual devices which have requested
+ *     them to be applied.
+ * @NL80211_REGDOM_TYPE_INTERSECTION: the regulatory domain set is the product
+ *    of an intersection between two regulatory domains -- the previously
+ *    set regulatory domain on the system and the last accepted regulatory
+ *    domain request to be processed.
+ */
+enum nl80211_reg_type {
+    NL80211_REGDOM_TYPE_COUNTRY,
+    NL80211_REGDOM_TYPE_WORLD,
+    NL80211_REGDOM_TYPE_CUSTOM_WORLD,
+    NL80211_REGDOM_TYPE_INTERSECTION,
+};
+
+/**
+ * enum nl80211_reg_rule_attr - regulatory rule attributes
+ * @__NL80211_REG_RULE_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional
+ *     considerations for a given frequency range. These are the
+ *     &enum nl80211_reg_rule_flags.
+ * @NL80211_ATTR_FREQ_RANGE_START: starting frequencry for the regulatory
+ *     rule in KHz. This is not a center of frequency but an actual regulatory
+ *     band edge.
+ * @NL80211_ATTR_FREQ_RANGE_END: ending frequency for the regulatory rule
+ *     in KHz. This is not a center a frequency but an actual regulatory
+ *     band edge.
+ * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this
+ *     frequency range, in KHz.
+ * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain
+ *     for a given frequency range. The value is in mBi (100 * dBi).
+ *     If you don't have one then don't send this.
+ * @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for
+ *     a given frequency range. The value is in mBm (100 * dBm).
+ * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number
+ *    currently defined
+ * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_reg_rule_attr {
+    __NL80211_REG_RULE_ATTR_INVALID,
+    NL80211_ATTR_REG_RULE_FLAGS,
+
+    NL80211_ATTR_FREQ_RANGE_START,
+    NL80211_ATTR_FREQ_RANGE_END,
+    NL80211_ATTR_FREQ_RANGE_MAX_BW,
+
+    NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
+    NL80211_ATTR_POWER_RULE_MAX_EIRP,
+
+    /* keep last */
+    __NL80211_REG_RULE_ATTR_AFTER_LAST,
+    NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_reg_rule_flags - regulatory rule flags
+ *
+ * @NL80211_RRF_NO_OFDM: OFDM modulation not allowed
+ * @NL80211_RRF_NO_CCK: CCK modulation not allowed
+ * @NL80211_RRF_NO_INDOOR: indoor operation not allowed
+ * @NL80211_RRF_NO_OUTDOOR: outdoor operation not allowed
+ * @NL80211_RRF_DFS: DFS support is required to be used
+ * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links
+ * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links
+ * @NL80211_RRF_PASSIVE_SCAN: passive scan is required
+ * @NL80211_RRF_NO_IBSS: no IBSS is allowed
+ */
+enum nl80211_reg_rule_flags {
+    NL80211_RRF_NO_OFDM        = 1<<0,
+    NL80211_RRF_NO_CCK        = 1<<1,
+    NL80211_RRF_NO_INDOOR        = 1<<2,
+    NL80211_RRF_NO_OUTDOOR        = 1<<3,
+    NL80211_RRF_DFS            = 1<<4,
+    NL80211_RRF_PTP_ONLY        = 1<<5,
+    NL80211_RRF_PTMP_ONLY        = 1<<6,
+    NL80211_RRF_PASSIVE_SCAN    = 1<<7,
+    NL80211_RRF_NO_IBSS        = 1<<8,
+};
+
+/**
+ * enum nl80211_survey_info - survey information
+ *
+ * These attribute types are used with %NL80211_ATTR_SURVEY_INFO
+ * when getting information about a survey.
+ *
+ * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel
+ * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm)
+ * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used
+ * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number
+ *    currently defined
+ * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use
+ */
+enum nl80211_survey_info {
+    __NL80211_SURVEY_INFO_INVALID,
+    NL80211_SURVEY_INFO_FREQUENCY,
+    NL80211_SURVEY_INFO_NOISE,
+    NL80211_SURVEY_INFO_IN_USE,
+
+    /* keep last */
+    __NL80211_SURVEY_INFO_AFTER_LAST,
+    NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_mntr_flags - monitor configuration flags
+ *
+ * Monitor configuration flags.
+ *
+ * @__NL80211_MNTR_FLAG_INVALID: reserved
+ *
+ * @NL80211_MNTR_FLAG_FCSFAIL: pass frames with bad FCS
+ * @NL80211_MNTR_FLAG_PLCPFAIL: pass frames with bad PLCP
+ * @NL80211_MNTR_FLAG_CONTROL: pass control frames
+ * @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering
+ * @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing.
+ *    overrides all other flags.
+ *
+ * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use
+ * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag
+ */
+enum nl80211_mntr_flags {
+    __NL80211_MNTR_FLAG_INVALID,
+    NL80211_MNTR_FLAG_FCSFAIL,
+    NL80211_MNTR_FLAG_PLCPFAIL,
+    NL80211_MNTR_FLAG_CONTROL,
+    NL80211_MNTR_FLAG_OTHER_BSS,
+    NL80211_MNTR_FLAG_COOK_FRAMES,
+
+    /* keep last */
+    __NL80211_MNTR_FLAG_AFTER_LAST,
+    NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_meshconf_params - mesh configuration parameters
+ *
+ * Mesh configuration parameters
+ *
+ * @__NL80211_MESHCONF_INVALID: internal use
+ *
+ * @NL80211_MESHCONF_RETRY_TIMEOUT: specifies the initial retry timeout in
+ * millisecond units, used by the Peer Link Open message
+ *
+ * @NL80211_MESHCONF_CONFIRM_TIMEOUT: specifies the inital confirm timeout, in
+ * millisecond units, used by the peer link management to close a peer link
+ *
+ * @NL80211_MESHCONF_HOLDING_TIMEOUT: specifies the holding timeout, in
+ * millisecond units
+ *
+ * @NL80211_MESHCONF_MAX_PEER_LINKS: maximum number of peer links allowed
+ * on this mesh interface
+ *
+ * @NL80211_MESHCONF_MAX_RETRIES: specifies the maximum number of peer link
+ * open retries that can be sent to establish a new peer link instance in a
+ * mesh
+ *
+ * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh
+ * point.
+ *
+ * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically
+ * open peer links when we detect compatible mesh peers.
+ *
+ * @NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: the number of action frames
+ * containing a PREQ that an MP can send to a particular destination (path
+ * target)
+ *
+ * @NL80211_MESHCONF_PATH_REFRESH_TIME: how frequently to refresh mesh paths
+ * (in milliseconds)
+ *
+ * @NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT: minimum length of time to wait
+ * until giving up on a path discovery (in milliseconds)
+ *
+ * @NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT: The time (in TUs) for which mesh
+ * points receiving a PREQ shall consider the forwarding information from the
+ * root to be valid. (TU = time unit)
+ *
+ * @NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL: The minimum interval of time (in
+ * TUs) during which an MP can send only one action frame containing a PREQ
+ * reference element
+ *
+ * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs)
+ * that it takes for an HWMP information element to propagate across the mesh
+ *
+ * @NL80211_MESHCONF_ROOTMODE: whether root mode is enabled or not
+ *
+ * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
+ *
+ * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_meshconf_params {
+    __NL80211_MESHCONF_INVALID,
+    NL80211_MESHCONF_RETRY_TIMEOUT,
+    NL80211_MESHCONF_CONFIRM_TIMEOUT,
+    NL80211_MESHCONF_HOLDING_TIMEOUT,
+    NL80211_MESHCONF_MAX_PEER_LINKS,
+    NL80211_MESHCONF_MAX_RETRIES,
+    NL80211_MESHCONF_TTL,
+    NL80211_MESHCONF_AUTO_OPEN_PLINKS,
+    NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
+    NL80211_MESHCONF_PATH_REFRESH_TIME,
+    NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
+    NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
+    NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
+    NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
+    NL80211_MESHCONF_HWMP_ROOTMODE,
+
+    /* keep last */
+    __NL80211_MESHCONF_ATTR_AFTER_LAST,
+    NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_txq_attr - TX queue parameter attributes
+ * @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved
+ * @NL80211_TXQ_ATTR_QUEUE: TX queue identifier (NL80211_TXQ_Q_*)
+ * @NL80211_TXQ_ATTR_TXOP: Maximum burst time in units of 32 usecs, 0 meaning
+ *    disabled
+ * @NL80211_TXQ_ATTR_CWMIN: Minimum contention window [a value of the form
+ *    2^n-1 in the range 1..32767]
+ * @NL80211_TXQ_ATTR_CWMAX: Maximum contention window [a value of the form
+ *    2^n-1 in the range 1..32767]
+ * @NL80211_TXQ_ATTR_AIFS: Arbitration interframe space [0..255]
+ * @__NL80211_TXQ_ATTR_AFTER_LAST: Internal
+ * @NL80211_TXQ_ATTR_MAX: Maximum TXQ attribute number
+ */
+enum nl80211_txq_attr {
+    __NL80211_TXQ_ATTR_INVALID,
+    NL80211_TXQ_ATTR_QUEUE,
+    NL80211_TXQ_ATTR_TXOP,
+    NL80211_TXQ_ATTR_CWMIN,
+    NL80211_TXQ_ATTR_CWMAX,
+    NL80211_TXQ_ATTR_AIFS,
+
+    /* keep last */
+    __NL80211_TXQ_ATTR_AFTER_LAST,
+    NL80211_TXQ_ATTR_MAX = __NL80211_TXQ_ATTR_AFTER_LAST - 1
+};
+
+enum nl80211_txq_q {
+    NL80211_TXQ_Q_VO,
+    NL80211_TXQ_Q_VI,
+    NL80211_TXQ_Q_BE,
+    NL80211_TXQ_Q_BK
+};
+
+enum nl80211_channel_type {
+    NL80211_CHAN_NO_HT,
+    NL80211_CHAN_HT20,
+    NL80211_CHAN_HT40MINUS,
+    NL80211_CHAN_HT40PLUS
+};
+
+/**
+ * enum nl80211_bss - netlink attributes for a BSS
+ *
+ * @__NL80211_BSS_INVALID: invalid
+ * @NL80211_BSS_BSSID: BSSID of the BSS (6 octets)
+ * @NL80211_BSS_FREQUENCY: frequency in MHz (u32)
+ * @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64)
+ * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16)
+ * @NL80211_BSS_CAPABILITY: capability field (CPU order, u16)
+ * @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the
+ *    raw information elements from the probe response/beacon (bin);
+ *    if the %NL80211_BSS_BEACON_IES attribute is present, the IEs here are
+ *    from a Probe Response frame; otherwise they are from a Beacon frame.
+ *    However, if the driver does not indicate the source of the IEs, these
+ *    IEs may be from either frame subtype.
+ * @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon
+ *    in mBm (100 * dBm) (s32)
+ * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon
+ *    in unspecified units, scaled to 0..100 (u8)
+ * @NL80211_BSS_STATUS: status, if this BSS is "used"
+ * @NL80211_BSS_SEEN_MS_AGO: age of this BSS entry in ms
+ * @NL80211_BSS_BEACON_IES: binary attribute containing the raw information
+ *    elements from a Beacon frame (bin); not present if no Beacon frame has
+ *    yet been received
+ * @__NL80211_BSS_AFTER_LAST: internal
+ * @NL80211_BSS_MAX: highest BSS attribute
+ */
+enum nl80211_bss {
+    __NL80211_BSS_INVALID,
+    NL80211_BSS_BSSID,
+    NL80211_BSS_FREQUENCY,
+    NL80211_BSS_TSF,
+    NL80211_BSS_BEACON_INTERVAL,
+    NL80211_BSS_CAPABILITY,
+    NL80211_BSS_INFORMATION_ELEMENTS,
+    NL80211_BSS_SIGNAL_MBM,
+    NL80211_BSS_SIGNAL_UNSPEC,
+    NL80211_BSS_STATUS,
+    NL80211_BSS_SEEN_MS_AGO,
+    NL80211_BSS_BEACON_IES,
+
+    /* keep last */
+    __NL80211_BSS_AFTER_LAST,
+    NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_bss_status - BSS "status"
+ * @NL80211_BSS_STATUS_AUTHENTICATED: Authenticated with this BSS.
+ * @NL80211_BSS_STATUS_ASSOCIATED: Associated with this BSS.
+ * @NL80211_BSS_STATUS_IBSS_JOINED: Joined to this IBSS.
+ *
+ * The BSS status is a BSS attribute in scan dumps, which
+ * indicates the status the interface has wrt. this BSS.
+ */
+enum nl80211_bss_status {
+    NL80211_BSS_STATUS_AUTHENTICATED,
+    NL80211_BSS_STATUS_ASSOCIATED,
+    NL80211_BSS_STATUS_IBSS_JOINED,
+};
+
+/**
+ * enum nl80211_auth_type - AuthenticationType
+ *
+ * @NL80211_AUTHTYPE_OPEN_SYSTEM: Open System authentication
+ * @NL80211_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only)
+ * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r)
+ * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP)
+ * @__NL80211_AUTHTYPE_NUM: internal
+ * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm
+ * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by
+ *    trying multiple times); this is invalid in netlink -- leave out
+ *    the attribute for this on CONNECT commands.
+ */
+enum nl80211_auth_type {
+    NL80211_AUTHTYPE_OPEN_SYSTEM,
+    NL80211_AUTHTYPE_SHARED_KEY,
+    NL80211_AUTHTYPE_FT,
+    NL80211_AUTHTYPE_NETWORK_EAP,
+
+    /* keep last */
+    __NL80211_AUTHTYPE_NUM,
+    NL80211_AUTHTYPE_MAX = __NL80211_AUTHTYPE_NUM - 1,
+    NL80211_AUTHTYPE_AUTOMATIC
+};
+
+/**
+ * enum nl80211_key_type - Key Type
+ * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key
+ * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key
+ * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS)
+ * @NUM_NL80211_KEYTYPES: number of defined key types
+ */
+enum nl80211_key_type {
+    NL80211_KEYTYPE_GROUP,
+    NL80211_KEYTYPE_PAIRWISE,
+    NL80211_KEYTYPE_PEERKEY,
+
+    NUM_NL80211_KEYTYPES
+};
+
+/**
+ * enum nl80211_mfp - Management frame protection state
+ * @NL80211_MFP_NO: Management frame protection not used
+ * @NL80211_MFP_REQUIRED: Management frame protection required
+ */
+enum nl80211_mfp {
+    NL80211_MFP_NO,
+    NL80211_MFP_REQUIRED,
+};
+
+enum nl80211_wpa_versions {
+    NL80211_WPA_VERSION_1 = 1 << 0,
+    NL80211_WPA_VERSION_2 = 1 << 1,
+};
+
+/**
+ * enum nl80211_key_attributes - key attributes
+ * @__NL80211_KEY_INVALID: invalid
+ * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of
+ *    16 bytes encryption key followed by 8 bytes each for TX and RX MIC
+ *    keys
+ * @NL80211_KEY_IDX: key ID (u8, 0-3)
+ * @NL80211_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11
+ *    section 7.3.2.25.1, e.g. 0x000FAC04)
+ * @NL80211_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and
+ *    CCMP keys, each six bytes in little endian
+ * @NL80211_KEY_DEFAULT: flag indicating default key
+ * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key
+ * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not
+ *    specified the default depends on whether a MAC address was
+ *    given with the command using the key or not (u32)
+ * @__NL80211_KEY_AFTER_LAST: internal
+ * @NL80211_KEY_MAX: highest key attribute
+ */
+enum nl80211_key_attributes {
+    __NL80211_KEY_INVALID,
+    NL80211_KEY_DATA,
+    NL80211_KEY_IDX,
+    NL80211_KEY_CIPHER,
+    NL80211_KEY_SEQ,
+    NL80211_KEY_DEFAULT,
+    NL80211_KEY_DEFAULT_MGMT,
+    NL80211_KEY_TYPE,
+
+    /* keep last */
+    __NL80211_KEY_AFTER_LAST,
+    NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_tx_rate_attributes - TX rate set attributes
+ * @__NL80211_TXRATE_INVALID: invalid
+ * @NL80211_TXRATE_LEGACY: Legacy (non-MCS) rates allowed for TX rate selection
+ *    in an array of rates as defined in IEEE 802.11 7.3.2.2 (u8 values with
+ *    1 = 500 kbps) but without the IE length restriction (at most
+ *    %NL80211_MAX_SUPP_RATES in a single array).
+ * @__NL80211_TXRATE_AFTER_LAST: internal
+ * @NL80211_TXRATE_MAX: highest TX rate attribute
+ */
+enum nl80211_tx_rate_attributes {
+    __NL80211_TXRATE_INVALID,
+    NL80211_TXRATE_LEGACY,
+
+    /* keep last */
+    __NL80211_TXRATE_AFTER_LAST,
+    NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_band - Frequency band
+ * @NL80211_BAND_2GHZ: 2.4 GHz ISM band
+ * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz)
+ */
+enum nl80211_band {
+    NL80211_BAND_2GHZ,
+    NL80211_BAND_5GHZ,
+};
+
+enum nl80211_ps_state {
+    NL80211_PS_DISABLED,
+    NL80211_PS_ENABLED,
+};
+
+/**
+ * enum nl80211_attr_cqm - connection quality monitor attributes
+ * @__NL80211_ATTR_CQM_INVALID: invalid
+ * @NL80211_ATTR_CQM_RSSI_THOLD: RSSI threshold in dBm. This value specifies
+ *    the threshold for the RSSI level at which an event will be sent. Zero
+ *    to disable.
+ * @NL80211_ATTR_CQM_RSSI_HYST: RSSI hysteresis in dBm. This value specifies
+ *    the minimum amount the RSSI level must change after an event before a
+ *    new event may be issued (to reduce effects of RSSI oscillation).
+ * @NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT: RSSI threshold event
+ * @__NL80211_ATTR_CQM_AFTER_LAST: internal
+ * @NL80211_ATTR_CQM_MAX: highest key attribute
+ */
+enum nl80211_attr_cqm {
+    __NL80211_ATTR_CQM_INVALID,
+    NL80211_ATTR_CQM_RSSI_THOLD,
+    NL80211_ATTR_CQM_RSSI_HYST,
+    NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
+
+    /* keep last */
+    __NL80211_ATTR_CQM_AFTER_LAST,
+    NL80211_ATTR_CQM_MAX = __NL80211_ATTR_CQM_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_cqm_rssi_threshold_event - RSSI threshold event
+ * @NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW: The RSSI level is lower than the
+ *      configured threshold
+ * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH: The RSSI is higher than the
+ *      configured threshold
+ */
+enum nl80211_cqm_rssi_threshold_event {
+    NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
+    NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
+};
+
+
+/**
+ * enum nl80211_tx_power_setting - TX power adjustment
+ * @NL80211_TX_POWER_AUTOMATIC: automatically determine transmit power
+ * @NL80211_TX_POWER_LIMITED: limit TX power by the mBm parameter
+ * @NL80211_TX_POWER_FIXED: fix TX power to the mBm parameter
+ */
+enum nl80211_tx_power_setting {
+    NL80211_TX_POWER_AUTOMATIC,
+    NL80211_TX_POWER_LIMITED,
+    NL80211_TX_POWER_FIXED,
+};
+
+#endif /* __LINUX_NL80211_H */