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 */