aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/ieee80211.c')
-rw-r--r--net/mac80211/ieee80211.c112
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
877int ieee80211_hw_config(struct ieee80211_local *local) 877int 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}
1568EXPORT_SYMBOL(ieee80211_register_hw); 1576EXPORT_SYMBOL(ieee80211_register_hw);
1569 1577
1570int 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}
1601EXPORT_SYMBOL(ieee80211_register_hwmode);
1602
1603void ieee80211_unregister_hw(struct ieee80211_hw *hw) 1578void 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