diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-07-09 08:40:37 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-07-14 14:30:07 -0400 |
commit | 9d139c810a2aa17365cc548d0cd2a189d8433c65 (patch) | |
tree | ef10ca55f93689ab97368376d277102d2527c961 /net/mac80211 | |
parent | f3947e2dfa3b18f375b7acd03b7ee2877d0751fc (diff) |
mac80211: revamp beacon configuration
This patch changes mac80211's beacon configuration handling
to never pass skbs to the driver directly but rather always
require the driver to use ieee80211_beacon_get(). Additionally,
it introduces "change flags" on the config_interface() call
to enable drivers to figure out what is changing. Finally, it
removes the beacon_update() driver callback in favour of
having IBSS beacon delivered by ieee80211_beacon_get() as well.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 4 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/main.c | 59 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 112 | ||||
-rw-r--r-- | net/mac80211/tx.c | 36 | ||||
-rw-r--r-- | net/mac80211/wext.c | 2 |
6 files changed, 95 insertions, 121 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ea0301025c15..8e7ba0e62cf5 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -469,7 +469,7 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, | |||
469 | 469 | ||
470 | kfree(old); | 470 | kfree(old); |
471 | 471 | ||
472 | return ieee80211_if_config_beacon(sdata->dev); | 472 | return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); |
473 | } | 473 | } |
474 | 474 | ||
475 | static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, | 475 | static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, |
@@ -523,7 +523,7 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) | |||
523 | synchronize_rcu(); | 523 | synchronize_rcu(); |
524 | kfree(old); | 524 | kfree(old); |
525 | 525 | ||
526 | return ieee80211_if_config_beacon(dev); | 526 | return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); |
527 | } | 527 | } |
528 | 528 | ||
529 | /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ | 529 | /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 2146c0c436d2..934c3ef4f0bc 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -854,8 +854,7 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) | |||
854 | 854 | ||
855 | /* ieee80211.c */ | 855 | /* ieee80211.c */ |
856 | int ieee80211_hw_config(struct ieee80211_local *local); | 856 | int ieee80211_hw_config(struct ieee80211_local *local); |
857 | int ieee80211_if_config(struct net_device *dev); | 857 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed); |
858 | int ieee80211_if_config_beacon(struct net_device *dev); | ||
859 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); | 858 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); |
860 | u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, | 859 | u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, |
861 | struct ieee80211_ht_info *req_ht_cap, | 860 | struct ieee80211_ht_info *req_ht_cap, |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0759ab2ca3ff..36859e794928 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -307,7 +307,8 @@ static int ieee80211_open(struct net_device *dev) | |||
307 | if (res) | 307 | if (res) |
308 | goto err_stop; | 308 | goto err_stop; |
309 | 309 | ||
310 | ieee80211_if_config(dev); | 310 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
311 | ieee80211_start_mesh(sdata->dev); | ||
311 | changed |= ieee80211_reset_erp_info(dev); | 312 | changed |= ieee80211_reset_erp_info(dev); |
312 | ieee80211_bss_info_change_notify(sdata, changed); | 313 | ieee80211_bss_info_change_notify(sdata, changed); |
313 | ieee80211_enable_keys(sdata); | 314 | ieee80211_enable_keys(sdata); |
@@ -985,57 +986,47 @@ void ieee80211_if_setup(struct net_device *dev) | |||
985 | 986 | ||
986 | /* everything else */ | 987 | /* everything else */ |
987 | 988 | ||
988 | static int __ieee80211_if_config(struct net_device *dev, | 989 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) |
989 | struct sk_buff *beacon) | ||
990 | { | 990 | { |
991 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 991 | struct ieee80211_local *local = sdata->local; |
992 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
993 | struct ieee80211_if_conf conf; | 992 | struct ieee80211_if_conf conf; |
994 | 993 | ||
995 | if (!local->ops->config_interface || !netif_running(dev)) | 994 | if (WARN_ON(!netif_running(sdata->dev))) |
995 | return 0; | ||
996 | |||
997 | if (!local->ops->config_interface) | ||
996 | return 0; | 998 | return 0; |
997 | 999 | ||
998 | memset(&conf, 0, sizeof(conf)); | 1000 | memset(&conf, 0, sizeof(conf)); |
999 | conf.type = sdata->vif.type; | 1001 | conf.changed = changed; |
1002 | |||
1000 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || | 1003 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || |
1001 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | 1004 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { |
1002 | conf.bssid = sdata->u.sta.bssid; | 1005 | conf.bssid = sdata->u.sta.bssid; |
1003 | conf.ssid = sdata->u.sta.ssid; | 1006 | conf.ssid = sdata->u.sta.ssid; |
1004 | conf.ssid_len = sdata->u.sta.ssid_len; | 1007 | conf.ssid_len = sdata->u.sta.ssid_len; |
1005 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
1006 | conf.beacon = beacon; | ||
1007 | ieee80211_start_mesh(dev); | ||
1008 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { | 1008 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { |
1009 | conf.bssid = sdata->dev->dev_addr; | ||
1009 | conf.ssid = sdata->u.ap.ssid; | 1010 | conf.ssid = sdata->u.ap.ssid; |
1010 | conf.ssid_len = sdata->u.ap.ssid_len; | 1011 | conf.ssid_len = sdata->u.ap.ssid_len; |
1011 | conf.beacon = beacon; | 1012 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
1013 | u8 zero[ETH_ALEN] = { 0 }; | ||
1014 | conf.bssid = zero; | ||
1015 | conf.ssid = zero; | ||
1016 | conf.ssid_len = 0; | ||
1017 | } else { | ||
1018 | WARN_ON(1); | ||
1019 | return -EINVAL; | ||
1012 | } | 1020 | } |
1013 | return local->ops->config_interface(local_to_hw(local), | ||
1014 | &sdata->vif, &conf); | ||
1015 | } | ||
1016 | 1021 | ||
1017 | int ieee80211_if_config(struct net_device *dev) | 1022 | if (WARN_ON(!conf.bssid && (changed & IEEE80211_IFCC_BSSID))) |
1018 | { | 1023 | return -EINVAL; |
1019 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1020 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
1021 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && | ||
1022 | (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) | ||
1023 | return ieee80211_if_config_beacon(dev); | ||
1024 | return __ieee80211_if_config(dev, NULL); | ||
1025 | } | ||
1026 | 1024 | ||
1027 | int ieee80211_if_config_beacon(struct net_device *dev) | 1025 | if (WARN_ON(!conf.ssid && (changed & IEEE80211_IFCC_SSID))) |
1028 | { | 1026 | return -EINVAL; |
1029 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
1030 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1031 | struct sk_buff *skb; | ||
1032 | 1027 | ||
1033 | if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) | 1028 | return local->ops->config_interface(local_to_hw(local), |
1034 | return 0; | 1029 | &sdata->vif, &conf); |
1035 | skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif); | ||
1036 | if (!skb) | ||
1037 | return -ENOMEM; | ||
1038 | return __ieee80211_if_config(dev, skb); | ||
1039 | } | 1030 | } |
1040 | 1031 | ||
1041 | int ieee80211_hw_config(struct ieee80211_local *local) | 1032 | int ieee80211_hw_config(struct ieee80211_local *local) |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 64d710a88b86..61d7f81bf45e 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2406,8 +2406,6 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2406 | int res, rates, i, j; | 2406 | int res, rates, i, j; |
2407 | struct sk_buff *skb; | 2407 | struct sk_buff *skb; |
2408 | struct ieee80211_mgmt *mgmt; | 2408 | struct ieee80211_mgmt *mgmt; |
2409 | struct ieee80211_tx_info *control; | ||
2410 | struct rate_selection ratesel; | ||
2411 | u8 *pos; | 2409 | u8 *pos; |
2412 | struct ieee80211_sub_if_data *sdata; | 2410 | struct ieee80211_sub_if_data *sdata; |
2413 | struct ieee80211_supported_band *sband; | 2411 | struct ieee80211_supported_band *sband; |
@@ -2425,7 +2423,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2425 | local->ops->reset_tsf(local_to_hw(local)); | 2423 | local->ops->reset_tsf(local_to_hw(local)); |
2426 | } | 2424 | } |
2427 | memcpy(ifsta->bssid, bss->bssid, ETH_ALEN); | 2425 | memcpy(ifsta->bssid, bss->bssid, ETH_ALEN); |
2428 | res = ieee80211_if_config(dev); | 2426 | res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID); |
2429 | if (res) | 2427 | if (res) |
2430 | return res; | 2428 | return res; |
2431 | 2429 | ||
@@ -2439,19 +2437,16 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2439 | if (res) | 2437 | if (res) |
2440 | return res; | 2438 | return res; |
2441 | 2439 | ||
2442 | /* Set beacon template */ | 2440 | /* Build IBSS probe response */ |
2443 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | 2441 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); |
2444 | do { | 2442 | if (skb) { |
2445 | if (!skb) | ||
2446 | break; | ||
2447 | |||
2448 | skb_reserve(skb, local->hw.extra_tx_headroom); | 2443 | skb_reserve(skb, local->hw.extra_tx_headroom); |
2449 | 2444 | ||
2450 | mgmt = (struct ieee80211_mgmt *) | 2445 | mgmt = (struct ieee80211_mgmt *) |
2451 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | 2446 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); |
2452 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | 2447 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); |
2453 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | 2448 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, |
2454 | IEEE80211_STYPE_BEACON); | 2449 | IEEE80211_STYPE_PROBE_RESP); |
2455 | memset(mgmt->da, 0xff, ETH_ALEN); | 2450 | memset(mgmt->da, 0xff, ETH_ALEN); |
2456 | memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); | 2451 | memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); |
2457 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); | 2452 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); |
@@ -2495,61 +2490,22 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2495 | memcpy(pos, &bss->supp_rates[8], rates); | 2490 | memcpy(pos, &bss->supp_rates[8], rates); |
2496 | } | 2491 | } |
2497 | 2492 | ||
2498 | control = IEEE80211_SKB_CB(skb); | 2493 | ifsta->probe_resp = skb; |
2499 | |||
2500 | rate_control_get_rate(dev, sband, skb, &ratesel); | ||
2501 | if (ratesel.rate_idx < 0) { | ||
2502 | printk(KERN_DEBUG "%s: Failed to determine TX rate " | ||
2503 | "for IBSS beacon\n", dev->name); | ||
2504 | break; | ||
2505 | } | ||
2506 | control->control.vif = &sdata->vif; | ||
2507 | control->tx_rate_idx = ratesel.rate_idx; | ||
2508 | if (sdata->bss_conf.use_short_preamble && | ||
2509 | sband->bitrates[ratesel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
2510 | control->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; | ||
2511 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; | ||
2512 | control->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
2513 | control->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | ||
2514 | control->control.retry_limit = 1; | ||
2515 | |||
2516 | ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC); | ||
2517 | if (ifsta->probe_resp) { | ||
2518 | mgmt = (struct ieee80211_mgmt *) | ||
2519 | ifsta->probe_resp->data; | ||
2520 | mgmt->frame_control = | ||
2521 | IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
2522 | IEEE80211_STYPE_PROBE_RESP); | ||
2523 | } else { | ||
2524 | printk(KERN_DEBUG "%s: Could not allocate ProbeResp " | ||
2525 | "template for IBSS\n", dev->name); | ||
2526 | } | ||
2527 | |||
2528 | if (local->ops->beacon_update && | ||
2529 | local->ops->beacon_update(local_to_hw(local), skb) == 0) { | ||
2530 | printk(KERN_DEBUG "%s: Configured IBSS beacon " | ||
2531 | "template\n", dev->name); | ||
2532 | skb = NULL; | ||
2533 | } | ||
2534 | |||
2535 | rates = 0; | ||
2536 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
2537 | for (i = 0; i < bss->supp_rates_len; i++) { | ||
2538 | int bitrate = (bss->supp_rates[i] & 0x7f) * 5; | ||
2539 | for (j = 0; j < sband->n_bitrates; j++) | ||
2540 | if (sband->bitrates[j].bitrate == bitrate) | ||
2541 | rates |= BIT(j); | ||
2542 | } | ||
2543 | ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates; | ||
2544 | 2494 | ||
2545 | ieee80211_sta_def_wmm_params(dev, bss, 1); | 2495 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); |
2546 | } while (0); | 2496 | } |
2547 | 2497 | ||
2548 | if (skb) { | 2498 | rates = 0; |
2549 | printk(KERN_DEBUG "%s: Failed to configure IBSS beacon " | 2499 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
2550 | "template\n", dev->name); | 2500 | for (i = 0; i < bss->supp_rates_len; i++) { |
2551 | dev_kfree_skb(skb); | 2501 | int bitrate = (bss->supp_rates[i] & 0x7f) * 5; |
2502 | for (j = 0; j < sband->n_bitrates; j++) | ||
2503 | if (sband->bitrates[j].bitrate == bitrate) | ||
2504 | rates |= BIT(j); | ||
2552 | } | 2505 | } |
2506 | ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates; | ||
2507 | |||
2508 | ieee80211_sta_def_wmm_params(dev, bss, 1); | ||
2553 | 2509 | ||
2554 | ifsta->state = IEEE80211_IBSS_JOINED; | 2510 | ifsta->state = IEEE80211_IBSS_JOINED; |
2555 | mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); | 2511 | mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); |
@@ -3333,7 +3289,7 @@ static void ieee80211_mesh_housekeeping(struct net_device *dev, | |||
3333 | 3289 | ||
3334 | free_plinks = mesh_plink_availables(sdata); | 3290 | free_plinks = mesh_plink_availables(sdata); |
3335 | if (free_plinks != sdata->u.sta.accepting_plinks) | 3291 | if (free_plinks != sdata->u.sta.accepting_plinks) |
3336 | ieee80211_if_config_beacon(dev); | 3292 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); |
3337 | 3293 | ||
3338 | mod_timer(&ifsta->timer, jiffies + | 3294 | mod_timer(&ifsta->timer, jiffies + |
3339 | IEEE80211_MESH_HOUSEKEEPING_INTERVAL); | 3295 | IEEE80211_MESH_HOUSEKEEPING_INTERVAL); |
@@ -3757,28 +3713,45 @@ int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) | |||
3757 | { | 3713 | { |
3758 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3714 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3759 | struct ieee80211_if_sta *ifsta; | 3715 | struct ieee80211_if_sta *ifsta; |
3716 | int res; | ||
3760 | 3717 | ||
3761 | if (len > IEEE80211_MAX_SSID_LEN) | 3718 | if (len > IEEE80211_MAX_SSID_LEN) |
3762 | return -EINVAL; | 3719 | return -EINVAL; |
3763 | 3720 | ||
3764 | ifsta = &sdata->u.sta; | 3721 | ifsta = &sdata->u.sta; |
3765 | 3722 | ||
3766 | if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) | 3723 | if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) { |
3724 | memset(ifsta->ssid, 0, sizeof(ifsta->ssid)); | ||
3725 | memcpy(ifsta->ssid, ssid, len); | ||
3726 | ifsta->ssid_len = len; | ||
3767 | ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET; | 3727 | ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET; |
3768 | memcpy(ifsta->ssid, ssid, len); | 3728 | |
3769 | memset(ifsta->ssid + len, 0, IEEE80211_MAX_SSID_LEN - len); | 3729 | res = 0; |
3770 | ifsta->ssid_len = len; | 3730 | /* |
3731 | * Hack! MLME code needs to be cleaned up to have different | ||
3732 | * entry points for configuration and internal selection change | ||
3733 | */ | ||
3734 | if (netif_running(sdata->dev)) | ||
3735 | res = ieee80211_if_config(sdata, IEEE80211_IFCC_SSID); | ||
3736 | if (res) { | ||
3737 | printk(KERN_DEBUG "%s: Failed to config new SSID to " | ||
3738 | "the low-level driver\n", dev->name); | ||
3739 | return res; | ||
3740 | } | ||
3741 | } | ||
3771 | 3742 | ||
3772 | if (len) | 3743 | if (len) |
3773 | ifsta->flags |= IEEE80211_STA_SSID_SET; | 3744 | ifsta->flags |= IEEE80211_STA_SSID_SET; |
3774 | else | 3745 | else |
3775 | ifsta->flags &= ~IEEE80211_STA_SSID_SET; | 3746 | ifsta->flags &= ~IEEE80211_STA_SSID_SET; |
3747 | |||
3776 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && | 3748 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && |
3777 | !(ifsta->flags & IEEE80211_STA_BSSID_SET)) { | 3749 | !(ifsta->flags & IEEE80211_STA_BSSID_SET)) { |
3778 | ifsta->ibss_join_req = jiffies; | 3750 | ifsta->ibss_join_req = jiffies; |
3779 | ifsta->state = IEEE80211_IBSS_SEARCH; | 3751 | ifsta->state = IEEE80211_IBSS_SEARCH; |
3780 | return ieee80211_sta_find_ibss(dev, ifsta); | 3752 | return ieee80211_sta_find_ibss(dev, ifsta); |
3781 | } | 3753 | } |
3754 | |||
3782 | return 0; | 3755 | return 0; |
3783 | } | 3756 | } |
3784 | 3757 | ||
@@ -3804,7 +3777,12 @@ int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid) | |||
3804 | 3777 | ||
3805 | if (memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { | 3778 | if (memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { |
3806 | memcpy(ifsta->bssid, bssid, ETH_ALEN); | 3779 | memcpy(ifsta->bssid, bssid, ETH_ALEN); |
3807 | res = ieee80211_if_config(dev); | 3780 | res = 0; |
3781 | /* | ||
3782 | * Hack! See also ieee80211_sta_set_ssid. | ||
3783 | */ | ||
3784 | if (netif_running(sdata->dev)) | ||
3785 | res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID); | ||
3808 | if (res) { | 3786 | if (res) { |
3809 | printk(KERN_DEBUG "%s: Failed to config new BSSID to " | 3787 | printk(KERN_DEBUG "%s: Failed to config new BSSID to " |
3810 | "the low-level driver\n", dev->name); | 3788 | "the low-level driver\n", dev->name); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index a757dcc1208d..8843416e1460 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1788,17 +1788,17 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1788 | struct ieee80211_vif *vif) | 1788 | struct ieee80211_vif *vif) |
1789 | { | 1789 | { |
1790 | struct ieee80211_local *local = hw_to_local(hw); | 1790 | struct ieee80211_local *local = hw_to_local(hw); |
1791 | struct sk_buff *skb; | 1791 | struct sk_buff *skb = NULL; |
1792 | struct ieee80211_tx_info *info; | 1792 | struct ieee80211_tx_info *info; |
1793 | struct net_device *bdev; | 1793 | struct net_device *bdev; |
1794 | struct ieee80211_sub_if_data *sdata = NULL; | 1794 | struct ieee80211_sub_if_data *sdata = NULL; |
1795 | struct ieee80211_if_ap *ap = NULL; | 1795 | struct ieee80211_if_ap *ap = NULL; |
1796 | struct ieee80211_if_sta *ifsta = NULL; | ||
1796 | struct rate_selection rsel; | 1797 | struct rate_selection rsel; |
1797 | struct beacon_data *beacon; | 1798 | struct beacon_data *beacon; |
1798 | struct ieee80211_supported_band *sband; | 1799 | struct ieee80211_supported_band *sband; |
1799 | struct ieee80211_mgmt *mgmt; | 1800 | struct ieee80211_mgmt *mgmt; |
1800 | int *num_beacons; | 1801 | int *num_beacons; |
1801 | bool err = true; | ||
1802 | enum ieee80211_band band = local->hw.conf.channel->band; | 1802 | enum ieee80211_band band = local->hw.conf.channel->band; |
1803 | u8 *pos; | 1803 | u8 *pos; |
1804 | 1804 | ||
@@ -1852,9 +1852,24 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1852 | beacon->tail, beacon->tail_len); | 1852 | beacon->tail, beacon->tail_len); |
1853 | 1853 | ||
1854 | num_beacons = &ap->num_beacons; | 1854 | num_beacons = &ap->num_beacons; |
1855 | } else | ||
1856 | goto out; | ||
1857 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | ||
1858 | struct ieee80211_hdr *hdr; | ||
1859 | ifsta = &sdata->u.sta; | ||
1855 | 1860 | ||
1856 | err = false; | 1861 | if (!ifsta->probe_resp) |
1857 | } | 1862 | goto out; |
1863 | |||
1864 | skb = skb_copy(ifsta->probe_resp, GFP_ATOMIC); | ||
1865 | if (!skb) | ||
1866 | goto out; | ||
1867 | |||
1868 | hdr = (struct ieee80211_hdr *) skb->data; | ||
1869 | hdr->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
1870 | IEEE80211_STYPE_BEACON); | ||
1871 | |||
1872 | num_beacons = &ifsta->num_beacons; | ||
1858 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | 1873 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
1859 | /* headroom, head length, tail length and maximum TIM length */ | 1874 | /* headroom, head length, tail length and maximum TIM length */ |
1860 | skb = dev_alloc_skb(local->tx_headroom + 400); | 1875 | skb = dev_alloc_skb(local->tx_headroom + 400); |
@@ -1881,17 +1896,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1881 | mesh_mgmt_ies_add(skb, sdata->dev); | 1896 | mesh_mgmt_ies_add(skb, sdata->dev); |
1882 | 1897 | ||
1883 | num_beacons = &sdata->u.sta.num_beacons; | 1898 | num_beacons = &sdata->u.sta.num_beacons; |
1884 | 1899 | } else { | |
1885 | err = false; | 1900 | WARN_ON(1); |
1886 | } | ||
1887 | |||
1888 | if (err) { | ||
1889 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
1890 | if (net_ratelimit()) | ||
1891 | printk(KERN_DEBUG "no beacon data avail for %s\n", | ||
1892 | bdev->name); | ||
1893 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | ||
1894 | skb = NULL; | ||
1895 | goto out; | 1901 | goto out; |
1896 | } | 1902 | } |
1897 | 1903 | ||
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index c041db9556c7..34fa8ed1e784 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -444,7 +444,7 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev, | |||
444 | memset(sdata->u.ap.ssid + len, 0, | 444 | memset(sdata->u.ap.ssid + len, 0, |
445 | IEEE80211_MAX_SSID_LEN - len); | 445 | IEEE80211_MAX_SSID_LEN - len); |
446 | sdata->u.ap.ssid_len = len; | 446 | sdata->u.ap.ssid_len = len; |
447 | return ieee80211_if_config(dev); | 447 | return ieee80211_if_config(sdata, IEEE80211_IFCC_SSID); |
448 | } | 448 | } |
449 | return -EOPNOTSUPP; | 449 | return -EOPNOTSUPP; |
450 | } | 450 | } |