diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 74 |
1 files changed, 41 insertions, 33 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4adba09e80ca..4d2b582dd055 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ) | 44 | #define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ) |
45 | #define IEEE80211_SCAN_INTERVAL (2 * HZ) | 45 | #define IEEE80211_SCAN_INTERVAL (2 * HZ) |
46 | #define IEEE80211_SCAN_INTERVAL_SLOW (15 * HZ) | 46 | #define IEEE80211_SCAN_INTERVAL_SLOW (15 * HZ) |
47 | #define IEEE80211_IBSS_JOIN_TIMEOUT (20 * HZ) | 47 | #define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ) |
48 | 48 | ||
49 | #define IEEE80211_PROBE_DELAY (HZ / 33) | 49 | #define IEEE80211_PROBE_DELAY (HZ / 33) |
50 | #define IEEE80211_CHANNEL_TIME (HZ / 33) | 50 | #define IEEE80211_CHANNEL_TIME (HZ / 33) |
@@ -730,7 +730,17 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
730 | if (bss->wmm_ie) { | 730 | if (bss->wmm_ie) { |
731 | wmm = 1; | 731 | wmm = 1; |
732 | } | 732 | } |
733 | |||
734 | /* get all rates supported by the device and the AP as | ||
735 | * some APs don't like getting a superset of their rates | ||
736 | * in the association request (e.g. D-Link DAP 1353 in | ||
737 | * b-only mode) */ | ||
738 | rates_len = ieee80211_compatible_rates(bss, sband, &rates); | ||
739 | |||
733 | ieee80211_rx_bss_put(dev, bss); | 740 | ieee80211_rx_bss_put(dev, bss); |
741 | } else { | ||
742 | rates = ~0; | ||
743 | rates_len = sband->n_bitrates; | ||
734 | } | 744 | } |
735 | 745 | ||
736 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); | 746 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); |
@@ -761,10 +771,7 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
761 | *pos++ = ifsta->ssid_len; | 771 | *pos++ = ifsta->ssid_len; |
762 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); | 772 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); |
763 | 773 | ||
764 | /* all supported rates should be added here but some APs | 774 | /* add all rates which were marked to be used above */ |
765 | * (e.g. D-Link DAP 1353 in b-only mode) don't like that | ||
766 | * Therefore only add rates the AP supports */ | ||
767 | rates_len = ieee80211_compatible_rates(bss, sband, &rates); | ||
768 | supp_rates_len = rates_len; | 775 | supp_rates_len = rates_len; |
769 | if (supp_rates_len > 8) | 776 | if (supp_rates_len > 8) |
770 | supp_rates_len = 8; | 777 | supp_rates_len = 8; |
@@ -1318,7 +1325,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1318 | 1325 | ||
1319 | /* prepare reordering buffer */ | 1326 | /* prepare reordering buffer */ |
1320 | tid_agg_rx->reorder_buf = | 1327 | tid_agg_rx->reorder_buf = |
1321 | kmalloc(buf_size * sizeof(struct sk_buf *), GFP_ATOMIC); | 1328 | kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC); |
1322 | if (!tid_agg_rx->reorder_buf) { | 1329 | if (!tid_agg_rx->reorder_buf) { |
1323 | if (net_ratelimit()) | 1330 | if (net_ratelimit()) |
1324 | printk(KERN_ERR "can not allocate reordering buffer " | 1331 | printk(KERN_ERR "can not allocate reordering buffer " |
@@ -1327,7 +1334,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1327 | goto end; | 1334 | goto end; |
1328 | } | 1335 | } |
1329 | memset(tid_agg_rx->reorder_buf, 0, | 1336 | memset(tid_agg_rx->reorder_buf, 0, |
1330 | buf_size * sizeof(struct sk_buf *)); | 1337 | buf_size * sizeof(struct sk_buff *)); |
1331 | 1338 | ||
1332 | if (local->ops->ampdu_action) | 1339 | if (local->ops->ampdu_action) |
1333 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START, | 1340 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START, |
@@ -1607,7 +1614,7 @@ void sta_addba_resp_timer_expired(unsigned long data) | |||
1607 | * only one argument, and both sta_info and TID are needed, so init | 1614 | * only one argument, and both sta_info and TID are needed, so init |
1608 | * flow in sta_info_create gives the TID as data, while the timer_to_id | 1615 | * flow in sta_info_create gives the TID as data, while the timer_to_id |
1609 | * array gives the sta through container_of */ | 1616 | * array gives the sta through container_of */ |
1610 | u16 tid = *(int *)data; | 1617 | u16 tid = *(u8 *)data; |
1611 | struct sta_info *temp_sta = container_of((void *)data, | 1618 | struct sta_info *temp_sta = container_of((void *)data, |
1612 | struct sta_info, timer_to_tid[tid]); | 1619 | struct sta_info, timer_to_tid[tid]); |
1613 | 1620 | ||
@@ -1655,7 +1662,7 @@ timer_expired_exit: | |||
1655 | void sta_rx_agg_session_timer_expired(unsigned long data) | 1662 | void sta_rx_agg_session_timer_expired(unsigned long data) |
1656 | { | 1663 | { |
1657 | /* not an elegant detour, but there is no choice as the timer passes | 1664 | /* not an elegant detour, but there is no choice as the timer passes |
1658 | * only one argument, and verious sta_info are needed here, so init | 1665 | * only one argument, and various sta_info are needed here, so init |
1659 | * flow in sta_info_create gives the TID as data, while the timer_to_id | 1666 | * flow in sta_info_create gives the TID as data, while the timer_to_id |
1660 | * array gives the sta through container_of */ | 1667 | * array gives the sta through container_of */ |
1661 | u8 *ptid = (u8 *)data; | 1668 | u8 *ptid = (u8 *)data; |
@@ -2329,6 +2336,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2329 | u8 *pos; | 2336 | u8 *pos; |
2330 | struct ieee80211_sub_if_data *sdata; | 2337 | struct ieee80211_sub_if_data *sdata; |
2331 | struct ieee80211_supported_band *sband; | 2338 | struct ieee80211_supported_band *sband; |
2339 | union iwreq_data wrqu; | ||
2332 | 2340 | ||
2333 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 2341 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
2334 | 2342 | ||
@@ -2351,13 +2359,10 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2351 | sdata->drop_unencrypted = bss->capability & | 2359 | sdata->drop_unencrypted = bss->capability & |
2352 | WLAN_CAPABILITY_PRIVACY ? 1 : 0; | 2360 | WLAN_CAPABILITY_PRIVACY ? 1 : 0; |
2353 | 2361 | ||
2354 | res = ieee80211_set_freq(local, bss->freq); | 2362 | res = ieee80211_set_freq(dev, bss->freq); |
2355 | 2363 | ||
2356 | if (local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) { | 2364 | if (res) |
2357 | printk(KERN_DEBUG "%s: IBSS not allowed on frequency " | 2365 | return res; |
2358 | "%d MHz\n", dev->name, local->oper_channel->center_freq); | ||
2359 | return -1; | ||
2360 | } | ||
2361 | 2366 | ||
2362 | /* Set beacon template */ | 2367 | /* Set beacon template */ |
2363 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | 2368 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); |
@@ -2472,7 +2477,9 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2472 | ifsta->state = IEEE80211_IBSS_JOINED; | 2477 | ifsta->state = IEEE80211_IBSS_JOINED; |
2473 | mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); | 2478 | mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); |
2474 | 2479 | ||
2475 | ieee80211_rx_bss_put(dev, bss); | 2480 | memset(&wrqu, 0, sizeof(wrqu)); |
2481 | memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN); | ||
2482 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); | ||
2476 | 2483 | ||
2477 | return res; | 2484 | return res; |
2478 | } | 2485 | } |
@@ -3446,21 +3453,17 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
3446 | struct ieee80211_sta_bss *bss, *selected = NULL; | 3453 | struct ieee80211_sta_bss *bss, *selected = NULL; |
3447 | int top_rssi = 0, freq; | 3454 | int top_rssi = 0, freq; |
3448 | 3455 | ||
3449 | if (!(ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL | | ||
3450 | IEEE80211_STA_AUTO_BSSID_SEL | IEEE80211_STA_AUTO_CHANNEL_SEL))) { | ||
3451 | ifsta->state = IEEE80211_AUTHENTICATE; | ||
3452 | ieee80211_sta_reset_auth(dev, ifsta); | ||
3453 | return 0; | ||
3454 | } | ||
3455 | |||
3456 | spin_lock_bh(&local->sta_bss_lock); | 3456 | spin_lock_bh(&local->sta_bss_lock); |
3457 | freq = local->oper_channel->center_freq; | 3457 | freq = local->oper_channel->center_freq; |
3458 | list_for_each_entry(bss, &local->sta_bss_list, list) { | 3458 | list_for_each_entry(bss, &local->sta_bss_list, list) { |
3459 | if (!(bss->capability & WLAN_CAPABILITY_ESS)) | 3459 | if (!(bss->capability & WLAN_CAPABILITY_ESS)) |
3460 | continue; | 3460 | continue; |
3461 | 3461 | ||
3462 | if (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^ | 3462 | if ((ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL | |
3463 | !!sdata->default_key) | 3463 | IEEE80211_STA_AUTO_BSSID_SEL | |
3464 | IEEE80211_STA_AUTO_CHANNEL_SEL)) && | ||
3465 | (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^ | ||
3466 | !!sdata->default_key)) | ||
3464 | continue; | 3467 | continue; |
3465 | 3468 | ||
3466 | if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) && | 3469 | if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) && |
@@ -3485,7 +3488,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
3485 | spin_unlock_bh(&local->sta_bss_lock); | 3488 | spin_unlock_bh(&local->sta_bss_lock); |
3486 | 3489 | ||
3487 | if (selected) { | 3490 | if (selected) { |
3488 | ieee80211_set_freq(local, selected->freq); | 3491 | ieee80211_set_freq(dev, selected->freq); |
3489 | if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) | 3492 | if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) |
3490 | ieee80211_sta_set_ssid(dev, selected->ssid, | 3493 | ieee80211_sta_set_ssid(dev, selected->ssid, |
3491 | selected->ssid_len); | 3494 | selected->ssid_len); |
@@ -3520,6 +3523,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
3520 | struct ieee80211_supported_band *sband; | 3523 | struct ieee80211_supported_band *sband; |
3521 | u8 bssid[ETH_ALEN], *pos; | 3524 | u8 bssid[ETH_ALEN], *pos; |
3522 | int i; | 3525 | int i; |
3526 | int ret; | ||
3523 | DECLARE_MAC_BUF(mac); | 3527 | DECLARE_MAC_BUF(mac); |
3524 | 3528 | ||
3525 | #if 0 | 3529 | #if 0 |
@@ -3564,7 +3568,9 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
3564 | *pos++ = (u8) (rate / 5); | 3568 | *pos++ = (u8) (rate / 5); |
3565 | } | 3569 | } |
3566 | 3570 | ||
3567 | return ieee80211_sta_join_ibss(dev, ifsta, bss); | 3571 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); |
3572 | ieee80211_rx_bss_put(dev, bss); | ||
3573 | return ret; | ||
3568 | } | 3574 | } |
3569 | 3575 | ||
3570 | 3576 | ||
@@ -3612,10 +3618,13 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
3612 | (bss = ieee80211_rx_bss_get(dev, bssid, | 3618 | (bss = ieee80211_rx_bss_get(dev, bssid, |
3613 | local->hw.conf.channel->center_freq, | 3619 | local->hw.conf.channel->center_freq, |
3614 | ifsta->ssid, ifsta->ssid_len))) { | 3620 | ifsta->ssid, ifsta->ssid_len))) { |
3621 | int ret; | ||
3615 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" | 3622 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" |
3616 | " based on configured SSID\n", | 3623 | " based on configured SSID\n", |
3617 | dev->name, print_mac(mac, bssid)); | 3624 | dev->name, print_mac(mac, bssid)); |
3618 | return ieee80211_sta_join_ibss(dev, ifsta, bss); | 3625 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); |
3626 | ieee80211_rx_bss_put(dev, bss); | ||
3627 | return ret; | ||
3619 | } | 3628 | } |
3620 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 3629 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
3621 | printk(KERN_DEBUG " did not try to join ibss\n"); | 3630 | printk(KERN_DEBUG " did not try to join ibss\n"); |
@@ -4092,18 +4101,17 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4092 | 4101 | ||
4093 | memset(&iwe, 0, sizeof(iwe)); | 4102 | memset(&iwe, 0, sizeof(iwe)); |
4094 | iwe.cmd = SIOCGIWFREQ; | 4103 | iwe.cmd = SIOCGIWFREQ; |
4095 | iwe.u.freq.m = bss->freq; | 4104 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); |
4096 | iwe.u.freq.e = 6; | 4105 | iwe.u.freq.e = 0; |
4097 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4106 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, |
4098 | IW_EV_FREQ_LEN); | 4107 | IW_EV_FREQ_LEN); |
4099 | 4108 | ||
4100 | memset(&iwe, 0, sizeof(iwe)); | 4109 | memset(&iwe, 0, sizeof(iwe)); |
4101 | iwe.cmd = SIOCGIWFREQ; | 4110 | iwe.cmd = SIOCGIWFREQ; |
4102 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); | 4111 | iwe.u.freq.m = bss->freq; |
4103 | iwe.u.freq.e = 0; | 4112 | iwe.u.freq.e = 6; |
4104 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4113 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, |
4105 | IW_EV_FREQ_LEN); | 4114 | IW_EV_FREQ_LEN); |
4106 | |||
4107 | memset(&iwe, 0, sizeof(iwe)); | 4115 | memset(&iwe, 0, sizeof(iwe)); |
4108 | iwe.cmd = IWEVQUAL; | 4116 | iwe.cmd = IWEVQUAL; |
4109 | iwe.u.qual.qual = bss->signal; | 4117 | iwe.u.qual.qual = bss->signal; |