aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/adm8211.c14
-rw-r--r--drivers/net/wireless/at76c50x-usb.c15
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c39
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c71
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c182
-rw-r--r--drivers/net/wireless/b43/main.c64
-rw-r--r--drivers/net/wireless/b43legacy/main.c63
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c162
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c1
-rw-r--r--drivers/net/wireless/libertas_tf/main.c56
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c25
-rw-r--r--drivers/net/wireless/mwl8k.c18
-rw-r--r--drivers/net/wireless/p54/p54common.c63
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c88
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c33
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c48
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c80
-rw-r--r--include/net/mac80211.h51
-rw-r--r--net/mac80211/cfg.c8
-rw-r--r--net/mac80211/ibss.c18
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/main.c131
-rw-r--r--net/mac80211/mesh.c6
-rw-r--r--net/mac80211/mlme.c8
-rw-r--r--net/mac80211/scan.c8
-rw-r--r--net/mac80211/util.c17
34 files changed, 504 insertions, 778 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index f71821795018..2b9e379994a1 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1311,18 +1311,20 @@ static int adm8211_config(struct ieee80211_hw *dev, u32 changed)
1311 return 0; 1311 return 0;
1312} 1312}
1313 1313
1314static int adm8211_config_interface(struct ieee80211_hw *dev, 1314static void adm8211_bss_info_changed(struct ieee80211_hw *dev,
1315 struct ieee80211_vif *vif, 1315 struct ieee80211_vif *vif,
1316 struct ieee80211_if_conf *conf) 1316 struct ieee80211_bss_conf *conf,
1317 u32 changes)
1317{ 1318{
1318 struct adm8211_priv *priv = dev->priv; 1319 struct adm8211_priv *priv = dev->priv;
1319 1320
1321 if (!(changes & BSS_CHANGED_BSSID))
1322 return;
1323
1320 if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) { 1324 if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {
1321 adm8211_set_bssid(dev, conf->bssid); 1325 adm8211_set_bssid(dev, conf->bssid);
1322 memcpy(priv->bssid, conf->bssid, ETH_ALEN); 1326 memcpy(priv->bssid, conf->bssid, ETH_ALEN);
1323 } 1327 }
1324
1325 return 0;
1326} 1328}
1327 1329
1328static void adm8211_configure_filter(struct ieee80211_hw *dev, 1330static void adm8211_configure_filter(struct ieee80211_hw *dev,
@@ -1753,7 +1755,7 @@ static const struct ieee80211_ops adm8211_ops = {
1753 .add_interface = adm8211_add_interface, 1755 .add_interface = adm8211_add_interface,
1754 .remove_interface = adm8211_remove_interface, 1756 .remove_interface = adm8211_remove_interface,
1755 .config = adm8211_config, 1757 .config = adm8211_config,
1756 .config_interface = adm8211_config_interface, 1758 .bss_info_changed = adm8211_bss_info_changed,
1757 .configure_filter = adm8211_configure_filter, 1759 .configure_filter = adm8211_configure_filter,
1758 .get_stats = adm8211_get_stats, 1760 .get_stats = adm8211_get_stats,
1759 .get_tx_stats = adm8211_get_tx_stats, 1761 .get_tx_stats = adm8211_get_tx_stats,
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 55f947ac56d1..cea7f1466c54 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1965,13 +1965,18 @@ static int at76_config(struct ieee80211_hw *hw, u32 changed)
1965 return 0; 1965 return 0;
1966} 1966}
1967 1967
1968static int at76_config_interface(struct ieee80211_hw *hw, 1968static void at76_bss_info_changed(struct ieee80211_hw *hw,
1969 struct ieee80211_vif *vif, 1969 struct ieee80211_vif *vif,
1970 struct ieee80211_if_conf *conf) 1970 struct ieee80211_bss_conf *conf,
1971 u32 changed)
1971{ 1972{
1972 struct at76_priv *priv = hw->priv; 1973 struct at76_priv *priv = hw->priv;
1973 1974
1974 at76_dbg(DBG_MAC80211, "%s():", __func__); 1975 at76_dbg(DBG_MAC80211, "%s():", __func__);
1976
1977 if (!(changed & BSS_CHANGED_BSSID))
1978 return;
1979
1975 at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:"); 1980 at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:");
1976 1981
1977 mutex_lock(&priv->mtx); 1982 mutex_lock(&priv->mtx);
@@ -1983,8 +1988,6 @@ static int at76_config_interface(struct ieee80211_hw *hw,
1983 at76_join(priv); 1988 at76_join(priv);
1984 1989
1985 mutex_unlock(&priv->mtx); 1990 mutex_unlock(&priv->mtx);
1986
1987 return 0;
1988} 1991}
1989 1992
1990/* must be atomic */ 1993/* must be atomic */
@@ -2076,7 +2079,7 @@ static const struct ieee80211_ops at76_ops = {
2076 .add_interface = at76_add_interface, 2079 .add_interface = at76_add_interface,
2077 .remove_interface = at76_remove_interface, 2080 .remove_interface = at76_remove_interface,
2078 .config = at76_config, 2081 .config = at76_config,
2079 .config_interface = at76_config_interface, 2082 .bss_info_changed = at76_bss_info_changed,
2080 .configure_filter = at76_configure_filter, 2083 .configure_filter = at76_configure_filter,
2081 .start = at76_mac80211_start, 2084 .start = at76_mac80211_start,
2082 .stop = at76_mac80211_stop, 2085 .stop = at76_mac80211_stop,
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 49c729bc7147..3bd3a61225ce 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -1360,33 +1360,6 @@ out:
1360 return err; 1360 return err;
1361} 1361}
1362 1362
1363static int ar9170_op_config_interface(struct ieee80211_hw *hw,
1364 struct ieee80211_vif *vif,
1365 struct ieee80211_if_conf *conf)
1366{
1367 struct ar9170 *ar = hw->priv;
1368 int err = 0;
1369
1370 mutex_lock(&ar->mutex);
1371
1372 if (conf->changed & IEEE80211_IFCC_BSSID) {
1373 memcpy(ar->bssid, conf->bssid, ETH_ALEN);
1374 err = ar9170_set_operating_mode(ar);
1375 }
1376
1377 if (conf->changed & IEEE80211_IFCC_BEACON) {
1378 err = ar9170_update_beacon(ar);
1379
1380 if (err)
1381 goto out;
1382 err = ar9170_set_beacon_timers(ar);
1383 }
1384
1385out:
1386 mutex_unlock(&ar->mutex);
1387 return err;
1388}
1389
1390static void ar9170_set_filters(struct work_struct *work) 1363static void ar9170_set_filters(struct work_struct *work)
1391{ 1364{
1392 struct ar9170 *ar = container_of(work, struct ar9170, 1365 struct ar9170 *ar = container_of(work, struct ar9170,
@@ -1488,6 +1461,17 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
1488 1461
1489 mutex_lock(&ar->mutex); 1462 mutex_lock(&ar->mutex);
1490 1463
1464 if (changed & BSS_CHANGED_BSSID) {
1465 memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN);
1466 err = ar9170_set_operating_mode(ar);
1467 }
1468
1469 if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) {
1470 err = ar9170_update_beacon(ar);
1471 if (!err)
1472 ar9170_set_beacon_timers(ar);
1473 }
1474
1491 ar9170_regwrite_begin(ar); 1475 ar9170_regwrite_begin(ar);
1492 1476
1493 if (changed & BSS_CHANGED_ASSOC) { 1477 if (changed & BSS_CHANGED_ASSOC) {
@@ -1796,7 +1780,6 @@ static const struct ieee80211_ops ar9170_ops = {
1796 .add_interface = ar9170_op_add_interface, 1780 .add_interface = ar9170_op_add_interface,
1797 .remove_interface = ar9170_op_remove_interface, 1781 .remove_interface = ar9170_op_remove_interface,
1798 .config = ar9170_op_config, 1782 .config = ar9170_op_config,
1799 .config_interface = ar9170_op_config_interface,
1800 .configure_filter = ar9170_op_configure_filter, 1783 .configure_filter = ar9170_op_configure_filter,
1801 .conf_tx = ar9170_conf_tx, 1784 .conf_tx = ar9170_conf_tx,
1802 .bss_info_changed = ar9170_op_bss_info_changed, 1785 .bss_info_changed = ar9170_op_bss_info_changed,
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index e4b1d9efa42e..410fc4cfc4c6 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -227,9 +227,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
227static void ath5k_remove_interface(struct ieee80211_hw *hw, 227static void ath5k_remove_interface(struct ieee80211_hw *hw,
228 struct ieee80211_if_init_conf *conf); 228 struct ieee80211_if_init_conf *conf);
229static int ath5k_config(struct ieee80211_hw *hw, u32 changed); 229static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
230static int ath5k_config_interface(struct ieee80211_hw *hw,
231 struct ieee80211_vif *vif,
232 struct ieee80211_if_conf *conf);
233static void ath5k_configure_filter(struct ieee80211_hw *hw, 230static void ath5k_configure_filter(struct ieee80211_hw *hw,
234 unsigned int changed_flags, 231 unsigned int changed_flags,
235 unsigned int *new_flags, 232 unsigned int *new_flags,
@@ -259,7 +256,6 @@ static const struct ieee80211_ops ath5k_hw_ops = {
259 .add_interface = ath5k_add_interface, 256 .add_interface = ath5k_add_interface,
260 .remove_interface = ath5k_remove_interface, 257 .remove_interface = ath5k_remove_interface,
261 .config = ath5k_config, 258 .config = ath5k_config,
262 .config_interface = ath5k_config_interface,
263 .configure_filter = ath5k_configure_filter, 259 .configure_filter = ath5k_configure_filter,
264 .set_key = ath5k_set_key, 260 .set_key = ath5k_set_key,
265 .get_stats = ath5k_get_stats, 261 .get_stats = ath5k_get_stats,
@@ -2764,44 +2760,6 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
2764 return ret; 2760 return ret;
2765} 2761}
2766 2762
2767static int
2768ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2769 struct ieee80211_if_conf *conf)
2770{
2771 struct ath5k_softc *sc = hw->priv;
2772 struct ath5k_hw *ah = sc->ah;
2773 int ret = 0;
2774
2775 mutex_lock(&sc->lock);
2776 if (sc->vif != vif) {
2777 ret = -EIO;
2778 goto unlock;
2779 }
2780 if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
2781 /* Cache for later use during resets */
2782 memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN);
2783 /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
2784 * a clean way of letting us retrieve this yet. */
2785 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
2786 mmiowb();
2787 }
2788 if (conf->changed & IEEE80211_IFCC_BEACON &&
2789 (vif->type == NL80211_IFTYPE_ADHOC ||
2790 vif->type == NL80211_IFTYPE_MESH_POINT ||
2791 vif->type == NL80211_IFTYPE_AP)) {
2792 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
2793 if (!beacon) {
2794 ret = -ENOMEM;
2795 goto unlock;
2796 }
2797 ath5k_beacon_update(sc, beacon);
2798 }
2799
2800unlock:
2801 mutex_unlock(&sc->lock);
2802 return ret;
2803}
2804
2805#define SUPPORTED_FIF_FLAGS \ 2763#define SUPPORTED_FIF_FLAGS \
2806 FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ 2764 FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \
2807 FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ 2765 FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
@@ -3082,15 +3040,40 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3082 u32 changes) 3040 u32 changes)
3083{ 3041{
3084 struct ath5k_softc *sc = hw->priv; 3042 struct ath5k_softc *sc = hw->priv;
3043 struct ath5k_hw *ah = sc->ah;
3044
3045 mutex_lock(&sc->lock);
3046 if (WARN_ON(sc->vif != vif))
3047 goto unlock;
3048
3049 if (changes & BSS_CHANGED_BSSID) {
3050 /* Cache for later use during resets */
3051 memcpy(ah->ah_bssid, bss_conf->bssid, ETH_ALEN);
3052 /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
3053 * a clean way of letting us retrieve this yet. */
3054 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
3055 mmiowb();
3056 }
3085 3057
3086 if (changes & BSS_CHANGED_BEACON_INT) 3058 if (changes & BSS_CHANGED_BEACON_INT)
3087 sc->bintval = bss_conf->beacon_int; 3059 sc->bintval = bss_conf->beacon_int;
3088 3060
3089 if (changes & BSS_CHANGED_ASSOC) { 3061 if (changes & BSS_CHANGED_ASSOC) {
3090 mutex_lock(&sc->lock);
3091 sc->assoc = bss_conf->assoc; 3062 sc->assoc = bss_conf->assoc;
3092 if (sc->opmode == NL80211_IFTYPE_STATION) 3063 if (sc->opmode == NL80211_IFTYPE_STATION)
3093 set_beacon_filter(hw, sc->assoc); 3064 set_beacon_filter(hw, sc->assoc);
3094 mutex_unlock(&sc->lock);
3095 } 3065 }
3066
3067 if (changes & BSS_CHANGED_BEACON &&
3068 (vif->type == NL80211_IFTYPE_ADHOC ||
3069 vif->type == NL80211_IFTYPE_MESH_POINT ||
3070 vif->type == NL80211_IFTYPE_AP)) {
3071 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
3072
3073 if (beacon)
3074 ath5k_beacon_update(sc, beacon);
3075 }
3076
3077 unlock:
3078 mutex_unlock(&sc->lock);
3096} 3079}
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 28cc9cd52f32..d3dc8e2c77b2 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2363,104 +2363,6 @@ skip_chan_change:
2363 return 0; 2363 return 0;
2364} 2364}
2365 2365
2366static int ath9k_config_interface(struct ieee80211_hw *hw,
2367 struct ieee80211_vif *vif,
2368 struct ieee80211_if_conf *conf)
2369{
2370 struct ath_wiphy *aphy = hw->priv;
2371 struct ath_softc *sc = aphy->sc;
2372 struct ath_hw *ah = sc->sc_ah;
2373 struct ath_vif *avp = (void *)vif->drv_priv;
2374 u32 rfilt = 0;
2375 int error, i;
2376
2377 mutex_lock(&sc->mutex);
2378
2379 /* TODO: Need to decide which hw opmode to use for multi-interface
2380 * cases */
2381 if (vif->type == NL80211_IFTYPE_AP &&
2382 ah->opmode != NL80211_IFTYPE_AP) {
2383 ah->opmode = NL80211_IFTYPE_STATION;
2384 ath9k_hw_setopmode(ah);
2385 memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
2386 sc->curaid = 0;
2387 ath9k_hw_write_associd(sc);
2388 /* Request full reset to get hw opmode changed properly */
2389 sc->sc_flags |= SC_OP_FULL_RESET;
2390 }
2391
2392 if ((conf->changed & IEEE80211_IFCC_BSSID) &&
2393 !is_zero_ether_addr(conf->bssid)) {
2394 switch (vif->type) {
2395 case NL80211_IFTYPE_STATION:
2396 case NL80211_IFTYPE_ADHOC:
2397 case NL80211_IFTYPE_MESH_POINT:
2398 /* Set BSSID */
2399 memcpy(sc->curbssid, conf->bssid, ETH_ALEN);
2400 memcpy(avp->bssid, conf->bssid, ETH_ALEN);
2401 sc->curaid = 0;
2402 ath9k_hw_write_associd(sc);
2403
2404 /* Set aggregation protection mode parameters */
2405 sc->config.ath_aggr_prot = 0;
2406
2407 DPRINTF(sc, ATH_DBG_CONFIG,
2408 "RX filter 0x%x bssid %pM aid 0x%x\n",
2409 rfilt, sc->curbssid, sc->curaid);
2410
2411 /* need to reconfigure the beacon */
2412 sc->sc_flags &= ~SC_OP_BEACONS ;
2413
2414 break;
2415 default:
2416 break;
2417 }
2418 }
2419
2420 if ((vif->type == NL80211_IFTYPE_ADHOC) ||
2421 (vif->type == NL80211_IFTYPE_AP) ||
2422 (vif->type == NL80211_IFTYPE_MESH_POINT)) {
2423 if ((conf->changed & IEEE80211_IFCC_BEACON) ||
2424 (conf->changed & IEEE80211_IFCC_BEACON_ENABLED &&
2425 conf->enable_beacon)) {
2426 /*
2427 * Allocate and setup the beacon frame.
2428 *
2429 * Stop any previous beacon DMA. This may be
2430 * necessary, for example, when an ibss merge
2431 * causes reconfiguration; we may be called
2432 * with beacon transmission active.
2433 */
2434 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
2435
2436 error = ath_beacon_alloc(aphy, vif);
2437 if (error != 0) {
2438 mutex_unlock(&sc->mutex);
2439 return error;
2440 }
2441
2442 ath_beacon_config(sc, vif);
2443 }
2444 }
2445
2446 /* Check for WLAN_CAPABILITY_PRIVACY ? */
2447 if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
2448 for (i = 0; i < IEEE80211_WEP_NKID; i++)
2449 if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
2450 ath9k_hw_keysetmac(sc->sc_ah,
2451 (u16)i,
2452 sc->curbssid);
2453 }
2454
2455 /* Only legacy IBSS for now */
2456 if (vif->type == NL80211_IFTYPE_ADHOC)
2457 ath_update_chainmask(sc, 0);
2458
2459 mutex_unlock(&sc->mutex);
2460
2461 return 0;
2462}
2463
2464#define SUPPORTED_FILTERS \ 2366#define SUPPORTED_FILTERS \
2465 (FIF_PROMISC_IN_BSS | \ 2367 (FIF_PROMISC_IN_BSS | \
2466 FIF_ALLMULTI | \ 2368 FIF_ALLMULTI | \
@@ -2597,9 +2499,92 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
2597{ 2499{
2598 struct ath_wiphy *aphy = hw->priv; 2500 struct ath_wiphy *aphy = hw->priv;
2599 struct ath_softc *sc = aphy->sc; 2501 struct ath_softc *sc = aphy->sc;
2502 struct ath_hw *ah = sc->sc_ah;
2503 struct ath_vif *avp = (void *)vif->drv_priv;
2504 u32 rfilt = 0;
2505 int error, i;
2600 2506
2601 mutex_lock(&sc->mutex); 2507 mutex_lock(&sc->mutex);
2602 2508
2509 /*
2510 * TODO: Need to decide which hw opmode to use for
2511 * multi-interface cases
2512 * XXX: This belongs into add_interface!
2513 */
2514 if (vif->type == NL80211_IFTYPE_AP &&
2515 ah->opmode != NL80211_IFTYPE_AP) {
2516 ah->opmode = NL80211_IFTYPE_STATION;
2517 ath9k_hw_setopmode(ah);
2518 memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
2519 sc->curaid = 0;
2520 ath9k_hw_write_associd(sc);
2521 /* Request full reset to get hw opmode changed properly */
2522 sc->sc_flags |= SC_OP_FULL_RESET;
2523 }
2524
2525 if ((changed & BSS_CHANGED_BSSID) &&
2526 !is_zero_ether_addr(bss_conf->bssid)) {
2527 switch (vif->type) {
2528 case NL80211_IFTYPE_STATION:
2529 case NL80211_IFTYPE_ADHOC:
2530 case NL80211_IFTYPE_MESH_POINT:
2531 /* Set BSSID */
2532 memcpy(sc->curbssid, bss_conf->bssid, ETH_ALEN);
2533 memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
2534 sc->curaid = 0;
2535 ath9k_hw_write_associd(sc);
2536
2537 /* Set aggregation protection mode parameters */
2538 sc->config.ath_aggr_prot = 0;
2539
2540 DPRINTF(sc, ATH_DBG_CONFIG,
2541 "RX filter 0x%x bssid %pM aid 0x%x\n",
2542 rfilt, sc->curbssid, sc->curaid);
2543
2544 /* need to reconfigure the beacon */
2545 sc->sc_flags &= ~SC_OP_BEACONS ;
2546
2547 break;
2548 default:
2549 break;
2550 }
2551 }
2552
2553 if ((vif->type == NL80211_IFTYPE_ADHOC) ||
2554 (vif->type == NL80211_IFTYPE_AP) ||
2555 (vif->type == NL80211_IFTYPE_MESH_POINT)) {
2556 if ((changed & BSS_CHANGED_BEACON) ||
2557 (changed & BSS_CHANGED_BEACON_ENABLED &&
2558 bss_conf->enable_beacon)) {
2559 /*
2560 * Allocate and setup the beacon frame.
2561 *
2562 * Stop any previous beacon DMA. This may be
2563 * necessary, for example, when an ibss merge
2564 * causes reconfiguration; we may be called
2565 * with beacon transmission active.
2566 */
2567 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
2568
2569 error = ath_beacon_alloc(aphy, vif);
2570 if (!error)
2571 ath_beacon_config(sc, vif);
2572 }
2573 }
2574
2575 /* Check for WLAN_CAPABILITY_PRIVACY ? */
2576 if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
2577 for (i = 0; i < IEEE80211_WEP_NKID; i++)
2578 if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
2579 ath9k_hw_keysetmac(sc->sc_ah,
2580 (u16)i,
2581 sc->curbssid);
2582 }
2583
2584 /* Only legacy IBSS for now */
2585 if (vif->type == NL80211_IFTYPE_ADHOC)
2586 ath_update_chainmask(sc, 0);
2587
2603 if (changed & BSS_CHANGED_ERP_PREAMBLE) { 2588 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
2604 DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", 2589 DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
2605 bss_conf->use_short_preamble); 2590 bss_conf->use_short_preamble);
@@ -2757,7 +2742,6 @@ struct ieee80211_ops ath9k_ops = {
2757 .add_interface = ath9k_add_interface, 2742 .add_interface = ath9k_add_interface,
2758 .remove_interface = ath9k_remove_interface, 2743 .remove_interface = ath9k_remove_interface,
2759 .config = ath9k_config, 2744 .config = ath9k_config,
2760 .config_interface = ath9k_config_interface,
2761 .configure_filter = ath9k_configure_filter, 2745 .configure_filter = ath9k_configure_filter,
2762 .sta_notify = ath9k_sta_notify, 2746 .sta_notify = ath9k_sta_notify,
2763 .conf_tx = ath9k_conf_tx, 2747 .conf_tx = ath9k_conf_tx,
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 3c693e6ec904..2615aaf7df6a 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3543,12 +3543,38 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
3543{ 3543{
3544 struct b43_wl *wl = hw_to_b43_wl(hw); 3544 struct b43_wl *wl = hw_to_b43_wl(hw);
3545 struct b43_wldev *dev; 3545 struct b43_wldev *dev;
3546 unsigned long flags;
3546 3547
3547 mutex_lock(&wl->mutex); 3548 mutex_lock(&wl->mutex);
3548 3549
3549 dev = wl->current_dev; 3550 dev = wl->current_dev;
3550 if (!dev || b43_status(dev) < B43_STAT_STARTED) 3551 if (!dev || b43_status(dev) < B43_STAT_STARTED)
3551 goto out_unlock_mutex; 3552 goto out_unlock_mutex;
3553
3554 B43_WARN_ON(wl->vif != vif);
3555
3556 if (changed & BSS_CHANGED_BSSID) {
3557 spin_lock_irqsave(&wl->irq_lock, flags);
3558 if (conf->bssid)
3559 memcpy(wl->bssid, conf->bssid, ETH_ALEN);
3560 else
3561 memset(wl->bssid, 0, ETH_ALEN);
3562
3563 if (b43_status(dev) >= B43_STAT_INITIALIZED) {
3564 if (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
3565 b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT)) {
3566 B43_WARN_ON(vif->type != wl->if_type);
3567 if (changed & BSS_CHANGED_BEACON)
3568 b43_update_templates(wl);
3569 } else if (b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) {
3570 if (changed & BSS_CHANGED_BEACON)
3571 b43_update_templates(wl);
3572 }
3573 b43_write_mac_bssid_templates(dev);
3574 }
3575 spin_unlock_irqrestore(&wl->irq_lock, flags);
3576 }
3577
3552 b43_mac_suspend(dev); 3578 b43_mac_suspend(dev);
3553 3579
3554 /* Update templates for AP/mesh mode. */ 3580 /* Update templates for AP/mesh mode. */
@@ -3571,8 +3597,6 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
3571 b43_mac_enable(dev); 3597 b43_mac_enable(dev);
3572out_unlock_mutex: 3598out_unlock_mutex:
3573 mutex_unlock(&wl->mutex); 3599 mutex_unlock(&wl->mutex);
3574
3575 return;
3576} 3600}
3577 3601
3578static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 3602static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -3730,41 +3754,6 @@ static void b43_op_configure_filter(struct ieee80211_hw *hw,
3730 spin_unlock_irqrestore(&wl->irq_lock, flags); 3754 spin_unlock_irqrestore(&wl->irq_lock, flags);
3731} 3755}
3732 3756
3733static int b43_op_config_interface(struct ieee80211_hw *hw,
3734 struct ieee80211_vif *vif,
3735 struct ieee80211_if_conf *conf)
3736{
3737 struct b43_wl *wl = hw_to_b43_wl(hw);
3738 struct b43_wldev *dev = wl->current_dev;
3739 unsigned long flags;
3740
3741 if (!dev)
3742 return -ENODEV;
3743 mutex_lock(&wl->mutex);
3744 spin_lock_irqsave(&wl->irq_lock, flags);
3745 B43_WARN_ON(wl->vif != vif);
3746 if (conf->bssid)
3747 memcpy(wl->bssid, conf->bssid, ETH_ALEN);
3748 else
3749 memset(wl->bssid, 0, ETH_ALEN);
3750 if (b43_status(dev) >= B43_STAT_INITIALIZED) {
3751 if (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
3752 b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT)) {
3753 B43_WARN_ON(vif->type != wl->if_type);
3754 if (conf->changed & IEEE80211_IFCC_BEACON)
3755 b43_update_templates(wl);
3756 } else if (b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) {
3757 if (conf->changed & IEEE80211_IFCC_BEACON)
3758 b43_update_templates(wl);
3759 }
3760 b43_write_mac_bssid_templates(dev);
3761 }
3762 spin_unlock_irqrestore(&wl->irq_lock, flags);
3763 mutex_unlock(&wl->mutex);
3764
3765 return 0;
3766}
3767
3768/* Locking: wl->mutex */ 3757/* Locking: wl->mutex */
3769static void b43_wireless_core_stop(struct b43_wldev *dev) 3758static void b43_wireless_core_stop(struct b43_wldev *dev)
3770{ 3759{
@@ -4434,7 +4423,6 @@ static const struct ieee80211_ops b43_hw_ops = {
4434 .remove_interface = b43_op_remove_interface, 4423 .remove_interface = b43_op_remove_interface,
4435 .config = b43_op_config, 4424 .config = b43_op_config,
4436 .bss_info_changed = b43_op_bss_info_changed, 4425 .bss_info_changed = b43_op_bss_info_changed,
4437 .config_interface = b43_op_config_interface,
4438 .configure_filter = b43_op_configure_filter, 4426 .configure_filter = b43_op_configure_filter,
4439 .set_key = b43_op_set_key, 4427 .set_key = b43_op_set_key,
4440 .get_stats = b43_op_get_stats, 4428 .get_stats = b43_op_get_stats,
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 276f314688f7..07c7898c87ac 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2804,6 +2804,7 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
2804 u32 savedirqs; 2804 u32 savedirqs;
2805 2805
2806 mutex_lock(&wl->mutex); 2806 mutex_lock(&wl->mutex);
2807 B43legacy_WARN_ON(wl->vif != vif);
2807 2808
2808 dev = wl->current_dev; 2809 dev = wl->current_dev;
2809 phy = &dev->phy; 2810 phy = &dev->phy;
@@ -2817,8 +2818,29 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
2817 goto out_unlock_mutex; 2818 goto out_unlock_mutex;
2818 } 2819 }
2819 savedirqs = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL); 2820 savedirqs = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL);
2820 spin_unlock_irqrestore(&wl->irq_lock, flags); 2821
2821 b43legacy_synchronize_irq(dev); 2822 if (changed & BSS_CHANGED_BSSID) {
2823 spin_unlock_irqrestore(&wl->irq_lock, flags);
2824 b43legacy_synchronize_irq(dev);
2825
2826 if (conf->bssid)
2827 memcpy(wl->bssid, conf->bssid, ETH_ALEN);
2828 else
2829 memset(wl->bssid, 0, ETH_ALEN);
2830
2831 if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) {
2832 if (b43legacy_is_mode(wl, NL80211_IFTYPE_AP)) {
2833 B43legacy_WARN_ON(vif->type != NL80211_IFTYPE_AP);
2834 if (changed & BSS_CHANGED_BEACON)
2835 b43legacy_update_templates(wl);
2836 } else if (b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC)) {
2837 if (changed & BSS_CHANGED_BEACON)
2838 b43legacy_update_templates(wl);
2839 }
2840 b43legacy_write_mac_bssid_templates(dev);
2841 }
2842 spin_unlock_irqrestore(&wl->irq_lock, flags);
2843 }
2822 2844
2823 b43legacy_mac_suspend(dev); 2845 b43legacy_mac_suspend(dev);
2824 2846
@@ -2846,8 +2868,6 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
2846 spin_unlock_irqrestore(&wl->irq_lock, flags); 2868 spin_unlock_irqrestore(&wl->irq_lock, flags);
2847 out_unlock_mutex: 2869 out_unlock_mutex:
2848 mutex_unlock(&wl->mutex); 2870 mutex_unlock(&wl->mutex);
2849
2850 return;
2851} 2871}
2852 2872
2853static void b43legacy_op_configure_filter(struct ieee80211_hw *hw, 2873static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
@@ -2889,40 +2909,6 @@ static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
2889 spin_unlock_irqrestore(&wl->irq_lock, flags); 2909 spin_unlock_irqrestore(&wl->irq_lock, flags);
2890} 2910}
2891 2911
2892static int b43legacy_op_config_interface(struct ieee80211_hw *hw,
2893 struct ieee80211_vif *vif,
2894 struct ieee80211_if_conf *conf)
2895{
2896 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
2897 struct b43legacy_wldev *dev = wl->current_dev;
2898 unsigned long flags;
2899
2900 if (!dev)
2901 return -ENODEV;
2902 mutex_lock(&wl->mutex);
2903 spin_lock_irqsave(&wl->irq_lock, flags);
2904 B43legacy_WARN_ON(wl->vif != vif);
2905 if (conf->bssid)
2906 memcpy(wl->bssid, conf->bssid, ETH_ALEN);
2907 else
2908 memset(wl->bssid, 0, ETH_ALEN);
2909 if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) {
2910 if (b43legacy_is_mode(wl, NL80211_IFTYPE_AP)) {
2911 B43legacy_WARN_ON(vif->type != NL80211_IFTYPE_AP);
2912 if (conf->changed & IEEE80211_IFCC_BEACON)
2913 b43legacy_update_templates(wl);
2914 } else if (b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC)) {
2915 if (conf->changed & IEEE80211_IFCC_BEACON)
2916 b43legacy_update_templates(wl);
2917 }
2918 b43legacy_write_mac_bssid_templates(dev);
2919 }
2920 spin_unlock_irqrestore(&wl->irq_lock, flags);
2921 mutex_unlock(&wl->mutex);
2922
2923 return 0;
2924}
2925
2926/* Locking: wl->mutex */ 2912/* Locking: wl->mutex */
2927static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev) 2913static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
2928{ 2914{
@@ -3563,7 +3549,6 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
3563 .remove_interface = b43legacy_op_remove_interface, 3549 .remove_interface = b43legacy_op_remove_interface,
3564 .config = b43legacy_op_dev_config, 3550 .config = b43legacy_op_dev_config,
3565 .bss_info_changed = b43legacy_op_bss_info_changed, 3551 .bss_info_changed = b43legacy_op_bss_info_changed,
3566 .config_interface = b43legacy_op_config_interface,
3567 .configure_filter = b43legacy_op_configure_filter, 3552 .configure_filter = b43legacy_op_configure_filter,
3568 .get_stats = b43legacy_op_get_stats, 3553 .get_stats = b43legacy_op_get_stats,
3569 .get_tx_stats = b43legacy_op_get_tx_stats, 3554 .get_tx_stats = b43legacy_op_get_tx_stats,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 4920dcf7d7b0..dd8b15ed8296 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2623,7 +2623,6 @@ static struct ieee80211_ops iwl_hw_ops = {
2623 .add_interface = iwl_mac_add_interface, 2623 .add_interface = iwl_mac_add_interface,
2624 .remove_interface = iwl_mac_remove_interface, 2624 .remove_interface = iwl_mac_remove_interface,
2625 .config = iwl_mac_config, 2625 .config = iwl_mac_config,
2626 .config_interface = iwl_mac_config_interface,
2627 .configure_filter = iwl_configure_filter, 2626 .configure_filter = iwl_configure_filter,
2628 .set_key = iwl_mac_set_key, 2627 .set_key = iwl_mac_set_key,
2629 .update_tkip_key = iwl_mac_update_tkip_key, 2628 .update_tkip_key = iwl_mac_update_tkip_key,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index cd8a5ed97c4f..0f21fc136ca7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2238,15 +2238,69 @@ static void iwl_ht_conf(struct iwl_priv *priv,
2238 2238
2239#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) 2239#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
2240void iwl_bss_info_changed(struct ieee80211_hw *hw, 2240void iwl_bss_info_changed(struct ieee80211_hw *hw,
2241 struct ieee80211_vif *vif, 2241 struct ieee80211_vif *vif,
2242 struct ieee80211_bss_conf *bss_conf, 2242 struct ieee80211_bss_conf *bss_conf,
2243 u32 changes) 2243 u32 changes)
2244{ 2244{
2245 struct iwl_priv *priv = hw->priv; 2245 struct iwl_priv *priv = hw->priv;
2246 int ret; 2246 int ret;
2247 2247
2248 IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); 2248 IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
2249 2249
2250 if (!iwl_is_alive(priv))
2251 return;
2252
2253 mutex_lock(&priv->mutex);
2254
2255 if (changes & BSS_CHANGED_BEACON &&
2256 priv->iw_mode == NL80211_IFTYPE_AP) {
2257 dev_kfree_skb(priv->ibss_beacon);
2258 priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
2259 }
2260
2261 if ((changes & BSS_CHANGED_BSSID) && !iwl_is_rfkill(priv)) {
2262 /* If there is currently a HW scan going on in the background
2263 * then we need to cancel it else the RXON below will fail. */
2264 if (iwl_scan_cancel_timeout(priv, 100)) {
2265 IWL_WARN(priv, "Aborted scan still in progress "
2266 "after 100ms\n");
2267 IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
2268 mutex_unlock(&priv->mutex);
2269 return;
2270 }
2271 memcpy(priv->staging_rxon.bssid_addr,
2272 bss_conf->bssid, ETH_ALEN);
2273
2274 /* TODO: Audit driver for usage of these members and see
2275 * if mac80211 deprecates them (priv->bssid looks like it
2276 * shouldn't be there, but I haven't scanned the IBSS code
2277 * to verify) - jpk */
2278 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
2279
2280 if (priv->iw_mode == NL80211_IFTYPE_AP)
2281 iwlcore_config_ap(priv);
2282 else {
2283 int rc = iwlcore_commit_rxon(priv);
2284 if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
2285 iwl_rxon_add_station(
2286 priv, priv->active_rxon.bssid_addr, 1);
2287 }
2288 } else if (!iwl_is_rfkill(priv)) {
2289 iwl_scan_cancel_timeout(priv, 100);
2290 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2291 iwlcore_commit_rxon(priv);
2292 }
2293
2294 if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
2295 changes & BSS_CHANGED_BEACON) {
2296 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
2297
2298 if (beacon)
2299 iwl_mac_beacon_update(hw, beacon);
2300 }
2301
2302 mutex_unlock(&priv->mutex);
2303
2250 if (changes & BSS_CHANGED_ERP_PREAMBLE) { 2304 if (changes & BSS_CHANGED_ERP_PREAMBLE) {
2251 IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", 2305 IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
2252 bss_conf->use_short_preamble); 2306 bss_conf->use_short_preamble);
@@ -2305,7 +2359,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2305 &priv->staging_rxon, 2359 &priv->staging_rxon,
2306 sizeof(struct iwl_rxon_cmd)); 2360 sizeof(struct iwl_rxon_cmd));
2307 } 2361 }
2308 2362 IWL_DEBUG_MAC80211(priv, "leave\n");
2309} 2363}
2310EXPORT_SYMBOL(iwl_bss_info_changed); 2364EXPORT_SYMBOL(iwl_bss_info_changed);
2311 2365
@@ -2589,106 +2643,6 @@ out:
2589} 2643}
2590EXPORT_SYMBOL(iwl_mac_config); 2644EXPORT_SYMBOL(iwl_mac_config);
2591 2645
2592int iwl_mac_config_interface(struct ieee80211_hw *hw,
2593 struct ieee80211_vif *vif,
2594 struct ieee80211_if_conf *conf)
2595{
2596 struct iwl_priv *priv = hw->priv;
2597 int rc;
2598
2599 if (conf == NULL)
2600 return -EIO;
2601
2602 if (priv->vif != vif) {
2603 IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
2604 return 0;
2605 }
2606
2607 if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
2608 conf->changed & IEEE80211_IFCC_BEACON) {
2609 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
2610 if (!beacon)
2611 return -ENOMEM;
2612 mutex_lock(&priv->mutex);
2613 rc = iwl_mac_beacon_update(hw, beacon);
2614 mutex_unlock(&priv->mutex);
2615 if (rc)
2616 return rc;
2617 }
2618
2619 if (!iwl_is_alive(priv))
2620 return -EAGAIN;
2621
2622 mutex_lock(&priv->mutex);
2623
2624 if (conf->bssid)
2625 IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
2626
2627/*
2628 * very dubious code was here; the probe filtering flag is never set:
2629 *
2630 if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) &&
2631 !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
2632 */
2633
2634 if (priv->iw_mode == NL80211_IFTYPE_AP) {
2635 if (!conf->bssid) {
2636 conf->bssid = priv->mac_addr;
2637 memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
2638 IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
2639 conf->bssid);
2640 }
2641 if (priv->ibss_beacon)
2642 dev_kfree_skb(priv->ibss_beacon);
2643
2644 priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
2645 }
2646
2647 if (iwl_is_rfkill(priv))
2648 goto done;
2649
2650 if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
2651 !is_multicast_ether_addr(conf->bssid)) {
2652 /* If there is currently a HW scan going on in the background
2653 * then we need to cancel it else the RXON below will fail. */
2654 if (iwl_scan_cancel_timeout(priv, 100)) {
2655 IWL_WARN(priv, "Aborted scan still in progress "
2656 "after 100ms\n");
2657 IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
2658 mutex_unlock(&priv->mutex);
2659 return -EAGAIN;
2660 }
2661 memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN);
2662
2663 /* TODO: Audit driver for usage of these members and see
2664 * if mac80211 deprecates them (priv->bssid looks like it
2665 * shouldn't be there, but I haven't scanned the IBSS code
2666 * to verify) - jpk */
2667 memcpy(priv->bssid, conf->bssid, ETH_ALEN);
2668
2669 if (priv->iw_mode == NL80211_IFTYPE_AP)
2670 iwlcore_config_ap(priv);
2671 else {
2672 rc = iwlcore_commit_rxon(priv);
2673 if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
2674 iwl_rxon_add_station(
2675 priv, priv->active_rxon.bssid_addr, 1);
2676 }
2677
2678 } else {
2679 iwl_scan_cancel_timeout(priv, 100);
2680 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2681 iwlcore_commit_rxon(priv);
2682 }
2683
2684 done:
2685 IWL_DEBUG_MAC80211(priv, "leave\n");
2686 mutex_unlock(&priv->mutex);
2687
2688 return 0;
2689}
2690EXPORT_SYMBOL(iwl_mac_config_interface);
2691
2692int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, 2646int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
2693 struct ieee80211_tx_queue_stats *stats) 2647 struct ieee80211_tx_queue_stats *stats)
2694{ 2648{
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index d4c60afa2891..bd7f9d9616bc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -281,9 +281,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
281 struct ieee80211_if_init_conf *conf); 281 struct ieee80211_if_init_conf *conf);
282int iwl_mac_config(struct ieee80211_hw *hw, u32 changed); 282int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
283void iwl_config_ap(struct iwl_priv *priv); 283void iwl_config_ap(struct iwl_priv *priv);
284int iwl_mac_config_interface(struct ieee80211_hw *hw,
285 struct ieee80211_vif *vif,
286 struct ieee80211_if_conf *conf);
287int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, 284int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
288 struct ieee80211_tx_queue_stats *stats); 285 struct ieee80211_tx_queue_stats *stats);
289void iwl_mac_reset_tsf(struct ieee80211_hw *hw); 286void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index f9d9b65ef300..5cd4321d7cf5 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -4106,7 +4106,6 @@ static struct ieee80211_ops iwl3945_hw_ops = {
4106 .add_interface = iwl_mac_add_interface, 4106 .add_interface = iwl_mac_add_interface,
4107 .remove_interface = iwl_mac_remove_interface, 4107 .remove_interface = iwl_mac_remove_interface,
4108 .config = iwl_mac_config, 4108 .config = iwl_mac_config,
4109 .config_interface = iwl_mac_config_interface,
4110 .configure_filter = iwl_configure_filter, 4109 .configure_filter = iwl_configure_filter,
4111 .set_key = iwl3945_mac_set_key, 4110 .set_key = iwl3945_mac_set_key,
4112 .get_tx_stats = iwl_mac_get_tx_stats, 4111 .get_tx_stats = iwl_mac_get_tx_stats,
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index 68e47fb47a1e..10a99e26d392 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -366,36 +366,6 @@ static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed)
366 return 0; 366 return 0;
367} 367}
368 368
369static int lbtf_op_config_interface(struct ieee80211_hw *hw,
370 struct ieee80211_vif *vif,
371 struct ieee80211_if_conf *conf)
372{
373 struct lbtf_private *priv = hw->priv;
374 struct sk_buff *beacon;
375
376 switch (priv->vif->type) {
377 case NL80211_IFTYPE_AP:
378 case NL80211_IFTYPE_MESH_POINT:
379 beacon = ieee80211_beacon_get(hw, vif);
380 if (beacon) {
381 lbtf_beacon_set(priv, beacon);
382 kfree_skb(beacon);
383 lbtf_beacon_ctrl(priv, 1, vif->bss_conf.beacon_int);
384 }
385 break;
386 default:
387 break;
388 }
389
390 if (conf->bssid) {
391 u8 null_bssid[ETH_ALEN] = {0};
392 bool activate = compare_ether_addr(conf->bssid, null_bssid);
393 lbtf_set_bssid(priv, activate, conf->bssid);
394 }
395
396 return 0;
397}
398
399#define SUPPORTED_FIF_FLAGS (FIF_PROMISC_IN_BSS | FIF_ALLMULTI) 369#define SUPPORTED_FIF_FLAGS (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)
400static void lbtf_op_configure_filter(struct ieee80211_hw *hw, 370static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
401 unsigned int changed_flags, 371 unsigned int changed_flags,
@@ -451,6 +421,29 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
451 u32 changes) 421 u32 changes)
452{ 422{
453 struct lbtf_private *priv = hw->priv; 423 struct lbtf_private *priv = hw->priv;
424 struct sk_buff *beacon;
425
426 if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_INT)) {
427 switch (priv->vif->type) {
428 case NL80211_IFTYPE_AP:
429 case NL80211_IFTYPE_MESH_POINT:
430 beacon = ieee80211_beacon_get(hw, vif);
431 if (beacon) {
432 lbtf_beacon_set(priv, beacon);
433 kfree_skb(beacon);
434 lbtf_beacon_ctrl(priv, 1,
435 bss_conf->beacon_int);
436 }
437 break;
438 default:
439 break;
440 }
441 }
442
443 if (changes & BSS_CHANGED_BSSID) {
444 bool activate = !is_zero_ether_addr(bss_conf->bssid);
445 lbtf_set_bssid(priv, activate, bss_conf->bssid);
446 }
454 447
455 if (changes & BSS_CHANGED_ERP_PREAMBLE) { 448 if (changes & BSS_CHANGED_ERP_PREAMBLE) {
456 if (bss_conf->use_short_preamble) 449 if (bss_conf->use_short_preamble)
@@ -459,8 +452,6 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
459 priv->preamble = CMD_TYPE_LONG_PREAMBLE; 452 priv->preamble = CMD_TYPE_LONG_PREAMBLE;
460 lbtf_set_radio_control(priv); 453 lbtf_set_radio_control(priv);
461 } 454 }
462
463 return;
464} 455}
465 456
466static const struct ieee80211_ops lbtf_ops = { 457static const struct ieee80211_ops lbtf_ops = {
@@ -470,7 +461,6 @@ static const struct ieee80211_ops lbtf_ops = {
470 .add_interface = lbtf_op_add_interface, 461 .add_interface = lbtf_op_add_interface,
471 .remove_interface = lbtf_op_remove_interface, 462 .remove_interface = lbtf_op_remove_interface,
472 .config = lbtf_op_config, 463 .config = lbtf_op_config,
473 .config_interface = lbtf_op_config_interface,
474 .configure_filter = lbtf_op_configure_filter, 464 .configure_filter = lbtf_op_configure_filter,
475 .bss_info_changed = lbtf_op_bss_info_changed, 465 .bss_info_changed = lbtf_op_bss_info_changed,
476}; 466};
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 24c95a619e4c..e67b424f925e 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -587,23 +587,6 @@ static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw,
587 *total_flags = data->rx_filter; 587 *total_flags = data->rx_filter;
588} 588}
589 589
590static int mac80211_hwsim_config_interface(struct ieee80211_hw *hw,
591 struct ieee80211_vif *vif,
592 struct ieee80211_if_conf *conf)
593{
594 struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
595
596 hwsim_check_magic(vif);
597 if (conf->changed & IEEE80211_IFCC_BSSID) {
598 DECLARE_MAC_BUF(mac);
599 printk(KERN_DEBUG "%s:%s: BSSID changed: %pM\n",
600 wiphy_name(hw->wiphy), __func__,
601 conf->bssid);
602 memcpy(vp->bssid, conf->bssid, ETH_ALEN);
603 }
604 return 0;
605}
606
607static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, 590static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
608 struct ieee80211_vif *vif, 591 struct ieee80211_vif *vif,
609 struct ieee80211_bss_conf *info, 592 struct ieee80211_bss_conf *info,
@@ -617,6 +600,13 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
617 printk(KERN_DEBUG "%s:%s(changed=0x%x)\n", 600 printk(KERN_DEBUG "%s:%s(changed=0x%x)\n",
618 wiphy_name(hw->wiphy), __func__, changed); 601 wiphy_name(hw->wiphy), __func__, changed);
619 602
603 if (changed & BSS_CHANGED_BSSID) {
604 printk(KERN_DEBUG "%s:%s: BSSID changed: %pM\n",
605 wiphy_name(hw->wiphy), __func__,
606 info->bssid);
607 memcpy(vp->bssid, info->bssid, ETH_ALEN);
608 }
609
620 if (changed & BSS_CHANGED_ASSOC) { 610 if (changed & BSS_CHANGED_ASSOC) {
621 printk(KERN_DEBUG " %s: ASSOC: assoc=%d aid=%d\n", 611 printk(KERN_DEBUG " %s: ASSOC: assoc=%d aid=%d\n",
622 wiphy_name(hw->wiphy), info->assoc, info->aid); 612 wiphy_name(hw->wiphy), info->assoc, info->aid);
@@ -708,7 +698,6 @@ static const struct ieee80211_ops mac80211_hwsim_ops =
708 .remove_interface = mac80211_hwsim_remove_interface, 698 .remove_interface = mac80211_hwsim_remove_interface,
709 .config = mac80211_hwsim_config, 699 .config = mac80211_hwsim_config,
710 .configure_filter = mac80211_hwsim_configure_filter, 700 .configure_filter = mac80211_hwsim_configure_filter,
711 .config_interface = mac80211_hwsim_config_interface,
712 .bss_info_changed = mac80211_hwsim_bss_info_changed, 701 .bss_info_changed = mac80211_hwsim_bss_info_changed,
713 .sta_notify = mac80211_hwsim_sta_notify, 702 .sta_notify = mac80211_hwsim_sta_notify,
714 .set_tim = mac80211_hwsim_set_tim, 703 .set_tim = mac80211_hwsim_set_tim,
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index a9a970469c2a..46b288dc8f4d 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -3089,19 +3089,6 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
3089 return rc ? -EINVAL : 0; 3089 return rc ? -EINVAL : 0;
3090} 3090}
3091 3091
3092static int mwl8k_config_interface(struct ieee80211_hw *hw,
3093 struct ieee80211_vif *vif,
3094 struct ieee80211_if_conf *conf)
3095{
3096 struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
3097 u32 changed = conf->changed;
3098
3099 if (changed & IEEE80211_IFCC_BSSID)
3100 memcpy(mv_vif->bssid, conf->bssid, IEEE80211_ADDR_LEN);
3101
3102 return 0;
3103}
3104
3105struct mwl8k_bss_info_changed_worker { 3092struct mwl8k_bss_info_changed_worker {
3106 struct mwl8k_work_struct header; 3093 struct mwl8k_work_struct header;
3107 struct ieee80211_vif *vif; 3094 struct ieee80211_vif *vif;
@@ -3183,8 +3170,12 @@ static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
3183{ 3170{
3184 struct mwl8k_bss_info_changed_worker *worker; 3171 struct mwl8k_bss_info_changed_worker *worker;
3185 struct mwl8k_priv *priv = hw->priv; 3172 struct mwl8k_priv *priv = hw->priv;
3173 struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
3186 int rc; 3174 int rc;
3187 3175
3176 if (changed & BSS_CHANGED_BSSID)
3177 memcpy(mv_vif->bssid, info->bssid, IEEE80211_ADDR_LEN);
3178
3188 if ((changed & BSS_CHANGED_ASSOC) == 0) 3179 if ((changed & BSS_CHANGED_ASSOC) == 0)
3189 return; 3180 return;
3190 3181
@@ -3442,7 +3433,6 @@ static const struct ieee80211_ops mwl8k_ops = {
3442 .add_interface = mwl8k_add_interface, 3433 .add_interface = mwl8k_add_interface,
3443 .remove_interface = mwl8k_remove_interface, 3434 .remove_interface = mwl8k_remove_interface,
3444 .config = mwl8k_config, 3435 .config = mwl8k_config,
3445 .config_interface = mwl8k_config_interface,
3446 .bss_info_changed = mwl8k_bss_info_changed, 3436 .bss_info_changed = mwl8k_bss_info_changed,
3447 .configure_filter = mwl8k_configure_filter, 3437 .configure_filter = mwl8k_configure_filter,
3448 .set_rts_threshold = mwl8k_set_rts_threshold, 3438 .set_rts_threshold = mwl8k_set_rts_threshold,
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 71394968d450..b85785291803 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -2204,41 +2204,6 @@ out:
2204 return ret; 2204 return ret;
2205} 2205}
2206 2206
2207static int p54_config_interface(struct ieee80211_hw *dev,
2208 struct ieee80211_vif *vif,
2209 struct ieee80211_if_conf *conf)
2210{
2211 struct p54_common *priv = dev->priv;
2212 int ret = 0;
2213
2214 mutex_lock(&priv->conf_mutex);
2215 if (conf->changed & IEEE80211_IFCC_BSSID) {
2216 memcpy(priv->bssid, conf->bssid, ETH_ALEN);
2217 ret = p54_setup_mac(dev);
2218 if (ret)
2219 goto out;
2220 }
2221
2222 if (conf->changed & IEEE80211_IFCC_BEACON) {
2223 ret = p54_scan(dev, P54_SCAN_EXIT, 0);
2224 if (ret)
2225 goto out;
2226 ret = p54_setup_mac(dev);
2227 if (ret)
2228 goto out;
2229 ret = p54_beacon_update(dev, vif);
2230 if (ret)
2231 goto out;
2232 ret = p54_set_edcf(dev);
2233 if (ret)
2234 goto out;
2235 }
2236
2237out:
2238 mutex_unlock(&priv->conf_mutex);
2239 return ret;
2240}
2241
2242static void p54_configure_filter(struct ieee80211_hw *dev, 2207static void p54_configure_filter(struct ieee80211_hw *dev,
2243 unsigned int changed_flags, 2208 unsigned int changed_flags,
2244 unsigned int *total_flags, 2209 unsigned int *total_flags,
@@ -2342,8 +2307,32 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
2342 u32 changed) 2307 u32 changed)
2343{ 2308{
2344 struct p54_common *priv = dev->priv; 2309 struct p54_common *priv = dev->priv;
2310 int ret;
2311
2312 mutex_lock(&priv->conf_mutex);
2313 if (changed & BSS_CHANGED_BSSID) {
2314 memcpy(priv->bssid, info->bssid, ETH_ALEN);
2315 ret = p54_setup_mac(dev);
2316 if (ret)
2317 goto out;
2318 }
2319
2320 if (changed & BSS_CHANGED_BEACON) {
2321 ret = p54_scan(dev, P54_SCAN_EXIT, 0);
2322 if (ret)
2323 goto out;
2324 ret = p54_setup_mac(dev);
2325 if (ret)
2326 goto out;
2327 ret = p54_beacon_update(dev, vif);
2328 if (ret)
2329 goto out;
2330 }
2331 /* XXX: this mimics having two callbacks... clean up */
2332 out:
2333 mutex_unlock(&priv->conf_mutex);
2345 2334
2346 if (changed & BSS_CHANGED_ERP_SLOT) { 2335 if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BEACON)) {
2347 priv->use_short_slot = info->use_short_slot; 2336 priv->use_short_slot = info->use_short_slot;
2348 p54_set_edcf(dev); 2337 p54_set_edcf(dev);
2349 } 2338 }
@@ -2364,7 +2353,6 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
2364 p54_setup_mac(dev); 2353 p54_setup_mac(dev);
2365 } 2354 }
2366 } 2355 }
2367
2368} 2356}
2369 2357
2370static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, 2358static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
@@ -2619,7 +2607,6 @@ static const struct ieee80211_ops p54_ops = {
2619 .sta_notify = p54_sta_notify, 2607 .sta_notify = p54_sta_notify,
2620 .set_key = p54_set_key, 2608 .set_key = p54_set_key,
2621 .config = p54_config, 2609 .config = p54_config,
2622 .config_interface = p54_config_interface,
2623 .bss_info_changed = p54_bss_info_changed, 2610 .bss_info_changed = p54_bss_info_changed,
2624 .configure_filter = p54_configure_filter, 2611 .configure_filter = p54_configure_filter,
2625 .conf_tx = p54_conf_tx, 2612 .conf_tx = p54_conf_tx,
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 411eb9cbb4e5..6f39ba662188 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1580,7 +1580,6 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
1580 .add_interface = rt2x00mac_add_interface, 1580 .add_interface = rt2x00mac_add_interface,
1581 .remove_interface = rt2x00mac_remove_interface, 1581 .remove_interface = rt2x00mac_remove_interface,
1582 .config = rt2x00mac_config, 1582 .config = rt2x00mac_config,
1583 .config_interface = rt2x00mac_config_interface,
1584 .configure_filter = rt2x00mac_configure_filter, 1583 .configure_filter = rt2x00mac_configure_filter,
1585 .get_stats = rt2x00mac_get_stats, 1584 .get_stats = rt2x00mac_get_stats,
1586 .bss_info_changed = rt2x00mac_bss_info_changed, 1585 .bss_info_changed = rt2x00mac_bss_info_changed,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index e1be67ca23d8..906960f67b6c 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1879,7 +1879,6 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
1879 .add_interface = rt2x00mac_add_interface, 1879 .add_interface = rt2x00mac_add_interface,
1880 .remove_interface = rt2x00mac_remove_interface, 1880 .remove_interface = rt2x00mac_remove_interface,
1881 .config = rt2x00mac_config, 1881 .config = rt2x00mac_config,
1882 .config_interface = rt2x00mac_config_interface,
1883 .configure_filter = rt2x00mac_configure_filter, 1882 .configure_filter = rt2x00mac_configure_filter,
1884 .get_stats = rt2x00mac_get_stats, 1883 .get_stats = rt2x00mac_get_stats,
1885 .bss_info_changed = rt2x00mac_bss_info_changed, 1884 .bss_info_changed = rt2x00mac_bss_info_changed,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 9e630e70fc97..08e88333b0ff 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1908,7 +1908,6 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
1908 .add_interface = rt2x00mac_add_interface, 1908 .add_interface = rt2x00mac_add_interface,
1909 .remove_interface = rt2x00mac_remove_interface, 1909 .remove_interface = rt2x00mac_remove_interface,
1910 .config = rt2x00mac_config, 1910 .config = rt2x00mac_config,
1911 .config_interface = rt2x00mac_config_interface,
1912 .configure_filter = rt2x00mac_configure_filter, 1911 .configure_filter = rt2x00mac_configure_filter,
1913 .set_key = rt2x00mac_set_key, 1912 .set_key = rt2x00mac_set_key,
1914 .get_stats = rt2x00mac_get_stats, 1913 .get_stats = rt2x00mac_get_stats,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index e03d69975ea4..0be395528261 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -943,9 +943,6 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
943void rt2x00mac_remove_interface(struct ieee80211_hw *hw, 943void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
944 struct ieee80211_if_init_conf *conf); 944 struct ieee80211_if_init_conf *conf);
945int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed); 945int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed);
946int rt2x00mac_config_interface(struct ieee80211_hw *hw,
947 struct ieee80211_vif *vif,
948 struct ieee80211_if_conf *conf);
949void rt2x00mac_configure_filter(struct ieee80211_hw *hw, 946void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
950 unsigned int changed_flags, 947 unsigned int changed_flags,
951 unsigned int *total_flags, 948 unsigned int *total_flags,
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index c41a0b9e473d..c4c06b4e1f08 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -390,56 +390,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
390} 390}
391EXPORT_SYMBOL_GPL(rt2x00mac_config); 391EXPORT_SYMBOL_GPL(rt2x00mac_config);
392 392
393int rt2x00mac_config_interface(struct ieee80211_hw *hw,
394 struct ieee80211_vif *vif,
395 struct ieee80211_if_conf *conf)
396{
397 struct rt2x00_dev *rt2x00dev = hw->priv;
398 struct rt2x00_intf *intf = vif_to_intf(vif);
399 int update_bssid = 0;
400 int status = 0;
401
402 /*
403 * Mac80211 might be calling this function while we are trying
404 * to remove the device or perhaps suspending it.
405 */
406 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
407 return 0;
408
409 spin_lock(&intf->lock);
410
411 /*
412 * conf->bssid can be NULL if coming from the internal
413 * beacon update routine.
414 */
415 if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
416 update_bssid = 1;
417 memcpy(&intf->bssid, conf->bssid, ETH_ALEN);
418 }
419
420 spin_unlock(&intf->lock);
421
422 /*
423 * Call rt2x00_config_intf() outside of the spinlock context since
424 * the call will sleep for USB drivers. By using the ieee80211_if_conf
425 * values as arguments we make keep access to rt2x00_intf thread safe
426 * even without the lock.
427 */
428 rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
429 update_bssid ? conf->bssid : NULL);
430
431 /*
432 * Update the beacon.
433 */
434 if (conf->changed & (IEEE80211_IFCC_BEACON |
435 IEEE80211_IFCC_BEACON_ENABLED))
436 status = rt2x00queue_update_beacon(rt2x00dev, vif,
437 conf->enable_beacon);
438
439 return status;
440}
441EXPORT_SYMBOL_GPL(rt2x00mac_config_interface);
442
443void rt2x00mac_configure_filter(struct ieee80211_hw *hw, 393void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
444 unsigned int changed_flags, 394 unsigned int changed_flags,
445 unsigned int *total_flags, 395 unsigned int *total_flags,
@@ -623,6 +573,44 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
623 struct rt2x00_dev *rt2x00dev = hw->priv; 573 struct rt2x00_dev *rt2x00dev = hw->priv;
624 struct rt2x00_intf *intf = vif_to_intf(vif); 574 struct rt2x00_intf *intf = vif_to_intf(vif);
625 unsigned int delayed = 0; 575 unsigned int delayed = 0;
576 int update_bssid = 0;
577
578 /*
579 * Mac80211 might be calling this function while we are trying
580 * to remove the device or perhaps suspending it.
581 */
582 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
583 return;
584
585 spin_lock(&intf->lock);
586
587 /*
588 * conf->bssid can be NULL if coming from the internal
589 * beacon update routine.
590 */
591 if (changes & BSS_CHANGED_BSSID) {
592 update_bssid = 1;
593 memcpy(&intf->bssid, bss_conf->bssid, ETH_ALEN);
594 }
595
596 spin_unlock(&intf->lock);
597
598 /*
599 * Call rt2x00_config_intf() outside of the spinlock context since
600 * the call will sleep for USB drivers. By using the ieee80211_if_conf
601 * values as arguments we make keep access to rt2x00_intf thread safe
602 * even without the lock.
603 */
604 if (changes & BSS_CHANGED_BSSID)
605 rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
606 update_bssid ? bss_conf->bssid : NULL);
607
608 /*
609 * Update the beacon.
610 */
611 if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED))
612 rt2x00queue_update_beacon(rt2x00dev, vif,
613 bss_conf->enable_beacon);
626 614
627 /* 615 /*
628 * When the association status has changed we must reset the link 616 * When the association status has changed we must reset the link
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 4346cd1494bc..cb521ee7a8f0 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2735,7 +2735,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
2735 .add_interface = rt2x00mac_add_interface, 2735 .add_interface = rt2x00mac_add_interface,
2736 .remove_interface = rt2x00mac_remove_interface, 2736 .remove_interface = rt2x00mac_remove_interface,
2737 .config = rt2x00mac_config, 2737 .config = rt2x00mac_config,
2738 .config_interface = rt2x00mac_config_interface,
2739 .configure_filter = rt2x00mac_configure_filter, 2738 .configure_filter = rt2x00mac_configure_filter,
2740 .set_key = rt2x00mac_set_key, 2739 .set_key = rt2x00mac_set_key,
2741 .get_stats = rt2x00mac_get_stats, 2740 .get_stats = rt2x00mac_get_stats,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 853b2b279b64..6bd28a6bcef2 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2259,7 +2259,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
2259 .add_interface = rt2x00mac_add_interface, 2259 .add_interface = rt2x00mac_add_interface,
2260 .remove_interface = rt2x00mac_remove_interface, 2260 .remove_interface = rt2x00mac_remove_interface,
2261 .config = rt2x00mac_config, 2261 .config = rt2x00mac_config,
2262 .config_interface = rt2x00mac_config_interface,
2263 .configure_filter = rt2x00mac_configure_filter, 2262 .configure_filter = rt2x00mac_configure_filter,
2264 .set_key = rt2x00mac_set_key, 2263 .set_key = rt2x00mac_set_key,
2265 .get_stats = rt2x00mac_get_stats, 2264 .get_stats = rt2x00mac_get_stats,
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 387c133ec0f2..7e65d7c31802 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -702,30 +702,26 @@ static int rtl8180_config(struct ieee80211_hw *dev, u32 changed)
702 return 0; 702 return 0;
703} 703}
704 704
705static int rtl8180_config_interface(struct ieee80211_hw *dev,
706 struct ieee80211_vif *vif,
707 struct ieee80211_if_conf *conf)
708{
709 struct rtl8180_priv *priv = dev->priv;
710 int i;
711
712 for (i = 0; i < ETH_ALEN; i++)
713 rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
714
715 if (is_valid_ether_addr(conf->bssid))
716 rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA);
717 else
718 rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK);
719
720 return 0;
721}
722
723static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, 705static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
724 struct ieee80211_vif *vif, 706 struct ieee80211_vif *vif,
725 struct ieee80211_bss_conf *info, 707 struct ieee80211_bss_conf *info,
726 u32 changed) 708 u32 changed)
727{ 709{
728 struct rtl8180_priv *priv = dev->priv; 710 struct rtl8180_priv *priv = dev->priv;
711 int i;
712
713 if (changed & BSS_CHANGED_BSSID) {
714 for (i = 0; i < ETH_ALEN; i++)
715 rtl818x_iowrite8(priv, &priv->map->BSSID[i],
716 info->bssid[i]);
717
718 if (is_valid_ether_addr(info->bssid))
719 rtl818x_iowrite8(priv, &priv->map->MSR,
720 RTL818X_MSR_INFRA);
721 else
722 rtl818x_iowrite8(priv, &priv->map->MSR,
723 RTL818X_MSR_NO_LINK);
724 }
729 725
730 if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp) 726 if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp)
731 priv->rf->conf_erp(dev, info); 727 priv->rf->conf_erp(dev, info);
@@ -770,7 +766,6 @@ static const struct ieee80211_ops rtl8180_ops = {
770 .add_interface = rtl8180_add_interface, 766 .add_interface = rtl8180_add_interface,
771 .remove_interface = rtl8180_remove_interface, 767 .remove_interface = rtl8180_remove_interface,
772 .config = rtl8180_config, 768 .config = rtl8180_config,
773 .config_interface = rtl8180_config_interface,
774 .bss_info_changed = rtl8180_bss_info_changed, 769 .bss_info_changed = rtl8180_bss_info_changed,
775 .configure_filter = rtl8180_configure_filter, 770 .configure_filter = rtl8180_configure_filter,
776}; 771};
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index ac558da92aac..158827e50c55 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -1090,32 +1090,6 @@ static int rtl8187_config(struct ieee80211_hw *dev, u32 changed)
1090 return 0; 1090 return 0;
1091} 1091}
1092 1092
1093static int rtl8187_config_interface(struct ieee80211_hw *dev,
1094 struct ieee80211_vif *vif,
1095 struct ieee80211_if_conf *conf)
1096{
1097 struct rtl8187_priv *priv = dev->priv;
1098 int i;
1099 u8 reg;
1100
1101 mutex_lock(&priv->conf_mutex);
1102 for (i = 0; i < ETH_ALEN; i++)
1103 rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
1104
1105 if (is_valid_ether_addr(conf->bssid)) {
1106 reg = RTL818X_MSR_INFRA;
1107 if (priv->is_rtl8187b)
1108 reg |= RTL818X_MSR_ENEDCA;
1109 rtl818x_iowrite8(priv, &priv->map->MSR, reg);
1110 } else {
1111 reg = RTL818X_MSR_NO_LINK;
1112 rtl818x_iowrite8(priv, &priv->map->MSR, reg);
1113 }
1114
1115 mutex_unlock(&priv->conf_mutex);
1116 return 0;
1117}
1118
1119/* 1093/*
1120 * With 8187B, AC_*_PARAM clashes with FEMR definition in struct rtl818x_csr for 1094 * With 8187B, AC_*_PARAM clashes with FEMR definition in struct rtl818x_csr for
1121 * example. Thus we have to use raw values for AC_*_PARAM register addresses. 1095 * example. Thus we have to use raw values for AC_*_PARAM register addresses.
@@ -1193,6 +1167,27 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
1193 u32 changed) 1167 u32 changed)
1194{ 1168{
1195 struct rtl8187_priv *priv = dev->priv; 1169 struct rtl8187_priv *priv = dev->priv;
1170 int i;
1171 u8 reg;
1172
1173 if (changed & BSS_CHANGED_BSSID) {
1174 mutex_lock(&priv->conf_mutex);
1175 for (i = 0; i < ETH_ALEN; i++)
1176 rtl818x_iowrite8(priv, &priv->map->BSSID[i],
1177 info->bssid[i]);
1178
1179 if (is_valid_ether_addr(info->bssid)) {
1180 reg = RTL818X_MSR_INFRA;
1181 if (priv->is_rtl8187b)
1182 reg |= RTL818X_MSR_ENEDCA;
1183 rtl818x_iowrite8(priv, &priv->map->MSR, reg);
1184 } else {
1185 reg = RTL818X_MSR_NO_LINK;
1186 rtl818x_iowrite8(priv, &priv->map->MSR, reg);
1187 }
1188
1189 mutex_unlock(&priv->conf_mutex);
1190 }
1196 1191
1197 if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) 1192 if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE))
1198 rtl8187_conf_erp(priv, info->use_short_slot, 1193 rtl8187_conf_erp(priv, info->use_short_slot,
@@ -1274,7 +1269,6 @@ static const struct ieee80211_ops rtl8187_ops = {
1274 .add_interface = rtl8187_add_interface, 1269 .add_interface = rtl8187_add_interface,
1275 .remove_interface = rtl8187_remove_interface, 1270 .remove_interface = rtl8187_remove_interface,
1276 .config = rtl8187_config, 1271 .config = rtl8187_config,
1277 .config_interface = rtl8187_config_interface,
1278 .bss_info_changed = rtl8187_bss_info_changed, 1272 .bss_info_changed = rtl8187_bss_info_changed,
1279 .configure_filter = rtl8187_configure_filter, 1273 .configure_filter = rtl8187_configure_filter,
1280 .conf_tx = rtl8187_conf_tx 1274 .conf_tx = rtl8187_conf_tx
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index c3a51266de20..6bdb1704083b 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -755,52 +755,6 @@ static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
755 return zd_chip_set_channel(&mac->chip, conf->channel->hw_value); 755 return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
756} 756}
757 757
758static int zd_op_config_interface(struct ieee80211_hw *hw,
759 struct ieee80211_vif *vif,
760 struct ieee80211_if_conf *conf)
761{
762 struct zd_mac *mac = zd_hw_mac(hw);
763 int associated;
764 int r;
765
766 if (mac->type == NL80211_IFTYPE_MESH_POINT ||
767 mac->type == NL80211_IFTYPE_ADHOC) {
768 associated = true;
769 if (conf->changed & IEEE80211_IFCC_BEACON) {
770 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
771
772 if (!beacon)
773 return -ENOMEM;
774 r = zd_mac_config_beacon(hw, beacon);
775 kfree_skb(beacon);
776
777 if (r < 0)
778 return r;
779 }
780
781 if (conf->changed & IEEE80211_IFCC_BEACON_ENABLED) {
782 u32 interval;
783
784 if (conf->enable_beacon)
785 interval = BCN_MODE_IBSS | hw->conf.beacon_int;
786 else
787 interval = 0;
788
789 r = zd_set_beacon_interval(&mac->chip, interval);
790 if (r < 0)
791 return r;
792 }
793 } else
794 associated = is_valid_ether_addr(conf->bssid);
795
796 spin_lock_irq(&mac->lock);
797 mac->associated = associated;
798 spin_unlock_irq(&mac->lock);
799
800 /* TODO: do hardware bssid filtering */
801 return 0;
802}
803
804static void zd_process_intr(struct work_struct *work) 758static void zd_process_intr(struct work_struct *work)
805{ 759{
806 u16 int_status; 760 u16 int_status;
@@ -923,9 +877,42 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
923{ 877{
924 struct zd_mac *mac = zd_hw_mac(hw); 878 struct zd_mac *mac = zd_hw_mac(hw);
925 unsigned long flags; 879 unsigned long flags;
880 int associated;
926 881
927 dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes); 882 dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);
928 883
884 if (mac->type == NL80211_IFTYPE_MESH_POINT ||
885 mac->type == NL80211_IFTYPE_ADHOC) {
886 associated = true;
887 if (changes & BSS_CHANGED_BEACON) {
888 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
889
890 if (beacon) {
891 zd_mac_config_beacon(hw, beacon);
892 kfree_skb(beacon);
893 }
894 }
895
896 if (changes & BSS_CHANGED_BEACON_ENABLED) {
897 u32 interval;
898
899 if (bss_conf->enable_beacon)
900 interval = BCN_MODE_IBSS |
901 bss_conf->beacon_int;
902 else
903 interval = 0;
904
905 zd_set_beacon_interval(&mac->chip, interval);
906 }
907 } else
908 associated = is_valid_ether_addr(bss_conf->bssid);
909
910 spin_lock_irq(&mac->lock);
911 mac->associated = associated;
912 spin_unlock_irq(&mac->lock);
913
914 /* TODO: do hardware bssid filtering */
915
929 if (changes & BSS_CHANGED_ERP_PREAMBLE) { 916 if (changes & BSS_CHANGED_ERP_PREAMBLE) {
930 spin_lock_irqsave(&mac->lock, flags); 917 spin_lock_irqsave(&mac->lock, flags);
931 mac->short_preamble = bss_conf->use_short_preamble; 918 mac->short_preamble = bss_conf->use_short_preamble;
@@ -952,7 +939,6 @@ static const struct ieee80211_ops zd_ops = {
952 .add_interface = zd_op_add_interface, 939 .add_interface = zd_op_add_interface,
953 .remove_interface = zd_op_remove_interface, 940 .remove_interface = zd_op_remove_interface,
954 .config = zd_op_config, 941 .config = zd_op_config,
955 .config_interface = zd_op_config_interface,
956 .configure_filter = zd_op_configure_filter, 942 .configure_filter = zd_op_configure_filter,
957 .bss_info_changed = zd_op_bss_info_changed, 943 .bss_info_changed = zd_op_bss_info_changed,
958 .get_tsf = zd_op_get_tsf, 944 .get_tsf = zd_op_get_tsf,
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 22c65e8cbb71..7806e22f4ace 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -150,6 +150,12 @@ struct ieee80211_low_level_stats {
150 * @BSS_CHANGED_HT: 802.11n parameters changed 150 * @BSS_CHANGED_HT: 802.11n parameters changed
151 * @BSS_CHANGED_BASIC_RATES: Basic rateset changed 151 * @BSS_CHANGED_BASIC_RATES: Basic rateset changed
152 * @BSS_CHANGED_BEACON_INT: Beacon interval changed 152 * @BSS_CHANGED_BEACON_INT: Beacon interval changed
153 * @BSS_CHANGED_BSSID: BSSID changed, for whatever
154 * reason (IBSS and managed mode)
155 * @BSS_CHANGED_BEACON: Beacon data changed, retrieve
156 * new beacon (beaconing modes)
157 * @BSS_CHANGED_BEACON_ENABLED: Beaconing should be
158 * enabled/disabled (beaconing modes)
153 */ 159 */
154enum ieee80211_bss_change { 160enum ieee80211_bss_change {
155 BSS_CHANGED_ASSOC = 1<<0, 161 BSS_CHANGED_ASSOC = 1<<0,
@@ -159,6 +165,9 @@ enum ieee80211_bss_change {
159 BSS_CHANGED_HT = 1<<4, 165 BSS_CHANGED_HT = 1<<4,
160 BSS_CHANGED_BASIC_RATES = 1<<5, 166 BSS_CHANGED_BASIC_RATES = 1<<5,
161 BSS_CHANGED_BEACON_INT = 1<<6, 167 BSS_CHANGED_BEACON_INT = 1<<6,
168 BSS_CHANGED_BSSID = 1<<7,
169 BSS_CHANGED_BEACON = 1<<8,
170 BSS_CHANGED_BEACON_ENABLED = 1<<9,
162}; 171};
163 172
164/** 173/**
@@ -192,8 +201,11 @@ struct ieee80211_bss_ht_conf {
192 * @basic_rates: bitmap of basic rates, each bit stands for an 201 * @basic_rates: bitmap of basic rates, each bit stands for an
193 * index into the rate table configured by the driver in 202 * index into the rate table configured by the driver in
194 * the current band. 203 * the current band.
204 * @bssid: The BSSID for this BSS
205 * @enable_beacon: whether beaconing should be enabled or not
195 */ 206 */
196struct ieee80211_bss_conf { 207struct ieee80211_bss_conf {
208 const u8 *bssid;
197 /* association related data */ 209 /* association related data */
198 bool assoc; 210 bool assoc;
199 u16 aid; 211 u16 aid;
@@ -201,6 +213,7 @@ struct ieee80211_bss_conf {
201 bool use_cts_prot; 213 bool use_cts_prot;
202 bool use_short_preamble; 214 bool use_short_preamble;
203 bool use_short_slot; 215 bool use_short_slot;
216 bool enable_beacon;
204 u8 dtim_period; 217 u8 dtim_period;
205 u16 beacon_int; 218 u16 beacon_int;
206 u16 assoc_capability; 219 u16 assoc_capability;
@@ -660,37 +673,6 @@ struct ieee80211_if_init_conf {
660}; 673};
661 674
662/** 675/**
663 * enum ieee80211_if_conf_change - interface config change flags
664 *
665 * @IEEE80211_IFCC_BSSID: The BSSID changed.
666 * @IEEE80211_IFCC_BEACON: The beacon for this interface changed
667 * (currently AP and MESH only), use ieee80211_beacon_get().
668 * @IEEE80211_IFCC_BEACON_ENABLED: The enable_beacon value changed.
669 */
670enum ieee80211_if_conf_change {
671 IEEE80211_IFCC_BSSID = BIT(0),
672 IEEE80211_IFCC_BEACON = BIT(1),
673 IEEE80211_IFCC_BEACON_ENABLED = BIT(2),
674};
675
676/**
677 * struct ieee80211_if_conf - configuration of an interface
678 *
679 * @changed: parameters that have changed, see &enum ieee80211_if_conf_change.
680 * @bssid: BSSID of the network we are associated to/creating.
681 * @enable_beacon: Indicates whether beacons can be sent.
682 * This is valid only for AP/IBSS/MESH modes.
683 *
684 * This structure is passed to the config_interface() callback of
685 * &struct ieee80211_hw.
686 */
687struct ieee80211_if_conf {
688 u32 changed;
689 const u8 *bssid;
690 bool enable_beacon;
691};
692
693/**
694 * enum ieee80211_key_alg - key algorithm 676 * enum ieee80211_key_alg - key algorithm
695 * @ALG_WEP: WEP40 or WEP104 677 * @ALG_WEP: WEP40 or WEP104
696 * @ALG_TKIP: TKIP 678 * @ALG_TKIP: TKIP
@@ -1358,10 +1340,6 @@ enum ieee80211_ampdu_mlme_action {
1358 * This function should never fail but returns a negative error code 1340 * This function should never fail but returns a negative error code
1359 * if it does. 1341 * if it does.
1360 * 1342 *
1361 * @config_interface: Handler for configuration requests related to interfaces
1362 * (e.g. BSSID changes.)
1363 * Returns a negative error code which will be seen in userspace.
1364 *
1365 * @bss_info_changed: Handler for configuration requests related to BSS 1343 * @bss_info_changed: Handler for configuration requests related to BSS
1366 * parameters that may vary during BSS's lifespan, and may affect low 1344 * parameters that may vary during BSS's lifespan, and may affect low
1367 * level driver (e.g. assoc/disassoc status, erp parameters). 1345 * level driver (e.g. assoc/disassoc status, erp parameters).
@@ -1463,9 +1441,6 @@ struct ieee80211_ops {
1463 void (*remove_interface)(struct ieee80211_hw *hw, 1441 void (*remove_interface)(struct ieee80211_hw *hw,
1464 struct ieee80211_if_init_conf *conf); 1442 struct ieee80211_if_init_conf *conf);
1465 int (*config)(struct ieee80211_hw *hw, u32 changed); 1443 int (*config)(struct ieee80211_hw *hw, u32 changed);
1466 int (*config_interface)(struct ieee80211_hw *hw,
1467 struct ieee80211_vif *vif,
1468 struct ieee80211_if_conf *conf);
1469 void (*bss_info_changed)(struct ieee80211_hw *hw, 1444 void (*bss_info_changed)(struct ieee80211_hw *hw,
1470 struct ieee80211_vif *vif, 1445 struct ieee80211_vif *vif,
1471 struct ieee80211_bss_conf *info, 1446 struct ieee80211_bss_conf *info,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a898ccd3f2c9..648bac1c850e 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -521,8 +521,9 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
521 521
522 kfree(old); 522 kfree(old);
523 523
524 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON | 524 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
525 IEEE80211_IFCC_BEACON_ENABLED); 525 BSS_CHANGED_BEACON);
526 return 0;
526} 527}
527 528
528static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, 529static 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)
573 synchronize_rcu(); 574 synchronize_rcu();
574 kfree(old); 575 kfree(old);
575 576
576 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED); 577 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
578 return 0;
577} 579}
578 580
579/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ 581/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index f4879dad3cd7..c87caad383f0 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -95,17 +95,10 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
95 95
96 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; 96 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
97 97
98 ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
99
100 local->oper_channel = chan; 98 local->oper_channel = chan;
101 local->oper_channel_type = NL80211_CHAN_NO_HT; 99 local->oper_channel_type = NL80211_CHAN_NO_HT;
102 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 100 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
103 101
104 sdata->vif.bss_conf.beacon_int = beacon_int;
105 bss_change = BSS_CHANGED_BEACON_INT;
106 bss_change |= ieee80211_reset_erp_info(sdata);
107 ieee80211_bss_info_change_notify(sdata, bss_change);
108
109 sband = local->hw.wiphy->bands[chan->band]; 102 sband = local->hw.wiphy->bands[chan->band];
110 103
111 /* Build IBSS probe response */ 104 /* Build IBSS probe response */
@@ -161,8 +154,13 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
161 154
162 rcu_assign_pointer(ifibss->presp, skb); 155 rcu_assign_pointer(ifibss->presp, skb);
163 156
164 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON | 157 sdata->vif.bss_conf.beacon_int = beacon_int;
165 IEEE80211_IFCC_BEACON_ENABLED); 158 bss_change = BSS_CHANGED_BEACON_INT;
159 bss_change |= ieee80211_reset_erp_info(sdata);
160 bss_change |= BSS_CHANGED_BSSID;
161 bss_change |= BSS_CHANGED_BEACON;
162 bss_change |= BSS_CHANGED_BEACON_ENABLED;
163 ieee80211_bss_info_change_notify(sdata, bss_change);
166 164
167 rates = 0; 165 rates = 0;
168 for (i = 0; i < supp_rates_len; i++) { 166 for (i = 0; i < supp_rates_len; i++) {
@@ -887,7 +885,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
887 kfree(sdata->u.ibss.ie); 885 kfree(sdata->u.ibss.ie);
888 skb = sdata->u.ibss.presp; 886 skb = sdata->u.ibss.presp;
889 rcu_assign_pointer(sdata->u.ibss.presp, NULL); 887 rcu_assign_pointer(sdata->u.ibss.presp, NULL);
890 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED); 888 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
891 synchronize_rcu(); 889 synchronize_rcu();
892 kfree_skb(skb); 890 kfree_skb(skb);
893 891
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e6fd4bcf1c3c..d8de1e159ee0 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -906,7 +906,6 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
906 906
907 907
908int ieee80211_hw_config(struct ieee80211_local *local, u32 changed); 908int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
909int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed);
910void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); 909void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
911void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, 910void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
912 u32 changed); 911 u32 changed);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index b254879d8631..c817c9ef215a 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -152,82 +152,6 @@ static void ieee80211_master_set_multicast_list(struct net_device *dev)
152 ieee80211_configure_filter(local); 152 ieee80211_configure_filter(local);
153} 153}
154 154
155/* everything else */
156
157int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
158{
159 struct ieee80211_local *local = sdata->local;
160 struct ieee80211_if_conf conf;
161
162 if (WARN_ON(!netif_running(sdata->dev)))
163 return 0;
164
165 memset(&conf, 0, sizeof(conf));
166
167 if (sdata->vif.type == NL80211_IFTYPE_STATION)
168 conf.bssid = sdata->u.mgd.bssid;
169 else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
170 conf.bssid = sdata->u.ibss.bssid;
171 else if (sdata->vif.type == NL80211_IFTYPE_AP)
172 conf.bssid = sdata->dev->dev_addr;
173 else if (ieee80211_vif_is_mesh(&sdata->vif)) {
174 static const u8 zero[ETH_ALEN] = { 0 };
175 conf.bssid = zero;
176 } else {
177 WARN_ON(1);
178 return -EINVAL;
179 }
180
181 if (!local->ops->config_interface)
182 return 0;
183
184 switch (sdata->vif.type) {
185 case NL80211_IFTYPE_AP:
186 case NL80211_IFTYPE_ADHOC:
187 case NL80211_IFTYPE_MESH_POINT:
188 break;
189 default:
190 /* do not warn to simplify caller in scan.c */
191 changed &= ~IEEE80211_IFCC_BEACON_ENABLED;
192 if (WARN_ON(changed & IEEE80211_IFCC_BEACON))
193 return -EINVAL;
194 changed &= ~IEEE80211_IFCC_BEACON;
195 break;
196 }
197
198 if (changed & IEEE80211_IFCC_BEACON_ENABLED) {
199 if (local->sw_scanning) {
200 conf.enable_beacon = false;
201 } else {
202 /*
203 * Beacon should be enabled, but AP mode must
204 * check whether there is a beacon configured.
205 */
206 switch (sdata->vif.type) {
207 case NL80211_IFTYPE_AP:
208 conf.enable_beacon =
209 !!rcu_dereference(sdata->u.ap.beacon);
210 break;
211 case NL80211_IFTYPE_ADHOC:
212 conf.enable_beacon = !!sdata->u.ibss.presp;
213 break;
214 case NL80211_IFTYPE_MESH_POINT:
215 conf.enable_beacon = true;
216 break;
217 default:
218 /* not reached */
219 WARN_ON(1);
220 break;
221 }
222 }
223 }
224
225 conf.changed = changed;
226
227 return local->ops->config_interface(local_to_hw(local),
228 &sdata->vif, &conf);
229}
230
231int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) 155int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
232{ 156{
233 struct ieee80211_channel *chan; 157 struct ieee80211_channel *chan;
@@ -297,6 +221,61 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
297 if (!changed) 221 if (!changed)
298 return; 222 return;
299 223
224 if (sdata->vif.type == NL80211_IFTYPE_STATION)
225 sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
226 else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
227 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
228 else if (sdata->vif.type == NL80211_IFTYPE_AP)
229 sdata->vif.bss_conf.bssid = sdata->dev->dev_addr;
230 else if (ieee80211_vif_is_mesh(&sdata->vif)) {
231 static const u8 zero[ETH_ALEN] = { 0 };
232 sdata->vif.bss_conf.bssid = zero;
233 } else {
234 WARN_ON(1);
235 return;
236 }
237
238 switch (sdata->vif.type) {
239 case NL80211_IFTYPE_AP:
240 case NL80211_IFTYPE_ADHOC:
241 case NL80211_IFTYPE_MESH_POINT:
242 break;
243 default:
244 /* do not warn to simplify caller in scan.c */
245 changed &= ~BSS_CHANGED_BEACON_ENABLED;
246 if (WARN_ON(changed & BSS_CHANGED_BEACON))
247 return;
248 break;
249 }
250
251 if (changed & BSS_CHANGED_BEACON_ENABLED) {
252 if (local->sw_scanning) {
253 sdata->vif.bss_conf.enable_beacon = false;
254 } else {
255 /*
256 * Beacon should be enabled, but AP mode must
257 * check whether there is a beacon configured.
258 */
259 switch (sdata->vif.type) {
260 case NL80211_IFTYPE_AP:
261 sdata->vif.bss_conf.enable_beacon =
262 !!rcu_dereference(sdata->u.ap.beacon);
263 break;
264 case NL80211_IFTYPE_ADHOC:
265 sdata->vif.bss_conf.enable_beacon =
266 !!rcu_dereference(sdata->u.ibss.presp);
267 break;
268 case NL80211_IFTYPE_MESH_POINT:
269 sdata->vif.bss_conf.enable_beacon = true;
270 break;
271 default:
272 /* not reached */
273 WARN_ON(1);
274 break;
275 }
276 }
277 }
278
300 if (local->ops->bss_info_changed) 279 if (local->ops->bss_info_changed)
301 local->ops->bss_info_changed(local_to_hw(local), 280 local->ops->bss_info_changed(local_to_hw(local),
302 &sdata->vif, 281 &sdata->vif,
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 9a3e5de0410a..9000b01a1671 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -417,7 +417,7 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
417 417
418 free_plinks = mesh_plink_availables(sdata); 418 free_plinks = mesh_plink_availables(sdata);
419 if (free_plinks != sdata->u.mesh.accepting_plinks) 419 if (free_plinks != sdata->u.mesh.accepting_plinks)
420 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); 420 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
421 421
422 ifmsh->housekeeping = false; 422 ifmsh->housekeeping = false;
423 mod_timer(&ifmsh->housekeeping_timer, 423 mod_timer(&ifmsh->housekeeping_timer,
@@ -432,8 +432,8 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
432 432
433 ifmsh->housekeeping = true; 433 ifmsh->housekeeping = true;
434 queue_work(local->hw.workqueue, &ifmsh->work); 434 queue_work(local->hw.workqueue, &ifmsh->work);
435 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON | 435 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
436 IEEE80211_IFCC_BEACON_ENABLED); 436 BSS_CHANGED_BEACON_ENABLED);
437} 437}
438 438
439void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) 439void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index bfd571e6f221..c7971196d9d5 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2289,12 +2289,8 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
2289 ifmgd->flags &= ~IEEE80211_STA_BSSID_SET; 2289 ifmgd->flags &= ~IEEE80211_STA_BSSID_SET;
2290 } 2290 }
2291 2291
2292 if (netif_running(sdata->dev)) { 2292 if (netif_running(sdata->dev))
2293 if (ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID)) { 2293 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
2294 printk(KERN_DEBUG "%s: Failed to config new BSSID to "
2295 "the low-level driver\n", sdata->dev->name);
2296 }
2297 }
2298 2294
2299 return ieee80211_sta_commit(sdata); 2295 return ieee80211_sta_commit(sdata);
2300} 2296}
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 086d21645cbc..04e270abdd22 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -346,8 +346,8 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
346 if (sdata->vif.type == NL80211_IFTYPE_AP || 346 if (sdata->vif.type == NL80211_IFTYPE_AP ||
347 sdata->vif.type == NL80211_IFTYPE_ADHOC || 347 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
348 sdata->vif.type == NL80211_IFTYPE_MESH_POINT) 348 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
349 ieee80211_if_config(sdata, 349 ieee80211_bss_info_change_notify(
350 IEEE80211_IFCC_BEACON_ENABLED); 350 sdata, BSS_CHANGED_BEACON_ENABLED);
351 } 351 }
352 mutex_unlock(&local->iflist_mtx); 352 mutex_unlock(&local->iflist_mtx);
353 353
@@ -387,8 +387,8 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
387 if (sdata->vif.type == NL80211_IFTYPE_AP || 387 if (sdata->vif.type == NL80211_IFTYPE_AP ||
388 sdata->vif.type == NL80211_IFTYPE_ADHOC || 388 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
389 sdata->vif.type == NL80211_IFTYPE_MESH_POINT) 389 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
390 ieee80211_if_config(sdata, 390 ieee80211_bss_info_change_notify(
391 IEEE80211_IFCC_BEACON_ENABLED); 391 sdata, BSS_CHANGED_BEACON_ENABLED);
392 392
393 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 393 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
394 if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) { 394 if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) {
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 61876eb50b49..2cde9bbfe7d9 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1063,24 +1063,13 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1063 switch (sdata->vif.type) { 1063 switch (sdata->vif.type) {
1064 case NL80211_IFTYPE_STATION: 1064 case NL80211_IFTYPE_STATION:
1065 /* disable beacon change bits */ 1065 /* disable beacon change bits */
1066 changed &= ~IEEE80211_IFCC_BEACON; 1066 changed &= ~(BSS_CHANGED_BEACON |
1067 BSS_CHANGED_BEACON_ENABLED);
1067 /* fall through */ 1068 /* fall through */
1068 case NL80211_IFTYPE_ADHOC: 1069 case NL80211_IFTYPE_ADHOC:
1069 case NL80211_IFTYPE_AP: 1070 case NL80211_IFTYPE_AP:
1070 case NL80211_IFTYPE_MESH_POINT: 1071 case NL80211_IFTYPE_MESH_POINT:
1071 /* 1072 ieee80211_bss_info_change_notify(sdata, changed);
1072 * Driver's config_interface can fail if rfkill is
1073 * enabled. Accommodate this return code.
1074 * FIXME: When mac80211 has knowledge of rfkill
1075 * state the code below can change back to:
1076 * WARN(ieee80211_if_config(sdata, changed));
1077 * ieee80211_bss_info_change_notify(sdata, ~0);
1078 */
1079 if (ieee80211_if_config(sdata, changed))
1080 printk(KERN_DEBUG "%s: failed to configure interface during resume\n",
1081 sdata->dev->name);
1082 else
1083 ieee80211_bss_info_change_notify(sdata, ~0);
1084 break; 1073 break;
1085 case NL80211_IFTYPE_WDS: 1074 case NL80211_IFTYPE_WDS:
1086 break; 1075 break;