diff options
Diffstat (limited to 'net/mac80211/ieee80211.c')
-rw-r--r-- | net/mac80211/ieee80211.c | 112 |
1 files changed, 40 insertions, 72 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 3961d4c4320c..de894b61a23c 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
@@ -876,37 +876,28 @@ int ieee80211_if_config_beacon(struct net_device *dev) | |||
876 | 876 | ||
877 | int ieee80211_hw_config(struct ieee80211_local *local) | 877 | int ieee80211_hw_config(struct ieee80211_local *local) |
878 | { | 878 | { |
879 | struct ieee80211_hw_mode *mode; | ||
880 | struct ieee80211_channel *chan; | 879 | struct ieee80211_channel *chan; |
881 | int ret = 0; | 880 | int ret = 0; |
882 | 881 | ||
883 | if (local->sta_sw_scanning) { | 882 | if (local->sta_sw_scanning) |
884 | chan = local->scan_channel; | 883 | chan = local->scan_channel; |
885 | mode = local->scan_hw_mode; | 884 | else |
886 | } else { | ||
887 | chan = local->oper_channel; | 885 | chan = local->oper_channel; |
888 | mode = local->oper_hw_mode; | ||
889 | } | ||
890 | 886 | ||
891 | local->hw.conf.channel = chan->chan; | 887 | local->hw.conf.channel = chan; |
892 | local->hw.conf.channel_val = chan->val; | 888 | |
893 | if (!local->hw.conf.power_level) { | 889 | if (!local->hw.conf.power_level) |
894 | local->hw.conf.power_level = chan->power_level; | 890 | local->hw.conf.power_level = chan->max_power; |
895 | } else { | 891 | else |
896 | local->hw.conf.power_level = min(chan->power_level, | 892 | local->hw.conf.power_level = min(chan->max_power, |
897 | local->hw.conf.power_level); | 893 | local->hw.conf.power_level); |
898 | } | 894 | |
899 | local->hw.conf.freq = chan->freq; | 895 | local->hw.conf.max_antenna_gain = chan->max_antenna_gain; |
900 | local->hw.conf.phymode = mode->mode; | ||
901 | local->hw.conf.antenna_max = chan->antenna_max; | ||
902 | local->hw.conf.chan = chan; | ||
903 | local->hw.conf.mode = mode; | ||
904 | 896 | ||
905 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 897 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
906 | printk(KERN_DEBUG "HW CONFIG: channel=%d freq=%d " | 898 | printk(KERN_DEBUG "%s: HW CONFIG: freq=%d\n", |
907 | "phymode=%d\n", local->hw.conf.channel, local->hw.conf.freq, | 899 | wiphy_name(local->hw.wiphy), chan->center_freq); |
908 | local->hw.conf.phymode); | 900 | #endif |
909 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | ||
910 | 901 | ||
911 | if (local->open_count) | 902 | if (local->open_count) |
912 | ret = local->ops->config(local_to_hw(local), &local->hw.conf); | 903 | ret = local->ops->config(local_to_hw(local), &local->hw.conf); |
@@ -924,11 +915,13 @@ int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, | |||
924 | struct ieee80211_ht_bss_info *req_bss_cap) | 915 | struct ieee80211_ht_bss_info *req_bss_cap) |
925 | { | 916 | { |
926 | struct ieee80211_conf *conf = &local->hw.conf; | 917 | struct ieee80211_conf *conf = &local->hw.conf; |
927 | struct ieee80211_hw_mode *mode = conf->mode; | 918 | struct ieee80211_supported_band *sband; |
928 | int i; | 919 | int i; |
929 | 920 | ||
921 | sband = local->hw.wiphy->bands[conf->channel->band]; | ||
922 | |||
930 | /* HT is not supported */ | 923 | /* HT is not supported */ |
931 | if (!mode->ht_info.ht_supported) { | 924 | if (!sband->ht_info.ht_supported) { |
932 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 925 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; |
933 | return -EOPNOTSUPP; | 926 | return -EOPNOTSUPP; |
934 | } | 927 | } |
@@ -938,17 +931,17 @@ int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, | |||
938 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 931 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; |
939 | } else { | 932 | } else { |
940 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; | 933 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; |
941 | conf->ht_conf.cap = req_ht_cap->cap & mode->ht_info.cap; | 934 | conf->ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; |
942 | conf->ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); | 935 | conf->ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); |
943 | conf->ht_conf.cap |= | 936 | conf->ht_conf.cap |= |
944 | mode->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; | 937 | sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; |
945 | conf->ht_bss_conf.primary_channel = | 938 | conf->ht_bss_conf.primary_channel = |
946 | req_bss_cap->primary_channel; | 939 | req_bss_cap->primary_channel; |
947 | conf->ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | 940 | conf->ht_bss_conf.bss_cap = req_bss_cap->bss_cap; |
948 | conf->ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | 941 | conf->ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; |
949 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) | 942 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) |
950 | conf->ht_conf.supp_mcs_set[i] = | 943 | conf->ht_conf.supp_mcs_set[i] = |
951 | mode->ht_info.supp_mcs_set[i] & | 944 | sband->ht_info.supp_mcs_set[i] & |
952 | req_ht_cap->supp_mcs_set[i]; | 945 | req_ht_cap->supp_mcs_set[i]; |
953 | 946 | ||
954 | /* In STA mode, this gives us indication | 947 | /* In STA mode, this gives us indication |
@@ -1418,10 +1411,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
1418 | local->long_retry_limit = 4; | 1411 | local->long_retry_limit = 4; |
1419 | local->hw.conf.radio_enabled = 1; | 1412 | local->hw.conf.radio_enabled = 1; |
1420 | 1413 | ||
1421 | local->enabled_modes = ~0; | ||
1422 | |||
1423 | INIT_LIST_HEAD(&local->modes_list); | ||
1424 | |||
1425 | INIT_LIST_HEAD(&local->interfaces); | 1414 | INIT_LIST_HEAD(&local->interfaces); |
1426 | 1415 | ||
1427 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work); | 1416 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work); |
@@ -1466,6 +1455,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1466 | struct ieee80211_local *local = hw_to_local(hw); | 1455 | struct ieee80211_local *local = hw_to_local(hw); |
1467 | const char *name; | 1456 | const char *name; |
1468 | int result; | 1457 | int result; |
1458 | enum ieee80211_band band; | ||
1459 | |||
1460 | /* | ||
1461 | * generic code guarantees at least one band, | ||
1462 | * set this very early because much code assumes | ||
1463 | * that hw.conf.channel is assigned | ||
1464 | */ | ||
1465 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
1466 | struct ieee80211_supported_band *sband; | ||
1467 | |||
1468 | sband = local->hw.wiphy->bands[band]; | ||
1469 | if (sband) { | ||
1470 | /* init channel we're on */ | ||
1471 | local->hw.conf.channel = | ||
1472 | local->oper_channel = | ||
1473 | local->scan_channel = &sband->channels[0]; | ||
1474 | break; | ||
1475 | } | ||
1476 | } | ||
1469 | 1477 | ||
1470 | result = wiphy_register(local->hw.wiphy); | 1478 | result = wiphy_register(local->hw.wiphy); |
1471 | if (result < 0) | 1479 | if (result < 0) |
@@ -1567,44 +1575,10 @@ fail_workqueue: | |||
1567 | } | 1575 | } |
1568 | EXPORT_SYMBOL(ieee80211_register_hw); | 1576 | EXPORT_SYMBOL(ieee80211_register_hw); |
1569 | 1577 | ||
1570 | int ieee80211_register_hwmode(struct ieee80211_hw *hw, | ||
1571 | struct ieee80211_hw_mode *mode) | ||
1572 | { | ||
1573 | struct ieee80211_local *local = hw_to_local(hw); | ||
1574 | struct ieee80211_rate *rate; | ||
1575 | int i; | ||
1576 | |||
1577 | INIT_LIST_HEAD(&mode->list); | ||
1578 | list_add_tail(&mode->list, &local->modes_list); | ||
1579 | |||
1580 | local->hw_modes |= (1 << mode->mode); | ||
1581 | for (i = 0; i < mode->num_rates; i++) { | ||
1582 | rate = &(mode->rates[i]); | ||
1583 | rate->rate_inv = CHAN_UTIL_RATE_LCM / rate->rate; | ||
1584 | } | ||
1585 | ieee80211_prepare_rates(local, mode); | ||
1586 | |||
1587 | if (!local->oper_hw_mode) { | ||
1588 | /* Default to this mode */ | ||
1589 | local->hw.conf.phymode = mode->mode; | ||
1590 | local->oper_hw_mode = local->scan_hw_mode = mode; | ||
1591 | local->oper_channel = local->scan_channel = &mode->channels[0]; | ||
1592 | local->hw.conf.mode = local->oper_hw_mode; | ||
1593 | local->hw.conf.chan = local->oper_channel; | ||
1594 | } | ||
1595 | |||
1596 | if (!(hw->flags & IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED)) | ||
1597 | ieee80211_set_default_regdomain(mode); | ||
1598 | |||
1599 | return 0; | ||
1600 | } | ||
1601 | EXPORT_SYMBOL(ieee80211_register_hwmode); | ||
1602 | |||
1603 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) | 1578 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) |
1604 | { | 1579 | { |
1605 | struct ieee80211_local *local = hw_to_local(hw); | 1580 | struct ieee80211_local *local = hw_to_local(hw); |
1606 | struct ieee80211_sub_if_data *sdata, *tmp; | 1581 | struct ieee80211_sub_if_data *sdata, *tmp; |
1607 | int i; | ||
1608 | 1582 | ||
1609 | tasklet_kill(&local->tx_pending_tasklet); | 1583 | tasklet_kill(&local->tx_pending_tasklet); |
1610 | tasklet_kill(&local->tasklet); | 1584 | tasklet_kill(&local->tasklet); |
@@ -1645,11 +1619,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1645 | rate_control_deinitialize(local); | 1619 | rate_control_deinitialize(local); |
1646 | debugfs_hw_del(local); | 1620 | debugfs_hw_del(local); |
1647 | 1621 | ||
1648 | for (i = 0; i < NUM_IEEE80211_MODES; i++) { | ||
1649 | kfree(local->supp_rates[i]); | ||
1650 | kfree(local->basic_rates[i]); | ||
1651 | } | ||
1652 | |||
1653 | if (skb_queue_len(&local->skb_queue) | 1622 | if (skb_queue_len(&local->skb_queue) |
1654 | || skb_queue_len(&local->skb_queue_unreliable)) | 1623 | || skb_queue_len(&local->skb_queue_unreliable)) |
1655 | printk(KERN_WARNING "%s: skb_queue not empty\n", | 1624 | printk(KERN_WARNING "%s: skb_queue not empty\n", |
@@ -1696,7 +1665,6 @@ static int __init ieee80211_init(void) | |||
1696 | } | 1665 | } |
1697 | 1666 | ||
1698 | ieee80211_debugfs_netdev_init(); | 1667 | ieee80211_debugfs_netdev_init(); |
1699 | ieee80211_regdomain_init(); | ||
1700 | 1668 | ||
1701 | return 0; | 1669 | return 0; |
1702 | 1670 | ||