aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-01-24 13:38:38 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:19:32 -0500
commit8318d78a44d49ac1edf2bdec7299de3617c4232e (patch)
treed434634418edd7399737801615d247be06616fdd /net/mac80211/ieee80211.c
parent10b6b80145cc93887dd8aab99bfffa375e9add31 (diff)
cfg80211 API for channels/bitrates, mac80211 and driver conversion
This patch creates new cfg80211 wiphy API for channel and bitrate registration and converts mac80211 and drivers to the new API. The old mac80211 API is completely ripped out. All drivers (except ath5k) are updated to the new API, in many cases I expect that optimisations can be done. Along with the regulatory code I've also ripped out the IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED flag, I believe it to be unnecessary if the hardware simply gives us whatever channels it wants to support and we then enable/disable them as required, which is pretty much required for travelling. Additionally, the patch adds proper "basic" rate handling for STA mode interface, AP mode interface will have to have new API added to allow userspace to set the basic rate set, currently it'll be empty... However, the basic rate handling will need to be moved to the BSS conf stuff. I do expect there to be bugs in this, especially wrt. transmit power handling where I'm basically clueless about how it should work. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
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