mac80211: unify config_interface and bss_info_changed
The config_interface method is a little strange, it contains the BSSID and beacon updates, while bss_info_changed contains most other BSS information for each interface. This patch removes config_interface and rolls all the information it previously passed to drivers into bss_info_changed. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:

committed by
John W. Linville

parent
57c4d7b4c4
commit
2d0ddec5b2
@@ -521,8 +521,9 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
kfree(old);
|
||||
|
||||
return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
|
||||
IEEE80211_IFCC_BEACON_ENABLED);
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
|
||||
BSS_CHANGED_BEACON);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
|
||||
@@ -573,7 +574,8 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
|
||||
synchronize_rcu();
|
||||
kfree(old);
|
||||
|
||||
return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED);
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
|
||||
|
@@ -95,17 +95,10 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
|
||||
|
||||
ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
|
||||
|
||||
local->oper_channel = chan;
|
||||
local->oper_channel_type = NL80211_CHAN_NO_HT;
|
||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
|
||||
|
||||
sdata->vif.bss_conf.beacon_int = beacon_int;
|
||||
bss_change = BSS_CHANGED_BEACON_INT;
|
||||
bss_change |= ieee80211_reset_erp_info(sdata);
|
||||
ieee80211_bss_info_change_notify(sdata, bss_change);
|
||||
|
||||
sband = local->hw.wiphy->bands[chan->band];
|
||||
|
||||
/* Build IBSS probe response */
|
||||
@@ -161,8 +154,13 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
rcu_assign_pointer(ifibss->presp, skb);
|
||||
|
||||
ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
|
||||
IEEE80211_IFCC_BEACON_ENABLED);
|
||||
sdata->vif.bss_conf.beacon_int = beacon_int;
|
||||
bss_change = BSS_CHANGED_BEACON_INT;
|
||||
bss_change |= ieee80211_reset_erp_info(sdata);
|
||||
bss_change |= BSS_CHANGED_BSSID;
|
||||
bss_change |= BSS_CHANGED_BEACON;
|
||||
bss_change |= BSS_CHANGED_BEACON_ENABLED;
|
||||
ieee80211_bss_info_change_notify(sdata, bss_change);
|
||||
|
||||
rates = 0;
|
||||
for (i = 0; i < supp_rates_len; i++) {
|
||||
@@ -887,7 +885,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
|
||||
kfree(sdata->u.ibss.ie);
|
||||
skb = sdata->u.ibss.presp;
|
||||
rcu_assign_pointer(sdata->u.ibss.presp, NULL);
|
||||
ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED);
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
|
||||
synchronize_rcu();
|
||||
kfree_skb(skb);
|
||||
|
||||
|
@@ -906,7 +906,6 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
|
||||
|
||||
|
||||
int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
|
||||
int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed);
|
||||
void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
|
||||
void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
|
||||
u32 changed);
|
||||
|
@@ -152,82 +152,6 @@ static void ieee80211_master_set_multicast_list(struct net_device *dev)
|
||||
ieee80211_configure_filter(local);
|
||||
}
|
||||
|
||||
/* everything else */
|
||||
|
||||
int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_if_conf conf;
|
||||
|
||||
if (WARN_ON(!netif_running(sdata->dev)))
|
||||
return 0;
|
||||
|
||||
memset(&conf, 0, sizeof(conf));
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||
conf.bssid = sdata->u.mgd.bssid;
|
||||
else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
|
||||
conf.bssid = sdata->u.ibss.bssid;
|
||||
else if (sdata->vif.type == NL80211_IFTYPE_AP)
|
||||
conf.bssid = sdata->dev->dev_addr;
|
||||
else if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
||||
static const u8 zero[ETH_ALEN] = { 0 };
|
||||
conf.bssid = zero;
|
||||
} else {
|
||||
WARN_ON(1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!local->ops->config_interface)
|
||||
return 0;
|
||||
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
break;
|
||||
default:
|
||||
/* do not warn to simplify caller in scan.c */
|
||||
changed &= ~IEEE80211_IFCC_BEACON_ENABLED;
|
||||
if (WARN_ON(changed & IEEE80211_IFCC_BEACON))
|
||||
return -EINVAL;
|
||||
changed &= ~IEEE80211_IFCC_BEACON;
|
||||
break;
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_IFCC_BEACON_ENABLED) {
|
||||
if (local->sw_scanning) {
|
||||
conf.enable_beacon = false;
|
||||
} else {
|
||||
/*
|
||||
* Beacon should be enabled, but AP mode must
|
||||
* check whether there is a beacon configured.
|
||||
*/
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
conf.enable_beacon =
|
||||
!!rcu_dereference(sdata->u.ap.beacon);
|
||||
break;
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
conf.enable_beacon = !!sdata->u.ibss.presp;
|
||||
break;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
conf.enable_beacon = true;
|
||||
break;
|
||||
default:
|
||||
/* not reached */
|
||||
WARN_ON(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
conf.changed = changed;
|
||||
|
||||
return local->ops->config_interface(local_to_hw(local),
|
||||
&sdata->vif, &conf);
|
||||
}
|
||||
|
||||
int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
|
||||
{
|
||||
struct ieee80211_channel *chan;
|
||||
@@ -297,6 +221,61 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
|
||||
if (!changed)
|
||||
return;
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||
sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
|
||||
else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
|
||||
sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
|
||||
else if (sdata->vif.type == NL80211_IFTYPE_AP)
|
||||
sdata->vif.bss_conf.bssid = sdata->dev->dev_addr;
|
||||
else if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
||||
static const u8 zero[ETH_ALEN] = { 0 };
|
||||
sdata->vif.bss_conf.bssid = zero;
|
||||
} else {
|
||||
WARN_ON(1);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
break;
|
||||
default:
|
||||
/* do not warn to simplify caller in scan.c */
|
||||
changed &= ~BSS_CHANGED_BEACON_ENABLED;
|
||||
if (WARN_ON(changed & BSS_CHANGED_BEACON))
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_BEACON_ENABLED) {
|
||||
if (local->sw_scanning) {
|
||||
sdata->vif.bss_conf.enable_beacon = false;
|
||||
} else {
|
||||
/*
|
||||
* Beacon should be enabled, but AP mode must
|
||||
* check whether there is a beacon configured.
|
||||
*/
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
sdata->vif.bss_conf.enable_beacon =
|
||||
!!rcu_dereference(sdata->u.ap.beacon);
|
||||
break;
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
sdata->vif.bss_conf.enable_beacon =
|
||||
!!rcu_dereference(sdata->u.ibss.presp);
|
||||
break;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
sdata->vif.bss_conf.enable_beacon = true;
|
||||
break;
|
||||
default:
|
||||
/* not reached */
|
||||
WARN_ON(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (local->ops->bss_info_changed)
|
||||
local->ops->bss_info_changed(local_to_hw(local),
|
||||
&sdata->vif,
|
||||
|
@@ -417,7 +417,7 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
free_plinks = mesh_plink_availables(sdata);
|
||||
if (free_plinks != sdata->u.mesh.accepting_plinks)
|
||||
ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
|
||||
|
||||
ifmsh->housekeeping = false;
|
||||
mod_timer(&ifmsh->housekeeping_timer,
|
||||
@@ -432,8 +432,8 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
|
||||
|
||||
ifmsh->housekeeping = true;
|
||||
queue_work(local->hw.workqueue, &ifmsh->work);
|
||||
ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
|
||||
IEEE80211_IFCC_BEACON_ENABLED);
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
|
||||
BSS_CHANGED_BEACON_ENABLED);
|
||||
}
|
||||
|
||||
void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
|
||||
|
@@ -2289,12 +2289,8 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
|
||||
ifmgd->flags &= ~IEEE80211_STA_BSSID_SET;
|
||||
}
|
||||
|
||||
if (netif_running(sdata->dev)) {
|
||||
if (ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID)) {
|
||||
printk(KERN_DEBUG "%s: Failed to config new BSSID to "
|
||||
"the low-level driver\n", sdata->dev->name);
|
||||
}
|
||||
}
|
||||
if (netif_running(sdata->dev))
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
|
||||
|
||||
return ieee80211_sta_commit(sdata);
|
||||
}
|
||||
|
@@ -346,8 +346,8 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP ||
|
||||
sdata->vif.type == NL80211_IFTYPE_ADHOC ||
|
||||
sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
|
||||
ieee80211_if_config(sdata,
|
||||
IEEE80211_IFCC_BEACON_ENABLED);
|
||||
ieee80211_bss_info_change_notify(
|
||||
sdata, BSS_CHANGED_BEACON_ENABLED);
|
||||
}
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
|
||||
@@ -387,8 +387,8 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP ||
|
||||
sdata->vif.type == NL80211_IFTYPE_ADHOC ||
|
||||
sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
|
||||
ieee80211_if_config(sdata,
|
||||
IEEE80211_IFCC_BEACON_ENABLED);
|
||||
ieee80211_bss_info_change_notify(
|
||||
sdata, BSS_CHANGED_BEACON_ENABLED);
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
|
||||
if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) {
|
||||
|
@@ -1063,24 +1063,13 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
/* disable beacon change bits */
|
||||
changed &= ~IEEE80211_IFCC_BEACON;
|
||||
changed &= ~(BSS_CHANGED_BEACON |
|
||||
BSS_CHANGED_BEACON_ENABLED);
|
||||
/* fall through */
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
/*
|
||||
* Driver's config_interface can fail if rfkill is
|
||||
* enabled. Accommodate this return code.
|
||||
* FIXME: When mac80211 has knowledge of rfkill
|
||||
* state the code below can change back to:
|
||||
* WARN(ieee80211_if_config(sdata, changed));
|
||||
* ieee80211_bss_info_change_notify(sdata, ~0);
|
||||
*/
|
||||
if (ieee80211_if_config(sdata, changed))
|
||||
printk(KERN_DEBUG "%s: failed to configure interface during resume\n",
|
||||
sdata->dev->name);
|
||||
else
|
||||
ieee80211_bss_info_change_notify(sdata, ~0);
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
break;
|
||||
case NL80211_IFTYPE_WDS:
|
||||
break;
|
||||
|
Reference in New Issue
Block a user