Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

b43: reload phy and bss settings after core restarts

b43_op_config and b43_op_bss_info_changed apply many settings by directly
writing to hardware registers. These settings are lost as soon as the core
is restarted and the initvals are reloaded. This was discovered because
restarting hostapd led to the beacon interval getting set to ~33s (see
https://dev.openwrt.org/ticket/8033 for more information).

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Felix Fietkau and committed by
John W. Linville
2a190322 69ce674b

+37 -5
+37 -5
drivers/net/wireless/b43/main.c
··· 320 320 static int b43_wireless_core_init(struct b43_wldev *dev); 321 321 static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev); 322 322 static int b43_wireless_core_start(struct b43_wldev *dev); 323 + static void b43_op_bss_info_changed(struct ieee80211_hw *hw, 324 + struct ieee80211_vif *vif, 325 + struct ieee80211_bss_conf *conf, 326 + u32 changed); 323 327 324 328 static int b43_ratelimit(struct b43_wl *wl) 325 329 { ··· 3782 3778 struct ieee80211_conf *conf = &hw->conf; 3783 3779 int antenna; 3784 3780 int err = 0; 3781 + bool reload_bss = false; 3785 3782 3786 3783 mutex_lock(&wl->mutex); 3784 + 3785 + dev = wl->current_dev; 3787 3786 3788 3787 /* Switch the band (if necessary). This might change the active core. */ 3789 3788 err = b43_switch_band(wl, conf->channel); 3790 3789 if (err) 3791 3790 goto out_unlock_mutex; 3792 - dev = wl->current_dev; 3791 + 3792 + /* Need to reload all settings if the core changed */ 3793 + if (dev != wl->current_dev) { 3794 + dev = wl->current_dev; 3795 + changed = ~0; 3796 + reload_bss = true; 3797 + } 3798 + 3793 3799 phy = &dev->phy; 3794 3800 3795 3801 if (conf_is_ht(conf)) ··· 3859 3845 b43_mac_enable(dev); 3860 3846 out_unlock_mutex: 3861 3847 mutex_unlock(&wl->mutex); 3848 + 3849 + if (wl->vif && reload_bss) 3850 + b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0); 3862 3851 3863 3852 return err; 3864 3853 } ··· 3951 3934 if (changed & BSS_CHANGED_BEACON_INT && 3952 3935 (b43_is_mode(wl, NL80211_IFTYPE_AP) || 3953 3936 b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) || 3954 - b43_is_mode(wl, NL80211_IFTYPE_ADHOC))) 3937 + b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) && 3938 + conf->beacon_int) 3955 3939 b43_set_beacon_int(dev, conf->beacon_int); 3956 3940 3957 3941 if (changed & BSS_CHANGED_BASIC_RATES) ··· 4720 4702 out_mutex_unlock: 4721 4703 mutex_unlock(&wl->mutex); 4722 4704 4705 + if (err == 0) 4706 + b43_op_bss_info_changed(hw, vif, &vif->bss_conf, ~0); 4707 + 4723 4708 return err; 4724 4709 } 4725 4710 ··· 4792 4771 4793 4772 out_mutex_unlock: 4794 4773 mutex_unlock(&wl->mutex); 4774 + 4775 + /* reload configuration */ 4776 + b43_op_config(hw, ~0); 4795 4777 4796 4778 return err; 4797 4779 } ··· 4952 4928 if (err) 4953 4929 wl->current_dev = NULL; /* Failed to init the dev. */ 4954 4930 mutex_unlock(&wl->mutex); 4955 - if (err) 4931 + 4932 + if (err) { 4956 4933 b43err(wl, "Controller restart FAILED\n"); 4957 - else 4958 - b43info(wl, "Controller restarted\n"); 4934 + return; 4935 + } 4936 + 4937 + /* reload configuration */ 4938 + b43_op_config(wl->hw, ~0); 4939 + if (wl->vif) 4940 + b43_op_bss_info_changed(wl->hw, wl->vif, &wl->vif->bss_conf, ~0); 4941 + 4942 + b43info(wl, "Controller restarted\n"); 4959 4943 } 4960 4944 4961 4945 static int b43_setup_bands(struct b43_wldev *dev,