Loading drivers/net/wireless/ath/wil6210/cfg80211.c +66 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #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); Loading @@ -36,6 +37,10 @@ static struct wiphy_wowlan_support wil_wowlan_support = { }; #endif 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; module_param(ignore_reg_hints, bool, 0444); MODULE_PARM_DESC(ignore_reg_hints, " Ignore OTA regulatory hints (Default: true)"); Loading Loading @@ -2107,6 +2112,65 @@ wil_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev, 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, 2); } static const struct cfg80211_ops wil_cfg80211_ops = { .add_virtual_intf = wil_cfg80211_add_iface, .del_virtual_intf = wil_cfg80211_del_iface, Loading Loading @@ -2178,6 +2242,8 @@ static void wil_wiphy_init(struct wiphy *wiphy) wiphy->mgmt_stypes = wil_mgmt_stypes; 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->vendor_commands = wil_nl80211_vendor_commands; wiphy->vendor_events = wil_nl80211_vendor_events; Loading drivers/net/wireless/ath/wil6210/fw.c +3 −0 Original line number Diff line number Diff line /* * Copyright (c) 2014-2015,2017 Qualcomm Atheros, Inc. * Copyright (c) 2018, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading @@ -22,6 +23,8 @@ MODULE_FIRMWARE(WIL_FW_NAME_DEFAULT); MODULE_FIRMWARE(WIL_FW_NAME_SPARROW_PLUS); MODULE_FIRMWARE(WIL_BOARD_FILE_NAME); MODULE_FIRMWARE(WIL_FW_NAME_TALYN); MODULE_FIRMWARE(WIL_BRD_NAME_TALYN); static void wil_memset_toio_32(volatile void __iomem *dst, u32 val, Loading drivers/net/wireless/ath/wil6210/main.c +47 −5 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #define WAIT_FOR_HALP_VOTE_MS 100 #define WAIT_FOR_SCAN_ABORT_MS 1000 #define WIL_DEFAULT_NUM_RX_STATUS_RINGS 1 #define WIL_BOARD_FILE_MAX_NAMELEN 128 bool debug_fw; /* = false; */ module_param(debug_fw, bool, 0444); Loading Loading @@ -698,6 +699,7 @@ void wil_priv_deinit(struct wil6210_priv *wil) wmi_event_flush(wil); destroy_workqueue(wil->wq_service); destroy_workqueue(wil->wmi_wq); kfree(wil->board_file); } static void wil_shutdown_bl(struct wil6210_priv *wil) Loading Loading @@ -1132,6 +1134,44 @@ 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; const char *ext; int prefix_len; const char *wil_talyn_fw_name = ftm_mode ? WIL_FW_NAME_FTM_TALYN : WIL_FW_NAME_TALYN; if (wil->board_file) { board_file = wil->board_file; } else { /* If specific FW file is used for Talyn, * use specific board file */ if (strcmp(wil->wil_fw_name, wil_talyn_fw_name) == 0) board_file = WIL_BRD_NAME_TALYN; else board_file = WIL_BOARD_FILE_NAME; } 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; Loading Loading @@ -1512,8 +1552,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 (wil->secured_boot) { wil_err(wil, "secured boot is not supported\n"); Loading @@ -1530,11 +1574,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; Loading drivers/net/wireless/ath/wil6210/pcie_bus.c +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ static bool use_msi = true; module_param(use_msi, bool, 0444); MODULE_PARM_DESC(use_msi, " Use MSI interrupt, default - true"); static bool ftm_mode; bool ftm_mode; module_param(ftm_mode, bool, 0444); MODULE_PARM_DESC(ftm_mode, " Set factory test mode, default - false"); Loading drivers/net/wireless/ath/wil6210/sysfs.c +47 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,52 @@ static DEVICE_ATTR(ftm_txrx_offset, 0644, wil_ftm_txrx_offset_sysfs_show, wil_ftm_txrx_offset_sysfs_store); static ssize_t wil_board_file_sysfs_show(struct device *dev, struct device_attribute *attr, char *buf) { struct wil6210_priv *wil = dev_get_drvdata(dev); wil_get_board_file(wil, buf, PAGE_SIZE); strlcat(buf, "\n", PAGE_SIZE); return strlen(buf); } static ssize_t wil_board_file_sysfs_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wil6210_priv *wil = dev_get_drvdata(dev); size_t len; mutex_lock(&wil->mutex); kfree(wil->board_file); wil->board_file = NULL; len = count; if (buf[count - 1] == '\n') len--; len = strnlen(buf, len); if (len > 0) { wil->board_file = kmalloc(len + 1, GFP_KERNEL); if (!wil->board_file) { mutex_unlock(&wil->mutex); return -ENOMEM; } strlcpy(wil->board_file, buf, len + 1); } mutex_unlock(&wil->mutex); return count; } static DEVICE_ATTR(board_file, 0644, wil_board_file_sysfs_show, wil_board_file_sysfs_store); static ssize_t wil_tt_sysfs_show(struct device *dev, struct device_attribute *attr, char *buf) { Loading Loading @@ -310,6 +356,7 @@ static DEVICE_ATTR(snr_thresh, 0644, static struct attribute *wil6210_sysfs_entries[] = { &dev_attr_ftm_txrx_offset.attr, &dev_attr_board_file.attr, &dev_attr_thermal_throttling.attr, &dev_attr_fst_link_loss.attr, &dev_attr_snr_thresh.attr, Loading Loading
drivers/net/wireless/ath/wil6210/cfg80211.c +66 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #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); Loading @@ -36,6 +37,10 @@ static struct wiphy_wowlan_support wil_wowlan_support = { }; #endif 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; module_param(ignore_reg_hints, bool, 0444); MODULE_PARM_DESC(ignore_reg_hints, " Ignore OTA regulatory hints (Default: true)"); Loading Loading @@ -2107,6 +2112,65 @@ wil_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev, 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, 2); } static const struct cfg80211_ops wil_cfg80211_ops = { .add_virtual_intf = wil_cfg80211_add_iface, .del_virtual_intf = wil_cfg80211_del_iface, Loading Loading @@ -2178,6 +2242,8 @@ static void wil_wiphy_init(struct wiphy *wiphy) wiphy->mgmt_stypes = wil_mgmt_stypes; 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->vendor_commands = wil_nl80211_vendor_commands; wiphy->vendor_events = wil_nl80211_vendor_events; Loading
drivers/net/wireless/ath/wil6210/fw.c +3 −0 Original line number Diff line number Diff line /* * Copyright (c) 2014-2015,2017 Qualcomm Atheros, Inc. * Copyright (c) 2018, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading @@ -22,6 +23,8 @@ MODULE_FIRMWARE(WIL_FW_NAME_DEFAULT); MODULE_FIRMWARE(WIL_FW_NAME_SPARROW_PLUS); MODULE_FIRMWARE(WIL_BOARD_FILE_NAME); MODULE_FIRMWARE(WIL_FW_NAME_TALYN); MODULE_FIRMWARE(WIL_BRD_NAME_TALYN); static void wil_memset_toio_32(volatile void __iomem *dst, u32 val, Loading
drivers/net/wireless/ath/wil6210/main.c +47 −5 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #define WAIT_FOR_HALP_VOTE_MS 100 #define WAIT_FOR_SCAN_ABORT_MS 1000 #define WIL_DEFAULT_NUM_RX_STATUS_RINGS 1 #define WIL_BOARD_FILE_MAX_NAMELEN 128 bool debug_fw; /* = false; */ module_param(debug_fw, bool, 0444); Loading Loading @@ -698,6 +699,7 @@ void wil_priv_deinit(struct wil6210_priv *wil) wmi_event_flush(wil); destroy_workqueue(wil->wq_service); destroy_workqueue(wil->wmi_wq); kfree(wil->board_file); } static void wil_shutdown_bl(struct wil6210_priv *wil) Loading Loading @@ -1132,6 +1134,44 @@ 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; const char *ext; int prefix_len; const char *wil_talyn_fw_name = ftm_mode ? WIL_FW_NAME_FTM_TALYN : WIL_FW_NAME_TALYN; if (wil->board_file) { board_file = wil->board_file; } else { /* If specific FW file is used for Talyn, * use specific board file */ if (strcmp(wil->wil_fw_name, wil_talyn_fw_name) == 0) board_file = WIL_BRD_NAME_TALYN; else board_file = WIL_BOARD_FILE_NAME; } 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; Loading Loading @@ -1512,8 +1552,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 (wil->secured_boot) { wil_err(wil, "secured boot is not supported\n"); Loading @@ -1530,11 +1574,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; Loading
drivers/net/wireless/ath/wil6210/pcie_bus.c +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ static bool use_msi = true; module_param(use_msi, bool, 0444); MODULE_PARM_DESC(use_msi, " Use MSI interrupt, default - true"); static bool ftm_mode; bool ftm_mode; module_param(ftm_mode, bool, 0444); MODULE_PARM_DESC(ftm_mode, " Set factory test mode, default - false"); Loading
drivers/net/wireless/ath/wil6210/sysfs.c +47 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,52 @@ static DEVICE_ATTR(ftm_txrx_offset, 0644, wil_ftm_txrx_offset_sysfs_show, wil_ftm_txrx_offset_sysfs_store); static ssize_t wil_board_file_sysfs_show(struct device *dev, struct device_attribute *attr, char *buf) { struct wil6210_priv *wil = dev_get_drvdata(dev); wil_get_board_file(wil, buf, PAGE_SIZE); strlcat(buf, "\n", PAGE_SIZE); return strlen(buf); } static ssize_t wil_board_file_sysfs_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wil6210_priv *wil = dev_get_drvdata(dev); size_t len; mutex_lock(&wil->mutex); kfree(wil->board_file); wil->board_file = NULL; len = count; if (buf[count - 1] == '\n') len--; len = strnlen(buf, len); if (len > 0) { wil->board_file = kmalloc(len + 1, GFP_KERNEL); if (!wil->board_file) { mutex_unlock(&wil->mutex); return -ENOMEM; } strlcpy(wil->board_file, buf, len + 1); } mutex_unlock(&wil->mutex); return count; } static DEVICE_ATTR(board_file, 0644, wil_board_file_sysfs_show, wil_board_file_sysfs_store); static ssize_t wil_tt_sysfs_show(struct device *dev, struct device_attribute *attr, char *buf) { Loading Loading @@ -310,6 +356,7 @@ static DEVICE_ATTR(snr_thresh, 0644, static struct attribute *wil6210_sysfs_entries[] = { &dev_attr_ftm_txrx_offset.attr, &dev_attr_board_file.attr, &dev_attr_thermal_throttling.attr, &dev_attr_fst_link_loss.attr, &dev_attr_snr_thresh.attr, Loading