diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 87 |
1 files changed, 50 insertions, 37 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4adba09e80ca..b404537c0bcd 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) |
@@ -547,15 +547,14 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
547 | sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf; | 547 | sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf; |
548 | } | 548 | } |
549 | 549 | ||
550 | netif_carrier_on(dev); | ||
551 | ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; | 550 | ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; |
552 | memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); | 551 | memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); |
553 | memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN); | 552 | memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN); |
554 | ieee80211_sta_send_associnfo(dev, ifsta); | 553 | ieee80211_sta_send_associnfo(dev, ifsta); |
555 | } else { | 554 | } else { |
555 | netif_carrier_off(dev); | ||
556 | ieee80211_sta_tear_down_BA_sessions(dev, ifsta->bssid); | 556 | ieee80211_sta_tear_down_BA_sessions(dev, ifsta->bssid); |
557 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; | 557 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; |
558 | netif_carrier_off(dev); | ||
559 | ieee80211_reset_erp_info(dev); | 558 | ieee80211_reset_erp_info(dev); |
560 | 559 | ||
561 | sdata->bss_conf.assoc_ht = 0; | 560 | sdata->bss_conf.assoc_ht = 0; |
@@ -569,6 +568,10 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
569 | 568 | ||
570 | sdata->bss_conf.assoc = assoc; | 569 | sdata->bss_conf.assoc = assoc; |
571 | ieee80211_bss_info_change_notify(sdata, changed); | 570 | ieee80211_bss_info_change_notify(sdata, changed); |
571 | |||
572 | if (assoc) | ||
573 | netif_carrier_on(dev); | ||
574 | |||
572 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | 575 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; |
573 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); | 576 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); |
574 | } | 577 | } |
@@ -730,7 +733,17 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
730 | if (bss->wmm_ie) { | 733 | if (bss->wmm_ie) { |
731 | wmm = 1; | 734 | wmm = 1; |
732 | } | 735 | } |
736 | |||
737 | /* get all rates supported by the device and the AP as | ||
738 | * some APs don't like getting a superset of their rates | ||
739 | * in the association request (e.g. D-Link DAP 1353 in | ||
740 | * b-only mode) */ | ||
741 | rates_len = ieee80211_compatible_rates(bss, sband, &rates); | ||
742 | |||
733 | ieee80211_rx_bss_put(dev, bss); | 743 | ieee80211_rx_bss_put(dev, bss); |
744 | } else { | ||
745 | rates = ~0; | ||
746 | rates_len = sband->n_bitrates; | ||
734 | } | 747 | } |
735 | 748 | ||
736 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); | 749 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); |
@@ -761,10 +774,7 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
761 | *pos++ = ifsta->ssid_len; | 774 | *pos++ = ifsta->ssid_len; |
762 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); | 775 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); |
763 | 776 | ||
764 | /* all supported rates should be added here but some APs | 777 | /* 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; | 778 | supp_rates_len = rates_len; |
769 | if (supp_rates_len > 8) | 779 | if (supp_rates_len > 8) |
770 | supp_rates_len = 8; | 780 | supp_rates_len = 8; |
@@ -1318,7 +1328,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1318 | 1328 | ||
1319 | /* prepare reordering buffer */ | 1329 | /* prepare reordering buffer */ |
1320 | tid_agg_rx->reorder_buf = | 1330 | tid_agg_rx->reorder_buf = |
1321 | kmalloc(buf_size * sizeof(struct sk_buf *), GFP_ATOMIC); | 1331 | kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC); |
1322 | if (!tid_agg_rx->reorder_buf) { | 1332 | if (!tid_agg_rx->reorder_buf) { |
1323 | if (net_ratelimit()) | 1333 | if (net_ratelimit()) |
1324 | printk(KERN_ERR "can not allocate reordering buffer " | 1334 | printk(KERN_ERR "can not allocate reordering buffer " |
@@ -1327,7 +1337,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1327 | goto end; | 1337 | goto end; |
1328 | } | 1338 | } |
1329 | memset(tid_agg_rx->reorder_buf, 0, | 1339 | memset(tid_agg_rx->reorder_buf, 0, |
1330 | buf_size * sizeof(struct sk_buf *)); | 1340 | buf_size * sizeof(struct sk_buff *)); |
1331 | 1341 | ||
1332 | if (local->ops->ampdu_action) | 1342 | if (local->ops->ampdu_action) |
1333 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START, | 1343 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START, |
@@ -1607,7 +1617,7 @@ void sta_addba_resp_timer_expired(unsigned long data) | |||
1607 | * only one argument, and both sta_info and TID are needed, so init | 1617 | * 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 | 1618 | * flow in sta_info_create gives the TID as data, while the timer_to_id |
1609 | * array gives the sta through container_of */ | 1619 | * array gives the sta through container_of */ |
1610 | u16 tid = *(int *)data; | 1620 | u16 tid = *(u8 *)data; |
1611 | struct sta_info *temp_sta = container_of((void *)data, | 1621 | struct sta_info *temp_sta = container_of((void *)data, |
1612 | struct sta_info, timer_to_tid[tid]); | 1622 | struct sta_info, timer_to_tid[tid]); |
1613 | 1623 | ||
@@ -1655,7 +1665,7 @@ timer_expired_exit: | |||
1655 | void sta_rx_agg_session_timer_expired(unsigned long data) | 1665 | void sta_rx_agg_session_timer_expired(unsigned long data) |
1656 | { | 1666 | { |
1657 | /* not an elegant detour, but there is no choice as the timer passes | 1667 | /* 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 | 1668 | * 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 | 1669 | * flow in sta_info_create gives the TID as data, while the timer_to_id |
1660 | * array gives the sta through container_of */ | 1670 | * array gives the sta through container_of */ |
1661 | u8 *ptid = (u8 *)data; | 1671 | u8 *ptid = (u8 *)data; |
@@ -2329,6 +2339,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2329 | u8 *pos; | 2339 | u8 *pos; |
2330 | struct ieee80211_sub_if_data *sdata; | 2340 | struct ieee80211_sub_if_data *sdata; |
2331 | struct ieee80211_supported_band *sband; | 2341 | struct ieee80211_supported_band *sband; |
2342 | union iwreq_data wrqu; | ||
2332 | 2343 | ||
2333 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 2344 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
2334 | 2345 | ||
@@ -2351,13 +2362,10 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2351 | sdata->drop_unencrypted = bss->capability & | 2362 | sdata->drop_unencrypted = bss->capability & |
2352 | WLAN_CAPABILITY_PRIVACY ? 1 : 0; | 2363 | WLAN_CAPABILITY_PRIVACY ? 1 : 0; |
2353 | 2364 | ||
2354 | res = ieee80211_set_freq(local, bss->freq); | 2365 | res = ieee80211_set_freq(dev, bss->freq); |
2355 | 2366 | ||
2356 | if (local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) { | 2367 | if (res) |
2357 | printk(KERN_DEBUG "%s: IBSS not allowed on frequency " | 2368 | return res; |
2358 | "%d MHz\n", dev->name, local->oper_channel->center_freq); | ||
2359 | return -1; | ||
2360 | } | ||
2361 | 2369 | ||
2362 | /* Set beacon template */ | 2370 | /* Set beacon template */ |
2363 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | 2371 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); |
@@ -2472,7 +2480,9 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2472 | ifsta->state = IEEE80211_IBSS_JOINED; | 2480 | ifsta->state = IEEE80211_IBSS_JOINED; |
2473 | mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); | 2481 | mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); |
2474 | 2482 | ||
2475 | ieee80211_rx_bss_put(dev, bss); | 2483 | memset(&wrqu, 0, sizeof(wrqu)); |
2484 | memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN); | ||
2485 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); | ||
2476 | 2486 | ||
2477 | return res; | 2487 | return res; |
2478 | } | 2488 | } |
@@ -3446,21 +3456,17 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
3446 | struct ieee80211_sta_bss *bss, *selected = NULL; | 3456 | struct ieee80211_sta_bss *bss, *selected = NULL; |
3447 | int top_rssi = 0, freq; | 3457 | int top_rssi = 0, freq; |
3448 | 3458 | ||
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); | 3459 | spin_lock_bh(&local->sta_bss_lock); |
3457 | freq = local->oper_channel->center_freq; | 3460 | freq = local->oper_channel->center_freq; |
3458 | list_for_each_entry(bss, &local->sta_bss_list, list) { | 3461 | list_for_each_entry(bss, &local->sta_bss_list, list) { |
3459 | if (!(bss->capability & WLAN_CAPABILITY_ESS)) | 3462 | if (!(bss->capability & WLAN_CAPABILITY_ESS)) |
3460 | continue; | 3463 | continue; |
3461 | 3464 | ||
3462 | if (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^ | 3465 | if ((ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL | |
3463 | !!sdata->default_key) | 3466 | IEEE80211_STA_AUTO_BSSID_SEL | |
3467 | IEEE80211_STA_AUTO_CHANNEL_SEL)) && | ||
3468 | (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^ | ||
3469 | !!sdata->default_key)) | ||
3464 | continue; | 3470 | continue; |
3465 | 3471 | ||
3466 | if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) && | 3472 | if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) && |
@@ -3485,7 +3491,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
3485 | spin_unlock_bh(&local->sta_bss_lock); | 3491 | spin_unlock_bh(&local->sta_bss_lock); |
3486 | 3492 | ||
3487 | if (selected) { | 3493 | if (selected) { |
3488 | ieee80211_set_freq(local, selected->freq); | 3494 | ieee80211_set_freq(dev, selected->freq); |
3489 | if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) | 3495 | if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) |
3490 | ieee80211_sta_set_ssid(dev, selected->ssid, | 3496 | ieee80211_sta_set_ssid(dev, selected->ssid, |
3491 | selected->ssid_len); | 3497 | selected->ssid_len); |
@@ -3520,6 +3526,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
3520 | struct ieee80211_supported_band *sband; | 3526 | struct ieee80211_supported_band *sband; |
3521 | u8 bssid[ETH_ALEN], *pos; | 3527 | u8 bssid[ETH_ALEN], *pos; |
3522 | int i; | 3528 | int i; |
3529 | int ret; | ||
3523 | DECLARE_MAC_BUF(mac); | 3530 | DECLARE_MAC_BUF(mac); |
3524 | 3531 | ||
3525 | #if 0 | 3532 | #if 0 |
@@ -3564,7 +3571,9 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
3564 | *pos++ = (u8) (rate / 5); | 3571 | *pos++ = (u8) (rate / 5); |
3565 | } | 3572 | } |
3566 | 3573 | ||
3567 | return ieee80211_sta_join_ibss(dev, ifsta, bss); | 3574 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); |
3575 | ieee80211_rx_bss_put(dev, bss); | ||
3576 | return ret; | ||
3568 | } | 3577 | } |
3569 | 3578 | ||
3570 | 3579 | ||
@@ -3605,17 +3614,22 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
3605 | spin_unlock_bh(&local->sta_bss_lock); | 3614 | spin_unlock_bh(&local->sta_bss_lock); |
3606 | 3615 | ||
3607 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 3616 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
3608 | printk(KERN_DEBUG " sta_find_ibss: selected %s current " | 3617 | if (found) |
3609 | "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); | 3618 | printk(KERN_DEBUG " sta_find_ibss: selected %s current " |
3619 | "%s\n", print_mac(mac, bssid), | ||
3620 | print_mac(mac2, ifsta->bssid)); | ||
3610 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 3621 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
3611 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && | 3622 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && |
3612 | (bss = ieee80211_rx_bss_get(dev, bssid, | 3623 | (bss = ieee80211_rx_bss_get(dev, bssid, |
3613 | local->hw.conf.channel->center_freq, | 3624 | local->hw.conf.channel->center_freq, |
3614 | ifsta->ssid, ifsta->ssid_len))) { | 3625 | ifsta->ssid, ifsta->ssid_len))) { |
3626 | int ret; | ||
3615 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" | 3627 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" |
3616 | " based on configured SSID\n", | 3628 | " based on configured SSID\n", |
3617 | dev->name, print_mac(mac, bssid)); | 3629 | dev->name, print_mac(mac, bssid)); |
3618 | return ieee80211_sta_join_ibss(dev, ifsta, bss); | 3630 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); |
3631 | ieee80211_rx_bss_put(dev, bss); | ||
3632 | return ret; | ||
3619 | } | 3633 | } |
3620 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 3634 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
3621 | printk(KERN_DEBUG " did not try to join ibss\n"); | 3635 | printk(KERN_DEBUG " did not try to join ibss\n"); |
@@ -4092,18 +4106,17 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4092 | 4106 | ||
4093 | memset(&iwe, 0, sizeof(iwe)); | 4107 | memset(&iwe, 0, sizeof(iwe)); |
4094 | iwe.cmd = SIOCGIWFREQ; | 4108 | iwe.cmd = SIOCGIWFREQ; |
4095 | iwe.u.freq.m = bss->freq; | 4109 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); |
4096 | iwe.u.freq.e = 6; | 4110 | iwe.u.freq.e = 0; |
4097 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4111 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, |
4098 | IW_EV_FREQ_LEN); | 4112 | IW_EV_FREQ_LEN); |
4099 | 4113 | ||
4100 | memset(&iwe, 0, sizeof(iwe)); | 4114 | memset(&iwe, 0, sizeof(iwe)); |
4101 | iwe.cmd = SIOCGIWFREQ; | 4115 | iwe.cmd = SIOCGIWFREQ; |
4102 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); | 4116 | iwe.u.freq.m = bss->freq; |
4103 | iwe.u.freq.e = 0; | 4117 | iwe.u.freq.e = 6; |
4104 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4118 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, |
4105 | IW_EV_FREQ_LEN); | 4119 | IW_EV_FREQ_LEN); |
4106 | |||
4107 | memset(&iwe, 0, sizeof(iwe)); | 4120 | memset(&iwe, 0, sizeof(iwe)); |
4108 | iwe.cmd = IWEVQUAL; | 4121 | iwe.cmd = IWEVQUAL; |
4109 | iwe.u.qual.qual = bss->signal; | 4122 | iwe.u.qual.qual = bss->signal; |