wil6210 patches
cover wil6210 patches
The following patches include multiple wil6210 fixes.
Ahmad Masri (1):
wil6210: align to latest auto generated wmi.h
Alexei Avshalom Lazar (3):
wil6210: disable tracing config option
wil6210: set/get EDMG channel through debugfs
wil6210: Initialize reply struct of the WMI commands
Dedy Lansky (4):
wil6210: use country specific board file upon reg domain change
wil6210: move WMI functionality out of wil_cfg80211_mgmt_tx
wil6210: remove unused rx_reorder members
wil6210: rate limit wil_rx_refill error
Lior David (2):
wil6210: fix call to wil6210_disconnect during unload
wil6210: change reply_size arg to u16 in wmi_call
drivers/net/wireless/ath/wil6210/Kconfig | 2 +- drivers/net/wireless/ath/wil6210/cfg80211.c | 216 ++++++++++--- drivers/net/wireless/ath/wil6210/debugfs.c | 6 +- drivers/net/wireless/ath/wil6210/main.c | 39 ++- drivers/net/wireless/ath/wil6210/netdev.c | 8 +- drivers/net/wireless/ath/wil6210/rx_reorder.c | 7 +- drivers/net/wireless/ath/wil6210/txrx.c | 12 +- drivers/net/wireless/ath/wil6210/wil6210.h | 23 +- drivers/net/wireless/ath/wil6210/wmi.c | 177 ++++++++--- drivers/net/wireless/ath/wil6210/wmi.h | 420 ++++++++++++++++++++++++-- 10 files changed, 769 insertions(+), 141 deletions(-)
Signature · 1 line
1.9.1
PATCH 1/10 wil6210: disable tracing config option
From: Alexei Avshalom Lazar <[email protected]>
Disable WIL6210_TRACING by default to avoid its performance overhead.
--- drivers/net/wireless/ath/wil6210/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath/wil6210/Kconfig +1 -1
@@ -33,7 +33,7 @@ config WIL6210_TRACING bool "wil6210 tracing support" depends on WIL6210 depends on EVENT_TRACING - default y + default n ---help--- Say Y here to enable tracepoints for the wil6210 driver using the kernel tracing infrastructure. Select this
Signature · 1 line
1.9.1
PATCH 2/10 wil6210: set/get EDMG channel through debugfs
In reply to Maya ErezFrom: Alexei Avshalom Lazar <[email protected]>
Setting EDMG channel through debugfs for connect and PCP start commands.
--- drivers/net/wireless/ath/wil6210/cfg80211.c | 89 +++++++++++++++++++++++++++++ drivers/net/wireless/ath/wil6210/debugfs.c | 1 + drivers/net/wireless/ath/wil6210/wil6210.h | 4 ++ drivers/net/wireless/ath/wil6210/wmi.c | 25 +++++++- drivers/net/wireless/ath/wil6210/wmi.h | 33 ++++++++++- 5 files changed, 146 insertions(+), 6 deletions(-)
drivers/net/wireless/ath/wil6210/cfg80211.c +89 -0
@@ -261,6 +261,86 @@ int wil_iftype_nl2wmi(enum nl80211_iftype type)return -EOPNOTSUPP ; } +int wil_spec2wmi_ch (u8 spec_ch,u8 *wmi_ch) +{ +switch (spec_ch) { +case 1 : + *wmi_ch =WMI_CHANNEL_1 ; +break ; +case 2 : + *wmi_ch =WMI_CHANNEL_2 ; +break ; +case 3 : + *wmi_ch =WMI_CHANNEL_3 ; +break ; +case 4 : + *wmi_ch =WMI_CHANNEL_4 ; +break ; +case 5 : + *wmi_ch =WMI_CHANNEL_5 ; +break ; +case 6 : + *wmi_ch =WMI_CHANNEL_6 ; +break ; +case 9 : + *wmi_ch =WMI_CHANNEL_9 ; +break ; +case 10 : + *wmi_ch =WMI_CHANNEL_10 ; +break ; +case 11 : + *wmi_ch =WMI_CHANNEL_11 ; +break ; +case 12 : + *wmi_ch =WMI_CHANNEL_12 ; +break ; +default : +return -EINVAL ; + } + +return 0 ; +} + +int wil_wmi2spec_ch (u8 wmi_ch,u8 *spec_ch) +{ +switch (wmi_ch) { +case WMI_CHANNEL_1 : + *spec_ch =1 ; +break ; +case WMI_CHANNEL_2 : + *spec_ch =2 ; +break ; +case WMI_CHANNEL_3 : + *spec_ch =3 ; +break ; +case WMI_CHANNEL_4 : + *spec_ch =4 ; +break ; +case WMI_CHANNEL_5 : + *spec_ch =5 ; +break ; +case WMI_CHANNEL_6 : + *spec_ch =6 ; +break ; +case WMI_CHANNEL_9 : + *spec_ch =9 ; +break ; +case WMI_CHANNEL_10 : + *spec_ch =10 ; +break ; +case WMI_CHANNEL_11 : + *spec_ch =11 ; +break ; +case WMI_CHANNEL_12 : + *spec_ch =12 ; +break ; +default : +return -EINVAL ; + } + +return 0 ; +} +int wil_cid_fill_sinfo (struct wil6210_vif *vif,int cid,struct station_info *sinfo) {
@@ -1005,6 +1085,15 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, } conn.channel = ch -1 ; +if (test_bit (WMI_FW_CAPABILITY_CHANNEL_BONDING , wil->fw_capabilities)) +if (wil->force_edmg_channel) { + rc =wil_spec2wmi_ch (wil->force_edmg_channel, + &conn.edmg_channel); +if (rc) +wil_err (wil,"wmi channel for channel %d not found" , + wil->force_edmg_channel); + } +ether_addr_copy (conn.bssid, bss->bssid);ether_addr_copy (conn.dst_mac, bss->bssid);
drivers/net/wireless/ath/wil6210/debugfs.c +1 -0
@@ -1852,6 +1852,7 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil,WIL_FIELD (abft_len,0644 , doff_u8),WIL_FIELD (wakeup_trigger,0644 , doff_u8),WIL_FIELD (vring_idle_trsh,0644 , doff_u32), + WIL_FIELD(force_edmg_channel, 0644, doff_u8), {}, };
drivers/net/wireless/ath/wil6210/wil6210.h +4 -0
@@ -791,6 +791,7 @@ struct wil6210_priv {u8 wakeup_trigger;struct wil_suspend_stats suspend_stats;struct wil_debugfs_data dbg_data; +u8 force_edmg_channel;void *platform_handle;struct wil_platform_ops platform_ops;
@@ -1151,4 +1152,7 @@ int wmi_start_sched_scan(struct wil6210_priv *wil, struct cfg80211_sched_scan_request *request);int wmi_stop_sched_scan (struct wil6210_priv *wil); +int wil_wmi2spec_ch (u8 wmi_ch,u8 *spec_ch); +int wil_spec2wmi_ch (u8 spec_ch,u8 *wmi_ch); +#endif /* __WIL6210_H__ */
drivers/net/wireless/ath/wil6210/wmi.c +22 -3
@@ -823,7 +823,8 @@ static void wmi_evt_connect(struct wil6210_vif *vif, int id, void *d, int len)struct net_device *ndev =vif_to_ndev (vif);struct wireless_dev *wdev =vif_to_wdev (vif);struct wmi_connect_event *evt = d; -int ch;/* channel number */ +int ch;/* channel number (primary) */ +u8 spec_ch =0 ;/* spec channel number */ struct station_info sinfo;u8 *assoc_req_ie, *assoc_resp_ie;size_t assoc_req_ielen, assoc_resp_ielen;
@@ -851,8 +852,17 @@ static void wmi_evt_connect(struct wil6210_vif *vif, int id, void *d, int len) } ch = evt->channel +1 ; -wil_info (wil,"Connect %pM channel [%d] cid %d aid %d\n" , - evt->bssid, ch, evt->cid, evt->aid); + +if (evt->edmg_channel && +test_bit (WMI_FW_CAPABILITY_CHANNEL_BONDING , wil->fw_capabilities)) +wil_wmi2spec_ch (evt->edmg_channel, &spec_ch); +if (spec_ch) +wil_info (wil,"Connect %pM EDMG channel [%d] primary channel [%d] cid %d aid %d\n" , + evt->bssid, spec_ch, ch, evt->cid, evt->aid); +else +wil_info (wil,"Connect %pM channel [%d] cid %d aid %d\n" , + evt->bssid, ch, evt->cid, evt->aid); +wil_hex_dump_wmi ("connect AI : " ,DUMP_PREFIX_OFFSET ,16 ,1 , evt->assoc_info, len -sizeof (*evt), true);
@@ -1562,6 +1572,15 @@ int wmi_pcp_start(struct wil6210_vif *vif,struct wmi_pcp_started_event evt; }__packed reply; +if (test_bit (WMI_FW_CAPABILITY_CHANNEL_BONDING , wil->fw_capabilities)) +if (wil->force_edmg_channel) { + rc =wil_spec2wmi_ch (wil->force_edmg_channel, + &cmd.edmg_channel); +if (rc) +wil_err (wil,"wmi channel for channel %d not found" , + wil->force_edmg_channel); + } +if (!vif->privacy) cmd.disable_sec =1 ;
drivers/net/wireless/ath/wil6210/wmi.h +30 -3
@@ -72,6 +72,7 @@ enum wmi_fw_capability {WMI_FW_CAPABILITY_SET_SILENT_RSSI_TABLE =13 ,WMI_FW_CAPABILITY_LO_POWER_CALIB_FROM_OTP =14 ,WMI_FW_CAPABILITY_PNO =15 , +WMI_FW_CAPABILITY_CHANNEL_BONDING =17 ,WMI_FW_CAPABILITY_REF_CLOCK_CONTROL =18 , WMI_FW_CAPABILITY_MAX, };
@@ -284,6 +285,19 @@ enum wmi_connect_ctrl_flag_bits {#define WMI_MAX_SSID_LEN (32) +enum wmi_channel { +WMI_CHANNEL_1 =0x00 , +WMI_CHANNEL_2 =0x01 , +WMI_CHANNEL_3 =0x02 , +WMI_CHANNEL_4 =0x03 , +WMI_CHANNEL_5 =0x04 , +WMI_CHANNEL_6 =0x05 , +WMI_CHANNEL_9 =0x06 , +WMI_CHANNEL_10 =0x07 , +WMI_CHANNEL_11 =0x08 , +WMI_CHANNEL_12 =0x09 , +}; +/* WMI_CONNECT_CMDID */ struct wmi_connect_cmd {u8 network_type;
@@ -295,8 +309,12 @@ struct wmi_connect_cmd {u8 group_crypto_len;u8 ssid_len;u8 ssid[WMI_MAX_SSID_LEN ]; +/* enum wmi_channel WMI_CHANNEL_1..WMI_CHANNEL_6; for EDMG this is +* the primary channel number +*/ u8 channel; -u8 reserved0; +/* enum wmi_channel WMI_CHANNEL_9..WMI_CHANNEL_12 */ +u8 edmg_channel;u8 bssid[WMI_MAC_LEN ];__le32 ctrl_flags;u8 dst_mac[WMI_MAC_LEN ];
@@ -590,11 +608,16 @@ struct wmi_pcp_start_cmd {u8 pcp_max_assoc_sta;u8 hidden_ssid;u8 is_go; -u8 reserved0[5 ]; +/* enum wmi_channel WMI_CHANNEL_9..WMI_CHANNEL_12 */ +u8 edmg_channel; +u8 reserved[4 ];/* A-BFT length override if non-0 */ u8 abft_len;u8 disable_ap_sme;u8 network_type; +/* enum wmi_channel WMI_CHANNEL_1..WMI_CHANNEL_6; for EDMG this is +* the primary channel number +*/ u8 channel;u8 disable_sec_offload;u8 disable_sec;
@@ -1576,8 +1599,12 @@ struct wmi_notify_req_done_event {/* WMI_CONNECT_EVENTID */ struct wmi_connect_event { +/* enum wmi_channel WMI_CHANNEL_1..WMI_CHANNEL_6; for EDMG this is +* the primary channel number +*/ u8 channel; -u8 reserved0; +/* enum wmi_channel WMI_CHANNEL_9..WMI_CHANNEL_12 */ +u8 edmg_channel;u8 bssid[WMI_MAC_LEN ];__le16 listen_interval;__le16 beacon_interval;
Signature · 1 line
1.9.1
Re: [02/10] wil6210: set/get EDMG channel through debugfs
Quoted 2 lines · Maya Erez
Setting EDMG channel through debugfs for connect and PCP start commands.
Why? And what is an EDMG channel?
I get bad vibes that this debugfs file is just a workaround for not adding this to nl80211, a proper commit log would not give me such vibes in the first place :)
Signature · 3 lines
https://patchwork.kernel.org/patch/10338031/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [02/10] wil6210: set/get EDMG channel through debugfs
Quoted 5 lines · Kalle Valo
Quoted 2 lines · Maya Erez
Setting EDMG channel through debugfs for connect and PCP start commands.
Quoted 7 lines
Why? And what is an EDMG channel?
I get bad vibes that this debugfs file is just a workaround for not adding this to nl80211, a proper commit log would not give me such vibes in the first place :)
EDMG (Enhanced Directional Multi-Gigabit) is a new feature, part of 11ad/11ay specification. In a nutshell it allows channel bonding of 60Ghz channels.
The debugfs is used for debug-only to allow forcing a channel, not intended to replace NL API, which we are working to upstream such.
I'll send a new version with fixed commit text.
Signature · 3 lines
Maya Erez Qualcomm Israel, Inc. on behalf of Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [02/10] wil6210: set/get EDMG channel through debugfs
Quoted 11 lines · [email protected] writes:
Quoted 9 lines · Kalle Valo
Quoted 2 lines · Maya Erez
Setting EDMG channel through debugfs for connect and PCP start commands.
Why? And what is an EDMG channel?
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#commit_log_does_not_answer_why
I get bad vibes that this debugfs file is just a workaround for not adding this to nl80211, a proper commit log would not give me such vibes in the first place :)
Quoted 6 lines
EDMG (Enhanced Directional Multi-Gigabit) is a new feature, part of 11ad/11ay specification. In a nutshell it allows channel bonding of 60Ghz channels.
The debugfs is used for debug-only to allow forcing a channel, not intended to replace NL API, which we are working to upstream such.
But why cannot you do debugging via nl80211 as well?
Signature · 1 line
Kalle Valo
Re: [02/10] wil6210: set/get EDMG channel through debugfs
Quoted 13 lines · Kalle Valo
Quoted 11 lines · [email protected] writes:
Quoted 9 lines · Kalle Valo
Quoted 2 lines · Maya Erez
Setting EDMG channel through debugfs for connect and PCP start commands.
Why? And what is an EDMG channel?
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#commit_log_does_not_answer_why
I get bad vibes that this debugfs file is just a workaround for not adding this to nl80211, a proper commit log would not give me such vibes in the first place :)
Quoted 8 lines
Quoted 6 lines
EDMG (Enhanced Directional Multi-Gigabit) is a new feature, part of 11ad/11ay specification. In a nutshell it allows channel bonding of 60Ghz channels.
The debugfs is used for debug-only to allow forcing a channel, not intended to replace NL API, which we are working to upstream such.
But why cannot you do debugging via nl80211 as well?
Debugging via nl80211 is possible, but there are benefits in using the debugfs interface:
- Debugfs allows forcing a specific channel, which is not always an option with NL API
- Debug via nl80211 is less straight forward and requires development of user-space application and upgrade of the kernel version on the debug setups
If you believe that the duplication is not justified please drop this patch.
Signature · 3 lines
Maya Erez Qualcomm Israel, Inc. on behalf of Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [02/10] wil6210: set/get EDMG channel through debugfs
Quoted 31 lines · [email protected] writes:
Quoted 13 lines · Kalle Valo
Quoted 11 lines · [email protected] writes:
Quoted 9 lines · Kalle Valo
Quoted 2 lines · Maya Erez
Setting EDMG channel through debugfs for connect and PCP start commands.
Why? And what is an EDMG channel?
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#commit_log_does_not_answer_why
I get bad vibes that this debugfs file is just a workaround for not adding this to nl80211, a proper commit log would not give me such vibes in the first place :)Quoted 8 lines
Quoted 6 lines
EDMG (Enhanced Directional Multi-Gigabit) is a new feature, part of 11ad/11ay specification. In a nutshell it allows channel bonding of 60Ghz channels.
The debugfs is used for debug-only to allow forcing a channel, not intended to replace NL API, which we are working to upstream such.
But why cannot you do debugging via nl80211 as well?
Debugging via nl80211 is possible, but there are benefits in using the debugfs interface:
- Debugfs allows forcing a specific channel, which is not always an option with NL API
- Debug via nl80211 is less straight forward and requires development of user-space application
and upgrade of the kernel version on the debug setups
Quoted 2 lines
If you believe that the duplication is not justified please drop this patch.
Yeah, I think it's better to drop this. Let's revisit after we have the corresonding nl80211 command in place.
Signature · 1 line
Kalle Valo
PATCH 3/10 wil6210: align to latest auto generated wmi.h
In reply to Maya ErezFrom: Ahmad Masri <[email protected]>
Align to latest version of the auto generated wmi file describing the interface with FW
--- drivers/net/wireless/ath/wil6210/wmi.c | 6 +- drivers/net/wireless/ath/wil6210/wmi.h | 387 +++++++++++++++++++++++++++++++-- 2 files changed, 371 insertions(+), 22 deletions(-)
drivers/net/wireless/ath/wil6210/wmi.c +4 -2
@@ -1564,7 +1564,9 @@ int wmi_pcp_start(struct wil6210_vif *vif, .pcp_max_assoc_sta = max_assoc_sta, .hidden_ssid = hidden_ssid, .is_go = is_go, - .disable_ap_sme = disable_ap_sme, + .ap_sme_offload_mode = disable_ap_sme ? +WMI_AP_SME_OFFLOAD_PARTIAL : + WMI_AP_SME_OFFLOAD_FULL, .abft_len = wil->abft_len, };struct {
@@ -1593,7 +1595,7 @@ int wmi_pcp_start(struct wil6210_vif *vif, }if (disable_ap_sme && - !test_bit (WMI_FW_CAPABILITY_DISABLE_AP_SME , + !test_bit (WMI_FW_CAPABILITY_AP_SME_OFFLOAD_PARTIAL , wil->fw_capabilities)) {wil_err (wil,"disable_ap_sme not supported by FW\n" );return -EOPNOTSUPP ;
drivers/net/wireless/ath/wil6210/wmi.h +367 -20
689 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH 4/10 wil6210: fix call to wil6210_disconnect during unload
In reply to Maya ErezFrom: Lior David <[email protected]>
Move the call to wil6210_disconnect so it will be called before unregister_netdevice. This is because it calls netif_carrier_off which is forbidden to call on an unregistered net device. Calling netif_carrier_off can add a link watch event which might be handled after net device was freed, causing a kernel oops.
--- drivers/net/wireless/ath/wil6210/netdev.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/wireless/ath/wil6210/netdev.c +4 -4
@@ -457,16 +457,16 @@ void wil_vif_remove(struct wil6210_priv *wil, u8 mid)return ; } +mutex_lock (&wil->mutex); +wil6210_disconnect (vif,NULL ,WLAN_REASON_DEAUTH_LEAVING , false); +mutex_unlock (&wil->mutex); + ndev =vif_to_ndev (vif);/* during unregister_netdevice cfg80211_leave may perform operations * such as stop AP, disconnect, so we only clear the VIF afterwards */ unregister_netdevice (ndev); -mutex_lock (&wil->mutex); -wil6210_disconnect (vif,NULL ,WLAN_REASON_DEAUTH_LEAVING , false); -mutex_unlock (&wil->mutex); -if (any_active && vif->mid !=0 )wmi_port_delete (wil, vif->mid);
Signature · 1 line
1.9.1
PATCH 5/10 wil6210: change reply_size arg to u16 in wmi_call
In reply to Maya ErezFrom: Lior David <[email protected]>
Change the type of the argument reply_size from u8 to u16 in order to support reply sizes > 255 bytes. The driver already supports u16 reply size in all other places, this was the only missing change.
--- drivers/net/wireless/ath/wil6210/wil6210.h | 2 +- drivers/net/wireless/ath/wil6210/wmi.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/wil6210/wil6210.h +1 -1
@@ -987,7 +987,7 @@ int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr,int wmi_send (struct wil6210_priv *wil,u16 cmdid,u8 mid,void *buf,u16 len);void wmi_recv_cmd (struct wil6210_priv *wil);int wmi_call (struct wil6210_priv *wil,u16 cmdid,u8 mid,void *buf,u16 len, -u16 reply_id,void *reply,u8 reply_size,int to_msec); +u16 reply_id,void *reply,u16 reply_size,int to_msec);void wmi_event_worker (struct work_struct *work);void wmi_event_flush (struct wil6210_priv *wil);int wmi_set_ssid (struct wil6210_vif *vif,u8 ssid_len,const void *ssid);
drivers/net/wireless/ath/wil6210/wmi.c +1 -1
@@ -1426,7 +1426,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil) }int wmi_call (struct wil6210_priv *wil,u16 cmdid,u8 mid,void *buf,u16 len, -u16 reply_id,void *reply,u8 reply_size,int to_msec) +u16 reply_id,void *reply,u16 reply_size,int to_msec) {int rc;unsigned long remain;
Signature · 1 line
1.9.1
PATCH 6/10 wil6210: use country specific board file upon reg domain change
In reply to Maya ErezFrom: Dedy Lansky <[email protected]>
wil6210 device needs to use country specific board file while in China regulatory domain.
Register cfg80211 reg_notifier and switch board file if needed according to new regulatory domain.
This feature is disabled by default and can be enabled with a new country_specific_board_file module parameter.
--- drivers/net/wireless/ath/wil6210/cfg80211.c | 66 +++++++++++++++++++++++++++++ drivers/net/wireless/ath/wil6210/main.c | 37 +++++++++++++--- drivers/net/wireless/ath/wil6210/wil6210.h | 6 +++ 3 files changed, 104 insertions(+), 5 deletions(-)
drivers/net/wireless/ath/wil6210/cfg80211.c +66 -0
@@ -24,11 +24,16 @@#include "fw.h" #define WIL_MAX_ROC_DURATION_MS 5000 +#define CTRY_CHINA "CN"bool disable_ap_sme;module_param (disable_ap_sme, bool,0444 );MODULE_PARM_DESC (disable_ap_sme," let user space handle AP mode SME" ); +static bool country_specific_board_file; +module_param (country_specific_board_file, bool,0444 ); +MODULE_PARM_DESC (country_specific_board_file," switch board file upon regulatory domain change (Default: false)" ); +#ifdef CONFIG_PM static struct wiphy_wowlan_support wil_wowlan_support = { .flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_DISCONNECT,
@@ -2124,6 +2129,65 @@ static int wil_cfg80211_resume(struct wiphy *wiphy)return 0 ; } +static int wil_switch_board_file (struct wil6210_priv *wil, +const u8 *new_regdomain) +{ +int rc =0 ; + +if (!country_specific_board_file) +return 0 ; + +if (memcmp (wil->regdomain,CTRY_CHINA ,2 ) ==0 ) { +wil_info (wil,"moving out of China reg domain, use default board file\n" ); + wil->board_file_country[0 ] ='\0' ; + }else if (memcmp (new_regdomain,CTRY_CHINA ,2 ) ==0 ) { +wil_info (wil,"moving into China reg domain, use country specific board file\n" ); +strlcpy (wil->board_file_country,CTRY_CHINA , +sizeof (wil->board_file_country)); + }else { +return 0 ; + } + +/* need to switch board file - reset the device */ + +mutex_lock (&wil->mutex); + +if (!wil_has_active_ifaces (wil, true, false) || +wil_is_recovery_blocked (wil)) +/* new board file will be used in next FW load */ + goto out; + +__wil_down (wil); + rc =__wil_up (wil); + +out: +mutex_unlock (&wil->mutex); +return rc; +} + +static void wil_cfg80211_reg_notify (struct wiphy *wiphy, +struct regulatory_request *request) +{ +struct wil6210_priv *wil =wiphy_to_wil (wiphy); +int rc; + +wil_info (wil,"cfg reg_notify %c%c%s%s initiator %d hint_type %d\n" , + request->alpha2[0 ], request->alpha2[1 ], + request->intersect ?" intersect" :"" , + request->processed ?" processed" :"" , + request->initiator, request->user_reg_hint_type); + +if (memcmp (wil->regdomain, request->alpha2,2 ) ==0 ) +/* reg domain did not change */ +return ; + + rc =wil_switch_board_file (wil, request->alpha2); +if (rc) +wil_err (wil,"switch board file failed %d\n" , rc); + +memcpy (wil->regdomain, request->alpha2,sizeof (wil->regdomain)); +} +static const struct cfg80211_ops wil_cfg80211_ops = { .add_virtual_intf = wil_cfg80211_add_iface, .del_virtual_intf = wil_cfg80211_del_iface,
@@ -2198,6 +2262,8 @@ static void wil_wiphy_init(struct wiphy *wiphy) wiphy->n_vendor_commands =ARRAY_SIZE (wil_nl80211_vendor_commands); wiphy->vendor_commands = wil_nl80211_vendor_commands; + wiphy->reg_notifier = wil_cfg80211_reg_notify; +#ifdef CONFIG_PM wiphy->wowlan = &wil_wowlan_support;#endif
drivers/net/wireless/ath/wil6210/main.c +32 -5
@@ -26,6 +26,7 @@#define WAIT_FOR_HALP_VOTE_MS 100#define WAIT_FOR_SCAN_ABORT_MS 1000 +#define WIL_BOARD_FILE_MAX_NAMELEN 128bool debug_fw;/* = false; */ module_param (debug_fw, bool,0444 );
@@ -943,6 +944,30 @@ void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)le32_to_cpus (&r->head); } +/* construct actual board file name to use */ +void wil_get_board_file (struct wil6210_priv *wil,char *buf,size_t len) +{ +const char *board_file =WIL_BOARD_FILE_NAME ; +const char *ext; +int prefix_len; + +if (wil->board_file_country[0 ] =='\0' ) { +strlcpy (buf, board_file, len); +return ; + } + +/* use country specific board file */ +if (len <strlen (board_file) +4 /* for _XX and terminating null */ ) +return ; + + ext =strrchr (board_file,'.' ); + prefix_len = (ext ? ext - board_file :strlen (board_file)); +snprintf (buf, len,"%.*s_%.2s" , + prefix_len, board_file, wil->board_file_country); +if (ext) +strlcat (buf, ext, len); +} +static int wil_get_bl_info (struct wil6210_priv *wil) {struct net_device *ndev = wil->main_ndev;
@@ -1302,8 +1327,12 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)wil_set_oob_mode (wil, oob_mode);if (load_fw) { +char board_file[WIL_BOARD_FILE_MAX_NAMELEN ]; + + board_file[0 ] ='\0' ; +wil_get_board_file (wil, board_file,sizeof (board_file));wil_info (wil,"Use firmware <%s> + board <%s>\n" , - wil->wil_fw_name,WIL_BOARD_FILE_NAME ); + wil->wil_fw_name, board_file);if (!no_flash)wil_bl_prepare_halt (wil);
@@ -1315,11 +1344,9 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)if (rc) goto out;if (wil->brd_file_addr) - rc =wil_request_board (wil,WIL_BOARD_FILE_NAME ); + rc =wil_request_board (wil, board_file);else - rc =wil_request_firmware (wil, -WIL_BOARD_FILE_NAME , - true); + rc =wil_request_firmware (wil, board_file, true);if (rc) goto out;
drivers/net/wireless/ath/wil6210/wil6210.h +6 -0
@@ -720,6 +720,7 @@ struct wil6210_priv {const char *hw_name;const char *wil_fw_name;char *board_file; +char board_file_country[3 ];/* alpha2 */ u32 brd_file_addr;u32 brd_file_max_size;DECLARE_BITMAP (hw_capa, hw_capa_last);
@@ -812,6 +813,9 @@ struct wil6210_priv {int fw_calib_result; +/* current reg domain configured in kernel */ +char regdomain[3 ];/* alpha2 */ +struct notifier_block pm_notify;bool suspend_resp_rcvd;
@@ -905,6 +909,8 @@ static inline void wil_c(struct wil6210_priv *wil, u32 reg, u32 val)wil_w (wil, reg,wil_r (wil, reg) & ~val); } +void wil_get_board_file (struct wil6210_priv *wil,char *buf,size_t len); +#if defined(CONFIG_DYNAMIC_DEBUG )#define wil_hex_dump_txrx (prefix_str, prefix_type, rowsize, \ groupsize, buf, len, ascii) \
Signature · 1 line
1.9.1
PATCH 7/10 wil6210: move WMI functionality out of wil_cfg80211_mgmt_tx
In reply to Maya ErezFrom: Dedy Lansky <[email protected]>
Rearrange the code by having new function wmi_mgmt_tx() to take care of the WMI part of wil_cfg80211_mgmt_tx().
--- drivers/net/wireless/ath/wil6210/cfg80211.c | 39 +++--------------------- drivers/net/wireless/ath/wil6210/wil6210.h | 1 + drivers/net/wireless/ath/wil6210/wmi.c | 47 +++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 35 deletions(-)
drivers/net/wireless/ath/wil6210/cfg80211.c +4 -35
@@ -1175,17 +1175,11 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, u64 *cookie) {const u8 *buf = params->buf; -size_t len = params->len, total; +size_t len = params->len;struct wil6210_priv *wil =wiphy_to_wil (wiphy);struct wil6210_vif *vif =wdev_to_vif (wil, wdev);int rc; -bool tx_status = false; -struct ieee80211_mgmt *mgmt_frame = (void *)buf; -struct wmi_sw_tx_req_cmd *cmd; -struct { -struct wmi_cmd_hdr wmi; -struct wmi_sw_tx_complete_event evt; - } __packed evt; +bool tx_status;/* Note, currently we do not support the "wait" parameter, user-space * must call remain_on_channel before mgmt_tx or listen on a channel
@@ -1194,34 +1188,9 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,* different from currently "listened" channel and fail if it is. */ -wil_dbg_misc (wil,"mgmt_tx mid %d\n" , vif->mid); -wil_hex_dump_misc ("mgmt tx frame " ,DUMP_PREFIX_OFFSET ,16 ,1 , buf, - len, true); - -if (len <sizeof (struct ieee80211_hdr_3addr )) -return -EINVAL ; - - total =sizeof (*cmd) + len; -if (total < len) -return -EINVAL ; - - cmd =kmalloc (total,GFP_KERNEL ); -if (!cmd) { - rc = -ENOMEM ; - goto out; - } - -memcpy (cmd->dst_mac, mgmt_frame->da,WMI_MAC_LEN ); - cmd->len =cpu_to_le16 (len); -memcpy (cmd->payload, buf, len); - - rc =wmi_call (wil,WMI_SW_TX_REQ_CMDID , vif->mid, cmd, total, -WMI_SW_TX_COMPLETE_EVENTID , &evt,sizeof (evt),2000 ); -if (rc ==0 ) - tx_status = !evt.evt.status; + rc =wmi_mgmt_tx (vif, buf, len); + tx_status = (rc ==0 ); -kfree (cmd); - out:cfg80211_mgmt_tx_status (wdev, cookie ? *cookie :0 , buf, len, tx_status,GFP_KERNEL );return rc;
drivers/net/wireless/ath/wil6210/wil6210.h +1 -0
@@ -1157,6 +1157,7 @@ int wil_request_firmware(struct wil6210_priv *wil, const char *name,int wmi_start_sched_scan (struct wil6210_priv *wil,struct cfg80211_sched_scan_request *request);int wmi_stop_sched_scan (struct wil6210_priv *wil); +int wmi_mgmt_tx (struct wil6210_vif *vif,const u8 *buf,size_t len);int wil_wmi2spec_ch (u8 wmi_ch,u8 *spec_ch);int wil_spec2wmi_ch (u8 spec_ch,u8 *wmi_ch);
drivers/net/wireless/ath/wil6210/wmi.c +47 -0
50 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH 8/10 wil6210: Initialize reply struct of the WMI commands
In reply to Maya ErezFrom: Alexei Avshalom Lazar <[email protected]>
WMI command reply saved in uninitialized struct. In order to avoid accessing unset values from FW initialize the reply struct.
--- drivers/net/wireless/ath/wil6210/cfg80211.c | 22 ++++--- drivers/net/wireless/ath/wil6210/debugfs.c | 2 + drivers/net/wireless/ath/wil6210/main.c | 2 + drivers/net/wireless/ath/wil6210/txrx.c | 8 ++- drivers/net/wireless/ath/wil6210/wmi.c | 97 ++++++++++++++++++----------- 5 files changed, 85 insertions(+), 46 deletions(-)
drivers/net/wireless/ath/wil6210/cfg80211.c +14 -8
@@ -361,6 +361,8 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,struct wil_net_stats *stats = &wil->sta[cid].stats;int rc; +memset (&reply,0 ,sizeof (reply)); + rc =wmi_call (wil,WMI_NOTIFY_REQ_CMDID , vif->mid, &cmd,sizeof (cmd),WMI_NOTIFY_REQ_DONE_EVENTID , &reply,sizeof (reply),20 );if (rc)
@@ -2401,7 +2403,9 @@ static int wil_rf_sector_get_cfg(struct wiphy *wiphy,struct {struct wmi_cmd_hdr wmi;struct wmi_get_rf_sector_params_done_event evt; - } __packed reply; + } __packed reply = { + .evt = {.status =WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR }, + };struct sk_buff *msg;struct nlattr *nl_cfgs, *nl_cfg;u32 i;
@@ -2447,7 +2451,6 @@ static int wil_rf_sector_get_cfg(struct wiphy *wiphy, cmd.sector_idx =cpu_to_le16 (sector_index); cmd.sector_type = sector_type; cmd.rf_modules_vec = rf_modules_vec &0xFF ; -memset (&reply,0 ,sizeof (reply)); rc = wmi_call(wil, WMI_GET_RF_SECTOR_PARAMS_CMDID, vif->mid, &cmd, sizeof(cmd), WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID, &reply, sizeof(reply),
@@ -2522,7 +2525,9 @@ static int wil_rf_sector_set_cfg(struct wiphy *wiphy,struct {struct wmi_cmd_hdr wmi;struct wmi_set_rf_sector_params_done_event evt; - } __packed reply; + } __packed reply = { + .evt = {.status =WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR }, + };struct nlattr *nl_cfg;struct wmi_rf_sector_info *si;
@@ -2605,7 +2610,6 @@ static int wil_rf_sector_set_cfg(struct wiphy *wiphy, } cmd.rf_modules_vec = rf_modules_vec &0xFF ; -memset (&reply,0 ,sizeof (reply)); rc = wmi_call(wil, WMI_SET_RF_SECTOR_PARAMS_CMDID, vif->mid, &cmd, sizeof(cmd), WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID, &reply, sizeof(reply),
@@ -2629,7 +2633,9 @@ static int wil_rf_sector_get_selected(struct wiphy *wiphy,struct {struct wmi_cmd_hdr wmi;struct wmi_get_selected_rf_sector_index_done_event evt; - } __packed reply; + } __packed reply = { + .evt = {.status =WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR }, + };struct sk_buff *msg;if (!test_bit (WMI_FW_CAPABILITY_RF_SECTORS , wil->fw_capabilities))
@@ -2669,7 +2675,6 @@ static int wil_rf_sector_get_selected(struct wiphy *wiphy,memset (&cmd,0 ,sizeof (cmd)); cmd.cid = (u8 )cid; cmd.sector_type = sector_type; -memset (&reply,0 ,sizeof (reply)); rc = wmi_call(wil, WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID, vif->mid, &cmd, sizeof(cmd), WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID,
@@ -2710,14 +2715,15 @@ static int wil_rf_sector_wmi_set_selected(struct wil6210_priv *wil,struct {struct wmi_cmd_hdr wmi;struct wmi_set_selected_rf_sector_index_done_event evt; - } __packed reply; + } __packed reply = { + .evt = {.status =WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR }, + };int rc;memset (&cmd,0 ,sizeof (cmd)); cmd.sector_idx =cpu_to_le16 (sector_index); cmd.sector_type = sector_type; cmd.cid = (u8 )cid; -memset (&reply,0 ,sizeof (reply)); rc = wmi_call(wil, WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID, mid, &cmd, sizeof(cmd), WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID,
drivers/net/wireless/ath/wil6210/debugfs.c +2 -0
@@ -1078,6 +1078,8 @@ static int wil_bf_debugfs_show(struct seq_file *s, void *data)struct wmi_notify_req_done_event evt; }__packed reply; +memset (&reply,0 ,sizeof (reply)); +for (i =0 ; i <ARRAY_SIZE (wil->sta); i++) {u32 status;
drivers/net/wireless/ath/wil6210/main.c +2 -0
@@ -343,6 +343,8 @@ void wil_disconnect_worker(struct work_struct *work)/* already disconnected */ return ; +memset (&reply,0 ,sizeof (reply)); + rc =wmi_call (wil,WMI_DISCONNECT_CMDID , vif->mid,NULL ,0 ,WMI_DISCONNECT_EVENTID , &reply,sizeof (reply),WIL6210_DISCONNECT_TO_MS );
drivers/net/wireless/ath/wil6210/txrx.c +6 -2
@@ -963,7 +963,9 @@ int wil_vring_init_tx(struct wil6210_vif *vif, int id, int size,struct {struct wmi_cmd_hdr wmi;struct wmi_vring_cfg_done_event cmd; - } __packed reply; + } __packed reply = { + .cmd = {.status =WMI_FW_STATUS_FAILURE }, + };struct vring *vring = &wil->vring_tx[id];struct vring_tx_data *txdata = &wil->vring_tx_data[id];
@@ -1045,7 +1047,9 @@ int wil_vring_init_bcast(struct wil6210_vif *vif, int id, int size)struct {struct wmi_cmd_hdr wmi;struct wmi_vring_cfg_done_event cmd; - } __packed reply; + } __packed reply = { + .cmd = {.status =WMI_FW_STATUS_FAILURE }, + };struct vring *vring = &wil->vring_tx[id];struct vring_tx_data *txdata = &wil->vring_tx_data[id];
drivers/net/wireless/ath/wil6210/wmi.c +61 -36
268 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH 9/10 wil6210: remove unused rx_reorder members
In reply to Maya ErezFrom: Dedy Lansky <[email protected]>
Remove unused members from struct wil_tid_ampdu_rx
--- drivers/net/wireless/ath/wil6210/debugfs.c | 3 +-- drivers/net/wireless/ath/wil6210/rx_reorder.c | 7 +------ drivers/net/wireless/ath/wil6210/wil6210.h | 10 ---------- 3 files changed, 2 insertions(+), 18 deletions(-)
drivers/net/wireless/ath/wil6210/debugfs.c +1 -2
@@ -1379,8 +1379,7 @@ static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)u16 index = ((r->head_seq_num - r->ssn) &0xfff ) % r->buf_size;unsigned long long drop_dup = r->drop_dup, drop_old = r->drop_old; -seq_printf (s,"([%2d] %3d TU) 0x%03x [" , r->buf_size, r->timeout, - r->head_seq_num); +seq_printf (s,"([%2d]) 0x%03x [" , r->buf_size, r->head_seq_num);for (i =0 ; i < r->buf_size; i++) {if (i == index)seq_printf (s,"%c" , r->reorder_buf[i] ?'O' :'|' );
drivers/net/wireless/ath/wil6210/rx_reorder.c +1 -6
@@ -206,7 +206,6 @@ void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)/* put the frame in the reordering buffer */ r->reorder_buf[index] = skb; - r->reorder_time[index] = jiffies; r->stored_mpdu_num++;wil_reorder_release (ndev, r);
@@ -252,11 +251,8 @@ struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil, r->reorder_buf =kcalloc (size,sizeof (struct sk_buff *),GFP_KERNEL ); - r->reorder_time = -kcalloc (size,sizeof (unsigned long ),GFP_KERNEL ); -if (!r->reorder_buf || !r->reorder_time) { +if (!r->reorder_buf) {kfree (r->reorder_buf); -kfree (r->reorder_time);kfree (r);return NULL ; }
@@ -286,7 +282,6 @@ void wil_tid_ampdu_rx_free(struct wil6210_priv *wil,kfree_skb (r->reorder_buf[i]);kfree (r->reorder_buf); -kfree (r->reorder_time);kfree (r); }
drivers/net/wireless/ath/wil6210/wil6210.h +0 -10
@@ -493,38 +493,28 @@ enum { /* for wil6210_priv.status */* struct tid_ampdu_rx - TID aggregation information (Rx). * * @reorder_buf: buffer to reorder incoming aggregated MPDUs -* @reorder_time: jiffies when skb was added -* @session_timer: check if peer keeps Tx-ing on the TID (by timeout value) -* @reorder_timer: releases expired frames from the reorder buffer. * @last_rx: jiffies of last rx activity * @head_seq_num: head sequence number in reordering buffer. * @stored_mpdu_num: number of MPDUs in reordering buffer * @ssn: Starting Sequence Number expected to be aggregated. * @buf_size: buffer size for incoming A-MPDUs -* @timeout: reset timer value (in TUs). * @ssn_last_drop: SSN of the last dropped frame * @total: total number of processed incoming frames * @drop_dup: duplicate frames dropped for this reorder buffer * @drop_old: old frames dropped for this reorder buffer -* @dialog_token: dialog token for aggregation session * @first_time: true when this buffer used 1-st time */ struct wil_tid_ampdu_rx {struct sk_buff **reorder_buf; -unsigned long *reorder_time; -struct timer_list session_timer; -struct timer_list reorder_timer;unsigned long last_rx;u16 head_seq_num;u16 stored_mpdu_num;u16 ssn;u16 buf_size; -u16 timeout;u16 ssn_last_drop;unsigned long long total;/* frames processed */ unsigned long long drop_dup;unsigned long long drop_old; -u8 dialog_token;bool first_time;/* is it 1-st time this buffer used? */ };
Signature · 1 line
1.9.1
PATCH 10/10 wil6210: rate limit wil_rx_refill error
In reply to Maya ErezFrom: Dedy Lansky <[email protected]>
wil_err inside wil_rx_refill can flood the log buffer. Replace it with wil_err_ratelimited.
--- drivers/net/wireless/ath/wil6210/txrx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/wil6210/txrx.c +2 -2
@@ -652,8 +652,8 @@ static int wil_rx_refill(struct wil6210_priv *wil, int count) v->swtail = next_tail) { rc =wil_vring_alloc_skb (wil, v, v->swtail, headroom);if (unlikely (rc)) { -wil_err (wil,"Error %d in wil_rx_refill[%d]\n" , - rc, v->swtail); +wil_err_ratelimited (wil,"Error %d in rx refill[%d]\n" , + rc, v->swtail);break ; } }
Signature · 1 line
1.9.1