Commit 2a190322 authored by Felix Fietkau's avatar Felix Fietkau Committed by John W. Linville

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: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 69ce674b
...@@ -320,6 +320,10 @@ static void b43_wireless_core_exit(struct b43_wldev *dev); ...@@ -320,6 +320,10 @@ static void b43_wireless_core_exit(struct b43_wldev *dev);
static int b43_wireless_core_init(struct b43_wldev *dev); static int b43_wireless_core_init(struct b43_wldev *dev);
static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev); static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
static int b43_wireless_core_start(struct b43_wldev *dev); static int b43_wireless_core_start(struct b43_wldev *dev);
static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *conf,
u32 changed);
static int b43_ratelimit(struct b43_wl *wl) static int b43_ratelimit(struct b43_wl *wl)
{ {
...@@ -3778,14 +3782,24 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) ...@@ -3778,14 +3782,24 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
struct ieee80211_conf *conf = &hw->conf; struct ieee80211_conf *conf = &hw->conf;
int antenna; int antenna;
int err = 0; int err = 0;
bool reload_bss = false;
mutex_lock(&wl->mutex); mutex_lock(&wl->mutex);
dev = wl->current_dev;
/* Switch the band (if necessary). This might change the active core. */ /* Switch the band (if necessary). This might change the active core. */
err = b43_switch_band(wl, conf->channel); err = b43_switch_band(wl, conf->channel);
if (err) if (err)
goto out_unlock_mutex; goto out_unlock_mutex;
dev = wl->current_dev;
/* Need to reload all settings if the core changed */
if (dev != wl->current_dev) {
dev = wl->current_dev;
changed = ~0;
reload_bss = true;
}
phy = &dev->phy; phy = &dev->phy;
if (conf_is_ht(conf)) if (conf_is_ht(conf))
...@@ -3846,6 +3860,9 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) ...@@ -3846,6 +3860,9 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
out_unlock_mutex: out_unlock_mutex:
mutex_unlock(&wl->mutex); mutex_unlock(&wl->mutex);
if (wl->vif && reload_bss)
b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
return err; return err;
} }
...@@ -3934,7 +3951,8 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw, ...@@ -3934,7 +3951,8 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_BEACON_INT && if (changed & BSS_CHANGED_BEACON_INT &&
(b43_is_mode(wl, NL80211_IFTYPE_AP) || (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) || b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) ||
b43_is_mode(wl, NL80211_IFTYPE_ADHOC))) b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) &&
conf->beacon_int)
b43_set_beacon_int(dev, conf->beacon_int); b43_set_beacon_int(dev, conf->beacon_int);
if (changed & BSS_CHANGED_BASIC_RATES) if (changed & BSS_CHANGED_BASIC_RATES)
...@@ -4702,6 +4720,9 @@ static int b43_op_add_interface(struct ieee80211_hw *hw, ...@@ -4702,6 +4720,9 @@ static int b43_op_add_interface(struct ieee80211_hw *hw,
out_mutex_unlock: out_mutex_unlock:
mutex_unlock(&wl->mutex); mutex_unlock(&wl->mutex);
if (err == 0)
b43_op_bss_info_changed(hw, vif, &vif->bss_conf, ~0);
return err; return err;
} }
...@@ -4772,6 +4793,9 @@ static int b43_op_start(struct ieee80211_hw *hw) ...@@ -4772,6 +4793,9 @@ static int b43_op_start(struct ieee80211_hw *hw)
out_mutex_unlock: out_mutex_unlock:
mutex_unlock(&wl->mutex); mutex_unlock(&wl->mutex);
/* reload configuration */
b43_op_config(hw, ~0);
return err; return err;
} }
...@@ -4928,10 +4952,18 @@ static void b43_chip_reset(struct work_struct *work) ...@@ -4928,10 +4952,18 @@ static void b43_chip_reset(struct work_struct *work)
if (err) if (err)
wl->current_dev = NULL; /* Failed to init the dev. */ wl->current_dev = NULL; /* Failed to init the dev. */
mutex_unlock(&wl->mutex); mutex_unlock(&wl->mutex);
if (err)
if (err) {
b43err(wl, "Controller restart FAILED\n"); b43err(wl, "Controller restart FAILED\n");
else return;
b43info(wl, "Controller restarted\n"); }
/* reload configuration */
b43_op_config(wl->hw, ~0);
if (wl->vif)
b43_op_bss_info_changed(wl->hw, wl->vif, &wl->vif->bss_conf, ~0);
b43info(wl, "Controller restarted\n");
} }
static int b43_setup_bands(struct b43_wldev *dev, static int b43_setup_bands(struct b43_wldev *dev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment