mxm_wifiex: update to mxm6x18505.p1 release

Corresponding firmware version:
SDIO-UART W8987 Firmware version 16.92.21.p142
PCIE-UART W8997 Firmware version 16.92.21.p137.3
SDIO-UART W8997 Firmware version 16.92.21.p137.3
SDIO-UART IW416 Firmware version 16.92.21.p142
SDIO_UART IW610 Firmware version 18.99.5.p35
SDIO_UART IW612 Firmware version 18.99.3.p21.4
SDIO-UART W8801 Firmware version 14.92.36.p194
SDIO-UART W9098 Firmware version 17.92.1.p149.50
PCIE-UART W9098 Firmware version 17.92.1.p149.50

Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
This commit is contained in:
Luke Wang 2024-10-17 10:39:54 +08:00 committed by Sherry Sun
parent e5c9a169d7
commit ac1604083f
67 changed files with 9688 additions and 1291 deletions

View file

@ -50,6 +50,8 @@ CONFIG_PCIE9097=n
CONFIG_SD9098=y
CONFIG_USB9098=n
CONFIG_PCIE9098=y
CONFIG_SDIW610=y
CONFIG_USBIW610=n
CONFIG_SDIW624=n
CONFIG_SDAW693=n
CONFIG_PCIEIW624=n
@ -186,7 +188,7 @@ APPDIR= $(shell if test -d "mapp"; then echo mapp; fi)
#############################################################################
ccflags-y += -I$(KERNELDIR)/include
ccflags-y += -DMLAN_RELEASE_VERSION='"437.p30"'
ccflags-y += -DMLAN_RELEASE_VERSION='"505.p1"'
ccflags-y += -DFPNUM='"92"'
@ -303,6 +305,10 @@ ifeq ($(CONFIG_SD9097),y)
CONFIG_SDIO=y
ccflags-y += -DSD9097
endif
ifeq ($(CONFIG_SDIW610),y)
CONFIG_SDIO=y
ccflags-y += -DSDIW610
endif
ifeq ($(CONFIG_SDIW624),y)
CONFIG_SDIO=y
ccflags-y += -DSDIW624
@ -343,6 +349,10 @@ ifeq ($(CONFIG_USB9097),y)
CONFIG_MUSB=y
ccflags-y += -DUSB9097
endif
ifeq ($(CONFIG_USBIW610),y)
CONFIG_MUSB=y
ccflags-y += -DUSBIW610
endif
ifeq ($(CONFIG_USBIW624),y)
CONFIG_MUSB=y
ccflags-y += -DUSBIW624

236
README
View file

@ -11,7 +11,7 @@
Goto source code directory.
make [clean] build
The driver and utility binaries can be found in bin_wlan directory.
The driver code supports Linux kernel from 2.6.32 to 6.9.0.
The driver code supports Linux kernel from 2.6.32 to 6.9.10.
2) FOR DRIVER INSTALL
@ -46,6 +46,21 @@
rmmod moal
rmmod mlan
pref_dbc
This load time parameter is used to config preferred DBC mode and takes effect when dmcs is enabled
This parameter only used for AW693(BB)
Usage:
pref_dbc=[value]
insmod mlan.ko; insmod pcieaw693.ko fw_name=aw693w.bin dmcs=1 pref_dbc=1
<value = 0> : default preferred DBC mode
<value = 1> : Enable preferred DBC mode
<value = 2> : Disable preferred DBC mode
Example :
insmod mlan.ko; insmod pcieaw693.ko fw_name=aw693w.bin dmcs=1 pref_dbc=1 : Enable preferred DBC mode
insmod mlan.ko; insmod pcieaw693.ko fw_name=aw693w.bin dmcs=1 pref_dbc=2 : Disable preferred DBC mode
To load driver with MFG firmware file, use mfg_mode=1 when insmod WLAN driver and
specify MFG firmware name if needed.
@ -53,82 +68,90 @@
This parameter only used for 9177(FC)
There are some other parameters for debugging purpose etc. Use modinfo to check details.
drvdbg=<bit mask of driver debug message control>
dev_cap_mask=<Bit mask of the device capability>
This load parameter is uses to configure device features support
Usage:
dev_cap_mask=<value to be configured>
<BIT0-BIT15> : Represents features supported
<BIT16>: Indicates support for 11AX
<BIT17>: Indicates support for 6G
Example:
To disable 11AX and 6G support: dev_cap_mask=0xfffcffff
mac_addr=xx:xx:xx:xx:xx:xx <override the MAC address (in hex)>
auto_ds=0|1|2 <use MLAN default | enable auto deepsleep | disable auto deepsleep>
ext_scan=0|1|2 <use MLAN default | Enable Extended Scan| Enable Enhanced Extended Scan>
net_rx=0|1 <use netif_rx_ni in rx | use netif_receive_skb in rx>
amsdu_deaggr=0|1 <buf copy in amsud deaggregation | avoid buf copy in amsud deaggregation (default)>
drvdbg=<bit mask of driver debug message control>
dev_cap_mask=<Bit mask of the device capability>
This load parameter is uses to configure device features support
Usage:
dev_cap_mask=<value to be configured>
<BIT0-BIT15> : Represents features supported
<BIT16>: Indicates support for 11AX
<BIT17>: Indicates support for 6G
Example:
To disable 11AX and 6G support: dev_cap_mask=0xfffcffff
bootup_cal_ctrl=0|1 <disable boot time config default | enable boot time config>
ps_mode=0|1|2 <use MLAN default | enable IEEE PS mode | disable IEEE PS mode>
sched_scan=0|1 <disable sched_scan | enable sched_scan default>
max_tx_buf=2048|4096|8192 <maximum AMSDU Tx buffer size>
pm_keep_power=1|0 <PM keep power in suspend (default) | PM no power in suspend>
shutdown_hs=1|0 <Enable HS when shutdown | No HS when shutdown (default)>
cfg_11d=0|1|2 <use MLAN default | enable 11d | disable 11d>
dts_enable=0|1 <Disable DTS | Enable DTS (default)>
fw_name = <FW file name>
mac_addr=xx:xx:xx:xx:xx:xx <override the MAC address (in hex)>
auto_ds=0|1|2 <use MLAN default | enable auto deepsleep | disable auto deepsleep>
ext_scan=0|1|2 <use MLAN default | Enable Extended Scan| Enable Enhanced Extended Scan>
p2a_scan=0|1|2 <MLAN default | Enable passive to active scan for DFS channel | Disable passive to active scan for DFS channel>
scan_chan_gap=x <Time gap between two scans in milliseconds when connected to AP (max value 500ms)>
net_rx=0|1 <use netif_rx/netif_rx_ni in rx | use netif_receive_skb in rx (default)>
amsdu_deaggr=0|1 <buf copy in amsud deaggregation | avoid buf copy in amsud deaggregation (default)>
bootup_cal_ctrl=0|1 <disable boot time config default | enable boot time config>
ps_mode=0|1|2 <use MLAN default | enable IEEE PS mode | disable IEEE PS mode>
sched_scan=0|1 <disable sched_scan | enable sched_scan default>
max_tx_buf=2048|4096|8192 <maximum AMSDU Tx buffer size>
pm_keep_power=1|0 <PM keep power in suspend (default) | PM no power in suspend>
shutdown_hs=1|0 <Enable HS when shutdown | No HS when shutdown (default)>
cfg_11d=0|1|2 <use MLAN default | enable 11d | disable 11d>
dts_enable=0|1 <Disable DTS | Enable DTS (default)>
fw_name = <FW file name>
e.g. copy pcieuart9098_combo_v1.bin to firmware directory, fw_name=nxp/pcieuart9098_combo_v1.bin
hw_name = <hardware name>
reg_work=0|1 <Disable register work queue| Enable register work queue>
hw_test=0|1 <Disable hardware test (default) | Enable hardware test>
fw_serial=0|1 <support parallel download FW | support serial download FW (default)>
req_fw_nowait=0|1 <use request_firmware API (default) | use request_firmware_nowait API>
dfs53cfg=0|1|2 <use Fw Default | New W53 | Old W53>
mcs32=0|1 <disable HT MCS32 support | enable HT MCS32 (default)>
SD8887: antcfg=0|1|2|0xffff <default | Tx/Rx antenna 1 | Tx/Rx antenna 2 | enable antenna diversity>
SD8897/SD8997: antcfg=0x11|0x13|0x33 <Bit0:Rx Path A, Bit1:Rx Path B, Bit 4:Tx Path A, Bit 5:Tx Path B>
slew_rate: Slew Rate Control value = 0|1|2|3 (0 is the slowest slew rate and 03 has the highest slew rate (default))
init_cfg=<init config (MAC addresses, registers etc.) file name>
hw_name = <hardware name>
reg_work=0|1 <Disable register work queue| Enable register work queue>
hw_test=0|1 <Disable hardware test (default) | Enable hardware test>
fw_serial=0|1 <support parallel download FW | support serial download FW (default)>
req_fw_nowait=0|1 <use request_firmware API (default) | use request_firmware_nowait API>
dfs53cfg=0|1|2 <use Fw Default | New W53 | Old W53>
mcs32=0|1 <disable HT MCS32 support | enable HT MCS32 (default)>
For 9097/9098/IW624/AW693: antcfg=0x101|0x303|.. <Bit0: Tx/Rx Path A for 2G, Bit1: Tx/Rx Path B for 2G, Bit8: Tx/Rx Path A for 5G, Bit9: Tx/Rx Path B for 5G>
For AW693, it's recommended to use mod_para configuration file for antcfg as MAC1 supports 2x2 and MAC2 supports only 1x1.
For 8897/8997: antcfg=0x11|0x13|0x33 <Bit0:Rx Path A, Bit1:Rx Path B, Bit 4:Tx Path A, Bit 5:Tx Path B>
For others: antcfg=0|1|2|0xffff <default | Tx/Rx antenna 1 | Tx/Rx antenna 2 | enable antenna diversity>
slew_rate: Slew Rate Control value = 0|1|2|3 (0 is the slowest slew rate and 03 has the highest slew rate (default))
init_cfg=<init config (MAC addresses, registers etc.) file name>
e.g. copy init_cfg.conf to firmware directory, init_cfg=nxp/init_cfg.conf
cal_data_cfg=<CAL data config file name>
cal_data_cfg=<CAL data config file name>
e.g. copy cal_data.conf to firmware directory, cal_data_cfg=nxp/cal_data.conf
Note: Loading driver with 8887 must include correct cal_data_cfg parameter.
dpd_data_cfg=<DPD data config file name>
e.g. copy dpd_data.conf to firmware directory, dpd_data_cfg=nxp/dpd_data.conf
txpwrlimit_cfg=<Tx power limit config file name>
Note: Loading driver with 8887 must include correct cal_data_cfg parameter.
dpd_data_cfg=<DPD data config file name>
e.g. copy dpd_data.conf to firmware directory, dpd_data_cfg=nxp/dpd_data.conf
txpwrlimit_cfg=<Tx power limit config file name>
e.g. copy txpwrlimit_cfg_set.conf to firmware directory, txpwrlimit_cfg=nxp/txpwrlimit_cfg_set.conf
txpwrlimit_cfg_set.conf file should be the binary format file generate by mlanutl application
cntry_txpwr=0|1|2
cntry_txpwr=0|1|2
0: Disable setting tx power table of country (default)
1: Enable setting tx power table of country
2: Enable setting rgpower table of country
init_hostcmd_cfg=<init hostcmd config file name>
init_hostcmd_cfg=<init hostcmd config file name>
e.g. copy init_hostcmd_cfg.conf to firmware directory, init_hostcmd_cfg=nxp/init_hostcmd_cfg.conf
band_steer_cfg=<band steer config file name>
band_steer_cfg=<band steer config file name>
e.g. generate bscfg.conf by band_steer_cfg.conf, then copy bscfg.conf to firmware directory, band_steer_cfg=nxp/bscfg.conf
sdio_rx_aggr=1|0 <Enable SDIO rx aggr (default) | Disable SDIO rx aggr>
cfg80211_wext=<bit mask of CFG80211 and WEXT control>
sdio_rx_aggr=1|0 <Enable SDIO rx aggr (default) | Disable SDIO rx aggr>
cfg80211_wext=<bit mask of CFG80211 and WEXT control>
Bit 0: STA WEXT
Bit 1: uAP WEXT
Bit 2: STA CFG80211
Bit 3: uAP CFG80211
cfg80211_drcs=1|0 <Enable DRCS support (default) | Disable DRCS support>
reg_alpha2=<Regulatory alpha2 (default NULL)>
skip_fwdnld=0|1 <enable FW download support (default) | disable FW download support>
wq_sched_prio: Priority for work queue
wq_sched_policy: Scheduling policy for work queue
cfg80211_drcs=1|0 <Enable DRCS support (default) | Disable DRCS support>
skip_fwdnld=0|1 <enable FW download support (default) | disable FW download support>
wq_sched_prio: Priority for work queue
wq_sched_policy: Scheduling policy for work queue
(0: SCHED_NORMAL, 1: SCHED_FIFO, 2: SCHED_RR, 3: SCHED_BATCH, 5: SCHED_IDLE)
Please note that, both wq_sched_prio and wq_sched_policy should be provided
as module parameters. If wq_sched_policy is (0, 3 or 5), then wq_sched_prio
must be 0. wq_sched_prio should be 1 to 99 otherwise.
rx_work=0|1|2 <default | Enable rx_work_queue | Disable rx_work_queue>
pcie_int_mode=0|1 <Legacy mode, MSI mode (default)>
ring_size=32|64|128|256|512 <adma ring size for 9097/9098>
aggrctrl=1|0 <enable Tx aggr | disable Tx aggr>
usb_aggr=0|1|2 <use MLAN default (disabled) | enable USB aggr | disable USB aggr>
low_power_mode_enable=0|1 <disable low power mode (default)| enable low power mode>
rx_work=0|1|2 <default (enabled for multi-core) | Enable rx_work_queue | Disable rx_work_queue>
tx_work=0|1 <Disable tx_work_queue | Enable tx_work_queue (default on iMX)>
tx_skb_clone=0|1 <Disable tx_skb_clone | Enable tx_skb_clone (default on iMX)>
pmqos=0|1 <Disable pmqos | Enable pmqos (default on iMX)>
rps=0|x <Disables rps (default) | bit0-bit4 (0x1-0xf) Enables rps on specific cpu>
intmode=0|1 <SDIO Interrupt Mode (default) | GPIO Interrupt Mode>
gpiopin=0|x <GPIO pin number when intmode=1 (default 0, HW mapped intr on GPIO-21)>
pcie_int_mode=0|1 <Legacy mode, MSI mode (default)>
ring_size=32|64|128|256|512 <adma ring size for 9097/9098>
aggrctrl=1|0 <enable Tx aggr | disable Tx aggr>
usb_aggr=0|1|2 <use MLAN default (disabled) | enable USB aggr | disable USB aggr>
low_power_mode_enable=0|1 <disable low power mode (default)| enable low power mode>
When low power mode is enabled, the output power will be clipped at ~+10dBm and the
expected PA current is expected to be in the 80-90 mA range for b/g/n modes
wakelock_timeout=<set wakelock_timeout value (ms)>
@ -139,7 +162,7 @@
hs_wake_interval=<Host sleep wakeup interval,it will round to nearest multiple dtim*beacon_period in fw>
disconnect_on_suspend=0|1 <Disable disconnect wifi on suspend (default) | Enable disconnect wifi on suspend>
hs_mimo_switch=0|1 <Disable dynamic MIMO-SISO switch during host sleep (default) | Enable dynamic MIMO-SISO switch during host sleep>
hs_auto_arp=0|1 <disable hs_auto_arp (default) | enable hs_auto_arp>
hs_auto_arp=0|1 <disable hs_auto_arp (default) | enable hs_auto_arp>
gtk_rekey_offload=0|1|2 <disable gtk_rekey_offload|enable gtk_rekey_offload (default) | enable gtk_rekey_offload in suspend mode only>
napi=0|1 <disable napi | enable napi>
fixed_beacon_buffer=0|1 <allocate default buffer size (default) | allocate max buffer size>
@ -152,24 +175,39 @@
Bit15~Bit8:Channel time for channel index1;
Bit7~Bit0:mode for channel index1; 0|1 <PM1 | Null2Self>
roamoffload_in_hs=0|1 <always enable fw roaming (default) | enable fw roaming only when host suspend>
uap_max_sta: Maximum number of STA for UAP/GO (default 0, max 64)
uap_max_sta: Maximum number of STA for UAP/GO (default 0, max STA number for UAP/GO supported in FW)
wacp_mode=0|1|2 <disable WACP (default) | WACP mode 1 | WACP mode 2>
dfs_offload=0|1 <disable dfs offload (default) | enable dfs offload>
indrstcfg=x <high byte: GPIO pin number (255 default); low byte: IR mode (0: disable, 1: out-of-band, 2: in band)>
auto_fw_reload=0|1|3 <disable|enable PCIE FLR|enable PCIE InBand Reset (default)>
auto_fw_reload=0|1 <disable|enable InBand Reset (default)>
dmcs=0|1 <disable (default)|enable dynamic mapping)>
dmcs=0|1|2 <firmware default (default) | enable dynamic mapping | disable dynamic mapping>
host_mlme=0|1 <Operate in non-host_mlme mode | Operate in host_mlme mode (default)>
for supplicant/authenticator running on host side, WPA3 support is available only in host_mlme mode
for chipset 89xx FP-92, 90xx and later, host_mlme restricted to 1
country_ie_ignore=0|1 <Follow countryIE from AP and beacon hint enable (default) | Ignore countryIE from AP and beacon hint disable>
beacon_hints=0|1 <enable beacon hints(default) | disable beacon hints>
for supplicant/authenticator running on host side, WPA3 support is available only in host_mlme mode
for chipset 89xx FP-92, 90xx and later, host_mlme restricted to 1
disable_regd_by_driver=0|1 <reg domain set by driver enable | reg domain set by driver disable (default)>
reg_alpha2=<Regulatory alpha2 (default NULL)>
country_ie_ignore=0|1 <Follow countryIE from AP and beacon hint enable | Ignore countryIE from AP and beacon hint disable (default)>
beacon_hints=0|1 <enable beacon hints | disable beacon hints (default)>
mon_filter=x <Bit6:TX frames excluding control; Bit5:non-bss beacons; Bit3:unicast destined non-promiscuous frames only; Bit2:data frames; Bit1:control frames; Bit0:management frames>
edmac_ctrl=0|1 <Disable edmac EU adaptivity (default) | Enable edmac EU adaptivity>
chan_track=0|1 <restore channel tracking parameters(default) | set channel tracking new parameters> for 9098 only
keep_previous_scan=0|1, <Flush previous scan result before start scan | Keep previous scan result(default)>
auto_11ax=0|1, <disable auto_11ax | enable auto_11ax(default)>
dual_nb=0|1, <default combo FW name - single narrowband (default) | default combo FW name - dual narrowband>
fw_data_cfg=0|x <disable configuration for custom Fw data(default) | set configuration for custom Fw data>
Configurations for fw_data_cfg:
Bit 0: Configuration for Fw remapping addr
Bit 1: Configuration for USB endpoint
BIT 2: Configuration for DPD current optimizations
mclient_scheduling=0|1 <disable multi-client scheduling | enable multi-client scheduling (default)>
tx_budget=xxx <airtime tx budget for multi-client scheduling in usec, 0 - disable, 2600 - default>
reject_addba_req=0(default)|1|2|3 <set the conditions of rejecting addba request>
The conditions are:
Bit 0 : 1 -- reject the addba request when host sleep activated
Bit 1 : 1 -- reject the addba request when FW auto re-connect enabled
this bit is only used with STA BSS
others -- reserved
Note: On some platforms (e.g. PXA910/920) double quotation marks ("") need to used
for module parameters.
@ -409,7 +447,7 @@
Set Tx Power
This command will set power only if caldata is already loaded in the FW.
Power (0 to 24 dBm)
Power (-15 to 24 dBm)
Modulation (0: CCK, 1:OFDM, 2:MCS)
Path ID (0: PathA, 1:PathB, 2:PathA+B)
echo "tx_power=16 2 0" > /proc/mwlan/adapterX/config
@ -459,13 +497,13 @@
GreenField Mode (0:disable, 1:enable)
STBC (0:disable, 1:enable)
Signal Bw (0: 20Mhz, 1: 40Mhz, 4:80Mhz, -1: Set to default)
NumPkt (Set to default value -1)
MaxPktExt (Set to default value -1)
BeamChange (Set to default value -1)
DCM (Set to default value -1)
Doppler (Set to default value -1)
MidamblePeriod (Set to default value -1)
QNum (Set to default value 1)
NumPkt (-1:Set to default value, 1 to 0xfffffffe to specify number of packaets to send)
MaxPktExt (0|8|16us, -1:Set to default Value 2)
BeamChange (0|1, -1:Set to default Value 1)
DCM (0|1, -1:Set to default Value 0)
Doppler (0|1, -1:Set to default Value 0)
MidamblePeriod (10|20, -1:Set to default Value 0)
QNum (0-12|17-20, -1:Set to default Value if 11ax QNum:17 else QNum:0)
BSSID (xx:xx:xx:xx:xx:xx)
Example: To start Tx frame with duty cycle, first stop any ongoing Tx
@ -474,6 +512,40 @@
echo "tx_frame=1 7 0xAAA 0x100 1 20 0 0 0 0 0 0 0 0 -1 -1 -1 -1 -1 -1 -1 05:43:3f:c4:51" > /proc/mwlan/adapterX/config
Configure Trigger Frame
Start (0|1, 0:disable, 1:enable)
standalone HETB (0|1, 0:disable, 1:enable)
Frame Control Type (1: Control frame)
Frame Control Sub-Type (2: Trigger frame)
Duration (0x156C , Max Duration time)
TriggerType (0: Basic Trigger Frame)
UlLen (UL Length)
MoreTF (0|1, 0:FALSE, 1:TRUE)
CS Required (0|1, 0:FALSE, 1:TRUE)
UL_bandwidth (0: 20Mhz, 1: 40Mhz, 2:80Mhz, 3:80+80 MHz|160MHz -1:Set to default value)
LTF Type (0: 1xLTF+1.6usGI, 1: 2xLTF+0.8usGI, 2: 2xLTF+1.6usGI, 3: 4xLTF+3.2usGI)
LTF Mode (0|1, 0: Single stream pilots, 1: Mask LTF sequence of each spatial stream)
LTF symbol (Number of LTF Symbols)
UL STBC (0|1, 0:STBC encoding disable, 1:STBC encoding disable)
LDPC ESS (0|1, 0:LDPC ESS disable, 1:LDPC ESS enable)
ApTxPwr (0-61, 0-60:Values 0-61 maps to -20 dBm to 40 dBm)
PreFecPadFct (1-4, a-factor)
Disambing (0|1, 0:Set to Default)
Spatial Reuse (65535 Default Value)
Doppler (0|1, 0:disable, 1:enable)
HE SIG2 (0x1FF Default value)
AID12 (any 12 bit value)
RUAllocReg (RU index, any 8 bit value)
RUAlloc (0|1, 0: RU allocated is primary 80Mhz, 1: non-primary 80MHz)
Coding Type (0|1, 0: BCC,1: LDPC)
UlMCS (Valid MCS Value)
UL DCM (0|1, 0:disable, 1:enable)
SSAlloc (Spatial streams, BITS[0-2]:Number of spatial streams BITS[3-5]:Starting spatial stream)
Target RSSI ID (0-90, 0-90:Values 0-90 map to -100dBm to -20dBm)
MPDU MU SF (0:Multiplier=1, 1:Multiplier=2 , 2:Multiplier=4, 3:Multiplier=8)
TID_AL (0:Set to default Value)
AC_PL (0|1, 0:disable, 1:enable)
Pref_AC (0:AC_VO, 1:AC_V1, 2:AC_BE, 3:AC_BK)
Example: To configure Trigger frame:
echo "trigger_frame=1 0 1 2 5484 0 256 0 0 2 1 0 0 0 1 60 1 0 65535 0 511 5 0 67 0 0 0 0 90 0 0 0 0" > /proc/mwlan/adapter0/config
@ -512,20 +584,20 @@
Bit 0 -- Tx Path A or Tx/Rx Path A if [n] is not provided
Bit 1 -- Tx Path B or Tx/Rx Path B if [n] is not provided
Bit 0-1 -- Tx Path A+B or Tx/Rx Path A+B if [n] is not provided
For 9097/9098/IW624, LOW BYTE for 2G setting
For 9097/9098/IW624/AW693, LOW BYTE for 2G setting
Bit 8 -- Tx Path A or Tx/Rx Path A if [n] is not provided
Bit 9 -- Tx Path B or Tx/Rx Path B if [n] is not provided
Bit 8-9 -- Tx Path A+B or Tx/Rx Path A+B if [n] is not provided
For 9097/9098/IW624, HIGH BYTE for 5G setting
For 9097/9098/IW624/AW693, HIGH BYTE for 5G setting
where value of n is:
Bit 0 -- Rx Path A
Bit 1 -- Rx Path B
Bit 0-1 -- Rx Path A+B
For 9097/9098/IW624, LOW BYTE for 2G setting
For 9097/9098/IW624/AW693, LOW BYTE for 2G setting
Bit 8 -- Rx Path A
Bit 8 -- Rx Path B
Bit 8-9 -- Rx Path A+B
For 9097/9098/IW624, HIGH BYTE for 5G setting
For 9097/9098/IW624/AW693, HIGH BYTE for 5G setting
The Tx path setting (m) is used for both Tx and Rx if Rx path (n) is not provided.
Examples:

View file

@ -561,8 +561,10 @@ void wlan_update_11ax_cap(mlan_adapter *pmadapter,
(t_u8 *)pmadapter->hw_2g_he_cap,
pmadapter->hw_2g_hecap_len);
} else {
pmadapter->fw_bands |= BAND_AAX;
pmadapter->config_bands |= BAND_AAX;
if (pmadapter->fw_bands & BAND_A) {
pmadapter->fw_bands |= BAND_AAX;
pmadapter->config_bands |= BAND_AAX;
}
pmadapter->hw_hecap_len =
hw_he_cap->len + sizeof(MrvlIEtypesHeader_t);
memcpy_ext(pmadapter, pmadapter->hw_he_cap, (t_u8 *)hw_he_cap,
@ -876,6 +878,7 @@ mlan_status wlan_11ax_ioctl_cmd(pmlan_adapter pmadapter,
t_u16 cmd_action = 0;
mlan_ds_11ax_llde_pkt_filter_cmd *llde_pkt_filter = MNULL;
int mlan_ds_11ax_cmd_cfg_header = 0;
t_u8 null_mac_addr[MLAN_MAC_ADDR_LENGTH] = {0};
ENTER();
@ -907,13 +910,41 @@ mlan_status wlan_11ax_ioctl_cmd(pmlan_adapter pmadapter,
pmadapter->llde_packet_type = llde_pkt_filter->packet_type;
pmadapter->llde_device_filter = llde_pkt_filter->device_filter;
memcpy_ext(pmadapter, pmadapter->llde_macfilter1,
&llde_pkt_filter->macfilter1, MLAN_MAC_ADDR_LENGTH,
MLAN_MAC_ADDR_LENGTH);
/* reset old entries */
pmadapter->llde_totalMacFilters = 0;
// coverity[bad_memset: SUPPRESS]
memset(pmadapter, (t_u8 *)&pmadapter->llde_macfilters, 0,
MAX_MAC_FILTER_ENTRIES * MLAN_MAC_ADDR_LENGTH);
memcpy_ext(pmadapter, pmadapter->llde_macfilter2,
&llde_pkt_filter->macfilter2, MLAN_MAC_ADDR_LENGTH,
MLAN_MAC_ADDR_LENGTH);
/* copy valid mac adresses only */
if (memcmp(pmadapter, &llde_pkt_filter->macfilter1,
&null_mac_addr, MLAN_MAC_ADDR_LENGTH) != 0) {
pmadapter->llde_totalMacFilters++;
memcpy_ext(pmadapter,
&pmadapter->llde_macfilters
[0 * MLAN_MAC_ADDR_LENGTH],
&llde_pkt_filter->macfilter1,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
if (memcmp(pmadapter, &llde_pkt_filter->macfilter2,
&null_mac_addr, MLAN_MAC_ADDR_LENGTH) != 0) {
pmadapter->llde_totalMacFilters++;
memcpy_ext(pmadapter,
&pmadapter->llde_macfilters
[1 * MLAN_MAC_ADDR_LENGTH],
&llde_pkt_filter->macfilter2,
MLAN_MAC_ADDR_LENGTH,
MLAN_MAC_ADDR_LENGTH);
}
} else if (memcmp(pmadapter, &llde_pkt_filter->macfilter2,
&null_mac_addr, MLAN_MAC_ADDR_LENGTH) != 0) {
pmadapter->llde_totalMacFilters++;
memcpy_ext(pmadapter,
&pmadapter->llde_macfilters
[0 * MLAN_MAC_ADDR_LENGTH],
&llde_pkt_filter->macfilter2,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
}
/* remove llde packet filter parameters from buffer which will
* be passed to fimrware */
@ -1186,6 +1217,9 @@ mlan_status wlan_cmd_twt_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
ds_twtcfg->param.twt_setup.twt_mantissa);
twt_setup_params->twt_request =
ds_twtcfg->param.twt_setup.twt_request;
twt_setup_params->bcnMiss_threshold = wlan_cpu_to_le16(
ds_twtcfg->param.twt_setup.bcnMiss_threshold);
cmd->size += sizeof(hostcmd_twtcfg->param.twt_setup);
break;
case MLAN_11AX_TWT_TEARDOWN_SUBID:

View file

@ -36,16 +36,8 @@ Change log:
********************************************************/
#ifdef STA_SUPPORT
/** Region code mapping */
typedef struct _region_code_mapping {
/** Region */
t_u8 region[COUNTRY_CODE_LEN];
/** Code */
t_u8 code;
} region_code_mapping_t;
/** Region code mapping table */
static region_code_mapping_t region_code_mapping[] = {
region_code_mapping_t region_code_mapping[] = {
{"US ", 0x10}, /* US FCC */
{"CA ", 0x20}, /* IC Canada */
{"SG ", 0x10}, /* Singapore */
@ -115,6 +107,7 @@ static chan_freq_power_t channel_freq_power_UN_AJ[] = {
{132, 5660, TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
{136, 5680, TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
{140, 5700, TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
{144, 5720, TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
{149, 5745, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
{153, 5765, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
{157, 5785, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
@ -145,7 +138,7 @@ static chan_freq_power_t channel_freq_power_UN_AJ[] = {
*
* @return Region string
*/
static t_u8 *wlan_11d_code_2_region(pmlan_adapter pmadapter, t_u8 code)
t_u8 *wlan_11d_code_2_region(pmlan_adapter pmadapter, t_u8 code)
{
t_u8 i;

View file

@ -3146,6 +3146,7 @@ mlan_status wlan_11h_ioctl_dfs_chan_report(mlan_private *priv,
LEAVE();
return ret;
}
/**
* @brief Check if channel is under NOP (Non-Occupancy Period)
* If so, the channel should not be used until the period expires.

View file

@ -4,7 +4,7 @@
* function declarations of 802.11h
*
*
* Copyright 2008-2021 NXP
* Copyright 2008-2024 NXP
*
* This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991

View file

@ -33,6 +33,7 @@ Change log:
#include "mlan_wmm.h"
#include "mlan_11n.h"
#include "mlan_11ac.h"
#include "mlan_11ax.h"
/********************************************************
Local Variables
@ -510,7 +511,12 @@ static mlan_status wlan_11n_ioctl_addba_param(pmlan_adapter pmadapter,
cfg->param.addba_param.rxamsdu = pmpriv->add_ba_param.rx_amsdu;
} else {
timeout = pmpriv->add_ba_param.timeout;
pmpriv->add_ba_param.timeout = cfg->param.addba_param.timeout;
if (pmadapter->tx_ba_timeout_support) {
pmpriv->add_ba_param.timeout =
cfg->param.addba_param.timeout;
} else {
pmpriv->add_ba_param.timeout = 0;
}
pmpriv->add_ba_param.tx_win_size =
cfg->param.addba_param.txwinsize;
@ -1624,8 +1630,9 @@ void wlan_show_dot11ndevcap(pmlan_adapter pmadapter, t_u32 cap)
PRINTM(MINFO, "GET_HW_SPEC: LDPC coded packet receive %s\n",
(ISSUPP_RXLDPC(cap) ? "supported" : "not supported"));
PRINTM(MINFO, "GET_HW_SPEC: Number of Tx BA streams supported = %d\n",
ISSUPP_GETTXBASTREAM(cap));
PRINTM(MINFO,
"GET_HW_SPEC: Number of Tx BA streams supported = %d/%d\n",
ISSUPP_GETTXBASTREAM(cap), wlan_get_bastream_limit(pmadapter));
PRINTM(MINFO, "GET_HW_SPEC: 40 Mhz channel width %s\n",
(ISSUPP_CHANWIDTH40(cap) ? "supported" : "not supported"));
PRINTM(MINFO, "GET_HW_SPEC: 20 Mhz channel width %s\n",
@ -2620,6 +2627,8 @@ int wlan_cmd_append_11n_tlv(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc,
RESET_EXTCAP_EXT_CHANNEL_SWITCH(pext_cap->ext_cap);
else
SET_EXTCAP_EXT_CHANNEL_SWITCH(pext_cap->ext_cap);
if (wlan_check_11ax_twt_supported(pmpriv, pbss_desc))
SET_EXTCAP_TWT_REQ(pext_cap->ext_cap);
HEXDUMP("Extended Capabilities IE", (t_u8 *)pext_cap,
sizeof(MrvlIETypes_ExtCap_t));
@ -3140,7 +3149,7 @@ int wlan_get_txbastream_tbl(mlan_private *priv, tx_ba_stream_tbl *buf)
LEAVE();
return count;
}
bastream_max = ISSUPP_GETTXBASTREAM(priv->adapter->hw_dot_11n_dev_cap);
bastream_max = wlan_get_bastream_limit(priv->adapter);
if (bastream_max == 0)
bastream_max = MLAN_MAX_TX_BASTREAM_DEFAULT;

View file

@ -297,7 +297,7 @@ static INLINE t_u8 wlan_is_amsdu_allowed(mlan_private *priv, raListTbl *ptr,
#ifdef UAP_SUPPORT
sta_node *sta_ptr = MNULL;
#endif
if (priv->amsdu_disable)
if (priv->amsdu_disable || !ptr->max_amsdu)
return MFALSE;
#ifdef UAP_SUPPORT
if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
@ -323,6 +323,23 @@ static INLINE t_u8 wlan_is_amsdu_allowed(mlan_private *priv, raListTbl *ptr,
MFALSE;
}
/**
* @brief This function gets max number of BA stream supported
*
* @param pmadapter A pointer to mlan_adapter
*
* @return number of BA streams
*/
static INLINE t_u32 wlan_get_bastream_limit(mlan_adapter *pmadapter)
{
t_u32 bastreams = ISSUPP_GETTXBASTREAM(pmadapter->hw_dot_11n_dev_cap);
if (pmadapter->mclient_tx_supported)
return pmadapter->tx_ba_stream_limit;
return bastreams;
}
/**
* @brief This function checks whether a BA stream is available or not
*
@ -342,7 +359,7 @@ static INLINE t_u8 wlan_is_bastream_avail(mlan_private *priv)
bastream_num += wlan_wmm_list_len(
(pmlan_list_head)&pmpriv->tx_ba_stream_tbl_ptr);
}
bastream_max = ISSUPP_GETTXBASTREAM(priv->adapter->hw_dot_11n_dev_cap);
bastream_max = wlan_get_bastream_limit(priv->adapter);
if (bastream_max == 0)
bastream_max = MLAN_MAX_TX_BASTREAM_DEFAULT;
return (bastream_num < bastream_max) ? MTRUE : MFALSE;

View file

@ -187,6 +187,9 @@ static t_u16 wlan_form_amsdu_txpd(mlan_private *priv, mlan_buffer *pmbuf,
head_ptr = pmbuf->pbuf + pmbuf->data_offset - Tx_PD_SIZEOF(pmadapter) -
priv->intf_hr_len;
/*making data buffer 8 ytes aligned for increasing TP with PCIE Scatter
* Gather*/
head_ptr = (t_u8 *)((t_ptr)head_ptr & ~((t_ptr)(8 - 1)));
ptx_pd = (TxPD *)(head_ptr + priv->intf_hr_len);
// coverity[bad_memset:SUPPRESS]
memset(pmadapter, ptx_pd, 0, Tx_PD_SIZEOF(pmadapter));
@ -675,6 +678,8 @@ static int wlan_send_amsdu_subframe_list(mlan_private *priv,
goto exit;
}
wlan_wmm_consume_mpdu_budget(pra_list);
while (pmbuf_src &&
((pkt_size + (pmbuf_src->data_len + LLC_SNAP_LEN) + headroom) <=
max_amsdu_size) &&
@ -683,6 +688,7 @@ static int wlan_send_amsdu_subframe_list(mlan_private *priv,
(pmlan_buffer)util_dequeue_list(pmadapter->pmoal_handle,
&pra_list->buf_head,
MNULL, MNULL);
wlan_wmm_consume_byte_budget(pra_list, pmbuf_src);
/* Collects TP statistics */
if (pmadapter->tp_state_on &&
(pkt_size > Tx_PD_SIZEOF(pmadapter)))
@ -728,7 +734,13 @@ static int wlan_send_amsdu_subframe_list(mlan_private *priv,
pmadapter->callbacks.moal_spin_unlock(pmadapter->pmoal_handle,
priv->wmm.ra_list_spinlock);
if (!pmbuf_last) {
PRINTM(MERROR,
"SG_AGGR ERROR: pkt_size=%d max_msdu_count=%d max_amsdu_size=%d msdu_in_tx_amsdu_cnt=%d\n",
pkt_size, max_msdu_count, max_amsdu_size,
msdu_in_tx_amsdu_cnt);
goto exit;
}
/* Last AMSDU packet does not need padding */
pkt_size -= pad;
pmbuf_last->data_len -= pad;
@ -758,9 +770,8 @@ static int wlan_send_amsdu_subframe_list(mlan_private *priv,
priv->wmm.packets_out[ptrindex]++;
priv->wmm.tid_tbl_ptr[ptrindex].ra_list_curr = pra_list;
}
pmadapter->bssprio_tbl[priv->bss_priority].bssprio_cur =
pmadapter->bssprio_tbl[priv->bss_priority]
.bssprio_cur->pnext;
wlan_advance_bss_on_pkt_push(
pmadapter, &pmadapter->bssprio_tbl[priv->bss_priority]);
pmadapter->callbacks.moal_spin_unlock(
pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock);
}
@ -865,12 +876,15 @@ int wlan_11n_aggregate_pkt(mlan_private *priv, raListTbl *pra_list,
goto exit;
}
wlan_wmm_consume_mpdu_budget(pra_list);
while (pmbuf_src && ((pkt_size + (pmbuf_src->data_len + LLC_SNAP_LEN) +
headroom) <= max_amsdu_size)) {
pmbuf_src =
(pmlan_buffer)util_dequeue_list(pmadapter->pmoal_handle,
&pra_list->buf_head,
MNULL, MNULL);
wlan_wmm_consume_byte_budget(pra_list, pmbuf_src);
/* Collects TP statistics */
if (pmadapter->tp_state_on &&
(pkt_size > Tx_PD_SIZEOF(pmadapter)))
@ -1011,9 +1025,10 @@ int wlan_11n_aggregate_pkt(mlan_private *priv, raListTbl *pra_list,
priv->wmm.packets_out[ptrindex]++;
priv->wmm.tid_tbl_ptr[ptrindex].ra_list_curr = pra_list;
}
pmadapter->bssprio_tbl[priv->bss_priority].bssprio_cur =
pmadapter->bssprio_tbl[priv->bss_priority]
.bssprio_cur->pnext;
wlan_advance_bss_on_pkt_push(
pmadapter, &pmadapter->bssprio_tbl[priv->bss_priority]);
pmadapter->callbacks.moal_spin_unlock(
pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock);
}

View file

@ -83,6 +83,7 @@ static country_code_mapping_t country_code_mapping[] = {
{"KR", 0x30, 0x30}, /* Republic Of Korea */
{"JP", 0xFF, 0x40}, /* Japan */
{"CN", 0x30, 0x50}, /* China */
{"TW", 0x30, 0x30}, /* TW support */
{"BR", 0x01, 0x09}, /* Brazil */
{"RU", 0x30, 0x0f}, /* Russia */
{"IN", 0x10, 0x06}, /* India */
@ -3232,8 +3233,9 @@ static void wlan_sort_cfp_otp_table(mlan_adapter *pmadapter)
*/
static void wlan_set_otp_cfp_max_tx_pwr(mlan_adapter *pmadapter, t_bool is6g)
{
t_u8 i, j;
t_u8 i, j, k, n;
t_u8 rows, cols, max = 0;
t_u8 bonded_chan_count = 0;
if (!pmadapter->otp_region)
return;
@ -3243,20 +3245,49 @@ static void wlan_set_otp_cfp_max_tx_pwr(mlan_adapter *pmadapter, t_bool is6g)
cols = pmadapter->tx_power_table_bg_cols;
if (pmadapter->tx_power_table_bg_size < (rows * cols))
goto table_a;
max = 0;
for (i = 0; i < rows; i++) {
max = 0;
if ((pmadapter->cfp_otp_bg + i)->dynamic.flags &
NXP_CHANNEL_DISABLED)
continue;
/* get the max value among all mod group for this
* channel */
for (j = 1; j < cols; j++)
/* Get the max value among all mod groups for this chan
*/
for (j = 1; j < cols; j++) {
max = MAX(
max,
pmadapter->tx_power_table_bg[i * cols +
j]);
}
(pmadapter->cfp_otp_bg + i)->max_tx_power = max;
bonded_chan_count++;
/* As the BG band allows overlapping 40MHz
* bonded groups, keep comparing the max value
* with the next consecutive 40Mhz channel, if
* all of below 4 cases are true:
* 1. this is not the last row
* 2. this channel suports 40 MHz
* 3. the next channel also supports 40MHz
* 4. the next channel is not disabled
*/
if ((i < (rows - 1)) &&
(!((pmadapter->cfp_otp_bg + i)->dynamic.flags &
NXP_CHANNEL_NOHT40)) &&
(!((pmadapter->cfp_otp_bg + i + 1)->dynamic.flags &
NXP_CHANNEL_NOHT40)) &&
(!((pmadapter->cfp_otp_bg + i + 1)->dynamic.flags &
NXP_CHANNEL_DISABLED))) {
continue;
}
/* Apply the max power value to all channels in this
* bonded group
*/
for (k = 0; k < bonded_chan_count; k++) {
(pmadapter->cfp_otp_bg + i - k)->max_tx_power =
max;
}
max = 0;
bonded_chan_count = 0;
}
}
table_a:
@ -3265,19 +3296,62 @@ table_a:
cols = pmadapter->tx_power_table_a_cols;
if (pmadapter->tx_power_table_a_size < (rows * cols))
return;
max = 0;
bonded_chan_count = 0;
for (i = 0; i < rows; i++) {
max = 0;
if ((pmadapter->cfp_otp_a + i)->dynamic.flags &
NXP_CHANNEL_DISABLED)
continue;
/* get the max value among all mod group for this
* channel */
/* The 5G cfp table is sorted based on the channel num
* and may contain 4G and 5.9G channels. As the cfp
* table index may not match the 5G powertable channel
* index, get the corresponding channel row from
* powertable
*/
n = 0;
while (n < pmadapter->tx_power_table_a_rows) {
if (pmadapter->tx_power_table_a[n * cols] ==
(pmadapter->cfp_otp_a + i)->channel)
break;
n++;
}
/* Get the max value among all mod groups for this chan
*/
for (j = 1; j < cols; j++)
max = MAX(max,
pmadapter->tx_power_table_a[i * cols +
pmadapter->tx_power_table_a[n * cols +
j]);
(pmadapter->cfp_otp_a + i)->max_tx_power = max;
bonded_chan_count++;
if ((i < (rows - 1)) &&
!((pmadapter->cfp_otp_a + i + 1)->dynamic.flags &
NXP_CHANNEL_DISABLED)) {
/* Compare the max power value with the next
* chan in this bonded group, unless this is the
* last or the next one is disabled
*/
if (!((pmadapter->cfp_otp_a + i)->dynamic.flags &
NXP_CHANNEL_NOHT80)) {
if (bonded_chan_count < 4)
continue;
} else if (!((pmadapter->cfp_otp_a + i)
->dynamic.flags &
NXP_CHANNEL_NOHT40)) {
if (bonded_chan_count < 2)
continue;
}
}
/* Apply the max power value to all channels in this
* bonded group
*/
for (k = 0; k < bonded_chan_count; k++)
(pmadapter->cfp_otp_a + i - k)->max_tx_power =
max;
max = 0;
bonded_chan_count = 0;
}
}
}
@ -3375,12 +3449,15 @@ void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left)
break;
}
}
for (i = 0; i < MLAN_CFP_TABLE_SIZE_A; i++) {
if (cfp_table_A[i].code ==
pmadapter->otp_region->region_code) {
max_tx_pwr_a = (cfp_table_A[i].cfp)
->max_tx_power;
break;
if (pmadapter->fw_bands & BAND_A) {
for (i = 0; i < MLAN_CFP_TABLE_SIZE_A; i++) {
if (cfp_table_A[i].code ==
pmadapter->otp_region->region_code) {
max_tx_pwr_a =
(cfp_table_A[i].cfp)
->max_tx_power;
break;
}
}
}
PRINTM(MCMND,
@ -3481,6 +3558,12 @@ void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left)
->dynamic.flags);
data++;
}
if (!(pmadapter->fw_bands & BAND_A)) {
pmadapter->tx_power_table_a_rows = 0;
pmadapter->tx_power_table_a_cols = 0;
break;
}
ret = pcb->moal_malloc(
pmadapter->pmoal_handle,
pmadapter->tx_power_table_a_rows *
@ -3564,6 +3647,12 @@ void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left)
data, i, i);
pmadapter->tx_power_table_bg_size = i;
data += i;
if (!(pmadapter->fw_bands & BAND_A)) {
pmadapter->tx_power_table_a_rows = 0;
pmadapter->tx_power_table_a_cols = 0;
break;
}
i = 0;
while ((i < pmadapter->tx_power_table_a_rows *
pmadapter->tx_power_table_a_cols) &&
@ -3592,16 +3681,19 @@ void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left)
((power_table_attr_t *)data)->rows_2g;
pmadapter->tx_power_table_bg_cols =
((power_table_attr_t *)data)->cols_2g;
pmadapter->tx_power_table_a_rows =
((power_table_attr_t *)data)->rows_5g;
pmadapter->tx_power_table_a_cols =
((power_table_attr_t *)data)->cols_5g;
PRINTM(MCMD_D,
"OTP region: bg_row=%d,bg_cols=%d a_row=%d, a_cols=%d\n",
PRINTM(MCMD_D, "OTP region: bg_row=%d,bg_cols=%d\n",
pmadapter->tx_power_table_bg_rows,
pmadapter->tx_power_table_bg_cols,
pmadapter->tx_power_table_a_rows,
pmadapter->tx_power_table_a_cols);
pmadapter->tx_power_table_bg_cols);
if (pmadapter->fw_bands & BAND_A) {
pmadapter->tx_power_table_a_rows =
((power_table_attr_t *)data)->rows_5g;
pmadapter->tx_power_table_a_cols =
((power_table_attr_t *)data)->cols_5g;
PRINTM(MCMD_D,
"OTP region: a_row=%d, a_cols=%d\n",
pmadapter->tx_power_table_a_rows,
pmadapter->tx_power_table_a_cols);
}
break;
default:
break;
@ -3612,8 +3704,6 @@ void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left)
if (!pmadapter->cfp_otp_bg || !pmadapter->tx_power_table_bg)
goto out;
wlan_set_otp_cfp_max_tx_pwr(pmadapter, MFALSE);
/* Set remaining flags for BG */
rows = pmadapter->tx_power_table_bg_rows;
cols = pmadapter->tx_power_table_bg_cols;
@ -3637,6 +3727,7 @@ void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left)
}
if (pmadapter->cfp_otp_a)
wlan_sort_cfp_otp_table(pmadapter);
wlan_set_otp_cfp_max_tx_pwr(pmadapter, MFALSE);
out:
LEAVE();
}
@ -3735,7 +3826,8 @@ mlan_status wlan_get_cfpinfo(pmlan_adapter pmadapter,
t_u8 cfp_code_a = pmadapter->region_code;
t_u8 cfp_code_bg = pmadapter->region_code;
t_u32 len = 0, size = 0;
t_u8 *req_buf, *tmp;
t_u8 *req_buf;
mlan_cfpinfo c = {0};
mlan_status ret = MLAN_STATUS_SUCCESS;
ENTER();
@ -3755,33 +3847,29 @@ mlan_status wlan_get_cfpinfo(pmlan_adapter pmadapter,
/* Calculate the total response size required to return region,
* country codes, cfp tables and power tables
*/
size = sizeof(pmadapter->country_code) + sizeof(pmadapter->region_code);
/* Add size to store region, country and environment codes */
size += sizeof(t_u32);
if (pmadapter->cfp_code_bg)
cfp_code_bg = pmadapter->cfp_code_bg;
size = sizeof(mlan_cfpinfo);
/* Get cfp table and its size corresponding to the region code */
cfp_bg = wlan_get_region_cfp_table(pmadapter, cfp_code_bg,
BAND_G | BAND_B, &cfp_no_bg);
size += cfp_no_bg * sizeof(chan_freq_power_t);
if (pmadapter->cfp_code_a)
cfp_code_a = pmadapter->cfp_code_a;
cfp_a = wlan_get_region_cfp_table(pmadapter, cfp_code_a, BAND_A,
&cfp_no_a);
size += cfp_no_a * sizeof(chan_freq_power_t);
if (pmadapter->otp_region)
size += sizeof(pmadapter->otp_region->environment);
/* Get power table size */
if (pmadapter->tx_power_table_bg) {
if (pmadapter->fw_bands & (BAND_B | BAND_G)) {
if (pmadapter->cfp_code_bg)
cfp_code_bg = pmadapter->cfp_code_bg;
cfp_bg = wlan_get_region_cfp_table(pmadapter, cfp_code_bg,
BAND_G | BAND_B, &cfp_no_bg);
size += cfp_no_bg * sizeof(chan_freq_power_t);
c.is2g_present = 1;
c.rows_2g = cfp_no_bg;
c.cols_2g = pmadapter->tx_power_table_bg_cols;
size += pmadapter->tx_power_table_bg_size;
/* Add size to store table size, rows and cols */
size += 3 * sizeof(t_u32);
}
if (pmadapter->tx_power_table_a) {
if (pmadapter->fw_bands & BAND_A) {
if (pmadapter->cfp_code_a)
cfp_code_a = pmadapter->cfp_code_a;
cfp_a = wlan_get_region_cfp_table(pmadapter, cfp_code_a, BAND_A,
&cfp_no_a);
size += cfp_no_a * sizeof(chan_freq_power_t);
c.is5g_present = 1;
c.rows_5g = cfp_no_a;
c.cols_5g = pmadapter->tx_power_table_a_cols;
size += pmadapter->tx_power_table_a_size;
size += 3 * sizeof(t_u32);
}
/* Check information buffer length of MLAN IOCTL */
if (pioctl_req->buf_len < size) {
@ -3792,90 +3880,52 @@ mlan_status wlan_get_cfpinfo(pmlan_adapter pmadapter,
ret = MLAN_STATUS_RESOURCE;
goto out;
}
/* Copy the total size of region code, country code and environment
* in first four bytes of the IOCTL request buffer and then copy
* codes respectively in following bytes
*/
req_buf = (t_u8 *)pioctl_req->pbuf;
size = sizeof(pmadapter->country_code) + sizeof(pmadapter->region_code);
/* Copy the nss, region code, country code and environment */
if (IS_STREAM_2X2(pmadapter->feature_control))
c.nss = 2;
else if (IS_CARDAW693(pmadapter->card_type) && !pmadapter->second_mac)
c.nss = 2;
else
c.nss = 1;
c.region_code = (t_u8)pmadapter->region_code;
c.country_code[0] = pmadapter->country_code[0];
c.country_code[1] = pmadapter->country_code[1];
if (pmadapter->otp_region)
size += sizeof(pmadapter->otp_region->environment);
tmp = (t_u8 *)&size;
memcpy_ext(pmadapter, req_buf, tmp, sizeof(size), sizeof(size));
len += sizeof(size);
memcpy_ext(pmadapter, req_buf + len, &pmadapter->region_code,
sizeof(pmadapter->region_code),
sizeof(pmadapter->region_code));
len += sizeof(pmadapter->region_code);
memcpy_ext(pmadapter, req_buf + len, &pmadapter->country_code,
sizeof(pmadapter->country_code),
sizeof(pmadapter->country_code));
len += sizeof(pmadapter->country_code);
if (pmadapter->otp_region) {
memcpy_ext(pmadapter, req_buf + len,
&pmadapter->otp_region->environment,
sizeof(pmadapter->otp_region->environment),
sizeof(pmadapter->otp_region->environment));
len += sizeof(pmadapter->otp_region->environment);
c.environment = pmadapter->otp_region->environment;
/* copy the mlan_cfpinfo struct at the start of req_buf */
memcpy_ext(pmadapter, req_buf, &c, sizeof(mlan_cfpinfo),
sizeof(mlan_cfpinfo));
len += sizeof(mlan_cfpinfo);
/* copy cfp tables */
if (cfp_bg) {
size = cfp_no_bg * sizeof(chan_freq_power_t);
memcpy_ext(pmadapter, req_buf + len, cfp_bg, size, size);
len += size;
}
if (cfp_a) {
size = cfp_no_a * sizeof(chan_freq_power_t);
memcpy_ext(pmadapter, req_buf + len, cfp_a, size, size);
len += size;
}
/* copy power tables */
if (pmadapter->tx_power_table_bg) {
memcpy_ext(pmadapter, req_buf + len,
pmadapter->tx_power_table_bg,
pmadapter->tx_power_table_bg_size,
pmadapter->tx_power_table_bg_size);
len += pmadapter->tx_power_table_bg_size;
}
if (pmadapter->tx_power_table_a) {
memcpy_ext(pmadapter, req_buf + len,
pmadapter->tx_power_table_a,
pmadapter->tx_power_table_a_size,
pmadapter->tx_power_table_a_size);
len += pmadapter->tx_power_table_a_size;
}
/* copy the cfp table size followed by the entire table */
if (!cfp_bg)
goto out;
size = cfp_no_bg * sizeof(chan_freq_power_t);
memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
len += sizeof(size);
memcpy_ext(pmadapter, req_buf + len, cfp_bg, size, size);
len += size;
if (!cfp_a)
goto out;
size = cfp_no_a * sizeof(chan_freq_power_t);
memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
len += sizeof(size);
memcpy_ext(pmadapter, req_buf + len, cfp_a, size, size);
len += size;
/* Copy the size of the power table, number of rows, number of cols
* and the entire power table
*/
if (!pmadapter->tx_power_table_bg)
goto out;
size = pmadapter->tx_power_table_bg_size;
memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
len += sizeof(size);
/* No. of rows */
size = pmadapter->tx_power_table_bg_rows;
memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
len += sizeof(size);
/* No. of cols */
size = pmadapter->tx_power_table_bg_size /
pmadapter->tx_power_table_bg_rows;
memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
len += sizeof(size);
memcpy_ext(pmadapter, req_buf + len, pmadapter->tx_power_table_bg,
pmadapter->tx_power_table_bg_size,
pmadapter->tx_power_table_bg_size);
len += pmadapter->tx_power_table_bg_size;
if (!pmadapter->tx_power_table_a)
goto out;
size = pmadapter->tx_power_table_a_size;
memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
len += sizeof(size);
/* No. of rows */
size = pmadapter->tx_power_table_a_rows;
memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
len += sizeof(size);
/* No. of cols */
size = pmadapter->tx_power_table_a_size /
pmadapter->tx_power_table_a_rows;
memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
len += sizeof(size);
memcpy_ext(pmadapter, req_buf + len, pmadapter->tx_power_table_a,
pmadapter->tx_power_table_a_size,
pmadapter->tx_power_table_a_size);
len += pmadapter->tx_power_table_a_size;
out:
if (pioctl_req)
pioctl_req->data_read_written = len;

View file

@ -1365,12 +1365,6 @@ static mlan_status wlan_dnld_cmd_to_fw(mlan_private *pmpriv,
pcmd->command == HostCmd_CMD_802_11_DISASSOCIATE))
wlan_clean_txrx(pmpriv);
if (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA &&
pmpriv->media_connected &&
(pcmd->command == HostCmd_CMD_802_11_DEAUTHENTICATE ||
pcmd->command == HostCmd_CMD_802_11_DISASSOCIATE))
wlan_clean_txrx(pmpriv);
PRINTM_GET_SYS_TIME(MCMND, &sec, &usec);
PRINTM_NETINTF(MCMND, pmpriv);
PRINTM(MCMND,
@ -1894,7 +1888,49 @@ t_void wlan_release_cmd_lock(mlan_adapter *pmadapter)
LEAVE();
return;
}
#ifdef USB
/**
* @brief This function requests a lock on Rx event.
*
* @param pmadapter A pointer to mlan_adapter structure
*
* @return N/A
*/
t_void wlan_request_event_lock(mlan_adapter *pmadapter)
{
mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
ENTER();
/* Call MOAL spin lock callback function */
pcb->moal_spin_lock(pmadapter->pmoal_handle,
pmadapter->pmlan_usb_event_lock);
LEAVE();
return;
}
/**
* @brief This function releases a lock on Rx event.
*
* @param pmadapter A pointer to mlan_adapter structure
*
* @return N/A
*/
t_void wlan_release_event_lock(mlan_adapter *pmadapter)
{
mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
ENTER();
/* Call MOAL spin unlock callback function */
pcb->moal_spin_unlock(pmadapter->pmoal_handle,
pmadapter->pmlan_usb_event_lock);
LEAVE();
return;
}
#endif
/**
* @brief This function prepare the command before sending to firmware.
*
@ -2209,6 +2245,7 @@ done:
return ret;
}
#if defined(SDIO) || defined(PCIE)
/**
* @brief This function handles the command error in pre_asleep state
*
@ -2226,20 +2263,12 @@ static void wlan_handle_cmd_error_in_pre_aleep(mlan_adapter *pmadapter,
pcmd_node = pmadapter->curr_cmd;
pmadapter->curr_cmd = MNULL;
if (pcmd_node) {
#ifdef USB
if (IS_USB(pmadapter->card_type)) {
pcmd_node->cmdbuf->data_offset += MLAN_TYPE_LEN;
pcmd_node->cmdbuf->data_len -= MLAN_TYPE_LEN;
}
#endif
#if defined(SDIO) || defined(PCIE)
if (!IS_USB(pmadapter->card_type)) {
pcmd_node->cmdbuf->data_offset +=
pmadapter->ops.intf_header_len;
pcmd_node->cmdbuf->data_len -=
pmadapter->ops.intf_header_len;
}
#endif
if (pcmd_node->respbuf) {
pmadapter->ops.cmdrsp_complete(pmadapter,
pcmd_node->respbuf,
@ -2251,6 +2280,7 @@ static void wlan_handle_cmd_error_in_pre_aleep(mlan_adapter *pmadapter,
wlan_release_cmd_lock(pmadapter);
LEAVE();
}
#endif
/**
* @brief This function handles the command response
@ -2403,26 +2433,29 @@ mlan_status wlan_process_cmdresp(mlan_adapter *pmadapter)
}
if (pmadapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
if (pmadapter->curr_cmd &&
#if defined(SDIO) || defined(PCIE)
if (!IS_USB(pmadapter->card_type) && pmadapter->curr_cmd &&
cmdresp_result == HostCmd_RESULT_PRE_ASLEEP) {
wlan_handle_cmd_error_in_pre_aleep(pmadapter,
cmdresp_no);
ret = MLAN_STATUS_FAILURE;
goto done;
}
#endif
pmadapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD;
if ((cmdresp_result == HostCmd_RESULT_OK) &&
(cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH))
ret = wlan_ret_802_11_hs_cfg(pmpriv, resp, pioctl_buf);
} else {
if (pmadapter->curr_cmd &&
#if defined(SDIO) || defined(PCIE)
if (!IS_USB(pmadapter->card_type) && pmadapter->curr_cmd &&
cmdresp_result == HostCmd_RESULT_PRE_ASLEEP) {
wlan_handle_cmd_error_in_pre_aleep(pmadapter,
cmdresp_no);
ret = MLAN_STATUS_FAILURE;
goto done;
}
#endif
/* handle response */
ret = pmpriv->ops.process_cmdresp(pmpriv, cmdresp_no, resp,
pioctl_buf);
@ -4356,6 +4389,102 @@ mlan_status wlan_ret_802_11_tx_rate_query(pmlan_private pmpriv,
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares command of fw_wakeup_method.
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param cmd_action The action: GET or SET
* @param pdata_buf A pointer to data buffer
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_cmd_802_11_fw_wakeup_method(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd,
t_u16 cmd_action, t_u16 *pdata_buf)
{
HostCmd_DS_802_11_FW_WAKEUP_METHOD *fwwm = &cmd->params.fwwakeupmethod;
mlan_fw_wakeup_params *fw_wakeup_params = MNULL;
MrvlIEtypes_WakeupSourceGPIO_t *tlv =
(MrvlIEtypes_WakeupSourceGPIO_t *)(t_u8 *)fwwm->tlv_buf;
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_FW_WAKE_METHOD);
cmd->size = sizeof(HostCmd_DS_802_11_FW_WAKEUP_METHOD) + S_DS_GEN;
fwwm->action = wlan_cpu_to_le16(cmd_action);
switch (cmd_action) {
case HostCmd_ACT_GEN_SET:
fw_wakeup_params = (mlan_fw_wakeup_params *)pdata_buf;
fwwm->method = wlan_cpu_to_le16(fw_wakeup_params->method);
if (fw_wakeup_params->method == WAKEUP_FW_THRU_GPIO) {
cmd->size += sizeof(MrvlIEtypes_WakeupSourceGPIO_t);
tlv->header.type = wlan_cpu_to_le16(
TLV_TYPE_HS_WAKEUP_SOURCE_GPIO);
tlv->header.len = wlan_cpu_to_le16(
sizeof(MrvlIEtypes_WakeupSourceGPIO_t) -
sizeof(MrvlIEtypesHeader_t));
tlv->ind_gpio = (t_u8)fw_wakeup_params->gpio_pin;
}
break;
case HostCmd_ACT_GEN_GET:
default:
fwwm->method = wlan_cpu_to_le16(WAKEUP_FW_UNCHANGED);
break;
}
cmd->size = wlan_cpu_to_le16(cmd->size);
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function handles the command response of fw_wakeup_method
*
* @param pmpriv A pointer to mlan_private structure
* @param resp A pointer to HostCmd_DS_COMMAND
* @param pioctl_buf A pointer to mlan_ioctl_req structure
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_ret_fw_wakeup_method(pmlan_private pmpriv,
HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf)
{
HostCmd_DS_802_11_FW_WAKEUP_METHOD *fwwm = &resp->params.fwwakeupmethod;
t_u16 action;
MrvlIEtypes_WakeupSourceGPIO_t *gpio_tlv =
(MrvlIEtypes_WakeupSourceGPIO_t *)(t_u8 *)fwwm->tlv_buf;
mlan_ds_pm_cfg *pmcfg = MNULL;
ENTER();
action = wlan_le16_to_cpu(fwwm->action);
pmpriv->adapter->fw_wakeup_method = wlan_le16_to_cpu(fwwm->method);
pmpriv->adapter->fw_wakeup_gpio_pin = 0;
if ((resp->size -
(sizeof(HostCmd_DS_802_11_FW_WAKEUP_METHOD) + S_DS_GEN)) ==
sizeof(MrvlIEtypes_WakeupSourceGPIO_t)) {
pmpriv->adapter->fw_wakeup_gpio_pin = gpio_tlv->ind_gpio;
}
PRINTM(MCMND, "FW wakeup method=%d, gpio=%d\n",
pmpriv->adapter->fw_wakeup_method,
pmpriv->adapter->fw_wakeup_gpio_pin);
if (pioctl_buf) {
pmcfg = (mlan_ds_pm_cfg *)pioctl_buf->pbuf;
pmcfg->param.fw_wakeup_params.method =
pmpriv->adapter->fw_wakeup_method;
pmcfg->param.fw_wakeup_params.gpio_pin =
pmpriv->adapter->fw_wakeup_gpio_pin;
}
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares command of robustcoex.
*
@ -4956,6 +5085,38 @@ mlan_status wlan_ret_tx_rate_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
return ret;
}
/**
* @brief This function prepares command of func_init.
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_cmd_func_init(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd)
{
HostCmd_DS_FUNC_INIT *func_init = &cmd->params.func_init;
mlan_adapter *pmadapter = pmpriv->adapter;
MrvlIEtypes_boot_time_cfg_t *pboot_time_tlv = MNULL;
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_FUNC_INIT);
cmd->size = S_DS_GEN + sizeof(MrvlIEtypes_boot_time_cfg_t);
pboot_time_tlv = (MrvlIEtypes_boot_time_cfg_t *)func_init->tlv_buf;
pboot_time_tlv->type = wlan_cpu_to_le16(TLV_TYPE_BOOT_TIME_CFG);
pboot_time_tlv->len =
wlan_cpu_to_le16(sizeof(MrvlIEtypes_boot_time_cfg_t) -
sizeof(MrvlIEtypesHeader_t));
if (pmadapter->init_para.bootup_cal_ctrl == 1) {
pboot_time_tlv->enable = MTRUE;
} else {
pboot_time_tlv->enable = MFALSE;
}
cmd->size = wlan_cpu_to_le16(cmd->size);
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function issues adapter specific commands
* to initialize firmware
@ -5076,6 +5237,17 @@ mlan_status wlan_adapter_init_cmd(pmlan_adapter pmadapter)
pmpriv_sta = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_STA);
#endif
/* Get fw wakeup method */
if (pmpriv) {
ret = wlan_prepare_cmd(pmpriv,
HostCmd_CMD_802_11_FW_WAKE_METHOD,
HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
if (ret) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
}
#ifdef SDIO
#endif
@ -5139,6 +5311,17 @@ mlan_status wlan_adapter_init_cmd(pmlan_adapter pmadapter)
mlan_ds_misc_mapping_policy dmcs_policy;
dmcs_policy.subcmd = 0;
dmcs_policy.mapping_policy = pmadapter->init_para.dmcs;
if (pmadapter->init_para.dmcs == 2)
dmcs_policy.mapping_policy = 0;
else {
dmcs_policy.mapping_policy = pmadapter->init_para.dmcs;
if ((pmadapter->init_para.dmcs == 1) &&
(pmadapter->init_para.pref_dbc == 2))
dmcs_policy.mapping_policy = 2;
else
dmcs_policy.mapping_policy = 1;
}
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_DMCS_CONFIG,
HostCmd_ACT_GEN_SET, 0, (t_void *)MNULL,
&dmcs_policy);
@ -6228,6 +6411,75 @@ mlan_status wlan_ret_mac_control(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function handles multi-client scheduling capabilites from FW
*
* @param pmpriv A pointer to mlan_private structure
* @param pmadapter A pointer to mlan_adapter structure
* @param tlv A pointer ti TLV payload from FW
* @param tlv_len length of TLV data pointed by tlv
*
* @return N/A
*/
static void wlan_setup_mclient_caps(mlan_private *pmpriv,
mlan_adapter *pmadapter, void *tlv,
t_u16 tlv_len)
{
MrvlIEtypes_MclientFwCaps_t caps = {0};
memcpy_ext(pmadapter, &caps, tlv, sizeof(caps), tlv_len);
PRINTM(MMSG, "mclient caps: tx_ba_stream_limit %u, tx_mpdu_pps %u %u",
wlan_le32_to_cpu(caps.tx_ba_stream_limit),
wlan_le32_to_cpu(caps.tx_mpdu_no_amsdu_pps),
wlan_le32_to_cpu(caps.tx_mpdu_with_amsdu_pps));
pmadapter->mclient_tx_supported =
pmadapter->init_para.mclient_scheduling;
pmadapter->tx_ba_stream_limit =
wlan_le32_to_cpu(caps.tx_ba_stream_limit);
pmadapter->tx_mpdu_with_amsdu_pps =
wlan_le32_to_cpu(caps.tx_mpdu_with_amsdu_pps);
pmadapter->tx_mpdu_no_amsdu_pps =
wlan_le32_to_cpu(caps.tx_mpdu_no_amsdu_pps);
if (pmadapter->mclient_tx_supported)
pmadapter->tx_ba_timeout_support = caps.tx_ba_timeout_support;
else
pmadapter->tx_ba_timeout_support = 1;
if (!pmadapter->tx_ba_timeout_support) {
t_u32 i;
for (i = 0; i < NELEMENTS(pmadapter->priv); ++i) {
mlan_private *mlan = pmadapter->priv[i];
if (mlan)
mlan->add_ba_param.timeout = 0;
}
}
wlan_cmd_mclient_scheduling_enable(pmpriv,
pmadapter->mclient_tx_supported);
}
/**
* @brief This function updates firmware extended caps
*
* @param pmadapter A pointer to mlan_adapter structure
*
* @return none
*/
static void wlan_update_fw_ext_cap(mlan_adapter *pmadapter)
{
if (!(pmadapter->init_para.dev_cap_mask & MBIT(16)))
pmadapter->fw_cap_ext &= ~FW_CAPINFO_EXT_802_11AX;
if (!(pmadapter->init_para.dev_cap_mask & MBIT(17)))
pmadapter->fw_cap_ext &= ~FW_CAPINFO_EXT_6G;
}
#define DISABLE_5G_MASK (1U << 10)
/**
* @brief This function handles the command response of get_hw_spec
*
@ -6256,11 +6508,18 @@ mlan_status wlan_ret_get_hw_spec(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
MrvlIEtypes_fw_cap_info_t *fw_cap_tlv = MNULL;
MrvlIEtypes_Secure_Boot_Uuid_t *sb_uuid_tlv = MNULL;
t_u32 feature_mask = 0;
ENTER();
pmadapter->fw_cap_info = wlan_le32_to_cpu(hw_spec->fw_cap_info);
pmadapter->fw_cap_info &= pmadapter->init_para.dev_cap_mask;
/* read feature list from lower 16-bytes only */
feature_mask =
0xffff0000 | (pmadapter->init_para.dev_cap_mask & 0xffff);
if (!(feature_mask & DISABLE_5G_MASK)) {
feature_mask &= ~(1 << 13);
}
pmadapter->fw_cap_info &= feature_mask;
PRINTM(MMSG, "fw_cap_info=0x%x, dev_cap_mask=0x%x\n",
wlan_le32_to_cpu(hw_spec->fw_cap_info),
@ -6404,6 +6663,12 @@ mlan_status wlan_ret_get_hw_spec(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
pmadapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
pmadapter->region_code = wlan_le16_to_cpu(hw_spec->region_code);
#ifdef STA_SUPPORT
/* Set country code */
memcpy(pmadapter, pmadapter->country_code,
wlan_11d_code_2_region(pmadapter, (t_u8)pmadapter->region_code),
COUNTRY_CODE_LEN - 1);
#endif
for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
/* Use the region code to search for the index */
if (pmadapter->region_code == region_code_index[i])
@ -6540,10 +6805,10 @@ mlan_status wlan_ret_get_hw_spec(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
fw_cap_tlv = (MrvlIEtypes_fw_cap_info_t *)tlv;
pmadapter->fw_cap_info =
wlan_le32_to_cpu(fw_cap_tlv->fw_cap_info);
pmadapter->fw_cap_info &=
pmadapter->init_para.dev_cap_mask;
pmadapter->fw_cap_info &= feature_mask;
pmadapter->fw_cap_ext =
wlan_le32_to_cpu(fw_cap_tlv->fw_cap_ext);
wlan_update_fw_ext_cap(pmadapter);
PRINTM(MCMND, "fw_cap_info=0x%x fw_cap_ext=0x%x\n",
pmadapter->fw_cap_info, pmadapter->fw_cap_ext);
break;
@ -6554,6 +6819,10 @@ mlan_status wlan_ret_get_hw_spec(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
PRINTM(MMSG, "uuid: %016llx%016llx\n",
pmadapter->uuid_lo, pmadapter->uuid_hi);
break;
case TLV_TYPE_MCLIENT_FW_CAPS:
wlan_setup_mclient_caps(pmpriv, pmadapter, tlv,
tlv_len);
break;
default:
break;
}
@ -7562,10 +7831,16 @@ mlan_status wlan_ret_802_11_rf_antenna(pmlan_private pmpriv,
defined(PCIE9097) || defined(SD9097) || defined(USB9097) || \
defined(SDIW624) || defined(SDAW693) || defined(PCIEAW693) || \
defined(PCIEIW624) || defined(USBIW624)
if (IS_CARD9098(pmadapter->card_type) ||
IS_CARDIW624(pmadapter->card_type) ||
IS_CARDAW693(pmadapter->card_type) ||
IS_CARD9097(pmadapter->card_type)) {
if (IS_CARDAW693(pmadapter->card_type) &&
(tx_ant_mode == RF_ANTENNA_AUTO)) {
PRINTM(MCMND,
"user_htstream=0x%x, tx_antenna=0x%x rx_antenna=0x%x\n",
pmadapter->user_htstream, tx_ant_mode,
rx_ant_mode);
} else if (IS_CARD9098(pmadapter->card_type) ||
IS_CARDIW624(pmadapter->card_type) ||
IS_CARDAW693(pmadapter->card_type) ||
IS_CARD9097(pmadapter->card_type)) {
tx_ant_mode &= 0x0303;
rx_ant_mode &= 0x0303;
/** 2G antcfg TX */
@ -8717,6 +8992,50 @@ mlan_status wlan_ret_get_tsf(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares command of chan region cfg
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param cmd_action the action: GET or SET
* @param pdata_buf A pointer to data buffer
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_cmd_chan_region_cfg(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
t_void *pdata_buf)
{
HostCmd_DS_CHAN_REGION_CFG *reg = MNULL;
mlan_ds_chan_attr *ca = (mlan_ds_chan_attr *)pdata_buf;
MrvlIEtypesHeader_t *tlv = MNULL;
t_u32 buf_size = 0;
ENTER();
reg = (HostCmd_DS_CHAN_REGION_CFG *)&cmd->params.reg_cfg;
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_CHAN_REGION_CFG);
cmd->size =
wlan_cpu_to_le16(sizeof(HostCmd_DS_CHAN_REGION_CFG) + S_DS_GEN);
reg->action = wlan_cpu_to_le16(cmd_action);
buf_size = MRVDRV_SIZE_OF_CMD_BUFFER - cmd->size;
if (ca && (cmd_action == HostCmd_ACT_GEN_SET)) {
tlv = (MrvlIEtypesHeader_t *)&reg->tlv_buffer;
tlv->type = wlan_cpu_to_le16(TLV_TYPE_CHAN_ATTR_CFG);
ca->data_len =
MIN(ca->data_len, MIN(sizeof(ca->chan_attr), buf_size));
tlv->len = wlan_cpu_to_le16(ca->data_len);
memcpy_ext(pmpriv->adapter,
(t_u8 *)tlv + sizeof(MrvlIEtypesHeader_t),
(t_u8 *)ca->chan_attr, ca->data_len, buf_size);
cmd->size += wlan_cpu_to_le16(sizeof(MrvlIEtypesHeader_t) +
ca->data_len);
}
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function handles the command response of chan_region_cfg
*
@ -8749,16 +9068,20 @@ mlan_status wlan_ret_chan_region_cfg(pmlan_private pmpriv,
action = wlan_le16_to_cpu(reg->action);
if (action != HostCmd_ACT_GEN_GET) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
tlv_buf = (t_u8 *)reg + sizeof(*reg);
tlv_buf = (t_u8 *)&resp->params.reg_cfg.tlv_buffer;
if (resp->size > (S_DS_GEN + sizeof(*reg))) {
tlv_buf_left = resp->size - S_DS_GEN - sizeof(*reg);
} else {
PRINTM(MERROR, "Region size calculation ERROR.\n");
}
if (!tlv_buf || !tlv_buf_left) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
/* Add FW cfp tables and region info */
wlan_add_fw_cfp_tables(pmpriv, tlv_buf, tlv_buf_left);
@ -10379,7 +10702,7 @@ mlan_status wlan_ret_set_get_low_power_mode_cfg(pmlan_private pmpriv,
}
/**
* @brief This function handles the command response of
* packet aggregation
* CHAN_TRPC setting
*
* @param pmpriv A pointer to mlan_private structure
* @param resp A pointer to HostCmd_DS_COMMAND
@ -10572,6 +10895,122 @@ mlan_status wlan_ret_range_ext(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares command of TSP config.
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param cmd_action The action: GET or SET
* @param pdata_buf A pointer to data buffer
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_cmd_tsp_config(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
t_u16 cmd_action, t_void *pdata_buf)
{
HostCmd_DS_TSP_CFG *tsp_config = &cmd->params.tsp_cfg;
mlan_ds_tsp_cfg *cfg = (mlan_ds_tsp_cfg *)pdata_buf;
t_u8 rfu = 0;
t_u8 rpath = 0;
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TSP_CFG);
cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_TSP_CFG) + S_DS_GEN);
tsp_config->action = wlan_cpu_to_le16(cmd_action);
if (cmd_action == HostCmd_ACT_GEN_SET) {
tsp_config->enable = wlan_cpu_to_le16(cfg->enable);
if (tsp_config->enable == 0) {
cmd->size = wlan_cpu_to_le16(
sizeof(tsp_config->action) +
sizeof(tsp_config->enable) + S_DS_GEN);
} else {
tsp_config->backoff = wlan_cpu_to_le32(cfg->backoff);
tsp_config->high_thrshld =
wlan_cpu_to_le32(cfg->high_thrshld);
tsp_config->low_thrshld =
wlan_cpu_to_le32(cfg->low_thrshld);
tsp_config->reg_cau_val =
wlan_cpu_to_le32(cfg->reg_cau_val);
tsp_config->duty_cyc_step =
wlan_cpu_to_le32(cfg->duty_cyc_step);
tsp_config->duty_cyc_min =
wlan_cpu_to_le32(cfg->duty_cyc_min);
tsp_config->high_thrshld_temp =
wlan_cpu_to_le32(cfg->high_thrshld_temp);
tsp_config->low_thrshld_temp =
wlan_cpu_to_le32(cfg->low_thrshld_temp);
for (rfu = 0; rfu < MAX_RFUS; rfu++) {
for (rpath = 0; rpath < MAX_PATHS; rpath++) {
tsp_config->reg_rfu_val
[rfu][rpath] = wlan_cpu_to_le32(
cfg->reg_rfu_temp[rfu][rpath]);
}
}
}
}
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function handles the command response of TSP config.
*
* @param pmpriv A pointer to mlan_private structure
* @param resp A pointer to HostCmd_DS_COMMAND structure
* @param pioctl_buf A pointer to mlan_ioctl_req buf
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_ret_tsp_config(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf)
{
HostCmd_DS_TSP_CFG *tsp_config = &resp->params.tsp_cfg;
mlan_ds_misc_cfg *cfg = MNULL;
t_u8 rfu = 0;
t_u8 rpath = 0;
ENTER();
if (pioctl_buf) {
cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
if (wlan_le16_to_cpu(tsp_config->action) ==
HostCmd_ACT_GEN_GET) {
cfg->param.tsp_cfg.enable =
wlan_le16_to_cpu(tsp_config->enable);
cfg->param.tsp_cfg.backoff =
wlan_le32_to_cpu(tsp_config->backoff);
cfg->param.tsp_cfg.high_thrshld =
wlan_le32_to_cpu(tsp_config->high_thrshld);
cfg->param.tsp_cfg.low_thrshld =
wlan_le32_to_cpu(tsp_config->low_thrshld);
cfg->param.tsp_cfg.reg_cau_val =
wlan_le32_to_cpu(tsp_config->reg_cau_val);
cfg->param.tsp_cfg.duty_cyc_step =
wlan_le32_to_cpu(tsp_config->duty_cyc_step);
cfg->param.tsp_cfg.duty_cyc_min =
wlan_le32_to_cpu(tsp_config->duty_cyc_min);
cfg->param.tsp_cfg.high_thrshld_temp =
wlan_le32_to_cpu(tsp_config->high_thrshld_temp);
cfg->param.tsp_cfg.low_thrshld_temp =
wlan_le32_to_cpu(tsp_config->low_thrshld_temp);
for (rfu = 0; rfu < MAX_RFUS; rfu++) {
for (rpath = 0; rpath < MAX_PATHS; rpath++) {
cfg->param.tsp_cfg
.reg_rfu_temp[rfu][rpath] =
wlan_le32_to_cpu(
tsp_config->reg_rfu_val
[rfu][rpath]);
}
}
}
}
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares command of TX_FRAME
*
@ -10729,3 +11168,119 @@ mlan_status wlan_cmd_edmac_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function send command to FW to configure multi-client scheduling
*
* @param pmpriv A pointer to mlan_private structure
* @param enable Enable/Disable multi-client scheduling
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_cmd_mclient_scheduling_enable(pmlan_private pmpriv,
t_bool enable)
{
HostCmd_MCLIENT_SCHEDULE_CFG cfg;
memset(pmpriv->adapter, &cfg, 0xff, sizeof(cfg));
cfg.action = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
cfg.mclient_enable = !!enable;
cfg.ps_mode_change_report = !!enable;
return wlan_prepare_cmd(pmpriv, HostCmd_CMD_MCLIENT_SCHEDULE_CFG,
HostCmd_ACT_GEN_SET, 0, MNULL, &cfg);
}
/**
* @brief This function prepares command to configure multi-client scheduling
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param cmd_action Action: GET or SET
* @param pdata_buf A pointer to data buffer
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_cmd_mclient_scheduling_cfg(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd,
t_u16 cmd_action, t_pvoid pdata_buf)
{
HostCmd_MCLIENT_SCHEDULE_CFG *req = pdata_buf;
HostCmd_MCLIENT_SCHEDULE_CFG *mclient_cfg = &cmd->params.mclient_cfg;
const t_u16 cmd_size = sizeof(*mclient_cfg);
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MCLIENT_SCHEDULE_CFG);
cmd->size = wlan_cpu_to_le16(cmd_size + S_DS_GEN);
memcpy_ext(pmpriv->adapter, mclient_cfg, req, cmd_size, cmd_size);
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares command to query TX rate
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param cmd_action Action: GET or SET
* @param pdata_buf A pointer to data buffer
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_cmd_sta_tx_rate_req(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
t_pvoid pdata_buf)
{
HostCmd_CMD_802_11_STA_TX_RATE *req = pdata_buf;
HostCmd_CMD_802_11_STA_TX_RATE *sta_tx_rate_req =
&cmd->params.sta_rx_rate;
const t_u16 cmd_size = MIN(sizeof(req->entry),
(sizeof(req->entry[0]) * req->num_entries));
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_PEER_TX_RATE_QUERY);
cmd->size = wlan_cpu_to_le16(cmd_size + S_DS_GEN);
memcpy_ext(pmpriv->adapter, sta_tx_rate_req, req, cmd_size, cmd_size);
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function handles HostCmd_CMD_PEER_TX_RATE_QUERY command response
*
* @param pmpriv A pointer to mlan_private structure
* @param resp A pointer to command response
* @param pioctl_buf A pointer to mlan_ioctl_req structure
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_ret_sta_tx_rate(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf)
{
HostCmd_CMD_802_11_STA_TX_RATE *info = &resp->params.sta_rx_rate;
int i;
mlan_adapter *pmadapter = pmpriv->adapter;
const t_s32 entry_size = sizeof(info->entry[0]);
t_s32 size = resp->size - S_DS_GEN;
pmadapter->callbacks.moal_spin_lock(pmadapter->pmoal_handle,
pmpriv->wmm.ra_list_spinlock);
for (i = 0; i < NELEMENTS(info->entry) && size >= entry_size;
i++, size -= entry_size) {
wlan_wmm_update_sta_tx_rate(pmpriv, info->entry[i].sta_mac,
&info->entry[i].rate);
}
pmadapter->callbacks.moal_spin_unlock(pmadapter->pmoal_handle,
pmpriv->wmm.ra_list_spinlock);
return MLAN_STATUS_SUCCESS;
}

View file

@ -206,6 +206,8 @@ typedef t_s32 t_sval;
#define MLAN_RATE_INDEX_MCS4 4
/** Rate index for MCS 7 */
#define MLAN_RATE_INDEX_MCS7 7
/** Rate index for MCS 8 */
#define MLAN_RATE_INDEX_MCS8 8
/** Rate index for MCS 9 */
#define MLAN_RATE_INDEX_MCS9 9
/** Rate index for MCS11 */
@ -395,14 +397,17 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define CARD_TYPE_IW624 0x0b
/** Black bird card type */
#define CARD_TYPE_AW693 0x0c
/** IW615 card type */
#define CARD_TYPE_IW615 0x0d
/** IW610 card type */
#define CARD_TYPE_IW610 0x0d
/** 9098 A0 reverion num */
#define CHIP_9098_REV_A0 1
#define CHIP_9098_REV_A1 2
/** 9097 CHIP REV */
#define CHIP_9097_REV_B0 1
/** Blackbird reverion num */
#define CHIP_AW693_REV_A0 1
#define CHIP_AW693_REV_A1 2
#define INTF_MASK 0xff
#define CARD_TYPE_MASK 0xff
@ -432,8 +437,8 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define CARD_TYPE_SDIW624 (CARD_TYPE_IW624 | (INTF_SD << 8))
/** SD_IW624 card type */
#define CARD_TYPE_SDAW693 (CARD_TYPE_AW693 | (INTF_SD << 8))
/** SD_IW615 card type */
#define CARD_TYPE_SDIW615 (CARD_TYPE_IW615 | (INTF_SD << 8))
/** SD_IW610 card type */
#define CARD_TYPE_SDIW610 (CARD_TYPE_IW610 | (INTF_SD << 8))
#define IS_SD8887(ct) (CARD_TYPE_SD8887 == (ct))
#define IS_SD8897(ct) (CARD_TYPE_SD8897 == (ct))
@ -447,7 +452,7 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define IS_SD8801(ct) (CARD_TYPE_SD8801 == (ct))
#define IS_SDIW624(ct) (CARD_TYPE_SDIW624 == (ct))
#define IS_SDAW693(ct) (CARD_TYPE_SDAW693 == (ct))
#define IS_SDIW615(ct) (CARD_TYPE_SDIW615 == (ct))
#define IS_SDIW610(ct) (CARD_TYPE_SDIW610 == (ct))
/** SD8887 Card */
#define CARD_SD8887 "SD8887"
@ -473,8 +478,8 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define CARD_SDIW624 "SDIW624"
/** SDAW693 Card */
#define CARD_SDAW693 "SDAW693"
/** SDIW615 Card */
#define CARD_SDIW615 "SDIW615"
/** SDIW610 Card */
#define CARD_SDIW610 "SDIW610"
#endif
#ifdef PCIE
@ -533,8 +538,8 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define CARD_TYPE_USB9097 (CARD_TYPE_9097 | (INTF_USB << 8))
/** USBIW624 card type */
#define CARD_TYPE_USBIW624 (CARD_TYPE_IW624 | (INTF_USB << 8))
/** USBIW615 card type */
#define CARD_TYPE_USBIW615 (CARD_TYPE_IW615 | (INTF_USB << 8))
/** USBIW610 card type */
#define CARD_TYPE_USBIW610 (CARD_TYPE_IW610 | (INTF_USB << 8))
#define IS_USB8801(ct) (CARD_TYPE_USB8801 == (ct))
#define IS_USB8897(ct) (CARD_TYPE_USB8897 == (ct))
@ -543,7 +548,7 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define IS_USB9098(ct) (CARD_TYPE_USB9098 == (ct))
#define IS_USB9097(ct) (CARD_TYPE_USB9097 == (ct))
#define IS_USBIW624(ct) (CARD_TYPE_USBIW624 == (ct))
#define IS_USBIW615(ct) (CARD_TYPE_USBIW615 == (ct))
#define IS_USBIW610(ct) (CARD_TYPE_USBIW610 == (ct))
/** USB8801 Card */
#define CARD_USB8801 "USB8801"
@ -559,14 +564,15 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define CARD_USB9097 "USBIW620"
/** USBIW624 Card */
#define CARD_USBIW624 "USBIW624"
/** USBIW615 Card */
#define CARD_USBIW615 "USBIW615"
/** USBIW610 Card */
#define CARD_USBIW610 "USBIW610"
#endif
#define IS_CARD8801(ct) (CARD_TYPE_8801 == ((ct)&0xf))
#define IS_CARD8887(ct) (CARD_TYPE_8887 == ((ct)&0xf))
#define IS_CARD8897(ct) (CARD_TYPE_8897 == ((ct)&0xf))
#define IS_CARD8977(ct) (CARD_TYPE_8977 == ((ct)&0xf))
#define IS_CARD8978(ct) (CARD_TYPE_8978 == ((ct)&0xf))
#define IS_CARD8997(ct) (CARD_TYPE_8997 == ((ct)&0xf))
#define IS_CARD8987(ct) (CARD_TYPE_8987 == ((ct)&0xf))
#define IS_CARD9098(ct) (CARD_TYPE_9098 == ((ct)&0xf))
@ -574,7 +580,7 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define IS_CARD9177(ct) (CARD_TYPE_9177 == ((ct)&0xf))
#define IS_CARDIW624(ct) (CARD_TYPE_IW624 == ((ct)&0xf))
#define IS_CARDAW693(ct) (CARD_TYPE_AW693 == ((ct)&0xf))
#define IS_CARDIW615(ct) (CARD_TYPE_IW615 == ((ct)&0xf))
#define IS_CARDIW610(ct) (CARD_TYPE_IW610 == ((ct)&0xf))
typedef struct _card_type_entry {
t_u16 card_type;
@ -648,6 +654,8 @@ typedef enum {
#define MLAN_BUF_FLAG_MC_AGGR_PKT MBIT(17)
#define MLAN_BUF_FLAG_TCP_PKT MBIT(18)
#define MLAN_BUF_FLAG_LLDE_PKT_FILTER MBIT(19)
#ifdef DEBUG_LEVEL1
@ -660,8 +668,8 @@ typedef enum {
#define MEVENT MBIT(5)
#define MINTR MBIT(6)
#define MIOCTL MBIT(7)
#define MREG_D MBIT(9)
#define MREG MBIT(10)
#define MMPA_D MBIT(15)
#define MDAT_D MBIT(16)
@ -670,7 +678,7 @@ typedef enum {
#define MFW_D MBIT(19)
#define MIF_D MBIT(20)
#define MFWDP_D MBIT(21)
#define MSCH_D MBIT(22)
#define MENTRY MBIT(28)
#define MWARN MBIT(29)
#define MINFO MBIT(30)
@ -1630,7 +1638,7 @@ typedef MLAN_PACK_START struct _tdls_each_link_status {
/** Key Length */
t_u8 key_length;
/** actual key */
t_u8 key[1];
t_u8 key[];
} MLAN_PACK_END tdls_each_link_status;
/** TDLS configuration data */
@ -1757,7 +1765,7 @@ typedef MLAN_PACK_START struct _tdls_all_config {
/** number of links */
t_u8 active_links;
/** structure for link status */
tdls_each_link_status link_stats[1];
tdls_each_link_status link_stats[];
} MLAN_PACK_END tdls_link_status_resp;
} u;
@ -2596,6 +2604,7 @@ typedef struct _mlan_callbacks {
t_u8 antenna);
t_void (*moal_updata_peer_signal)(t_void *pmoal, t_u32 bss_index,
t_u8 *peer_addr, t_s8 snr, t_s8 nflr);
mlan_status (*moal_get_host_time_ns)(t_u64 *time);
t_u64 (*moal_do_div)(t_u64 num, t_u32 base);
void (*moal_tp_accounting)(t_void *pmoal, t_void *buf,
t_u32 drop_point);
@ -2694,6 +2703,8 @@ typedef struct _mlan_device {
#endif
/** Auto deep sleep */
t_u32 auto_ds;
/** Boot Time Config */
t_u32 bootup_cal_ctrl;
/** IEEE PS mode */
t_u32 ps_mode;
/** Max Tx buffer size */
@ -2745,6 +2756,8 @@ typedef struct _mlan_device {
t_u8 uap_max_sta;
/** wacp mode */
t_u8 wacp_mode;
/** custom Fw data */
t_u32 fw_data_cfg;
/** drv mode */
t_u32 drv_mode;
/** dfs w53 cfg */
@ -2763,8 +2776,12 @@ typedef struct _mlan_device {
t_u32 antcfg;
/** dmcs */
t_u8 dmcs;
t_u8 pref_dbc;
t_u32 reject_addba_req;
t_u32 max_tx_pending;
t_u16 tx_budget;
t_u8 mclient_scheduling;
} mlan_device, *pmlan_device;
/** MLAN API function prototype */

View file

@ -209,5 +209,9 @@ ENUM_ELEMENT(EVENT_DUMMY_HOST_WAKEUP_SIGNAL, 0x0001),
/** Event ID: Bulk Tx status */
ENUM_ELEMENT(EVENT_TX_STATUS_BULK_REPORT, 0x00A2),
/** Event ID: peer's power save mode change */
ENUM_ELEMENT(EVENT_PEER_PS_MODE_CHANGE, 0x00A3),
ENUM_ELEMENT(EVENT_CHAN_SWITCH_TO_6G_BLOCK, 0x00A4),
/* Always keep this last */
ENUM_ELEMENT_LAST(__HostEvent_Last)

View file

@ -156,6 +156,30 @@ extern t_u8 SupportedRates_BG[BG_SUPPORTED_RATES];
extern t_u8 SupportedRates_A[A_SUPPORTED_RATES];
extern t_u8 SupportedRates_N[N_SUPPORTED_RATES];
#define MAX_FW_DATA_BLOCK 8
#if defined(USB8978) || defined(SD8978)
/** Fw custom data */
#define FW_DATA_FW_REMAP_CONFIG_LEN 44
extern t_u8 fw_data_fw_remap_config[FW_DATA_FW_REMAP_CONFIG_LEN];
#endif
#if defined(USB8978)
#define FW_DATA_USB_BULK_EP_LEN 36
extern t_u8 fw_data_usb_bulk_ep[FW_DATA_USB_BULK_EP_LEN];
#endif
#if defined(USB8978) || defined(SD8978)
#define FW_DATA_DPD_CURRENT_OPT_LEN 36
extern t_u8 fw_data_dpd_current_opt[FW_DATA_DPD_CURRENT_OPT_LEN];
#endif
/** Firmware wakeup method : Unchanged */
#define WAKEUP_FW_UNCHANGED 0
/** Firmware wakeup method : Through interface */
#define WAKEUP_FW_THRU_INTERFACE 1
/** Firmware wakeup method : Through GPIO*/
#define WAKEUP_FW_THRU_GPIO 2
/** Default value of GPIO */
#define DEF_WAKEUP_FW_GPIO 0
/** Default auto deep sleep mode */
#define DEFAULT_AUTO_DS_MODE MTRUE
/** Default power save mode */
@ -820,12 +844,15 @@ typedef enum _WLAN_802_11_WEP_STATUS {
#define MOD_CLASS_HT 0x08
/** Modulation class for VHT Rates */
#define MOD_CLASS_VHT 0x09
/** HT bandwidth 20 MHz */
#define HT_BW_20 0
/** HT bandwidth 40 MHz */
#define HT_BW_40 1
/** HT bandwidth 80 MHz */
#define HT_BW_80 2
/** Modulation class for HE Rates */
#define MOD_CLASS_HE 0x0A
/** HT/VHT/HE bandwidth 20 MHz */
#define BW_20 0
/** HT/VHT/HE bandwidth 40 MHz */
#define BW_40 1
/** HT/VHT/HE bandwidth 80 MHz */
#define BW_80 2
/** Firmware Host Command ID Constants */
@ -1154,6 +1181,7 @@ typedef enum _ENH_PS_MODES {
#define HostCmd_ACT_GEN_REMOVE 0x0004
/** General purpose action : Reset */
#define HostCmd_ACT_GEN_RESET 0x0005
/** Host command action : Set Rx */
#define HostCmd_ACT_SET_RX 0x0001
/** Host command action : Set Tx */
@ -2474,6 +2502,16 @@ typedef MLAN_PACK_START struct _filter_entry {
t_u32 ipv4_addr;
} MLAN_PACK_END filter_entry;
#define NUM_EVT_MASK_BITMAP 10
typedef struct _HostCmd_DS_EVENT_MASK_CFG {
/** Get / Set action*/
t_u8 action;
/** feature enabled or disabled */
t_u8 enabled;
/** Bit map of the masked events. 1 - masked, 0 - allowed */
t_u32 events_bitmap[NUM_EVT_MASK_BITMAP];
} MLAN_PACK_END HostCmd_DS_EVENT_MASK_CFG;
typedef MLAN_PACK_START struct _HostCmd_DS_MEF_CFG {
/** Criteria */
t_u32 criteria;
@ -3192,6 +3230,8 @@ typedef MLAN_PACK_START struct _HostCmd_DS_802_11_GET_LOG {
t_u32 gdma_abort_cnt;
/** Rx Reset MAC Count */
t_u32 g_reset_rx_mac_cnt;
/** SDMA FSM stuck Count*/
t_u32 SdmaStuckCnt;
// Ownership error counters
/*Error Ownership error count*/
t_u32 dwCtlErrCnt;
@ -3521,6 +3561,15 @@ typedef MLAN_PACK_START struct _HostCmd_DS_802_11_HS_CFG_ENH {
} params;
} MLAN_PACK_END HostCmd_DS_802_11_HS_CFG_ENH;
/** HostCmd_CMD_802_11_FW_WAKE_METHOD */
typedef MLAN_PACK_START struct _HostCmd_DS_802_11_FW_WAKEUP_METHOD {
/** Action */
t_u16 action;
/** Method */
t_u16 method;
t_u8 tlv_buf[];
} MLAN_PACK_END HostCmd_DS_802_11_FW_WAKEUP_METHOD;
/** HostCmd_CMD_802_11_ROBUSTCOEX */
typedef MLAN_PACK_START struct _HostCmd_DS_802_11_ROBUSTCOEX {
/** Action */
@ -3723,6 +3772,25 @@ typedef MLAN_PACK_START struct _HostCmd_DS_TX_RATE_CFG {
t_u8 tlv_buf[];
} MLAN_PACK_END HostCmd_DS_TX_RATE_CFG;
/** HostCmd_DS_FUNC_INIT */
typedef MLAN_PACK_START struct _HostCmd_DS_FUNC_INIT {
/* MrvlIEtypes_boot_time_cfg_t */
t_u8 tlv_buf[0];
} MLAN_PACK_END HostCmd_DS_FUNC_INIT;
/** BootTimeCfg TLV */
typedef MLAN_PACK_START struct _MrvlIEtypes_boot_time_cfg_t {
/** Header type */
t_u16 type;
/** Header length */
t_u16 len;
/* enable: 1: enable boot time optimization 0: disable boot time
* optimization */
t_u8 enable;
/* reserved */
t_u8 reserve[3];
} MLAN_PACK_END MrvlIEtypes_boot_time_cfg_t, *pMrvlIEtypes_boot_time_cfg_t;
/** Power_Group_t */
typedef MLAN_PACK_START struct _Power_Group_t {
/** Modulation Class */
@ -3925,6 +3993,31 @@ typedef MLAN_PACK_START struct _HostCmd_DS_CROSS_CHIP_SYNCH {
t_u32 init_tsf_high;
} MLAN_PACK_END HostCmd_DS_CROSS_CHIP_SYNCH;
typedef MLAN_PACK_START struct _HostCmd_DS_TSP_CFG {
/** TSP config action 0-GET, 1-SET */
t_u16 action;
/** TSP enable/disable tsp algothrim */
t_u16 enable;
/** TSP config power backoff */
t_s32 backoff;
/** TSP config high threshold */
t_s32 high_thrshld;
/** TSP config low threshold */
t_s32 low_thrshld;
/** TSP config DUTY_CYC_STEP */
t_s32 duty_cyc_step;
/** TSP config DUTY_CYC_MIN */
t_s32 duty_cyc_min;
/** TSP config HIGH_THRESHOLD_TEMP */
t_s32 high_thrshld_temp;
/** TSP config LOW_THRESHOLD_TEMP */
t_s32 low_thrshld_temp;
/** TSP CAU TSEN read value */
t_s32 reg_cau_val;
/** TSP RFU read values */
t_s32 reg_rfu_val[MAX_RFUS][MAX_PATHS];
} MLAN_PACK_END HostCmd_DS_TSP_CFG;
MLAN_PACK_START struct coalesce_filt_field_param {
t_u8 operation;
t_u8 operand_len;
@ -4444,8 +4537,8 @@ typedef struct MLAN_PACK_START _hostcmd_twt_setup {
t_u8 twt_request;
/** TWT Setup State. Set to 0 by driver, filled by FW in response*/
t_u8 twt_setup_state;
/** Reserved, set to 0. */
t_u8 reserved[2];
/** TWT link lost timeout threshold */
t_u16 bcnMiss_threshold;
} MLAN_PACK_END hostcmd_twt_setup, *phostcmd_twt_setup;
/** Type definition of hostcmd_twt_teardown */
@ -5164,6 +5257,8 @@ typedef MLAN_PACK_START struct _HostCmd_DS_VERSION_EXT {
typedef MLAN_PACK_START struct _HostCmd_DS_CHAN_REGION_CFG {
/** Action */
t_u16 action;
/** TLV buffer */
t_u8 tlv_buffer[1];
} MLAN_PACK_END HostCmd_DS_CHAN_REGION_CFG;
/** HostCmd_DS_REGION_POWER_CFG */
@ -6745,6 +6840,20 @@ typedef MLAN_PACK_START struct _dual_desc_buf {
t_u64 paddr;
} MLAN_PACK_END adma_dual_desc_buf, *padma_dual_desc_buf;
/** PCIE ADMA configuration */
typedef MLAN_PACK_START struct _HostCmd_DS_PCIE_ADMA_INIT {
/* tx adma ring size */
t_u16 tx_ring_size;
/* rx adma ring size */
t_u16 rx_ring_size;
/* event adma ring size */
t_u16 evt_ring_size;
/* interrupt mode: 0-legacy 1-msi 2-msix */
t_u8 int_mode;
/** reserved */
t_u8 reserved;
} HostCmd_DS_PCIE_ADMA_INIT;
#if defined(PCIE8997) || defined(PCIE8897)
/** PCIE ring buffer description for DATA */
typedef MLAN_PACK_START struct _mlan_pcie_data_buf {
@ -7296,6 +7405,52 @@ typedef MLAN_PACK_START struct _HostCmd_DS_EDMAC_CFG {
t_u32 ed_bitmap_txq_lock;
} MLAN_PACK_END HostCmd_DS_EDMAC_CFG;
/* Auth, Assoc Timeout configuration: HostCmd_DS_AUTH_ASSOC_TIMEOUT_CFG */
typedef MLAN_PACK_START struct _HostCmd_DS_AUTH_ASSOC_TIMEOUT_CFG {
/** Action */
t_u16 action;
/** auth timeout */
t_u16 auth_timeout;
/** Auth retry timeout if received ack */
t_u16 auth_retry_timeout_if_ack;
/** Auth retry timeout if ack is not received */
t_u16 auth_retry_timeout_if_no_ack;
/** assoc timeout */
t_u16 assoc_timeout;
/** reassoc timeout */
t_u16 reassoc_timeout;
/** assoc/reassoc frame retry timeout if ack received */
t_u16 retry_timeout;
} MLAN_PACK_END HostCmd_DS_AUTH_ASSOC_TIMEOUT_CFG;
/* maximum number of STAs HostCmd_CMD_802_11_STA_TX_RATE can have */
enum { MAX_STA_IN_TX_RATE_REQ = 32 };
/** HostCmd_CMD_802_11_STA_TX_RATE */
typedef MLAN_PACK_START struct _HostCmd_CMD_802_11_STA_TX_RATE {
struct {
/** STA`s MAC */
t_u8 sta_mac[MLAN_MAC_ADDR_LENGTH];
/** TX rate */
HostCmd_TX_RATE_QUERY rate;
} entry[MAX_STA_IN_TX_RATE_REQ];
/** actual number of entries in array */
t_u16 num_entries;
} HostCmd_CMD_802_11_STA_TX_RATE;
/** HostCmd_MCLIENT_SCHEDULE_CFG */
typedef MLAN_PACK_START struct _HostCmd_MCLIENT_SCHEDULE_CFG {
/** action - get/set */
t_u16 action;
/** enable multi-client scheduliing */
t_u8 mclient_enable;
/** enable PS mode change reporting */
t_u8 ps_mode_change_report;
} HostCmd_MCLIENT_SCHEDULE_CFG;
/** HostCmd_DS_COMMAND */
typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND {
/** Command Header : Command */
@ -7353,9 +7508,12 @@ typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND {
/** RF antenna */
HostCmd_DS_802_11_RF_ANTENNA antenna;
/** Function Init */
HostCmd_DS_FUNC_INIT func_init;
/** Enhanced power save command */
HostCmd_DS_802_11_PS_MODE_ENH psmode_enh;
HostCmd_DS_802_11_HS_CFG_ENH opt_hs_cfg;
HostCmd_DS_802_11_FW_WAKEUP_METHOD fwwakeupmethod;
/** Scan */
HostCmd_DS_802_11_SCAN scan;
/** Extended Scan */
@ -7487,6 +7645,9 @@ typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND {
#if defined(PCIE8997) || defined(PCIE8897)
HostCmd_DS_PCIE_HOST_BUF_DETAILS pcie_host_spec;
#endif
#endif
#if defined(PCIE)
HostCmd_DS_PCIE_ADMA_INIT pcie_adma_config;
#endif
HostCmd_DS_REMAIN_ON_CHANNEL remain_on_chan;
#ifdef WIFI_DIRECT_SUPPORT
@ -7564,6 +7725,7 @@ typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND {
struct mfg_Cmd_HE_TBTx_t mfg_he_power;
mfg_Cmd_IEEEtypes_CtlBasicTrigHdr_t mfg_tx_trigger_config;
mfg_cmd_otp_mac_addr_rd_wr_t mfg_otp_mac_addr_rd_wr;
mfg_cmd_otp_cal_data_rd_wr_t mfg_otp_cal_data_rd_wr;
HostCmd_DS_CMD_ARB_CONFIG arb_cfg;
HostCmd_DS_CMD_DOT11MC_UNASSOC_FTM_CFG dot11mc_unassoc_ftm_cfg;
HostCmd_DS_HAL_PHY_CFG hal_phy_cfg_params;
@ -7572,15 +7734,21 @@ typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND {
HostCmd_DS_STATS stats;
HostCmd_DS_GET_CH_LOAD ch_load;
HostCmd_DS_CROSS_CHIP_SYNCH cross_chip_synch;
HostCmd_DS_TSP_CFG tsp_cfg;
HostCmd_DS_80211_TX_FRAME tx_frame;
HostCmd_DS_EDMAC_CFG ed_mac_cfg;
HostCmd_gpio_cfg_ops gpio_cfg_ops;
HostCmd_CMD_802_11_STA_TX_RATE sta_rx_rate;
HostCmd_MCLIENT_SCHEDULE_CFG mclient_cfg;
/** WMM HOST ADDTS */
HostCmd_DS_WMM_HOST_ADDTS_REQ host_add_ts;
/** WMM HOST DELTS */
HostCmd_DS_WMM_HOST_DELTS_REQ host_del_ts;
/** Auth, (Re)Assoc timeout configuration */
HostCmd_DS_AUTH_ASSOC_TIMEOUT_CFG auth_assoc_cfg;
} params;
} MLAN_PACK_END HostCmd_DS_COMMAND, *pHostCmd_DS_COMMAND;
@ -7617,6 +7785,11 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_Secure_Boot_Uuid_t {
t_u64 uuid_hi;
} MLAN_PACK_END MrvlIEtypes_Secure_Boot_Uuid_t;
typedef MLAN_PACK_START struct _MrvlIEtypes_PsStaStatus_t {
t_u8 mac[MLAN_MAC_ADDR_LENGTH];
t_u8 sleep;
} MLAN_PACK_END MrvlIEtypes_PsStaStatus_t;
/** req host side download vdll block */
#define VDLL_IND_TYPE_REQ 0
/** notify vdll start offset in firmware image */
@ -7642,6 +7815,36 @@ typedef MLAN_PACK_START struct _vdll_ind {
t_u16 block_len;
} MLAN_PACK_END vdll_ind, *pvdll_ind;
typedef MLAN_PACK_START struct _MrvlIEtypes_MclientFwCaps_t {
/** Header */
MrvlIEtypesHeader_t header;
/* max number of supported TX BA streams */
t_u32 tx_ba_stream_limit;
/* estimated FW MPDU PPS performance */
t_u32 tx_mpdu_with_amsdu_pps;
t_u32 tx_mpdu_no_amsdu_pps;
/* timeout support for TX BA */
t_u8 tx_ba_timeout_support;
t_u8 __padding[3];
} MLAN_PACK_END MrvlIEtypes_MclientFwCaps_t;
/** Fw custom data structure */
typedef struct MLAN_PACK_START _fw_data_t {
t_u8 *fw_data_buffer;
t_u8 fw_data_buffer_len;
} MLAN_PACK_END fw_data_t;
typedef enum _BLOCK_6G_CHAN_SWITCH_REASON {
BLOCK_6G_CHAN_SWITCH_REASON_MMH = 1,
BLOCK_6G_CHAN_SWITCH_REASON_MMH_STA = 2,
BLOCK_6G_CHAN_SWITCH_REASON_STA_MMH = 3,
BLOCK_6G_CHAN_SWITCH_REASON_STA_RX_ECSA = 4,
} BLOCK_6G_CHAN_SWITCH_REASON;
#ifdef PRAGMA_PACK
#pragma pack(pop)
#endif

View file

@ -126,6 +126,8 @@ ENUM_ELEMENT(HostCmd_CMD_GET_HW_SPEC, 0x0003),
/** Host Command ID : 802.11 get status */
ENUM_ELEMENT(HostCmd_CMD_WMM_GET_STATUS, 0x0071),
/** Host Command ID : 802.11 firmware wakeup method */
ENUM_ELEMENT(HostCmd_CMD_802_11_FW_WAKE_METHOD, 0x0074),
/** Host Command ID : 802.11 subscribe event */
ENUM_ELEMENT(HostCmd_CMD_802_11_SUBSCRIBE_EVENT, 0x0075),
@ -262,6 +264,8 @@ ENUM_ELEMENT(HostCmd_CMD_GET_HW_SPEC, 0x0003),
/** Host Command ID: CROSS CHIP SYNCH */
ENUM_ELEMENT(HostCmd_CMD_CROSS_CHIP_SYNCH, 0x027d),
ENUM_ELEMENT(HostCmd_CMD_TSP_CFG, 0x0280),
/** Host Command ID : TDLS configuration */
ENUM_ELEMENT(HostCmd_CMD_TDLS_CONFIG, 0x0100),
/** Host Command ID : TDLS operation */
@ -457,10 +461,21 @@ ENUM_ELEMENT(HostCmd_CMD_GET_HW_SPEC, 0x0003),
/** Host Command ID: PCIE ADMA INIT */
ENUM_ELEMENT(HostCmd_CMD_PCIE_ADMA_INIT, 0x0284),
/** Host Command ID: query of current TX rate to the peer */
ENUM_ELEMENT(HostCmd_CMD_PEER_TX_RATE_QUERY, 0x0285),
/** Host Command ID: multi-client TX scheduling configuration */
ENUM_ELEMENT(HostCmd_CMD_MCLIENT_SCHEDULE_CFG, 0x0286),
/** Host Command ID : WMM HOST ADDTS req */
ENUM_ELEMENT(HostCmd_CMD_WMM_HOST_ADDTS_REQ, 0x0287),
/** Host Command ID : WMM HOST DELTS req */
ENUM_ELEMENT(HostCmd_CMD_WMM_HOST_DELTS_REQ, 0x0288),
/** Host Command ID : Auth, Assoc timeout configuration */
ENUM_ELEMENT(HostCmd_CMD_AUTH_ASSOC_TIMEOUT_CFG, 0x0289),
/** Host Command ID : HS Event masking configuration */
ENUM_ELEMENT(HostCmd_CMD_HS_EVENT_MASK, 0x028a),
/* Always keep this last */
ENUM_ELEMENT_LAST(__HostCmd_CMD_Last)

View file

@ -71,6 +71,9 @@ typedef enum _WLAN_802_11_NETWORK_TYPE {
typedef enum _IEEEtypes_Ext_ElementId_e {
HE_CAPABILITY = 35,
HE_OPERATION = 36,
MU_EDCA_PARAM_SET = 38,
MBSSID_CONFIG = 55,
NON_INHERITANCE = 56,
HE_6G_CAPABILITY = 59
} IEEEtypes_Ext_ElementId_e;
@ -260,7 +263,7 @@ typedef MLAN_PACK_START struct _IEEEtypes_FastBssTransElement_t {
/** SNonce */
t_u8 s_nonce[32];
/** sub element */
t_u8 sub_element[1];
t_u8 sub_element[];
} MLAN_PACK_END IEEEtypes_FastBssTransElement_t;
/*Category for FT*/
@ -547,7 +550,7 @@ typedef MLAN_PACK_START struct _IEEEtypes_AssocRsp_t {
/** Association ID */
IEEEtypes_AId_t a_id;
/** IE data buffer */
t_u8 ie_buffer[1];
t_u8 ie_buffer[];
} MLAN_PACK_END IEEEtypes_AssocRsp_t, *pIEEEtypes_AssocRsp_t;
/** 802.11 supported rates */
@ -985,7 +988,7 @@ typedef MLAN_PACK_START struct _IEEEtypes_CountryInfoSet_t {
/** Country code */
t_u8 country_code[COUNTRY_CODE_LEN];
/** Set of subbands */
IEEEtypes_SubbandSet_t sub_band[1];
IEEEtypes_SubbandSet_t sub_band[];
} MLAN_PACK_END IEEEtypes_CountryInfoSet_t, *pIEEEtypes_CountryInfoSet_t;
/** Data structure for Country IE full set */
@ -1151,6 +1154,18 @@ typedef MLAN_PACK_START struct _IEEEtypes_MultiBSSID_t {
/** Optional Subelement data*/
t_u8 sub_elem_data[];
} MLAN_PACK_END IEEEtypes_MultiBSSID_t, *pIEEEtypes_MultiBSSID_t;
/** Multi BSSID Configuration IE */
typedef MLAN_PACK_START struct _IEEEtypes_MBSSID_Config_t {
/** Generic IE header */
IEEEtypes_Header_t ieee_hdr;
/** Element id extension */
t_u8 ext_id;
/** BSSID Count */
t_u8 bssid_cnt;
/** Full Set Rx Periodicity */
t_u8 fs_rx_periodicity;
} MLAN_PACK_END IEEEtypes_MBSSID_Config_t, *pIEEEtypes_MBSSID_Config_t;
/** 20/40 BSS Coexistence IE */
typedef MLAN_PACK_START struct _IEEEtypes_2040BSSCo_t {
/** Generic IE header */
@ -1466,6 +1481,32 @@ typedef MLAN_PACK_START struct _IEEEtypes_HeOp_t {
t_u8 option[9];
} MLAN_PACK_END IEEEtypes_HeOp_t;
/** MU EDCA Parameter Set */
typedef MLAN_PACK_START struct _IEEEtypes_MUEDCAParamSet_t {
/** Generic IE header */
IEEEtypes_Header_t ieee_hdr;
/** Extended Tag */
t_u8 ext_tag;
/** QOS Information */
t_u8 qos_info;
/** MUAC BE Paramter Record */
t_u8 muac_be[3];
/** MUAC BK Paramter Record */
t_u8 muac_bk[3];
/** MUAC VI Paramter Record */
t_u8 muac_vi[3];
/** MUAC VO Paramter Record */
t_u8 muac_vo[3];
} MLAN_PACK_END IEEEtypes_MUEDCAParamSet_t, *pIEEEtypes_MUEDCAParamSet_t;
/** IEEE format IE */
typedef MLAN_PACK_START struct _IEEEtypes_Element_t {
/** Generic IE header */
IEEEtypes_Header_t ieee_hdr;
/** IE data */
t_u8 data[];
} MLAN_PACK_END IEEEtypes_Element_t, *pIEEEtypes_Element_t;
/** default channel switch count */
#define DEF_CHAN_SWITCH_COUNT 5
@ -2094,6 +2135,10 @@ typedef struct _BSSDescriptor_t {
t_u8 multi_bssid_ap;
/** the mac address of multi-bssid AP */
mlan_802_11_mac_addr multi_bssid_ap_addr;
/** Multi BSSID Configuration IE */
IEEEtypes_MBSSID_Config_t *pmbssid_config;
/** Multi BSSID Configuration IE offset */
t_u16 mbssid_config_offset;
/** 20/40 BSS Coexistence IE */
IEEEtypes_2040BSSCo_t *pbss_co_2040;
/** 20/40 BSS Coexistence Offset */
@ -2174,7 +2219,10 @@ typedef struct _BSSDescriptor_t {
IEEEtypes_MobilityDomain_t *pmd_ie;
/** Mobility domain IE offset in the beacon buffer */
t_u16 md_offset;
/** MU EDCA Parameter IE */
IEEEtypes_MUEDCAParamSet_t *pmuedca_ie;
/** MU EDCA Parameter IE offset */
t_u16 muedca_offset;
/** Pointer to the returned scan response */
t_u8 *pbeacon_buf;
/** Length of the stored scan response */

View file

@ -776,6 +776,8 @@ t_void wlan_init_adapter(pmlan_adapter pmadapter)
pmadapter->local_listen_interval = 0; /* default value in firmware will
be used */
#endif /* STA_SUPPORT */
pmadapter->fw_wakeup_method = WAKEUP_FW_UNCHANGED;
pmadapter->fw_wakeup_gpio_pin = DEF_WAKEUP_FW_GPIO;
pmadapter->is_deep_sleep = MFALSE;
pmadapter->idle_time = DEEP_SLEEP_IDLE_TIME;
@ -1038,6 +1040,28 @@ mlan_status wlan_init_priv_lock_list(pmlan_adapter pmadapter, t_u8 start_index)
MTRUE,
priv->adapter->callbacks.moal_init_lock);
}
util_init_list_head(
pmadapter->pmoal_handle, &priv->wmm.all_stas,
MTRUE, pmadapter->callbacks.moal_init_lock);
util_init_list_head(
pmadapter->pmoal_handle,
&priv->wmm.pending_stas, MTRUE,
pmadapter->callbacks.moal_init_lock);
util_init_list_head(
pmadapter->pmoal_handle,
&priv->wmm.active_stas.list, MTRUE,
pmadapter->callbacks.moal_init_lock);
for (j = 0; j < NELEMENTS(priv->wmm.pending_txq); ++j) {
util_init_list_head(
pmadapter->pmoal_handle,
&priv->wmm.pending_txq[j], MTRUE,
pmadapter->callbacks.moal_init_lock);
}
priv->wmm.selected_ra_list = MNULL;
pcb->moal_get_host_time_ns(
&priv->wmm.active_stas.next_update);
pcb->moal_get_host_time_ns(&priv->wmm.next_rate_update);
priv->wmm.is_rate_update_pending = MFALSE;
util_init_list_head(
(t_void *)pmadapter->pmoal_handle,
&priv->tx_ba_stream_tbl_ptr, MTRUE,
@ -1156,6 +1180,16 @@ mlan_status wlan_init_lock_list(pmlan_adapter pmadapter)
goto error;
}
#endif
#ifdef USB
if (IS_USB(pmadapter->card_type)) {
if (pcb->moal_init_lock(pmadapter->pmoal_handle,
&pmadapter->pmlan_usb_event_lock) !=
MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto error;
}
}
#endif
#if defined(USB)
if (IS_USB(pmadapter->card_type)) {
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) {
@ -1258,6 +1292,11 @@ t_void wlan_free_lock_list(pmlan_adapter pmadapter)
pcb->moal_free_lock(pmadapter->pmoal_handle,
pmadapter->pmlan_pcie_lock);
#endif
#ifdef USB
if (IS_USB(pmadapter->card_type) && pmadapter->pmlan_usb_event_lock)
pcb->moal_free_lock(pmadapter->pmoal_handle,
pmadapter->pmlan_usb_event_lock);
#endif
#if defined(USB)
if (IS_USB(pmadapter->card_type)) {
for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) {
@ -1343,6 +1382,24 @@ t_void wlan_free_lock_list(pmlan_adapter pmadapter)
(t_void *)priv->adapter->pmoal_handle,
&priv->wmm.tid_tbl_ptr[j].ra_list,
priv->adapter->callbacks.moal_free_lock);
util_free_list_head(
(t_void *)priv->adapter->pmoal_handle,
&priv->wmm.all_stas,
priv->adapter->callbacks.moal_free_lock);
util_free_list_head(
(t_void *)priv->adapter->pmoal_handle,
&priv->wmm.pending_stas,
priv->adapter->callbacks.moal_free_lock);
util_free_list_head(
(t_void *)priv->adapter->pmoal_handle,
&priv->wmm.active_stas.list,
priv->adapter->callbacks.moal_free_lock);
for (j = 0; j < NELEMENTS(priv->wmm.pending_txq); ++j) {
util_free_list_head(
(t_void *)priv->adapter->pmoal_handle,
&priv->wmm.pending_txq[j],
priv->adapter->callbacks.moal_free_lock);
}
util_free_list_head(
(t_void *)priv->adapter->pmoal_handle,
&priv->tx_ba_stream_tbl_ptr,
@ -1597,7 +1654,7 @@ static void wlan_update_hw_spec(pmlan_adapter pmadapter)
pmadapter->fw_bands |= BAND_GAX;
pmadapter->config_bands |= BAND_GAX;
}
if (pmadapter->hw_hecap_len) {
if ((pmadapter->fw_bands & BAND_A) && pmadapter->hw_hecap_len) {
pmadapter->fw_bands |= BAND_AAX;
pmadapter->config_bands |= BAND_AAX;
}
@ -1741,6 +1798,14 @@ t_void wlan_free_adapter(pmlan_adapter pmadapter)
return;
}
#ifdef PCIE
if (IS_PCIE(pmadapter->card_type)) {
/* Free ssu dma buffer just in case */
wlan_free_ssu_pcie_buf(pmadapter);
/* Free PCIE ring buffers */
wlan_free_pcie_ring_buf(pmadapter);
}
#endif
wlan_cancel_all_pending_cmd(pmadapter, MTRUE);
/* Free command buffer */
PRINTM(MINFO, "Free Command buffer\n");
@ -1844,15 +1909,6 @@ t_void wlan_free_adapter(pmlan_adapter pmadapter)
wlan_free_mlan_buffer(pmadapter, pmadapter->psleep_cfm);
pmadapter->psleep_cfm = MNULL;
#ifdef PCIE
if (IS_PCIE(pmadapter->card_type)) {
/* Free ssu dma buffer just in case */
wlan_free_ssu_pcie_buf(pmadapter);
/* Free PCIE ring buffers */
wlan_free_pcie_ring_buf(pmadapter);
}
#endif
/* Free timers */
wlan_free_timer(pmadapter);

View file

@ -164,6 +164,7 @@ enum _mlan_ioctl_req_id {
MLAN_OID_PM_CFG_DEEP_SLEEP = 0x00090004,
MLAN_OID_PM_CFG_SLEEP_PD = 0x00090005,
MLAN_OID_PM_CFG_PS_CFG = 0x00090006,
MLAN_OID_PM_CFG_FW_WAKEUP_METHOD = 0x00090007,
MLAN_OID_PM_CFG_SLEEP_PARAMS = 0x00090008,
#ifdef UAP_SUPPORT
MLAN_OID_PM_CFG_PS_MODE = 0x00090009,
@ -375,6 +376,7 @@ enum _mlan_ioctl_req_id {
MLAN_OID_MISC_CROSS_CHIP_SYNCH = 0x0020008B,
MLAN_OID_MISC_RF_TEST_CONFIG_TRIGGER_FRAME = 0x0020008C,
MLAN_OID_MISC_OFDM_DESENSE_CFG = 0x0020008D,
MLAN_OID_MISC_TSP_CFG = 0x002008C,
MLAN_OID_MISC_REORDER_FLUSH_TIME = 0x0020008F,
MLAN_OID_MISC_NAV_MITIGATION = 0x00200090,
MLAN_OID_MISC_LED_CONFIG = 0x00200091,
@ -383,6 +385,8 @@ enum _mlan_ioctl_req_id {
MLAN_OID_MISC_GPIO_CFG = 0x00200094,
MLAN_OID_MISC_REGION_POWER_CFG = 0x00200095,
MLAN_OID_MISC_OTP_MAC_RD_WR = 0x00200097,
MLAN_OID_MISC_OTP_CAL_DATA_RD_WR = 0x00200098,
MLAN_OID_MISC_AUTH_ASSOC_TIMEOUT_CONFIG = 0x00200099,
};
/** Sub command size */
@ -519,7 +523,7 @@ typedef struct {
* Buffer marker for multiple wlan_ioctl_get_scan_table_entry
* structures. Each struct is padded to the nearest 32 bit boundary.
*/
t_u8 scan_table_entry_buf[1];
t_u8 scan_table_entry_buf[];
} wlan_ioctl_get_scan_table_info;
/**
@ -576,7 +580,7 @@ typedef struct _mlan_user_scan {
/** Length of scan_cfg_buf */
t_u32 scan_cfg_len;
/** Buffer of scan config */
t_u8 scan_cfg_buf[1];
t_u8 scan_cfg_buf[];
} mlan_user_scan, *pmlan_user_scan;
/** Type definition of mlan_scan_req */
@ -1763,6 +1767,8 @@ typedef struct _mlan_ds_get_stats {
t_u32 gdma_abort_cnt;
/** Rx Reset MAC Count */
t_u32 g_reset_rx_mac_cnt;
/** SDMA FSM stuck Count*/
t_u32 SdmaStuckCnt;
// Ownership error counters
/*Error Ownership error count*/
t_u32 dwCtlErrCnt;
@ -3395,6 +3401,15 @@ typedef struct _mlan_ds_hs_wakeup_reason {
t_u16 hs_wakeup_reason;
} mlan_ds_hs_wakeup_reason;
/** Type definition of mlan_fw_wakeup_params for
* MLAN_OID_PM_CFG_FW_WAKEUP_METHOD */
typedef struct _mlan_fw_wakeup_params {
/** FW wakeup method */
t_u16 method;
/** GPIO pin NO.*/
t_u8 gpio_pin;
} mlan_fw_wakeup_params, *pmlan_fw_wakeup_params;
/** Type definition of mlan_ds_ps_cfg for MLAN_OID_PM_CFG_PS_CFG */
typedef struct _mlan_ds_bcn_timeout {
/** Beacon miss timeout period window */
@ -3425,6 +3440,8 @@ typedef struct _mlan_ds_pm_cfg {
t_u32 sleep_period;
/** PS configuration parameters for MLAN_OID_PM_CFG_PS_CFG */
mlan_ds_ps_cfg ps_cfg;
/** FW wakeup method for MLAN_OID_PM_CFG_FW_WAKEUP_METHOD */
mlan_fw_wakeup_params fw_wakeup_params;
/** PS configuration parameters for MLAN_OID_PM_CFG_SLEEP_PARAMS
*/
mlan_ds_sleep_params sleep_params;
@ -4177,6 +4194,9 @@ typedef struct _mlan_ds_11ax_rutxpwr_cmd {
/** column,row are 3 for every subband table,however column are 7 for FC
* and 6 for other SOCs */
t_u8 col;
/** row are 3 for every subband table,total row for MAC1 is 12 and MAC2
* id 3 ( consider only 2G support */
t_u8 row;
/**ru tx data */
t_s8 rutxSubPwr[89];
} mlan_ds_11ax_rutxpwr_cmd, *pmlan_ds_11ax_rutxpwr_cmd;
@ -4264,6 +4284,8 @@ typedef struct MLAN_PACK_START _mlan_ds_twt_setup {
t_u16 twt_mantissa;
/** TWT Request Type, 0: REQUEST_TWT, 1: SUGGEST_TWT*/
t_u8 twt_request;
/** TWT link lost timeout threshold */
t_u16 bcnMiss_threshold;
} MLAN_PACK_END mlan_ds_twt_setup, *pmlan_ds_twt_setup;
/** Type definition of mlan_ds_twt_teardown for MLAN_OID_11AX_TWT_CFG */
@ -4415,14 +4437,14 @@ enum _mlan_reg_type {
defined(PCIE9097) || defined(USB9097) || defined(SDIW624) || \
defined(SDAW693) || defined(PCIEAW693) || defined(PCIEIW624) || \
defined(USBIW624) || defined(SD9097) || defined(SD9177) || \
defined(SDIW615) || defined(USBIW615)
defined(SDIW610) || defined(USBIW610)
MLAN_REG_CIU = 8,
#endif
#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
defined(PCIE9097) || defined(USB9097) || defined(SDIW624) || \
defined(SDAW693) || defined(PCIEAW693) || defined(PCIEIW624) || \
defined(USBIW624) || defined(SD9097) || defined(SDIW615) || \
defined(USBIW615)
defined(USBIW624) || defined(SD9097) || defined(SDIW610) || \
defined(USBIW610)
MLAN_REG_MAC2 = 0x81,
MLAN_REG_BBP2 = 0x82,
MLAN_REG_RF2 = 0x83,
@ -5659,7 +5681,7 @@ typedef MLAN_PACK_START struct _mlan_ds_misc_tx_rx_histogram {
/** Size of Tx/Rx info */
t_u16 size;
/** Store Tx/Rx info */
t_u8 value[1];
t_u8 value[];
} MLAN_PACK_END mlan_ds_misc_tx_rx_histogram;
#define RX_PKT_INFO MBIT(1)
@ -5917,6 +5939,7 @@ typedef struct _mlan_ds_misc_chan_trpc_cfg {
#define MFG_CMD_CONFIG_MAC_HE_TB_TX 0x110A
#define MFG_CMD_CONFIG_TRIGGER_FRAME 0x110C
#define MFG_CMD_OTP_MAC_ADD 0x108C
#define MFG_CMD_OTP_CAL_DATA 0x121A
/** MFG CMD generic cfg */
struct MLAN_PACK_START mfg_cmd_generic_cfg {
@ -6227,6 +6250,24 @@ typedef MLAN_PACK_START struct _mfg_cmd_otp_mac_addr_rd_wr_t {
t_u8 mac_addr[MLAN_MAC_ADDR_LENGTH];
} MLAN_PACK_END mfg_cmd_otp_mac_addr_rd_wr_t;
#define CAL_DATA_LEN 1400
typedef MLAN_PACK_START struct _mfg_cmd_otp_cal_data_rd_wr_t {
/** MFG command code */
t_u32 mfg_cmd;
/** Action */
t_u16 action;
/** Device ID */
t_u16 device_id;
/** MFG Error code */
t_u32 error;
/** CAL Data write status */
t_u32 cal_data_status;
/** CAL Data Length*/
t_u32 cal_data_len;
/** Destination MAC Address */
t_u8 cal_data[CAL_DATA_LEN];
} MLAN_PACK_END mfg_cmd_otp_cal_data_rd_wr_t;
typedef struct _mlan_ds_misc_chnrgpwr_cfg {
/** length */
t_u16 length;
@ -6244,6 +6285,22 @@ typedef struct _mlan_ds_misc_cfp_tbl {
chan_freq_power_t cfp_tbl[];
} mlan_ds_misc_cfp_tbl;
/** channel attribute */
typedef struct _chan_attr {
/** channel number */
t_u8 channel;
/** channel flags */
t_u8 flags;
} chan_attr_t;
/** channel flags table */
typedef struct _mlan_ds_chan_attr {
/** Data length */
t_u16 data_len;
/** Data */
chan_attr_t chan_attr[MLAN_MAX_CHANNEL_NUM];
} MLAN_PACK_END mlan_ds_chan_attr;
/** mlan_ds_mc_aggr_cfg for MLAN_OID_MISC_MC_AGGR_CFG */
typedef struct _mlan_ds_mc_aggr_cfg {
/** action */
@ -6301,6 +6358,33 @@ typedef struct _mlan_ds_cross_chip_synch {
t_u32 init_tsf_high;
} mlan_ds_cross_chip_synch;
#define MAX_RFUS 2
#define MAX_PATHS 2
typedef struct _mlan_ds_tsp_cfg {
/** TSP config action 0-GET, 1-SET */
t_u16 action;
/** TSP enable/disable tsp algothrim */
t_u16 enable;
/** TSP config power backoff */
t_s32 backoff;
/** TSP config high threshold */
t_s32 high_thrshld;
/** TSP config low threshold */
t_s32 low_thrshld;
/** TSP config DUTY_CYC_STEP */
t_s32 duty_cyc_step;
/** TSP config DUTY_CYC_MIN */
t_s32 duty_cyc_min;
/** TSP config HIGH_THRESHOLD_TEMP */
t_s32 high_thrshld_temp;
/** TSP config LOW_THRESHOLD_TEMP */
t_s32 low_thrshld_temp;
/** TSP CAU TSEN register */
t_s32 reg_cau_val;
/** TSP RFU registers */
t_s32 reg_rfu_temp[MAX_RFUS][MAX_PATHS];
} MLAN_PACK_END mlan_ds_tsp_cfg;
typedef struct _mlan_ds_reorder_flush_time {
/** AC BK/BE_flush time*/
t_u16 flush_time_ac_be_bk;
@ -6322,6 +6406,36 @@ typedef struct _mlan_ds_ed_mac_cfg {
t_u32 ed_bitmap_txq_lock;
} mlan_ds_ed_mac_cfg;
/** valid range for mlan_ds_auth_assoc_timeout_cfg */
#define AUTH_TIMEOUT_MIN 500
#define AUTH_TIMEOUT_MAX 2400
#define AUTH_RETRY_TIMEOUT_ACK_MIN 50
#define AUTH_RETRY_TIMEOUT_ACK_MAX 300
#define AUTH_RETRY_TIMEOUT_NO_ACK_MIN 40
#define AUTH_RETRY_TIMEOUT_NO_ACK_MAX 80
#define ASSOC_TIMEOUT_MIN 200
#define ASSOC_TIMEOUT_MAX 1500
#define REASSOC_TIMEOUT_MIN 100
#define REASSOC_TIMEOUT_MAX 1500
#define ASSOC_RETRY_TIMEOUT_MIN 50
#define ASSOC_RETRY_TIMEOUT_MAX 150
/** Auth Assoc timeout configuration parameters */
typedef struct _mlan_ds_auth_assoc_timeout_cfg {
/** auth timeout */
t_u16 auth_timeout;
/** Auth retry timeout if received ack */
t_u16 auth_retry_timeout_if_ack;
/** Auth retry timeout if ack is not received */
t_u16 auth_retry_timeout_if_no_ack;
/** assoc timeout */
t_u16 assoc_timeout;
/** reassoc timeout */
t_u16 reassoc_timeout;
/** assoc/reassoc frame retry timeout if ack received */
t_u16 retry_timeout;
} mlan_ds_auth_assoc_timeout_cfg;
/** Type definition of mlan_ds_misc_cfg for MLAN_IOCTL_MISC_CFG */
typedef struct _mlan_ds_misc_cfg {
/** Sub-command */
@ -6469,6 +6583,7 @@ typedef struct _mlan_ds_misc_cfg {
mlan_ds_misc_cck_desense_cfg cck_desense_cfg;
mlan_ds_misc_chan_trpc_cfg trpc_cfg;
mlan_ds_misc_chnrgpwr_cfg rgchnpwr_cfg;
mlan_ds_chan_attr chan_attr_cfg;
mlan_ds_band_steer_cfg band_steer_cfg;
mlan_ds_beacon_stuck_param_cfg beacon_stuck_cfg;
@ -6478,6 +6593,7 @@ typedef struct _mlan_ds_misc_cfg {
struct mfg_Cmd_HE_TBTx_t mfg_he_power;
mfg_Cmd_IEEEtypes_CtlBasicTrigHdr_t mfg_tx_trigger_config;
mfg_cmd_otp_mac_addr_rd_wr_t mfg_otp_mac_addr_rd_wr;
mfg_cmd_otp_cal_data_rd_wr_t mfg_otp_cal_data_rd_wr;
mlan_ds_misc_arb_cfg arb_cfg;
mlan_ds_misc_cfp_tbl cfp;
t_u8 range_ext_mode;
@ -6493,12 +6609,32 @@ typedef struct _mlan_ds_misc_cfg {
t_u32 ips_ctrl;
mlan_ds_ch_load ch_load;
mlan_ds_cross_chip_synch cross_chip_synch;
mlan_ds_tsp_cfg tsp_cfg;
mlan_ds_reorder_flush_time flush_time;
mlan_ds_ed_mac_cfg edmac_cfg;
mlan_ds_gpio_cfg_ops gpio_cfg_ops;
mlan_ds_auth_assoc_timeout_cfg auth_assoc_cfg;
} param;
} mlan_ds_misc_cfg, *pmlan_ds_misc_cfg;
typedef struct _mlan_cfpinfo {
t_u8 nss : 2;
t_u8 is2g_present : 1;
t_u8 is5g_present : 1;
t_u8 is6g_present : 1;
t_u8 reserved : 3;
t_u8 rows_2g;
t_u8 cols_2g;
t_u8 rows_5g;
t_u8 cols_5g;
t_u8 rows_6g;
t_u8 cols_6g;
t_u8 region_code;
t_u8 environment;
t_u8 country_code[2];
t_u16 action;
} mlan_cfpinfo;
/** Hotspot status enable */
#define HOTSPOT_ENABLED MBIT(0)
/** Hotspot status disable */

View file

@ -156,6 +156,12 @@ extern t_u32 mlan_drvdbg;
print_callback(MNULL, MMSG, msg); \
} while (0)
#define PRINTM_MSCH_D(msg...) \
do { \
if ((mlan_drvdbg & MSCH_D) && (print_callback)) \
print_callback(MNULL, MSCH_D, msg); \
} while (0)
#define PRINTM(level, msg...) PRINTM_##level((char *)msg)
/** Log debug message */
@ -571,7 +577,7 @@ extern t_void (*assert_callback)(t_void *pmoal_handle, t_u32 cond);
#if defined(SD8887) || defined(SD8997) || defined(SD8977) || \
defined(SD8987) || defined(SD9098) || defined(SD9097) || \
defined(SDAW693) || defined(SDIW624) || defined(SD8978) || \
defined(SD9177) || defined(SDIW615)
defined(SD9177) || defined(SDIW610)
#define MAX_MP_REGS 196
#else
/* upto 0xB7 */
@ -621,6 +627,11 @@ extern t_void (*assert_callback)(t_void *pmoal_handle, t_u32 cond);
/** scan GAP value is optional */
#define GAP_FLAG_OPTIONAL MBIT(15)
/** max numbe of mac filters allowed in llde list */
#define MAX_MAC_FILTER_ENTRIES 2
/** max numbe of iPhone devices allowed in llde list */
#define MAX_IPHONE_FILTER_ENTRIES 2
/** Info for debug purpose */
typedef struct _wlan_dbg {
/** Number of host to card command failures */
@ -787,6 +798,11 @@ struct _raListTbl {
t_u8 is_tdls_link;
/** tx_pause flag */
t_u8 tx_pause;
t_u8 tid;
t_u8 queue;
struct wmm_sta_table *sta;
mlan_linked_list pending_txq_entry;
};
/** TID table */
@ -810,6 +826,45 @@ typedef struct _tidTbl {
/** Max driver packet delay in msec */
#define WMM_DRV_DELAY_MAX 510
struct wmm_sta_table {
mlan_linked_list all_stas_entry;
mlan_linked_list pending_stas_entry;
mlan_linked_list active_sta_entry;
t_u8 ra[MLAN_MAC_ADDR_LENGTH];
t_bool ps_sleep;
raListTbl *ra_lists[MAX_NUM_TID];
struct {
t_u16 time_budget_init_us;
t_u32 mpdu_with_amsdu_pps_cap;
t_u32 mpdu_no_amsdu_pps_cap;
t_u32 byte_budget_init;
t_u32 mpdu_with_amsdu_budget_init;
t_u32 mpdu_no_amsdu_budget_init;
t_u32 phy_rate_kbps;
t_u32 queue_packets;
t_s32 bytes[MAX_NUM_TID];
t_s32 mpdus[MAX_NUM_TID];
} budget;
};
typedef struct mlan_wmm_param {
t_u8 ecwmin;
;
t_u8 ecwmax;
t_u8 aifsn;
} mlan_wmm_param;
typedef struct mlan_wmm_contention {
mlan_wmm_param param;
t_u8 ecw;
t_bool move_cw_on_lost;
t_u16 remaining_aifs;
t_u16 remaining_backoff;
} mlan_wmm_contention;
/** Struct of WMM DESC */
typedef struct _wmm_desc {
/** TID table */
@ -840,6 +895,24 @@ typedef struct _wmm_desc {
mlan_scalar tx_pkts_queued;
/** Tracks highest priority with a packet queued */
mlan_scalar highest_queued_prio;
mlan_list_head all_stas; /* struct wmm_sta_table */
mlan_list_head pending_stas; /* struct wmm_sta_table */
struct {
mlan_list_head list; /* STAs that had some TX traffic since last
tracking period, struct wmm_sta_table */
t_u32 n_stas;
t_u64 next_update;
} active_stas;
mlan_list_head pending_txq[MAX_AC_QUEUES];
mlan_wmm_contention txq_contention[MAX_AC_QUEUES];
raListTbl *selected_ra_list;
t_u64 next_rate_update;
t_bool is_rate_update_pending;
} wmm_desc_t;
/** Security structure */
@ -1517,6 +1590,9 @@ typedef enum _tdlsStatus_e {
/** station node */
typedef struct _sta_node sta_node, *psta_node;
#define VENDOR_OUI_LEN 4
#define MAX_VENDOR_OUI_NUM 10
/** station node*/
struct _sta_node {
/** previous node */
@ -1591,6 +1667,10 @@ struct _sta_node {
t_u16 aid;
/** apple device based on OUI in assoc req */
t_u8 is_apple_sta;
/** vendor oui list */
t_u8 vendor_oui[VENDOR_OUI_LEN * MAX_VENDOR_OUI_NUM];
/** vendor OUI count */
t_u8 vendor_oui_count;
};
/** 802.11h State information kept in the 'mlan_adapter' driver structure */
@ -1916,6 +1996,8 @@ typedef struct _mlan_init_para {
#endif
/** Auto deep sleep */
t_u32 auto_ds;
/** Boot Time Config */
t_u32 bootup_cal_ctrl;
/** IEEE PS mode */
t_u32 ps_mode;
/** Max Tx buffer size */
@ -1938,6 +2020,8 @@ typedef struct _mlan_init_para {
t_u8 uap_max_sta;
/** wacp mode */
t_u8 wacp_mode;
/** custom Fw data */
t_u32 fw_data_cfg;
/** dfs w53 cfg */
t_u8 dfs53cfg;
/** dfs_offload */
@ -1952,6 +2036,11 @@ typedef struct _mlan_init_para {
t_u32 antcfg;
/** dmcs*/
t_u8 dmcs;
/** pref_dbc*/
t_u8 pref_dbc;
t_u32 max_tx_pending;
t_u16 tx_budget;
t_u8 mclient_scheduling;
t_u32 reject_addba_req;
} mlan_init_para, *pmlan_init_para;
@ -2378,6 +2467,7 @@ struct _mlan_adapter {
t_void *pmlan_lock;
/** main_proc_lock for main_process */
t_void *pmain_proc_lock;
mlan_private *selected_mlan_bss;
#ifdef PCIE
/** rx data lock to synchronize wlan_pcie_process_recv_data */
t_void *pmlan_rx_lock;
@ -2702,6 +2792,8 @@ struct _mlan_adapter {
t_u8 rx_data_ep;
/** Tx data endpoint address */
t_u8 tx_data_ep;
/** mlan_lock for rx event */
t_void *pmlan_usb_event_lock;
#endif
/** Multi channel status */
t_u8 mc_status;
@ -2746,6 +2838,10 @@ struct _mlan_adapter {
/** Beacon miss timeout */
t_u16 bcn_miss_time_out;
/** Firmware wakeup method */
t_u16 fw_wakeup_method;
/** Firmware wakeup GPIO pin */
t_u8 fw_wakeup_gpio_pin;
/** Deep Sleep flag */
t_u8 is_deep_sleep;
/** Idle time */
@ -2932,14 +3028,90 @@ struct _mlan_adapter {
t_u16 flush_time_ac_vi_vo;
/** remain_on_channel flag */
t_u8 remain_on_channel;
t_u8 mclient_tx_supported;
t_u8 tx_ba_timeout_support;
t_u32 tx_ba_stream_limit;
t_u32 tx_mpdu_with_amsdu_pps;
t_u32 tx_mpdu_no_amsdu_pps;
struct {
raListTbl *ra_list;
t_u32 pushed_pkg;
} ra_list_tracing;
/** LLDE enable/disable */
t_u8 llde_enabled;
/** LLDE modes 0 - default; 1 - carplay; 2 - gameplay; 3 - sound bar, 4
* <EFBFBD> validation, 5- event driven */
t_u8 llde_mode;
/** high priority data packet type. 0: All traffic, 1: ping, 2: TCP ACK,
* 4: TCP Data, 8: UDP */
t_u8 llde_packet_type;
/** 0: no preference, 1: iphone */
t_u8 llde_device_filter;
t_u8 llde_macfilter1[MLAN_MAC_ADDR_LENGTH];
t_u8 llde_macfilter2[MLAN_MAC_ADDR_LENGTH];
/** total iPhone devices allowed in list */
t_u8 llde_totalIPhones;
/** total other devices as defined in llde.conf */
t_u8 llde_totalMacFilters;
/** mac filter list as defined in llde.conf file */
t_u8 llde_macfilters[MAX_MAC_FILTER_ENTRIES * MLAN_MAC_ADDR_LENGTH];
/** iPhone device list */
t_u8 llde_iphonefilters[MAX_IPHONE_FILTER_ENTRIES *
MLAN_MAC_ADDR_LENGTH];
};
/** IPv4 ARP request header */
typedef MLAN_PACK_START struct {
/** Hardware type */
t_u16 Htype;
/** Protocol type */
t_u16 Ptype;
/** Hardware address length */
t_u8 addr_len;
/** Protocol address length */
t_u8 proto_len;
/** Operation code */
t_u16 op_code;
/** Source mac address */
t_u8 sender_mac[MLAN_MAC_ADDR_LENGTH];
/** Sender IP address */
t_u8 sender_ip[4];
/** Destination mac address */
t_u8 target_mac[MLAN_MAC_ADDR_LENGTH];
/** Destination IP address */
t_u8 target_ip[4];
} MLAN_PACK_END IPv4_ARP_t;
/** IPv6 Nadv packet header */
typedef MLAN_PACK_START struct {
/** IP protocol version */
t_u8 version;
/** flow label */
t_u8 flow_lab[3];
/** Payload length */
t_u16 payload_len;
/** Next header type */
t_u8 next_hdr;
/** Hot limit */
t_u8 hop_limit;
/** Source address */
t_u8 src_addr[16];
/** Destination address */
t_u8 dst_addr[16];
/** ICMP type */
t_u8 icmp_type;
/** IPv6 Code */
t_u8 ipv6_code;
/** IPv6 Checksum */
t_u16 ipv6_checksum;
/** Flags */
t_u32 flags;
/** Target address */
t_u8 taget_addr[16];
/** Reserved */
t_u8 rev[8];
} MLAN_PACK_END IPv6_Nadv_t;
/** Check if stream 2X2 enabled */
#define IS_STREAM_2X2(x) ((x)&FEATURE_CTRL_STREAM_2X2)
/** Check if DFS support enabled */
@ -2979,6 +3151,18 @@ struct _mlan_adapter {
#define MLAN_TCP_ACK_OFFSET 24
#define MLAN_TCP_ACK_HEADER_LEN 52
#ifdef STA_SUPPORT
/** Region code mapping */
typedef struct _region_code_mapping {
/** Region */
t_u8 region[COUNTRY_CODE_LEN];
/** Code */
t_u8 code;
} region_code_mapping_t;
extern region_code_mapping_t region_code_mapping[];
t_u8 *wlan_11d_code_2_region(pmlan_adapter pmadapter, t_u8 code);
#endif
/** Rx packet Sniffer Operation Mode
*
* MODE1 : Can be enabled only in disconnected state.
@ -3181,6 +3365,10 @@ mlan_status wlan_write_data_complete(pmlan_adapter pmlan_adapter,
pmlan_buffer pmbuf, mlan_status status);
#ifdef USB
/** Request event lock */
t_void wlan_request_event_lock(mlan_adapter *pmadapter);
/** Release event lock */
t_void wlan_release_event_lock(mlan_adapter *pmadapter);
mlan_status wlan_usb_deaggr_rx_pkt(pmlan_adapter pmadapter, pmlan_buffer pmbuf);
/**
@ -3380,6 +3568,12 @@ mlan_status wlan_ret_cross_chip_synch(pmlan_private pmpriv,
mlan_ioctl_req *pioctl_buf);
mlan_status wlan_misc_ioctl_cross_chip_synch(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);
mlan_status wlan_cmd_tsp_config(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
t_u16 cmd_action, t_void *pdata_buf);
mlan_status wlan_ret_tsp_config(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf);
mlan_status wlan_misc_ioctl_tsp_config(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);
/** get ralist info */
int wlan_get_ralist_info(mlan_private *priv, pralist_info buf);
/** dump ralist */
@ -3454,6 +3648,16 @@ mlan_status wlan_ret_802_11_hs_cfg(pmlan_private pmpriv,
/** Sends HS_WAKEUP event to applications */
t_void wlan_host_sleep_wakeup_event(pmlan_private priv);
mlan_status wlan_cmd_802_11_fw_wakeup_method(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd,
t_u16 cmd_action,
t_u16 *pdata_buf);
mlan_status wlan_ret_fw_wakeup_method(pmlan_private pmpriv,
HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf);
mlan_status wlan_fw_wakeup_method(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);
/** Prepares command of robustcoex */
mlan_status wlan_cmd_robustcoex(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
t_u16 cmd_action, t_u16 *pdata_buf);
@ -3836,6 +4040,7 @@ t_void wlan_set_chan_dfs_state(mlan_private *priv, t_u16 band, t_u8 chan,
dfs_state_t dfs_state);
t_void wlan_reset_all_chan_dfs_state(mlan_private *priv, t_u16 band,
dfs_state_t dfs_state);
/* 802.11D related functions */
/** Initialize 11D */
t_void wlan_11d_priv_init(mlan_private *pmpriv);
@ -4079,6 +4284,7 @@ mlan_status wlan_misc_ioctl_custom_ie_list(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req,
t_bool send_ioctl);
mlan_status wlan_cmd_func_init(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd);
mlan_status wlan_cmd_get_hw_spec(pmlan_private pmpriv,
HostCmd_DS_COMMAND *pcmd);
mlan_status wlan_ret_get_hw_spec(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
@ -4368,7 +4574,6 @@ mlan_status wlan_misc_ioctl_get_tsf(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);
void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left);
void wlan_free_fw_cfp_tables(mlan_adapter *pmadapter);
mlan_status wlan_misc_chan_reg_cfg(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);
mlan_status wlan_misc_region_power_cfg(pmlan_adapter pmadapter,
@ -4410,6 +4615,9 @@ t_u8 wlan_mrvl_rateid_to_ieee_rateid(t_u8 rate);
t_u8 wlan_get_center_freq_idx(mlan_private *pmpriv, t_u16 band, t_u32 pri_chan,
t_u8 chan_bw);
mlan_status wlan_cmd_chan_region_cfg(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
t_void *pdata_buf);
mlan_status wlan_ret_chan_region_cfg(pmlan_private pmpriv,
HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf);
@ -4449,6 +4657,9 @@ mlan_status wlan_cmd_set_get_low_power_mode_cfg(pmlan_private pmpriv,
mlan_status wlan_ret_set_get_low_power_mode_cfg(pmlan_private pmpriv,
HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf);
mlan_status wlan_ret_auth_assoc_timeout_cfg(pmlan_private pmpriv,
HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf);
mlan_status wlan_cmd_range_ext(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
t_u16 cmd_action, t_void *pdata_buf);
@ -4472,6 +4683,9 @@ mlan_status wlan_cmd_edmac_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
mlan_status wlan_misc_ioctl_country_code(pmlan_adapter pmadapter,
mlan_ioctl_req *pioctl_req);
/** Get custom Fw data */
mlan_status wlan_get_custom_fw_data(pmlan_adapter pmadapter, t_u8 *pdata);
/**
* @brief RA based queueing
*
@ -4836,4 +5050,27 @@ t_bool wlan_secure_add(t_void *datain, t_s32 add, t_void *dataout,
t_bool wlan_secure_sub(t_void *datain, t_s32 sub, t_void *dataout,
data_type type);
void wlan_wmm_contention_init(
mlan_private *mlan,
const IEEEtypes_WmmAcParameters_t ac_params[MAX_AC_QUEUES]);
void wlan_update_sta_ps_state(pmlan_private priv, t_u8 *mac, t_u8 sleep);
mlan_status wlan_cmd_sta_tx_rate_req(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
t_pvoid pdata_buf);
mlan_status wlan_ret_sta_tx_rate(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf);
mlan_status wlan_cmd_mclient_scheduling_cfg(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd,
t_u16 cmd_action,
t_pvoid pdata_buf);
mlan_status wlan_cmd_mclient_scheduling_enable(pmlan_private pmpriv,
t_bool enable);
void wlan_add_iPhone_entry(mlan_private *priv, t_u8 *mac);
void wlan_delete_iPhone_entry(mlan_private *priv, t_u8 *mac);
extern void print_chan_switch_block_event(t_u16 reason_code);
#endif /* !_MLAN_MAIN_H_ */

View file

@ -46,6 +46,31 @@ Change Log:
/********************************************************
Global Variables
********************************************************/
#if defined(USB8978) || defined(SD8978)
/** custom Fw data */
/** Fw remap config */
t_u8 fw_data_fw_remap_config[FW_DATA_FW_REMAP_CONFIG_LEN] = {
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00,
0x00, 0x6A, 0x26, 0x96, 0xB2, 0x44, 0x65, 0x01, 0x04, 0x01, 0x00,
0x00, 0x80, 0x00, 0x00, 0x0C, 0xA0, 0xCC, 0x1B, 0x6A, 0x41, 0x04,
0x00, 0x0C, 0xA0, 0x02, 0x00, 0x00, 0x00, 0x4A, 0xE7, 0xE5, 0xA3};
#endif
#if defined(USB8978)
/** USB endpoint config */
t_u8 fw_data_usb_bulk_ep[FW_DATA_USB_BULK_EP_LEN] = {
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x93, 0xCC, 0x0E, 0xB8, 0xFC, 0x83, 0x02, 0xC0, 0x01, 0x00, 0x00, 0x00,
0xF8, 0x83, 0x02, 0xC0, 0xCC, 0x1B, 0x6A, 0x41, 0xAC, 0x56, 0xD9, 0xEB};
#endif
#if defined(USB8978) || defined(SD8978)
/** DPD curremt optimizations */
t_u8 fw_data_dpd_current_opt[FW_DATA_DPD_CURRENT_OPT_LEN] = {
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x93, 0xCC, 0x0E, 0xB8, 0xF8, 0xAF, 0x00, 0xB0, 0xCC, 0x1B, 0x6A, 0x41,
0xFC, 0xAF, 0x00, 0xB0, 0x01, 0x00, 0x00, 0x00, 0xF5, 0x1D, 0xBA, 0x80};
#endif
/********************************************************
Local Functions
@ -300,6 +325,71 @@ static mlan_status wlan_custom_ioctl_auto_delete(pmlan_private pmpriv,
/********************************************************
Global Functions
********************************************************/
/**
* @brief Get custom Fw data
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to custom Fw data buffer
*
* @return MLAN_STATUS_SUCCESS --success, otherwise
* MLAN_STATUS_FAILURE
*/
mlan_status wlan_get_custom_fw_data(pmlan_adapter pmadapter, t_u8 *pdata)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
t_u32 fw_data_param = pmadapter->init_para.fw_data_cfg;
t_u32 fw_data_param_num = 0, index = 0, i = 0;
fw_data_t *pfw_data_list = MNULL;
ENTER();
MASSERT(pmadapter);
if (MNULL == pdata) {
LEAVE();
return MLAN_STATUS_FAILURE;
}
fw_data_param_num = MIN(MAX_FW_DATA_BLOCK, bitcount(fw_data_param));
pfw_data_list = (fw_data_t *)pdata;
for (i = 0; i < fw_data_param_num; i++) {
/** initilize the Fw data buffers with correct index */
while (fw_data_param) {
index = fw_data_param & (-fw_data_param);
switch (index) {
#if defined(USB8978) || defined(SD8978)
case MBIT(0):
pfw_data_list[i].fw_data_buffer =
fw_data_fw_remap_config;
pfw_data_list[i].fw_data_buffer_len =
sizeof(fw_data_fw_remap_config);
break;
#endif
#if defined(USB8978)
case MBIT(1):
pfw_data_list[i].fw_data_buffer =
fw_data_usb_bulk_ep;
pfw_data_list[i].fw_data_buffer_len =
sizeof(fw_data_usb_bulk_ep);
break;
#endif
#if defined(USB8978) || defined(SD8978)
case MBIT(2):
pfw_data_list[i].fw_data_buffer =
fw_data_dpd_current_opt;
pfw_data_list[i].fw_data_buffer_len =
sizeof(fw_data_dpd_current_opt);
break;
#endif
default:
break;
}
fw_data_param ^= index;
break;
}
}
LEAVE();
return ret;
}
/**
* @brief send host cmd
@ -857,6 +947,40 @@ mlan_status wlan_pm_ioctl_hscfg(pmlan_adapter pmadapter,
return status;
}
/**
* @brief Get/Set the firmware wakeup method
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
* @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
* otherwise fail
*/
mlan_status wlan_fw_wakeup_method(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req)
{
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_status ret = MLAN_STATUS_SUCCESS;
t_u16 cmd_action;
mlan_ds_pm_cfg *pmcfg = (mlan_ds_pm_cfg *)pioctl_req->pbuf;
ENTER();
if (pioctl_req->action == MLAN_ACT_SET)
cmd_action = HostCmd_ACT_GEN_SET;
else
cmd_action = HostCmd_ACT_GEN_GET;
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_FW_WAKE_METHOD,
cmd_action, 0, (t_void *)pioctl_req,
&pmcfg->param.fw_wakeup_params);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
LEAVE();
return ret;
}
/**
* @brief Set Robustcoex gpiocfg
*
@ -1388,6 +1512,14 @@ mlan_status wlan_misc_ioctl_custom_ie_list(pmlan_adapter pmadapter,
pioctl_req->action = MLAN_ACT_GET;
/* Get the IE */
cmd_action = HostCmd_ACT_GEN_GET;
ie_data = (custom_ie *)(((t_u8 *)&misc->param.cust_ie) +
sizeof(MrvlIEtypesHeader_t));
index = ie_data->ie_index;
if (index >= pmadapter->max_mgmt_ie_index) {
PRINTM(MERROR, "Invalid custom IE index %d\n", index);
ret = MLAN_STATUS_FAILURE;
goto done;
}
} else {
/* ioctl_len : ioctl length from application, start with
* misc->param.cust_ie.len and reach upto 0 */
@ -1728,7 +1860,7 @@ mlan_status wlan_reg_mem_ioctl_reg_rw(pmlan_adapter pmadapter,
defined(PCIE9097) || defined(USB9097) || defined(SDIW624) || \
defined(SDAW693) || defined(PCIEAW693) || defined(PCIEIW624) || \
defined(USBIW624) || defined(SD9097) || defined(SD9177) || \
defined(SDIW615) || defined(USBIW615)
defined(SDIW610) || defined(USBIW610)
case MLAN_REG_CIU:
cmd_no = HostCmd_CMD_REG_ACCESS;
break;
@ -1912,6 +2044,38 @@ done:
return sta_ptr;
}
/**
* @brief This function deletes iPhone entry from llde device list
*
* @param priv A pointer to mlan_private
* @param mac iPhone mac address to dekete in llde iPhone device list table
*
* @return void
*/
void wlan_delete_iPhone_entry(mlan_private *priv, t_u8 *mac)
{
t_u8 i = 0;
/* validate devices which are in llde_iphonefilters list are available
*/
for (i = 0; i < MAX_IPHONE_FILTER_ENTRIES; i++) {
if (memcmp(priv->adapter,
&priv->adapter
->llde_iphonefilters[i *
MLAN_MAC_ADDR_LENGTH],
mac, MLAN_MAC_ADDR_LENGTH) == 0) {
/* remove device as it is not available */
// coverity[bad_memset: SUPPRESS]
memset(priv->adapter,
(t_u8 *)&priv->adapter->llde_iphonefilters
[i * MLAN_MAC_ADDR_LENGTH],
0, MLAN_MAC_ADDR_LENGTH);
priv->adapter->llde_totalIPhones--;
break;
}
}
}
/**
* @brief This function will delete a station entry from station list
*
@ -1927,6 +2091,8 @@ t_void wlan_delete_station_entry(mlan_private *priv, t_u8 *mac)
ENTER();
sta_ptr = wlan_get_station_entry(priv, mac);
if (sta_ptr) {
if (sta_ptr->is_apple_sta)
wlan_delete_iPhone_entry(priv, mac);
util_unlink_list(priv->adapter->pmoal_handle, &priv->sta_list,
(pmlan_linked_list)sta_ptr,
priv->adapter->callbacks.moal_spin_lock,
@ -3178,7 +3344,8 @@ mlan_status wlan_reg_rx_mgmt_ind(pmlan_adapter pmadapter,
/* Send request to firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RX_MGMT_IND,
pioctl_req->action, 0, (t_void *)pioctl_req,
(t_u16)pioctl_req->action, 0,
(t_void *)pioctl_req,
&misc->param.mgmt_subtype_mask);
if (ret == MLAN_STATUS_SUCCESS)
@ -3408,7 +3575,8 @@ mlan_status wlan_process_802dot11_mgmt_pkt(mlan_private *priv, t_u8 *payload,
prx_pd->nf, prx_pd->snr);
}
if (memcmp(pmadapter, pieee_pkt_hdr->addr1, broadcast,
MLAN_MAC_ADDR_LENGTH))
MLAN_MAC_ADDR_LENGTH) &&
!is_mcast_addr(pieee_pkt_hdr->addr1))
unicast = MTRUE;
break;
default:
@ -3596,8 +3764,17 @@ mlan_status wlan_misc_multi_ap_cfg(pmlan_adapter pmadapter,
if (MLAN_ACT_GET == pioctl_req->action)
misc->param.multi_ap_flag = pmpriv->multi_ap_flag;
else if (MLAN_ACT_SET == pioctl_req->action)
else if (MLAN_ACT_SET == pioctl_req->action) {
if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_UAP) {
ret = wlan_prepare_cmd(pmpriv,
HostCmd_CMD_APCMD_SYS_CONFIGURE,
HostCmd_ACT_GEN_SET, 0,
(t_void *)pioctl_req, MNULL);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
}
pmpriv->multi_ap_flag = misc->param.multi_ap_flag;
}
LEAVE();
return ret;
@ -3734,25 +3911,95 @@ static t_u8 wlan_check_ie_11b_support_rates(pIEEEtypes_Generic_t prates)
#endif
/**
* @brief check if Apple ie present.
* @brief This function adds iPhone entry into llde device list
*
* @param priv A pointer to mlan_private
* @param mac iPhone mac address to add in llde iPhone device list table
*
* @return void
*/
void wlan_add_iPhone_entry(mlan_private *priv, t_u8 *mac)
{
t_u8 null_mac_addr[MLAN_MAC_ADDR_LENGTH] = {0};
t_u8 t_iphonefilters[MAX_IPHONE_FILTER_ENTRIES * MLAN_MAC_ADDR_LENGTH] =
{0};
int i = 0, j = 0;
/* reset count */
priv->adapter->llde_totalIPhones = 0;
if (MAX_IPHONE_FILTER_ENTRIES > 1) {
/* back up original list */
memcpy_ext(priv->adapter, &t_iphonefilters,
&priv->adapter->llde_iphonefilters,
MAX_IPHONE_FILTER_ENTRIES * MLAN_MAC_ADDR_LENGTH,
MAX_IPHONE_FILTER_ENTRIES * MLAN_MAC_ADDR_LENGTH);
/* clear original list */
// coverity[bad_memset: SUPPRESS]
memset(priv->adapter,
(t_u8 *)&priv->adapter->llde_iphonefilters, 0,
MAX_IPHONE_FILTER_ENTRIES * MLAN_MAC_ADDR_LENGTH);
/* copy valid entries into original list */
for (i = 0, j = 1; i < MAX_IPHONE_FILTER_ENTRIES; i++) {
if (memcmp(priv->adapter,
&t_iphonefilters[i * MLAN_MAC_ADDR_LENGTH],
&null_mac_addr, MLAN_MAC_ADDR_LENGTH) != 0) {
memcpy_ext(
priv->adapter,
&priv->adapter->llde_iphonefilters
[j++ * MLAN_MAC_ADDR_LENGTH],
&t_iphonefilters[i *
MLAN_MAC_ADDR_LENGTH],
MLAN_MAC_ADDR_LENGTH,
MLAN_MAC_ADDR_LENGTH);
}
}
}
/* add latest connected device entry at the start of list to get high
* priority while search in list */
if (MAX_IPHONE_FILTER_ENTRIES) {
memcpy_ext(priv->adapter, &priv->adapter->llde_iphonefilters[0],
mac, MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
}
/* update connected device count */
for (i = 0; i < MAX_IPHONE_FILTER_ENTRIES; i++) {
if (memcmp(priv->adapter,
&priv->adapter
->llde_iphonefilters[i *
MLAN_MAC_ADDR_LENGTH],
&null_mac_addr, MLAN_MAC_ADDR_LENGTH) != 0)
priv->adapter->llde_totalIPhones++;
}
return;
}
/**
* @brief extracts all vendor specific oui's to pass it to fw in add_station
* cmd
*
* @param pmadapter A pointer to mlan_adapter structure
* @param sta_ptr A pointer to sta_node
* @param pbuf A pointer to IE buffer
* @param buf_len IE buffer len
*
* @return MTRUE/MFALSE
*/
static t_u8 wlan_is_apple_ie_present(pmlan_adapter pmadapter, t_u8 *pbuf,
t_u16 buf_len)
static void wlan_check_sta_vendor_ies(pmlan_adapter pmadapter,
sta_node *sta_ptr, t_u8 *pbuf,
t_u16 buf_len)
{
t_u16 bytes_left = buf_len;
IEEEtypes_ElementId_e element_id;
t_u8 *pcurrent_ptr = pbuf;
t_u8 element_len;
t_u8 element_len, oui_pos = 0, index = 0, found_existing_oui = 0;
t_u16 total_ie_len;
IEEEtypes_VendorSpecific_t *pvendor_ie;
const t_u8 apple_oui[4] = {0x00, 0x17, 0xf2, 0x0a};
t_u8 found_apple_ie = MFALSE;
const t_u8 apple_oui[VENDOR_OUI_LEN] = {0x00, 0x17, 0xf2, 0x0a};
ENTER();
@ -3773,8 +4020,35 @@ static t_u8 wlan_is_apple_ie_present(pmlan_adapter pmadapter, t_u8 *pbuf,
pvendor_ie = (IEEEtypes_VendorSpecific_t *)pcurrent_ptr;
if (!memcmp(pmadapter, pvendor_ie->vend_hdr.oui,
apple_oui, sizeof(apple_oui))) {
found_apple_ie = MTRUE;
PRINTM(MINFO, "found Apple IE\n");
sta_ptr->is_apple_sta = MTRUE;
}
found_existing_oui = 0;
/* check if oui already present in list */
for (index = 0; index < sta_ptr->vendor_oui_count;
index++) {
oui_pos = index * VENDOR_OUI_LEN;
if (!memcmp(pmadapter, pvendor_ie->vend_hdr.oui,
(t_u8 *)&sta_ptr
->vendor_oui[oui_pos],
VENDOR_OUI_LEN)) {
found_existing_oui = 1;
break;
}
}
if ((found_existing_oui == 0) &&
(sta_ptr->vendor_oui_count < MAX_VENDOR_OUI_NUM)) {
// add oui in list, sta_ptr->vendor_oui_count
// does not exceed MAX_VENDOR_OUI_NUM hence
// sta_ptr->vendor_oui buffer size does not
// exceed (MAX_VENDOR_OUI_NUM * VENDOR_OUI_LEN)
// coverity[overrun-buffer-arg: SUPPRESS]
memcpy_ext(pmadapter,
(t_u8 *)&sta_ptr->vendor_oui
[sta_ptr->vendor_oui_count *
VENDOR_OUI_LEN],
pvendor_ie->vend_hdr.oui,
VENDOR_OUI_LEN, VENDOR_OUI_LEN);
sta_ptr->vendor_oui_count++;
}
break;
default:
@ -3783,12 +4057,10 @@ static t_u8 wlan_is_apple_ie_present(pmlan_adapter pmadapter, t_u8 *pbuf,
pcurrent_ptr += element_len + 2;
/* Need to account for IE ID and IE Len */
bytes_left -= (element_len + 2);
if (found_apple_ie)
break;
}
LEAVE();
return found_apple_ie;
return;
}
/**
@ -3872,6 +4144,7 @@ void wlan_check_sta_capability(pmlan_private priv, pmlan_buffer pevent,
t_u8 *rate = MNULL;
t_u8 b_only = MFALSE;
#endif
t_u8 maxIPhoneEntries = MAX_IPHONE_FILTER_ENTRIES;
int tlv_buf_left = pevent->data_len - ASSOC_EVENT_FIX_SIZE;
MrvlIEtypesHeader_t *tlv =
@ -3930,12 +4203,14 @@ void wlan_check_sta_capability(pmlan_private priv, pmlan_buffer pevent,
ie_len);
PRINTM(MCMND, "STA: is_wmm_enabled=%d\n",
sta_ptr->is_wmm_enabled);
sta_ptr->is_apple_sta =
wlan_is_apple_ie_present(priv->adapter,
assoc_req_ie,
ie_len);
PRINTM(MINFO, "STA: is Apple device=%d\n",
sta_ptr->is_apple_sta);
wlan_check_sta_vendor_ies(priv->adapter,
sta_ptr, assoc_req_ie,
ie_len);
if (sta_ptr->is_apple_sta && maxIPhoneEntries) {
wlan_add_iPhone_entry(
priv, sta_ptr->mac_addr);
}
pht_cap = (IEEEtypes_HTCap_t *)
wlan_get_specific_ie(priv, assoc_req_ie,
ie_len,
@ -4325,10 +4600,17 @@ mlan_status wlan_radio_ioctl_ant_cfg(pmlan_adapter pmadapter,
defined(PCIE9097) || defined(USB9097) || defined(SDIW624) || \
defined(SDAW693) || defined(PCIEAW693) || defined(PCIEIW624) || \
defined(USBIW624) || defined(SD9097)
if (IS_CARD9098(pmadapter->card_type) ||
IS_CARD9097(pmadapter->card_type) ||
IS_CARDAW693(pmadapter->card_type) ||
IS_CARDIW624(pmadapter->card_type)) {
if (IS_CARDAW693(pmadapter->card_type) &&
ant_cfg->tx_antenna == RF_ANTENNA_AUTO) {
PRINTM(MCMND,
"user_htstream=0x%x, tx_antenna=0x%x >rx_antenna=0x%x\n",
pmadapter->user_htstream,
ant_cfg->tx_antenna,
ant_cfg->rx_antenna);
} else if (IS_CARD9098(pmadapter->card_type) ||
IS_CARD9097(pmadapter->card_type) ||
IS_CARDAW693(pmadapter->card_type) ||
IS_CARDIW624(pmadapter->card_type)) {
ant_cfg->tx_antenna &= 0x0303;
ant_cfg->rx_antenna &= 0x0303;
/** 2G antcfg TX */
@ -4378,10 +4660,11 @@ mlan_status wlan_radio_ioctl_ant_cfg(pmlan_adapter pmadapter,
}
#endif
if (!ant_cfg->tx_antenna ||
bitcount(ant_cfg->tx_antenna & 0x00FF) >
pmadapter->number_of_antenna ||
bitcount(ant_cfg->tx_antenna & 0xFF00) >
pmadapter->number_of_antenna) {
(ant_cfg->tx_antenna != RF_ANTENNA_AUTO &&
(bitcount(ant_cfg->tx_antenna & 0x00FF) >
pmadapter->number_of_antenna ||
bitcount(ant_cfg->tx_antenna & 0xFF00) >
pmadapter->number_of_antenna))) {
PRINTM(MERROR,
"Invalid TX antenna setting: 0x%x\n",
ant_cfg->tx_antenna);
@ -4390,6 +4673,7 @@ mlan_status wlan_radio_ioctl_ant_cfg(pmlan_adapter pmadapter,
ret = MLAN_STATUS_FAILURE;
goto exit;
}
if (ant_cfg->rx_antenna) {
if (bitcount(ant_cfg->rx_antenna & 0x00FF) >
pmadapter->number_of_antenna ||
@ -4403,8 +4687,11 @@ mlan_status wlan_radio_ioctl_ant_cfg(pmlan_adapter pmadapter,
ret = MLAN_STATUS_FAILURE;
goto exit;
}
} else
ant_cfg->rx_antenna = ant_cfg->tx_antenna;
} else {
if (ant_cfg->tx_antenna != RF_ANTENNA_AUTO)
ant_cfg->rx_antenna =
ant_cfg->tx_antenna;
}
} else if (!radio_cfg->param.ant_cfg_1x1.antenna ||
((radio_cfg->param.ant_cfg_1x1.antenna !=
RF_ANTENNA_AUTO) &&
@ -5275,6 +5562,47 @@ mlan_status wlan_misc_ioctl_cross_chip_synch(pmlan_adapter pmadapter,
return ret;
}
/**
* @brief Set/Get TSP config
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
* @return MLAN_STATUS_SUCCESS --success, otherwise fail
*/
mlan_status wlan_misc_ioctl_tsp_config(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
mlan_ds_misc_cfg *misc_cfg = MNULL;
t_u16 cmd_action = 0;
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
ENTER();
misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
if (pioctl_req->action == MLAN_ACT_SET)
cmd_action = HostCmd_ACT_GEN_SET;
else if (pioctl_req->action == MLAN_ACT_GET)
cmd_action = HostCmd_ACT_GEN_GET;
else {
PRINTM(MERROR, "Unsupported cmd_action\n");
LEAVE();
return MLAN_STATUS_FAILURE;
}
/* Send request to firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TSP_CFG, cmd_action, 0,
(t_void *)pioctl_req,
&misc_cfg->param.gpio_tsf_latch_config);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
LEAVE();
return ret;
}
/**
* @brief Set coalesce config
*
@ -6568,33 +6896,37 @@ mlan_status wlan_misc_chan_reg_cfg(pmlan_adapter pmadapter,
ENTER();
if (pioctl_req->action == MLAN_ACT_GET)
cmd_action = HostCmd_ACT_GEN_GET;
else {
PRINTM(MERROR, "No support set channel region cfg!");
LEAVE();
return MLAN_STATUS_FAILURE;
}
misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
if (misc_cfg &&
misc_cfg->param.custom_reg_domain.region.country_code[0] != '\0' &&
misc_cfg->param.custom_reg_domain.region.country_code[1] != '\0') {
/* Copy the driver country code in the custom_reg_domain. The
* cmd response handler will use it to compare with the FW
* country code
*/
pmadapter->country_code[0] =
misc_cfg->param.custom_reg_domain.region.country_code[0];
pmadapter->country_code[1] =
misc_cfg->param.custom_reg_domain.region.country_code[1];
pmadapter->country_code[2] = '\0';
if (pioctl_req->action == MLAN_ACT_GET) {
cmd_action = HostCmd_ACT_GEN_GET;
if (misc_cfg &&
misc_cfg->param.custom_reg_domain.region.country_code[0] !=
'\0' &&
misc_cfg->param.custom_reg_domain.region.country_code[1] !=
'\0') {
/* Copy the driver country code in the
* custom_reg_domain. The cmd response handler will use
* it to compare with the FW country code
*/
pmadapter->country_code[0] =
misc_cfg->param.custom_reg_domain.region
.country_code[0];
pmadapter->country_code[1] =
misc_cfg->param.custom_reg_domain.region
.country_code[1];
pmadapter->country_code[2] = '\0';
}
/* Send 2G/5G/6G CFP table request to the firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_CHAN_REGION_CFG,
cmd_action, 0, (t_void *)pioctl_req,
MNULL);
} else {
cmd_action = HostCmd_ACT_GEN_SET;
/* Send 2G/5G/6G CFP table to the firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_CHAN_REGION_CFG,
cmd_action, 0, (t_void *)pioctl_req,
&misc_cfg->param.chan_attr_cfg);
}
/* Send 2G/5G CFP table request to firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_CHAN_REGION_CFG, cmd_action,
0, (t_void *)pioctl_req, MNULL);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
@ -6758,7 +7090,7 @@ mlan_status wlan_misc_ioctl_ch_load(pmlan_adapter pmadapter,
return MLAN_STATUS_FAILURE;
pmpriv = pmadapter->priv[pioctl_req->bss_index];
misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
cmd_action = pioctl_req->action;
cmd_action = (t_u16)pioctl_req->action;
/* Send request to firmware */
pmpriv->ch_load_param = 255; /* Default value for identifying
@ -7548,6 +7880,21 @@ mlan_status wlan_misc_ioctl_rf_test_cfg(pmlan_adapter pmadapter,
cmd_action, 0, (t_void *)pioctl_req,
&(pmisc->param.mfg_otp_mac_addr_rd_wr));
break;
case MLAN_OID_MISC_OTP_CAL_DATA_RD_WR:
if (pioctl_req->action == MLAN_ACT_SET)
cmd_action = HostCmd_ACT_GEN_SET;
else if (pioctl_req->action == MLAN_ACT_GET)
cmd_action = HostCmd_ACT_GEN_GET;
else {
PRINTM(MERROR, "Unsupported cmd_action\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND,
cmd_action, 0, (t_void *)pioctl_req,
&(pmisc->param.mfg_otp_cal_data_rd_wr));
break;
}
if (ret == MLAN_STATUS_SUCCESS)
@ -7909,11 +8256,42 @@ mlan_status wlan_misc_ioctl_edmac_cfg(pmlan_adapter pmadapter,
misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
if (MLAN_ACT_SET == pioctl_req->action) {
misc->param.edmac_cfg.ed_ctrl_2g = 0x1;
misc->param.edmac_cfg.ed_offset_2g = 0x8;
misc->param.edmac_cfg.ed_ctrl_5g = 0x1;
misc->param.edmac_cfg.ed_offset_5g = 0x8;
misc->param.edmac_cfg.ed_bitmap_txq_lock = 0x1e00FF;
if (IS_CARD9098(pmadapter->card_type) ||
IS_CARD9097(pmadapter->card_type) ||
IS_CARDAW693(pmadapter->card_type) ||
IS_CARDIW624(pmadapter->card_type) ||
IS_CARDIW610(pmadapter->card_type)) {
misc->param.edmac_cfg.ed_ctrl_2g = 0x1;
misc->param.edmac_cfg.ed_offset_2g = 0x8;
misc->param.edmac_cfg.ed_ctrl_5g = 0x1;
misc->param.edmac_cfg.ed_offset_5g = 0x8;
misc->param.edmac_cfg.ed_bitmap_txq_lock = 0x1e00FF;
} else if (IS_CARD9177(pmadapter->card_type)) {
// from config/ed_mac_ctrl_V2_nw61x.conf
misc->param.edmac_cfg.ed_ctrl_2g = 0x1;
misc->param.edmac_cfg.ed_offset_2g = 0xA;
misc->param.edmac_cfg.ed_ctrl_5g = 0x1;
misc->param.edmac_cfg.ed_offset_5g = 0xA;
misc->param.edmac_cfg.ed_bitmap_txq_lock = 0x1e00FF;
} else if (IS_CARD8997(pmadapter->card_type)) {
// from config/ed_mac_ctrl_V2_8997.conf
misc->param.edmac_cfg.ed_ctrl_2g = 0x1;
misc->param.edmac_cfg.ed_offset_2g = 0x0;
misc->param.edmac_cfg.ed_ctrl_5g = 0x1;
misc->param.edmac_cfg.ed_offset_5g = 0x4;
misc->param.edmac_cfg.ed_bitmap_txq_lock = 0xFF;
} else if (IS_CARD8978(pmadapter->card_type)) {
// from config/ed_mac_ctrl_V2_iw416.conf
misc->param.edmac_cfg.ed_ctrl_2g = 0x1;
misc->param.edmac_cfg.ed_offset_2g = 0x9;
misc->param.edmac_cfg.ed_ctrl_5g = 0x1;
misc->param.edmac_cfg.ed_offset_5g = 0xC;
misc->param.edmac_cfg.ed_bitmap_txq_lock = 0xFF;
} else {
PRINTM(MERROR, "Failed to configure edmac param");
pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
return MLAN_STATUS_FAILURE;
}
} else {
misc->param.edmac_cfg.ed_ctrl_2g = 0x0;
misc->param.edmac_cfg.ed_ctrl_5g = 0x0;
@ -8111,3 +8489,41 @@ fail:
status = MFALSE;
goto ret;
}
/**
* @brief Prints verbose msg of 6G chan_switch block event for the reason_code
*
* @param reason_code Reason code contained in event body
*
* @return N/A
*/
void print_chan_switch_block_event(t_u16 reason_code)
{
ENTER();
switch (reason_code) {
case BLOCK_6G_CHAN_SWITCH_REASON_STA_RX_ECSA:
PRINTM(MEVENT,
"EVENT: Mobile-AP does not support HE-Cap/WPA3"
" to switch to 6Ghz, leading to RX ECSA Failure of STA\n");
break;
case BLOCK_6G_CHAN_SWITCH_REASON_MMH_STA:
PRINTM(MEVENT,
"EVENT: Mobile-AP does not support HE-Cap/WPA3"
" to switch to 6Ghz, leading to 6Ghz Assoc Failure of STA\n");
break;
case BLOCK_6G_CHAN_SWITCH_REASON_STA_MMH:
PRINTM(MEVENT,
"EVENT: Mobile-AP does not support HE-Cap/WPA3"
" to switch to 6Ghz channel same as STA, leading to bss start failure");
break;
case BLOCK_6G_CHAN_SWITCH_REASON_MMH:
PRINTM(MEVENT,
"EVENT: Mobile-AP does not support HE-Cap/WPA3"
" to switch to 6Ghz channel, leading to chan_switch failure");
break;
default:
break;
}
LEAVE();
return;
}

View file

@ -270,7 +270,8 @@ static mlan_status wlan_init_dma_cfg_registers(mlan_adapter *pmadapter,
t_u8 dma_mode, t_u16 size,
t_u8 init)
{
t_u32 dma_cfg, dma_cfg2, dma_cfg3;
t_u32 dma_cfg, dma_cfg2 = 0;
t_u32 dma_cfg3 = 0;
pmlan_callbacks pcb = &pmadapter->callbacks;
mlan_status ret = MLAN_STATUS_SUCCESS;
@ -532,11 +533,16 @@ static mlan_status wlan_init_adma(mlan_adapter *pmadapter, t_u8 type,
}
}
}
if (wlan_init_dma_cfg_registers(pmadapter, q_addr, direction, dma_mode,
size, init)) {
PRINTM(MERROR, "Failed to configure dma_cfg registers\n");
ret = MLAN_STATUS_FAILURE;
goto done;
if (!IS_PCIEIW624(pmadapter->card_type) &&
!(IS_PCIEAW693(pmadapter->card_type) &&
(pmadapter->card_rev > CHIP_AW693_REV_A0))) {
if (wlan_init_dma_cfg_registers(pmadapter, q_addr, direction,
dma_mode, size, init)) {
PRINTM(MERROR,
"Failed to configure dma_cfg registers\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
}
if (type == ADMA_CMD && !init) {
@ -968,9 +974,20 @@ static mlan_status wlan_pcie_send_vdll(mlan_adapter *pmadapter,
defined(PCIEIW624)
/* issue the DMA */
if (pmadapter->pcard_pcie->reg->use_adma) {
/* send the VDLL block down to the firmware */
wlan_init_adma(pmadapter, ADMA_CMD, pmbuf->buf_pa,
pmbuf->data_len, MFALSE);
if (IS_PCIEIW624(pmadapter->card_type) ||
(IS_PCIEAW693(pmadapter->card_type) &&
(pmadapter->card_rev > CHIP_AW693_REV_A0))) {
if (wlan_pcie_send_boot_cmd(pmadapter, pmbuf, MFALSE)) {
PRINTM(MERROR,
"Failed to send vdll block to device\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
} else {
/* send the VDLL block down to the firmware */
wlan_init_adma(pmadapter, ADMA_CMD, pmbuf->buf_pa,
pmbuf->data_len, MFALSE);
}
}
#endif
@ -1852,7 +1869,7 @@ static mlan_status wlan_pcie_alloc_cmdrsp_buf(mlan_adapter *pmadapter)
pmlan_callbacks pcb = &pmadapter->callbacks;
mlan_status ret = MLAN_STATUS_SUCCESS;
/** Virtual base address of command response */
t_u8 *cmdrsp_vbase;
t_u8 *cmdrsp_vbase = MNULL;
/** Physical base address of command response */
t_u64 cmdrsp_pbase = 0;
@ -2029,7 +2046,7 @@ static mlan_status wlan_pcie_send_data_complete(mlan_adapter *pmadapter)
pmlan_callbacks pcb = &pmadapter->callbacks;
mlan_buffer *pmbuf;
t_u32 wrdoneidx;
t_u32 rdptr;
t_u32 rdptr = 0;
t_u32 unmap_count = 0;
#if defined(PCIE8997) || defined(PCIE8897)
t_u32 txrx_rw_ptr_mask = pmadapter->pcard_pcie->reg->txrx_rw_ptr_mask;
@ -2395,9 +2412,10 @@ static mlan_status wlan_pcie_send_adma_data(mlan_adapter *pmadapter,
if (wlan_check_txbd_not_full(pmadapter)) {
#ifdef PCIEAW693
if (IS_PCIEAW693(pmadapter->card_type) &&
(wlan_pcie_get_max_msdu_cnt(pmadapter) < 2))
(wlan_pcie_get_max_msdu_cnt(pmadapter) < 2)) {
pmadapter->data_sent = MTRUE;
else
wlan_pcie_process_tx_complete(pmadapter);
} else
#endif
pmadapter->data_sent = MFALSE;
} else
@ -2626,9 +2644,10 @@ static mlan_status wlan_pcie_send_data(mlan_adapter *pmadapter, t_u8 type,
if (wlan_check_txbd_not_full(pmadapter)) {
#ifdef PCIEAW693
if (IS_PCIEAW693(pmadapter->card_type) &&
(wlan_pcie_get_max_msdu_cnt(pmadapter) < 2))
(wlan_pcie_get_max_msdu_cnt(pmadapter) < 2)) {
pmadapter->data_sent = MTRUE;
else
wlan_pcie_process_tx_complete(pmadapter);
} else
#endif
pmadapter->data_sent = MFALSE;
} else
@ -2803,7 +2822,8 @@ static mlan_status wlan_pcie_process_recv_data(mlan_adapter *pmadapter)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_callbacks pcb = &pmadapter->callbacks;
t_u32 rdptr, rd_index;
t_u32 rdptr = 0;
t_u32 rd_index;
mlan_buffer *pmbuf = MNULL;
t_u32 txbd_val = 0;
t_u16 rx_len = 0, rx_type;
@ -2819,7 +2839,8 @@ static mlan_status wlan_pcie_process_recv_data(mlan_adapter *pmadapter)
defined(PCIEIW624)
adma_dual_desc_buf *padma_bd_buf;
#endif
t_u32 in_ts_sec, in_ts_usec;
t_u32 in_ts_sec = 0;
t_u32 in_ts_usec = 0;
ENTER();
@ -3187,10 +3208,21 @@ static mlan_status wlan_pcie_send_cmd(mlan_adapter *pmadapter,
wlan_init_adma(pmadapter, ADMA_CMDRESP,
pmadapter->pcard_pcie->cmdrsp_buf->buf_pa,
MRVDRV_SIZE_OF_CMD_BUFFER, MFALSE);
wlan_init_adma(pmadapter, ADMA_CMD,
pmadapter->pcard_pcie->cmd_buf->buf_pa,
pmadapter->pcard_pcie->cmd_buf->data_len,
MFALSE);
if (IS_PCIEIW624(pmadapter->card_type) ||
(IS_PCIEAW693(pmadapter->card_type) &&
(pmadapter->card_rev > CHIP_AW693_REV_A0))) {
if (wlan_pcie_send_boot_cmd(pmadapter, pmbuf, MFALSE)) {
PRINTM(MERROR,
"Failed to send vdll block to device\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
} else {
wlan_init_adma(pmadapter, ADMA_CMD,
pmadapter->pcard_pcie->cmd_buf->buf_pa,
pmadapter->pcard_pcie->cmd_buf->data_len,
MFALSE);
}
}
#endif
done:
@ -3441,7 +3473,8 @@ static mlan_status wlan_pcie_process_event_ready(mlan_adapter *pmadapter)
{
t_u32 rd_index =
pmadapter->pcard_pcie->evtbd_rdptr & (MLAN_MAX_EVT_BD - 1);
t_u32 rdptr, event;
t_u32 rdptr = 0;
t_u32 event;
pmlan_callbacks pcb = &pmadapter->callbacks;
#if defined(PCIE8997) || defined(PCIE8897)
mlan_pcie_evt_buf *pevtbd_buf;
@ -3639,7 +3672,7 @@ static mlan_status wlan_pcie_event_complete(mlan_adapter *pmadapter,
pmlan_callbacks pcb = &pmadapter->callbacks;
t_u32 wrptr =
pmadapter->pcard_pcie->evtbd_wrptr & (MLAN_MAX_EVT_BD - 1);
t_u32 rdptr;
t_u32 rdptr = 0;
#if defined(PCIE8997) || defined(PCIE8897)
mlan_pcie_evt_buf *pevtbd_buf;
#endif
@ -4171,7 +4204,7 @@ mlan_status wlan_pcie_wakeup(mlan_adapter *pmadapter)
*/
static mlan_status wlan_pcie_interrupt(t_u16 msg_id, pmlan_adapter pmadapter)
{
t_u32 pcie_ireg;
t_u32 pcie_ireg = 0;
pmlan_callbacks pcb = &pmadapter->callbacks;
t_void *pmoal_handle = pmadapter->pmoal_handle;
t_void *pint_lock = pmadapter->pint_lock;
@ -4487,7 +4520,7 @@ static mlan_status wlan_pcie_check_fw_status(mlan_adapter *pmadapter,
{
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_callbacks pcb = &pmadapter->callbacks;
t_u32 firmware_stat;
t_u32 firmware_stat = 0;
t_u32 tries;
ENTER();
@ -4663,7 +4696,7 @@ mlan_status wlan_alloc_ssu_pcie_buf(pmlan_adapter pmadapter)
pmlan_callbacks pcb = &pmadapter->callbacks;
mlan_buffer *pmbuf = MNULL;
/** Virtual base address of ssu buffer */
t_u8 *ssu_vbase;
t_u8 *ssu_vbase = MNULL;
/** Physical base address of ssu buffer */
t_u64 ssu_pbase = 0;
@ -4874,6 +4907,12 @@ mlan_status wlan_set_pcie_buf_config(mlan_private *pmpriv)
pmlan_adapter pmadapter = MNULL;
#if defined(PCIE8997) || defined(PCIE8897)
HostCmd_DS_PCIE_HOST_BUF_DETAILS host_spec;
#endif
#if defined(PCIE)
#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIEAW693) || \
defined(PCIEIW624)
HostCmd_DS_PCIE_ADMA_INIT pcie_adma_cfg;
#endif
#endif
mlan_status ret = MLAN_STATUS_SUCCESS;
@ -4925,6 +4964,26 @@ mlan_status wlan_set_pcie_buf_config(mlan_private *pmpriv)
#if defined(PCIE9098) || defined(PCIE9097) || defined(PCIEAW693) || \
defined(PCIEIW624)
if (pmadapter->pcard_pcie->reg->use_adma) {
if (IS_PCIEIW624(pmadapter->card_type) ||
(IS_PCIEAW693(pmadapter->card_type) &&
(pmadapter->card_rev > CHIP_AW693_REV_A0))) {
pcie_adma_cfg.tx_ring_size =
pmadapter->pcard_pcie->txrx_bd_size;
pcie_adma_cfg.rx_ring_size =
pmadapter->pcard_pcie->txrx_bd_size;
pcie_adma_cfg.evt_ring_size = MLAN_MAX_EVT_BD;
pcie_adma_cfg.int_mode =
pmadapter->pcard_pcie->pcie_int_mode;
ret = wlan_prepare_cmd(pmpriv,
HostCmd_CMD_PCIE_ADMA_INIT,
HostCmd_ACT_GEN_SET, 0, MNULL,
&pcie_adma_cfg);
if (ret) {
PRINTM(MERROR,
"PCIE_ADMA_INIT: send command failed\n");
ret = MLAN_STATUS_FAILURE;
}
}
/** config ADMA for Tx Data */
wlan_init_adma(pmadapter, ADMA_TX_DATA,
pmadapter->pcard_pcie->txbd_ring_pbase,
@ -4985,6 +5044,40 @@ mlan_status wlan_cmd_pcie_host_buf_cfg(pmlan_private pmpriv,
}
#endif
#if defined(PCIE)
/**
* @brief This function prepares command PCIE ADMA init.
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param cmd_action The action: GET or SET
* @param pdata_buf A pointer to data buffer
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_cmd_pcie_adma_init(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
t_pvoid pdata_buf)
{
HostCmd_DS_PCIE_ADMA_INIT *ppcie_adma_cfg =
&cmd->params.pcie_adma_config;
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_PCIE_ADMA_INIT);
cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_PCIE_ADMA_INIT)) +
S_DS_GEN);
if (cmd_action == HostCmd_ACT_GEN_SET) {
memcpy_ext(pmpriv->adapter, ppcie_adma_cfg, pdata_buf,
sizeof(HostCmd_DS_PCIE_ADMA_INIT),
sizeof(HostCmd_DS_PCIE_ADMA_INIT));
}
LEAVE();
return MLAN_STATUS_SUCCESS;
}
#endif
/**
* @brief This function wakes up the card.
*
@ -5228,7 +5321,9 @@ static mlan_status wlan_pcie_send_data_list(mlan_adapter *pmadapter, t_u8 type,
return MLAN_STATUS_FAILURE;
}
#endif
if (wlan_is_tx_pending(pmadapter))
if ((((pmadapter->pcard_pcie->txbd_wrptr >> 1) %
TX_DONE_POLL_DISTANCE) == 0) &&
wlan_is_tx_pending(pmadapter))
wlan_pcie_process_tx_complete(pmadapter);
if (num_pkt == 1) {

View file

@ -466,6 +466,9 @@ Change log:
/** Max interrupt status register read limit */
#define MAX_READ_REG_RETRY 10000
/* check TX done ring on every X pushed packets */
#define TX_DONE_POLL_DISTANCE 16
extern mlan_adapter_operations mlan_pcie_ops;
/* Get pcie device from card type */
@ -481,6 +484,13 @@ mlan_status wlan_cmd_pcie_host_buf_cfg(pmlan_private pmpriv,
t_u16 cmd_action, t_pvoid pdata_buf);
#endif
#if defined(PCIE)
/** Prepare command PCIE host buffer config */
mlan_status wlan_cmd_pcie_adma_init(pmlan_private pmpriv,
pHostCmd_DS_COMMAND cmd, t_u16 cmd_action,
t_pvoid pdata_buf);
#endif
/** Wakeup PCIE card */
mlan_status wlan_pcie_wakeup(pmlan_adapter pmadapter);

File diff suppressed because it is too large Load diff

View file

@ -226,7 +226,7 @@ static const struct _mlan_card_info mlan_card_info_sd8897 = {
#if defined(SD8977) || defined(SD8997) || defined(SD8987) || \
defined(SD9098) || defined(SD9097) || defined(SDIW624) || \
defined(SDAW693) || defined(SD8978) || defined(SD9177) || \
defined(SDIW615)
defined(SDIW610)
static const struct _mlan_sdio_card_reg mlan_reg_sd8977_sd8997 = {
.start_rd_port = 0,
.start_wr_port = 0,
@ -359,8 +359,8 @@ static const struct _mlan_card_info mlan_card_info_sd9177 = {
};
#endif
#ifdef SDIW615
static const struct _mlan_card_info mlan_card_info_sdiw615 = {
#ifdef SDIW610
static const struct _mlan_card_info mlan_card_info_sdiw610 = {
.max_tx_buf_size = MLAN_TX_DATA_BUF_SIZE_4K,
.v16_fw_api = 1,
.v17_fw_api = 1,
@ -1068,11 +1068,11 @@ static mlan_status wlan_sdio_prog_fw_w_helper(pmlan_adapter pmadapter, t_u8 *fw,
}
#endif
#if defined(SD9097) || defined(SD9177) || defined(SDIW624) || \
defined(SDAW693) || defined(SDIW615)
defined(SDAW693) || defined(SDIW610)
if (IS_SD9097(pmadapter->card_type) ||
IS_SDIW624(pmadapter->card_type) ||
IS_SDAW693(pmadapter->card_type) ||
IS_SDIW615(pmadapter->card_type) || IS_SD9177(pmadapter->card_type))
IS_SDIW610(pmadapter->card_type) || IS_SD9177(pmadapter->card_type))
check_fw_status = MTRUE;
#endif
@ -1280,6 +1280,7 @@ static mlan_status wlan_decode_rx_packet(mlan_adapter *pmadapter,
{
t_u8 *cmd_buf;
t_u32 event;
t_u32 offset = 0;
t_u32 in_ts_sec, in_ts_usec;
pmlan_callbacks pcb = &pmadapter->callbacks;
@ -1408,8 +1409,11 @@ static mlan_status wlan_decode_rx_packet(mlan_adapter *pmadapter,
case MLAN_TYPE_EVENT:
PRINTM(MINFO, "--- Rx: Event ---\n");
event = *(t_u32 *)&pmbuf->pbuf[pmbuf->data_offset +
SDIO_INTF_HEADER_LEN];
if (!wlan_secure_add(&pmbuf->data_offset, SDIO_INTF_HEADER_LEN,
&offset, TYPE_UINT32)) {
PRINTM(MERROR, "offset is invalid\n");
}
event = *(t_u32 *)&pmbuf->pbuf[offset];
pmadapter->event_cause = wlan_le32_to_cpu(event);
if ((pmadapter->upld_len > MLAN_EVENT_HEADER_LEN) &&
((pmadapter->upld_len - MLAN_EVENT_HEADER_LEN) <
@ -1937,6 +1941,7 @@ static mlan_status wlan_host_to_card_mp_aggr(mlan_adapter *pmadapter,
t_s32 f_send_cur_buf = 0;
t_s32 f_precopy_cur_buf = 0;
t_s32 f_postcopy_cur_buf = 0;
t_u32 temp = 0;
t_u8 aggr_sg = 0;
t_u8 mp_aggr_pkt_limit = pmadapter->pcard_sd->mp_aggr_pkt_limit;
t_bool new_mode = pmadapter->pcard_sd->supports_sdio_new_mode;
@ -2055,8 +2060,12 @@ tx_curr_single:
if (f_send_cur_buf) {
PRINTM(MINFO, "host_2_card_mp_aggr: writing to port #%d\n",
port);
ret = wlan_write_data_sync(pmadapter, mbuf,
pmadapter->pcard_sd->ioport + port);
if (!wlan_secure_add(&pmadapter->pcard_sd->ioport, port, &temp,
TYPE_UINT32)) {
PRINTM(MERROR, "temp is overflowed\n");
return MLAN_STATUS_FAILURE;
}
ret = wlan_write_data_sync(pmadapter, mbuf, temp);
if (!(pmadapter->pcard_sd->mp_wr_bitmap &
(1 << pmadapter->pcard_sd->curr_wr_port)))
pmadapter->pcard_sd->mpa_sent_no_ports++;
@ -2463,10 +2472,10 @@ mlan_status wlan_get_sdio_device(pmlan_adapter pmadapter)
pmadapter->pcard_info = &mlan_card_info_sdaw693;
break;
#endif
#ifdef SDIW615
case CARD_TYPE_SDIW615:
#ifdef SDIW610
case CARD_TYPE_SDIW610:
pmadapter->pcard_sd->reg = &mlan_reg_sd8977_sd8997;
pmadapter->pcard_info = &mlan_card_info_sdiw615;
pmadapter->pcard_info = &mlan_card_info_sdiw610;
break;
#endif
#ifdef SD9177
@ -3086,7 +3095,7 @@ exit:
#if defined(SD9098) || defined(SD9097) || defined(SDIW624) || \
defined(SDAW693) || defined(SD9177) || defined(SD8997) || \
defined(SD8987) || defined(SD8978) || defined(SDIW615)
defined(SD8987) || defined(SD8978) || defined(SDIW610)
/**
* @brief This function sends vdll data to the card.
*
@ -3149,7 +3158,7 @@ static mlan_status wlan_sdio_host_to_card_ext(pmlan_private pmpriv, t_u8 type,
#if defined(SD9098) || defined(SD9097) || defined(SDIW624) || \
defined(SDAW693) || defined(SD9177) || defined(SD8997) || \
defined(SD8987) || defined(SD8978) || defined(SDIW615)
defined(SD8987) || defined(SD8978) || defined(SDIW610)
if (type == MLAN_TYPE_VDLL)
return wlan_sdio_send_vdll(pmadapter, pmbuf);
#endif
@ -3479,8 +3488,12 @@ static mlan_status wlan_pm_sdio_wakeup_card(pmlan_adapter pmadapter,
pmadapter->wakeup_fw_timer_is_set = MTRUE;
}
ret = pcb->moal_write_reg(pmadapter->pmoal_handle,
HOST_TO_CARD_EVENT_REG, HOST_POWER_UP);
if (pmadapter->fw_wakeup_method == WAKEUP_FW_THRU_GPIO) {
/* GPIO_PORT_TO_LOW(); */
} else
ret = pcb->moal_write_reg(pmadapter->pmoal_handle,
HOST_TO_CARD_EVENT_REG,
HOST_POWER_UP);
LEAVE();
return ret;
@ -3500,8 +3513,11 @@ static mlan_status wlan_pm_sdio_reset_card(pmlan_adapter pmadapter)
ENTER();
ret = pcb->moal_write_reg(pmadapter->pmoal_handle,
HOST_TO_CARD_EVENT_REG, 0);
if (pmadapter->fw_wakeup_method == WAKEUP_FW_THRU_GPIO) {
/* GPIO_PORT_TO_HIGH(); */
} else
ret = pcb->moal_write_reg(pmadapter->pmoal_handle,
HOST_TO_CARD_EVENT_REG, 0);
LEAVE();
return ret;
@ -3633,7 +3649,7 @@ mlan_status wlan_reset_fw(pmlan_adapter pmadapter)
#if defined(SD8997) || defined(SD8977) || defined(SD8987) || \
defined(SD9098) || defined(SD9097) || defined(SDIW624) || \
defined(SDAW693) || defined(SD8978) || defined(SD9177) || \
defined(SDIW615)
defined(SDIW610)
if (MFALSE
#ifdef SD8997
|| IS_SD8997(pmadapter->card_type)
@ -3659,8 +3675,8 @@ mlan_status wlan_reset_fw(pmlan_adapter pmadapter)
#ifdef SDAW693
|| IS_SDAW693(pmadapter->card_type)
#endif
#ifdef SDIW615
|| IS_SDIW615(pmadapter->card_type)
#ifdef SDIW610
|| IS_SDIW610(pmadapter->card_type)
#endif
#ifdef SD9177
|| IS_SD9177(pmadapter->card_type)

View file

@ -317,6 +317,8 @@ mlan_status mlan_register(pmlan_device pmdevice, t_void **ppmlan_adapter)
MASSERT(pcb->moal_hist_data_add);
MASSERT(pcb->moal_updata_peer_signal);
MASSERT(pcb->moal_do_div);
MASSERT(pcb->moal_get_host_time_ns);
/* Save pmoal_handle */
pmadapter->pmoal_handle = pmdevice->pmoal_handle;
@ -326,10 +328,12 @@ mlan_status mlan_register(pmlan_device pmdevice, t_void **ppmlan_adapter)
pmadapter->card_rev = pmdevice->card_rev;
pmadapter->init_para.uap_max_sta = pmdevice->uap_max_sta;
pmadapter->init_para.wacp_mode = pmdevice->wacp_mode;
pmadapter->init_para.fw_data_cfg = pmdevice->fw_data_cfg;
pmadapter->init_para.mcs32 = pmdevice->mcs32;
pmadapter->init_para.antcfg = pmdevice->antcfg;
pmadapter->init_para.reject_addba_req = pmdevice->reject_addba_req;
pmadapter->init_para.dmcs = pmdevice->dmcs;
pmadapter->init_para.pref_dbc = pmdevice->pref_dbc;
#ifdef SDIO
if (IS_SD(pmadapter->card_type)) {
@ -346,10 +350,8 @@ mlan_status mlan_register(pmlan_device pmdevice, t_void **ppmlan_adapter)
}
if ((pmdevice->int_mode == INT_MODE_GPIO) &&
(pmdevice->gpio_pin == 0)) {
PRINTM(MERROR,
"SDIO_GPIO_INT_CONFIG: Invalid GPIO Pin\n");
ret = MLAN_STATUS_FAILURE;
goto error;
PRINTM(MINFO,
"SDIO_GPIO_INT_CONFIG: FW will duplicate SDIO Intr on GPIO-21\n");
}
pmadapter->init_para.int_mode = pmdevice->int_mode;
pmadapter->init_para.gpio_pin = pmdevice->gpio_pin;
@ -382,6 +384,10 @@ mlan_status mlan_register(pmlan_device pmdevice, t_void **ppmlan_adapter)
sizeof(mlan_adapter_operations),
sizeof(mlan_adapter_operations));
pmadapter->init_para.ring_size = pmdevice->ring_size;
pmadapter->init_para.max_tx_pending = pmdevice->max_tx_pending;
pmadapter->init_para.tx_budget = pmdevice->tx_budget;
pmadapter->init_para.mclient_scheduling =
pmdevice->mclient_scheduling;
ret = wlan_get_pcie_device(pmadapter);
if (MLAN_STATUS_SUCCESS != ret) {
ret = MLAN_STATUS_FAILURE;
@ -417,6 +423,7 @@ mlan_status mlan_register(pmlan_device pmdevice, t_void **ppmlan_adapter)
#endif
pmadapter->init_para.auto_ds = pmdevice->auto_ds;
pmadapter->init_para.ext_scan = pmdevice->ext_scan;
pmadapter->init_para.bootup_cal_ctrl = pmdevice->bootup_cal_ctrl;
pmadapter->init_para.ps_mode = pmdevice->ps_mode;
if (pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_2K ||
pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_4K ||
@ -1318,10 +1325,24 @@ process_start:
}
/* Check for event */
#ifdef USB
if (IS_USB(pmadapter->card_type))
wlan_request_event_lock(pmadapter);
#endif
if (pmadapter->event_received) {
pmadapter->event_received = MFALSE;
#ifdef USB
if (IS_USB(pmadapter->card_type))
wlan_release_event_lock(pmadapter);
#endif
wlan_process_event(pmadapter);
}
#ifdef USB
else {
if (IS_USB(pmadapter->card_type))
wlan_release_event_lock(pmadapter);
}
#endif
/* Check if we need to confirm Sleep Request received previously
*/
if (pmadapter->ps_state == PS_STATE_PRE_SLEEP)
@ -1447,35 +1468,42 @@ exit_main_proc:
static void mlan_check_llde_pkt_filter(mlan_adapter *pmadapter,
pmlan_buffer pmbuf, t_u8 ip_protocol)
{
mlan_private *pmpriv = pmadapter->priv[pmbuf->bss_index];
t_u8 matched_filter = 0;
t_u8 i = 0;
if (!(pmadapter->llde_enabled &&
(pmadapter->llde_mode == MLAN_11AXCMD_LLDE_MODE_EVENT_DRIVEN))) {
return;
}
/* match iphone mac addr */
if (pmadapter->llde_device_filter == 1) {
sta_node *sta_ptr = MNULL;
// get station entry from Peer MAC address
sta_ptr = wlan_get_station_entry(
pmpriv, (pmbuf->pbuf + pmbuf->data_offset));
if (sta_ptr && sta_ptr->is_apple_sta) {
matched_filter = 1;
if (pmadapter->llde_device_filter) {
for (i = 0; i < pmadapter->llde_totalIPhones; i++) {
if (memcmp(pmadapter,
&pmadapter->llde_iphonefilters
[i * MLAN_MAC_ADDR_LENGTH],
(pmbuf->pbuf + pmbuf->data_offset),
MLAN_MAC_ADDR_LENGTH) == 0) {
matched_filter = 1;
break;
}
}
}
if (matched_filter == 0) {
/* check mac filter if iphone device filter not matched */
if ((memcmp(pmadapter, pmadapter->llde_macfilter1,
(pmbuf->pbuf + pmbuf->data_offset),
MLAN_MAC_ADDR_LENGTH) == 0) ||
(memcmp(pmadapter, pmadapter->llde_macfilter2,
(pmbuf->pbuf + pmbuf->data_offset),
MLAN_MAC_ADDR_LENGTH) == 0)) {
matched_filter = 1;
for (i = 0; i < pmadapter->llde_totalMacFilters; i++) {
if (memcmp(pmadapter,
&pmadapter->llde_macfilters
[i * MLAN_MAC_ADDR_LENGTH],
(pmbuf->pbuf + pmbuf->data_offset),
MLAN_MAC_ADDR_LENGTH) == 0) {
matched_filter = 1;
break;
}
}
}
/* device address is matched, check packet type to mark it as special
* llde packet */
if (matched_filter) {
if ((pmadapter->llde_packet_type == LLDE_FILTER_PKT_ALL) ||
((pmadapter->llde_packet_type == LLDE_FILTER_PKT_UDP) &&
@ -1811,11 +1839,13 @@ mlan_status mlan_recv(t_void *padapter, pmlan_buffer pmbuf, t_u32 port)
if ((len > 0) && (len < MAX_EVENT_SIZE))
memmove(pmadapter, pmadapter->event_body, pbuf,
len);
wlan_request_event_lock(pmadapter);
/* remove 4 byte recv_type */
pmbuf->data_offset += MLAN_TYPE_LEN;
pmbuf->data_len -= MLAN_TYPE_LEN;
pmadapter->event_received = MTRUE;
pmadapter->pmlan_buffer_event = pmbuf;
wlan_release_event_lock(pmadapter);
/* MOAL to call mlan_main_process for processing */
break;
default:

View file

@ -549,6 +549,44 @@ static mlan_status wlan_cmd_mfg_otp_rw(pmlan_private pmpriv,
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares command of MFG OTP CAL DATA RW.
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param action The action: GET or SET
* @param pdata_buf A pointer to data buffer
*
* @return MLAN_STATUS_SUCCESS
*/
static mlan_status wlan_cmd_mfg_otp_cal_data_rw(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd,
t_u16 action, t_void *pdata_buf)
{
mfg_cmd_otp_cal_data_rd_wr_t *mcmd =
(mfg_cmd_otp_cal_data_rd_wr_t *)&cmd->params
.mfg_otp_cal_data_rd_wr;
mfg_cmd_otp_cal_data_rd_wr_t *cfg =
(mfg_cmd_otp_cal_data_rd_wr_t *)pdata_buf;
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MFG_COMMAND);
cmd->size = wlan_cpu_to_le16(sizeof(mfg_cmd_otp_cal_data_rd_wr_t) +
S_DS_GEN);
mcmd->mfg_cmd = wlan_cpu_to_le32(cfg->mfg_cmd);
mcmd->action = wlan_cpu_to_le16(cfg->action);
mcmd->cal_data_status = wlan_cpu_to_le32(cfg->cal_data_status);
mcmd->cal_data_len = wlan_cpu_to_le32(cfg->cal_data_len);
if (action == HostCmd_ACT_GEN_SET) {
memcpy_ext(pmpriv->adapter, mcmd->cal_data, cfg->cal_data,
mcmd->cal_data_len, mcmd->cal_data_len);
}
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares command of MFG cmd.
*
@ -591,6 +629,10 @@ mlan_status wlan_cmd_mfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
case MFG_CMD_OTP_MAC_ADD:
ret = wlan_cmd_mfg_otp_rw(pmpriv, cmd, action, pdata_buf);
goto cmd_mfg_done;
case MFG_CMD_OTP_CAL_DATA:
ret = wlan_cmd_mfg_otp_cal_data_rw(pmpriv, cmd, action,
pdata_buf);
goto cmd_mfg_done;
case MFG_CMD_SET_TEST_MODE:
case MFG_CMD_UNSET_TEST_MODE:
case MFG_CMD_TX_ANT:
@ -3610,6 +3652,51 @@ static mlan_status wlan_is_cmd_allowed(mlan_private *priv, t_u16 cmd_no)
return ret;
}
/**
* @brief This function prepares command to configure Auth, (Re)assoc Timeout
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param cmd_action Action: GET or SET
* @param pdata_buf A pointer to data buffer
*
* @return MLAN_STATUS_SUCCESS
*/
static mlan_status wlan_cmd_auth_assoc_timeout_cfg(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd,
t_u16 cmd_action,
t_void *pdata_buf)
{
HostCmd_DS_AUTH_ASSOC_TIMEOUT_CFG *auth_assoc_cmd =
&cmd->params.auth_assoc_cfg;
mlan_ds_auth_assoc_timeout_cfg *auth_assoc_cfg =
(mlan_ds_auth_assoc_timeout_cfg *)pdata_buf;
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_AUTH_ASSOC_TIMEOUT_CFG);
cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_AUTH_ASSOC_TIMEOUT_CFG) +
S_DS_GEN);
auth_assoc_cmd->action = wlan_cpu_to_le16(cmd_action);
auth_assoc_cmd->auth_timeout =
wlan_cpu_to_le16(auth_assoc_cfg->auth_timeout);
auth_assoc_cmd->auth_retry_timeout_if_ack =
wlan_cpu_to_le16(auth_assoc_cfg->auth_retry_timeout_if_ack);
auth_assoc_cmd->auth_retry_timeout_if_no_ack =
wlan_cpu_to_le16(auth_assoc_cfg->auth_retry_timeout_if_no_ack);
auth_assoc_cmd->assoc_timeout =
wlan_cpu_to_le16(auth_assoc_cfg->assoc_timeout);
auth_assoc_cmd->reassoc_timeout =
wlan_cpu_to_le16(auth_assoc_cfg->reassoc_timeout);
auth_assoc_cmd->retry_timeout =
wlan_cpu_to_le16(auth_assoc_cfg->retry_timeout);
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepare the command before sending to firmware.
*
@ -3687,6 +3774,10 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no,
ret = wlan_cmd_802_11_hs_cfg(pmpriv, cmd_ptr, cmd_action,
(hs_config_param *)pdata_buf);
break;
case HostCmd_CMD_802_11_FW_WAKE_METHOD:
ret = wlan_cmd_802_11_fw_wakeup_method(pmpriv, cmd_ptr,
cmd_action, pdata_buf);
break;
case HostCmd_CMD_802_11_ROBUSTCOEX:
ret = wlan_cmd_robustcoex(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
@ -3803,8 +3894,7 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no,
if (pmpriv->adapter->hw_status == WlanHardwareStatusReset)
pmpriv->adapter->hw_status =
WlanHardwareStatusInitializing;
cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
cmd_ptr->size = wlan_cpu_to_le16(S_DS_GEN);
ret = wlan_cmd_func_init(pmpriv, cmd_ptr);
break;
case HostCmd_CMD_FUNC_SHUTDOWN:
pmpriv->adapter->hw_status = WlanHardwareStatusReset;
@ -3989,6 +4079,12 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no,
pdata_buf);
break;
#endif
#endif
#if defined(PCIE)
case HostCmd_CMD_PCIE_ADMA_INIT:
ret = wlan_cmd_pcie_adma_init(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
break;
#endif
case HostCmd_CMD_802_11_REMAIN_ON_CHANNEL:
ret = wlan_cmd_remain_on_channel(pmpriv, cmd_ptr, cmd_action,
@ -4080,10 +4176,8 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no,
cmd_action, pdata_buf);
break;
case HostCmd_CMD_CHAN_REGION_CFG:
cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
cmd_ptr->size = wlan_cpu_to_le16(
sizeof(HostCmd_DS_CHAN_REGION_CFG) + S_DS_GEN);
cmd_ptr->params.reg_cfg.action = wlan_cpu_to_le16(cmd_action);
ret = wlan_cmd_chan_region_cfg(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
break;
case HostCmd_CMD_REGION_POWER_CFG:
cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
@ -4192,6 +4286,10 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no,
ret = wlan_cmd_cross_chip_synch(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
break;
case HostCmd_CMD_TSP_CFG:
ret = wlan_cmd_tsp_config(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
break;
case HostCmd_CMD_802_11_TX_FRAME:
ret = wlan_cmd_tx_frame(pmpriv, cmd_ptr, cmd_action, pdata_buf);
break;
@ -4199,6 +4297,18 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no,
ret = wlan_cmd_edmac_cfg(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
break;
case HostCmd_CMD_PEER_TX_RATE_QUERY:
ret = wlan_cmd_sta_tx_rate_req(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
break;
case HostCmd_CMD_MCLIENT_SCHEDULE_CFG:
ret = wlan_cmd_mclient_scheduling_cfg(pmpriv, cmd_ptr,
cmd_action, pdata_buf);
break;
case HostCmd_CMD_AUTH_ASSOC_TIMEOUT_CFG:
ret = wlan_cmd_auth_assoc_timeout_cfg(pmpriv, cmd_ptr,
cmd_action, pdata_buf);
break;
default:
PRINTM(MERROR, "PREP_CMD: unknown command- %#x\n", cmd_no);
ret = MLAN_STATUS_FAILURE;

View file

@ -754,6 +754,8 @@ static mlan_status wlan_ret_get_log(pmlan_private pmpriv,
wlan_le32_to_cpu(pget_log->gdma_abort_cnt);
pget_info->param.stats.g_reset_rx_mac_cnt =
wlan_le32_to_cpu(pget_log->g_reset_rx_mac_cnt);
pget_info->param.stats.SdmaStuckCnt =
wlan_le32_to_cpu(pget_log->SdmaStuckCnt);
// Ownership error counters
pget_info->param.stats.dwCtlErrCnt =
wlan_le32_to_cpu(pget_log->dwCtlErrCnt);
@ -1825,7 +1827,7 @@ static mlan_status wlan_ret_tdls_config(pmlan_private pmpriv,
wlan_le16_to_cpu(link_ptr->data_rssi_avg);
link_ptr->data_nf_avg =
wlan_le16_to_cpu(link_ptr->data_nf_avg);
link_length = sizeof(tdls_each_link_status) - 1;
link_length = sizeof(tdls_each_link_status);
/* adjust as per open or secure network */
if (link_ptr->link_flags & 0x02) {
link_ptr->key_lifetime = wlan_le32_to_cpu(
@ -3036,6 +3038,40 @@ static mlan_status wlan_ret_mfg_otp_rw(pmlan_private pmpriv,
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares command resp of MFG CMD OTP CAL DATA RW
*
* @param pmpriv A pointer to mlan_private structure
* @param resp A pointer to HostCmd_DS_COMMAND
* @param pioctl_buf A pointer to mlan_ioctl_req structure
*
* @return MLAN_STATUS_SUCCESS
*/
static mlan_status wlan_ret_mfg_otp_cal_data_rw(pmlan_private pmpriv,
HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf)
{
mlan_ds_misc_cfg *misc = MNULL;
mfg_cmd_otp_cal_data_rd_wr_t *cfg = MNULL;
mfg_cmd_otp_cal_data_rd_wr_t *mcmd =
(mfg_cmd_otp_cal_data_rd_wr_t *)&resp->params
.mfg_otp_cal_data_rd_wr;
ENTER();
if (!pioctl_buf) {
LEAVE();
return MLAN_STATUS_FAILURE;
}
misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
cfg = (mfg_cmd_otp_cal_data_rd_wr_t *)&misc->param
.mfg_otp_cal_data_rd_wr;
memcpy_ext(pmpriv->adapter, &(cfg->cal_data[0]), &(mcmd->cal_data[0]),
cfg->cal_data_len, cfg->cal_data_len);
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares command resp of MFG Cmd
*
@ -3078,6 +3114,9 @@ mlan_status wlan_ret_mfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
case MFG_CMD_OTP_MAC_ADD:
ret = wlan_ret_mfg_otp_rw(pmpriv, resp, pioctl_buf);
goto cmd_mfg_done;
case MFG_CMD_OTP_CAL_DATA:
ret = wlan_ret_mfg_otp_cal_data_rw(pmpriv, resp, pioctl_buf);
goto cmd_mfg_done;
case MFG_CMD_SET_TEST_MODE:
case MFG_CMD_UNSET_TEST_MODE:
case MFG_CMD_TX_ANT:
@ -3100,7 +3139,8 @@ mlan_status wlan_ret_mfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
card_type = card_type & 0xff;
if (((card_type == CARD_TYPE_9098) || (card_type == CARD_TYPE_9097) ||
(card_type == CARD_TYPE_9177) || (card_type == CARD_TYPE_IW624) ||
(card_type == CARD_TYPE_AW693)) &&
(card_type == CARD_TYPE_AW693) ||
(card_type == CARD_TYPE_IW610)) &&
(wlan_le32_to_cpu(mcmd->mfg_cmd) == MFG_CMD_RFPWR)) {
//! TX_POWER was multipied by 16 while passing to fw
//! So It is needed to divide by 16 for user vals understanding.
@ -3112,6 +3152,9 @@ mlan_status wlan_ret_mfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
cfg->data2 = wlan_le32_to_cpu(mcmd->data2);
cfg->data3 = wlan_le32_to_cpu(mcmd->data3);
cmd_mfg_done:
if (mcmd->error)
PRINTM(MERROR, "RFTM_COMMAND ERROR: 0x%08x\n",
wlan_le32_to_cpu(mcmd->error));
LEAVE();
return ret;
}
@ -3149,6 +3192,47 @@ mlan_status wlan_ret_twt_report(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function handles the command response of auth assoc timeout cfg
*
* @param pmpriv A pointer to mlan_private structure
* @param resp A pointer to HostCmd_DS_COMMAND
* @param pioctl_buf A pointer to mlan_ioctl_req structure
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_ret_auth_assoc_timeout_cfg(pmlan_private pmpriv,
HostCmd_DS_COMMAND *resp,
mlan_ioctl_req *pioctl_buf)
{
HostCmd_DS_AUTH_ASSOC_TIMEOUT_CFG *auth_assoc_cmd =
(HostCmd_DS_AUTH_ASSOC_TIMEOUT_CFG *)&resp->params
.auth_assoc_cfg;
mlan_ds_misc_cfg *misc_cfg = MNULL;
ENTER();
if (pioctl_buf) {
misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
misc_cfg->param.auth_assoc_cfg.auth_timeout =
wlan_le16_to_cpu(auth_assoc_cmd->auth_timeout);
misc_cfg->param.auth_assoc_cfg.auth_retry_timeout_if_ack =
wlan_le16_to_cpu(
auth_assoc_cmd->auth_retry_timeout_if_ack);
misc_cfg->param.auth_assoc_cfg.auth_retry_timeout_if_no_ack =
wlan_le16_to_cpu(
auth_assoc_cmd->auth_retry_timeout_if_no_ack);
misc_cfg->param.auth_assoc_cfg.assoc_timeout =
wlan_le16_to_cpu(auth_assoc_cmd->assoc_timeout);
misc_cfg->param.auth_assoc_cfg.reassoc_timeout =
wlan_le16_to_cpu(auth_assoc_cmd->reassoc_timeout);
misc_cfg->param.auth_assoc_cfg.retry_timeout =
wlan_le16_to_cpu(auth_assoc_cmd->retry_timeout);
}
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function handles the station command response
*
@ -3243,6 +3327,9 @@ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no,
case HostCmd_CMD_802_11_SLEEP_PARAMS:
ret = wlan_ret_802_11_sleep_params(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_802_11_FW_WAKE_METHOD:
ret = wlan_ret_fw_wakeup_method(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_802_11_ROBUSTCOEX:
break;
case HostCmd_CMD_DMCS_CONFIG:
@ -3487,6 +3574,12 @@ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no,
PRINTM(MINFO, "PCIE host buffer configuration successful.\n");
break;
#endif
#endif
#if defined(PCIE)
case HostCmd_CMD_PCIE_ADMA_INIT:
PRINTM(MINFO, "PCIE ADMA init successful.\n");
wlan_pcie_init_fw(pmpriv->adapter);
break;
#endif
case HostCmd_CMD_802_11_REMAIN_ON_CHANNEL:
ret = wlan_ret_remain_on_channel(pmpriv, resp, pioctl_buf);
@ -3651,10 +3744,21 @@ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no,
case HostCmd_CMD_CROSS_CHIP_SYNCH:
ret = wlan_ret_cross_chip_synch(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_TSP_CFG:
ret = wlan_ret_tsp_config(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_802_11_TX_FRAME:
break;
case HostCmd_CMD_EDMAC_CFG:
break;
case HostCmd_CMD_PEER_TX_RATE_QUERY:
ret = wlan_ret_sta_tx_rate(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_MCLIENT_SCHEDULE_CFG:
break;
case HostCmd_CMD_AUTH_ASSOC_TIMEOUT_CFG:
ret = wlan_ret_auth_assoc_timeout_cfg(pmpriv, resp, pioctl_buf);
break;
default:
PRINTM(MERROR, "CMD_RESP: Unknown command response %#x\n",
resp->command);

View file

@ -611,15 +611,9 @@ static void wlan_process_sta_tx_pause_event(pmlan_private priv,
}
if (tlv_type == TLV_TYPE_TX_PAUSE) {
tx_pause_tlv = (MrvlIEtypes_tx_pause_t *)tlv;
PRINTM(MCMND,
"TxPause: " MACSTR
" pause=%d, pkts=%d, priv->tx_pause=%d\n",
PRINTM(MCMND, "TxPause: " MACSTR " pause=%d, pkts=%d\n",
MAC2STR(tx_pause_tlv->peermac),
tx_pause_tlv->tx_pause, tx_pause_tlv->pkt_cnt,
priv->tx_pause);
if (bssid)
PRINTM(MCMND, "TxPause: " MACSTR "\n",
MAC2STR(bssid));
tx_pause_tlv->tx_pause, tx_pause_tlv->pkt_cnt);
status = wlan_get_tdls_link_status(
priv, tx_pause_tlv->peermac);
if (status != TDLS_NOT_SETUP) {
@ -971,6 +965,13 @@ mlan_status wlan_ops_sta_process_event(t_void *priv)
wlan_recv_event(pmpriv, pevent->event_id, pevent);
break;
case EVENT_CHAN_SWITCH_TO_6G_BLOCK:
reason_code = wlan_le16_to_cpu(*(t_u16 *)(pmbuf->pbuf +
pmbuf->data_offset +
sizeof(eventcause)));
print_chan_switch_block_event(reason_code);
break;
case EVENT_BG_SCAN_REPORT:
PRINTM(MEVENT, "EVENT: BGS_REPORT\n");
pmadapter->bgscan_reported = MTRUE;

View file

@ -692,47 +692,39 @@ static mlan_status wlan_bss_ioctl_set_multicast_list(pmlan_adapter pmadapter,
}
pioctl_req->data_read_written =
sizeof(mlan_multicast_list) + MLAN_SUB_COMMAND_SIZE;
if (bss->param.multicast_list.mode == MLAN_PROMISC_MODE) {
PRINTM(MINFO, "Enable Promiscuous mode\n");
pmpriv->curr_pkt_filter |= HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
/* Multicast */
pmpriv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
if (bss->param.multicast_list.mode == MLAN_ALL_MULTI_MODE) {
PRINTM(MINFO, "Enabling All Multicast!\n");
pmpriv->curr_pkt_filter |= HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
} else {
pmpriv->curr_pkt_filter &=
~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
} else {
/* Multicast */
pmpriv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
if (bss->param.multicast_list.mode == MLAN_ALL_MULTI_MODE) {
PRINTM(MINFO, "Enabling All Multicast!\n");
if (bss->param.multicast_list.mode == MLAN_PROMISC_MODE)
pmpriv->curr_pkt_filter |=
HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
} else {
pmpriv->curr_pkt_filter &=
~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
if (bss->param.multicast_list.num_multicast_addr) {
PRINTM(MINFO, "Set multicast list=%d\n",
bss->param.multicast_list
.num_multicast_addr);
/* Set multicast addresses to firmware */
if (old_pkt_filter == pmpriv->curr_pkt_filter) {
/* Send request to firmware */
ret = wlan_prepare_cmd(
pmpriv,
HostCmd_CMD_MAC_MULTICAST_ADR,
HostCmd_ACT_GEN_SET, 0,
(t_void *)pioctl_req,
&bss->param.multicast_list);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
} else {
/* Send request to firmware */
ret = wlan_prepare_cmd(
pmpriv,
HostCmd_CMD_MAC_MULTICAST_ADR,
HostCmd_ACT_GEN_SET, 0, MNULL,
&bss->param.multicast_list);
}
if (ret)
goto exit;
HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
if (bss->param.multicast_list.num_multicast_addr) {
PRINTM(MINFO, "Set multicast list=%d\n",
bss->param.multicast_list.num_multicast_addr);
/* Set multicast addresses to firmware */
if (old_pkt_filter == pmpriv->curr_pkt_filter) {
/* Send request to firmware */
ret = wlan_prepare_cmd(
pmpriv, HostCmd_CMD_MAC_MULTICAST_ADR,
HostCmd_ACT_GEN_SET, 0,
(t_void *)pioctl_req,
&bss->param.multicast_list);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
} else {
/* Send request to firmware */
ret = wlan_prepare_cmd(
pmpriv, HostCmd_CMD_MAC_MULTICAST_ADR,
HostCmd_ACT_GEN_SET, 0, MNULL,
&bss->param.multicast_list);
}
if (ret)
goto exit;
}
}
PRINTM(MINFO, "old_pkt_filter=0x%x, curr_pkt_filter=0x%x\n",
@ -1601,6 +1593,10 @@ static mlan_status wlan_power_ioctl_set_power(pmlan_adapter pmadapter,
*)(buf + sizeof(HostCmd_DS_TXPWR_CFG));
pg_tlv->type = TLV_TYPE_POWER_GROUP;
pg_tlv->length = 4 * sizeof(Power_Group_t);
/*Power Groups for VHTBW20, VHTBW40, VHTBW80 */
pg_tlv->length += 3 * sizeof(Power_Group_t);
/*Power Groups for HEBW20, HEBW40, HEBW80 */
pg_tlv->length += 3 * sizeof(Power_Group_t);
pg = (Power_Group_t *)(buf + sizeof(HostCmd_DS_TXPWR_CFG) +
sizeof(MrvlTypes_Power_Group_t));
/* Power group for modulation class HR/DSSS */
@ -1626,7 +1622,7 @@ static mlan_status wlan_power_ioctl_set_power(pmlan_adapter pmadapter,
pg->power_step = 0;
pg->power_min = (t_s8)dbm;
pg->power_max = (t_s8)dbm;
pg->ht_bandwidth = HT_BW_20;
pg->ht_bandwidth = BW_20;
pg++;
/* Power group for modulation class HTBW40 */
pg->first_rate_code = 0x00;
@ -1635,7 +1631,61 @@ static mlan_status wlan_power_ioctl_set_power(pmlan_adapter pmadapter,
pg->power_step = 0;
pg->power_min = (t_s8)dbm;
pg->power_max = (t_s8)dbm;
pg->ht_bandwidth = HT_BW_40;
pg->ht_bandwidth = BW_40;
pg++;
/* Power group for modulation class VHTBW20 */
pg->first_rate_code = 0x00;
pg->last_rate_code = 0x19;
pg->modulation_class = MOD_CLASS_VHT;
pg->power_step = 0;
pg->power_min = (t_s8)dbm;
pg->power_max = (t_s8)dbm;
pg->ht_bandwidth = BW_20;
pg++;
/* Power group for modulation class VHTBW40 */
pg->first_rate_code = 0x00;
pg->last_rate_code = 0x19;
pg->modulation_class = MOD_CLASS_VHT;
pg->power_step = 0;
pg->power_min = (t_s8)dbm;
pg->power_max = (t_s8)dbm;
pg->ht_bandwidth = BW_40;
pg++;
/* Power group for modulation class VHTBW80 */
pg->first_rate_code = 0x00;
pg->last_rate_code = 0x19;
pg->modulation_class = MOD_CLASS_VHT;
pg->power_step = 0;
pg->power_min = (t_s8)dbm;
pg->power_max = (t_s8)dbm;
pg->ht_bandwidth = BW_80;
pg++;
/* Power group for modulation class HEBW20 */
pg->first_rate_code = 0x00;
pg->last_rate_code = 0x1B;
pg->modulation_class = MOD_CLASS_HE;
pg->power_step = 0;
pg->power_min = (t_s8)dbm;
pg->power_max = (t_s8)dbm;
pg->ht_bandwidth = BW_20;
pg++;
/* Power group for modulation class HEBW40 */
pg->first_rate_code = 0x00;
pg->last_rate_code = 0x1B;
pg->modulation_class = MOD_CLASS_HE;
pg->power_step = 0;
pg->power_min = (t_s8)dbm;
pg->power_max = (t_s8)dbm;
pg->ht_bandwidth = BW_40;
pg++;
/* Power group for modulation class HEBW80 */
pg->first_rate_code = 0x00;
pg->last_rate_code = 0x1B;
pg->modulation_class = MOD_CLASS_HE;
pg->power_step = 0;
pg->power_min = (t_s8)dbm;
pg->power_max = (t_s8)dbm;
pg->ht_bandwidth = BW_80;
}
/* Send request to firmware */
@ -2247,6 +2297,9 @@ static mlan_status wlan_pm_ioctl(pmlan_adapter pmadapter,
case MLAN_OID_PM_CFG_SLEEP_PD:
status = wlan_set_get_sleep_pd(pmadapter, pioctl_req);
break;
case MLAN_OID_PM_CFG_FW_WAKEUP_METHOD:
status = wlan_fw_wakeup_method(pmadapter, pioctl_req);
break;
case MLAN_OID_PM_CFG_SLEEP_PARAMS:
status = wlan_set_get_sleep_params(pmadapter, pioctl_req);
break;
@ -2842,8 +2895,8 @@ static mlan_status wlan_sec_ioctl_set_wpa_key(pmlan_adapter pmadapter,
}
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_KEY_MATERIAL,
pioctl_req->action, 0, (t_void *)pioctl_req,
&sec->param.encrypt_key);
(t_u16)pioctl_req->action, 0,
(t_void *)pioctl_req, &sec->param.encrypt_key);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
@ -4846,6 +4899,38 @@ static mlan_status wlan_misc_cloud_keep_alive_rx(pmlan_adapter pmadapter,
return ret;
}
/**
* @brief configure auth,assoc timeout parameter
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
* @return MLAN_STATUS_PENDING --success, otherwise fail
*/
static mlan_status wlan_misc_auth_assoc_timeout_cfg(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req)
{
mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_ds_misc_cfg *pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
mlan_status ret = MLAN_STATUS_SUCCESS;
t_u16 cmd_action = 0;
ENTER();
if (pioctl_req->action == MLAN_ACT_SET)
cmd_action = HostCmd_ACT_GEN_SET;
else
cmd_action = HostCmd_ACT_GEN_GET;
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_AUTH_ASSOC_TIMEOUT_CFG,
cmd_action, 0, (t_void *)pioctl_req,
&(pmisc->param.auth_assoc_cfg));
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
LEAVE();
return ret;
}
/**
* @brief Miscellaneous configuration handler
*
@ -5065,6 +5150,9 @@ static mlan_status wlan_misc_cfg_ioctl(pmlan_adapter pmadapter,
status =
wlan_misc_ioctl_cross_chip_synch(pmadapter, pioctl_req);
break;
case MLAN_OID_MISC_TSP_CFG:
status = wlan_misc_ioctl_tsp_config(pmadapter, pioctl_req);
break;
case MLAN_OID_MISC_ROAM_OFFLOAD:
status = wlan_misc_roam_offload(pmadapter, pioctl_req);
break;
@ -5180,6 +5268,7 @@ static mlan_status wlan_misc_cfg_ioctl(pmlan_adapter pmadapter,
case MLAN_OID_MISC_RF_TEST_TX_FRAME:
case MLAN_OID_MISC_RF_TEST_HE_POWER:
case MLAN_OID_MISC_OTP_MAC_RD_WR:
case MLAN_OID_MISC_OTP_CAL_DATA_RD_WR:
status = wlan_misc_ioctl_rf_test_cfg(pmadapter, pioctl_req);
break;
case MLAN_OID_MISC_ARB_CONFIG:
@ -5207,6 +5296,10 @@ static mlan_status wlan_misc_cfg_ioctl(pmlan_adapter pmadapter,
case MLAN_OID_MISC_EDMAC_CONFIG:
status = wlan_misc_ioctl_edmac_cfg(pmadapter, pioctl_req);
break;
case MLAN_OID_MISC_AUTH_ASSOC_TIMEOUT_CONFIG:
status =
wlan_misc_auth_assoc_timeout_cfg(pmadapter, pioctl_req);
break;
default:
if (pioctl_req)
pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;

View file

@ -39,58 +39,6 @@ Change log:
Local Variables
********************************************************/
/** IPv4 ARP request header */
typedef MLAN_PACK_START struct {
/** Hardware type */
t_u16 Htype;
/** Protocol type */
t_u16 Ptype;
/** Hardware address length */
t_u8 addr_len;
/** Protocol address length */
t_u8 proto_len;
/** Operation code */
t_u16 op_code;
/** Source mac address */
t_u8 src_mac[MLAN_MAC_ADDR_LENGTH];
/** Sender IP address */
t_u8 src_ip[4];
/** Destination mac address */
t_u8 dst_mac[MLAN_MAC_ADDR_LENGTH];
/** Destination IP address */
t_u8 dst_ip[4];
} MLAN_PACK_END IPv4_ARP_t;
/** IPv6 Nadv packet header */
typedef MLAN_PACK_START struct {
/** IP protocol version */
t_u8 version;
/** flow label */
t_u8 flow_lab[3];
/** Payload length */
t_u16 payload_len;
/** Next header type */
t_u8 next_hdr;
/** Hot limit */
t_u8 hop_limit;
/** Source address */
t_u8 src_addr[16];
/** Destination address */
t_u8 dst_addr[16];
/** ICMP type */
t_u8 icmp_type;
/** IPv6 Code */
t_u8 ipv6_code;
/** IPv6 Checksum */
t_u16 ipv6_checksum;
/** Flags */
t_u32 flags;
/** Target address */
t_u8 taget_addr[16];
/** Reserved */
t_u8 rev[8];
} MLAN_PACK_END IPv6_Nadv_t;
/********************************************************
Global functions
********************************************************/
@ -122,8 +70,8 @@ static t_u8 discard_gratuitous_ARP_msg(RxPacketHdr_t *prx_pkt,
/* Graguitous ARP can be ARP request or ARP reply*/
if ((parp_hdr->op_code == mlan_htons(0x01)) ||
(parp_hdr->op_code == mlan_htons(0x02)))
if (memcmp(pmadapter, parp_hdr->src_ip,
parp_hdr->dst_ip, 4) == 0)
if (memcmp(pmadapter, parp_hdr->sender_ip,
parp_hdr->target_ip, 4) == 0)
ret = MTRUE;
}

View file

@ -3,7 +3,7 @@
* @brief This file contains TLV ID definitions.
*
*
* Copyright 2024 NXP
* Copyright 2023-2024 NXP
*
* This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991
@ -499,5 +499,8 @@
#define TLV_TYPE_PS_EXT_PARAM (PROPRIETARY_TLV_BASE_ID + 351) /* 0x025f */
#define TLV_TYPE_MCLIENT_FW_CAPS (PROPRIETARY_TLV_BASE_ID + 352) /* 0x0260 */
#define NXP_CSI_MONITOR_TLV_ID (PROPRIETARY_TLV_BASE_ID + 354) /* 0x0262 */
#define TLV_TYPE_BOOT_TIME_CFG (PROPRIETARY_TLV_BASE_ID + 355) /* 0x0263 */
#define VENDOR_IE_OUIS_TLV_ID (PROPRIETARY_TLV_BASE_ID + 357) /* 0x0265 */
#endif /* !MLAN_TLV_IDS_H_ */

View file

@ -681,6 +681,28 @@ static void wlan_process_tx_pause_event(pmlan_private priv, pmlan_buffer pevent)
return;
}
/**
* @brief This function will STA`s PS mode change event
*
* @param priv A pointer to mlan_private
* @param pevent A pointer to event buf
*
* @return N/A
*/
static void wlan_process_sta_ps_change_event(pmlan_private priv,
pmlan_buffer pevent)
{
MrvlIEtypes_PsStaStatus_t *ps_status =
(void *)(pevent->pbuf + pevent->data_offset + sizeof(t_u32));
ENTER();
wlan_update_sta_ps_state(priv, ps_status->mac, ps_status->sleep);
LEAVE();
return;
}
/**
* @brief This function prepares command for config uap settings
*
@ -1541,6 +1563,7 @@ static mlan_status wlan_uap_cmd_sys_configure(pmlan_private pmpriv,
MrvlIEtypes_action_chan_switch_t *tlv_chan_switch = MNULL;
IEEEtypes_ChanSwitchAnn_t *csa_ie = MNULL;
IEEEtypes_ExtChanSwitchAnn_t *ecsa_ie = MNULL;
MrvlIEtypes_MultiAp_t *tlv_multi_ap = MNULL;
ENTER();
@ -1992,6 +2015,19 @@ static mlan_status wlan_uap_cmd_sys_configure(pmlan_private pmpriv,
sizeof(HostCmd_DS_SYS_CONFIG) + S_DS_GEN +
sizeof(MrvlIEtypes_wacp_mode_t));
}
if (misc->sub_command == MLAN_OID_MISC_MULTI_AP_CFG) {
/** Add multi AP tlv here */
tlv_multi_ap =
(MrvlIEtypes_MultiAp_t *)sys_config->tlv_buffer;
tlv_multi_ap->header.type =
wlan_cpu_to_le16(TLV_TYPE_MULTI_AP);
tlv_multi_ap->header.len =
wlan_cpu_to_le16(sizeof(tlv_multi_ap->flag));
tlv_multi_ap->flag = misc->param.multi_ap_flag;
cmd->size = wlan_cpu_to_le16(
sizeof(HostCmd_DS_SYS_CONFIG) + S_DS_GEN +
sizeof(MrvlIEtypes_MultiAp_t));
}
}
done:
LEAVE();
@ -3332,6 +3368,8 @@ static mlan_status wlan_uap_ret_get_log(pmlan_private pmpriv,
wlan_le32_to_cpu(pget_log->gdma_abort_cnt);
pget_info->param.stats.g_reset_rx_mac_cnt =
wlan_le32_to_cpu(pget_log->g_reset_rx_mac_cnt);
pget_info->param.stats.SdmaStuckCnt =
wlan_le32_to_cpu(pget_log->SdmaStuckCnt);
// Ownership error counters
pget_info->param.stats.dwCtlErrCnt =
wlan_le32_to_cpu(pget_log->dwCtlErrCnt);
@ -3997,6 +4035,8 @@ static void wlan_check_uap_capability(pmlan_private priv, pmlan_buffer pevent)
wmm_param_ie.vend_hdr.element_id = WMM_IE;
wlan_wmm_setup_queue_priorities(priv,
&wmm_param_ie);
wlan_wmm_contention_init(
priv, wmm_param_ie.ac_params);
}
}
if (tlv_type == TLV_TYPE_UAP_PKT_FWD_CTL) {
@ -4452,7 +4492,7 @@ static mlan_status wlan_uap_cmd_add_station(pmlan_private pmpriv,
tlv_buf = bss->param.sta_info.tlv;
tlv = (MrvlIEtypesHeader_t *)tlv_buf;
if (bss->param.sta_info.sta_flags & STA_FLAG_WME) {
PRINTM(MCMND, "STA flags supports wmm \n");
PRINTM(MCMND, "ADD_STA flags supports wmm \n");
sta_ptr->is_wmm_enabled = MTRUE;
}
// append sta_flag_flags.
@ -4474,11 +4514,11 @@ static mlan_status wlan_uap_cmd_add_station(pmlan_private pmpriv,
(MrvlIEtypes_RatesParamSet_t *)tlv);
break;
case QOS_INFO:
PRINTM(MCMND, "STA supports wmm\n");
PRINTM(MCMND, "ADD_STA supports wmm\n");
sta_ptr->is_wmm_enabled = MTRUE;
break;
case HT_CAPABILITY:
PRINTM(MCMND, "STA supports 11n\n");
PRINTM(MCMND, "ADD_STA supports 11n\n");
sta_ptr->is_11n_enabled = MTRUE;
phtcap = (MrvlIETypes_HTCap_t *)tlv;
if (sta_ptr->HTcap.ieee_hdr.element_id ==
@ -4497,7 +4537,7 @@ static mlan_status wlan_uap_cmd_add_station(pmlan_private pmpriv,
sta_ptr->max_amsdu = MLAN_TX_DATA_BUF_SIZE_4K;
break;
case VHT_CAPABILITY:
PRINTM(MCMND, "STA supports 11ac\n");
PRINTM(MCMND, "ADD_STA supports 11ac\n");
sta_ptr->is_11ac_enabled = MTRUE;
pvhtcap = (MrvlIETypes_VHTCap_t *)tlv;
if (GET_VHTCAP_MAXMPDULEN(
@ -4515,7 +4555,7 @@ static mlan_status wlan_uap_cmd_add_station(pmlan_private pmpriv,
pext_tlv = (MrvlIEtypes_Extension_t *)tlv;
if (pext_tlv->ext_id == HE_CAPABILITY) {
sta_ptr->is_11ax_enabled = MTRUE;
PRINTM(MCMND, "STA supports 11ax\n");
PRINTM(MCMND, "ADD_STA supports 11ax\n");
} else {
pext_tlv = MNULL;
}
@ -4547,6 +4587,7 @@ static mlan_status wlan_uap_cmd_add_station(pmlan_private pmpriv,
memcpy_ext(pmadapter, pos,
(t_u8 *)&sta_ptr->he_cap.ext_id, tlv->len,
tlv->len);
pos += tlv->len;
travel_len += sizeof(MrvlIEtypesHeader_t) + tlv->len;
tlv->len = wlan_cpu_to_le16(tlv->len);
}
@ -4560,6 +4601,19 @@ static mlan_status wlan_uap_cmd_add_station(pmlan_private pmpriv,
pos += sizeof(MrvlIEtypesHeader_t);
memcpy_ext(pmadapter, pos, (t_u8 *)&sta_ptr->multi_ap_ie.data,
tlv->len, tlv->len);
pos += tlv->len;
travel_len += sizeof(MrvlIEtypesHeader_t) + tlv->len;
tlv->len = wlan_cpu_to_le16(tlv->len);
}
if (sta_ptr->vendor_oui_count) {
tlv = (MrvlIEtypesHeader_t *)pos;
tlv->type = wlan_cpu_to_le16(VENDOR_IE_OUIS_TLV_ID);
tlv->len = sta_ptr->vendor_oui_count * VENDOR_OUI_LEN;
pos += sizeof(MrvlIEtypesHeader_t);
memcpy_ext(pmadapter, pos, (t_u8 *)&sta_ptr->vendor_oui,
tlv->len, tlv->len);
pos += tlv->len;
travel_len += sizeof(MrvlIEtypesHeader_t) + tlv->len;
tlv->len = wlan_cpu_to_le16(tlv->len);
}
@ -4810,8 +4864,7 @@ mlan_status wlan_ops_uap_prepare_cmd(t_void *priv, t_u16 cmd_no,
if (pmpriv->adapter->hw_status == WlanHardwareStatusReset)
pmpriv->adapter->hw_status =
WlanHardwareStatusInitializing;
cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
cmd_ptr->size = wlan_cpu_to_le16(S_DS_GEN);
ret = wlan_cmd_func_init(pmpriv, cmd_ptr);
break;
case HostCmd_CMD_FUNC_SHUTDOWN:
pmpriv->adapter->hw_status = WlanHardwareStatusReset;
@ -4866,6 +4919,10 @@ mlan_status wlan_ops_uap_prepare_cmd(t_void *priv, t_u16 cmd_no,
case HostCmd_CMD_HS_WAKEUP_REASON:
ret = wlan_cmd_hs_wakeup_reason(pmpriv, cmd_ptr, pdata_buf);
break;
case HostCmd_CMD_802_11_FW_WAKE_METHOD:
ret = wlan_cmd_802_11_fw_wakeup_method(
pmpriv, cmd_ptr, cmd_action, (t_u16 *)pdata_buf);
break;
case HostCmd_CMD_802_11_ROBUSTCOEX:
ret = wlan_cmd_robustcoex(pmpriv, cmd_ptr, cmd_action,
(t_u16 *)pdata_buf);
@ -5065,6 +5122,12 @@ mlan_status wlan_ops_uap_prepare_cmd(t_void *priv, t_u16 cmd_no,
pdata_buf);
break;
#endif
#endif
#if defined(PCIE)
case HostCmd_CMD_PCIE_ADMA_INIT:
ret = wlan_cmd_pcie_adma_init(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
break;
#endif
case HostCmd_CMD_TX_RX_PKT_STATS:
ret = wlan_cmd_tx_rx_pkt_stats(pmpriv, cmd_ptr,
@ -5171,6 +5234,10 @@ mlan_status wlan_ops_uap_prepare_cmd(t_void *priv, t_u16 cmd_no,
ret = wlan_cmd_cross_chip_synch(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
break;
case HostCmd_CMD_TSP_CFG:
ret = wlan_cmd_tsp_config(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
break;
case HostCmd_CMD_DS_GET_SENSOR_TEMP:
wlan_cmd_get_sensor_temp(pmpriv, cmd_ptr, cmd_action);
break;
@ -5189,6 +5256,17 @@ mlan_status wlan_ops_uap_prepare_cmd(t_void *priv, t_u16 cmd_no,
case HostCmd_CMD_CSI:
ret = wlan_cmd_csi(pmpriv, cmd_ptr, cmd_action, pdata_buf);
break;
case HostCmd_CMD_PEER_TX_RATE_QUERY:
ret = wlan_cmd_sta_tx_rate_req(pmpriv, cmd_ptr, cmd_action,
pdata_buf);
break;
case HostCmd_CMD_MCLIENT_SCHEDULE_CFG:
ret = wlan_cmd_mclient_scheduling_cfg(pmpriv, cmd_ptr,
cmd_action, pdata_buf);
break;
default:
PRINTM(MERROR, "PREP_CMD: unknown command- %#x\n", cmd_no);
if (pioctl_req)
@ -5343,6 +5421,9 @@ mlan_status wlan_ops_uap_process_cmdresp(t_void *priv, t_u16 cmdresp_no,
case HostCmd_CMD_HS_WAKEUP_REASON:
ret = wlan_ret_hs_wakeup_reason(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_802_11_FW_WAKE_METHOD:
ret = wlan_ret_fw_wakeup_method(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_802_11_ROBUSTCOEX:
break;
case HostCmd_CMD_DMCS_CONFIG:
@ -5523,6 +5604,12 @@ mlan_status wlan_ops_uap_process_cmdresp(t_void *priv, t_u16 cmdresp_no,
PRINTM(MINFO, "PCIE host buffer configuration successful.\n");
break;
#endif
#endif
#if defined(PCIE)
case HostCmd_CMD_PCIE_ADMA_INIT:
PRINTM(MINFO, "PCIE ADMA init successful.\n");
wlan_pcie_init_fw(pmpriv->adapter);
break;
#endif
case HostCmd_CMD_TX_RX_PKT_STATS:
ret = wlan_ret_tx_rx_pkt_stats(pmpriv, resp, pioctl_buf);
@ -5606,6 +5693,9 @@ mlan_status wlan_ops_uap_process_cmdresp(t_void *priv, t_u16 cmdresp_no,
case HostCmd_CMD_CROSS_CHIP_SYNCH:
ret = wlan_ret_cross_chip_synch(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_TSP_CFG:
ret = wlan_ret_tsp_config(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_DS_GET_SENSOR_TEMP:
ret = wlan_ret_get_sensor_temp(pmpriv, resp, pioctl_buf);
break;
@ -5629,6 +5719,14 @@ mlan_status wlan_ops_uap_process_cmdresp(t_void *priv, t_u16 cmdresp_no,
PRINTM(MCMND, "CSI DISABLE cmdresp\n");
}
break;
case HostCmd_CMD_PEER_TX_RATE_QUERY:
ret = wlan_ret_sta_tx_rate(pmpriv, resp, pioctl_buf);
break;
case HostCmd_CMD_MCLIENT_SCHEDULE_CFG:
break;
default:
PRINTM(MERROR, "CMD_RESP: Unknown command response %#x\n",
resp->command);
@ -6111,6 +6209,14 @@ mlan_status wlan_ops_uap_process_event(t_void *priv)
pevent->event_id = 0; /* clear to avoid resending at end of fcn
*/
break;
case EVENT_CHAN_SWITCH_TO_6G_BLOCK:
reason_code = wlan_le16_to_cpu(*(t_u16 *)(pmbuf->pbuf +
pmbuf->data_offset +
sizeof(eventcause)));
print_chan_switch_block_event(reason_code);
break;
case EVENT_TX_STATUS_REPORT:
PRINTM(MINFO, "EVENT: TX_STATUS\n");
pevent->event_id = MLAN_EVENT_ID_FW_TX_STATUS;
@ -6212,6 +6318,10 @@ mlan_status wlan_ops_uap_process_event(t_void *priv)
break;
#endif
case EVENT_PEER_PS_MODE_CHANGE:
wlan_process_sta_ps_change_event(priv, pmbuf);
break;
default:
pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU;
break;

View file

@ -337,7 +337,10 @@ static mlan_status wlan_uap_bss_ioctl_reset(pmlan_adapter pmadapter,
*/
for (i = 0; i < pmadapter->max_mgmt_ie_index; i++)
memset(pmadapter, &pmpriv->mgmt_ie[i], 0, sizeof(custom_ie));
pmpriv->add_ba_param.timeout = MLAN_DEFAULT_BLOCK_ACK_TIMEOUT;
pmpriv->add_ba_param.timeout = pmadapter->tx_ba_timeout_support ?
MLAN_DEFAULT_BLOCK_ACK_TIMEOUT :
0;
pmpriv->add_ba_param.tx_win_size = MLAN_UAP_AMPDU_DEF_TXWINSIZE;
pmpriv->add_ba_param.rx_win_size = MLAN_UAP_AMPDU_DEF_RXWINSIZE;
pmpriv->user_rxwinsize = pmpriv->add_ba_param.rx_win_size;
@ -2247,6 +2250,10 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req)
status = wlan_misc_ioctl_cross_chip_synch(pmadapter,
pioctl_req);
}
if (misc->sub_command == MLAN_OID_MISC_TSP_CFG) {
status = wlan_misc_ioctl_tsp_config(pmadapter,
pioctl_req);
}
if (misc->sub_command == MLAN_OID_MISC_GET_CHAN_REGION_CFG)
status = wlan_misc_chan_reg_cfg(pmadapter, pioctl_req);
if (misc->sub_command == MLAN_OID_MISC_OPER_CLASS_CHECK)
@ -2375,6 +2382,8 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req)
status = wlan_config_mgmt_filter(pmadapter, pioctl_req);
if (pm->sub_command == MLAN_OID_PM_INFO)
status = wlan_get_pm_info(pmadapter, pioctl_req);
if (pm->sub_command == MLAN_OID_PM_CFG_FW_WAKEUP_METHOD)
status = wlan_fw_wakeup_method(pmadapter, pioctl_req);
break;
case MLAN_IOCTL_SNMP_MIB:
snmp = (mlan_ds_snmp_mib *)pioctl_req->pbuf;

View file

@ -69,10 +69,10 @@ static const struct _mlan_card_info mlan_card_info_usb8997 = {
#ifdef USB8978
static const struct _mlan_card_info mlan_card_info_usb8978 = {
.max_tx_buf_size = MLAN_TX_DATA_BUF_SIZE_4K,
.max_tx_buf_size = MLAN_TX_DATA_BUF_SIZE_2K,
.v16_fw_api = 1,
.supp_ps_handshake = 1,
.default_11n_tx_bf_cap = DEFAULT_11N_TX_BF_CAP_2X2,
.default_11n_tx_bf_cap = DEFAULT_11N_TX_BF_CAP_1X1,
.support_11mc = 1,
};
#endif
@ -110,8 +110,8 @@ static const struct _mlan_card_info mlan_card_info_usbIW624 = {
};
#endif
#ifdef USBIW615
static const struct _mlan_card_info mlan_card_info_usbIW615 = {
#ifdef USBIW610
static const struct _mlan_card_info mlan_card_info_usbIW610 = {
.max_tx_buf_size = MLAN_TX_DATA_BUF_SIZE_4K,
.v16_fw_api = 1,
.v17_fw_api = 1,
@ -228,6 +228,10 @@ static mlan_status wlan_usb_prog_fw_w_helper(pmlan_adapter pmadapter,
#if defined(USB9098)
t_u32 revision_id = 0;
#endif
t_u32 i = 0;
t_u32 fw_data_param = pmadapter->init_para.fw_data_cfg;
fw_data_t fw_data_list[MAX_FW_DATA_BLOCK] = {0};
t_u32 fw_data_param_num = 0, fw_data_index = 0;
ENTER();
@ -269,6 +273,16 @@ static mlan_status wlan_usb_prog_fw_w_helper(pmlan_adapter pmadapter,
check_fw_status = MTRUE;
}
#endif
if (fw_data_param) {
fw_data_param_num =
MIN(MAX_FW_DATA_BLOCK, bitcount(fw_data_param));
/** Get the custom Fw data */
if (MLAN_STATUS_SUCCESS !=
wlan_get_custom_fw_data(pmadapter, (t_u8 *)fw_data_list))
goto cleanup;
}
#if defined(USB9097)
if (IS_USB9097(pmadapter->card_type))
check_fw_status = MTRUE;
@ -435,6 +449,25 @@ static mlan_status wlan_usb_prog_fw_w_helper(pmlan_adapter pmadapter,
FWSeqNum++;
PRINTM(MINFO, ".\n");
if (fw_data_param) {
for (i = fw_data_index; i < fw_data_param_num;) {
firmware = fw_data_list[i].fw_data_buffer;
/** make TotalBytes as 0 as allocated custom Fw
* data buffers are not contiguous */
TotalBytes = 0;
fw_data_index++;
break;
}
/** custom Fw data download complete, restore Fw */
if (i >= fw_data_param_num) {
firmware = pmfw->pfw_buf;
fw_data_param = 0;
fw_data_index = 0;
FWSeqNum = 0;
TotalBytes = 0;
}
}
/* Add FW ending check for secure download */
if (((DnldCmd == FW_CMD_21) && (DataLength == 0)) ||
(TotalBytes >= pmfw->fw_len))
@ -828,9 +861,9 @@ mlan_status wlan_get_usb_device(pmlan_adapter pmadapter)
pmadapter->pcard_info = &mlan_card_info_usbIW624;
break;
#endif
#ifdef USBIW615
case CARD_TYPE_USBIW615:
pmadapter->pcard_info = &mlan_card_info_usbIW615;
#ifdef USBIW610
case CARD_TYPE_USBIW610:
pmadapter->pcard_info = &mlan_card_info_usbIW610;
break;
#endif
default:
@ -1328,7 +1361,7 @@ static mlan_status wlan_usb_host_to_card(pmlan_private pmpriv, t_u8 type,
}
if (type == MLAN_TYPE_CMD
#if defined(USB9098) || defined(USB9097) || defined(USBIW624) || \
defined(USB8997) || defined(USB8978)
defined(USB8997) || defined(USB8978) || defined(USBIW610)
|| type == MLAN_TYPE_VDLL
#endif
) {
@ -1389,9 +1422,13 @@ static mlan_status wlan_usb_evt_complete(pmlan_adapter pmadapter,
mlan_buffer *pmbuf, mlan_status status)
{
ENTER();
pmadapter->event_received = MFALSE;
wlan_request_event_lock(pmadapter);
if (pmadapter->event_received)
pmadapter->event_received = MFALSE;
pmadapter->event_cause = 0;
pmadapter->pmlan_buffer_event = MNULL;
wlan_release_event_lock(pmadapter);
pmadapter->callbacks.moal_recv_complete(pmadapter->pmoal_handle, pmbuf,
pmadapter->rx_cmd_ep, status);

View file

@ -68,6 +68,19 @@ static INLINE t_void util_init_list(pmlan_linked_list phead)
phead->pprev = phead->pnext = (pmlan_linked_list)phead;
}
/**
* @brief This function initializes a list head without locking
*
* @param phead List head
*
* @return N/A
*/
static INLINE t_void util_list_head_reset(pmlan_list_head phead)
{
/* Both next and prev point to self */
phead->pprev = phead->pnext = (pmlan_linked_list)phead;
}
/**
* @brief This function initializes a list
*
@ -106,6 +119,24 @@ static INLINE t_void util_free_list_head(
moal_free_lock(pmoal_handle, phead->plock);
}
/**
* @brief This function peeks into a list without lock
*
* @param phead List head
*
* @return List node
*/
static INLINE pmlan_linked_list util_peek_list_nl(t_void *pmoal_handle,
pmlan_list_head phead)
{
pmlan_linked_list pnode = MNULL;
if (phead->pnext != (pmlan_linked_list)phead)
pnode = phead->pnext;
return pnode;
}
/**
* @brief This function peeks into a list
*
@ -124,13 +155,33 @@ util_peek_list(t_void *pmoal_handle, pmlan_list_head phead,
if (moal_spin_lock)
moal_spin_lock(pmoal_handle, phead->plock);
if (phead->pnext != (pmlan_linked_list)phead)
pnode = phead->pnext;
pnode = util_peek_list_nl(pmoal_handle, phead);
if (moal_spin_unlock)
moal_spin_unlock(pmoal_handle, phead->plock);
return pnode;
}
/**
* @brief This function queues a node at the list tail without taking any lock
*
* @param phead List head
* @param pnode List node to queue
*
* @return N/A
*/
static INLINE t_void util_enqueue_list_tail_nl(t_void *pmoal_handle,
pmlan_list_head phead,
pmlan_linked_list pnode)
{
pmlan_linked_list pold_last = phead->pprev;
pnode->pprev = pold_last;
pnode->pnext = (pmlan_linked_list)phead;
phead->pprev = pold_last->pnext = pnode;
}
/**
* @brief This function queues a node at the list tail
*
@ -146,15 +197,11 @@ static INLINE t_void util_enqueue_list_tail(
mlan_status (*moal_spin_lock)(t_void *handle, t_void *plock),
mlan_status (*moal_spin_unlock)(t_void *handle, t_void *plock))
{
pmlan_linked_list pold_last;
if (moal_spin_lock)
moal_spin_lock(pmoal_handle, phead->plock);
pold_last = phead->pprev;
pnode->pprev = pold_last;
pnode->pnext = (pmlan_linked_list)phead;
phead->pprev = pold_last->pnext = pnode;
util_enqueue_list_tail_nl(pmoal_handle, phead, pnode);
if (moal_spin_unlock)
moal_spin_unlock(pmoal_handle, phead->plock);
}
@ -187,6 +234,89 @@ static INLINE t_void util_enqueue_list_head(
moal_spin_unlock(pmoal_handle, phead->plock);
}
/**
* @brief This function checks if the node points to itself
*
* @param pnode List node to check
*
* @return MTRUE if node points to itself only
*/
static INLINE t_bool util_is_node_itself(pmlan_linked_list pnode)
{
return pnode->pprev == pnode && pnode->pnext == pnode;
}
/**
* @brief This function checks if the node in some list
*
* @param pnode List node to check
*
* @return MTRUE if node is enqueued into some list
*/
static INLINE t_bool util_is_node_in_list(pmlan_linked_list pnode)
{
return pnode->pprev && pnode->pnext && !util_is_node_itself(pnode);
}
/**
* @brief This function checks if the pnode is valid node of list
*
* @param phead List`s head
* @param pnode List node to check
*
* @return MTRUE if node is enqueued into some list
*/
static INLINE t_bool util_is_list_node(pmlan_list_head phead,
pmlan_linked_list pnode)
{
return pnode && (pmlan_linked_list)phead != pnode;
}
/**
* @brief This function removes a node from the list if the node was in the
* list
*
* @param pnode List node to remove
*
* @return N/A
*/
static INLINE t_void util_unlink_list_safe_nl(t_void *pmoal_handle,
pmlan_linked_list pnode)
{
if (util_is_node_in_list(pnode)) {
pmlan_linked_list pmy_prev;
pmlan_linked_list pmy_next;
pmy_prev = pnode->pprev;
pmy_next = pnode->pnext;
pmy_next->pprev = pmy_prev;
pmy_prev->pnext = pmy_next;
pnode->pnext = pnode->pprev = MNULL;
}
}
/**
* @brief This function removes a node from the list
*
* @param pnode List node to remove
*
* @return N/A
*/
static INLINE t_void util_unlink_list_nl(t_void *pmoal_handle,
pmlan_linked_list pnode)
{
pmlan_linked_list pmy_prev;
pmlan_linked_list pmy_next;
pmy_prev = pnode->pprev;
pmy_next = pnode->pnext;
pmy_next->pprev = pmy_prev;
pmy_prev->pnext = pmy_next;
pnode->pnext = pnode->pprev = MNULL;
}
/**
* @brief This function removes a node from the list
*
@ -202,17 +332,11 @@ static INLINE t_void util_unlink_list(
mlan_status (*moal_spin_lock)(t_void *handle, t_void *plock),
mlan_status (*moal_spin_unlock)(t_void *handle, t_void *plock))
{
pmlan_linked_list pmy_prev;
pmlan_linked_list pmy_next;
if (moal_spin_lock)
moal_spin_lock(pmoal_handle, phead->plock);
pmy_prev = pnode->pprev;
pmy_next = pnode->pnext;
pmy_next->pprev = pmy_prev;
pmy_prev->pnext = pmy_next;
pnode->pnext = pnode->pprev = MNULL;
util_unlink_list_nl(pmoal_handle, pnode);
if (moal_spin_unlock)
moal_spin_unlock(pmoal_handle, phead->plock);
}
@ -515,4 +639,26 @@ reflective_enum_lookup_name(const struct reflective_enum_element *elements,
return elem->name;
}
#define util_offsetof(struct_type, member_name) \
((t_ptr) & ((struct_type *)0)->member_name)
#define util_container_of(ptr, struct_type, member_name) \
((struct_type *)((t_u8 *)(ptr)-util_offsetof(struct_type, member_name)))
/**
* @brief This function checks if t1 timestamp is before t2 timestamp
*
* @param t1 t1 timestamp
* @param t2 t2 timestamp
*
* @return MTRUE if t1 is before t2
*/
static INLINE t_bool util_is_time_before(t_u64 t1, t_u64 t2)
{
t_s64 delta = t2 - t1;
// coverity[integer_overflow:SUPPRESS]
return delta > 0;
}
#endif /* !_MLAN_UTIL_H_ */

File diff suppressed because it is too large Load diff

View file

@ -251,4 +251,20 @@ extern mlan_status wlan_ret_wmm_queue_config(pmlan_private pmpriv,
mlan_status wlan_wmm_cfg_ioctl(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);
void wlan_wmm_update_sta_tx_rate(pmlan_private priv, t_u8 *mac,
HostCmd_TX_RATE_QUERY *rate);
void wlan_wmm_consume_byte_budget(raListTbl *ra_list, mlan_buffer *pmbuf);
void wlan_wmm_consume_mpdu_budget(raListTbl *ra_list);
static INLINE void wlan_advance_bss_on_pkt_push(pmlan_adapter pmadapter,
mlan_bssprio_tbl *bssprio_tbl)
{
if (pmadapter->mclient_tx_supported)
return;
bssprio_tbl->bssprio_cur = bssprio_tbl->bssprio_cur->pnext;
}
#endif /* !_MLAN_WMM_H_ */

View file

@ -206,6 +206,8 @@ typedef t_s32 t_sval;
#define MLAN_RATE_INDEX_MCS4 4
/** Rate index for MCS 7 */
#define MLAN_RATE_INDEX_MCS7 7
/** Rate index for MCS 8 */
#define MLAN_RATE_INDEX_MCS8 8
/** Rate index for MCS 9 */
#define MLAN_RATE_INDEX_MCS9 9
/** Rate index for MCS11 */
@ -395,14 +397,17 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define CARD_TYPE_IW624 0x0b
/** Black bird card type */
#define CARD_TYPE_AW693 0x0c
/** IW615 card type */
#define CARD_TYPE_IW615 0x0d
/** IW610 card type */
#define CARD_TYPE_IW610 0x0d
/** 9098 A0 reverion num */
#define CHIP_9098_REV_A0 1
#define CHIP_9098_REV_A1 2
/** 9097 CHIP REV */
#define CHIP_9097_REV_B0 1
/** Blackbird reverion num */
#define CHIP_AW693_REV_A0 1
#define CHIP_AW693_REV_A1 2
#define INTF_MASK 0xff
#define CARD_TYPE_MASK 0xff
@ -432,8 +437,8 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define CARD_TYPE_SDIW624 (CARD_TYPE_IW624 | (INTF_SD << 8))
/** SD_IW624 card type */
#define CARD_TYPE_SDAW693 (CARD_TYPE_AW693 | (INTF_SD << 8))
/** SD_IW615 card type */
#define CARD_TYPE_SDIW615 (CARD_TYPE_IW615 | (INTF_SD << 8))
/** SD_IW610 card type */
#define CARD_TYPE_SDIW610 (CARD_TYPE_IW610 | (INTF_SD << 8))
#define IS_SD8887(ct) (CARD_TYPE_SD8887 == (ct))
#define IS_SD8897(ct) (CARD_TYPE_SD8897 == (ct))
@ -447,7 +452,7 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define IS_SD8801(ct) (CARD_TYPE_SD8801 == (ct))
#define IS_SDIW624(ct) (CARD_TYPE_SDIW624 == (ct))
#define IS_SDAW693(ct) (CARD_TYPE_SDAW693 == (ct))
#define IS_SDIW615(ct) (CARD_TYPE_SDIW615 == (ct))
#define IS_SDIW610(ct) (CARD_TYPE_SDIW610 == (ct))
/** SD8887 Card */
#define CARD_SD8887 "SD8887"
@ -473,8 +478,8 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define CARD_SDIW624 "SDIW624"
/** SDAW693 Card */
#define CARD_SDAW693 "SDAW693"
/** SDIW615 Card */
#define CARD_SDIW615 "SDIW615"
/** SDIW610 Card */
#define CARD_SDIW610 "SDIW610"
#endif
#ifdef PCIE
@ -533,8 +538,8 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define CARD_TYPE_USB9097 (CARD_TYPE_9097 | (INTF_USB << 8))
/** USBIW624 card type */
#define CARD_TYPE_USBIW624 (CARD_TYPE_IW624 | (INTF_USB << 8))
/** USBIW615 card type */
#define CARD_TYPE_USBIW615 (CARD_TYPE_IW615 | (INTF_USB << 8))
/** USBIW610 card type */
#define CARD_TYPE_USBIW610 (CARD_TYPE_IW610 | (INTF_USB << 8))
#define IS_USB8801(ct) (CARD_TYPE_USB8801 == (ct))
#define IS_USB8897(ct) (CARD_TYPE_USB8897 == (ct))
@ -543,7 +548,7 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define IS_USB9098(ct) (CARD_TYPE_USB9098 == (ct))
#define IS_USB9097(ct) (CARD_TYPE_USB9097 == (ct))
#define IS_USBIW624(ct) (CARD_TYPE_USBIW624 == (ct))
#define IS_USBIW615(ct) (CARD_TYPE_USBIW615 == (ct))
#define IS_USBIW610(ct) (CARD_TYPE_USBIW610 == (ct))
/** USB8801 Card */
#define CARD_USB8801 "USB8801"
@ -559,14 +564,15 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define CARD_USB9097 "USBIW620"
/** USBIW624 Card */
#define CARD_USBIW624 "USBIW624"
/** USBIW615 Card */
#define CARD_USBIW615 "USBIW615"
/** USBIW610 Card */
#define CARD_USBIW610 "USBIW610"
#endif
#define IS_CARD8801(ct) (CARD_TYPE_8801 == ((ct)&0xf))
#define IS_CARD8887(ct) (CARD_TYPE_8887 == ((ct)&0xf))
#define IS_CARD8897(ct) (CARD_TYPE_8897 == ((ct)&0xf))
#define IS_CARD8977(ct) (CARD_TYPE_8977 == ((ct)&0xf))
#define IS_CARD8978(ct) (CARD_TYPE_8978 == ((ct)&0xf))
#define IS_CARD8997(ct) (CARD_TYPE_8997 == ((ct)&0xf))
#define IS_CARD8987(ct) (CARD_TYPE_8987 == ((ct)&0xf))
#define IS_CARD9098(ct) (CARD_TYPE_9098 == ((ct)&0xf))
@ -574,7 +580,7 @@ typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
#define IS_CARD9177(ct) (CARD_TYPE_9177 == ((ct)&0xf))
#define IS_CARDIW624(ct) (CARD_TYPE_IW624 == ((ct)&0xf))
#define IS_CARDAW693(ct) (CARD_TYPE_AW693 == ((ct)&0xf))
#define IS_CARDIW615(ct) (CARD_TYPE_IW615 == ((ct)&0xf))
#define IS_CARDIW610(ct) (CARD_TYPE_IW610 == ((ct)&0xf))
typedef struct _card_type_entry {
t_u16 card_type;
@ -648,6 +654,8 @@ typedef enum {
#define MLAN_BUF_FLAG_MC_AGGR_PKT MBIT(17)
#define MLAN_BUF_FLAG_TCP_PKT MBIT(18)
#define MLAN_BUF_FLAG_LLDE_PKT_FILTER MBIT(19)
#ifdef DEBUG_LEVEL1
@ -660,8 +668,8 @@ typedef enum {
#define MEVENT MBIT(5)
#define MINTR MBIT(6)
#define MIOCTL MBIT(7)
#define MREG_D MBIT(9)
#define MREG MBIT(10)
#define MMPA_D MBIT(15)
#define MDAT_D MBIT(16)
@ -670,7 +678,7 @@ typedef enum {
#define MFW_D MBIT(19)
#define MIF_D MBIT(20)
#define MFWDP_D MBIT(21)
#define MSCH_D MBIT(22)
#define MENTRY MBIT(28)
#define MWARN MBIT(29)
#define MINFO MBIT(30)
@ -1630,7 +1638,7 @@ typedef MLAN_PACK_START struct _tdls_each_link_status {
/** Key Length */
t_u8 key_length;
/** actual key */
t_u8 key[1];
t_u8 key[];
} MLAN_PACK_END tdls_each_link_status;
/** TDLS configuration data */
@ -1757,7 +1765,7 @@ typedef MLAN_PACK_START struct _tdls_all_config {
/** number of links */
t_u8 active_links;
/** structure for link status */
tdls_each_link_status link_stats[1];
tdls_each_link_status link_stats[];
} MLAN_PACK_END tdls_link_status_resp;
} u;
@ -2596,6 +2604,7 @@ typedef struct _mlan_callbacks {
t_u8 antenna);
t_void (*moal_updata_peer_signal)(t_void *pmoal, t_u32 bss_index,
t_u8 *peer_addr, t_s8 snr, t_s8 nflr);
mlan_status (*moal_get_host_time_ns)(t_u64 *time);
t_u64 (*moal_do_div)(t_u64 num, t_u32 base);
void (*moal_tp_accounting)(t_void *pmoal, t_void *buf,
t_u32 drop_point);
@ -2694,6 +2703,8 @@ typedef struct _mlan_device {
#endif
/** Auto deep sleep */
t_u32 auto_ds;
/** Boot Time Config */
t_u32 bootup_cal_ctrl;
/** IEEE PS mode */
t_u32 ps_mode;
/** Max Tx buffer size */
@ -2745,6 +2756,8 @@ typedef struct _mlan_device {
t_u8 uap_max_sta;
/** wacp mode */
t_u8 wacp_mode;
/** custom Fw data */
t_u32 fw_data_cfg;
/** drv mode */
t_u32 drv_mode;
/** dfs w53 cfg */
@ -2763,8 +2776,12 @@ typedef struct _mlan_device {
t_u32 antcfg;
/** dmcs */
t_u8 dmcs;
t_u8 pref_dbc;
t_u32 reject_addba_req;
t_u32 max_tx_pending;
t_u16 tx_budget;
t_u8 mclient_scheduling;
} mlan_device, *pmlan_device;
/** MLAN API function prototype */

View file

@ -71,6 +71,9 @@ typedef enum _WLAN_802_11_NETWORK_TYPE {
typedef enum _IEEEtypes_Ext_ElementId_e {
HE_CAPABILITY = 35,
HE_OPERATION = 36,
MU_EDCA_PARAM_SET = 38,
MBSSID_CONFIG = 55,
NON_INHERITANCE = 56,
HE_6G_CAPABILITY = 59
} IEEEtypes_Ext_ElementId_e;
@ -260,7 +263,7 @@ typedef MLAN_PACK_START struct _IEEEtypes_FastBssTransElement_t {
/** SNonce */
t_u8 s_nonce[32];
/** sub element */
t_u8 sub_element[1];
t_u8 sub_element[];
} MLAN_PACK_END IEEEtypes_FastBssTransElement_t;
/*Category for FT*/
@ -547,7 +550,7 @@ typedef MLAN_PACK_START struct _IEEEtypes_AssocRsp_t {
/** Association ID */
IEEEtypes_AId_t a_id;
/** IE data buffer */
t_u8 ie_buffer[1];
t_u8 ie_buffer[];
} MLAN_PACK_END IEEEtypes_AssocRsp_t, *pIEEEtypes_AssocRsp_t;
/** 802.11 supported rates */
@ -985,7 +988,7 @@ typedef MLAN_PACK_START struct _IEEEtypes_CountryInfoSet_t {
/** Country code */
t_u8 country_code[COUNTRY_CODE_LEN];
/** Set of subbands */
IEEEtypes_SubbandSet_t sub_band[1];
IEEEtypes_SubbandSet_t sub_band[];
} MLAN_PACK_END IEEEtypes_CountryInfoSet_t, *pIEEEtypes_CountryInfoSet_t;
/** Data structure for Country IE full set */
@ -1151,6 +1154,18 @@ typedef MLAN_PACK_START struct _IEEEtypes_MultiBSSID_t {
/** Optional Subelement data*/
t_u8 sub_elem_data[];
} MLAN_PACK_END IEEEtypes_MultiBSSID_t, *pIEEEtypes_MultiBSSID_t;
/** Multi BSSID Configuration IE */
typedef MLAN_PACK_START struct _IEEEtypes_MBSSID_Config_t {
/** Generic IE header */
IEEEtypes_Header_t ieee_hdr;
/** Element id extension */
t_u8 ext_id;
/** BSSID Count */
t_u8 bssid_cnt;
/** Full Set Rx Periodicity */
t_u8 fs_rx_periodicity;
} MLAN_PACK_END IEEEtypes_MBSSID_Config_t, *pIEEEtypes_MBSSID_Config_t;
/** 20/40 BSS Coexistence IE */
typedef MLAN_PACK_START struct _IEEEtypes_2040BSSCo_t {
/** Generic IE header */
@ -1466,6 +1481,32 @@ typedef MLAN_PACK_START struct _IEEEtypes_HeOp_t {
t_u8 option[9];
} MLAN_PACK_END IEEEtypes_HeOp_t;
/** MU EDCA Parameter Set */
typedef MLAN_PACK_START struct _IEEEtypes_MUEDCAParamSet_t {
/** Generic IE header */
IEEEtypes_Header_t ieee_hdr;
/** Extended Tag */
t_u8 ext_tag;
/** QOS Information */
t_u8 qos_info;
/** MUAC BE Paramter Record */
t_u8 muac_be[3];
/** MUAC BK Paramter Record */
t_u8 muac_bk[3];
/** MUAC VI Paramter Record */
t_u8 muac_vi[3];
/** MUAC VO Paramter Record */
t_u8 muac_vo[3];
} MLAN_PACK_END IEEEtypes_MUEDCAParamSet_t, *pIEEEtypes_MUEDCAParamSet_t;
/** IEEE format IE */
typedef MLAN_PACK_START struct _IEEEtypes_Element_t {
/** Generic IE header */
IEEEtypes_Header_t ieee_hdr;
/** IE data */
t_u8 data[];
} MLAN_PACK_END IEEEtypes_Element_t, *pIEEEtypes_Element_t;
/** default channel switch count */
#define DEF_CHAN_SWITCH_COUNT 5
@ -2094,6 +2135,10 @@ typedef struct _BSSDescriptor_t {
t_u8 multi_bssid_ap;
/** the mac address of multi-bssid AP */
mlan_802_11_mac_addr multi_bssid_ap_addr;
/** Multi BSSID Configuration IE */
IEEEtypes_MBSSID_Config_t *pmbssid_config;
/** Multi BSSID Configuration IE offset */
t_u16 mbssid_config_offset;
/** 20/40 BSS Coexistence IE */
IEEEtypes_2040BSSCo_t *pbss_co_2040;
/** 20/40 BSS Coexistence Offset */
@ -2174,7 +2219,10 @@ typedef struct _BSSDescriptor_t {
IEEEtypes_MobilityDomain_t *pmd_ie;
/** Mobility domain IE offset in the beacon buffer */
t_u16 md_offset;
/** MU EDCA Parameter IE */
IEEEtypes_MUEDCAParamSet_t *pmuedca_ie;
/** MU EDCA Parameter IE offset */
t_u16 muedca_offset;
/** Pointer to the returned scan response */
t_u8 *pbeacon_buf;
/** Length of the stored scan response */

View file

@ -164,6 +164,7 @@ enum _mlan_ioctl_req_id {
MLAN_OID_PM_CFG_DEEP_SLEEP = 0x00090004,
MLAN_OID_PM_CFG_SLEEP_PD = 0x00090005,
MLAN_OID_PM_CFG_PS_CFG = 0x00090006,
MLAN_OID_PM_CFG_FW_WAKEUP_METHOD = 0x00090007,
MLAN_OID_PM_CFG_SLEEP_PARAMS = 0x00090008,
#ifdef UAP_SUPPORT
MLAN_OID_PM_CFG_PS_MODE = 0x00090009,
@ -375,6 +376,7 @@ enum _mlan_ioctl_req_id {
MLAN_OID_MISC_CROSS_CHIP_SYNCH = 0x0020008B,
MLAN_OID_MISC_RF_TEST_CONFIG_TRIGGER_FRAME = 0x0020008C,
MLAN_OID_MISC_OFDM_DESENSE_CFG = 0x0020008D,
MLAN_OID_MISC_TSP_CFG = 0x002008C,
MLAN_OID_MISC_REORDER_FLUSH_TIME = 0x0020008F,
MLAN_OID_MISC_NAV_MITIGATION = 0x00200090,
MLAN_OID_MISC_LED_CONFIG = 0x00200091,
@ -383,6 +385,8 @@ enum _mlan_ioctl_req_id {
MLAN_OID_MISC_GPIO_CFG = 0x00200094,
MLAN_OID_MISC_REGION_POWER_CFG = 0x00200095,
MLAN_OID_MISC_OTP_MAC_RD_WR = 0x00200097,
MLAN_OID_MISC_OTP_CAL_DATA_RD_WR = 0x00200098,
MLAN_OID_MISC_AUTH_ASSOC_TIMEOUT_CONFIG = 0x00200099,
};
/** Sub command size */
@ -519,7 +523,7 @@ typedef struct {
* Buffer marker for multiple wlan_ioctl_get_scan_table_entry
* structures. Each struct is padded to the nearest 32 bit boundary.
*/
t_u8 scan_table_entry_buf[1];
t_u8 scan_table_entry_buf[];
} wlan_ioctl_get_scan_table_info;
/**
@ -576,7 +580,7 @@ typedef struct _mlan_user_scan {
/** Length of scan_cfg_buf */
t_u32 scan_cfg_len;
/** Buffer of scan config */
t_u8 scan_cfg_buf[1];
t_u8 scan_cfg_buf[];
} mlan_user_scan, *pmlan_user_scan;
/** Type definition of mlan_scan_req */
@ -1763,6 +1767,8 @@ typedef struct _mlan_ds_get_stats {
t_u32 gdma_abort_cnt;
/** Rx Reset MAC Count */
t_u32 g_reset_rx_mac_cnt;
/** SDMA FSM stuck Count*/
t_u32 SdmaStuckCnt;
// Ownership error counters
/*Error Ownership error count*/
t_u32 dwCtlErrCnt;
@ -3395,6 +3401,15 @@ typedef struct _mlan_ds_hs_wakeup_reason {
t_u16 hs_wakeup_reason;
} mlan_ds_hs_wakeup_reason;
/** Type definition of mlan_fw_wakeup_params for
* MLAN_OID_PM_CFG_FW_WAKEUP_METHOD */
typedef struct _mlan_fw_wakeup_params {
/** FW wakeup method */
t_u16 method;
/** GPIO pin NO.*/
t_u8 gpio_pin;
} mlan_fw_wakeup_params, *pmlan_fw_wakeup_params;
/** Type definition of mlan_ds_ps_cfg for MLAN_OID_PM_CFG_PS_CFG */
typedef struct _mlan_ds_bcn_timeout {
/** Beacon miss timeout period window */
@ -3425,6 +3440,8 @@ typedef struct _mlan_ds_pm_cfg {
t_u32 sleep_period;
/** PS configuration parameters for MLAN_OID_PM_CFG_PS_CFG */
mlan_ds_ps_cfg ps_cfg;
/** FW wakeup method for MLAN_OID_PM_CFG_FW_WAKEUP_METHOD */
mlan_fw_wakeup_params fw_wakeup_params;
/** PS configuration parameters for MLAN_OID_PM_CFG_SLEEP_PARAMS
*/
mlan_ds_sleep_params sleep_params;
@ -4177,6 +4194,9 @@ typedef struct _mlan_ds_11ax_rutxpwr_cmd {
/** column,row are 3 for every subband table,however column are 7 for FC
* and 6 for other SOCs */
t_u8 col;
/** row are 3 for every subband table,total row for MAC1 is 12 and MAC2
* id 3 ( consider only 2G support */
t_u8 row;
/**ru tx data */
t_s8 rutxSubPwr[89];
} mlan_ds_11ax_rutxpwr_cmd, *pmlan_ds_11ax_rutxpwr_cmd;
@ -4264,6 +4284,8 @@ typedef struct MLAN_PACK_START _mlan_ds_twt_setup {
t_u16 twt_mantissa;
/** TWT Request Type, 0: REQUEST_TWT, 1: SUGGEST_TWT*/
t_u8 twt_request;
/** TWT link lost timeout threshold */
t_u16 bcnMiss_threshold;
} MLAN_PACK_END mlan_ds_twt_setup, *pmlan_ds_twt_setup;
/** Type definition of mlan_ds_twt_teardown for MLAN_OID_11AX_TWT_CFG */
@ -4415,14 +4437,14 @@ enum _mlan_reg_type {
defined(PCIE9097) || defined(USB9097) || defined(SDIW624) || \
defined(SDAW693) || defined(PCIEAW693) || defined(PCIEIW624) || \
defined(USBIW624) || defined(SD9097) || defined(SD9177) || \
defined(SDIW615) || defined(USBIW615)
defined(SDIW610) || defined(USBIW610)
MLAN_REG_CIU = 8,
#endif
#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || \
defined(PCIE9097) || defined(USB9097) || defined(SDIW624) || \
defined(SDAW693) || defined(PCIEAW693) || defined(PCIEIW624) || \
defined(USBIW624) || defined(SD9097) || defined(SDIW615) || \
defined(USBIW615)
defined(USBIW624) || defined(SD9097) || defined(SDIW610) || \
defined(USBIW610)
MLAN_REG_MAC2 = 0x81,
MLAN_REG_BBP2 = 0x82,
MLAN_REG_RF2 = 0x83,
@ -5659,7 +5681,7 @@ typedef MLAN_PACK_START struct _mlan_ds_misc_tx_rx_histogram {
/** Size of Tx/Rx info */
t_u16 size;
/** Store Tx/Rx info */
t_u8 value[1];
t_u8 value[];
} MLAN_PACK_END mlan_ds_misc_tx_rx_histogram;
#define RX_PKT_INFO MBIT(1)
@ -5917,6 +5939,7 @@ typedef struct _mlan_ds_misc_chan_trpc_cfg {
#define MFG_CMD_CONFIG_MAC_HE_TB_TX 0x110A
#define MFG_CMD_CONFIG_TRIGGER_FRAME 0x110C
#define MFG_CMD_OTP_MAC_ADD 0x108C
#define MFG_CMD_OTP_CAL_DATA 0x121A
/** MFG CMD generic cfg */
struct MLAN_PACK_START mfg_cmd_generic_cfg {
@ -6227,6 +6250,24 @@ typedef MLAN_PACK_START struct _mfg_cmd_otp_mac_addr_rd_wr_t {
t_u8 mac_addr[MLAN_MAC_ADDR_LENGTH];
} MLAN_PACK_END mfg_cmd_otp_mac_addr_rd_wr_t;
#define CAL_DATA_LEN 1400
typedef MLAN_PACK_START struct _mfg_cmd_otp_cal_data_rd_wr_t {
/** MFG command code */
t_u32 mfg_cmd;
/** Action */
t_u16 action;
/** Device ID */
t_u16 device_id;
/** MFG Error code */
t_u32 error;
/** CAL Data write status */
t_u32 cal_data_status;
/** CAL Data Length*/
t_u32 cal_data_len;
/** Destination MAC Address */
t_u8 cal_data[CAL_DATA_LEN];
} MLAN_PACK_END mfg_cmd_otp_cal_data_rd_wr_t;
typedef struct _mlan_ds_misc_chnrgpwr_cfg {
/** length */
t_u16 length;
@ -6244,6 +6285,22 @@ typedef struct _mlan_ds_misc_cfp_tbl {
chan_freq_power_t cfp_tbl[];
} mlan_ds_misc_cfp_tbl;
/** channel attribute */
typedef struct _chan_attr {
/** channel number */
t_u8 channel;
/** channel flags */
t_u8 flags;
} chan_attr_t;
/** channel flags table */
typedef struct _mlan_ds_chan_attr {
/** Data length */
t_u16 data_len;
/** Data */
chan_attr_t chan_attr[MLAN_MAX_CHANNEL_NUM];
} MLAN_PACK_END mlan_ds_chan_attr;
/** mlan_ds_mc_aggr_cfg for MLAN_OID_MISC_MC_AGGR_CFG */
typedef struct _mlan_ds_mc_aggr_cfg {
/** action */
@ -6301,6 +6358,33 @@ typedef struct _mlan_ds_cross_chip_synch {
t_u32 init_tsf_high;
} mlan_ds_cross_chip_synch;
#define MAX_RFUS 2
#define MAX_PATHS 2
typedef struct _mlan_ds_tsp_cfg {
/** TSP config action 0-GET, 1-SET */
t_u16 action;
/** TSP enable/disable tsp algothrim */
t_u16 enable;
/** TSP config power backoff */
t_s32 backoff;
/** TSP config high threshold */
t_s32 high_thrshld;
/** TSP config low threshold */
t_s32 low_thrshld;
/** TSP config DUTY_CYC_STEP */
t_s32 duty_cyc_step;
/** TSP config DUTY_CYC_MIN */
t_s32 duty_cyc_min;
/** TSP config HIGH_THRESHOLD_TEMP */
t_s32 high_thrshld_temp;
/** TSP config LOW_THRESHOLD_TEMP */
t_s32 low_thrshld_temp;
/** TSP CAU TSEN register */
t_s32 reg_cau_val;
/** TSP RFU registers */
t_s32 reg_rfu_temp[MAX_RFUS][MAX_PATHS];
} MLAN_PACK_END mlan_ds_tsp_cfg;
typedef struct _mlan_ds_reorder_flush_time {
/** AC BK/BE_flush time*/
t_u16 flush_time_ac_be_bk;
@ -6322,6 +6406,36 @@ typedef struct _mlan_ds_ed_mac_cfg {
t_u32 ed_bitmap_txq_lock;
} mlan_ds_ed_mac_cfg;
/** valid range for mlan_ds_auth_assoc_timeout_cfg */
#define AUTH_TIMEOUT_MIN 500
#define AUTH_TIMEOUT_MAX 2400
#define AUTH_RETRY_TIMEOUT_ACK_MIN 50
#define AUTH_RETRY_TIMEOUT_ACK_MAX 300
#define AUTH_RETRY_TIMEOUT_NO_ACK_MIN 40
#define AUTH_RETRY_TIMEOUT_NO_ACK_MAX 80
#define ASSOC_TIMEOUT_MIN 200
#define ASSOC_TIMEOUT_MAX 1500
#define REASSOC_TIMEOUT_MIN 100
#define REASSOC_TIMEOUT_MAX 1500
#define ASSOC_RETRY_TIMEOUT_MIN 50
#define ASSOC_RETRY_TIMEOUT_MAX 150
/** Auth Assoc timeout configuration parameters */
typedef struct _mlan_ds_auth_assoc_timeout_cfg {
/** auth timeout */
t_u16 auth_timeout;
/** Auth retry timeout if received ack */
t_u16 auth_retry_timeout_if_ack;
/** Auth retry timeout if ack is not received */
t_u16 auth_retry_timeout_if_no_ack;
/** assoc timeout */
t_u16 assoc_timeout;
/** reassoc timeout */
t_u16 reassoc_timeout;
/** assoc/reassoc frame retry timeout if ack received */
t_u16 retry_timeout;
} mlan_ds_auth_assoc_timeout_cfg;
/** Type definition of mlan_ds_misc_cfg for MLAN_IOCTL_MISC_CFG */
typedef struct _mlan_ds_misc_cfg {
/** Sub-command */
@ -6469,6 +6583,7 @@ typedef struct _mlan_ds_misc_cfg {
mlan_ds_misc_cck_desense_cfg cck_desense_cfg;
mlan_ds_misc_chan_trpc_cfg trpc_cfg;
mlan_ds_misc_chnrgpwr_cfg rgchnpwr_cfg;
mlan_ds_chan_attr chan_attr_cfg;
mlan_ds_band_steer_cfg band_steer_cfg;
mlan_ds_beacon_stuck_param_cfg beacon_stuck_cfg;
@ -6478,6 +6593,7 @@ typedef struct _mlan_ds_misc_cfg {
struct mfg_Cmd_HE_TBTx_t mfg_he_power;
mfg_Cmd_IEEEtypes_CtlBasicTrigHdr_t mfg_tx_trigger_config;
mfg_cmd_otp_mac_addr_rd_wr_t mfg_otp_mac_addr_rd_wr;
mfg_cmd_otp_cal_data_rd_wr_t mfg_otp_cal_data_rd_wr;
mlan_ds_misc_arb_cfg arb_cfg;
mlan_ds_misc_cfp_tbl cfp;
t_u8 range_ext_mode;
@ -6493,12 +6609,32 @@ typedef struct _mlan_ds_misc_cfg {
t_u32 ips_ctrl;
mlan_ds_ch_load ch_load;
mlan_ds_cross_chip_synch cross_chip_synch;
mlan_ds_tsp_cfg tsp_cfg;
mlan_ds_reorder_flush_time flush_time;
mlan_ds_ed_mac_cfg edmac_cfg;
mlan_ds_gpio_cfg_ops gpio_cfg_ops;
mlan_ds_auth_assoc_timeout_cfg auth_assoc_cfg;
} param;
} mlan_ds_misc_cfg, *pmlan_ds_misc_cfg;
typedef struct _mlan_cfpinfo {
t_u8 nss : 2;
t_u8 is2g_present : 1;
t_u8 is5g_present : 1;
t_u8 is6g_present : 1;
t_u8 reserved : 3;
t_u8 rows_2g;
t_u8 cols_2g;
t_u8 rows_5g;
t_u8 cols_5g;
t_u8 rows_6g;
t_u8 cols_6g;
t_u8 region_code;
t_u8 environment;
t_u8 country_code[2];
t_u16 action;
} mlan_cfpinfo;
/** Hotspot status enable */
#define HOTSPOT_ENABLED MBIT(0)
/** Hotspot status disable */

View file

@ -30,6 +30,10 @@
/********************************************************
* Local Variables
********************************************************/
/* frmctl + durationid + addr1 + addr2 + addr3 + seqctl */
#define PACKET_ADDR4_POS (2 + 2 + 6 + 6 + 6 + 2)
/** Supported rates to be advertised to the cfg80211 */
static struct ieee80211_rate cfg80211_rates[] = {
{
@ -82,54 +86,59 @@ static struct ieee80211_rate cfg80211_rates[] = {
},
};
/** Kernel picks the min of the register max power and the regulatory max.
So to register the max chip capability the default max power for all
channels is set to 23 dbm which is the max of the typical max tx pwr out
range among all chips*/
/** Channel definitions for 2 GHz to be advertised to cfg80211 */
static struct ieee80211_channel cfg80211_channels_2ghz[] = {
{.center_freq = 2412, .hw_value = 1, .max_power = 20},
{.center_freq = 2417, .hw_value = 2, .max_power = 20},
{.center_freq = 2422, .hw_value = 3, .max_power = 20},
{.center_freq = 2427, .hw_value = 4, .max_power = 20},
{.center_freq = 2432, .hw_value = 5, .max_power = 20},
{.center_freq = 2437, .hw_value = 6, .max_power = 20},
{.center_freq = 2442, .hw_value = 7, .max_power = 20},
{.center_freq = 2447, .hw_value = 8, .max_power = 20},
{.center_freq = 2452, .hw_value = 9, .max_power = 20},
{.center_freq = 2457, .hw_value = 10, .max_power = 20},
{.center_freq = 2462, .hw_value = 11, .max_power = 20},
{.center_freq = 2467, .hw_value = 12, .max_power = 20},
{.center_freq = 2472, .hw_value = 13, .max_power = 20},
{.center_freq = 2484, .hw_value = 14, .max_power = 20},
{.center_freq = 2412, .hw_value = 1, .max_power = 23},
{.center_freq = 2417, .hw_value = 2, .max_power = 23},
{.center_freq = 2422, .hw_value = 3, .max_power = 23},
{.center_freq = 2427, .hw_value = 4, .max_power = 23},
{.center_freq = 2432, .hw_value = 5, .max_power = 23},
{.center_freq = 2437, .hw_value = 6, .max_power = 23},
{.center_freq = 2442, .hw_value = 7, .max_power = 23},
{.center_freq = 2447, .hw_value = 8, .max_power = 23},
{.center_freq = 2452, .hw_value = 9, .max_power = 23},
{.center_freq = 2457, .hw_value = 10, .max_power = 23},
{.center_freq = 2462, .hw_value = 11, .max_power = 23},
{.center_freq = 2467, .hw_value = 12, .max_power = 23},
{.center_freq = 2472, .hw_value = 13, .max_power = 23},
{.center_freq = 2484, .hw_value = 14, .max_power = 23},
};
/** Channel definitions for 5 GHz to be advertised to cfg80211 */
static struct ieee80211_channel cfg80211_channels_5ghz[] = {
{.center_freq = 5180, .hw_value = 36, .max_power = 20},
{.center_freq = 5200, .hw_value = 40, .max_power = 20},
{.center_freq = 5220, .hw_value = 44, .max_power = 20},
{.center_freq = 5240, .hw_value = 48, .max_power = 20},
{.center_freq = 5260, .hw_value = 52, .max_power = 20},
{.center_freq = 5280, .hw_value = 56, .max_power = 20},
{.center_freq = 5300, .hw_value = 60, .max_power = 20},
{.center_freq = 5320, .hw_value = 64, .max_power = 20},
{.center_freq = 5500, .hw_value = 100, .max_power = 20},
{.center_freq = 5520, .hw_value = 104, .max_power = 20},
{.center_freq = 5540, .hw_value = 108, .max_power = 20},
{.center_freq = 5560, .hw_value = 112, .max_power = 20},
{.center_freq = 5580, .hw_value = 116, .max_power = 20},
{.center_freq = 5600, .hw_value = 120, .max_power = 20},
{.center_freq = 5620, .hw_value = 124, .max_power = 20},
{.center_freq = 5640, .hw_value = 128, .max_power = 20},
{.center_freq = 5660, .hw_value = 132, .max_power = 20},
{.center_freq = 5680, .hw_value = 136, .max_power = 20},
{.center_freq = 5700, .hw_value = 140, .max_power = 20},
{.center_freq = 5720, .hw_value = 144, .max_power = 20},
{.center_freq = 5745, .hw_value = 149, .max_power = 20},
{.center_freq = 5765, .hw_value = 153, .max_power = 20},
{.center_freq = 5785, .hw_value = 157, .max_power = 20},
{.center_freq = 5805, .hw_value = 161, .max_power = 20},
{.center_freq = 5825, .hw_value = 165, .max_power = 20},
{.center_freq = 5845, .hw_value = 169, .max_power = 20},
{.center_freq = 5865, .hw_value = 173, .max_power = 20},
{.center_freq = 5885, .hw_value = 177, .max_power = 20},
{.center_freq = 5180, .hw_value = 36, .max_power = 23},
{.center_freq = 5200, .hw_value = 40, .max_power = 23},
{.center_freq = 5220, .hw_value = 44, .max_power = 23},
{.center_freq = 5240, .hw_value = 48, .max_power = 23},
{.center_freq = 5260, .hw_value = 52, .max_power = 23},
{.center_freq = 5280, .hw_value = 56, .max_power = 23},
{.center_freq = 5300, .hw_value = 60, .max_power = 23},
{.center_freq = 5320, .hw_value = 64, .max_power = 23},
{.center_freq = 5500, .hw_value = 100, .max_power = 23},
{.center_freq = 5520, .hw_value = 104, .max_power = 23},
{.center_freq = 5540, .hw_value = 108, .max_power = 23},
{.center_freq = 5560, .hw_value = 112, .max_power = 23},
{.center_freq = 5580, .hw_value = 116, .max_power = 23},
{.center_freq = 5600, .hw_value = 120, .max_power = 23},
{.center_freq = 5620, .hw_value = 124, .max_power = 23},
{.center_freq = 5640, .hw_value = 128, .max_power = 23},
{.center_freq = 5660, .hw_value = 132, .max_power = 23},
{.center_freq = 5680, .hw_value = 136, .max_power = 23},
{.center_freq = 5700, .hw_value = 140, .max_power = 23},
{.center_freq = 5720, .hw_value = 144, .max_power = 23},
{.center_freq = 5745, .hw_value = 149, .max_power = 23},
{.center_freq = 5765, .hw_value = 153, .max_power = 23},
{.center_freq = 5785, .hw_value = 157, .max_power = 23},
{.center_freq = 5805, .hw_value = 161, .max_power = 23},
{.center_freq = 5825, .hw_value = 165, .max_power = 23},
{.center_freq = 5845, .hw_value = 169, .max_power = 23},
{.center_freq = 5865, .hw_value = 173, .max_power = 23},
{.center_freq = 5885, .hw_value = 177, .max_power = 23},
};
struct ieee80211_supported_band cfg80211_band_2ghz = {
@ -174,6 +183,10 @@ int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg,
#endif
#endif
static t_u8 *woal_remove_11ax_ies(moal_private *priv, t_u8 *ie, t_u8 len,
t_u8 *new_ie_len, t_u32 ie_out_len,
t_u8 *skipped_len);
/**
* @brief Get the private structure from wiphy
*
@ -1137,6 +1150,10 @@ int woal_cfg80211_change_virtual_intf(struct wiphy *wiphy,
mlan_ioctl_req *req = NULL;
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
t_u8 bss_role;
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
moal_private *dfs_priv =
woal_get_priv_bss_type(priv->phandle, MLAN_BSS_TYPE_DFS);
#endif
mlan_status status = MLAN_STATUS_SUCCESS;
@ -1156,6 +1173,22 @@ int woal_cfg80211_change_virtual_intf(struct wiphy *wiphy,
*/
if (priv->wdev->iftype == NL80211_IFTYPE_AP &&
type == NL80211_IFTYPE_STATION) {
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
if (dfs_priv && dfs_priv->radar_background) {
PRINTM(MMSG, "Cancel background radar detection\n");
woal_11h_cancel_chan_report_ioctl(dfs_priv,
MOAL_IOCTL_WAIT);
dfs_priv->chan_rpt_pending = MFALSE;
dfs_priv->radar_background = MFALSE;
woal_update_channels_dfs_state(
dfs_priv, dfs_priv->chan_rpt_req.chanNum,
dfs_priv->chan_rpt_req.bandcfg.chanWidth,
DFS_USABLE);
memset(&dfs_priv->chan_rpt_req, 0,
sizeof(mlan_ds_11h_chan_rep_req));
cfg80211_background_cac_abort(wiphy);
}
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
if (priv->phandle->is_cac_timer_set &&
priv->bss_index == priv->phandle->cac_bss_index) {
@ -2685,6 +2718,10 @@ static int woal_mgmt_tx(moal_private *priv, const u8 *buf, size_t len,
t_u8 tx_seq_num = 0;
mlan_ioctl_req *ioctl_req = NULL;
mlan_ds_misc_cfg *misc = NULL;
t_u8 *new_ie = NULL;
t_u8 new_ie_len = 0;
t_u16 fc, type, stype;
t_u8 skipped_len = 0;
ENTER();
@ -2695,7 +2732,32 @@ static int woal_mgmt_tx(moal_private *priv, const u8 *buf, size_t len,
/* pkt_type + tx_control */
#define HEADER_SIZE 8
packet_len = (t_u16)(len + MLAN_MAC_ADDR_LENGTH);
if (!woal_secure_add(&len, MLAN_MAC_ADDR_LENGTH, &packet_len,
TYPE_UINT16)) {
PRINTM(MERROR, "packet_len is invalid\n");
}
/* Remove 11ax IEs and reduce IE length if band support disabled
* and assoc response includes 11ax IEs
*/
if (chan && ((chan->band == NL80211_BAND_2GHZ &&
!(priv->phandle->fw_bands & BAND_GAX)) ||
(chan->band == NL80211_BAND_5GHZ &&
!(priv->phandle->fw_bands & BAND_AAX)))) {
fc = le16_to_cpu(((struct ieee80211_mgmt *)buf)->frame_control);
type = fc & IEEE80211_FCTL_FTYPE;
stype = fc & IEEE80211_FCTL_STYPE;
if ((type == IEEE80211_FTYPE_MGMT &&
(stype == IEEE80211_STYPE_ASSOC_RESP ||
stype == IEEE80211_STYPE_REASSOC_RESP))) {
new_ie = woal_remove_11ax_ies(priv, (t_u8 *)buf, len,
&new_ie_len, MAX_IE_SIZE,
&skipped_len);
}
}
if (new_ie && skipped_len)
packet_len -= skipped_len;
if (priv->phandle->cmd_tx_data) {
ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
@ -2736,8 +2798,6 @@ static int woal_mgmt_tx(moal_private *priv, const u8 *buf, size_t len,
moal_memcpy_ext(priv->phandle, pbuf + sizeof(pkt_type), &tx_control,
sizeof(tx_control), remain_len);
remain_len -= sizeof(tx_control);
/* frmctl + durationid + addr1 + addr2 + addr3 + seqctl */
#define PACKET_ADDR4_POS (2 + 2 + 6 + 6 + 6 + 2)
pkt_len = woal_cpu_to_le16(packet_len);
moal_memcpy_ext(priv->phandle, pbuf + HEADER_SIZE, &pkt_len,
sizeof(pkt_len), remain_len);
@ -2750,11 +2810,22 @@ static int woal_mgmt_tx(moal_private *priv, const u8 *buf, size_t len,
PACKET_ADDR4_POS,
addr, MLAN_MAC_ADDR_LENGTH, remain_len);
remain_len -= MLAN_MAC_ADDR_LENGTH;
moal_memcpy_ext(priv->phandle,
pbuf + HEADER_SIZE + sizeof(packet_len) +
PACKET_ADDR4_POS + MLAN_MAC_ADDR_LENGTH,
buf + PACKET_ADDR4_POS, len - PACKET_ADDR4_POS,
remain_len);
if (!new_ie_len) {
// coverity[overrun:SUPPRESS]
moal_memcpy_ext(priv->phandle,
pbuf + HEADER_SIZE + sizeof(packet_len) +
PACKET_ADDR4_POS + MLAN_MAC_ADDR_LENGTH,
buf + PACKET_ADDR4_POS, len - PACKET_ADDR4_POS,
remain_len);
} else {
/* new IEs post cleanup of 11ax IEs received from kernel */
// coverity[overrun:SUPPRESS]
moal_memcpy_ext(priv->phandle,
pbuf + HEADER_SIZE + sizeof(packet_len) +
PACKET_ADDR4_POS + MLAN_MAC_ADDR_LENGTH,
new_ie, new_ie_len, remain_len);
}
DBG_HEXDUMP(MDAT_D, "Mgmt Tx", pbuf,
HEADER_SIZE + packet_len + sizeof(packet_len));
@ -2891,6 +2962,9 @@ done:
}
}
if (new_ie)
kfree(new_ie);
LEAVE();
return ret;
}
@ -3461,10 +3535,21 @@ done:
int woal_cfg80211_set_qos_map(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_qos_map *qos_map)
{
moal_private *priv = (moal_private *)woal_get_netdev_priv(dev);
moal_private *priv = NULL;
int i, j, ret = 0;
ENTER();
if (!dev) {
PRINTM(MERROR, "netdev pointer is NULL \n");
ret = -EINVAL;
goto done;
}
priv = (moal_private *)woal_get_netdev_priv(dev);
if (!priv) {
PRINTM(MERROR, "failed to retrieve netdev priv\n");
ret = -EINVAL;
goto done;
}
/**clear dscp map*/
if (!qos_map) {
memset(priv->dscp_map, 0xFF, sizeof(priv->dscp_map));
@ -3501,7 +3586,7 @@ int woal_cfg80211_set_qos_map(struct wiphy *wiphy, struct net_device *dev,
qos_map_ie.ieee_hdr.element_id = QOS_MAPPING;
qos_map_ie.ieee_hdr.len =
2 * qos_map->num_des + sizeof(qos_map->up);
(t_u8)(2 * qos_map->num_des + sizeof(qos_map->up));
qos_map_ies_len =
qos_map_ie.ieee_hdr.len + sizeof(qos_map_ie.ieee_hdr);
@ -3672,6 +3757,145 @@ static t_u8 woal_find_ie(const t_u8 *ie, int len, const t_u8 *spec_ie,
return MFALSE;
}
/*
* @brief search for given IE
*
* @param ie A pointer to IE
* @param ie_len IE length
* @param eid Element id to be searched
* @param ext_eid Element extension id to be searched
*
* @return true - success, false - otherwise
*/
static bool woal_search_ie(t_u8 *ie, t_u8 ie_len, t_u8 eid, t_u8 ext_eid)
{
IEEEtypes_Header_t *pheader = NULL;
t_u8 *pos = NULL;
t_u8 ret_len = 0;
t_u8 ret = false;
t_u8 id = 0;
ENTER();
pos = (t_u8 *)ie;
ret_len = ie_len;
while (ret_len >= 2) {
pheader = (IEEEtypes_Header_t *)pos;
if ((t_u8)(pheader->len + sizeof(IEEEtypes_Header_t)) >
ret_len) {
PRINTM(MMSG, "invalid IE length = %d left len %d\n",
pheader->len, ret_len);
break;
}
if (ext_eid && pheader->element_id == ext_eid) {
id = *(pos + 2);
if (id == eid) {
ret = true;
break;
}
} else if (pheader->element_id == eid) {
ret = true;
break;
}
ret_len -= pheader->len + sizeof(IEEEtypes_Header_t);
pos += pheader->len + sizeof(IEEEtypes_Header_t);
}
LEAVE();
return ret;
}
/*
* @brief remove 11ax IEs if band support is disabled
*
* @param priv A pointer moal_private structure
* @param buf Frame buffer
* @param len Frame length
* @param new_ie A pointer to newly generated IE
* @param new_ie_len Length of newly generated IE
* @param skipped_len Length of IEs removed
*
* @return new ie buffer - success, NULL - otherwise
*/
static t_u8 *woal_remove_11ax_ies(moal_private *priv, t_u8 *ie, t_u8 len,
t_u8 *new_ie_len, t_u32 ie_out_len,
t_u8 *skipped_len)
{
int left_len = 0;
const t_u8 *pos = NULL;
int length = 0;
t_u8 id = 0;
t_u8 ext_id = 0;
t_u8 *new_ie = NULL;
t_u8 min_ie_len = PACKET_ADDR4_POS + sizeof(IEEEtypes_CapInfo_t) +
sizeof(IEEEtypes_StatusCode_t) +
sizeof(IEEEtypes_AId_t);
/* search for 11ax IE in IE buffer */
if (!woal_search_ie(ie + min_ie_len, len - min_ie_len, HE_CAPABILITY,
EXTENSION) &&
!woal_search_ie(ie + min_ie_len, len - min_ie_len, HE_OPERATION,
EXTENSION))
return NULL;
new_ie = kzalloc(len, GFP_KERNEL);
if (!new_ie) {
PRINTM(MERROR, "Failed to allocate memory for New IE\n");
return NULL;
}
/* copy fixed parameters of assoc response */
moal_memcpy_ext(priv->phandle, new_ie, ie + PACKET_ADDR4_POS,
sizeof(IEEEtypes_AssocRsp_t),
sizeof(IEEEtypes_AssocRsp_t));
*new_ie_len += sizeof(IEEEtypes_AssocRsp_t);
pos = ie + min_ie_len;
left_len = len - min_ie_len;
/* HE IE will be fileter out */
while (left_len >= 2) {
length = *(pos + 1);
id = *pos;
/* length exceeds remaining IE length */
if ((length + 2) > left_len)
break;
switch (id) {
case EXTENSION:
ext_id = *(pos + 2);
if (ext_id == HE_CAPABILITY || ext_id == HE_OPERATION ||
ext_id == HE_6G_CAPABILITY) {
*skipped_len +=
length + sizeof(IEEEtypes_Header_t);
break;
}
// fall through
default:
if ((*new_ie_len + length + 2) < (int)ie_out_len) {
moal_memcpy_ext(priv->phandle,
new_ie + *new_ie_len, pos,
length + 2,
ie_out_len - *new_ie_len);
*new_ie_len += length + 2;
} else {
PRINTM(MERROR,
"IE len exceeds, failed to copy %d IE\n",
id);
}
break;
}
pos += (length + 2);
left_len -= (length + 2);
}
return new_ie;
}
/**
* @brief Filter specific IE in ie buf
*
@ -3761,6 +3985,11 @@ static t_u16 woal_filter_beacon_ies(moal_private *priv, const t_u8 *ie,
case WAPI_IE:
break;
case EXTENSION:
/* skip 11ax, 6G if bands are not enabled */
if (!(priv->phandle->fw_bands & BAND_GAX) ||
!(priv->phandle->fw_bands & BAND_AAX))
break;
ext_id = *(pos + 2);
if ((ext_id == HE_CAPABILITY || ext_id == HE_OPERATION)
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
@ -3898,8 +4127,7 @@ static t_u16 woal_filter_beacon_ies(moal_private *priv, const t_u8 *ie,
}
break;
case REGULATORY_CLASS:
break;
// fall thru to default to add IE
/* FALLTHRU */
default:
if ((out_len + length + 2) < (int)ie_out_len) {
moal_memcpy_ext(priv->phandle, ie_out + out_len,
@ -4729,8 +4957,12 @@ Note: bits not mentioned below are set to 0.
===
HE MAC Cap:
Bit0: 1 (+HTC HE Support)
Bit1: 1 (TWT requester support)
Bit2: 1 (TWT responder support)
Bit20: 1 (Broadcast TWT support)
Bit25: 1 (OM Control Support. But uAP does not support
Tx OM received from the STA, as it does not support UL OFDMA)
Bit28-27: Max. A-MPDU Length Exponent Extension
HE PHY Cap:
Bit1-7: 0x2 (Supported Channel Width Set.
@ -4761,7 +4993,7 @@ Bit75: 0x1 (Rx 1024-QAM Support < 242-tone RU)
#define UAP_HE_MAC_CAP0_MASK 0x06
#define UAP_HE_MAC_CAP1_MASK 0x00
#define UAP_HE_MAC_CAP2_MASK 0x10
#define UAP_HE_MAC_CAP3_MASK 0x02
#define UAP_HE_MAC_CAP3_MASK 0x1a
#define UAP_HE_MAC_CAP4_MASK 0x00
#define UAP_HE_MAC_CAP5_MASK 0x00
#define UAP_HE_PHY_CAP0_MASK 0x04
@ -4781,8 +5013,12 @@ Bit75: 0x1 (Rx 1024-QAM Support < 242-tone RU)
===
HE MAC Cap:
Bit0: 1 (+HTC HE Support)
Bit1: 1 (TWT requester support)
Bit2: 1 (TWT responder support)
Bit20: 1 (Broadcast TWT support)
Bit25: 1 (OM Control Support. Note: uAP does not support
Tx OM received from the STA, as it does not support UL OFDMA)
Bit28-27: Max. A-MPDU Length Exponent Extension
HE PHY Cap:
Bit1-7: 0x1 (Supported Channel Width Set)
@ -4807,10 +5043,10 @@ Bit58: 0x1 (HE SU PPDU and HE MU PPDU with 4xHE-LTF+0.8usGI)
Bit59-61: 0x1 (Max Nc)
Bit75: 0x1 (Rx 1024-QAM Support < 242-tone RU)
*/
#define UAP_HE_2G_MAC_CAP0_MASK 0x00
#define UAP_HE_2G_MAC_CAP0_MASK 0x06
#define UAP_HE_2G_MAC_CAP1_MASK 0x00
#define UAP_HE_2G_MAC_CAP2_MASK 0x00
#define UAP_HE_2G_MAC_CAP3_MASK 0x02
#define UAP_HE_2G_MAC_CAP2_MASK 0x10
#define UAP_HE_2G_MAC_CAP3_MASK 0x1a
#define UAP_HE_2G_MAC_CAP4_MASK 0x00
#define UAP_HE_2G_MAC_CAP5_MASK 0x00
#define UAP_HE_2G_PHY_CAP0_MASK 0x02
@ -4892,16 +5128,17 @@ void woal_cfg80211_setup_he_cap(moal_private *priv,
t_u8 extra_mcs_size = 0;
int ppe_threshold_len = 0;
mlan_ds_11ax_he_capa *phe_cap = NULL;
t_u8 hw_hecap_len;
t_u8 hw_hecap_len = 0;
memset(&fw_info, 0, sizeof(mlan_fw_info));
woal_request_get_fw_info(priv, MOAL_IOCTL_WAIT, &fw_info);
if (band->band == NL80211_BAND_5GHZ) {
if (band->band == NL80211_BAND_5GHZ && fw_info.fw_bands & BAND_AAX) {
phe_cap = (mlan_ds_11ax_he_capa *)fw_info.hw_he_cap;
hw_hecap_len = fw_info.hw_hecap_len;
woal_uap_update_11ax_ie(BAND_5GHZ, phe_cap);
} else {
} else if (band->band == NL80211_BAND_2GHZ &&
fw_info.fw_bands & BAND_GAX) {
phe_cap = (mlan_ds_11ax_he_capa *)fw_info.hw_2g_he_cap;
hw_hecap_len = fw_info.hw_2g_hecap_len;
woal_uap_update_11ax_ie(BAND_2GHZ, phe_cap);

View file

@ -110,6 +110,8 @@ void woal_host_mlme_disconnect(pmoal_private priv, u16 reason_code, u8 *sa);
void woal_host_mlme_work_queue(struct work_struct *work);
void woal_host_mlme_process_assoc_resp(moal_private *priv,
mlan_ds_assoc_info *assoc_info);
void woal_host_mlme_process_assoc_timeout(moal_private *priv,
struct cfg80211_bss *bss);
#endif
#endif

View file

@ -2890,6 +2890,659 @@ int woal_deinit_wifi_hal(moal_private *priv)
return 0;
}
/**
* @brief Prints the scancfg params from the mlan_ds_scan struct
*
* @param scan A pointer to mlan_ds_scan struct
*
* @return void
*/
static void woal_print_scancfg_params(mlan_ds_scan *scan)
{
if (!scan)
return;
PRINTM(MCMND,
"scancfg params: scan_type = 0x%x, scan_mode = 0x%x, scan_probe = 0x%x \n",
scan->param.scan_cfg.scan_type, scan->param.scan_cfg.scan_mode,
scan->param.scan_cfg.scan_probe);
PRINTM(MCMND, "scancfg params: passive_to_active_scan = 0x%x \n",
scan->param.scan_cfg.passive_to_active_scan);
PRINTM(MCMND,
"scancfg params: specific_scan_time = 0x%x, active_scan_time = 0x%x, passive_scan_time = 0x%x \n",
scan->param.scan_cfg.scan_time.specific_scan_time,
scan->param.scan_cfg.scan_time.active_scan_time,
scan->param.scan_cfg.scan_time.passive_scan_time);
PRINTM(MCMND, "scancfg params: ext_scan = 0x%x\n",
scan->param.scan_cfg.ext_scan);
PRINTM(MCMND, "scancfg params: scan_chan_gap = 0x%x\n",
scan->param.scan_cfg.scan_chan_gap);
}
/**
* @brief Parse the vendor cmd input data based on attribute len
* and copy each attrubute into a output buffer/integer array
*
* @param data A pointer to input data buffer
* @param data_len Input data buffer total len
* @param user_buff A pointer to output data buffer after the
* parsing
* @param buff_len Maximum no. of data attributes to be parsed
* @param user_data_len No. of data attributes that are parsed
*
* @return 0: success -1: fail
*/
static int woal_parse_vendor_cmd_attributes(t_u8 *data, t_u32 data_len,
t_u32 *user_buff, t_u32 buff_len,
t_u16 *user_data_len)
{
t_u16 i = 0, j = 0, len = 0;
len = strlen(data);
for (i = 0, j = 0; (i < data_len) && (j < buff_len); ++j) {
t_u32 value = 0, value1 = 0;
t_u8 attr_len = 0;
attr_len = (t_u8) * (data + i);
++i;
if (attr_len > 0) {
t_u8 k = 0;
for (k = 0; k < attr_len; ++k) {
value1 = (t_u8) * (data + i + k);
value = (value << 8) + value1;
}
i = i + k;
} else {
PRINTM(MERROR, "\nIn parse_args: Invalid attr_len \n");
*user_data_len = 0;
return -1;
}
user_buff[j] = value;
}
*user_data_len = j;
return 0;
}
/**
* @brief Vendor cmd to trigger the scancfg params.
* Set/Get the scancfg params to/from driver
*
* @param wiphy A pointer to wiphy struct
* @param wdev A pointer to wireless_dev struct
* @param data a pointer to data
* @param len data length
*
* @return 0: success -1: fail
*/
static int woal_cfg80211_subcmd_set_get_scancfg(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data, int len)
{
struct net_device *dev = wdev->netdev;
moal_private *priv = (moal_private *)woal_get_netdev_priv(dev);
mlan_ds_scan *scan = NULL;
mlan_ioctl_req *req = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
struct sk_buff *skb = NULL;
t_s32 user_data[9];
t_s32 ret = 0;
t_u16 user_data_len = 0;
t_u16 ret_length = 1;
t_u8 get_data = 0, get_val = 0;
t_u8 *data_buff = (t_u8 *)data;
t_u8 *pos = NULL;
ENTER();
if (len < 1) {
PRINTM(MERROR, "vendor cmd: scancfg - Invalid data length!\n");
ret = -EINVAL;
goto done;
}
if (len == 1) {
PRINTM(MMSG, "vendor cmd: Get scancfg params!\n");
get_val = (t_u8) * (data_buff);
/* Get scancfg works if an input argument passed is 00 */
if (get_val) {
PRINTM(MERROR,
"vendor cmd: Get scancfg failed due to Invalid argument!\n");
ret = -EINVAL;
goto done;
}
get_data = 1;
} else if (len > 1) {
PRINTM(MMSG, "Vendor cmd: Set scancfg params!\n");
memset((char *)user_data, 0, sizeof(user_data));
/* vendor cmd : the user_data_len is set only for set cmd */
if (woal_parse_vendor_cmd_attributes(data_buff, len, user_data,
ARRAY_SIZE(user_data),
&user_data_len)) {
PRINTM(MMSG,
"vendor cmd: Couldn't parse the scancfg params!\n");
ret = -EINVAL;
goto done;
}
}
/* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
if (req == NULL) {
PRINTM(MERROR,
"vendor cmd: Could not allocate mlan ioctl request, scancfg!\n");
ret = -ENOMEM;
goto done;
}
/* Fill request buffer */
scan = (mlan_ds_scan *)req->pbuf;
scan->sub_command = MLAN_OID_SCAN_CONFIG;
req->req_id = MLAN_IOCTL_SCAN;
/* Validate each scancfg parameters */
if (user_data_len) {
DBG_HEXDUMP(MCMD_D, "scancfg input dump: ", (t_u8 *)user_data,
(user_data_len * sizeof(t_u32)));
moal_memcpy_ext(priv->phandle, &scan->param.scan_cfg, user_data,
sizeof(user_data),
sizeof(scan->param.scan_cfg));
if (scan->param.scan_cfg.scan_type > MLAN_SCAN_TYPE_PASSIVE) {
PRINTM(MERROR,
"vendor cmd:Invalid argument for scan type\n");
ret = -EINVAL;
goto done;
}
if (scan->param.scan_cfg.scan_mode > MLAN_SCAN_MODE_ANY) {
PRINTM(MERROR,
"vendor cmd:Invalid argument for scan mode\n");
ret = -EINVAL;
goto done;
}
if (scan->param.scan_cfg.scan_probe > MAX_PROBES) {
PRINTM(MERROR,
"vendor cmd:Invalid argument for scan probes\n");
ret = -EINVAL;
goto done;
}
if ((scan->param.scan_cfg.scan_time.specific_scan_time >
MRVDRV_MAX_ACTIVE_SCAN_CHAN_TIME) ||
(scan->param.scan_cfg.scan_time.active_scan_time >
MRVDRV_MAX_ACTIVE_SCAN_CHAN_TIME) ||
(scan->param.scan_cfg.scan_time.passive_scan_time >
MRVDRV_MAX_PASSIVE_SCAN_CHAN_TIME)) {
PRINTM(MERROR, "Invalid argument for scan time\n");
ret = -EINVAL;
goto done;
}
if (scan->param.scan_cfg.passive_to_active_scan >
MLAN_PASS_TO_ACT_SCAN_DIS) {
PRINTM(MERROR,
"Invalid argument for Passive to Active Scan\n");
ret = -EINVAL;
goto done;
}
if (scan->param.scan_cfg.ext_scan > MLAN_EXT_SCAN_ENH) {
PRINTM(MERROR, "Invalid argument for extended scan\n");
ret = -EINVAL;
goto done;
}
if (scan->param.scan_cfg.scan_chan_gap >
MRVDRV_MAX_SCAN_CHAN_GAP_TIME) {
PRINTM(MERROR,
"Invalid argument for scan channel gap\n");
ret = -EINVAL;
goto done;
}
req->action = MLAN_ACT_SET;
if (scan->param.scan_cfg.scan_time.specific_scan_time)
priv->phandle->user_scan_cfg = MTRUE;
PRINTM(MINFO, "vendor cmd: SET ioctl request for scanfg\n");
woal_print_scancfg_params(scan);
} else {
PRINTM(MINFO, "vendor cmd: GET ioctl request for scanfg\n");
req->action = MLAN_ACT_GET;
}
/* Send IOCTL request to MLAN */
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status == MLAN_STATUS_SUCCESS) {
PRINTM(MMSG, "Set/Get scancfg ioctl successfull\n");
if (!user_data_len) {
moal_memcpy_ext(priv->phandle, user_data,
&scan->param.scan_cfg,
sizeof(scan->param.scan_cfg),
sizeof(user_data));
DBG_HEXDUMP(MCMD_D, "scancfg dump: ", (t_u8 *)user_data,
sizeof(user_data));
ret_length = sizeof(mlan_scan_cfg);
}
} else {
PRINTM(MERROR, "Set/Get scancfg ioctl failed!\n");
ret = -EFAULT;
goto done;
}
/* Allocate skb for cmd reply*/
skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, ret_length);
if (!skb) {
PRINTM(MERROR,
"vendor cmd: allocate memory fail for vendor cmd\n");
ret = -ENOMEM;
goto done;
}
/* Get scancfg if an input argument passed is 00 */
if (!user_data_len && get_data == 1) {
PRINTM(MINFO, "vendor cmd: copying the response into buffer\n");
scan = (mlan_ds_scan *)req->pbuf;
pos = skb_put(skb, sizeof(mlan_scan_cfg));
moal_memcpy_ext(priv->phandle, pos, &scan->param.scan_cfg,
sizeof(mlan_scan_cfg), sizeof(mlan_scan_cfg));
woal_print_scancfg_params(scan);
}
ret = cfg80211_vendor_cmd_reply(skb);
if (unlikely(ret))
PRINTM(MERROR, "vendor cmd: reply failed with ret:%d \n", ret);
done:
if (status != MLAN_STATUS_PENDING && req)
kfree(req);
LEAVE();
return ret;
}
/*
* @brief A common function copies an user data(from integer array) into
* different types of structures. Declare a layout based on each member size of
* a strucure within the caller().
*
* @param phandle A pointer to moal handler
* @param dest_struct Final destination strucuture
* @param src_data A pointer to input user data/integer array
* @param src_data_len Input user data length
* @param dest_struct_len Destination data structure length
* @param layout A pointer to integer array/layout describing struct
* member
* *
* @return 0: success -1: fail
* */
static void
woal_memcpy_user_intarray_to_struct(moal_handle *phandle, void *dest_struct,
t_u32 *src_data, t_u32 src_data_len,
t_u32 dest_struct_len, t_u32 *layout)
{
t_u8 *dest = (t_u8 *)dest_struct;
t_u16 i = 0;
if (!dest_struct || !src_data) {
PRINTM(MERROR, "dest/src pointer is null\n");
}
for (i = 0; (layout[i] > 0 && i < src_data_len); ++i) {
moal_memcpy_ext(phandle, dest, src_data, layout[i], layout[i]);
dest += layout[i];
if (layout[i] > sizeof(t_u32)) {
src_data += layout[i] / sizeof(t_u32);
src_data += (layout[i] % sizeof(t_u32)) ? 1 : 0;
} else
src_data += 1;
}
}
/*
* @brief A common function directly copies different type of structures into
* user data buffer(integere array). Declare a layout based on each member size
* of a strucure within the caller function.
*
* @param phandle A pointer to moal handler
* @param dest_data A pointer to destination data buffer/integer
* array
* @param src_struct A pointer to source structure
* @param src_struct_len Source data structure length
* @param dest_data_len Destination user data length
* @param layout A pointer to integer array/layout describing struct
* member
* *
* @return 0: success -1: fail
* */
static void
woal_memcpy_struct_to_user_intarray(moal_handle *phandle, t_u32 *dest_data,
void *src_struct, t_u32 src_struct_len,
t_u32 dest_data_len, t_u32 *layout)
{
t_u8 *src = (t_u8 *)src_struct;
t_u16 i = 0;
if (!dest_data || !src_struct) {
PRINTM(MERROR, "dest/src pointer is null\n");
}
for (i = 0; (layout[i] > 0 && i < dest_data_len); ++i) {
moal_memcpy_ext(phandle, dest_data, src, layout[i], layout[i]);
src += layout[i];
if (layout[i] > sizeof(t_u32)) {
dest_data += layout[i] / sizeof(t_u32);
dest_data += (layout[i] % sizeof(t_u32)) ? 1 : 0;
} else
dest_data += 1;
}
}
/**
* @brief Prints the addba params from the woal_print_addba_param
*
* @param scan A pointer to woal_print_addba_param struct
*
* @return void
*/
static void woal_print_addba_params(mlan_ds_11n_addba_param *addba)
{
if (!addba) {
PRINTM(MERROR, "addba param is null\n");
return;
}
PRINTM(MCMND,
"ADDBA: timeout:%d txwinsize:%d rxwinsize:%d txamsdu=%d, rxamsdu=%d\n",
addba->timeout, addba->txwinsize, addba->rxwinsize,
addba->txamsdu, addba->rxamsdu);
return;
}
/**
* @brief API to trigger the addba params.
* It sets or gets the addba params
*
* @param wiphy A pointer to wiphy struct
* @param wdev A pointer to wireless_dev struct
* @param data a pointer to data
* @param len data length
*
* @return 0: success -1: fail
*/
static int woal_cfg80211_subcmd_set_get_addbaparams(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data, int len)
{
struct net_device *dev = wdev->netdev;
moal_private *priv = (moal_private *)woal_get_netdev_priv(dev);
mlan_ds_11n_cfg *cfg_addba = NULL;
mlan_ioctl_req *req = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
struct sk_buff *skb = NULL;
t_u32 user_data[5];
/* Define layout as per required structure */
t_u32 layout[5] = {sizeof(t_u32), sizeof(t_u32), sizeof(t_u32),
sizeof(char), sizeof(char)};
t_s32 ret = 0;
t_u16 user_data_len = 0;
t_u16 ret_length = 1;
t_u8 get_data = 0, get_val = 0;
t_u8 *data_buff = (t_u8 *)data;
t_u8 *pos = NULL;
ENTER();
if (len < 1) {
PRINTM(MERROR,
"vendor cmd: addbaparams - Invalid data length!\n");
ret = -EINVAL;
goto done;
}
if (len == 1) {
PRINTM(MMSG, "vendor cmd: Get addbaparams!\n");
get_val = (t_u8) * (data_buff);
/* Get addbaparams works if an input argument passed is 00 */
if (get_val) {
PRINTM(MERROR,
"vendor cmd: Get addbaparams failed due to Invalid argument!\n");
ret = -EINVAL;
goto done;
}
get_data = 1;
memset((char *)user_data, 0, sizeof(user_data));
} else if (len > 1) {
PRINTM(MMSG, "Vendor cmd: Set addbaparams !\n");
memset((char *)user_data, 0, sizeof(user_data));
/* vendor cmd : the user_data_len is set only for set cmd */
if (woal_parse_vendor_cmd_attributes(data_buff, len, user_data,
ARRAY_SIZE(user_data),
&user_data_len)) {
PRINTM(MERROR,
"vendor cmd: Couldn't parse the addbaparams!\n");
ret = -EINVAL;
goto done;
}
}
/* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
if (req == NULL) {
PRINTM(MERROR,
"vendor cmd: Could not allocate mlan ioctl request, addbaparams!\n");
ret = -ENOMEM;
goto done;
}
/* Fill request buffer */
cfg_addba = (mlan_ds_11n_cfg *)req->pbuf;
cfg_addba->sub_command = MLAN_OID_11N_CFG_ADDBA_PARAM;
req->req_id = MLAN_IOCTL_11N_CFG;
/* Validate each addbaparams parameters */
if (user_data_len) {
DBG_HEXDUMP(MCMD_D,
"addbaparams input dump: ", (t_u8 *)user_data,
(user_data_len * sizeof(t_u32)));
/* To copy an user data in an integer array format into strcture
*/
woal_memcpy_user_intarray_to_struct(
priv->phandle, (void *)&cfg_addba->param.addba_param,
user_data, ARRAY_SIZE(user_data),
sizeof(cfg_addba->param.addba_param), layout);
woal_print_addba_params(&cfg_addba->param.addba_param);
if (cfg_addba->param.addba_param.timeout >
MLAN_DEFAULT_BLOCK_ACK_TIMEOUT) {
PRINTM(MERROR, "Incorrect addba timeout value.\n");
ret = -EINVAL;
goto done;
}
if (cfg_addba->param.addba_param.txwinsize >
MLAN_AMPDU_MAX_TXWINSIZE) {
PRINTM(MERROR, "Incorrect Tx window size.\n");
ret = -EINVAL;
goto done;
}
if (cfg_addba->param.addba_param.rxwinsize >
MLAN_AMPDU_MAX_RXWINSIZE) {
PRINTM(MERROR, "Incorrect Rx window size.\n");
ret = -EINVAL;
goto done;
}
if (cfg_addba->param.addba_param.txamsdu > 1 ||
cfg_addba->param.addba_param.rxamsdu > 1) {
PRINTM(MERROR, "Incorrect Tx/Rx amsdu.\n");
ret = -EINVAL;
goto done;
}
req->action = MLAN_ACT_SET;
PRINTM(MINFO,
"vendor cmd: SET ioctl request for addbaparams\n");
} else {
PRINTM(MINFO,
"vendor cmd: GET ioctl request for addbaparams\n");
req->action = MLAN_ACT_GET;
}
/* Send IOCTL request to MLAN */
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status == MLAN_STATUS_SUCCESS) {
PRINTM(MMSG, "Set/Get addbaparams ioctl successfull\n");
if (!user_data_len) {
/* To copy an strcture members into user data/integer
* array separately */
woal_memcpy_struct_to_user_intarray(
priv->phandle, user_data,
(void *)&cfg_addba->param.addba_param,
sizeof(cfg_addba->param.addba_param),
ARRAY_SIZE(user_data), layout);
woal_print_addba_params(&cfg_addba->param.addba_param);
ret_length = sizeof(user_data);
}
} else {
PRINTM(MERROR, "Set/Get addbaparams ioctl failed!\n");
ret = -EFAULT;
goto done;
}
/* Allocate skb for cmd reply*/
skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, ret_length);
if (!skb) {
PRINTM(MERROR,
"vendor cmd: allocate memory fail for vendor cmd\n");
ret = -ENOMEM;
goto done;
}
/* Get addbaparams if an input data argument is 00 */
if (!user_data_len && get_data == 1) {
PRINTM(MINFO, "vendor cmd: copying the response into buffer\n");
DBG_HEXDUMP(MCMD_D, "addbaparams dump: ", (t_u8 *)user_data,
sizeof(user_data));
cfg_addba = (mlan_ds_11n_cfg *)req->pbuf;
pos = skb_put(skb, sizeof(user_data));
moal_memcpy_ext(priv->phandle, pos, user_data,
sizeof(user_data), sizeof(user_data));
}
ret = cfg80211_vendor_cmd_reply(skb);
if (unlikely(ret))
PRINTM(MERROR, "vendor cmd: reply failed with ret:%d \n", ret);
done:
if (status != MLAN_STATUS_PENDING && req)
kfree(req);
LEAVE();
return ret;
}
/**
* @brief API to trigger the vendor cmd related to
* hostcmd/sys_cfg_80211d_country_ie. It sets/get/clear the function/operation
* that is specific the hostcmd.
*
* @param wiphy A pointer to wiphy struct
* @param wdev A pointer to wireless_dev struct
* @param data a pointer to data
* @param len data length
*
* @return 0: success -1: fail
*/
static int woal_cfg80211_subcmd_hostcmd(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data, int len)
{
struct net_device *dev = wdev->netdev;
moal_private *priv = (moal_private *)woal_get_netdev_priv(dev);
mlan_ds_misc_cfg *misc_cfg = NULL;
mlan_ioctl_req *req = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
struct sk_buff *skb = NULL;
HostCmd_DS_GEN cmd_info;
t_s32 ret = 0;
t_u16 ret_length = 1;
t_u16 action = 0;
t_u8 get_data = 0;
t_u8 *data_buff = (t_u8 *)data;
t_u8 *pos = NULL;
ENTER();
if (len < (sizeof(HostCmd_DS_GEN) + sizeof(action))) {
PRINTM(MERROR, "vendor cmd: Invalid hostcmd!\n");
ret = -EINVAL;
goto done;
}
moal_memcpy_ext(priv->phandle, &cmd_info, data_buff,
sizeof(HostCmd_DS_GEN), sizeof(HostCmd_DS_GEN));
action = (u16) * (data_buff + sizeof(cmd_info));
PRINTM(MMSG, "vendor cmd: hostcmd len=%d, action=%d\n", len, action);
if (action == 0)
get_data = 1;
/* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
PRINTM(MERROR,
"vendor cmd: Could not allocate mlan ioctl memory, hostcmd!\n");
ret = -ENOMEM;
goto done;
}
/* Fill request buffer */
misc_cfg = (mlan_ds_misc_cfg *)req->pbuf;
misc_cfg->sub_command = MLAN_OID_MISC_HOST_CMD;
req->req_id = MLAN_IOCTL_MISC_CFG;
req->action = action;
misc_cfg->param.hostcmd.len = woal_le16_to_cpu(cmd_info.size);
/* Copy the entire command data into hostcmd cmd buffer */
moal_memcpy_ext(priv->phandle, misc_cfg->param.hostcmd.cmd, data_buff,
misc_cfg->param.hostcmd.len, MRVDRV_SIZE_OF_CMD_BUFFER);
DBG_HEXDUMP(MCMD_D, "vendor cmd: hostcmd cmd dump",
(t_u8 *)misc_cfg->param.hostcmd.cmd,
misc_cfg->param.hostcmd.len);
/* Send IOCTL request to MLAN */
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status == MLAN_STATUS_SUCCESS) {
PRINTM(MMSG, "Set/Clear/Get hostcmd ioctl successfull\n");
if (get_data) {
ret_length = misc_cfg->param.hostcmd.len;
PRINTM(MMSG, "vendor cmd: hostcmd GET, len=%d\n",
ret_length);
}
} else {
PRINTM(MERROR, "Set/Clear/Get hostcmd ioctl failed!\n");
ret = -EFAULT;
goto done;
}
/* Allocate skb for cmd reply*/
skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, ret_length);
if (!skb) {
PRINTM(MERROR, "vendor cmd: memory allocation failed \n");
ret = -ENOMEM;
goto done;
}
if (get_data && ret_length > 1) {
PRINTM(MINFO, "vendor cmd: copying the response into buffer\n");
DBG_HEXDUMP(MCMD_D, "vendor cmd: hostcmd dump",
(t_u8 *)misc_cfg->param.hostcmd.cmd, ret_length);
pos = skb_put(skb, ret_length);
moal_memcpy_ext(priv->phandle, pos, misc_cfg->param.hostcmd.cmd,
misc_cfg->param.hostcmd.len,
misc_cfg->param.hostcmd.len);
}
ret = cfg80211_vendor_cmd_reply(skb);
if (unlikely(ret))
PRINTM(MERROR, "vendor cmd: reply failed with ret:%d \n", ret);
done:
if (status != MLAN_STATUS_PENDING && req)
kfree(req);
LEAVE();
return ret;
}
/**
* @brief vendor command to get link layer statistic
*
@ -5679,6 +6332,42 @@ static const struct wiphy_vendor_command vendor_commands[] = {
#if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE
.policy = woal_attr_policy,
.maxattr = ATTR_WIFI_MAX,
#endif
},
{
.info = {
.vendor_id = MRVL_VENDOR_ID,
.subcmd = SUBCMD_SET_GET_SCANCFG,
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = woal_cfg80211_subcmd_set_get_scancfg,
#if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE
.policy = VENDOR_CMD_RAW_DATA,
#endif
},
{
.info = {
.vendor_id = MRVL_VENDOR_ID,
.subcmd = SUBCMD_SET_GET_ADDBAPARAMS,
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = woal_cfg80211_subcmd_set_get_addbaparams,
#if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE
.policy = VENDOR_CMD_RAW_DATA,
#endif
},
{
.info = {
.vendor_id = MRVL_VENDOR_ID,
.subcmd = SUBCMD_SET_GET_CLR_HOSTCMD,
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = woal_cfg80211_subcmd_hostcmd,
#if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE
.policy = VENDOR_CMD_RAW_DATA,
#endif
},
{

View file

@ -736,6 +736,9 @@ enum vendor_sub_command {
sub_cmd_set_packet_filter = 0x0011,
sub_cmd_get_packet_filter_capability,
sub_cmd_nd_offload = 0x0100,
SUBCMD_SET_GET_SCANCFG = 0x0200,
SUBCMD_SET_GET_ADDBAPARAMS = 0x0201,
SUBCMD_SET_GET_CLR_HOSTCMD = 0x0202,
SUBCMD_RTT_GET_CAPA = 0x1100,
SUBCMD_RTT_RANGE_REQUEST,
SUBCMD_RTT_RANGE_CANCEL,

View file

@ -69,15 +69,16 @@ Change log:
/** Bands supported in Infra mode */
static t_u16 SupportedInfraBand[] = {
BAND_B,
BAND_B | BAND_G,
BAND_G,
BAND_GN,
BAND_B | BAND_G | BAND_GN,
BAND_B | BAND_G,
BAND_G | BAND_GN,
BAND_B | BAND_GN,
BAND_B | BAND_G | BAND_GN,
BAND_A,
BAND_B | BAND_A,
BAND_B | BAND_G | BAND_A,
BAND_G | BAND_A,
BAND_B | BAND_G | BAND_A,
BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN,
BAND_A | BAND_G | BAND_AN | BAND_GN,
BAND_A | BAND_AN,
@ -85,6 +86,7 @@ static t_u16 SupportedInfraBand[] = {
BAND_B | BAND_G | BAND_GN | BAND_GAC,
BAND_G | BAND_GN | BAND_GAC,
BAND_GN | BAND_GAC | BAND_GAX,
BAND_GN | BAND_GAX,
BAND_B | BAND_G | BAND_GN | BAND_GAC | BAND_GAX,
BAND_G | BAND_GN | BAND_GAC | BAND_GAX,
BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN | BAND_AAC,
@ -92,10 +94,17 @@ static t_u16 SupportedInfraBand[] = {
BAND_A | BAND_G | BAND_AN | BAND_GN | BAND_AAC,
BAND_A | BAND_AN | BAND_AAC,
BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN | BAND_AAC | BAND_AAX,
BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN | BAND_AAC | BAND_AAX |
BAND_GAX,
BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN | BAND_AAC | BAND_GAC |
BAND_AAX,
BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN | BAND_AAC | BAND_GAC |
BAND_AAX | BAND_GAX,
BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN | BAND_AAC | BAND_GAC |
BAND_GAX,
BAND_A | BAND_G | BAND_AN | BAND_GN | BAND_AAC | BAND_AAX,
BAND_A | BAND_AN | BAND_AAC | BAND_AAX,
BAND_B | BAND_G | BAND_GN | BAND_GAX,
};
/********************************************************
@ -156,6 +165,7 @@ mlan_status parse_arguments(t_u8 *pos, int *data, int datalen,
} else {
if (woal_atoi(&data[j], cdata) !=
MLAN_STATUS_SUCCESS) {
PRINTM(MERROR, " fail on woal_atoi()");
}
}
j++;
@ -478,7 +488,7 @@ static int woal_set_priv_11axcmdcfg_llde_pkt_filer_cmd(
llde_pkt_filter_pos =
llde_pkt_filter_pos + strlen("macfilter1=");
tmp_pos = llde_pkt_filter_pos + MAC_STRING_LENGTH;
tmp_pos = llde_pkt_filter_pos + MAC_STRING_LENGTH;
if (llde_pkt_filter_pos && tmp_pos) {
moal_memcpy_ext(priv->phandle, (t_u8 *)mac_pos,
(t_u8 *)llde_pkt_filter_pos, MAC_STRING_LENGTH,
@ -896,7 +906,8 @@ static int woal_setget_priv_bandcfg(moal_private *priv, t_u8 *respbuf,
i++)
if (infra_band == SupportedInfraBand[i])
break;
if (i == sizeof(SupportedInfraBand)) {
if (i == (sizeof(SupportedInfraBand) /
sizeof(SupportedInfraBand[0]))) {
ret = -EINVAL;
goto error;
}
@ -2209,8 +2220,18 @@ static int woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf,
mlan_status status = MLAN_STATUS_SUCCESS;
txrate_setting *rate_setting = NULL;
t_u32 vht_mcs_limit = MLAN_RATE_INDEX_MCS9;
t_u32 he_mcs_limit = MLAN_RATE_INDEX_MCS11;
t_u32 nss_limit = MLAN_RATE_NSS2;
ENTER();
if (IS_CARDIW610(priv->phandle->card_type)) {
vht_mcs_limit = MLAN_RATE_INDEX_MCS8;
he_mcs_limit = MLAN_RATE_INDEX_MCS9;
nss_limit = MLAN_RATE_NSS1;
}
if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_TXRATECFG))) {
/* GET operation */
user_data_len = 0;
@ -2263,6 +2284,15 @@ static int woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf,
/* auto */
rate->param.rate_cfg.is_rate_auto = 1;
} else {
if (data[0] == MLAN_RATE_FORMAT_LG ||
data[0] == MLAN_RATE_FORMAT_HT) {
if (user_data_len > 2) {
PRINTM(MERROR,
"Invalid number of arguments\n");
ret = -EINVAL;
goto done;
}
}
/* fixed rate */
PRINTM(MINFO, "SET: txratefg format: 0x%x\n", data[0]);
if ((data[0] != AUTO_RATE) &&
@ -2282,9 +2312,9 @@ static int woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf,
((data[0] == MLAN_RATE_FORMAT_HT) &&
(data[1] != 32) && (data[1] > 15)) ||
((data[0] == MLAN_RATE_FORMAT_VHT) &&
(data[1] > MLAN_RATE_INDEX_MCS9)) ||
(data[1] > vht_mcs_limit)) ||
((data[0] == MLAN_RATE_FORMAT_HE) &&
(data[1] > MLAN_RATE_INDEX_MCS11))) {
(data[1] > he_mcs_limit))) {
PRINTM(MERROR,
"Invalid index selection\n");
ret = -EINVAL;
@ -2299,8 +2329,9 @@ static int woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf,
if (data[0] == 2 || data[0] == 3) {
PRINTM(MINFO, "SET: txratefg nss: 0x%x\n",
data[2]);
/* NSS is supported up to 2 */
if ((data[2] <= 0) || (data[2] >= 3)) {
/* NSS is supported up to 1 for IW610, and up to
* 2 for other chips */
if ((data[2] <= 0) || (data[2] > nss_limit)) {
PRINTM(MERROR,
"Invalid nss selection\n");
ret = -EINVAL;
@ -2316,15 +2347,50 @@ static int woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf,
data[3]);
/* HE Preamble type */
//#define HE_SU_PREAMBLE 0
#define HE_SU_PREAMBLE 0
#define HE_ER_PREAMBLE 1
/* HE ER SU Type */
#define HE_ER_SU_BANDWIDTH_TONE242 0
#define HE_ER_SU_BANDWIDTH_TONE106 1
#define HE_SU_BANDWIDTH_MAX 3
rate_setting = (txrate_setting *)&data[3];
if (IS_CARDIW610(priv->phandle->card_type)) {
if (rate_setting->stbc != 0) {
PRINTM(MERROR,
"This chip does not support STBC\n");
ret = -EINVAL;
goto done;
}
if (rate_setting->adv_coding != 0) {
PRINTM(MERROR,
"This chip does not support LDPC\n");
ret = -EINVAL;
goto done;
}
if (data[0] == MLAN_RATE_FORMAT_HE &&
rate_setting->preamble ==
HE_ER_PREAMBLE) {
if (rate_setting->bandwidth >
HE_ER_SU_BANDWIDTH_TONE106) {
PRINTM(MERROR,
"BW setting for this ER rate is not supported for this 20MHz only chip\n");
ret = -EINVAL;
goto done;
}
} else {
if (rate_setting->bandwidth !=
0) {
PRINTM(MERROR,
"BW setting is not supported for this 20MHz only chip\n");
ret = -EINVAL;
goto done;
}
}
}
if (data[0] == MLAN_RATE_FORMAT_HE) {
if (rate_setting->preamble ==
HE_ER_PREAMBLE) {
@ -2357,7 +2423,17 @@ static int woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf,
ret = -EINVAL;
goto done;
}
} else if (rate_setting->preamble ==
HE_SU_PREAMBLE) {
if (rate_setting->bandwidth >
HE_SU_BANDWIDTH_MAX) {
PRINTM(MERROR,
"Invalid Bandwidth for HE SU Preamble\n");
ret = -EINVAL;
goto done;
}
}
if ((rate_setting->dcm) &&
(rate_setting->stbc == 0)) {
if ((data[1] ==
@ -3028,16 +3104,15 @@ done:
/**
* @brief easymesh uap Set/Get multi AP mode handler
*
* @param priv A pointer to moal_private structure
* @param req A pointer to ifreq structure
* @return 0 --success, otherwise fail
* @param priv A pointer to moal_private structure
* @param respbuf A pointer to response buffer
* @param respbuflen Length of response buffer
*
* @return MultiAP mode for GET, 0 -- success, otherwise fail for SET
*/
static int woal_uap_set_multiap_mode(moal_private *priv, t_u8 *respbuf,
t_u32 respbuflen)
{
mlan_ioctl_req *req = NULL;
mlan_ds_misc_cfg *misc = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
int mode[1] = {0};
int ret = 0;
int header_len = 0;
@ -3054,22 +3129,20 @@ static int woal_uap_set_multiap_mode(moal_private *priv, t_u8 *respbuf,
header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_SETMODE);
user_data_len = strlen(respbuf) - header_len;
/* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
ret = -ENOMEM;
goto done;
}
/* Fill request buffer */
misc = (mlan_ds_misc_cfg *)req->pbuf;
misc->sub_command = MLAN_OID_MISC_MULTI_AP_CFG;
req->req_id = MLAN_IOCTL_MISC_CFG;
if ((int)strlen(respbuf) == header_len) {
/* GET operation */
user_data_len = 0;
req->action = MLAN_ACT_GET;
if (priv->multi_ap_flag == EASY_MESH_MULTI_AP_BH_AND_FH_BSS)
mode[0] = EASY_MESH_MULTI_AP_BSS_MODE_3;
else if (priv->multi_ap_flag == EASY_MESH_MULTI_AP_BH_BSS)
mode[0] = EASY_MESH_MULTI_AP_BSS_MODE_2;
else if (priv->multi_ap_flag == EASY_MESH_MULTI_AP_FH_BSS)
mode[0] = EASY_MESH_MULTI_AP_BSS_MODE_1;
PRINTM(MINFO, "[EM:%s:%d] setmode to 0x%x\n", __func__,
__LINE__, mode[0]);
moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)mode,
sizeof(mode), respbuflen);
ret = sizeof(mode);
} else {
/* SET operation */
parse_arguments(respbuf + header_len, mode, ARRAY_SIZE(mode),
@ -3098,35 +3171,9 @@ static int woal_uap_set_multiap_mode(moal_private *priv, t_u8 *respbuf,
priv->multi_ap_flag = EASY_MESH_MULTI_AP_FH_BSS;
PRINTM(MINFO, "[EM:%s:%d] priv->multi_ap_flag 0x%x\n", __func__,
__LINE__, priv->multi_ap_flag);
req->action = MLAN_ACT_SET;
}
/* Send IOCTL request to MLAN */
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
ret = -EFAULT;
goto done;
}
if (req->action == MLAN_ACT_GET) {
if (priv->multi_ap_flag == EASY_MESH_MULTI_AP_BH_AND_FH_BSS)
mode[0] = EASY_MESH_MULTI_AP_BSS_MODE_3;
else if (priv->multi_ap_flag == EASY_MESH_MULTI_AP_BH_BSS)
mode[0] = EASY_MESH_MULTI_AP_BSS_MODE_2;
else if (priv->multi_ap_flag == EASY_MESH_MULTI_AP_FH_BSS)
mode[0] = EASY_MESH_MULTI_AP_BSS_MODE_1;
PRINTM(MINFO, "[EM:%s:%d] setmode to 0x%x\n", __func__,
__LINE__, mode[0]);
moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)mode,
sizeof(mode), respbuflen);
ret = sizeof(mode);
}
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return ret;
}
@ -4077,6 +4124,8 @@ static int woal_priv_get_cfpinfo(moal_private *priv, t_u8 *respbuf,
int ret = 0;
mlan_ioctl_req *req = NULL;
mlan_ds_misc_cfg *cfp_misc = NULL;
mlan_cfpinfo *c = NULL;
t_u32 header_len = 0;
mlan_status status = MLAN_STATUS_SUCCESS;
ENTER();
@ -4095,6 +4144,11 @@ static int woal_priv_get_cfpinfo(moal_private *priv, t_u8 *respbuf,
goto done;
}
/* Check whether user has requested 6GHz or MAC2 tables */
header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_CFPINFO);
if (respbuflen >= (header_len + sizeof(mlan_cfpinfo)))
c = (mlan_cfpinfo *)(respbuf + header_len);
/* Fill request buffer */
cfp_misc = (mlan_ds_misc_cfg *)req->pbuf;
cfp_misc->sub_command = MLAN_OID_MISC_CFP_INFO;
@ -4311,8 +4365,7 @@ static int woal_priv_assocessid(moal_private *priv, t_u8 *respbuf,
if (MOAL_ACQ_SEMAPHORE_BLOCK(&handle->reassoc_sem)) {
PRINTM(MERROR, "Acquire semaphore error, woal_set_essid\n");
ret = -EBUSY;
LEAVE();
return ret;
goto setessid_ret;
}
if (priv->scan_type == MLAN_SCAN_TYPE_PASSIVE)
@ -4889,6 +4942,8 @@ static int woal_priv_set_get_drvdbg(moal_private *priv, t_u8 *respbuf,
(drvdbg & MCMD_D) ? "X" : "");
printk(KERN_ALERT "MDAT_D (%08x) %s\n", MDAT_D,
(drvdbg & MDAT_D) ? "X" : "");
printk(KERN_ALERT "MREG (%08x) %s\n", MREG,
(drvdbg & MREG) ? "X" : "");
printk(KERN_ALERT "MREG_D (%08x) %s\n", MREG_D,
(drvdbg & MREG_D) ? "X" : "");
printk(KERN_ALERT "MIOCTL (%08x) %s\n", MIOCTL,
@ -5295,12 +5350,14 @@ static int woal_priv_hssetpara(moal_private *priv, t_u8 *respbuf,
buf = kzalloc(CMD_BUF_LEN, GFP_ATOMIC);
if (!buf) {
PRINTM(MERROR, "Could not allocate buffer\n");
LEAVE();
return -ENOMEM;
goto done;
}
memcpy(buf, respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_HSSETPARA)),
CMD_BUF_LEN - (strlen(CMD_NXP) + strlen(PRIV_CMD_HSSETPARA)));
memcpy(buf,
respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_HSSETPARA)),
CMD_BUF_LEN -
(strlen(CMD_NXP) + strlen(PRIV_CMD_HSSETPARA)));
snprintf(respbuf, CMD_BUF_LEN, "%s%s%s", CMD_NXP,
PRIV_CMD_HSCFG, buf);
respbuflen = strlen(respbuf);
@ -5433,6 +5490,166 @@ done:
return ret;
}
/**
* @brief Set/Get auth_assoc timeout configuration parameters
*
* @param priv A pointer to moal_private structure
* @param respbuf A pointer to response buffer
* @param respbuflen Available length of response buffer
*
* @return 0 --success, otherwise fail
*/
static int woal_priv_set_get_auth_assoc_timeout_cfg(moal_private *priv,
t_u8 *respbuf,
t_u32 respbuflen)
{
int ret = 0;
int user_data_len = 0;
int data[6];
mlan_ds_misc_cfg *misc = NULL;
mlan_ioctl_req *req = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
ENTER();
memset(data, 0, sizeof(data));
if (strlen(respbuf) ==
(strlen(CMD_NXP) + strlen(PRIV_CMD_AUTH_ASSOC_TIMEOUT_CFG))) {
/* GET operation */
user_data_len = 0;
} else {
/* SET operation */
memset((char *)data, 0, sizeof(data));
parse_arguments(respbuf + strlen(CMD_NXP) +
strlen(PRIV_CMD_AUTH_ASSOC_TIMEOUT_CFG),
data, ARRAY_SIZE(data), &user_data_len);
if (sizeof(int) * user_data_len != sizeof(data)) {
PRINTM(MERROR,
"auth_assoc_timeout_cfg: invalid numder of arguments provided\n");
LEAVE();
return -EINVAL;
}
}
/* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
ret = -ENOMEM;
goto done;
}
/* Fill request buffer */
misc = (mlan_ds_misc_cfg *)req->pbuf;
misc->sub_command = MLAN_OID_MISC_AUTH_ASSOC_TIMEOUT_CONFIG;
req->req_id = MLAN_IOCTL_MISC_CFG;
if (user_data_len) {
// SET operation
if (data[0] < AUTH_TIMEOUT_MIN || data[0] > AUTH_TIMEOUT_MAX) {
PRINTM(MERROR,
"Invalid auth_timeout configuration provided,"
" valid range: %d-%d",
AUTH_TIMEOUT_MIN, AUTH_TIMEOUT_MAX);
ret = -EINVAL;
goto done;
}
misc->param.auth_assoc_cfg.auth_timeout = (u16)data[0];
if (data[1] < AUTH_RETRY_TIMEOUT_ACK_MIN ||
data[1] > AUTH_RETRY_TIMEOUT_ACK_MAX) {
PRINTM(MERROR,
"Invalid auth_retry_timeout_if_ack configuration provided, "
"valid range: %d-%d",
AUTH_RETRY_TIMEOUT_ACK_MIN,
AUTH_RETRY_TIMEOUT_ACK_MAX);
ret = -EINVAL;
goto done;
}
misc->param.auth_assoc_cfg.auth_retry_timeout_if_ack =
(u16)data[1];
if (data[2] < AUTH_RETRY_TIMEOUT_NO_ACK_MIN ||
data[2] > AUTH_RETRY_TIMEOUT_NO_ACK_MAX) {
PRINTM(MERROR,
"Invalid auth_retry_timeout_if_no_ack configuration provided, "
"valid range: %d-%d",
AUTH_RETRY_TIMEOUT_NO_ACK_MIN,
AUTH_RETRY_TIMEOUT_NO_ACK_MAX);
ret = -EINVAL;
goto done;
}
misc->param.auth_assoc_cfg.auth_retry_timeout_if_no_ack =
(u16)data[2];
if (data[3] < ASSOC_TIMEOUT_MIN ||
data[3] > ASSOC_TIMEOUT_MAX) {
PRINTM(MERROR,
"Invalid assoc_timeout configuration provided, "
"valid range: %d-%d",
ASSOC_TIMEOUT_MIN, ASSOC_TIMEOUT_MAX);
ret = -EINVAL;
goto done;
}
misc->param.auth_assoc_cfg.assoc_timeout = (u16)data[3];
if (data[4] < REASSOC_TIMEOUT_MIN ||
data[4] > REASSOC_TIMEOUT_MAX) {
PRINTM(MERROR,
"Invalid reassoc_timeout configuration provided, "
"valid range: %d-%d",
REASSOC_TIMEOUT_MIN, REASSOC_TIMEOUT_MAX);
ret = -EINVAL;
goto done;
}
misc->param.auth_assoc_cfg.reassoc_timeout = (u16)data[4];
if (data[5] < ASSOC_RETRY_TIMEOUT_MIN ||
data[5] > ASSOC_RETRY_TIMEOUT_MAX) {
PRINTM(MERROR,
"Invalid retry_timeout configuration provided, "
"valid range: %d-%d",
ASSOC_RETRY_TIMEOUT_MIN,
ASSOC_RETRY_TIMEOUT_MAX);
ret = -EINVAL;
goto done;
}
misc->param.auth_assoc_cfg.retry_timeout = (u16)data[5];
req->action = MLAN_ACT_SET;
} else {
/* GET operation */
req->action = MLAN_ACT_GET;
}
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
ret = -EFAULT;
goto done;
}
if (user_data_len) {
// For SET opearion store auth_timeout in driver as driver
// handles auth_timeout
priv->auth_tx_wait_time =
misc->param.auth_assoc_cfg.auth_timeout;
}
// get auth_timeout from driver
misc->param.auth_assoc_cfg.auth_timeout = priv->auth_tx_wait_time;
data[0] = misc->param.auth_assoc_cfg.auth_timeout;
data[1] = misc->param.auth_assoc_cfg.auth_retry_timeout_if_ack;
data[2] = misc->param.auth_assoc_cfg.auth_retry_timeout_if_no_ack;
data[3] = misc->param.auth_assoc_cfg.assoc_timeout;
data[4] = misc->param.auth_assoc_cfg.reassoc_timeout;
data[5] = misc->param.auth_assoc_cfg.retry_timeout;
moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data, sizeof(data),
respbuflen);
ret = sizeof(data);
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return ret;
}
/**
* @brief Get Netlink Number
*
@ -6149,8 +6366,7 @@ static int woal_priv_set_essid(moal_private *priv, t_u8 *respbuf,
0);
ret = MLAN_STATUS_SUCCESS;
LEAVE();
return ret;
goto setessid_ret;
}
}
#endif
@ -7834,7 +8050,9 @@ static int woal_priv_get_txpwrlimit(moal_private *priv, t_u8 *respbuf,
(trpc_cfg->sub_band != 0x21) && (trpc_cfg->sub_band != 0x22) &&
(trpc_cfg->sub_band != 0x23) && (trpc_cfg->sub_band != 0x24) &&
(trpc_cfg->sub_band != 0x25) && (trpc_cfg->sub_band != 0x26) &&
(trpc_cfg->sub_band != 0x27)) {
(trpc_cfg->sub_band != 0x27) &&
(IS_CARDAW693(priv->phandle->card_type) &&
(trpc_cfg->sub_band != 0x80))) {
PRINTM(MERROR, "Invalid subband=0x%x\n", trpc_cfg->sub_band);
ret = -EINVAL;
goto done;
@ -12330,9 +12548,7 @@ static int woal_channel_switch(moal_private *priv, t_u8 block_tx,
} else if (band_width == CHANNEL_BW_80MHZ) {
pbwchansw_ie->new_channel_width = 1;
pbwchansw_ie->new_channel_center_freq0 =
center_freq_idx - 4;
pbwchansw_ie->new_channel_center_freq1 =
center_freq_idx + 4;
center_freq_idx;
} else if (band_width == CHANNEL_BW_160MHZ) {
pbwchansw_ie->new_channel_width = 2;
pbwchansw_ie->new_channel_center_freq0 =
@ -13620,18 +13836,17 @@ static int woal_priv_set_get_tx_rx_ant(moal_private *priv, t_u8 *respbuf,
}
if (priv->phandle->feature_control & FEATURE_CTRL_STREAM_2X2) {
radio->param.ant_cfg.tx_antenna = data[0];
radio->param.ant_cfg.rx_antenna = data[0];
if (data[0] == RF_ANTENNA_AUTO) {
radio->param.ant_cfg.rx_antenna = 0;
if (data[1] > 0xffff) {
ret = -EINVAL;
goto done;
}
} else {
radio->param.ant_cfg.rx_antenna = data[0];
}
if (user_data_len == 2)
radio->param.ant_cfg.rx_antenna = data[1];
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
if (IS_CARD9098(priv->phandle->card_type) ||
IS_CARD9097(priv->phandle->card_type) ||
IS_CARDIW624(priv->phandle->card_type) ||
IS_CARDAW693(priv->phandle->card_type)) {
woal_cfg80211_notify_antcfg(
priv, priv->phandle->wiphy, radio);
}
#endif
} else {
radio->param.ant_cfg_1x1.antenna = data[0];
if (user_data_len == 2) {
@ -13647,9 +13862,24 @@ static int woal_priv_set_get_tx_rx_ant(moal_private *priv, t_u8 *respbuf,
}
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
PRINTM(MERROR, "Failed to set new antenna config\n");
ret = -EFAULT;
goto done;
}
/* Notify the CFG80211 layer only on SUCCESS from FW */
if ((status == MLAN_STATUS_SUCCESS) && (req->action == MLAN_ACT_SET)) {
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
if (IS_CARD9098(priv->phandle->card_type) ||
IS_CARD9097(priv->phandle->card_type) ||
IS_CARDIW624(priv->phandle->card_type) ||
IS_CARDAW693(priv->phandle->card_type)) {
woal_cfg80211_notify_antcfg(priv, priv->phandle->wiphy,
radio);
}
#endif
}
if (!user_data_len) {
if (priv->phandle->feature_control & FEATURE_CTRL_STREAM_2X2) {
data[0] = radio->param.ant_cfg.tx_antenna;
@ -14615,6 +14845,90 @@ static int woal_priv_bypassed_packet(moal_private *priv, t_u8 *respbuf,
return ret;
}
/**
* @brief Set/Get module configuration
* @param priv Pointer to moal_private structure
* @param respbuf Pointer to response buffer
* @param resplen Response buffer length
*
* @return Number of bytes written, negative for failure.
*/
static int woal_priv_fw_wakeup_method(moal_private *priv, t_u8 *respbuf,
t_u32 respbuflen)
{
int header_len = 0, user_data_len = 0;
int ret = 0, data[2];
mlan_ds_pm_cfg *pm_cfg = NULL;
mlan_ioctl_req *req = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
ENTER();
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
if (req == NULL) {
ret = -ENOMEM;
goto done;
}
pm_cfg = (mlan_ds_pm_cfg *)req->pbuf;
header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_FW_WAKEUP_METHOD);
if ((int)strlen(respbuf) == header_len) {
/* GET operation */
user_data_len = 0;
req->action = MLAN_ACT_GET;
} else {
/* SET operation */
parse_arguments(respbuf + header_len, data,
sizeof(data) / sizeof(int), &user_data_len);
if (user_data_len > 2) {
PRINTM(MERROR, "Invalid parameter number\n");
ret = -EINVAL;
goto done;
}
if (data[0] != FW_WAKEUP_METHOD_INTERFACE &&
data[0] != FW_WAKEUP_METHOD_GPIO) {
PRINTM(MERROR, "Invalid FW wake up method:%d\n",
data[0]);
ret = -EINVAL;
goto done;
}
if (data[0] == FW_WAKEUP_METHOD_GPIO) {
if (user_data_len == 1) {
PRINTM(MERROR,
"Please provide gpio pin number for FW_WAKEUP_METHOD gpio\n");
ret = -EINVAL;
goto done;
}
pm_cfg->param.fw_wakeup_params.gpio_pin = data[1];
}
req->action = MLAN_ACT_SET;
pm_cfg->param.fw_wakeup_params.method = data[0];
}
pm_cfg->sub_command = MLAN_OID_PM_CFG_FW_WAKEUP_METHOD;
req->req_id = MLAN_IOCTL_PM_CFG;
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
ret = -EFAULT;
goto done;
}
data[0] = ((mlan_ds_pm_cfg *)req->pbuf)->param.fw_wakeup_params.method;
data[1] =
((mlan_ds_pm_cfg *)req->pbuf)->param.fw_wakeup_params.gpio_pin;
moal_memcpy_ext(priv->phandle, respbuf, &data, sizeof(data),
respbuflen);
ret = sizeof(int) * 2;
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return ret;
}
/**
* @brief Set Robustcoex gpiocfg
* @param priv Pointer to moal_private structure
@ -15929,6 +16243,155 @@ done:
return ret;
}
/**
* @brief Set/Get TSP config parameters
* @param priv Pointer to moal_private structure
* @param respbuf Pointer to response buffer
* @param resplen Response buffer length
*
* @return Number of bytes written, negative for failure.
*/
static int woal_priv_tsp_config(moal_private *priv, t_u8 *respbuf,
t_u32 respbuflen)
{
mlan_ds_tsp_cfg *tsp_cfg = NULL;
mlan_ioctl_req *req = NULL;
mlan_ds_misc_cfg *misc_cfg = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
int data[8] = {0};
int header_len = 0;
int user_data_len = 0;
int ret = 0;
ENTER();
if (!priv || !priv->phandle) {
PRINTM(MERROR, "priv or handle is null\n");
ret = -EFAULT;
goto done;
}
if (!respbuf) {
PRINTM(MERROR, "response buffer is not available!\n");
ret = -EINVAL;
goto done;
}
header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TSP_CFG);
memset(data, 0, sizeof(data));
parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
&user_data_len);
if (user_data_len > 8) {
PRINTM(MERROR, "invalid parameters\n");
ret = -EINVAL;
goto done;
}
/* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
ret = -ENOMEM;
goto done;
}
/* Fill request buffer */
req->req_id = MLAN_IOCTL_MISC_CFG;
misc_cfg = (mlan_ds_misc_cfg *)req->pbuf;
misc_cfg->sub_command = MLAN_OID_MISC_TSP_CFG;
tsp_cfg = &misc_cfg->param.tsp_cfg;
memset(tsp_cfg, 0, sizeof(mlan_ds_tsp_cfg));
if ((int)strlen(respbuf) == header_len) {
/* GET operation */
req->action = MLAN_ACT_GET;
user_data_len = 0;
} else {
req->action = MLAN_ACT_SET;
if (data[0] == 0) {
tsp_cfg->enable = (t_u16)data[0];
} else if (data[0] < 0 || data[0] > 1) {
PRINTM(MERROR, "err: Invalid TSP enable value\n");
ret = -EINVAL;
goto done;
} else if (data[1] < 0 || data[1] > 10) {
PRINTM(MERROR,
"err: Invalid TSP power backoff value\n");
ret = -EINVAL;
goto done;
} else if (data[2] < 0 || data[2] > 300) {
PRINTM(MERROR,
"err: Invalid TSP high power threshold value\n");
ret = -EINVAL;
goto done;
} else if (data[3] < 0 || data[3] > 300) {
PRINTM(MERROR,
"err: Invalid TSP low power threshold value\n");
ret = -EINVAL;
goto done;
} else if (data[3] > data[2]) {
PRINTM(MERROR,
"err: TSP low_thrshld value is greater than high_thrshld\n");
ret = -EINVAL;
goto done;
} else if (data[4] < 1 || data[4] > 100) {
PRINTM(MERROR, "err: Invalid Duty Cycle Step value\n");
ret = -EINVAL;
goto done;
} else if (data[5] < 0 || data[5] > 100) {
PRINTM(MERROR, "err: Invalid Duty Cycle Min value\n");
ret = -EINVAL;
goto done;
} else if (data[6] < -100 || data[6] > 150) {
PRINTM(MERROR,
"err: Invalid High Threshold Temperature value\n");
ret = -EINVAL;
goto done;
} else if (data[7] < -100 || data[7] > 150) {
PRINTM(MERROR,
"err: Invalid Low Threshold Temperature value\n");
ret = -EINVAL;
goto done;
} else if (data[7] > data[6]) {
PRINTM(MERROR,
"err: TSP Low Threshold Temperature is greater than High Threshold Temperature value\n");
ret = -EINVAL;
goto done;
} else {
tsp_cfg->enable = (t_u16)data[0];
tsp_cfg->backoff = (t_s32)data[1];
tsp_cfg->high_thrshld = (t_s32)data[2];
tsp_cfg->low_thrshld = (t_s32)data[3];
tsp_cfg->duty_cyc_step = (t_s32)data[4];
tsp_cfg->duty_cyc_min = (t_s32)data[5];
tsp_cfg->high_thrshld_temp = (t_s32)data[6];
tsp_cfg->low_thrshld_temp = (t_s32)data[7];
}
}
/* Send IOCTL request to MLAN */
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
ret = -EFAULT;
goto done;
}
if (!user_data_len) {
/* Copy back to userspace call */
moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)tsp_cfg,
sizeof(mlan_ds_tsp_cfg), respbuflen);
ret = sizeof(mlan_ds_tsp_cfg);
}
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return ret;
}
/**
* @brief Set/Get cross chip sync config parameters
* @param priv Pointer to moal_private structure
@ -20709,6 +21172,14 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
len = woal_priv_set_get_scancfg(priv, buf,
priv_cmd.total_len);
goto handled;
} else if (strnicmp(buf + strlen(CMD_NXP),
PRIV_CMD_AUTH_ASSOC_TIMEOUT_CFG,
strlen(PRIV_CMD_AUTH_ASSOC_TIMEOUT_CFG)) ==
0) {
/* Auth, Assoc configuration */
len = woal_priv_set_get_auth_assoc_timeout_cfg(
priv, buf, priv_cmd.total_len);
goto handled;
} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_GETNLNUM,
strlen(PRIV_CMD_GETNLNUM)) == 0) {
/* Scan configuration */
@ -21310,6 +21781,11 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
len = woal_priv_cross_chip_synch(priv, buf,
priv_cmd.total_len);
goto handled;
} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_TSP_CFG,
strlen(PRIV_CMD_TSP_CFG)) == 0) {
len = woal_priv_tsp_config(priv, buf,
priv_cmd.total_len);
goto handled;
} else if (strnicmp(buf + strlen(CMD_NXP),
PRIV_CMD_CH_LOAD_RESULTS,
strlen(PRIV_CMD_CH_LOAD_RESULTS)) == 0) {
@ -21446,6 +21922,13 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
len = woal_priv_bypassed_packet(priv, buf,
priv_cmd.total_len);
goto handled;
} else if (strnicmp(buf + strlen(CMD_NXP),
PRIV_CMD_FW_WAKEUP_METHOD,
strlen(PRIV_CMD_FW_WAKEUP_METHOD)) == 0) {
/* Set/Get fw wake up method */
len = woal_priv_fw_wakeup_method(priv, buf,
priv_cmd.total_len);
goto handled;
#ifdef WIFI_DIRECT_SUPPORT
#if defined(UAP_CFG80211)
} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_CFG_NOA,
@ -21701,7 +22184,7 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
} else if (strnicmp(buf + strlen(CMD_NXP),
PRIV_CMD_GET_CFG_CHAN_LIST,
strlen(PRIV_CMD_GET_CFG_CHAN_LIST)) == 0) {
/* Get txpwrlimit */
/* Get channel list */
if (IS_STA_OR_UAP_CFG80211(cfg80211_wext))
len = woal_priv_getcfgchanlist(
priv, buf, priv_cmd.total_len);

View file

@ -238,6 +238,7 @@ typedef struct _chan_stats {
#define PRIV_CMD_TX_BF_CFG "httxbfcfg"
#define PRIV_CMD_PORT_CTRL "port_ctrl"
#define PRIV_CMD_PB_BYPASS "pb_bypass"
#define PRIV_CMD_FW_WAKEUP_METHOD "fwwakeupmethod"
#ifdef SDIO
#define PRIV_CMD_SD_CMD53_RW "sdcmd53rw"
#endif
@ -305,6 +306,7 @@ typedef struct _chan_stats {
#define PRIV_CMD_CH_LOAD "getchload"
#define PRIV_CMD_CH_LOAD_RESULTS "getloadresults"
#define PRIV_CMD_CROSS_CHIP_SYNCH "crosssynch"
#define PRIV_CMD_TSP_CFG "wlan_tsp_cfg"
#define PRIV_CMD_ARB_CFG "arb"
@ -413,6 +415,8 @@ typedef struct _ssu_params_cfg {
#define PRIV_CMD_BTWT_AP_CONFIG_GET "btwt_AP_config_get"
#define PRIV_CMD_LPM "lpm"
/** Private command: auth/assoc timeout cfg*/
#define PRIV_CMD_AUTH_ASSOC_TIMEOUT_CFG "auth_assoc_timeout_cfg"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
int woal_do_ioctl(struct net_device *dev, struct ifreq *req, void __user *data,

View file

@ -60,13 +60,14 @@ static int disable_regd_by_driver = 1;
/** Region alpha2 string */
static char *reg_alpha2;
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
static int country_ie_ignore;
static int beacon_hints;
static int country_ie_ignore = 1;
static int beacon_hints = 1;
#endif
#endif
static int cfg80211_drcs;
static int dmcs;
static int pref_dbc;
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
@ -81,13 +82,18 @@ static int drcs_chantime_mode;
/** Auto deep sleep */
static int auto_ds;
/** net_rx mode*/
static int net_rx;
/** net_rx mode */
static int net_rx = 1;
/** amsdu deaggr mode */
static int amsdu_deaggr = 1;
static int tx_budget = 2600;
static int mclient_scheduling = 1;
static int ext_scan;
/** Boot Time config */
static int bootup_cal_ctrl = 0;
/** IEEE PS mode */
static int ps_mode;
/** passive to active scan */
@ -117,6 +123,9 @@ static int uap_max_sta;
static int wacp_mode = WACP_MODE_DEFAULT;
#endif
/** Fw cutom data config */
static unsigned int fw_data_cfg = 0;
#ifdef WIFI_DIRECT_SUPPORT
/** Max WIFIDIRECT interfaces */
static int max_wfd_bss = DEF_WIFIDIRECT_BSS;
@ -144,7 +153,11 @@ static int shutdown_hs;
/** SDIO slew rate */
static int slew_rate = 3;
#endif
int tx_work = 0;
#ifdef IMX_SUPPORT
static int tx_work = 1;
#else
static int tx_work = 0;
#endif
#if defined(CONFIG_RPS)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
@ -170,10 +183,11 @@ static int rps = 0;
*/
static int edmac_ctrl = 0;
static int tx_skb_clone = 0;
#ifdef IMX_SUPPORT
static int tx_skb_clone = 1;
static int pmqos = 1;
#else
static int tx_skb_clone = 0;
static int pmqos = 0;
#endif
@ -326,7 +340,7 @@ int dual_nb;
#ifdef DEBUG_LEVEL2
#define DEFAULT_DEBUG_MASK (0xffffffff)
#else
#define DEFAULT_DEBUG_MASK (MMSG | MFATAL | MERROR | MREG_D)
#define DEFAULT_DEBUG_MASK (MMSG | MFATAL | MERROR | MREG_D | MFW_D)
#endif /* DEBUG_LEVEL2 */
t_u32 drvdbg = DEFAULT_DEBUG_MASK;
@ -369,8 +383,8 @@ static card_type_entry card_type_map_tbl[] = {
#ifdef SDAW693
{CARD_TYPE_SDAW693, 0, CARD_SDAW693},
#endif
#ifdef SDIW615
{CARD_TYPE_SDIW615, 0, CARD_SDIW615},
#ifdef SDIW610
{CARD_TYPE_SDIW610, 0, CARD_SDIW610},
#endif
#ifdef PCIE8897
{CARD_TYPE_PCIE8897, 0, CARD_PCIE8897},
@ -412,8 +426,8 @@ static card_type_entry card_type_map_tbl[] = {
#ifdef USBIW624
{CARD_TYPE_USBIW624, 0, CARD_USBIW624},
#endif
#ifdef USBIW615
{CARD_TYPE_USBIW615, 0, CARD_USBIW615},
#ifdef USBIW610
{CARD_TYPE_USBIW610, 0, CARD_USBIW610},
#endif
};
@ -449,6 +463,12 @@ static t_size parse_cfg_get_line(t_u8 *data, t_size size, t_u8 *line_pos)
dest = line_pos;
while (pos < (t_s32)size && *src != '\x0A' && *src != '\0') {
if ((dest - line_pos) >= (MAX_LINE_LEN - 1)) {
PRINTM(MERROR,
"error: input data size exceeds the dest buff limit\n");
LEAVE();
return -1;
}
if (*src != ' ' && *src != '\t') /* parse space */
*dest++ = *src++;
else
@ -839,12 +859,32 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size,
params->amsdu_deaggr = out_data;
PRINTM(MMSG, "amsdu_deaggr = %d\n",
params->amsdu_deaggr);
} else if (strncmp(line, "tx_budget", strlen("tx_budget")) ==
0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
params->tx_budget = out_data;
} else if (strncmp(line, "mclient_scheduling",
strlen("mclient_scheduling")) == 0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
params->mclient_scheduling = out_data;
} else if (strncmp(line, "ext_scan", strlen("ext_scan")) == 0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
params->ext_scan = out_data;
PRINTM(MMSG, "ext_scan = %d\n", params->ext_scan);
} else if (strncmp(line, "bootup_cal_ctrl",
strlen("bootup_cal_ctrl")) == 0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
params->bootup_cal_ctrl = out_data;
PRINTM(MMSG, "bootup_cal_ctrl = %d\n",
params->bootup_cal_ctrl);
} else if (strncmp(line, "ps_mode", strlen("ps_mode")) == 0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
@ -1365,13 +1405,14 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size,
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
if (out_data)
moal_extflg_set(handle, EXT_DMCS);
else
moal_extflg_clear(handle, EXT_DMCS);
PRINTM(MMSG, "dmcs %s\n",
moal_extflg_isset(handle, EXT_DMCS) ? "on" :
"off");
params->dmcs = out_data;
PRINTM(MMSG, "dmcs=%d\n", params->dmcs);
} else if (strncmp(line, "pref_dbc", strlen("pref_dbc")) == 0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
params->pref_dbc = out_data;
PRINTM(MMSG, "pref_dbc=%d\n", params->pref_dbc);
}
else if (strncmp(line, "drcs_chantime_mode",
@ -1472,7 +1513,14 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size,
PRINTM(MMSG, "wacp_moe=%d\n", params->wacp_mode);
}
#endif
else if (strncmp(line, "mcs32", strlen("mcs32")) == 0) {
else if (strncmp(line, "fw_data_cfg", strlen("fw_data_cfg")) ==
0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
params->fw_data_cfg = out_data;
PRINTM(MMSG, "fw_data_cfg= %d\n", params->fw_data_cfg);
} else if (strncmp(line, "mcs32", strlen("mcs32")) == 0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
@ -1551,6 +1599,17 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size,
params->reject_addba_req);
}
}
if (params->tx_budget <= 0)
params->mclient_scheduling = 0;
#ifdef PCIE
if (!IS_PCIEAW693(handle->card_type))
params->mclient_scheduling = 0;
#else
params->mclient_scheduling = 0;
#endif
if (end)
return ret;
err:
@ -1649,6 +1708,10 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params)
handle->params.mcs32 = params->mcs32;
}
#endif /* UAP_SUPPORT */
handle->params.fw_data_cfg = fw_data_cfg;
if (params) {
handle->params.fw_data_cfg = params->fw_data_cfg;
}
handle->params.hs_auto_arp = hs_auto_arp;
if (params) {
@ -1684,16 +1747,32 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params)
if (params)
handle->params.amsdu_deaggr = params->amsdu_deaggr;
handle->params.tx_budget = params ? params->tx_budget : tx_budget;
handle->params.mclient_scheduling =
params ? params->mclient_scheduling : mclient_scheduling;
if (handle->params.tx_budget <= 0)
handle->params.mclient_scheduling = 0;
#ifdef PCIE
if (!IS_PCIEAW693(handle->card_type))
handle->params.mclient_scheduling = 0;
#else
handle->params.mclient_scheduling = 0;
#endif
handle->params.ext_scan = ext_scan;
if (params)
handle->params.ext_scan = params->ext_scan;
handle->params.bootup_cal_ctrl = bootup_cal_ctrl;
handle->params.ps_mode = ps_mode;
handle->params.p2a_scan = p2a_scan;
handle->params.scan_chan_gap = scan_chan_gap;
handle->params.sched_scan = sched_scan;
handle->params.max_tx_buf = max_tx_buf;
if (params) {
handle->params.bootup_cal_ctrl = params->bootup_cal_ctrl;
handle->params.ps_mode = params->ps_mode;
handle->params.max_tx_buf = params->max_tx_buf;
handle->params.p2a_scan = params->p2a_scan;
@ -1867,8 +1946,12 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params)
#endif
if (cfg80211_drcs)
moal_extflg_set(handle, EXT_CFG80211_DRCS);
if (dmcs)
moal_extflg_set(handle, EXT_DMCS);
handle->params.dmcs = dmcs;
if (params)
handle->params.dmcs = params->dmcs;
handle->params.pref_dbc = pref_dbc;
if (params)
handle->params.pref_dbc = params->pref_dbc;
handle->params.drcs_chantime_mode = drcs_chantime_mode;
if (params)
@ -2248,6 +2331,12 @@ void woal_init_from_dev_tree(void)
PRINTM(MIOCTL, "dmcs=0x%x\n", data);
dmcs = data;
}
} else if (!strncmp(prop->name, "pref_dbc",
strlen("pref_dbc"))) {
if (!of_property_read_u32(dt_node, prop->name, &data)) {
PRINTM(MIOCTL, "pref_dbc=0x%x\n", data);
pref_dbc = data;
}
}
#endif
#endif
@ -2372,6 +2461,13 @@ void woal_init_from_dev_tree(void)
multi_dtim = data;
PRINTM(MIOCTL, "multi_dtim=%d\n", multi_dtim);
}
} else if (!strncmp(prop->name, "bootup_cal_ctrl",
strlen("bootup_cal_ctrl"))) {
if (!of_property_read_u32(dt_node, prop->name, &data)) {
bootup_cal_ctrl = data;
PRINTM(MIOCTL, "bootup_cal_ctrl=%d\n",
bootup_cal_ctrl);
}
} else if (!strncmp(prop->name, "inact_tmo",
strlen("inact_tmo"))) {
if (!of_property_read_u32(dt_node, prop->name, &data)) {
@ -2429,7 +2525,13 @@ void woal_init_from_dev_tree(void)
}
}
#endif
else if (!strncmp(prop->name, "mcs32", strlen("mcs32"))) {
else if (!strncmp(prop->name, "fw_data_cfg",
strlen("fw_data_cfg"))) {
if (!of_property_read_u32(dt_node, prop->name, &data)) {
PRINTM(MERROR, "fw_data_cfg=0x%x\n", data);
fw_data_cfg = data;
}
} else if (!strncmp(prop->name, "mcs32", strlen("mcs32"))) {
if (!of_property_read_u32(dt_node, prop->name, &data)) {
PRINTM(MERROR, "mcs32=0x%x\n", data);
mcs32 = data;
@ -2648,6 +2750,19 @@ mlan_status woal_init_module_param(moal_handle *handle)
}
}
}
/* do some special handle for MFG mode if mfg_mode is specified in
* module param cfg file */
#ifdef MFG_CMD_SUPPORT
if (handle->params.mfg_mode) {
#if defined(STA_WEXT) || defined(UAP_WEXT)
handle->params.cfg80211_wext = STA_WEXT_MASK | UAP_WEXT_MASK;
#else
handle->params.cfg80211_wext = 0;
#endif
handle->params.drv_mode = DRV_MODE_STA;
}
#endif
if (no_match)
ret = woal_cfg_fallback_process(handle);
out:
@ -2751,6 +2866,10 @@ module_param(ext_scan, int, 0660);
MODULE_PARM_DESC(
ext_scan,
"0: MLAN default; 1: Enable Extended Scan; 2: Enable Enhanced Extended Scan");
module_param(bootup_cal_ctrl, int, 0660);
MODULE_PARM_DESC(
bootup_cal_ctrl,
"0: Disable boot time optimization (default); 1: Enable boot time optimization");
module_param(ps_mode, int, 0660);
MODULE_PARM_DESC(
ps_mode,
@ -2771,9 +2890,11 @@ MODULE_PARM_DESC(max_tx_buf, "Maximum Tx buffer size (2048/4096/8192)");
#if defined(SDIO)
module_param(intmode, int, 0);
MODULE_PARM_DESC(intmode, "0: INT_MODE_SDIO, 1: INT_MODE_GPIO");
MODULE_PARM_DESC(intmode, "0: INT_MODE_SDIO (default), 1: INT_MODE_GPIO");
module_param(gpiopin, int, 0);
MODULE_PARM_DESC(gpiopin, "255:new GPIO int mode, other vlue: gpio pin number");
MODULE_PARM_DESC(
gpiopin,
"GPIO pin number when intmode=1 (default 0, HW mapped intr on GPIO-21)");
#endif
module_param(pm_keep_power, int, 0);
@ -2795,22 +2916,25 @@ MODULE_PARM_DESC(
"0:has the slowest slew rate, then 01, then 02, and 03 has the highest slew rate");
#endif
module_param(tx_work, uint, 0660);
MODULE_PARM_DESC(tx_work, "1: Enable tx_work; 0: Disable tx_work");
MODULE_PARM_DESC(
tx_work,
"1: Enable tx_work_queue (default on iMX); 0: Disable tx_work_queue");
#if defined(CONFIG_RPS)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
module_param(rps, uint, 0660);
MODULE_PARM_DESC(
rps,
"bit0-bit4(0x1 - 0xf): Enables rps on specific cpu ; 0: Disables rps");
"bit0-bit4 (0x1-0xf): Enables rps on specific cpu ; 0: Disables rps (default)");
#endif
#endif
module_param(edmac_ctrl, int, 0660);
MODULE_PARM_DESC(edmac_ctrl, "0: Disable edmac; 1: Enable edmac");
module_param(tx_skb_clone, uint, 0660);
MODULE_PARM_DESC(tx_skb_clone,
"1: Enable tx_skb_clone; 0: Disable tx_skb_clone");
MODULE_PARM_DESC(
tx_skb_clone,
"1: Enable tx_skb_clone (default on iMX); 0: Disable tx_skb_clone");
module_param(pmqos, uint, 0660);
MODULE_PARM_DESC(pmqos, "1: Enable pmqos; 0: Disable pmqos");
MODULE_PARM_DESC(pmqos, "1: Enable pmqos (default on iMX); 0: Disable pmqos");
module_param(mcs32, uint, 0660);
MODULE_PARM_DESC(mcs32, "1: Enable mcs32; 0: Disable mcs32");
module_param(hs_auto_arp, uint, 0660);
@ -2881,13 +3005,23 @@ MODULE_PARM_DESC(wakelock_timeout, "set wakelock_timeout value (ms)");
module_param(dev_cap_mask, uint, 0);
MODULE_PARM_DESC(dev_cap_mask, "Device capability mask");
module_param(net_rx, int, 0);
MODULE_PARM_DESC(net_rx,
"0: use netif_rx_ni in rx; 1: use netif_receive_skb in rx");
MODULE_PARM_DESC(
net_rx,
"0: use netif_rx/netif_rx_ni in rx; 1: use netif_receive_skb in rx (default)");
module_param(amsdu_deaggr, int, 0);
MODULE_PARM_DESC(
amsdu_deaggr,
"0: buf copy in amsud deaggregation; 1: avoid buf copy in amsud deaggregation (default)");
module_param(tx_budget, int, 0);
MODULE_PARM_DESC(
tx_budget,
"airtime tx budget for multi-client scheduling in usec, 0 - disable, default - 2600");
module_param(mclient_scheduling, int, 0);
MODULE_PARM_DESC(mclient_scheduling,
"0: disable multi-client scheduling; 1 - enable(default)");
#ifdef SDIO
module_param(sdio_rx_aggr, int, 0);
MODULE_PARM_DESC(sdio_rx_aggr,
@ -2956,7 +3090,8 @@ MODULE_PARM_DESC(napi, "1: enable napi api; 0: disable napi");
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
module_param(dfs_offload, int, 0);
MODULE_PARM_DESC(dfs_offload, "1: enable dfs offload; 0: disable dfs offload.");
MODULE_PARM_DESC(dfs_offload,
"1: enable dfs offload; 0: disable dfs offload (default)");
#endif
module_param(drcs_chantime_mode, int, 0);
@ -2968,7 +3103,13 @@ MODULE_PARM_DESC(cfg80211_drcs,
"1: Enable DRCS support; 0: Disable DRCS support");
module_param(dmcs, int, 0);
MODULE_PARM_DESC(dmcs, "1: Enable dynamic mapping; 0: Disable dynamic mapping");
MODULE_PARM_DESC(
dmcs,
"0: Firmware default (default); 1: Enable dynamic mapping; 2: Disable dynamic mapping");
module_param(pref_dbc, int, 0);
MODULE_PARM_DESC(
pref_dbc,
"0: Firmware Default (default); 1: Enable prefer DBC; 2:Disable prefer DBC");
module_param(roamoffload_in_hs, int, 0);
MODULE_PARM_DESC(
@ -2983,6 +3124,10 @@ MODULE_PARM_DESC(
wacp_mode,
"WACP mode for UAP/GO 0: WACP_MODE_DEFAULT; 1: WACP_MODE_1; 2: WACP_MODE_2");
#endif
module_param(fw_data_cfg, int, 0);
MODULE_PARM_DESC(
fw_data_cfg,
"Custom Fw data Bit0: Fw Remapping; Bit1: USB Bulk End Point; Bit2: DPD Current Optimizations");
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
module_param(host_mlme, int, 0);
@ -2996,17 +3141,17 @@ MODULE_PARM_DESC(
module_param(disable_regd_by_driver, int, 0);
MODULE_PARM_DESC(
disable_regd_by_driver,
"0: reg domain set by driver enable(default); 1: reg domain set by driver disable");
"0: reg domain set by driver enable; 1: reg domain set by driver disable (default)");
module_param(reg_alpha2, charp, 0660);
MODULE_PARM_DESC(reg_alpha2, "Regulatory alpha2");
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
module_param(country_ie_ignore, int, 0);
MODULE_PARM_DESC(
country_ie_ignore,
"0: Follow countryIE from AP and beacon hint enable; 1: Ignore countryIE from AP and beacon hint disable");
"0: Follow countryIE from AP and beacon hint enable; 1: Ignore countryIE from AP and beacon hint disable (default)");
module_param(beacon_hints, int, 0);
MODULE_PARM_DESC(beacon_hints,
"0: enable beacon hints(default); 1: disable beacon hints");
"0: enable beacon hints; 1: disable beacon hints (default)");
#endif
#endif

View file

@ -906,12 +906,12 @@ void woal_request_set_multicast_list(moal_private *priv, struct net_device *dev)
bss->sub_command = MLAN_OID_BSS_MULTICAST_LIST;
req->req_id = MLAN_IOCTL_BSS;
req->action = MLAN_ACT_SET;
if (dev->flags & IFF_PROMISC) {
bss->param.multicast_list.mode = MLAN_PROMISC_MODE;
} else if (dev->flags & IFF_ALLMULTI) {
if (dev->flags & IFF_ALLMULTI) {
bss->param.multicast_list.mode = MLAN_ALL_MULTI_MODE;
} else {
bss->param.multicast_list.mode = MLAN_MULTICAST_MODE;
if (dev->flags & IFF_PROMISC)
bss->param.multicast_list.mode = MLAN_PROMISC_MODE;
bss->param.multicast_list.mode |= MLAN_MULTICAST_MODE;
mc_count = woal_copy_all_mc_list(priv->phandle,
&bss->param.multicast_list);
if (mc_count > MLAN_MAX_MULTICAST_LIST_SIZE)
@ -1283,6 +1283,11 @@ mlan_status woal_bss_start(moal_private *priv, t_u8 wait_option,
kfree(temp_ssid_bssid);
#endif
if (MOAL_ACQ_SEMAPHORE_BLOCK(&priv->phandle->async_sem)) {
PRINTM(MERROR, "Acquire semaphore error, woal_bss_start\n");
LEAVE();
return -EBUSY;
}
/* Allocate an IOCTL request buffer */
req = (mlan_ioctl_req *)woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
if (req == NULL) {
@ -1308,10 +1313,12 @@ mlan_status woal_bss_start(moal_private *priv, t_u8 wait_option,
sizeof(mlan_ssid_bssid));
#ifdef STA_CFG80211
#ifdef STA_SUPPORT
priv->assoc_status = req->status_code;
if (status != MLAN_STATUS_PENDING)
priv->assoc_status = req->status_code;
#endif
#endif
done:
MOAL_REL_SEMAPHORE(&priv->phandle->async_sem);
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
@ -2183,10 +2190,12 @@ mlan_status woal_request_get_fw_info(moal_private *priv, t_u8 wait_option,
sizeof(mlan_fw_info),
sizeof(mlan_fw_info));
DBG_HEXDUMP(MCMD_D, "mac", priv->current_addr, 6);
} else
} else if (status != MLAN_STATUS_PENDING)
PRINTM(MERROR,
"get fw info failed! status=%d, error_code=0x%x\n",
status, req->status_code);
else
PRINTM(MERROR, "get fw info failed! status=%d", status);
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
@ -6093,8 +6102,27 @@ mlan_status woal_cancel_scan(moal_private *priv, t_u8 wait_option)
unsigned long flags;
#endif
/* If scan is in process, cancel the scan command */
if (!handle->scan_pending_on_block || !scan_priv)
if (!handle->scan_pending_on_block || !scan_priv) {
#ifdef STA_CFG80211
spin_lock_irqsave(&handle->scan_req_lock, flags);
if (IS_STA_CFG80211(handle->params.cfg80211_wext) &&
handle->scan_request) {
cancel_delayed_work(&handle->scan_timeout_work);
/* some supplicant cannot handle SCAN abort event */
if (scan_priv &&
(scan_priv->bss_type == MLAN_BSS_TYPE_STA))
woal_cfg80211_scan_done(handle->scan_request,
MTRUE);
else
woal_cfg80211_scan_done(handle->scan_request,
MFALSE);
handle->scan_request = NULL;
handle->fake_scan_complete = MFALSE;
}
spin_unlock_irqrestore(&handle->scan_req_lock, flags);
#endif
return ret;
}
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
if (req == NULL) {
ret = MLAN_STATUS_FAILURE;
@ -6643,7 +6671,7 @@ mlan_status woal_set_rssi_low_threshold(moal_private *priv, char *rssi,
priv->mrvl_rssi_low = low_rssi;
#endif
misc->param.subscribe_event.low_rssi = low_rssi;
misc->param.subscribe_event.low_rssi_freq = 1;
misc->param.subscribe_event.low_rssi_freq = 0;
ret = woal_request_ioctl(priv, req, wait_option);
if (ret == MLAN_STATUS_FAILURE) {
PRINTM(MERROR, "request set rssi_low_threshold fail!\n");
@ -6707,7 +6735,7 @@ mlan_status woal_set_rssi_threshold(moal_private *priv, t_u32 event_id,
SUBSCRIBE_EVT_ACT_BITWISE_SET;
misc->param.subscribe_event.evt_bitmap =
SUBSCRIBE_EVT_RSSI_LOW | SUBSCRIBE_EVT_RSSI_HIGH;
misc->param.subscribe_event.low_rssi_freq = 1;
misc->param.subscribe_event.low_rssi_freq = 0;
misc->param.subscribe_event.low_rssi = priv->last_rssi_low;
misc->param.subscribe_event.high_rssi_freq = 0;
misc->param.subscribe_event.high_rssi = priv->last_rssi_high;
@ -7676,6 +7704,9 @@ mlan_status woal_multi_ap_cfg(moal_private *priv, t_u8 wait_option, t_u8 flag)
if (status != MLAN_STATUS_SUCCESS)
goto done;
PRINTM(MCMND, "%s: %s 4addr mode\n", priv->netdev->name,
flag ? "Enable" : "Disable");
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
@ -8292,7 +8323,7 @@ static int parse_tx_pwr_string(moal_handle *handle, const char *s, size_t len,
card_type = (handle->card_type) & 0xff;
if ((card_type == CARD_TYPE_9098) || (card_type == CARD_TYPE_9097) ||
(card_type == CARD_TYPE_9177) || (card_type == CARD_TYPE_IW624) ||
(card_type == CARD_TYPE_AW693))
(card_type == CARD_TYPE_AW693) || (card_type == CARD_TYPE_IW610))
pow_conv = MTRUE;
flag = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL;
@ -8643,6 +8674,32 @@ static int parse_tx_frame_string(const char *s, size_t len,
if (string == NULL)
return -ENOMEM;
/*Initialize the parameters to default values to be used*/
d->data_rate = 0x1100;
d->frame_pattern = 0xB496DEB6;
d->frame_length = 0x400;
d->enable = 0;
d->short_preamble = -1;
d->short_gi = 0;
d->adv_coding = -1;
d->tx_bf = 0;
d->gf_mode = 0;
d->stbc = 0;
d->adjust_burst_sifs = 0;
d->burst_sifs_in_us = 0;
d->signal_bw = -1;
d->NumPkt = -1;
d->MaxPE = -1;
d->BeamChange = -1;
d->Dcm = -1;
d->Doppler = -1;
d->MidP = -1;
d->QNum = -1;
for (i = 0; i < ETH_ALEN; i++) {
d->bssid[i] = 0xff;
}
moal_memcpy_ext(NULL, string, s + strlen("tx_frame="),
len - strlen("tx_frame="), TX_FRAME_STR_LEN - 1);
@ -8747,12 +8804,7 @@ static int parse_tx_frame_string(const char *s, size_t len,
}
}
if ((d->enable > 1) || (d->frame_length == 0) ||
(d->adjust_burst_sifs > 1) || (d->burst_sifs_in_us > 255) ||
(d->short_preamble > 1) ||
(d->act_sub_ch == 2 || d->act_sub_ch > 3) || (d->short_gi > 1) ||
(d->adv_coding > 1) || (d->tx_bf > 1) || (d->gf_mode > 1) ||
(d->stbc > 1))
if (d->enable > 1)
ret = -EINVAL;
done:
kfree(tmp);
@ -8953,6 +9005,50 @@ done:
return ret;
}
/*
* @brief Parse mfg cmd otp cal data rdwr
*
* @param handle A pointer to moal_handle structure
* @param s A pointer to user buffer
* @param len Length of user buffer
* @param d A pointer to mfg_cmd_generic_cfg struct
* @return 0 on success, -EINVAL otherwise
*/
static int parse_otp_cal_data_rd_wr_string(const char *s, size_t len,
mfg_cmd_otp_cal_data_rd_wr_t *d)
{
int ret = MLAN_STATUS_SUCCESS;
char *string = NULL;
char *pos = NULL;
int i = 0;
ENTER();
if (!s || !d) {
LEAVE();
return -EINVAL;
}
string = (char *)&(s[strlen("otp_cal_data_rd_wr=")]);
pos = strsep(&string, " \t");
d->action = (t_u16)woal_string_to_number(pos);
if (d->action == MFALSE)
goto done;
for (i = 0; i < CAL_DATA_LEN; i++) {
pos = strsep(&string, " \t");
if (pos) {
d->cal_data[i] = (t_u16)woal_string_to_number(pos);
d->cal_data_len++;
}
}
if (d->action > 1)
ret = -EINVAL;
done:
LEAVE();
return ret;
}
/**
* @brief This function sends RF test mode command in firmware
*
@ -9047,6 +9143,13 @@ mlan_status woal_process_rf_test_mode_cmd(moal_handle *handle, t_u32 cmd,
err = MTRUE;
}
break;
case MFG_CMD_OTP_CAL_DATA:
misc->sub_command = MLAN_OID_MISC_OTP_CAL_DATA_RD_WR;
if (parse_otp_cal_data_rd_wr_string(
buffer, len, &misc->param.mfg_otp_cal_data_rd_wr)) {
err = MTRUE;
}
break;
default:
err = MTRUE;
}
@ -9205,6 +9308,15 @@ mlan_status woal_process_rf_test_mode_cmd(moal_handle *handle, t_u32 cmd,
misc->param.mfg_otp_mac_addr_rd_wr.mac_addr[i];
}
break;
case MFG_CMD_OTP_CAL_DATA:
handle->rf_data->mfg_otp_cal_data_rd_wr.action =
misc->param.mfg_otp_cal_data_rd_wr.action;
for (i = 0; i < misc->param.mfg_otp_cal_data_rd_wr.cal_data_len;
i++) {
handle->rf_data->mfg_otp_cal_data_rd_wr.cal_data[i] =
misc->param.mfg_otp_cal_data_rd_wr.cal_data[i];
}
break;
}
done:
if (err || ret != MLAN_STATUS_PENDING)

View file

@ -4,7 +4,7 @@
* driver.
*
*
* Copyright 2008-2024, 2024 NXP
* Copyright 2008-2024 NXP
*
* This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991
@ -75,6 +75,16 @@ Change log:
#endif
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
#include <linux/ktime.h>
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
#include <linux/hrtimer.h>
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
#include <linux/rtc.h>
#include <linux/utsname.h>
#endif
/********************************************************
Global Variables
********************************************************/
@ -604,8 +614,8 @@ static struct _card_info card_info_SD9177 = {
};
#endif
#ifdef SDIW615
static struct _card_info card_info_SDIW615 = {
#ifdef SDIW610
static struct _card_info card_info_SDIW610 = {
.embedded_supp = 1,
.drcs = 1,
.go_noa = 1,
@ -620,8 +630,8 @@ static struct _card_info card_info_SDIW615 = {
.rev_id_reg = 0xc8,
.host_strap_reg = 0xf4,
.magic_reg = 0xf0,
.fw_name = SDIW615_DEFAULT_COMBO_FW_NAME,
.fw_name_wlan = SDIW615_DEFAULT_WLAN_FW_NAME,
.fw_name = SDIW610_DEFAULT_COMBO_FW_NAME,
.fw_name_wlan = SDIW610_DEFAULT_WLAN_FW_NAME,
#ifdef SDIO
.dump_fw_info = DUMP_FW_SDIO_V3,
.dump_fw_ctrl_reg = 0xf9,
@ -637,8 +647,10 @@ static struct _card_info card_info_SDIW615 = {
.fw_stuck_code_reg = 0xEB,
.fw_reset_reg = 0x0EE,
.fw_reset_val = 0x99,
.slew_rate_reg = 0x90002328,
.slew_rate_bit_offset = 12,
.fw_wakeup_reg = 0,
.fw_wakeup_val = 2,
.slew_rate_reg = 0x45001064,
.slew_rate_bit_offset = 16,
#endif
.sniffer_support = 1,
.per_pkt_cfg_support = 1,
@ -773,6 +785,7 @@ static struct _card_info card_info_PCIEAW693 = {
.rev_id_reg = 0x8,
.host_strap_reg = 0x1c70,
.magic_reg = 0x1c74,
.boot_mode_reg = 0x1c8c,
.fw_name = PCIEAW693_DEFAULT_COMBO_FW_NAME,
.fw_name_wlan = PCIEAW693_DEFAULT_WLAN_FW_NAME,
.fw_stuck_code_reg = 0x1c80,
@ -910,8 +923,8 @@ static struct _card_info card_info_USBIW624 = {
};
#endif
#ifdef USBIW615
static struct _card_info card_info_USBIW615 = {
#ifdef USBIW610
static struct _card_info card_info_USBIW610 = {
.embedded_supp = 1,
.drcs = 1,
.go_noa = 1,
@ -923,8 +936,8 @@ static struct _card_info card_info_USBIW615 = {
.rx_rate_max = 412,
.feature_control = FEATURE_CTRL_DEFAULT,
.histogram_table_num = 3,
.fw_name = USBIW615_DEFAULT_COMBO_FW_NAME,
.fw_name_wlan = USBIW615_DEFAULT_WLAN_FW_NAME,
.fw_name = USBIW610_DEFAULT_COMBO_FW_NAME,
.fw_name_wlan = USBIW610_DEFAULT_WLAN_FW_NAME,
.sniffer_support = 1,
.per_pkt_cfg_support = 1,
};
@ -1041,6 +1054,7 @@ static mlan_callbacks woal_callbacks = {
.moal_assert = moal_assert,
.moal_hist_data_add = moal_hist_data_add,
.moal_updata_peer_signal = moal_updata_peer_signal,
.moal_get_host_time_ns = moal_get_host_time_ns,
.moal_do_div = moal_do_div,
.moal_tp_accounting = moal_tp_accounting,
.moal_tp_accounting_rx_param = moal_tp_accounting_rx_param,
@ -1201,6 +1215,38 @@ void woal_clean_up(moal_handle *handle)
MOAL_REL_SEMAPHORE(&handle->async_sem);
}
#endif
#ifdef UAP_CFG80211
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
if (IS_STA_CFG80211(cfg80211_wext) && handle->is_cac_timer_set &&
(handle->cac_bss_index != 0xff)) {
woal_cancel_timer(&handle->cac_timer);
handle->is_cac_timer_set = MFALSE;
handle->cac_period = MFALSE;
priv = handle->priv[handle->cac_bss_index];
if (priv) {
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 11, 0)
cfg80211_cac_event(priv->netdev, &handle->dfs_channel,
NL80211_RADAR_CAC_ABORTED,
GFP_KERNEL, 0);
#elif CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
cfg80211_cac_event(priv->netdev, &handle->dfs_channel,
NL80211_RADAR_CAC_ABORTED,
GFP_KERNEL);
#else
cfg80211_cac_event(priv->netdev,
NL80211_RADAR_CAC_ABORTED,
GFP_KERNEL);
#endif
if (priv->csa_workqueue)
flush_workqueue(priv->csa_workqueue);
}
memset(&handle->dfs_channel, 0,
sizeof(struct cfg80211_chan_def));
handle->cac_bss_index = 0xff;
}
#endif
#endif
for (i = 0; i < handle->priv_num; i++) {
if (handle->priv[i]) {
priv = handle->priv[i];
@ -1236,7 +1282,6 @@ void woal_clean_up(moal_handle *handle)
}
#endif
#endif
// stop bgscan
#ifdef STA_CFG80211
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
@ -1287,6 +1332,32 @@ void woal_send_auto_recovery_complete_event(moal_handle *handle)
reset_handle = NULL;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
/**
* @brief This function reads hostname
*
* @hostname Pointer to hostname
* @return N/A
*/
static void woal_get_hostname(char *hostname)
{
snprintf(hostname, MAX_HOSTNAME_LEN, "%s ", utsname()->nodename);
}
/**
* @brief This function reads real time
*
* @tstamp Pointer to timestamp
* @return N/A
*/
static void woal_get_timestamp(char *tstamp)
{
struct rtc_time time;
time = rtc_ktime_to_tm(ktime_get_real());
snprintf(tstamp, MAX_TIME_LEN, "%ptRs\n", &time);
}
#endif
/**
* @brief This function process FW hang
*
@ -2142,6 +2213,9 @@ mlan_status woal_update_drv_tbl(moal_handle *handle, int drv_mode_local)
#endif
int max_nan_bss = handle->params.max_nan_bss;
int max_dfs_bss = MAX_DFS_BSS;
#ifdef UAP_SUPPORT
int max_uap_bss_limit = MAX_UAP_BSS;
#endif
ENTER();
@ -2161,7 +2235,9 @@ mlan_status woal_update_drv_tbl(moal_handle *handle, int drv_mode_local)
#ifdef UAP_SUPPORT
if (drv_mode_local & DRV_MODE_UAP) {
if ((max_uap_bss < 1) || (max_uap_bss > MAX_UAP_BSS)) {
if (handle->pref_mac)
max_uap_bss_limit = MAX_UAP_BSS_DUAL_MAC;
if ((max_uap_bss < 1) || (max_uap_bss > max_uap_bss_limit)) {
PRINTM(MWARN,
"Unsupported max_uap_bss (%d), setting to default\n",
max_uap_bss);
@ -2356,6 +2432,10 @@ mlan_status woal_init_sw(moal_handle *handle)
drvdbg = handle->params.drvdbg;
#endif
#ifdef MFG_CMD_SUPPORT
mfg_mode = handle->params.mfg_mode;
#endif
handle->fw_dump_status = MFALSE;
#ifdef STA_SUPPORT
@ -2549,6 +2629,7 @@ mlan_status woal_init_sw(moal_handle *handle)
(t_u32)moal_extflg_isset(handle, EXT_FIX_BCN_BUF);
device.auto_ds = (t_u32)handle->params.auto_ds;
device.ext_scan = (t_u8)handle->params.ext_scan;
device.bootup_cal_ctrl = handle->params.bootup_cal_ctrl;
device.ps_mode = (t_u32)handle->params.ps_mode;
device.passive_to_active_scan = (t_u8)handle->params.p2a_scan;
device.max_tx_buf = (t_u32)handle->params.max_tx_buf;
@ -2620,6 +2701,7 @@ mlan_status woal_init_sw(moal_handle *handle)
device.uap_max_sta = handle->params.uap_max_sta;
device.wacp_mode = handle->params.wacp_mode;
#endif
device.fw_data_cfg = handle->params.fw_data_cfg;
device.mcs32 = handle->params.mcs32;
device.hs_wake_interval = handle->params.hs_wake_interval;
device.indication_gpio = handle->params.indication_gpio;
@ -2631,7 +2713,8 @@ mlan_status woal_init_sw(moal_handle *handle)
#endif
device.second_mac = handle->second_mac;
device.antcfg = handle->params.antcfg;
device.dmcs = moal_extflg_isset(handle, EXT_DMCS);
device.dmcs = handle->params.dmcs;
device.pref_dbc = handle->params.pref_dbc;
device.reject_addba_req = handle->params.reject_addba_req;
for (i = 0; i < handle->drv_mode.intf_num; i++) {
@ -2647,6 +2730,13 @@ mlan_status woal_init_sw(moal_handle *handle)
device.bss_attr[i].bss_virtual =
handle->drv_mode.bss_attr[i].bss_virtual;
}
device.max_tx_pending = handle->params.mclient_scheduling ?
MCLIENT_MAX_TX_PENDING :
MAX_TX_PENDING;
device.tx_budget = handle->params.tx_budget;
device.mclient_scheduling = handle->params.mclient_scheduling;
moal_memcpy_ext(handle, &device.callbacks, &woal_callbacks,
sizeof(mlan_callbacks), sizeof(mlan_callbacks));
if (!handle->params.amsdu_deaggr)
@ -2914,6 +3004,9 @@ static t_u32 woal_set_sdio_slew_rate(moal_handle *handle)
t_u32 new_value = 0;
t_u32 reg_type = MLAN_REG_MAC;
int status;
t_u32 i = 0;
t_u32 roll_count = 1;
t_u8 slew_rate_bit_offset = handle->card_info->slew_rate_bit_offset;
priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY);
if (!priv)
@ -2923,13 +3016,18 @@ static t_u32 woal_set_sdio_slew_rate(moal_handle *handle)
(handle->params.slew_rate > 3 || handle->params.slew_rate < 0))
return MLAN_STATUS_FAILURE;
#if defined(SD9098) || defined(SD9097) || defined(SDIW624) || \
defined(SDAW693) || defined(SD9177) || defined(SDIW615)
defined(SDAW693) || defined(SD9177) || defined(SDIW610)
if (IS_SD9098(handle->card_type) || IS_SD9097(handle->card_type) ||
IS_SDIW624(handle->card_type) || IS_SDIW615(handle->card_type) ||
IS_SDIW624(handle->card_type) || IS_SDIW610(handle->card_type) ||
IS_SD9177(handle->card_type))
reg_type = MLAN_REG_CIU;
#endif
#if defined(SDIW610)
if (IS_SDIW610(handle->card_type))
roll_count = 6;
#endif
status = woal_getset_regrdwr(priv, MLAN_ACT_GET, reg_type,
handle->card_info->slew_rate_reg, &value);
if (status < 0) {
@ -2937,9 +3035,12 @@ static t_u32 woal_set_sdio_slew_rate(moal_handle *handle)
ret = MLAN_STATUS_FAILURE;
goto done;
}
new_value = value & ~(0x3 << handle->card_info->slew_rate_bit_offset);
new_value |= (t_u32)handle->params.slew_rate
<< handle->card_info->slew_rate_bit_offset;
for (i = 0; i < roll_count; i++) {
slew_rate_bit_offset += 2 * i;
new_value = value & ~(0x3 << slew_rate_bit_offset);
new_value |= (t_u32)handle->params.slew_rate
<< slew_rate_bit_offset;
}
if (value != new_value) {
PRINTM(MMSG, "Set REG 0x%8x: 0x%x slew_rate=%d\n",
@ -3993,11 +4094,12 @@ static ssize_t woal_set_rps_map(struct netdev_rx_queue *queue, const char *buf,
static mlan_status woal_add_card_dpc(moal_handle *handle)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
int i, j;
int i;
char str_buf[MLAN_MAX_VER_STR_LEN];
#if defined(CONFIG_RPS)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
int j;
moal_private *priv_rps = NULL;
t_u8 rps_buf[3];
#endif
@ -4521,7 +4623,7 @@ static mlan_status woal_init_fw_dpc(moal_handle *handle)
!IS_USB9098(handle->card_type) &&
!IS_USB9097(handle->card_type) &&
!IS_USBIW624(handle->card_type) &&
!IS_USBIW615(handle->card_type) &&
!IS_USBIW610(handle->card_type) &&
!IS_USB8978(handle->card_type))
ret = woal_reset_usb_dev(handle);
goto done;
@ -5408,6 +5510,8 @@ mlan_status woal_init_uap_dev(struct net_device *dev, moal_private *priv)
dev->hard_header_len += MLAN_MIN_DATA_HEADER_LEN + sizeof(mlan_buffer) +
priv->extra_tx_head_len;
#endif
if (priv->phandle->params.mclient_scheduling)
dev->tx_queue_len = MCLIENT_MAX_TX_PENDING;
/** don't need register to wext */
if (priv->bss_type == MLAN_BSS_TYPE_DFS) {
LEAVE();
@ -5429,6 +5533,27 @@ mlan_status woal_init_uap_dev(struct net_device *dev, moal_private *priv)
}
#endif /* UAP_SUPPORT */
/**
* @brief This function sets thresholds for tx_pending
*
* @param handle A pointer to moal_handle structure
* @param priv A pointer to moal_private structure
*
* @return N/A
*/
static void woal_set_interface_pending_limits(moal_handle *handle,
moal_private *priv)
{
priv->max_tx_pending = MAX_TX_PENDING;
priv->low_tx_pending = LOW_TX_PENDING;
if (handle->params.mclient_scheduling &&
priv->bss_type == MLAN_BSS_TYPE_UAP) {
priv->max_tx_pending = MCLIENT_MAX_TX_PENDING;
priv->low_tx_pending = MCLIENT_LOW_TX_PENDING;
}
}
/**
* @brief This function adds a new interface. It will
* allocate, initialize and register the device.
@ -5562,9 +5687,8 @@ moal_private *woal_add_interface(moal_handle *handle, t_u8 bss_index,
#ifdef STA_CFG80211
INIT_LIST_HEAD(&priv->dhcp_discover_queue);
/* CID - 10017917 */
// coverity[side_effect_free: SUPPRESS]
spin_lock_init(&priv->dhcp_discover_lock);
hash_init(priv->hlist);
#endif
#ifdef STA_CFG80211
#ifdef STA_SUPPORT
@ -5870,6 +5994,7 @@ void woal_remove_interface(moal_handle *handle, t_u8 bss_index)
woal_flush_tcp_sess_queue(priv);
#ifdef STA_CFG80211
woal_flush_dhcp_discover_queue(priv);
woal_flush_arp_request_entry(priv);
#endif
#ifdef STA_CFG80211
@ -6504,6 +6629,7 @@ int woal_close(struct net_device *dev)
woal_flush_tx_stat_queue(priv);
#ifdef STA_CFG80211
woal_flush_dhcp_discover_queue(priv);
woal_flush_arp_request_entry(priv);
#endif
if ((priv->media_connected == MTRUE)
@ -7302,11 +7428,166 @@ void woal_remove_tx_info(moal_private *priv, t_u8 tx_seq_num)
#if defined(STA_CFG80211)
/**
* @brief This function flushes timesync info queue
* @brief This function flushes arp request entry from list
*
* @param priv A pointer to moal_private structure
* @param priv A pointer to moal_private structure
*
* @return N/A
* @return N/A
*/
t_void woal_flush_arp_request_entry(moal_private *priv)
{
struct arp_entry *arp = NULL;
struct hlist_node *tmp = NULL;
unsigned long flags;
int i;
spin_lock_irqsave(&priv->arp_request_lock, flags);
hash_for_each_safe (priv->hlist, i, tmp, arp, arp_hlist) {
hlist_del(&arp->arp_hlist);
kfree(arp);
}
spin_unlock_irqrestore(&priv->arp_request_lock, flags);
}
/**
* @brief This function generates constant factor for hash
*
* @param factor Constant factor of hash
*
* @return Returns updated hash factor
*/
static t_u32 woal_generate_hash_factor(t_u32 factor)
{
factor *= 0xcc9e2d51;
factor = (factor << 15) | (factor >> 17);
factor *= 0x1b873593;
// coverity[integer_overflow:SUPPRESS]
return factor;
}
/**
* @brief This function generates hash based on murmurhash
*
* @param data A pointer to input for hash
* @param len Length of input
* @param seed Seed value for hash
*
* @return Returns hash value
*/
static t_u32 woal_generate_hash(t_u8 *data, size_t len, t_u32 seed)
{
t_u32 hash = seed;
t_u32 factor;
size_t i;
for (i = len >> 2; i; i--) {
memcpy(&factor, data, sizeof(t_u32));
data += sizeof(t_u32);
hash ^= woal_generate_hash_factor(factor);
hash = (hash << 13) | (hash >> 19);
hash = hash * 5 + 0xe6546b64;
}
factor = 0;
for (i = len & 3; i; i--) {
factor <<= 8;
factor |= data[i - 1];
}
hash ^= woal_generate_hash_factor(factor);
hash ^= len;
hash ^= hash >> 16;
hash *= 0x85ebca6b;
hash ^= hash >> 13;
hash *= 0xc2b2ae35;
hash ^= hash >> 16;
// coverity[integer_overflow:SUPPRESS]
return hash;
}
/**
* @brief This function generates hash for arp request
*
* @param skb A pointer to sk_buff structure
*
* @return Returns hash of arp request
*/
t_u32 woal_generate_arp_request_hash(struct sk_buff *skb)
{
struct ethhdr *eth;
struct arphdr *arp;
t_u32 hash_key = 0;
t_u32 min_len = sizeof(*eth) + sizeof(*arp);
eth = (struct ethhdr *)(skb->data);
if (skb->len < min_len || eth->h_proto != htons(ETH_P_ARP))
return 0;
arp = (struct arphdr *)((u8 *)eth + ETH_HLEN);
if (arp->ar_op == htons(ARPOP_REQUEST)) {
/*
* since a hash value is required to distinguish ARP
* request.
*/
hash_key = woal_generate_hash((t_u8 *)arp,
sizeof(struct arp_hdr), 0);
return hash_key;
}
return 0;
}
/**
* @brief This function adds arp request hash to list
*
* @param priv A pointer to moal_private structure
* @param hash_key hash key of arp request
*
* @return N/A
*/
t_void woal_add_arp_request_node(moal_private *priv, t_u32 hash_key)
{
struct arp_entry *node = NULL;
struct hlist_node *temp = NULL;
unsigned long flags;
bool found = false;
int i;
spin_lock_irqsave(&priv->arp_request_lock, flags);
hash_for_each_safe (priv->hlist, i, temp, node, arp_hlist) {
if (node && node->hash_key == hash_key) {
found = true;
break;
}
if (node &&
(jiffies - node->ageout_jiffies) >= ARP_REQ_AGEOUT_TIME) {
hlist_del(&node->arp_hlist);
kfree(node);
}
}
if (!found) {
node = kzalloc(sizeof(struct arp_entry), GFP_ATOMIC);
if (!node) {
PRINTM(MERROR, "Failed to alloc memory for arp node\n");
return;
}
node->hash_key = hash_key;
node->ageout_jiffies = jiffies;
hash_add(priv->hlist, &node->arp_hlist, hash_key);
}
spin_unlock_irqrestore(&priv->arp_request_lock, flags);
}
/**
* @brief This function flushes dhcp discover info queue
*
* @param priv A pointer to moal_private structure
*
* @return N/A
*/
void woal_flush_dhcp_discover_queue(moal_private *priv)
{
@ -7390,8 +7671,6 @@ t_void woal_add_dhcp_discover_node(moal_private *priv, t_u32 transaction_id,
}
spin_unlock_irqrestore(&priv->dhcp_discover_lock, flags);
}
/* CID - 36267456 */
// coverity[leaked_storage:SUPPRESS]
}
/**
@ -7758,7 +8037,7 @@ static void woal_tcp_ack_timer_func(void *context)
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
atomic_inc(&priv->wmm_tx_pending[index]);
if (atomic_read(&priv->wmm_tx_pending[index]) >=
MAX_TX_PENDING) {
priv->max_tx_pending) {
struct netdev_queue *txq = netdev_get_tx_queue(
priv->netdev, index);
netif_tx_stop_queue(txq);
@ -7818,7 +8097,7 @@ static void woal_send_tcp_ack(moal_private *priv, struct sk_buff *skb,
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
atomic_inc(&priv->wmm_tx_pending[index]);
if (atomic_read(&priv->wmm_tx_pending[index]) >=
MAX_TX_PENDING) {
priv->max_tx_pending) {
struct netdev_queue *txq =
netdev_get_tx_queue(priv->netdev, index);
netif_tx_stop_queue(txq);
@ -7880,6 +8159,8 @@ static int woal_process_tcp_ack(moal_private *priv, mlan_buffer *pmbuf)
LEAVE();
return 0;
}
pmbuf->flags |= MLAN_BUF_FLAG_TCP_PKT;
tcph = (struct tcphdr *)((t_u8 *)iph + iph->ihl * 4);
if (*((t_u8 *)tcph + 13) == 0x10) {
@ -8273,13 +8554,21 @@ static void woal_start_xmit(moal_private *priv, struct sk_buff *skb)
#endif
#endif
#ifdef STA_CFG80211
if (priv->multi_ap_flag && priv->bss_type == MLAN_BSS_TYPE_STA) {
if (priv->wdev->use_4addr &&
priv->wdev->iftype == NL80211_IFTYPE_STATION) {
t_u32 transaction_id;
transaction_id = woal_get_dhcp_discover_transation_id(skb);
if (transaction_id)
woal_add_dhcp_discover_node(priv, transaction_id,
pmbuf);
}
if (priv->wdev->use_4addr &&
priv->wdev->iftype == NL80211_IFTYPE_STATION) {
t_u32 hash_key = woal_generate_arp_request_hash(skb);
if (hash_key)
woal_add_arp_request_node(priv, hash_key);
}
#endif
if (priv->enable_tcp_ack_enh && priv->media_connected) {
@ -8321,7 +8610,7 @@ static void woal_start_xmit(moal_private *priv, struct sk_buff *skb)
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
atomic_inc(&priv->wmm_tx_pending[index]);
if (atomic_read(&priv->wmm_tx_pending[index]) >=
MAX_TX_PENDING) {
priv->max_tx_pending) {
struct netdev_queue *txq =
netdev_get_tx_queue(priv->netdev, index);
netif_tx_stop_queue(txq);
@ -8383,7 +8672,8 @@ netdev_tx_t woal_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
priv->stats.tx_dropped++;
goto done;
}
if (moal_extflg_isset(priv->phandle, EXT_TX_WORK) &&
if (!priv->wdev->use_4addr &&
moal_extflg_isset(priv->phandle, EXT_TX_WORK) &&
(skb->protocol != htons(NXP_ETH_P_EAPOL))) {
spin_lock_bh(&(priv->tx_q.lock));
__skb_queue_tail(&(priv->tx_q), skb);
@ -8832,6 +9122,8 @@ void woal_init_priv(moal_private *priv, t_u8 wait_option)
priv->multi_ap_flag = 0;
#endif
#endif
priv->auth_tx_wait_time = AUTH_TX_DEFAULT_WAIT_TIME;
woal_set_interface_pending_limits(priv->phandle, priv);
LEAVE();
}
@ -9216,9 +9508,9 @@ static int woal_get_card_info(moal_handle *phandle)
phandle->card_info = &card_info_SDIW624;
break;
#endif
#ifdef SDIW615
case CARD_TYPE_SDIW615:
phandle->card_info = &card_info_SDIW615;
#ifdef SDIW610
case CARD_TYPE_SDIW610:
phandle->card_info = &card_info_SDIW610;
break;
#endif
#ifdef SD9177
@ -9285,9 +9577,9 @@ static int woal_get_card_info(moal_handle *phandle)
phandle->card_info = &card_info_USBIW624;
break;
#endif
#ifdef USBIW615
case CARD_TYPE_USBIW615:
phandle->card_info = &card_info_USBIW615;
#ifdef USBIW610
case CARD_TYPE_USBIW610:
phandle->card_info = &card_info_USBIW610;
break;
#endif
#ifdef SD8987
@ -10464,6 +10756,12 @@ t_void woal_store_firmware_dump(moal_handle *phandle, mlan_event *pmevent)
GFP_ATOMIC :
GFP_KERNEL;
fwdump_fname = kzalloc(64, flag);
if (!fwdump_fname) {
PRINTM(MERROR,
"Failed to allocate memory for fwdump fname\n");
LEAVE();
return;
}
}
snprintf(fwdump_fname, MAX_BUF_LEN, "%s/file_fwdump",
path_name);
@ -10489,11 +10787,7 @@ t_void woal_store_firmware_dump(moal_handle *phandle, mlan_event *pmevent)
LEAVE();
return;
}
if (pmevent->event_len > OFFSET_SEQNUM) {
phandle->fw_dump_len += pmevent->event_len - OFFSET_SEQNUM;
} else {
PRINTM(MERROR, "event_len is invalid\n");
}
phandle->fw_dump_len += pmevent->event_len - OFFSET_SEQNUM;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
vfs_write(pfile_fwdump,
(const char __user *)pmevent->event_buf + OFFSET_SEQNUM,
@ -10663,6 +10957,10 @@ static int woal_dump_moal_drv_info(moal_handle *phandle, t_u8 *buf)
struct usb_card_rec *cardp = NULL;
#endif
char str_buf[MLAN_MAX_VER_STR_LEN];
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
char hostname[MAX_HOSTNAME_LEN];
char tstamp[MAX_TIME_LEN];
#endif
ENTER();
if (!phandle || !buf) {
@ -10677,6 +10975,12 @@ static int woal_dump_moal_drv_info(moal_handle *phandle, t_u8 *buf)
ptr = (char *)buf;
ptr += snprintf(ptr, MAX_BUF_LEN,
"------------moal_debug_info-------------\n");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
woal_get_hostname(hostname);
woal_get_timestamp(tstamp);
ptr += snprintf(ptr, MAX_HOSTNAME_LEN, "Host:%s ", hostname);
ptr += snprintf(ptr, MAX_TIME_LEN, "Timestamp:%s", tstamp);
#endif
woal_get_version(phandle, str_buf, sizeof(str_buf) - 1);
ptr += snprintf(ptr, MAX_BUF_LEN, "Driver version = %s\n", str_buf);
ptr += snprintf(ptr, MAX_BUF_LEN, "main_state = %d\n",
@ -11535,6 +11839,10 @@ void woal_moal_debug_info(moal_private *priv, moal_handle *handle, u8 flag)
struct usb_card_rec *cardp = NULL;
#endif
char buf[MLAN_MAX_VER_STR_LEN];
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
char hostname[MAX_HOSTNAME_LEN];
char tstamp[MAX_TIME_LEN];
#endif
int i = 0;
ENTER();
@ -11569,6 +11877,11 @@ void woal_moal_debug_info(moal_private *priv, moal_handle *handle, u8 flag)
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
woal_get_hostname(hostname);
woal_get_timestamp(tstamp);
PRINTM(MERROR, "Host:%s Timestamp:%s", hostname, tstamp);
#endif
woal_get_version(phandle, buf, sizeof(buf) - 1);
PRINTM(MERROR, "Driver version = %s\n", buf);
PRINTM(MERROR, "main_state = %d\n", phandle->main_state);
@ -12016,6 +12329,10 @@ t_void woal_evt_work_queue(struct work_struct *work)
woal_host_mlme_process_assoc_resp(
(moal_private *)evt->priv, &evt->assoc_info);
break;
case WOAL_EVENT_ASSOC_TIMEOUT:
woal_host_mlme_process_assoc_timeout(
(moal_private *)evt->priv, evt->assoc_bss);
break;
#endif
#endif
#ifdef UAP_SUPPORT
@ -12683,6 +13000,10 @@ moal_handle *woal_add_card(void *card, struct device *dev, moal_if_ops *if_ops,
drvdbg = handle->params.drvdbg;
#endif
#ifdef MFG_CMD_SUPPORT
mfg_mode = handle->params.mfg_mode;
#endif
if (handle->params.mac_addr
#ifdef MFG_CMD_SUPPORT
&& handle->params.mfg_mode != MLAN_INIT_PARA_ENABLED
@ -13552,6 +13873,11 @@ static void woal_post_reset(moal_handle *handle)
#ifdef DEBUG_LEVEL1
drvdbg = handle->params.drvdbg;
#endif
#ifdef MFG_CMD_SUPPORT
mfg_mode = handle->params.mfg_mode;
#endif
handle->fw_dump_status = MFALSE;
handle->driver_status = MFALSE;
handle->hardware_status = HardwareStatusReady;
@ -14115,6 +14441,7 @@ static void woal_cleanup_module(void)
woal_flush_tx_stat_queue(handle->priv[i]);
#ifdef STA_CFG80211
woal_flush_dhcp_discover_queue(handle->priv[i]);
woal_flush_arp_request_entry(handle->priv[i]);
#endif
#endif
}

View file

@ -46,6 +46,7 @@ Change log:
#include <linux/sched.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/hashtable.h>
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 10, 17)
#include <uapi/linux/sched/types.h>
#endif
@ -313,10 +314,29 @@ typedef t_u8 BOOLEAN;
#define CARD_TYPE_PCIEIW624_UARTUART 7 // As per datasheet/SoC design
/** card type PCIEIW624_UARTSPI */
#define CARD_TYPE_PCIEIW624_UARTSPI 5 // As per datasheet/SoC design
/** card type SDIW615_sd_uart_spi **/
#ifdef SDIW610
#define CARD_TYPE_SDIW610_UART \
1 // As per datasheet/SoC design - Nighthawk, sd-uart strap = 0x3
#endif
#ifdef USBIW610
#define CARD_TYPE_USBIW610_USB \
5 // As per datasheet/SoC design - Nighthawk, usb-usb strap = 0x5
#define CARD_TYPE_USBIW610_UART \
7 // As per datasheet/SoC design - Nighthawk, usb-uart strap = 0x7
#endif
/* Max buffer size */
#define MAX_BUF_LEN 512
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
/* Max hostname length */
#define MAX_HOSTNAME_LEN 128
/* Max rtc time length */
#define MAX_TIME_LEN 128
#endif
/** Driver version */
extern char driver_version[];
@ -364,6 +384,7 @@ typedef enum {
RDWR_STATUS_DONE = 2
} rdwr_status;
#endif
/** Private structure for MOAL */
typedef struct _moal_private moal_private, *pmoal_private;
/** Handle data structure for MOAL */
@ -989,6 +1010,12 @@ mlan_status woal_do_dfs_cac(moal_private *priv,
/** LOW Tx Pending count */
#define LOW_TX_PENDING 380
/** MAX Tx Pending count when multi-client scheduling is used */
#define MCLIENT_MAX_TX_PENDING (128 * MAX_STA_COUNT)
/** LOW Tx Pending count when multi-client scheduling is used */
#define MCLIENT_LOW_TX_PENDING (MCLIENT_MAX_TX_PENDING * 3 / 4)
/** Offset for subcommand */
#define SUBCMD_OFFSET 4
@ -999,6 +1026,8 @@ mlan_status woal_do_dfs_cac(moal_private *priv,
/** GAP value is optional */
#define GAP_FLAG_OPTIONAL MBIT(15)
#define AUTH_TX_DEFAULT_WAIT_TIME 2400
/** max retry count for wait_event_interupptible_xx while loop */
#define MAX_RETRY_CNT 100
/** wait_queue structure */
@ -1066,7 +1095,8 @@ typedef struct _wait_queue {
/** Driver mode uAP bit */
#define DRV_MODE_UAP MBIT(1)
/** Maximum uAP BSS */
#define MAX_UAP_BSS 3
#define MAX_UAP_BSS 2
#define MAX_UAP_BSS_DUAL_MAC 3
/** Default uAP BSS */
#define DEF_UAP_BSS 1
@ -1217,6 +1247,7 @@ enum woal_event_type {
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
WOAL_EVENT_DEAUTH,
WOAL_EVENT_ASSOC_RESP,
WOAL_EVENT_ASSOC_TIMEOUT,
#endif
#endif
WOAL_EVENT_CHAN_RPT,
@ -1252,6 +1283,7 @@ struct woal_event {
enum woal_event_type type;
/** priv pointer */
void *priv;
struct cfg80211_bss *assoc_bss;
union {
chan_band_info chan_info;
woal_evt_buf evt;
@ -1415,6 +1447,8 @@ struct rf_test_mode_data {
mfg_Cmd_IEEEtypes_CtlBasicTrigHdr_t mfg_tx_trigger_config;
/* OTP frame data */
mfg_cmd_otp_mac_addr_rd_wr_t mfg_otp_mac_addr_rd_wr;
/* OTP CAL data */
mfg_cmd_otp_cal_data_rd_wr_t mfg_otp_cal_data_rd_wr;
};
/** Number of samples in histogram (/proc/mwlan/adapterX/mlan0/histogram).*/
@ -1560,6 +1594,38 @@ struct dhcp_pkt {
t_u8 pOptions[1];
} __ATTRIB_PACK__;
/** IPv4 arp header */
struct arp_hdr {
/** Hardware type */
t_u16 htype;
/** Protocol type */
t_u16 ptype;
/** Hardware address length */
t_u8 addr_len;
/** Protocol address length */
t_u8 proto_len;
/** Operation code */
t_u16 op_code;
/** Source mac address */
t_u8 sender_mac[MLAN_MAC_ADDR_LENGTH];
/** Sender IP address */
t_u8 sender_ip[4];
/** Destination mac address */
t_u8 target_mac[MLAN_MAC_ADDR_LENGTH];
/** Destination IP address */
t_u8 target_ip[4];
} __ATTRIB_PACK__;
/** ARP request entry ageout of 10 secs */
#define ARP_REQ_AGEOUT_TIME (10 * HZ)
/** ARP request node */
struct arp_entry {
t_u32 hash_key;
struct hlist_node arp_hlist;
t_u64 ageout_jiffies;
};
#define EASY_MESH_MULTI_AP_FH_BSS (t_u8)(0x20)
#define EASY_MESH_MULTI_AP_BH_BSS (t_u8)(0x40)
#define EASY_MESH_MULTI_AP_BH_AND_FH_BSS (t_u8)(0x60)
@ -1585,6 +1651,7 @@ struct ipv6addr_entry {
/** IPv6 address entry */
t_u8 ipv6_addr[16];
};
/** Private structure for MOAL */
struct _moal_private {
/** Handle structure */
@ -1934,6 +2001,8 @@ struct _moal_private {
t_u8 tdls_check_tx;
auto_assoc auto_assoc_priv;
#if CFG80211_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
t_u32 max_tx_pending;
t_u32 low_tx_pending;
atomic_t wmm_tx_pending[4];
#endif
struct sk_buff_head tx_q;
@ -1979,12 +2048,17 @@ struct _moal_private {
spinlock_t dhcp_discover_lock;
/** DHCP DISCOVER Info queue */
struct list_head dhcp_discover_queue;
/** hash table for arp request */
DECLARE_HASHTABLE(hlist, 8);
/** arp request lock */
spinlock_t arp_request_lock;
/** txwatchdog disable */
t_u8 txwatchdog_disable;
/** secure boot uuid lower and higher 8 bytes */
t_u64 uuid_lo;
t_u64 uuid_hi;
t_u16 auth_tx_wait_time;
};
#ifdef SDIO
@ -2526,6 +2600,7 @@ enum ext_mod_params {
EXT_PMQOS,
EXT_CHAN_TRACK,
EXT_DMCS,
EXT_PREF_DBC,
EXT_MAX_PARAM,
};
@ -2560,6 +2635,7 @@ typedef struct _moal_mod_para {
int uap_max_sta;
int wacp_mode;
#endif /* UAP_SUPPORT */
unsigned int fw_data_cfg;
#ifdef WIFI_DIRECT_SUPPORT
int max_wfd_bss;
char *wfd_name;
@ -2572,7 +2648,10 @@ typedef struct _moal_mod_para {
int auto_ds;
int net_rx;
int amsdu_deaggr;
int tx_budget;
int mclient_scheduling;
int ext_scan;
int bootup_cal_ctrl;
int ps_mode;
int p2a_scan;
/** scan chan gap */
@ -2612,6 +2691,10 @@ typedef struct _moal_mod_para {
unsigned int dev_cap_mask;
int pmic;
int antcfg;
/** dmcs*/
int dmcs;
/** pref_dbc*/
int pref_dbc;
unsigned int uap_oper_ctrl;
int hs_wake_interval;
int indication_gpio;
@ -3383,6 +3466,12 @@ extern t_u32 drvdbg;
printk(KERN_DEBUG msg); \
} while (0)
#define PRINTM_MREG(level, msg...) \
do { \
woal_print(level, msg); \
if (drvdbg & MREG) \
printk(KERN_DEBUG msg); \
} while (0)
#define PRINTM_MIOCTL(level, msg...) \
do { \
woal_print(level, msg); \
@ -4353,6 +4442,9 @@ void woal_flush_dhcp_discover_queue(moal_private *priv);
t_u32 woal_get_dhcp_discover_transation_id(struct sk_buff *skb);
t_void woal_add_dhcp_discover_node(moal_private *priv, t_u32 transaction_id,
mlan_buffer *pmbuf);
t_void woal_add_arp_request_node(moal_private *priv, t_u32 hash_key);
t_u32 woal_generate_arp_request_hash(struct sk_buff *skb);
t_void woal_flush_arp_request_entry(moal_private *priv);
#endif
mlan_status woal_set_get_wowlan_config(moal_private *priv, t_u16 action,
@ -4449,4 +4541,9 @@ mlan_status woal_edmac_cfg(moal_private *priv, t_u8 *country_code);
#ifdef DUMP_TO_PROC
void woal_print_firmware_dump_buf(t_u8 *pfd_buf, t_u64 fwdump_len);
#endif
#if !defined(STA_CFG80211) && !defined(UAP_CFG80211)
unsigned int woal_classify8021d(struct sk_buff *skb);
#endif
#endif /* _MOAL_MAIN_H */

View file

@ -636,7 +636,7 @@ static void woal_pcie_remove(struct pci_dev *dev)
}
cancel_work_sync(&card->reset_work);
handle = card->handle;
if (!handle || !handle->priv_num) {
if (!handle) {
PRINTM(MINFO, "PCIE card handle removed\n");
woal_pcie_cleanup(card);
kfree(card);
@ -958,7 +958,8 @@ static void woal_pcie_reset_prepare(struct pci_dev *pdev)
handle->fw_reseting = MTRUE;
// TODO: Can add more chips once the related code has been ported to fw
// v18
if (IS_PCIE9097(handle->card_type) || IS_PCIE9098(handle->card_type)) {
if (IS_PCIE9097(handle->card_type) || IS_PCIE9098(handle->card_type) ||
IS_PCIEAW693(handle->card_type)) {
woal_reset_adma(handle);
}
@ -1077,7 +1078,8 @@ static void woal_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
// TODO: Can add more chips once the related code has been
// ported to fw v18
if (IS_PCIE9097(handle->card_type) ||
IS_PCIE9098(handle->card_type)) {
IS_PCIE9098(handle->card_type) ||
IS_PCIEAW693(handle->card_type)) {
woal_reset_adma(handle);
}
woal_do_flr(handle, prepare, true);
@ -1161,6 +1163,7 @@ static mlan_status woal_pcie_write_reg(moal_handle *handle, t_u32 reg,
pcie_service_card *card = (pcie_service_card *)handle->card;
iowrite32(data, card->pci_mmap1 + reg);
PRINTM(MREG, "pcie w %x = %x\n", reg, data);
return MLAN_STATUS_SUCCESS;
}
@ -1179,6 +1182,7 @@ static mlan_status woal_pcie_read_reg(moal_handle *handle, t_u32 reg,
{
pcie_service_card *card = (pcie_service_card *)handle->card;
*data = ioread32(card->pci_mmap1 + reg);
PRINTM(MREG, "pcie r %x = %x\n", reg, *data);
if (*data == MLAN_STATUS_FAILURE)
return MLAN_STATUS_FAILURE;
@ -2610,7 +2614,7 @@ static mlan_status woal_pcie_get_fw_name(moal_handle *handle)
t_u32 strap = 0;
t_u32 magic = 0;
#endif
#ifdef PCIEIW624
#if defined(PCIEIW624) || defined(PCIEAW693)
t_u32 boot_mode_reg = handle->card_info->boot_mode_reg;
t_u32 boot_mode;
#endif
@ -2638,6 +2642,21 @@ static mlan_status woal_pcie_get_fw_name(moal_handle *handle)
break;
}
}
#endif
#ifdef PCIEAW693
if (IS_PCIEAW693(handle->card_type)) {
woal_pcie_read_reg(handle, rev_id_reg, &revision_id);
revision_id &= 0xff;
PRINTM(MCMND, "revision_id=0x%x\n", revision_id);
switch (revision_id) {
case PCIEAW693_A1:
handle->card_rev = CHIP_AW693_REV_A1;
break;
default:
handle->card_rev = CHIP_AW693_REV_A0;
break;
}
}
#endif
goto done;
}
@ -2776,23 +2795,84 @@ static mlan_status woal_pcie_get_fw_name(moal_handle *handle)
woal_pcie_read_reg(handle, rev_id_reg, &revision_id);
woal_pcie_read_reg(handle, host_strap_reg, &strap);
woal_pcie_read_reg(handle, magic_reg, &magic);
woal_pcie_read_reg(handle, boot_mode_reg, &boot_mode);
revision_id &= 0xff;
strap &= 0x7;
magic &= 0xff;
boot_mode &= 0x03;
PRINTM(MCMND,
"magic=0x%x, strap=0x%x, revision_id=0x%x\n",
magic, strap, revision_id);
if (magic == CHIP_MAGIC_VALUE) {
if (strap == CARD_TYPE_PCIE_UART)
strcpy(handle->card_info->fw_name,
PCIEUARTAW693_DEFAULT_COMBO_FW_NAME);
else
strcpy(handle->card_info->fw_name,
PCIEAW693_DEFAULT_COMBO_FW_NAME);
"magic=0x%x, boot_mode=0x%x, strap=0x%x, revision_id=0x%x\n",
magic, boot_mode, strap, revision_id);
if (boot_mode == 0x03)
PRINTM(MMSG,
"wlan: PCIE-AW693 in secure-boot mode\n");
switch (revision_id) {
case PCIEAW693_A1:
handle->card_rev = CHIP_AW693_REV_A1;
if (magic == CHIP_MAGIC_VALUE) {
if (strap == CARD_TYPE_PCIE_UART)
strcpy(handle->card_info
->fw_name,
PCIEUARTAW693_COMBO_V1_FW_NAME);
else
strcpy(handle->card_info
->fw_name,
PCIEAW693_COMBO_V1_FW_NAME);
}
strcpy(handle->card_info->fw_name_wlan,
PCIEAW693_WLAN_V1_FW_NAME);
if (boot_mode != 0x03) {
/* remove extension .se */
if (strstr(handle->card_info->fw_name,
".se"))
memset(strstr(handle->card_info
->fw_name,
".se"),
'\0', sizeof(".se"));
if (strstr(handle->card_info
->fw_name_wlan,
".se"))
memset(strstr(handle->card_info
->fw_name_wlan,
".se"),
'\0', sizeof(".se"));
}
break;
case PCIEAW693_A0:
handle->card_rev = CHIP_AW693_REV_A0;
if (magic == CHIP_MAGIC_VALUE) {
if (strap == CARD_TYPE_PCIE_UART)
strcpy(handle->card_info
->fw_name,
PCIEUARTAW693_DEFAULT_COMBO_FW_NAME);
else
strcpy(handle->card_info
->fw_name,
PCIEAW693_DEFAULT_COMBO_FW_NAME);
}
strcpy(handle->card_info->fw_name_wlan,
PCIEAW693_DEFAULT_WLAN_FW_NAME);
break;
default:
break;
}
} else {
ref_handle = (moal_handle *)handle->pref_mac;
if (ref_handle) {
woal_pcie_read_reg(handle, rev_id_reg,
&revision_id);
revision_id &= 0xff;
PRINTM(MCMND, "revision_id=0x%x\n",
revision_id);
switch (revision_id) {
case PCIEAW693_A1:
handle->card_rev = CHIP_AW693_REV_A1;
break;
default:
handle->card_rev = CHIP_AW693_REV_A0;
break;
}
strcpy(handle->card_info->fw_name,
ref_handle->card_info->fw_name);
strcpy(handle->card_info->fw_name_wlan,
@ -2933,7 +3013,8 @@ static void woal_pcie_work(struct work_struct *work)
handle->fw_reseting = MTRUE;
// TODO: Can add more chips once the related code has been ported to fw
// v18
if (IS_PCIE9097(handle->card_type) || IS_PCIE9098(handle->card_type)) {
if (IS_PCIE9097(handle->card_type) || IS_PCIE9098(handle->card_type) ||
IS_PCIEAW693(handle->card_type)) {
woal_reset_adma(handle);
}
woal_do_flr(handle, true, true);

View file

@ -94,7 +94,12 @@ Change log:
#ifdef PCIEAW693
#define PCIEUARTAW693_DEFAULT_COMBO_FW_NAME "nxp/pcieuartaw693_combo.bin"
#define PCIEAW693_DEFAULT_COMBO_FW_NAME "nxp/pcieuartaw693_combo.bin"
#define PCIEUARTAW693_COMBO_V1_FW_NAME "nxp/pcieuartaw693_combo_v1.bin.se"
#define PCIEAW693_COMBO_V1_FW_NAME "nxp/pcieuartaw693_combo_v1.bin.se"
#define PCIEAW693_DEFAULT_WLAN_FW_NAME "nxp/pcieaw693_wlan.bin"
#define PCIEAW693_WLAN_V1_FW_NAME "nxp/pcieaw693_wlan_v1.bin.se"
#define PCIEAW693_A0 0x00
#define PCIEAW693_A1 0x01
#endif /* PCIEAW693*/
#ifdef PCIE9098

View file

@ -124,11 +124,9 @@ static int woal_associate_ssid_bssid(moal_private *priv, struct iwreq *wrq)
if (buf[i] == ':') {
mac_idx++;
} else {
if (mac_idx < ETH_ALEN) {
// coverity[tainted_data: SUPPRESS]
if (mac_idx < ETH_ALEN)
ssid_bssid->bssid[mac_idx] =
(t_u8)woal_atox(buf + i);
}
while ((i < buflen) && (isxdigit(buf[i + 1]))) {
/* Skip entire hex value */
@ -2753,6 +2751,8 @@ static int woal_drv_dbg(moal_private *priv, struct iwreq *wrq)
(drvdbg & MCMD_D) ? "X" : "");
printk(KERN_ALERT "MDAT_D (%08x) %s\n", MDAT_D,
(drvdbg & MDAT_D) ? "X" : "");
printk(KERN_ALERT "MREG (%08x) %s\n", MREG,
(drvdbg & MREG) ? "X" : "");
printk(KERN_ALERT "MREG_D (%08x) %s\n", MREG_D,
(drvdbg & MREG_D) ? "X" : "");
printk(KERN_ALERT "MIOCTL (%08x) %s\n", MIOCTL,
@ -2960,6 +2960,94 @@ done:
return ret;
}
/**
* @brief Set/Get module configuration
*
* @param priv A pointer to moal_private structure
* @param wrq A pointer to iwreq structure
*
* @return 0 --success, otherwise fail
*/
static int woal_fw_wakeup_method(moal_private *priv, struct iwreq *wrq)
{
int ret = 0, data[2];
mlan_ds_pm_cfg *pm_cfg = NULL;
mlan_ioctl_req *req = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
ENTER();
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
if (req == NULL) {
ret = -ENOMEM;
goto done;
}
pm_cfg = (mlan_ds_pm_cfg *)req->pbuf;
if (wrq->u.data.length > 2) {
ret = -EINVAL;
goto done;
}
if (!wrq->u.data.length) {
req->action = MLAN_ACT_GET;
} else {
req->action = MLAN_ACT_SET;
if (copy_from_user(data, wrq->u.data.pointer,
sizeof(int) * wrq->u.data.length)) {
PRINTM(MINFO, "Copy from user failed\n");
ret = -EFAULT;
goto done;
}
if (data[0] != FW_WAKEUP_METHOD_INTERFACE &&
data[0] != FW_WAKEUP_METHOD_GPIO) {
PRINTM(MERROR, "Invalid FW wake up method:%d\n",
data[0]);
ret = -EINVAL;
goto done;
}
if (data[0] == FW_WAKEUP_METHOD_GPIO) {
if (wrq->u.data.length == 1) {
PRINTM(MERROR,
"Please provide gpio pin number for FW_WAKEUP_METHOD gpio\n");
ret = -EINVAL;
goto done;
}
pm_cfg->param.fw_wakeup_params.gpio_pin = data[1];
}
pm_cfg->param.fw_wakeup_params.method = data[0];
}
pm_cfg->sub_command = MLAN_OID_PM_CFG_FW_WAKEUP_METHOD;
req->req_id = MLAN_IOCTL_PM_CFG;
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
ret = -EFAULT;
goto done;
}
data[0] = ((mlan_ds_pm_cfg *)req->pbuf)->param.fw_wakeup_params.method;
data[1] =
((mlan_ds_pm_cfg *)req->pbuf)->param.fw_wakeup_params.gpio_pin;
if (data[0] == FW_WAKEUP_METHOD_INTERFACE)
wrq->u.data.length = 1;
else
wrq->u.data.length = 2;
if (copy_to_user(wrq->u.data.pointer, data,
sizeof(int) * wrq->u.data.length)) {
ret = -EFAULT;
goto done;
}
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return ret;
}
/**
* @brief Configure sleep parameters
*
@ -6372,7 +6460,15 @@ static int woal_set_get_tx_rx_ant(moal_private *priv, struct iwreq *wrq)
if (priv->phandle->feature_control & FEATURE_CTRL_STREAM_2X2) {
radio->param.ant_cfg.tx_antenna = data[0];
radio->param.ant_cfg.rx_antenna = data[0];
if (data[0] == RF_ANTENNA_AUTO) {
radio->param.ant_cfg.rx_antenna = 0;
if (data[1] > 0xffff) {
ret = -EINVAL;
goto done;
}
} else {
radio->param.ant_cfg.rx_antenna = data[0];
}
if (wrq->u.data.length == 2)
radio->param.ant_cfg.rx_antenna = data[1];
} else {
@ -6615,6 +6711,9 @@ int woal_wext_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
case WOAL_SLEEP_PD:
ret = woal_sleep_pd(priv, wrq);
break;
case WOAL_FW_WAKEUP_METHOD:
ret = woal_fw_wakeup_method(priv, wrq);
break;
case WOAL_AUTH_TYPE:
ret = woal_auth_type(priv, wrq);
break;

View file

@ -170,6 +170,8 @@ Change log:
#define WOAL_SET_GET_WWS_CFG 12
/** Private command ID to set/get sleep period */
#define WOAL_SLEEP_PD 13
/** Private command ID to set/get firmware wakeup method */
#define WOAL_FW_WAKEUP_METHOD 15
/** Private command ID to set/get auth type */
#define WOAL_AUTH_TYPE 18
/** Private command ID to set/get port control */

View file

@ -236,7 +236,7 @@ static int woal_info_proc_read(struct seq_file *sfp, void *data)
for (i = 0; i < (int)netdev->num_tx_queues; i++) {
seq_printf(sfp, "tx queue %d: %s\n", i,
((netif_tx_queue_stopped(
netdev_get_tx_queue(netdev, 0))) ?
netdev_get_tx_queue(netdev, i))) ?
"stopped" :
"started"));
}
@ -558,7 +558,16 @@ static mlan_status woal_priv_set_tx_rx_ant(moal_handle *handle, char *line)
if (handle->feature_control & FEATURE_CTRL_STREAM_2X2) {
radio->param.ant_cfg.tx_antenna = data[0];
radio->param.ant_cfg.rx_antenna = data[0];
if (data[0] == RF_ANTENNA_AUTO) {
radio->param.ant_cfg.rx_antenna = 0;
if (data[1] > 0xffff) {
kfree(req);
LEAVE();
return MLAN_STATUS_FAILURE;
}
} else {
radio->param.ant_cfg.rx_antenna = data[0];
}
if (user_data_len == 2)
radio->param.ant_cfg.rx_antenna = data[1];
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
@ -601,9 +610,11 @@ static mlan_status woal_priv_set_tx_rx_ant(moal_handle *handle, char *line)
static ssize_t woal_config_write(struct file *f, const char __user *buf,
size_t count, loff_t *off)
{
char databuf[200];
char *databuf = NULL;
char *line = NULL;
int ret = 0;
gfp_t flag;
t_u32 config_data = 0;
struct seq_file *sfp = f->private_data;
moal_handle *handle = (moal_handle *)sfp->private;
@ -622,15 +633,17 @@ static ssize_t woal_config_write(struct file *f, const char __user *buf,
return 0;
}
if (count >= sizeof(databuf)) {
MODULE_PUT;
flag = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL;
databuf = kzalloc(count, flag);
if (databuf == NULL) {
LEAVE();
return (int)count;
return -ENOMEM;
}
memset(databuf, 0, sizeof(databuf));
copy_len = MIN((sizeof(databuf) - 1), count);
if (copy_from_user(databuf, buf, copy_len)) {
copy_len = count;
if (copy_from_user(databuf, buf, count)) {
MODULE_PUT;
kfree(databuf);
LEAVE();
return 0;
}
@ -692,7 +705,7 @@ static ssize_t woal_config_write(struct file *f, const char __user *buf,
if (!strncmp(databuf, "fwdump_file=", strlen("fwdump_file="))) {
int len = copy_len - strlen("fwdump_file=");
gfp_t flag;
if (len) {
if (len > 0) {
kfree(handle->fwdump_fname);
flag = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC :
GFP_KERNEL;
@ -806,9 +819,13 @@ static ssize_t woal_config_write(struct file *f, const char __user *buf,
cmd = MFG_CMD_CONFIG_TRIGGER_FRAME;
if (!strncmp(databuf,
"otp_mac_addr_rd_wr=", strlen("otp_mac_add_rd_wr=")) &&
count > strlen("otp_mac_addr_rd_wr=")) {
count > strlen("otp_mac_addr_rd_wr="))
cmd = MFG_CMD_OTP_MAC_ADD;
}
if (!strncmp(databuf,
"otp_cal_data_rd_wr=", strlen("otp_cal_data_rd_wr=")) &&
count > strlen("otp_cal_data_rd_wr="))
cmd = MFG_CMD_OTP_CAL_DATA;
if (cmd && handle->rf_test_mode &&
(woal_process_rf_test_mode_cmd(
handle, cmd, (const char *)databuf, (size_t)count,
@ -826,6 +843,7 @@ static ssize_t woal_config_write(struct file *f, const char __user *buf,
}
MODULE_PUT;
kfree(databuf);
LEAVE();
if (ret < 0)
return ret;
@ -1630,7 +1648,7 @@ void woal_create_proc_entry(moal_private *priv)
atomic_inc(&(priv->phandle->proc_wlan->count));
#endif /* < 3.10.0 */
#endif /* < 2.6.26 */
strncpy(priv->proc_entry_name, dev->name, IFNAMSIZ);
strncpy(priv->proc_entry_name, dev->name, IFNAMSIZ - 1);
if (priv->proc_entry) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
r = proc_create_data("info", 0, priv->proc_entry,

View file

@ -154,10 +154,15 @@ Change log:
#endif /* SDIW624 */
#ifdef SDAW693
#define SDAW693_A0 0x00
#define SDAW693_A1 0x01
#define SDAW693_DEFAULT_COMBO_FW_NAME "nxp/sdsdwaw693_combo.bin"
#define SDUARTAW693_COMBO_FW_NAME "nxp/sduartw693_combo.bin"
#define SDSDAW693_COMBO_FW_NAME "sdsdaw693_combo.bin"
#define SDUARTAW693_COMBO_V1_FW_NAME "nxp/sduartw693_combo_v1.bin.se"
#define SDSDAW693_COMBO_V1_FW_NAME "sdsdaw693_combo_v1.bin.se"
#define SDAW693_DEFAULT_WLAN_FW_NAME "nxp/sdaw693_wlan.bin"
#define SDAW693_WLAN_V1_FW_NAME "nxp/sdaw693_wlan_v1.bin.se"
#endif /* SDAW693 */
#ifdef SD9177
@ -177,12 +182,12 @@ Change log:
#define SD9177_DEFAULT_RFTM_WLAN_V1_FW_NAME "nxp/sd_w61x_rftm_v1.bin.se"
#endif /* SD9177 */
#ifdef SDIW615
#define SDIW615_DEFAULT_COMBO_FW_NAME "nxp/sdsdiw615_combo.bin"
#define SDUARTIW615_COMBO_FW_NAME "nxp/sduartiw615_combo.bin"
#define SDSDIW615_COMBO_FW_NAME "sdsdiw615_combo.bin"
#define SDIW615_DEFAULT_WLAN_FW_NAME "nxp/sdiw615_wlan.bin"
#endif /* SDIW615 */
#ifdef SDIW610
#define SDIW610_DEFAULT_COMBO_FW_NAME "nxp/sduartspi_iw610.bin.se"
#define SDUARTIW610_COMBO_FW_NAME "nxp/sduart_iw610.bin.se"
#define SDUARTSPIIW610_COMBO_FW_NAME "nxp/sduartspi_iw610.bin.se"
#define SDIW610_DEFAULT_WLAN_FW_NAME "nxp/sd_iw610.bin.se"
#endif /* SDIW610 */
/********************************************************
Global Functions
@ -220,6 +225,20 @@ typedef struct _sdio_mmc_card {
t_u8 work_flags;
/** saved host clock value */
unsigned int host_clock;
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 11, 0)
/** oob irq */
int oob_irq;
/** irq enabled */
int irq_enabled;
/** sdio func intr enabled **/
int sdio_func_intr_enabled;
/** irq registered */
int irq_registered;
/* SDIO OOB Interrupt handling workqueue */
struct workqueue_struct *sdio_oob_irq_workqueue;
/* SDIO OOB Interrupt handler work */
struct work_struct sdio_oob_irq_work;
#endif
} sdio_mmc_card;
void woal_sdio_reset_hw(moal_handle *handle);
#endif /* SDIO_MMC */

View file

@ -36,10 +36,22 @@ Change log:
#include <net/addrconf.h>
#endif
#endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 11, 0)
#include <linux/gpio.h>
#include <uapi/linux/sched/types.h>
#endif
/** define nxp vendor id */
#define NXP_VENDOR_ID 0x0471
#define MRVL_VENDOR_ID 0x02df
/* The macros below are hardware platform dependent.
The definition should match the actual platform */
/** Initialize GPIO port */
#define GPIO_PORT_INIT()
/** Set GPIO port to high */
#define GPIO_PORT_TO_HIGH()
/** Set GPIO port to low */
#define GPIO_PORT_TO_LOW()
/********************************************************
Local Variables
@ -102,9 +114,9 @@ static moal_if_ops sdiommc_ops;
/** Device ID for SDIW624 */
#define SD_DEVICE_ID_IW624 (0x020D)
#endif
#ifdef SDIW615
/** Device ID for SDIW615 */
#define SD_DEVICE_ID_IW615 (0x020D)
#ifdef SDIW610
/** Device ID for SDIW610 */
#define SD_DEVICE_ID_IW610 (0x0215)
#endif
/** WLAN IDs */
@ -147,8 +159,8 @@ static const struct sdio_device_id wlan_ids[] = {
#ifdef SDIW624
{SDIO_DEVICE(NXP_VENDOR_ID, SD_DEVICE_ID_IW624)},
#endif
#ifdef SDIW615
{SDIO_DEVICE(NXP_VENDOR_ID, SD_DEVICE_ID_IW615)},
#ifdef SDIW610
{SDIO_DEVICE(NXP_VENDOR_ID, SD_DEVICE_ID_IW610)},
#endif
{},
};
@ -208,6 +220,7 @@ static struct sdio_driver REFDATA wlan_sdio = {
Local Functions
********************************************************/
static void woal_sdiommc_dump_fw_info(moal_handle *phandle);
static void woal_trigger_nmi_on_no_dump_event(moal_handle *phandle);
#if 0
/** @brief This function dump the sdio register
*
@ -310,6 +323,245 @@ static void woal_sdio_interrupt(struct sdio_func *func)
LEAVE();
}
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 11, 0)
/**
* @brief This work handles oob sdio top irq.
*/
static void woal_sdio_oob_irq_work(struct work_struct *work)
{
sdio_mmc_card *card =
container_of(work, sdio_mmc_card, sdio_oob_irq_work);
struct mmc_card *mmc_card = card->func->card;
struct sdio_func *func;
unsigned char pending;
int i;
int ret;
for (i = 0; i < mmc_card->sdio_funcs; i++) {
func = NULL;
if (mmc_card->sdio_func[i]) {
func = mmc_card->sdio_func[i];
}
if (func) {
sdio_claim_host(func);
pending = sdio_f0_readb(func, SDIO_CCCR_INTx, &ret);
if (!ret && pending && func->irq_handler)
func->irq_handler(func);
sdio_release_host(func);
}
}
if (card->irq_registered && !card->irq_enabled) {
card->irq_enabled = MTRUE;
enable_irq(card->oob_irq);
}
}
/**
* @brief oob_sdio_irq interrupt handler.
*
* @param irq irq
* @param dev_id a pointer to structure sdio_mmc_card
* @return IRQ_HANDLED
*/
static irqreturn_t oob_sdio_irq(int irq, void *dev_id)
{
sdio_mmc_card *card = (sdio_mmc_card *)dev_id;
if (card->sdio_func_intr_enabled) {
disable_irq_nosync(card->oob_irq);
card->irq_enabled = MFALSE;
queue_work(card->sdio_oob_irq_workqueue,
&card->sdio_oob_irq_work);
}
return IRQ_HANDLED;
}
/**
* @brief This function registers oob_sdio_irq
*
* @param card a pointer to sdio_mmc_card
* @return 0-success else failure
*/
static int oob_sdio_irq_register(sdio_mmc_card *card)
{
int ret = 0;
ret = devm_request_irq(card->handle->hotplug_device, card->oob_irq,
oob_sdio_irq, IRQF_TRIGGER_LOW | IRQF_SHARED,
"nxp_oob_sdio_irq", card);
if (!ret) {
card->irq_registered = MTRUE;
card->irq_enabled = MTRUE;
enable_irq_wake(card->oob_irq);
}
return ret;
}
/**
* @brief This function unregister oob_sdio_irq
*
* @param card a pointer to sdio_mmc_card
* @return N/A
*/
static void oob_sdio_irq_unregister(sdio_mmc_card *card)
{
if (card->irq_registered) {
card->irq_registered = MFALSE;
disable_irq_wake(card->oob_irq);
if (card->irq_enabled) {
disable_irq(card->oob_irq);
card->irq_enabled = MFALSE;
}
devm_free_irq(card->handle->hotplug_device, card->oob_irq,
card);
}
}
/**
* @brief This function enable interrupt in SDIO Func0 SDIO_CCCR_IENx
*
* @param func a pointer to struct sdio_func
* @param handler sdio_irq_handler
* @return 0-success else failure
*/
static int sdio_func_intr_enable(struct sdio_func *func,
sdio_irq_handler_t *handler)
{
int ret;
unsigned char reg;
#ifdef MMC_QUIRK_LENIENT_FN0
func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
#endif
reg = sdio_f0_readb(func, SDIO_CCCR_IENx, &ret);
if (ret)
return ret;
reg |= 1 << func->num;
reg |= 1;
sdio_f0_writeb(func, reg, SDIO_CCCR_IENx, &ret);
if (ret)
return ret;
func->irq_handler = handler;
return ret;
}
/**
* @brief This function disable interrupt in SDIO Func0 SDIO_CCCR_IENx
*
* @param func a pointer to struct sdio_func
* @return 0-success else failure
*/
static int sdio_func_intr_disable(struct sdio_func *func)
{
int ret;
unsigned char reg;
#ifdef MMC_QUIRK_LENIENT_FN0
func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
#endif
if (func->irq_handler)
func->irq_handler = NULL;
reg = sdio_f0_readb(func, SDIO_CCCR_IENx, &ret);
if (ret)
return ret;
reg &= ~(1 << func->num);
if (!(reg & 0xFE))
reg = 0;
sdio_f0_writeb(func, reg, SDIO_CCCR_IENx, &ret);
return ret;
}
/**
* @brief This function claim the oob sdio irq
*
* @param card a pointer to sdio_mmc_card
* @param handler sdio_irq_handler
* @return 0-success else failure
*/
static int woal_sdio_claim_irq(sdio_mmc_card *card, sdio_irq_handler_t *handler)
{
int ret;
struct sdio_func *func = card->func;
BUG_ON(!func);
BUG_ON(!func->card);
card->sdio_oob_irq_workqueue = alloc_ordered_workqueue(
"SDIO_OOB_IRQ_WORKQ",
__WQ_LEGACY | WQ_MEM_RECLAIM | WQ_HIGHPRI);
MLAN_INIT_WORK(&card->sdio_oob_irq_work, woal_sdio_oob_irq_work);
ret = oob_sdio_irq_register(card);
if (ret) {
destroy_workqueue(card->sdio_oob_irq_workqueue);
card->sdio_oob_irq_workqueue = NULL;
return ret;
}
ret = sdio_func_intr_enable(func, handler);
if (ret) {
oob_sdio_irq_unregister(card);
destroy_workqueue(card->sdio_oob_irq_workqueue);
card->sdio_oob_irq_workqueue = NULL;
}
card->sdio_func_intr_enabled = MTRUE;
return ret;
}
/**
* @brief This function release the oob sdio irq
*
* @param card a pointer to sdio_mmc_card
* @return 0-success else failure
*/
static int woal_sdio_release_irq(sdio_mmc_card *card)
{
struct sdio_func *func = card->func;
BUG_ON(!func);
BUG_ON(!func->card);
oob_sdio_irq_unregister(card);
flush_workqueue(card->sdio_oob_irq_workqueue);
destroy_workqueue(card->sdio_oob_irq_workqueue);
card->sdio_oob_irq_workqueue = NULL;
if (card->sdio_func_intr_enabled) {
sdio_func_intr_disable(func);
card->sdio_func_intr_enabled = MFALSE;
}
return 0;
}
/**
* @brief This function request oob gpio
*
* @param card a pointer to sdio_mmc_card
* @param oob_gpio oob gpio
* @return 0-success else failure
*/
static int woal_request_gpio(sdio_mmc_card *card, t_u8 oob_gpio)
{
#if defined(IMX_SUPPORT)
struct device_node *node;
node = of_find_compatible_node(NULL, NULL, "nxp,wifi-oob-int");
if (!node)
return -1;
card->oob_irq = irq_of_parse_and_map(node, 0);
PRINTM(MMSG, "SDIO OOB IRQ: %d", card->oob_irq);
return 0;
#else
return -1;
#endif
}
#endif
/** @brief This function updates the card types
*
* @param handle A Pointer to the moal_handle structure
@ -494,11 +746,11 @@ static t_u16 woal_update_card_type(t_void *card)
(strlen(INTF_CARDTYPE) + strlen(KERN_VERSION)));
}
#endif
#ifdef SDIW615
if (cardp_sd->func->device == SD_DEVICE_ID_IW615) {
card_type = CARD_TYPE_SDIW615;
moal_memcpy_ext(NULL, driver_version, CARD_SDIW615,
strlen(CARD_SDIW615), strlen(driver_version));
#ifdef SDIW610
if (cardp_sd->func->device == SD_DEVICE_ID_IW610) {
card_type = CARD_TYPE_SDIW610;
moal_memcpy_ext(NULL, driver_version, CARD_SDIW610,
strlen(CARD_SDIW610), strlen(driver_version));
moal_memcpy_ext(
NULL,
driver_version + strlen(INTF_CARDTYPE) +
@ -625,7 +877,9 @@ void woal_sdio_remove(struct sdio_func *func)
/* check if woal_sdio_interrupt() is running */
while (card->handle->main_state !=
MOAL_END_MAIN_PROCESS)
MOAL_END_MAIN_PROCESS &&
card->handle->main_state !=
MOAL_STATE_IDLE)
woal_sched_timeout(2); /* wait until
woal_sdio_interrupt
ends */
@ -825,9 +1079,7 @@ int woal_sdio_suspend(struct device *dev)
#ifdef MMC_PM_FUNC_SUSPENDED
handle->suspend_notify_req = MTRUE;
#endif
/* add delay to wait kernel complete cfg80211_disconnect*/
woal_sched_timeout(200);
hs_actived = woal_enable_hs(
woal_get_priv(handle, MLAN_BSS_ROLE_ANY));
#ifdef MMC_PM_FUNC_SUSPENDED
@ -943,6 +1195,7 @@ static mlan_status woal_sdiommc_write_reg(moal_handle *handle, t_u32 reg,
sdio_writeb(((sdio_mmc_card *)handle->card)->func, (t_u8)data, reg,
(int *)&ret);
sdio_release_host(((sdio_mmc_card *)handle->card)->func);
PRINTM(MREG, "sdio w %x = %x (%x)\n", reg, data, ret);
return ret;
}
@ -965,6 +1218,7 @@ static mlan_status woal_sdiommc_read_reg(moal_handle *handle, t_u32 reg,
(int *)&ret);
sdio_release_host(((sdio_mmc_card *)handle->card)->func);
*data = val;
PRINTM(MREG, "sdio r %x = %x (%x)\n", reg, *data, ret);
return ret;
}
@ -985,6 +1239,7 @@ static mlan_status woal_sdio_writeb(moal_handle *handle, t_u32 reg, t_u8 data)
sdio_writeb(((sdio_mmc_card *)handle->card)->func, (t_u8)data, reg,
(int *)&ret);
sdio_release_host(((sdio_mmc_card *)handle->card)->func);
PRINTM(MREG, "sdio w %x = %x (%x)\n", reg, data, ret);
return ret;
}
@ -1006,6 +1261,7 @@ static mlan_status woal_sdio_readb(moal_handle *handle, t_u32 reg, t_u8 *data)
(int *)&ret);
sdio_release_host(((sdio_mmc_card *)handle->card)->func);
*data = val;
PRINTM(MREG, "sdio r %x = %x (%x)\n", reg, *data, ret);
return ret;
}
@ -1029,6 +1285,7 @@ static mlan_status woal_sdio_f0_readb(moal_handle *handle, t_u32 reg,
(int *)&ret);
sdio_release_host(((sdio_mmc_card *)handle->card)->func);
*data = val;
PRINTM(MREG, "sdio f0 r %x = %x (%x)\n", reg, *data, ret);
return ret;
}
@ -1232,6 +1489,11 @@ mlan_status woal_sdiommc_bus_register(void)
return MLAN_STATUS_FAILURE;
}
/* init GPIO PORT for wakeup purpose */
GPIO_PORT_INIT();
/* set default value */
GPIO_PORT_TO_HIGH();
LEAVE();
return ret;
}
@ -1267,7 +1529,12 @@ static void woal_sdiommc_unregister_dev(moal_handle *handle)
#endif
/* Release the SDIO IRQ */
sdio_claim_host(card->func);
sdio_release_irq(card->func);
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 11, 0)
if (moal_extflg_isset(handle, EXT_INTMODE))
woal_sdio_release_irq(card);
else
#endif
sdio_release_irq(card->func);
sdio_disable_func(card->func);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
if (handle->driver_status)
@ -1281,6 +1548,7 @@ static void woal_sdiommc_unregister_dev(moal_handle *handle)
sdio_set_drvdata(card->func, NULL);
GPIO_PORT_TO_LOW();
PRINTM(MWARN, "Making the sdio dev card as NULL\n");
card->handle = NULL;
}
@ -1302,12 +1570,26 @@ static mlan_status woal_sdiommc_register_dev(moal_handle *handle)
ENTER();
GPIO_PORT_INIT();
GPIO_PORT_TO_HIGH();
/* save adapter pointer in card */
card->handle = handle;
func = card->func;
sdio_claim_host(func);
/* Request the SDIO IRQ */
ret = sdio_claim_irq(func, woal_sdio_interrupt);
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 11, 0)
if (moal_extflg_isset(handle, EXT_INTMODE)) {
ret = woal_request_gpio(card, card->handle->params.gpiopin);
if (ret) {
PRINTM(MERROR, "Fail to request gpio\n");
goto release_host;
}
ret = woal_sdio_claim_irq(card, woal_sdio_interrupt);
} else
#endif
ret = sdio_claim_irq(func, woal_sdio_interrupt);
if (ret) {
PRINTM(MFATAL, "sdio_claim_irq failed: ret=%d\n", ret);
goto release_host;
@ -1329,7 +1611,12 @@ static mlan_status woal_sdiommc_register_dev(moal_handle *handle)
return MLAN_STATUS_SUCCESS;
release_irq:
sdio_release_irq(func);
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 11, 0)
if (moal_extflg_isset(handle, EXT_INTMODE))
woal_sdio_release_irq(card);
else
#endif
sdio_release_irq(func);
release_host:
sdio_release_host(func);
handle->card = NULL;
@ -1496,7 +1783,7 @@ static mlan_status woal_sdiommc_get_fw_name(moal_handle *handle)
#if defined(SD8987) || defined(SD8997) || defined(SD9098) || \
defined(SD9097) || defined(SDIW624) || defined(SDAW693) || \
defined(SD8978) || defined(SD9177) || defined(SDIW615)
defined(SD8978) || defined(SD9177) || defined(SDIW610)
t_u32 magic_reg = handle->card_info->magic_reg;
t_u32 magic = 0;
t_u32 host_strap_reg = handle->card_info->host_strap_reg;
@ -1517,7 +1804,7 @@ static mlan_status woal_sdiommc_get_fw_name(moal_handle *handle)
#if defined(SD8987) || defined(SD8997) || defined(SD9098) || \
defined(SD9097) || defined(SDIW624) || defined(SDAW693) || \
defined(SD8978) || defined(SD9177) || defined(SDIW615)
defined(SD8978) || defined(SD9177) || defined(SDIW610)
/** Revision ID register */
woal_sdiommc_read_reg(handle, magic_reg, &magic);
/** Revision ID register */
@ -1684,7 +1971,12 @@ static mlan_status woal_sdiommc_get_fw_name(moal_handle *handle)
#endif
#ifdef SDAW693
if (IS_SDAW693(handle->card_type)) {
if (magic == CHIP_MAGIC_VALUE) {
magic &= 0x03;
if (magic == 0x03)
PRINTM(MMSG, "wlan: SDAW693 in secure-boot mode\n");
switch (revision_id) {
case SDAW693_A0:
if (strap == CARD_TYPE_SD_UART)
strncpy(handle->card_info->fw_name,
SDUARTAW693_COMBO_FW_NAME,
@ -1693,6 +1985,36 @@ static mlan_status woal_sdiommc_get_fw_name(moal_handle *handle)
strncpy(handle->card_info->fw_name,
SDSDAW693_COMBO_FW_NAME,
FW_NAMW_MAX_LEN);
strncpy(handle->card_info->fw_name_wlan,
SDAW693_DEFAULT_WLAN_FW_NAME, FW_NAMW_MAX_LEN);
break;
case SDAW693_A1:
if (strap == CARD_TYPE_SD_UART)
strncpy(handle->card_info->fw_name,
SDUARTAW693_COMBO_V1_FW_NAME,
FW_NAMW_MAX_LEN);
else
strncpy(handle->card_info->fw_name,
SDSDAW693_COMBO_V1_FW_NAME,
FW_NAMW_MAX_LEN);
strncpy(handle->card_info->fw_name_wlan,
SDAW693_WLAN_V1_FW_NAME, FW_NAMW_MAX_LEN);
if (magic != 0x03) {
/* remove extension .se */
if (strstr(handle->card_info->fw_name, ".se"))
memset(strstr(handle->card_info->fw_name,
".se"),
'\0', sizeof(".se"));
if (strstr(handle->card_info->fw_name_wlan,
".se"))
memset(strstr(handle->card_info
->fw_name_wlan,
".se"),
'\0', sizeof(".se"));
}
break;
default:
break;
}
}
#endif
@ -1785,15 +2107,33 @@ static mlan_status woal_sdiommc_get_fw_name(moal_handle *handle)
}
#endif
#ifdef SDIW615
if (IS_SDIW615(handle->card_type)) {
if (magic == CHIP_MAGIC_VALUE) {
if (strap == CARD_TYPE_SD_UART)
strcpy(handle->card_info->fw_name,
SDUARTIW615_COMBO_FW_NAME);
#ifdef SDIW610
if (IS_SDIW610(handle->card_type)) {
magic &= 0x03;
if (magic == 0x03)
PRINTM(MMSG, "wlan: SDIW610 in secure-boot mode\n");
if (strap == CARD_TYPE_SDIW610_UART) {
if (handle->params.dual_nb)
strncpy(handle->card_info->fw_name,
SDUARTSPIIW610_COMBO_FW_NAME,
FW_NAMW_MAX_LEN);
else
strcpy(handle->card_info->fw_name,
SDSDIW615_COMBO_FW_NAME);
strncpy(handle->card_info->fw_name,
SDUARTIW610_COMBO_FW_NAME,
FW_NAMW_MAX_LEN);
}
strncpy(handle->card_info->fw_name_wlan,
SDIW610_DEFAULT_WLAN_FW_NAME, FW_NAMW_MAX_LEN);
if (magic != 0x03) {
/* remove extension .se */
if (strstr(handle->card_info->fw_name, ".se"))
memset(strstr(handle->card_info->fw_name,
".se"),
'\0', sizeof(".se"));
if (strstr(handle->card_info->fw_name_wlan, ".se"))
memset(strstr(handle->card_info->fw_name_wlan,
".se"),
'\0', sizeof(".se"));
}
}
#endif
@ -2915,7 +3255,12 @@ void woal_sdio_reset_hw(moal_handle *handle)
struct sdio_func *func = card->func;
ENTER();
sdio_claim_host(func);
sdio_release_irq(card->func);
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 11, 0)
if (moal_extflg_isset(handle, EXT_INTMODE))
woal_sdio_release_irq(card);
else
#endif
sdio_release_irq(card->func);
sdio_disable_func(card->func);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
@ -2941,7 +3286,12 @@ void woal_sdio_reset_hw(moal_handle *handle)
func->enable_timeout = 200;
#endif
sdio_enable_func(func);
sdio_claim_irq(func, woal_sdio_interrupt);
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 11, 0)
if (moal_extflg_isset(handle, EXT_INTMODE))
woal_sdio_claim_irq(card, woal_sdio_interrupt);
else
#endif
sdio_claim_irq(func, woal_sdio_interrupt);
sdio_set_block_size(card->func, MLAN_SDIO_BLOCK_SIZE);
sdio_release_host(func);
LEAVE();
@ -2972,7 +3322,7 @@ static int woal_sdiommc_reset_fw(moal_handle *handle)
ret = -EFAULT;
goto done;
}
udelay(4000);
/** wait SOC fully wake up */
for (tries = 0; tries < MAX_POLL_TRIES; ++tries) {
ret = handle->ops.write_reg(handle, reset_reg, 0xba);
@ -2993,10 +3343,10 @@ static int woal_sdiommc_reset_fw(moal_handle *handle)
goto done;
}
#if defined(SD9098) || defined(SD9097) || defined(SDIW624) || \
defined(SDAW693) || defined(SD9177) || defined(SDIW615)
defined(SDAW693) || defined(SD9177) || defined(SDIW610)
if (IS_SD9098(handle->card_type) || IS_SD9097(handle->card_type) ||
IS_SDIW624(handle->card_type) || IS_SD9177(handle->card_type) ||
IS_SDIW615(handle->card_type) || IS_SDAW693(handle->card_type))
IS_SDIW610(handle->card_type) || IS_SDAW693(handle->card_type))
handle->ops.write_reg(handle, 0x00, 0x10);
#endif
/* Poll register around 100 ms */
@ -3058,6 +3408,12 @@ static mlan_status woal_do_sdiommc_flr(moal_handle *handle, bool prepare,
if (!prepare)
goto perform_init;
if (!(handle->pmlan_adapter)) {
PRINTM(MINFO, "\n Handle null 2 during prepare=%d\n", prepare);
LEAVE();
return status;
}
/* Reset all interfaces */
priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY);
mlan_disable_host_int(handle->pmlan_adapter);

View file

@ -225,7 +225,8 @@ mlan_status moal_malloc_consistent(t_void *pmoal, t_u32 size, t_u8 **ppbuf,
return MLAN_STATUS_FAILURE;
}
#ifdef PCIEAW693
if (IS_PCIEAW693(handle->card_type))
if (IS_PCIEAW693(handle->card_type) &&
(handle->card_rev == CHIP_AW693_REV_A0))
dma |= 0x100000000;
#endif
*pbuf_pa = (t_u64)dma;
@ -253,7 +254,8 @@ mlan_status moal_mfree_consistent(t_void *pmoal, t_u32 size, t_u8 *pbuf,
if (!pbuf || !card)
return MLAN_STATUS_FAILURE;
#ifdef PCIEAW693
if (IS_PCIEAW693(handle->card_type))
if (IS_PCIEAW693(handle->card_type) &&
(handle->card_rev == CHIP_AW693_REV_A0))
buf_pa &= 0xffffffff;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
@ -301,7 +303,8 @@ mlan_status moal_map_memory(t_void *pmoal, t_u8 *pbuf, t_u64 *pbuf_pa,
return MLAN_STATUS_FAILURE;
}
#ifdef PCIEAW693
if (IS_PCIEAW693(handle->card_type))
if (IS_PCIEAW693(handle->card_type) &&
(handle->card_rev == CHIP_AW693_REV_A0))
dma |= 0x100000000;
#endif
*pbuf_pa = dma;
@ -328,7 +331,8 @@ mlan_status moal_unmap_memory(t_void *pmoal, t_u8 *pbuf, t_u64 buf_pa,
if (!card)
return MLAN_STATUS_FAILURE;
#ifdef PCIEAW693
if (IS_PCIEAW693(handle->card_type))
if (IS_PCIEAW693(handle->card_type) &&
(handle->card_rev == CHIP_AW693_REV_A0))
buf_pa &= 0xffffffff;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
@ -1055,11 +1059,17 @@ mlan_status moal_ioctl_complete(t_void *pmoal, pmlan_ioctl_req pioctl_req,
}
if (status != MLAN_STATUS_SUCCESS && status != MLAN_STATUS_COMPLETE)
PRINTM(MERROR,
"IOCTL failed: %p id=0x%x, sub_id=0x%x action=%d, status_code=0x%x\n",
pioctl_req, pioctl_req->req_id,
(*(t_u32 *)pioctl_req->pbuf), (int)pioctl_req->action,
pioctl_req->status_code);
if (handle->rf_test_mode == MTRUE)
PRINTM(MERROR,
"Operation id=0x%x not allowed in rf-mode\n",
pioctl_req->req_id);
else
PRINTM(MERROR,
"IOCTL failed: %p id=0x%x, sub_id=0x%x action=%d, status_code=0x%x\n",
pioctl_req, pioctl_req->req_id,
(*(t_u32 *)pioctl_req->pbuf),
(int)pioctl_req->action,
pioctl_req->status_code);
else
PRINTM(MIOCTL,
"IOCTL completed: %p id=0x%x sub_id=0x%x, action=%d, status=%d, status_code=0x%x\n",
@ -1209,7 +1219,7 @@ mlan_status moal_send_packet_complete(t_void *pmoal, pmlan_buffer pmbuf,
atomic_dec(&handle->tx_pending);
if (atomic_dec_return(
&priv->wmm_tx_pending[index]) ==
LOW_TX_PENDING) {
priv->low_tx_pending) {
struct netdev_queue *txq =
netdev_get_tx_queue(
priv->netdev,
@ -2114,6 +2124,10 @@ mlan_status moal_recv_amsdu_packet(t_void *pmoal, pmlan_buffer pmbuf)
}
frame->protocol = eth_type_trans(frame, netdev);
frame->ip_summed = CHECKSUM_NONE;
priv->stats.rx_bytes += frame->len;
priv->stats.rx_packets++;
if (in_interrupt())
netif_rx(frame);
else {
@ -2322,9 +2336,10 @@ mlan_status moal_recv_packet(t_void *pmoal, pmlan_buffer pmbuf)
}
#endif
#endif
if (priv->multi_ap_flag &&
priv->bss_type == MLAN_BSS_TYPE_STA) {
if (priv->wdev->use_4addr &&
priv->wdev->iftype == NL80211_IFTYPE_STATION) {
t_u32 transaction_id;
t_u32 hash_key;
transaction_id =
woal_get_dhcp_discover_transation_id(
skb);
@ -2337,6 +2352,23 @@ mlan_status moal_recv_packet(t_void *pmoal, pmlan_buffer pmbuf)
dev_kfree_skb(skb);
goto done;
}
hash_key = woal_generate_arp_request_hash(skb);
// TODO: Drop too old entry
if (hash_key) {
struct arp_entry *node;
hash_for_each_possible (priv->hlist,
node, arp_hlist,
hash_key) {
if (node->hash_key ==
hash_key) {
PRINTM(MDATA,
"ARP entry exists, drop pkt\n");
dev_kfree_skb(skb);
goto done;
}
}
}
}
if (!netdev)
netdev = priv->netdev;
@ -3043,12 +3075,6 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent)
case MLAN_EVENT_ID_DRV_SCAN_REPORT:
PRINTM(MINFO, "Scan report\n");
if (priv->phandle->scan_pending_on_block == MTRUE) {
priv->phandle->scan_pending_on_block = MFALSE;
priv->phandle->scan_priv = NULL;
MOAL_REL_SEMAPHORE(&priv->phandle->async_sem);
}
if (priv->report_scan_result) {
priv->report_scan_result = MFALSE;
#ifdef STA_CFG80211
@ -3100,7 +3126,11 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent)
woal_broadcast_event(priv, (t_u8 *)&pmevent->event_id,
sizeof(mlan_event_id));
}
if (priv->phandle->scan_pending_on_block == MTRUE) {
priv->phandle->scan_pending_on_block = MFALSE;
priv->phandle->scan_priv = NULL;
MOAL_REL_SEMAPHORE(&priv->phandle->async_sem);
}
if (!is_zero_timeval(priv->phandle->scan_time_start)) {
woal_get_monotonic_time(&priv->phandle->scan_time_end);
priv->phandle->scan_time +=
@ -5085,6 +5115,55 @@ t_void moal_updata_peer_signal(t_void *pmoal, t_u32 bss_index, t_u8 *peer_addr,
spin_unlock_irqrestore(&priv->tdls_lock, flags);
}
}
#if 0
/**
* @brief This function records host time in nano seconds
*
* @return 64 bit value of host time in nano seconds
*/
s64 get_host_time_ns(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
struct timespec64 ts;
#else
struct timespec ts;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
ktime_get_real_ts64(&ts);
return timespec64_to_ns(&ts);
#else
getnstimeofday(&ts);
return timespec_to_ns(&ts);
#endif
}
#endif
/**
* @brief Retrieves the current system time
*
* @param time Pointer for the seconds of system time
*
* @return MLAN_STATUS_SUCCESS
*/
mlan_status moal_get_host_time_ns(t_u64 *time)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
struct timespec64 ts;
#else
struct timespec ts;
#endif
t_u64 hclk_val;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
ktime_get_real_ts64(&ts);
#else
getnstimeofday(&ts);
#endif
hclk_val = (ts.tv_sec * 1000000000L) + ts.tv_nsec;
*time = hclk_val;
return MLAN_STATUS_SUCCESS;
}
/**
* @brief Performs division of 64-bit num with base

View file

@ -103,6 +103,7 @@ t_void moal_hist_data_add(t_void *pmoal, t_u32 bss_index, t_u16 rx_rate,
t_void moal_updata_peer_signal(t_void *pmoal, t_u32 bss_index, t_u8 *peer_addr,
t_s8 snr, t_s8 nflr);
mlan_status moal_get_host_time_ns(t_u64 *time);
t_u64 moal_do_div(t_u64 num, t_u32 base);
mlan_status moal_init_timer(t_void *pmoal, t_void **pptimer,

View file

@ -166,7 +166,7 @@ static int woal_cfg80211_set_tx_power(struct wiphy *wiphy,
#else
enum nl80211_tx_power_setting type,
#endif
int dbm);
int mbm);
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
@ -323,6 +323,9 @@ static int woal_cfg80211_del_tx_ts(struct wiphy *wiphy, struct net_device *dev,
u8 tsid, const u8 *peer);
#endif /* KERNEL_VERSION(3, 8, 0) */
static mlan_status woal_cfg80211_dump_station_info(moal_private *priv,
struct station_info *sinfo);
/** cfg80211 operations */
static struct cfg80211_ops woal_cfg80211_ops = {
.change_virtual_intf = woal_cfg80211_change_virtual_intf,
@ -490,7 +493,6 @@ static const struct ieee80211_regdomain mrvl_regdom = {
REG_RULE(5470 - 10, 5850 + 10, 80, 6, 20, 0),
}};
#define AUTH_TX_DEFAULT_WAIT_TIME 2400
/********************************************************
Local Variables
********************************************************/
@ -1255,6 +1257,7 @@ static mlan_status woal_send_domain_info_cmd_fw(moal_private *priv,
ret = MLAN_STATUS_FAILURE;
goto done;
}
band = priv->phandle->band;
if (!priv->wdev->wiphy->bands[band]) {
PRINTM(MERROR, "11D: setting domain info in FW failed band=%d",
@ -1359,6 +1362,124 @@ done:
return ret;
}
/**
* @brief Send channel attributes to the FW
*
* @param priv A pointer to moal_private structure
* @param is6g whether its a 6g table
* @param wait_option wait option
*
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
*/
static mlan_status woal_dnld_chan_attr(moal_private *priv, t_bool is6g,
t_u8 wait_option)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
struct ieee80211_supported_band *sband = NULL;
struct wiphy *wiphy = NULL;
t_u8 i, c = 0;
mlan_ds_misc_cfg *misc = NULL;
mlan_ds_chan_attr *ca = NULL;
mlan_ioctl_req *req = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
ENTER();
if (!priv || !priv->wdev || !priv->wdev->wiphy) {
PRINTM(MERROR, "No priv or no wdev or wiphy in priv\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
wiphy = priv->wdev->wiphy;
/* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
misc = (mlan_ds_misc_cfg *)req->pbuf;
misc->sub_command = MLAN_OID_MISC_GET_CHAN_REGION_CFG;
req->req_id = MLAN_IOCTL_MISC_CFG;
memset(&misc->param.chan_attr_cfg, 0,
sizeof(misc->param.chan_attr_cfg));
ca = (mlan_ds_chan_attr *)&misc->param.chan_attr_cfg;
{
req->action = MLAN_ACT_SET;
sband = wiphy->bands[NL80211_BAND_2GHZ];
if (sband) {
for (i = 0; i < sband->n_channels; i++, c++) {
ca->chan_attr[c].channel =
sband->channels[i].hw_value;
if (sband->channels[i].flags &
IEEE80211_CHAN_DISABLED)
ca->chan_attr[c].flags |=
NXP_CHANNEL_DISABLED;
if (sband->channels[i].flags &
IEEE80211_CHAN_NO_IR)
ca->chan_attr[c].flags |=
NXP_CHANNEL_PASSIVE;
if (sband->channels[i].flags &
IEEE80211_CHAN_RADAR)
ca->chan_attr[c].flags |=
NXP_CHANNEL_DFS;
if ((sband->channels[i].flags &
IEEE80211_CHAN_NO_HT40MINUS) &&
(sband->channels[i].flags &
IEEE80211_CHAN_NO_HT40PLUS))
ca->chan_attr[c].flags |=
NXP_CHANNEL_NOHT40;
if (sband->channels[i].flags &
IEEE80211_CHAN_NO_80MHZ)
ca->chan_attr[c].flags |=
NXP_CHANNEL_NOHT80;
}
}
sband = wiphy->bands[NL80211_BAND_5GHZ];
if (sband) {
for (i = 0; i < sband->n_channels; i++, c++) {
ca->chan_attr[c].channel =
sband->channels[i].hw_value;
if (sband->channels[i].flags &
IEEE80211_CHAN_DISABLED)
ca->chan_attr[c].flags |=
NXP_CHANNEL_DISABLED;
if (sband->channels[i].flags &
IEEE80211_CHAN_NO_IR)
ca->chan_attr[c].flags |=
NXP_CHANNEL_PASSIVE;
if (sband->channels[i].flags &
IEEE80211_CHAN_RADAR)
ca->chan_attr[c].flags |=
NXP_CHANNEL_DFS;
if ((sband->channels[i].flags &
IEEE80211_CHAN_NO_HT40MINUS) &&
(sband->channels[i].flags &
IEEE80211_CHAN_NO_HT40PLUS))
ca->chan_attr[c].flags |=
NXP_CHANNEL_NOHT40;
if (sband->channels[i].flags &
IEEE80211_CHAN_NO_80MHZ)
ca->chan_attr[c].flags |=
NXP_CHANNEL_NOHT80;
}
}
}
c = (c > MLAN_MAX_CHANNEL_NUM) ? MLAN_MAX_CHANNEL_NUM : c;
ca->data_len = c * sizeof(chan_attr_t);
/* Send chan attr command to FW */
if (c)
status = woal_request_ioctl(priv, req, wait_option);
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return ret;
}
/**
* @brief Request the driver to change the channel and
* change domain info according to that channel
@ -1972,6 +2093,12 @@ static void woal_save_assoc_params(moal_private *priv,
MLAN_MAC_ADDR_LENGTH);
if (req->ie && req->ie_len) {
priv->sme_current.ie = kzalloc(req->ie_len, GFP_ATOMIC);
if (!priv->sme_current.ie) {
PRINTM(MERROR,
"Failed to allocate memory for sme params\n");
LEAVE();
return;
}
priv->sme_current.ie_len = req->ie_len;
moal_memcpy_ext(priv->phandle, (void *)priv->sme_current.ie,
req->ie, req->ie_len, priv->sme_current.ie_len);
@ -2007,7 +2134,7 @@ static void woal_save_assoc_params(moal_private *priv,
if (priv->sinfo)
memset(priv->sinfo, 0, sizeof(struct station_info));
else
priv->sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
priv->sinfo = kzalloc(sizeof(struct station_info), GFP_ATOMIC);
LEAVE();
}
@ -2170,8 +2297,10 @@ static mlan_status woal_request_set_host_mlme(moal_private *priv, t_u8 *bssid)
bss->sub_command = MLAN_OID_BSS_HOST_MLME;
req->req_id = MLAN_IOCTL_BSS;
req->action = MLAN_ACT_SET;
moal_memcpy_ext(priv->phandle, &bss->param.bssid, bssid,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
if (bssid) {
moal_memcpy_ext(priv->phandle, &bss->param.bssid, bssid,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
}
/* Send IOCTL request to MLAN */
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
done:
@ -2396,9 +2525,48 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy,
}
if (priv->auth_flag == 0) {
/*
* The priority of auth req is highest so we need to cancel
* current exist remain on channel for same function.
* EX: If wfd0 supplicant often scans, mlan0 is difficult to
* get the chance to request ROC.
* Risk: If exist one is another auth, it will be replaced
* with new auth ROC request.
* Avoid: if using woal_cfg80211_mgmt_tx_cancel_wait(), we
* cannot sure the result when the API reports cancel event
* to cfg80211 if priv->phandle->cookie != 0.
*/
if (priv->phandle->remain_on_channel) {
moal_private *remain_priv = NULL;
remain_priv =
priv->phandle
->priv[priv->phandle->remain_bss_index];
if (!remain_priv) {
/* cannot find its priv, weird! keep
* continuing... */
PRINTM(MERROR,
"mgmt_tx_cancel_wait: Wrong remain_bss_index=%d\n",
priv->phandle->remain_bss_index);
} else {
if (woal_cfg80211_remain_on_channel_cfg(
remain_priv, MOAL_IOCTL_WAIT, MTRUE,
(t_u8 *)&status, NULL, 0, 0)) {
/* fail to cancel current one! keep
* continuing... */
PRINTM(MERROR,
"mgmt_tx_cancel_wait: Fail to cancel remain on channel\n");
} else {
/* only cancel is successfully then
* change the flag */
priv->phandle->remain_on_channel =
MFALSE;
}
}
}
if (woal_cfg80211_remain_on_channel_cfg(
priv, MOAL_IOCTL_WAIT, MFALSE, (t_u8 *)&status,
req->bss->channel, 0, AUTH_TX_DEFAULT_WAIT_TIME)) {
req->bss->channel, 0, priv->auth_tx_wait_time)) {
PRINTM(MERROR, "Fail to configure remain on channel\n");
ret = -EFAULT;
goto done;
@ -2648,6 +2816,35 @@ void woal_host_mlme_work_queue(struct work_struct *work)
}
}
/**
* @brief This workqueue function handles association timeout event in event
* queue case
*
* @param priv pointer to moal_private
* @param assoc_info pointer to cfg80211_bss
*
* @return N/A
*/
void woal_host_mlme_process_assoc_timeout(moal_private *priv,
struct cfg80211_bss *bss)
{
/* Send Assoc Failure with Timeout to CFG80211 */
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
struct cfg80211_assoc_failure data;
memset(&data, 0, sizeof(struct cfg80211_assoc_failure));
data.timeout = 1;
data.bss[0] = bss;
PRINTM(MEVENT, "wlan: HostMlme assoc failure\n");
cfg80211_assoc_failure(priv->netdev, &data);
#else
PRINTM(MEVENT, "wlan: HostMlme assoc timeout\n");
cfg80211_assoc_timeout(priv->netdev, bss);
#endif
memset(priv->cfg_bssid, 0, ETH_ALEN);
woal_clear_conn_params(priv);
}
/**
* @brief This workqueue function handles association response in event queue
* case
@ -2803,6 +3000,36 @@ void woal_host_mlme_process_assoc_resp(moal_private *priv,
}
}
/**
* @brief Handle assoc timeout event (When AP do not respond to (Re)Assoc
* Request)
*
* @param priv A pointer moal_private structure
* @param pchan_info A pointer to cfg80211_assoc_request structre
*
* @return N/A
*/
static void woal_assoc_timeout_event(moal_private *priv,
struct cfg80211_assoc_request *req)
{
struct woal_event *evt;
unsigned long flags;
moal_handle *handle = priv->phandle;
evt = kzalloc(sizeof(struct woal_event), GFP_ATOMIC);
if (evt) {
evt->priv = priv;
evt->type = WOAL_EVENT_ASSOC_TIMEOUT;
evt->assoc_bss = req->bss;
INIT_LIST_HEAD(&evt->link);
spin_lock_irqsave(&handle->evt_lock, flags);
list_add_tail(&evt->link, &handle->evt_queue);
spin_unlock_irqrestore(&handle->evt_lock, flags);
queue_work(handle->evt_workqueue, &handle->evt_work);
}
// coverity[leaked_storage:SUPPRESS]
}
/**
* @brief Handle assoc response event
*
@ -2851,7 +3078,6 @@ static void woal_assoc_resp_event(moal_private *priv,
queue_work(handle->evt_workqueue, &handle->evt_work);
}
kfree(assoc_req);
// coverity[leaked_storage:SUPPRESS]
return;
}
@ -2924,6 +3150,11 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev,
return -EBUSY;
}
if (!req || !req->bss) {
ret = -EINVAL;
goto done;
}
/** cancel pending scan */
woal_cancel_scan(priv, MOAL_IOCTL_WAIT);
@ -2933,6 +3164,7 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev,
memset(ssid_bssid, 0, sizeof(mlan_ssid_bssid));
rcu_read_lock();
ssid_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
moal_memcpy_ext(priv->phandle, ssid_bssid->bssid, req->bss->bssid,
ETH_ALEN, sizeof(ssid_bssid->bssid));
@ -2960,6 +3192,18 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev,
goto done;
}
if (req->bss) {
if ((!priv->phandle->params.reg_alpha2 ||
strncmp(priv->phandle->params.reg_alpha2, "99",
strlen("99")))
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
&&
(!moal_extflg_isset(priv->phandle, EXT_COUNTRY_IE_IGNORE))
#endif
)
woal_process_country_ie(priv, req->bss);
}
#ifdef STA_WEXT
if (IS_STA_WEXT(priv->phandle->params.cfg80211_wext)) {
switch (req->crypto.wpa_versions) {
@ -3041,9 +3285,15 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev,
done:
if (!ret) {
struct station_info sinfo;
priv->rssi_low = DEFAULT_RSSI_LOW_THRESHOLD;
woal_save_assoc_params(priv, req, ssid_bssid);
memset(&sinfo, 0, sizeof(sinfo));
if (MLAN_STATUS_SUCCESS !=
woal_cfg80211_dump_station_info(priv, &sinfo)) {
PRINTM(MERROR, "Failed to get station info\n");
}
memset(&bss_info, 0, sizeof(bss_info));
if (MLAN_STATUS_SUCCESS !=
@ -3093,9 +3343,8 @@ done:
ret = 0;
} else {
ssid_bssid->assoc_rsp.assoc_resp_len = 0;
ret = -EFAULT;
memset(priv->cfg_bssid, 0, ETH_ALEN);
woal_clear_conn_params(priv);
ret = 0;
woal_assoc_timeout_event(priv, req);
}
priv->host_mlme = MFALSE;
priv->auth_flag = 0;
@ -3912,8 +4161,10 @@ create_custom_regdomain(moal_private *priv,
chflags);
new_rule = false;
if (chflags & NXP_CHANNEL_DISABLED)
if (chflags & NXP_CHANNEL_DISABLED) {
prev_chflags = chflags;
continue;
}
if (band == IEEE80211_BAND_5GHZ) {
if (!(chflags & NXP_CHANNEL_NOHT80))
@ -3937,16 +4188,8 @@ create_custom_regdomain(moal_private *priv,
new_rule = true;
}
if (!new_rule && pwr != prev_pwr) {
if (band == IEEE80211_BAND_2GHZ &&
!(chflags & NXP_CHANNEL_NOHT40)) {
/* skip adding new pwr rule for 40 MHz 2G
* overlapping bonded channels, as max tx
* power value may differ
*/
} else {
valid_rules++;
new_rule = true;
}
valid_rules++;
new_rule = true;
}
rule = &regd->reg_rules[valid_rules - 1];
@ -4143,7 +4386,7 @@ static int woal_update_custom_regdomain(moal_private *priv, struct wiphy *wiphy)
}
regd = create_custom_regdomain(priv, &misc->param.custom_reg_domain);
if (regd) {
PRINTM(MMSG, "call regulatory_set_wiphy_regd %c%c",
PRINTM(MMSG, "call regulatory_set_wiphy_regd %c%c\n",
misc->param.custom_reg_domain.region.country_code[0],
misc->param.custom_reg_domain.region.country_code[1]);
wiphy->regulatory_flags &=
@ -4340,6 +4583,7 @@ woal_cfg80211_reg_notifier(struct wiphy *wiphy,
PRINTM(MCMND, "Regulatory domain BY_COUNTRY_IE\n");
break;
}
if (priv->wdev && priv->wdev->wiphy &&
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
!(wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) &&
@ -4355,7 +4599,14 @@ woal_cfg80211_reg_notifier(struct wiphy *wiphy,
priv->phandle->band = band;
}
if (handle->params.edmac_ctrl && IS_CARD9098(priv->phandle->card_type))
if (priv->wdev && priv->wdev->wiphy &&
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
!(wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
#endif
) {
woal_dnld_chan_attr(priv, MFALSE, MOAL_IOCTL_WAIT);
}
if (handle->params.edmac_ctrl)
woal_edmac_cfg(priv, priv->phandle->country_code);
LEAVE();
@ -5140,7 +5391,7 @@ static int woal_connect_ft_over_air(moal_private *priv, t_u8 *bssid,
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
if (woal_cfg80211_remain_on_channel_cfg(priv, wait_option, MFALSE,
&status, chan, 0,
AUTH_TX_DEFAULT_WAIT_TIME)) {
priv->auth_tx_wait_time)) {
PRINTM(MERROR, "Failed remain on channel config\n");
}
#endif
@ -6125,7 +6376,7 @@ static int woal_cfg80211_get_tx_power(struct wiphy *wiphy,
*
* @param wiphy A pointer to wiphy structure
* @param type TX power adjustment type
* @param dbm TX power in dbm
* @param mbm TX power in mbm
*
* @return 0 -- success, otherwise fail
*/
@ -6138,12 +6389,13 @@ static int woal_cfg80211_set_tx_power(struct wiphy *wiphy,
#else
enum nl80211_tx_power_setting type,
#endif
int dbm)
int mbm)
{
int ret = 0;
moal_private *priv = NULL;
moal_handle *handle = (moal_handle *)woal_get_wiphy_priv(wiphy);
mlan_power_cfg_t power_cfg;
int dbm = MBM_TO_DBM(mbm);
ENTER();
memset(&power_cfg, 0, sizeof(power_cfg));
@ -6157,6 +6409,11 @@ static int woal_cfg80211_set_tx_power(struct wiphy *wiphy,
if (type) {
power_cfg.is_power_auto = 0;
if (mbm < 0 || (mbm % 100)) {
PRINTM(MERROR, "Invalid tx power value %d mbm\n", mbm);
LEAVE();
return -EOPNOTSUPP;
}
power_cfg.power_level = dbm;
} else
power_cfg.is_power_auto = 1;
@ -7029,6 +7286,7 @@ int woal_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
moal_handle *handle = (moal_handle *)woal_get_wiphy_priv(wiphy);
int i;
int ret = 0;
moal_private *priv = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
mlan_ds_misc_mef_flt_cfg mef_cfg;
mef_entry_t *mef_entry = NULL;
@ -7039,8 +7297,11 @@ int woal_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
t_u8 byte_seq[MAX_NUM_BYTE_SEQ + 1];
const t_u8 ipv4_mc_mac[] = {0x33, 0x33};
const t_u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
moal_private *priv = woal_get_priv(handle, MLAN_BSS_ROLE_STA);
mlan_ds_hs_cfg hscfg;
priv = woal_get_priv(handle, MLAN_BSS_ROLE_STA);
if (!priv) {
return 0;
}
PRINTM(MCMND, "<--- Enter woal_cfg80211_suspend --->\n");
for (i = 0; i < MIN(handle->priv_num, MLAN_MAX_BSS_NUM); i++) {
@ -9144,6 +9405,12 @@ void woal_save_conn_params(moal_private *priv,
}
if (sme->ie && sme->ie_len) {
priv->sme_current.ie = kzalloc(sme->ie_len, GFP_KERNEL);
if (!priv->sme_current.ie) {
PRINTM(MERROR,
"Failed to allocate memory for sme params\n");
LEAVE();
return;
}
moal_memcpy_ext(priv->phandle, (void *)priv->sme_current.ie,
sme->ie, sme->ie_len, sme->ie_len);
}
@ -9609,6 +9876,7 @@ int woal_cfg80211_uap_add_station(struct wiphy *wiphy, struct net_device *dev,
#else
if (params->he_capa_len)
req_len += sizeof(MrvlExtIEtypesHeader_t) + params->he_capa_len;
#endif
#endif
req = woal_alloc_mlan_ioctl_req(req_len);
@ -9789,6 +10057,7 @@ int woal_cfg80211_uap_add_station(struct wiphy *wiphy, struct net_device *dev,
sizeof(MrvlExtIEtypesHeader_t) + params->he_capa_len;
tlv = (MrvlIEtypes_Data_t *)pos;
}
#endif
DBG_HEXDUMP(MCMD_D, "sta tlv", &bss->param.sta_info.tlv[0],
bss->param.sta_info.tlv_len);
@ -10439,6 +10708,11 @@ mlan_status woal_register_cfg80211(moal_private *priv)
wiphy->flags |=
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | WIPHY_FLAG_OFFCHAN_TX;
wiphy->flags |= WIPHY_FLAG_AP_UAPSD | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
if (moal_extflg_isset(priv->phandle, EXT_HOST_MLME))
wiphy->flags |= WIPHY_FLAG_REPORTS_OBSS;

View file

@ -3,7 +3,7 @@
* @brief This file contains the STA CFG80211 specific defines.
*
*
* Copyright 2011-2021 NXP
* Copyright 2011-2024 NXP
*
* This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991

View file

@ -1917,6 +1917,17 @@ static int woal_uap_antenna_cfg(struct net_device *dev, struct ifreq *req)
mreq->action = MLAN_ACT_SET;
radio->param.ant_cfg.tx_antenna = antenna_config.tx_mode;
radio->param.ant_cfg.rx_antenna = antenna_config.rx_mode;
}
status = woal_request_ioctl(priv, mreq, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
PRINTM(MERROR, "Failed to set new antenna config\n");
ret = -EFAULT;
goto done;
}
/* Notify the CFG80211 layer only on SUCCESS from FW */
if ((status == MLAN_STATUS_SUCCESS) && (mreq->action == MLAN_ACT_SET)) {
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
if (IS_CARD9098(priv->phandle->card_type) ||
IS_CARD9097(priv->phandle->card_type) ||
@ -1930,11 +1941,6 @@ static int woal_uap_antenna_cfg(struct net_device *dev, struct ifreq *req)
#endif
}
status = woal_request_ioctl(priv, mreq, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
ret = -EFAULT;
goto done;
}
if (mreq->action == MLAN_ACT_GET) {
antenna_config.tx_mode = radio->param.ant_cfg.tx_antenna;
antenna_config.rx_mode = radio->param.ant_cfg.rx_antenna;
@ -2156,7 +2162,8 @@ static int woal_uap_get_dfs_chan(t_u8 pri_chan, t_u8 bw,
{116, 120, 124, 128},
{132, 136, 140, 144}};
t_u8 find = false;
int i, j;
int j;
int i;
t_u8 sec_chan = 0;
mlan_ds_11h_chan_dfs_state *pos = ch_dfs_state;
t_u8 n_chan = 1;
@ -2790,7 +2797,8 @@ static int woal_uap_sta_deauth_ioctl(struct net_device *dev, struct ifreq *req)
sizeof(mlan_deauth_param),
sizeof(bss->param.deauth_param));
status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
if ((status != MLAN_STATUS_SUCCESS) &&
(status != MLAN_STATUS_PENDING)) {
ret = -EFAULT;
if (copy_to_user(req->ifr_data, &ioctl_req->status_code,
sizeof(t_u32)))
@ -3175,7 +3183,8 @@ static int woal_uap_power_mode_ioctl(struct net_device *dev, struct ifreq *req)
}
status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
if ((status != MLAN_STATUS_SUCCESS) &&
(status != MLAN_STATUS_PENDING)) {
ret = -EFAULT;
if (copy_to_user(req->ifr_data, &ioctl_req->status_code,
sizeof(t_u32)))
@ -3931,6 +3940,9 @@ int woal_uap_set_11ax_status(moal_private *priv, t_u8 action, t_u8 band,
&hecap_ie->ext_id, he_cfg.he_cap.len,
he_cfg.he_cap.len);
}
#define HE_MAC_CAP_TWT_REQ_SUPPORT MBIT(1)
/* uap mode should be TWT responder only */
he_cfg.he_cap.he_mac_cap[0] &= ~HE_MAC_CAP_TWT_REQ_SUPPORT;
if (action == MLAN_ACT_DISABLE) {
if (he_cfg.he_cap.len &&
(he_cfg.he_cap.ext_id == HE_CAPABILITY)) {

View file

@ -103,6 +103,11 @@ Change log:
/** BSS RESET */
#define UAP_BSS_RESET 2
/* HE MAC Capabilities Information field BIT 1 for TWT Req */
#define HE_MAC_CAP_TWT_REQ_SUPPORT MBIT(1)
/* HE MAC Capabilities Information field BIT 2 for TWT Resp*/
#define HE_MAC_CAP_TWT_RESP_SUPPORT MBIT(2)
/** wapi_msg */
typedef struct _wapi_msg {
/** message type */

View file

@ -614,6 +614,43 @@ static t_u8 woal_check_11ax_capability(moal_private *priv, t_u8 band,
}
#endif
#if KERNEL_VERSION(4, 20, 0) <= CFG80211_VERSION_CODE
/**
* @brief check channel width with HE capabilities
* @param priv A pointer to moal private structure
* @param chandef A pointer to cfg80211_chan_def structure
* @return 0 -- channel width supported, otherwise not supported
*/
static t_u8 woal_check_chan_width_capa(moal_private *priv,
struct cfg80211_chan_def *chandef)
{
mlan_fw_info fw_info;
mlan_ds_11ax_he_capa *phe_cap = NULL;
ENTER();
memset(&fw_info, 0, sizeof(mlan_fw_info));
woal_request_get_fw_info(priv, MOAL_IOCTL_WAIT, &fw_info);
if (chandef->chan->band == NL80211_BAND_5GHZ) {
phe_cap = (mlan_ds_11ax_he_capa *)fw_info.hw_he_cap;
if (((chandef->width == NL80211_CHAN_WIDTH_160) &&
(!(phe_cap->he_phy_cap[0] & MBIT(3)))) ||
((chandef->width == NL80211_CHAN_WIDTH_80P80) &&
(!(phe_cap->he_phy_cap[0] & MBIT(4))))) {
PRINTM(MCMND, "FW don't support %s in %s band",
(chandef->width == NL80211_CHAN_WIDTH_160) ?
"160MHz" :
"80+80 MHz",
(chandef->chan->band == NL80211_BAND_5GHZ) ?
"5G" :
"6G");
LEAVE();
return MFALSE;
}
}
LEAVE();
return MTRUE;
}
#endif
/**
* @brief get ht_cap from beacon ie
*
@ -994,6 +1031,13 @@ static int woal_cfg80211_beacon_config(moal_private *priv,
sizeof(struct cfg80211_chan_def), sizeof(priv->chan));
#endif
#if KERNEL_VERSION(4, 20, 0) <= CFG80211_VERSION_CODE
if (!woal_check_chan_width_capa(priv, &params->chandef)) {
ret = -EFAULT;
goto done;
}
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
woal_convert_chan_to_bandconfig(priv, &bandcfg, &params->chandef);
#endif
@ -1467,6 +1511,11 @@ static int woal_cfg80211_beacon_config(moal_private *priv,
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)
hecap_ie = (IEEEtypes_HECap_t *)woal_parse_ext_ie_tlv(
ie, ie_len, HE_CAPABILITY);
#if CFG80211_VERSION_CODE > KERNEL_VERSION(5, 3, 0)
if (params->twt_responder == MFALSE) {
hecap_ie->he_mac_cap[0] &= ~HE_MAC_CAP_TWT_RESP_SUPPORT;
}
#endif
#endif
woal_uap_set_11ax_status(priv, MLAN_ACT_ENABLE,
sys_config->bandcfg.chanBand,
@ -1828,6 +1877,9 @@ static int woal_cfg80211_add_vlan_vir_if(struct wiphy *wiphy,
new_priv->bss_index = priv->bss_index;
new_priv->parent_priv = priv;
new_priv->wdev->iftype = NL80211_IFTYPE_AP_VLAN;
new_priv->max_tx_pending = MAX_TX_PENDING;
new_priv->low_tx_pending = LOW_TX_PENDING;
skb_queue_head_init(&new_priv->tx_q);
ndev->ieee80211_ptr->use_4addr = params->use_4addr;
@ -1849,6 +1901,17 @@ static int woal_cfg80211_add_vlan_vir_if(struct wiphy *wiphy,
if (new_dev)
*new_dev = ndev;
if (ndev->ieee80211_ptr->use_4addr && !priv->multi_ap_flag) {
/* Supports backhaul and fronthaul BSS and enable four_address
* flag */
if (MLAN_STATUS_SUCCESS ==
woal_multi_ap_cfg(priv, MOAL_IOCTL_WAIT,
EASY_MESH_MULTI_AP_BH_AND_FH_BSS)) {
priv->multi_ap_flag = EASY_MESH_MULTI_AP_BH_AND_FH_BSS;
}
}
fail:
LEAVE();
return ret;
@ -3051,6 +3114,10 @@ int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
#ifdef STA_SUPPORT
moal_private *pmpriv = NULL;
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
moal_private *dfs_priv =
woal_get_priv_bss_type(priv->phandle, MLAN_BSS_TYPE_DFS);
#endif
ENTER();
@ -3076,6 +3143,21 @@ int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
if (moal_extflg_isset(priv->phandle, EXT_DFS_OFFLOAD))
woal_cancel_cac_block(priv);
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
if (dfs_priv && dfs_priv->radar_background) {
PRINTM(MMSG, "Cancel background radar detection\n");
woal_11h_cancel_chan_report_ioctl(dfs_priv, MOAL_IOCTL_WAIT);
dfs_priv->chan_rpt_pending = MFALSE;
dfs_priv->radar_background = MFALSE;
woal_update_channels_dfs_state(
dfs_priv, dfs_priv->chan_rpt_req.chanNum,
dfs_priv->chan_rpt_req.bandcfg.chanWidth, DFS_USABLE);
memset(&dfs_priv->chan_rpt_req, 0,
sizeof(mlan_ds_11h_chan_rep_req));
cfg80211_background_cac_abort(priv->phandle->wiphy);
}
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
memset(&priv->chan, 0, sizeof(struct cfg80211_chan_def));
if (priv->phandle->is_cac_timer_set &&
@ -3136,6 +3218,7 @@ int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
memset(priv->uap_wep_key, 0, sizeof(priv->uap_wep_key));
priv->channel = 0;
priv->bandwidth = 0;
priv->multi_ap_flag = 0;
PRINTM(MMSG, "wlan: %s AP stopped\n", dev->name);
done:
@ -3692,6 +3775,9 @@ int woal_cfg80211_set_radar_background(struct wiphy *wiphy,
woal_11h_cancel_chan_report_ioctl(priv, MOAL_IOCTL_WAIT);
priv->chan_rpt_pending = MFALSE;
priv->radar_background = MFALSE;
woal_update_channels_dfs_state(
priv, priv->chan_rpt_req.chanNum,
priv->chan_rpt_req.bandcfg.chanWidth, DFS_USABLE);
memset(&priv->chan_rpt_req, 0,
sizeof(mlan_ds_11h_chan_rep_req));
LEAVE();

View file

@ -35,7 +35,7 @@ extern struct semaphore AddRemoveCardSem;
********************************************************/
#if defined(USB8997) || defined(USB9098) || defined(USB9097) || \
defined(USB8978) || defined(USBIW624) || defined(USBIW615)
defined(USB8978) || defined(USBIW624) || defined(USBIW610)
/** Card-type detection frame response */
typedef struct {
/** 32-bit ACK+WINNER field */
@ -101,10 +101,10 @@ static struct usb_device_id woal_usb_table[] = {
{NXP_USB_DEVICE(USBIW624_VID_1, USBIW624_PID_2,
"NXP WLAN USB Adapter")},
#endif
#ifdef USBIW615
{NXP_USB_DEVICE(USBIW615_VID_1, USBIW615_PID_1,
#ifdef USBIW610
{NXP_USB_DEVICE(USBIW610_VID_1, USBIW610_PID_1,
"NXP WLAN USB Adapter")},
{NXP_USB_DEVICE(USBIW615_VID_1, USBIW615_PID_2,
{NXP_USB_DEVICE(USBIW610_VID_1, USBIW610_PID_2,
"NXP WLAN USB Adapter")},
#endif
/* Terminating entry */
@ -138,8 +138,8 @@ static struct usb_device_id woal_usb_table_skip_fwdnld[] = {
{NXP_USB_DEVICE(USBIW624_VID_1, USBIW624_PID_2,
"NXP WLAN USB Adapter")},
#endif
#ifdef USBIW615
{NXP_USB_DEVICE(USBIW615_VID_1, USBIW615_PID_2,
#ifdef USBIW610
{NXP_USB_DEVICE(USBIW610_VID_1, USBIW610_PID_2,
"NXP WLAN USB Adapter")},
#endif
/* Terminating entry */
@ -507,7 +507,7 @@ rx_ret:
********************************************************/
#if defined(USB8997) || defined(USB9098) || defined(USB9097) || \
defined(USB8978) || defined(USBIW624) || defined(USBIW615)
defined(USB8978) || defined(USBIW624) || defined(USBIW610)
/**
* @brief Check chip revision
*
@ -836,18 +836,18 @@ static t_u16 woal_update_card_type(t_void *card)
strlen(KERN_VERSION));
}
#endif
#ifdef USBIW615
#ifdef USBIW610
if (woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
(__force __le16)USBIW615_PID_1 ||
(__force __le16)USBIW610_PID_1 ||
woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
(__force __le16)USBIW615_PID_2) {
card_type = CARD_TYPE_USBIW615;
moal_memcpy_ext(NULL, driver_version, CARD_USBIW615,
strlen(CARD_USBIW615), strlen(driver_version));
(__force __le16)USBIW610_PID_2) {
card_type = CARD_TYPE_USBIW610;
moal_memcpy_ext(NULL, driver_version, CARD_USBIW610,
strlen(CARD_USBIW610), strlen(driver_version));
moal_memcpy_ext(NULL,
driver_version + strlen(INTF_CARDTYPE) +
strlen(KERN_VERSION),
V17, strlen(V17),
V18, strlen(V18),
strlen(driver_version) - strlen(INTF_CARDTYPE) -
strlen(KERN_VERSION));
}
@ -922,9 +922,9 @@ static int woal_usb_probe(struct usb_interface *intf,
#ifdef USBIW624
case (__force __le16)USBIW624_PID_1:
#endif /* USBIW624 */
#ifdef USBIW615
case (__force __le16)USBIW615_PID_1:
#endif /* USBIW615 */
#ifdef USBIW610
case (__force __le16)USBIW610_PID_1:
#endif /* USBIW610 */
/* If skip FW is set, we must return error so
* the next driver can download the FW */
@ -955,9 +955,9 @@ static int woal_usb_probe(struct usb_interface *intf,
#ifdef USBIW624
case (__force __le16)USBIW624_PID_2:
#endif /* USBIW624 */
#ifdef USBIW615
case (__force __le16)USBIW615_PID_2:
#endif /* USBIW615 */
#ifdef USBIW610
case (__force __le16)USBIW610_PID_2:
#endif /* USBIW610 */
usb_cardp->boot_state = USB_FW_READY;
break;
@ -2097,7 +2097,7 @@ static mlan_status woal_usb_get_fw_name(moal_handle *handle)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
#if defined(USB8997) || defined(USB9098) || defined(USB9097) || \
defined(USB8978) || defined(USBIW624) || defined(USBIW615)
defined(USB8978) || defined(USBIW624) || defined(USBIW610)
t_u32 revision_id = 0;
t_u32 strap = 0;
t_u32 boot_mode = 0;
@ -2118,7 +2118,7 @@ static mlan_status woal_usb_get_fw_name(moal_handle *handle)
#endif
#if defined(USB8997) || defined(USB9098) || defined(USB9097) || \
defined(USB8978) || defined(USBIW624) || defined(USBIW615)
defined(USB8978) || defined(USBIW624) || defined(USBIW610)
ret = woal_check_chip_revision(handle, &revision_id, &strap,
&boot_mode);
if (ret != MLAN_STATUS_SUCCESS) {
@ -2236,14 +2236,42 @@ static mlan_status woal_usb_get_fw_name(moal_handle *handle)
USBUSBIW624_COMBO_FW_NAME, FW_NAMW_MAX_LEN);
}
#endif
#ifdef USBIW615
if (IS_USBIW615(handle->card_type)) {
if (strap == CARD_TYPE_USB_UART)
strcpy(handle->card_info->fw_name,
USBUARTIW615_COMBO_FW_NAME);
else
strcpy(handle->card_info->fw_name,
USBUSBIW615_COMBO_FW_NAME);
#ifdef USBIW610
if (IS_USBIW610(handle->card_type)) {
if (boot_mode == 0x03)
PRINTM(MMSG, "wlan: USB-IW610 in secure-boot mode\n");
if (strap == CARD_TYPE_USBIW610_UART) {
if (handle->params.dual_nb)
strncpy(handle->card_info->fw_name,
USBUARTSPIIW610_COMBO_FW_NAME,
FW_NAMW_MAX_LEN);
else
strncpy(handle->card_info->fw_name,
USBUARTIW610_COMBO_FW_NAME,
FW_NAMW_MAX_LEN);
} else if (strap == CARD_TYPE_USBIW610_USB) {
if (handle->params.dual_nb)
strncpy(handle->card_info->fw_name,
USBUSBSPIIW610_COMBO_FW_NAME,
FW_NAMW_MAX_LEN);
else
strncpy(handle->card_info->fw_name,
USBUSBIW610_COMBO_FW_NAME,
FW_NAMW_MAX_LEN);
}
strncpy(handle->card_info->fw_name_wlan,
USBIW610_DEFAULT_WLAN_FW_NAME, FW_NAMW_MAX_LEN);
if (boot_mode != 0x03) {
/* remove extension .se */
if (strstr(handle->card_info->fw_name, ".se"))
memset(strstr(handle->card_info->fw_name,
".se"),
'\0', sizeof(".se"));
if (strstr(handle->card_info->fw_name_wlan, ".se"))
memset(strstr(handle->card_info->fw_name_wlan,
".se"),
'\0', sizeof(".se"));
}
}
#endif

View file

@ -98,14 +98,14 @@ Change Log:
#define USBIW624_PID_2 0x020F
#endif /* USBIW624 */
#ifdef USBIW615
#ifdef USBIW610
/** USB VID 1 */
#define USBIW615_VID_1 0x0471
#define USBIW610_VID_1 0x0471
/** USB PID 1 */
#define USBIW615_PID_1 0x021E
#define USBIW610_PID_1 0x0214
/** USB PID 2 */
#define USBIW615_PID_2 0x021F
#endif /* USBIW615 */
#define USBIW610_PID_2 0x0215
#endif /* USBIW610 */
/** Boot state: FW download */
#define USB_FW_DNLD 1
@ -120,7 +120,7 @@ Change Log:
#if defined(USB8997) || defined(USB9098) || defined(USB9097) || \
defined(USB8978) || defined(USB8801) || defined(USBIW624) || \
defined(USBIW615)
defined(USBIW610)
/* Transmit buffer size for chip revision check */
#define CHIP_REV_TX_BUF_SIZE 16
/* Receive buffer size for chip revision check */
@ -189,12 +189,14 @@ Change Log:
#define USBIW624_DEFAULT_WLAN_FW_NAME "nxp/usbiw624_wlan.bin"
#endif /* USBIW624 */
#ifdef USBIW615
#define USBIW615_DEFAULT_COMBO_FW_NAME "nxp/usbusbiw615_combo.bin"
#define USBUARTIW615_COMBO_FW_NAME "nxp/usbuartiw615_combo.bin"
#define USBUSBIW615_COMBO_FW_NAME "nxp/usbusbiw615_combo.bin"
#define USBIW615_DEFAULT_WLAN_FW_NAME "nxp/usbiw615_wlan.bin"
#endif /* USBIW615 */
#ifdef USBIW610
#define USBIW610_DEFAULT_COMBO_FW_NAME "nxp/usbusbspi_iw610.bin.se"
#define USBUARTIW610_COMBO_FW_NAME "nxp/usbuart_iw610.bin.se"
#define USBUARTSPIIW610_COMBO_FW_NAME "nxp/usbuartspi_iw610.bin.se"
#define USBUSBIW610_COMBO_FW_NAME "nxp/usbusb_iw610.bin.se"
#define USBUSBSPIIW610_COMBO_FW_NAME "nxp/usbusbspi_iw610.bin.se"
#define USBIW610_DEFAULT_WLAN_FW_NAME "nxp/usb_iw610.bin.se"
#endif /* USBIW610 */
/** urb context */
typedef struct _urb_context {

View file

@ -77,6 +77,8 @@ static const struct iw_priv_args woal_private_args[] = {
{WOAL_TXBUF_CFG, IW_PRIV_TYPE_INT | 1, IW_PRIV_TYPE_INT | 1,
"txbufcfg"},
{WOAL_SLEEP_PD, IW_PRIV_TYPE_INT | 1, IW_PRIV_TYPE_INT | 1, "sleeppd"},
{WOAL_FW_WAKEUP_METHOD, IW_PRIV_TYPE_INT | 1, IW_PRIV_TYPE_INT | 1,
"fwwakeupmethod"},
{WOAL_AUTH_TYPE, IW_PRIV_TYPE_INT | 1, IW_PRIV_TYPE_INT | 1,
"authtype"},
{WOAL_PORT_CTRL, IW_PRIV_TYPE_INT | 1, IW_PRIV_TYPE_INT | 1,
@ -2777,8 +2779,7 @@ static int woal_set_essid(struct net_device *dev, struct iw_request_info *info,
0);
ret = MLAN_STATUS_SUCCESS;
LEAVE();
return ret;
goto setessid_ret;
}
}
#endif