Loading drivers/net/wireless/ath/wil6210/cfg80211.c +65 −0 Original line number Original line Diff line number Diff line Loading @@ -21,11 +21,16 @@ #include "ftm.h" #include "ftm.h" #define WIL_MAX_ROC_DURATION_MS 5000 #define WIL_MAX_ROC_DURATION_MS 5000 #define CTRY_CHINA "CN" bool disable_ap_sme; bool disable_ap_sme; module_param(disable_ap_sme, bool, 0444); module_param(disable_ap_sme, bool, 0444); MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME"); 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)"); static bool ignore_reg_hints = true; static bool ignore_reg_hints = true; module_param(ignore_reg_hints, bool, 0444); module_param(ignore_reg_hints, bool, 0444); MODULE_PARM_DESC(ignore_reg_hints, " Ignore OTA regulatory hints (Default: true)"); MODULE_PARM_DESC(ignore_reg_hints, " Ignore OTA regulatory hints (Default: true)"); Loading Loading @@ -1984,6 +1989,64 @@ wil_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev) return 0; 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 (!netif_running(wil_to_ndev(wil)) || 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, 2); } static struct cfg80211_ops wil_cfg80211_ops = { static struct cfg80211_ops wil_cfg80211_ops = { .add_virtual_intf = wil_cfg80211_add_iface, .add_virtual_intf = wil_cfg80211_add_iface, .del_virtual_intf = wil_cfg80211_del_iface, .del_virtual_intf = wil_cfg80211_del_iface, Loading Loading @@ -2055,6 +2118,8 @@ static void wil_wiphy_init(struct wiphy *wiphy) wiphy->mgmt_stypes = wil_mgmt_stypes; wiphy->mgmt_stypes = wil_mgmt_stypes; wiphy->features |= NL80211_FEATURE_SK_TX_STATUS; wiphy->features |= NL80211_FEATURE_SK_TX_STATUS; wiphy->reg_notifier = wil_cfg80211_reg_notify; wiphy->n_vendor_commands = ARRAY_SIZE(wil_nl80211_vendor_commands); wiphy->n_vendor_commands = ARRAY_SIZE(wil_nl80211_vendor_commands); wiphy->vendor_commands = wil_nl80211_vendor_commands; wiphy->vendor_commands = wil_nl80211_vendor_commands; wiphy->vendor_events = wil_nl80211_vendor_events; wiphy->vendor_events = wil_nl80211_vendor_events; Loading drivers/net/wireless/ath/wil6210/main.c +32 −5 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ #define WAIT_FOR_HALP_VOTE_MS 100 #define WAIT_FOR_HALP_VOTE_MS 100 #define WAIT_FOR_SCAN_ABORT_MS 1000 #define WAIT_FOR_SCAN_ABORT_MS 1000 #define WIL_BOARD_FILE_MAX_NAMELEN 128 bool debug_fw; /* = false; */ bool debug_fw; /* = false; */ module_param(debug_fw, bool, 0444); module_param(debug_fw, bool, 0444); Loading Loading @@ -946,6 +947,30 @@ void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) le32_to_cpus(&r->head); 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) static int wil_get_bl_info(struct wil6210_priv *wil) { { struct net_device *ndev = wil_to_ndev(wil); struct net_device *ndev = wil_to_ndev(wil); Loading Loading @@ -1260,8 +1285,12 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) wil_set_oob_mode(wil, oob_mode); wil_set_oob_mode(wil, oob_mode); if (load_fw) { 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_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) if (!no_flash) wil_bl_prepare_halt(wil); wil_bl_prepare_halt(wil); Loading @@ -1273,11 +1302,9 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) if (rc) if (rc) goto out; goto out; if (wil->brd_file_addr) if (wil->brd_file_addr) rc = wil_request_board(wil, WIL_BOARD_FILE_NAME); rc = wil_request_board(wil, board_file); else else rc = wil_request_firmware(wil, rc = wil_request_firmware(wil, board_file, true); WIL_BOARD_FILE_NAME, true); if (rc) if (rc) goto out; goto out; Loading drivers/net/wireless/ath/wil6210/wil6210.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -683,6 +683,7 @@ struct wil6210_priv { const char *hw_name; const char *hw_name; const char *wil_fw_name; const char *wil_fw_name; char *board_file; char *board_file; char board_file_country[3]; /* alpha2 */ u32 brd_file_addr; u32 brd_file_addr; u32 brd_file_max_size; u32 brd_file_max_size; DECLARE_BITMAP(hw_capa, hw_capa_last); DECLARE_BITMAP(hw_capa, hw_capa_last); Loading Loading @@ -796,6 +797,8 @@ struct wil6210_priv { } snr_thresh; } snr_thresh; int fw_calib_result; int fw_calib_result; /* current reg domain configured in kernel */ char regdomain[3]; /* alpha2 */ #ifdef CONFIG_PM #ifdef CONFIG_PM struct notifier_block pm_notify; struct notifier_block pm_notify; Loading Loading @@ -873,6 +876,8 @@ static inline void wil_c(struct wil6210_priv *wil, u32 reg, u32 val) wil_w(wil, reg, wil_r(wil, reg) & ~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) #if defined(CONFIG_DYNAMIC_DEBUG) #define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize, \ #define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize, \ groupsize, buf, len, ascii) \ groupsize, buf, len, ascii) \ Loading Loading
drivers/net/wireless/ath/wil6210/cfg80211.c +65 −0 Original line number Original line Diff line number Diff line Loading @@ -21,11 +21,16 @@ #include "ftm.h" #include "ftm.h" #define WIL_MAX_ROC_DURATION_MS 5000 #define WIL_MAX_ROC_DURATION_MS 5000 #define CTRY_CHINA "CN" bool disable_ap_sme; bool disable_ap_sme; module_param(disable_ap_sme, bool, 0444); module_param(disable_ap_sme, bool, 0444); MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME"); 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)"); static bool ignore_reg_hints = true; static bool ignore_reg_hints = true; module_param(ignore_reg_hints, bool, 0444); module_param(ignore_reg_hints, bool, 0444); MODULE_PARM_DESC(ignore_reg_hints, " Ignore OTA regulatory hints (Default: true)"); MODULE_PARM_DESC(ignore_reg_hints, " Ignore OTA regulatory hints (Default: true)"); Loading Loading @@ -1984,6 +1989,64 @@ wil_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev) return 0; 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 (!netif_running(wil_to_ndev(wil)) || 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, 2); } static struct cfg80211_ops wil_cfg80211_ops = { static struct cfg80211_ops wil_cfg80211_ops = { .add_virtual_intf = wil_cfg80211_add_iface, .add_virtual_intf = wil_cfg80211_add_iface, .del_virtual_intf = wil_cfg80211_del_iface, .del_virtual_intf = wil_cfg80211_del_iface, Loading Loading @@ -2055,6 +2118,8 @@ static void wil_wiphy_init(struct wiphy *wiphy) wiphy->mgmt_stypes = wil_mgmt_stypes; wiphy->mgmt_stypes = wil_mgmt_stypes; wiphy->features |= NL80211_FEATURE_SK_TX_STATUS; wiphy->features |= NL80211_FEATURE_SK_TX_STATUS; wiphy->reg_notifier = wil_cfg80211_reg_notify; wiphy->n_vendor_commands = ARRAY_SIZE(wil_nl80211_vendor_commands); wiphy->n_vendor_commands = ARRAY_SIZE(wil_nl80211_vendor_commands); wiphy->vendor_commands = wil_nl80211_vendor_commands; wiphy->vendor_commands = wil_nl80211_vendor_commands; wiphy->vendor_events = wil_nl80211_vendor_events; wiphy->vendor_events = wil_nl80211_vendor_events; Loading
drivers/net/wireless/ath/wil6210/main.c +32 −5 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ #define WAIT_FOR_HALP_VOTE_MS 100 #define WAIT_FOR_HALP_VOTE_MS 100 #define WAIT_FOR_SCAN_ABORT_MS 1000 #define WAIT_FOR_SCAN_ABORT_MS 1000 #define WIL_BOARD_FILE_MAX_NAMELEN 128 bool debug_fw; /* = false; */ bool debug_fw; /* = false; */ module_param(debug_fw, bool, 0444); module_param(debug_fw, bool, 0444); Loading Loading @@ -946,6 +947,30 @@ void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) le32_to_cpus(&r->head); 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) static int wil_get_bl_info(struct wil6210_priv *wil) { { struct net_device *ndev = wil_to_ndev(wil); struct net_device *ndev = wil_to_ndev(wil); Loading Loading @@ -1260,8 +1285,12 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) wil_set_oob_mode(wil, oob_mode); wil_set_oob_mode(wil, oob_mode); if (load_fw) { 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_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) if (!no_flash) wil_bl_prepare_halt(wil); wil_bl_prepare_halt(wil); Loading @@ -1273,11 +1302,9 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) if (rc) if (rc) goto out; goto out; if (wil->brd_file_addr) if (wil->brd_file_addr) rc = wil_request_board(wil, WIL_BOARD_FILE_NAME); rc = wil_request_board(wil, board_file); else else rc = wil_request_firmware(wil, rc = wil_request_firmware(wil, board_file, true); WIL_BOARD_FILE_NAME, true); if (rc) if (rc) goto out; goto out; Loading
drivers/net/wireless/ath/wil6210/wil6210.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -683,6 +683,7 @@ struct wil6210_priv { const char *hw_name; const char *hw_name; const char *wil_fw_name; const char *wil_fw_name; char *board_file; char *board_file; char board_file_country[3]; /* alpha2 */ u32 brd_file_addr; u32 brd_file_addr; u32 brd_file_max_size; u32 brd_file_max_size; DECLARE_BITMAP(hw_capa, hw_capa_last); DECLARE_BITMAP(hw_capa, hw_capa_last); Loading Loading @@ -796,6 +797,8 @@ struct wil6210_priv { } snr_thresh; } snr_thresh; int fw_calib_result; int fw_calib_result; /* current reg domain configured in kernel */ char regdomain[3]; /* alpha2 */ #ifdef CONFIG_PM #ifdef CONFIG_PM struct notifier_block pm_notify; struct notifier_block pm_notify; Loading Loading @@ -873,6 +876,8 @@ static inline void wil_c(struct wil6210_priv *wil, u32 reg, u32 val) wil_w(wil, reg, wil_r(wil, reg) & ~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) #if defined(CONFIG_DYNAMIC_DEBUG) #define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize, \ #define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize, \ groupsize, buf, len, ascii) \ groupsize, buf, len, ascii) \ Loading