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:
Johannes Berg
2009-04-23 16:13:26 +02:00
committed by John W. Linville
parent 57c4d7b4c4
commit 2d0ddec5b2
34 changed files with 504 additions and 778 deletions

View File

@@ -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) */

View File

@@ -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);

View File

@@ -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);

View File

@@ -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,

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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) {

View File

@@ -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;