| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2002-2005, Instant802 Networks, Inc. | 2 * Copyright 2002-2005, Instant802 Networks, Inc. |
| 3 * Copyright 2005-2006, Devicescape Software, Inc. | 3 * Copyright 2005-2006, Devicescape Software, Inc. |
| 4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | 4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> |
| 5 * Copyright 2008 Luis R. Rodriguez <lrodriguz@atheros.com> | 5 * Copyright 2008 Luis R. Rodriguez <lrodriguz@atheros.com> |
| 6 * | 6 * |
| 7 * This program is free software; you can redistribute it and/or modify | 7 * This program is free software; you can redistribute it and/or modify |
| 8 * it under the terms of the GNU General Public License version 2 as | 8 * it under the terms of the GNU General Public License version 2 as |
| 9 * published by the Free Software Foundation. | 9 * published by the Free Software Foundation. |
| 10 */ | 10 */ |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 | 716 |
| 717 /* | 717 /* |
| 718 * Note that right now we assume the desired channel bandwidth | 718 * Note that right now we assume the desired channel bandwidth |
| 719 * is always 20 MHz for each individual channel (HT40 uses 20 MHz | 719 * is always 20 MHz for each individual channel (HT40 uses 20 MHz |
| 720 * per channel, the primary and the extension channel). To support | 720 * per channel, the primary and the extension channel). To support |
| 721 * smaller custom bandwidths such as 5 MHz or 10 MHz we'll need a | 721 * smaller custom bandwidths such as 5 MHz or 10 MHz we'll need a |
| 722 * new ieee80211_channel.target_bw and re run the regulatory check | 722 * new ieee80211_channel.target_bw and re run the regulatory check |
| 723 * on the wiphy with the target_bw specified. Then we can simply use | 723 * on the wiphy with the target_bw specified. Then we can simply use |
| 724 * that below for the desired_bw_khz below. | 724 * that below for the desired_bw_khz below. |
| 725 */ | 725 */ |
| 726 static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, | 726 static void handle_channel(struct wiphy *wiphy, |
| 727 » » » enum nl80211_reg_initiator initiator, |
| 728 » » » enum ieee80211_band band, |
| 727 unsigned int chan_idx) | 729 unsigned int chan_idx) |
| 728 { | 730 { |
| 729 int r; | 731 int r; |
| 730 u32 flags, bw_flags = 0; | 732 u32 flags, bw_flags = 0; |
| 731 u32 desired_bw_khz = MHZ_TO_KHZ(20); | 733 u32 desired_bw_khz = MHZ_TO_KHZ(20); |
| 732 const struct ieee80211_reg_rule *reg_rule = NULL; | 734 const struct ieee80211_reg_rule *reg_rule = NULL; |
| 733 const struct ieee80211_power_rule *power_rule = NULL; | 735 const struct ieee80211_power_rule *power_rule = NULL; |
| 734 const struct ieee80211_freq_range *freq_range = NULL; | 736 const struct ieee80211_freq_range *freq_range = NULL; |
| 735 struct ieee80211_supported_band *sband; | 737 struct ieee80211_supported_band *sband; |
| 736 struct ieee80211_channel *chan; | 738 struct ieee80211_channel *chan; |
| 737 struct wiphy *request_wiphy = NULL; | 739 struct wiphy *request_wiphy = NULL; |
| 738 | 740 |
| 739 assert_cfg80211_lock(); | 741 assert_cfg80211_lock(); |
| 740 | 742 |
| 741 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); | 743 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); |
| 742 | 744 |
| 743 sband = wiphy->bands[band]; | 745 sband = wiphy->bands[band]; |
| 744 BUG_ON(chan_idx >= sband->n_channels); | 746 BUG_ON(chan_idx >= sband->n_channels); |
| 745 chan = &sband->channels[chan_idx]; | 747 chan = &sband->channels[chan_idx]; |
| 746 | 748 |
| 747 flags = chan->orig_flags; | 749 flags = chan->orig_flags; |
| 748 | 750 |
| 749 r = freq_reg_info(wiphy, | 751 r = freq_reg_info(wiphy, |
| 750 MHZ_TO_KHZ(chan->center_freq), | 752 MHZ_TO_KHZ(chan->center_freq), |
| 751 desired_bw_khz, | 753 desired_bw_khz, |
| 752 ®_rule); | 754 ®_rule); |
| 753 | 755 |
| 754 » if (r) | 756 » if (r) { |
| 757 » » /* |
| 758 » » * We will disable all channels that do not match our |
| 759 » » * recieved regulatory rule unless the hint is coming |
| 760 » » * from a Country IE and the Country IE had no information |
| 761 » » * about a band. The IEEE 802.11 spec allows for an AP |
| 762 » » * to send only a subset of the regulatory rules allowed, |
| 763 » » * so an AP in the US that only supports 2.4 GHz may only send |
| 764 » » * a country IE with information for the 2.4 GHz band |
| 765 » » * while 5 GHz is still supported. |
| 766 » » */ |
| 767 » » if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && |
| 768 » » r == -ERANGE) |
| 769 » » » return; |
| 770 |
| 771 » » REG_DBG_PRINT("cfg80211: Disabling freq %d MHz\n", |
| 772 » » » chan->center_freq); |
| 773 » » chan->flags = IEEE80211_CHAN_DISABLED; |
| 755 return; | 774 return; |
| 775 } |
| 756 | 776 |
| 757 power_rule = ®_rule->power_rule; | 777 power_rule = ®_rule->power_rule; |
| 758 freq_range = ®_rule->freq_range; | 778 freq_range = ®_rule->freq_range; |
| 759 | 779 |
| 760 if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(40)) | 780 if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(40)) |
| 761 bw_flags = IEEE80211_CHAN_NO_HT40; | 781 bw_flags = IEEE80211_CHAN_NO_HT40; |
| 762 | 782 |
| 763 if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER && | 783 if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER && |
| 764 request_wiphy && request_wiphy == wiphy && | 784 request_wiphy && request_wiphy == wiphy && |
| 765 request_wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) { | 785 request_wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 780 chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags); | 800 chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags); |
| 781 chan->max_antenna_gain = min(chan->orig_mag, | 801 chan->max_antenna_gain = min(chan->orig_mag, |
| 782 (int) MBI_TO_DBI(power_rule->max_antenna_gain)); | 802 (int) MBI_TO_DBI(power_rule->max_antenna_gain)); |
| 783 if (chan->orig_mpwr) | 803 if (chan->orig_mpwr) |
| 784 chan->max_power = min(chan->orig_mpwr, | 804 chan->max_power = min(chan->orig_mpwr, |
| 785 (int) MBM_TO_DBM(power_rule->max_eirp)); | 805 (int) MBM_TO_DBM(power_rule->max_eirp)); |
| 786 else | 806 else |
| 787 chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); | 807 chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); |
| 788 } | 808 } |
| 789 | 809 |
| 790 static void handle_band(struct wiphy *wiphy, enum ieee80211_band band) | 810 static void handle_band(struct wiphy *wiphy, |
| 811 » » » enum ieee80211_band band, |
| 812 » » » enum nl80211_reg_initiator initiator) |
| 791 { | 813 { |
| 792 unsigned int i; | 814 unsigned int i; |
| 793 struct ieee80211_supported_band *sband; | 815 struct ieee80211_supported_band *sband; |
| 794 | 816 |
| 795 BUG_ON(!wiphy->bands[band]); | 817 BUG_ON(!wiphy->bands[band]); |
| 796 sband = wiphy->bands[band]; | 818 sband = wiphy->bands[band]; |
| 797 | 819 |
| 798 for (i = 0; i < sband->n_channels; i++) | 820 for (i = 0; i < sband->n_channels; i++) |
| 799 » » handle_channel(wiphy, band, i); | 821 » » handle_channel(wiphy, initiator, band, i); |
| 800 } | 822 } |
| 801 | 823 |
| 802 static bool ignore_reg_update(struct wiphy *wiphy, | 824 static bool ignore_reg_update(struct wiphy *wiphy, |
| 803 enum nl80211_reg_initiator initiator) | 825 enum nl80211_reg_initiator initiator) |
| 804 { | 826 { |
| 805 if (!last_request) | 827 if (!last_request) |
| 806 return true; | 828 return true; |
| 807 if (initiator == NL80211_REGDOM_SET_BY_CORE && | 829 if (initiator == NL80211_REGDOM_SET_BY_CORE && |
| 808 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) | 830 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) |
| 809 return true; | 831 return true; |
| 810 /* | 832 /* |
| 811 * wiphy->regd will be set once the device has its own | 833 * wiphy->regd will be set once the device has its own |
| 812 * desired regulatory domain set | 834 * desired regulatory domain set |
| 813 */ | 835 */ |
| 814 if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd && | 836 if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd && |
| 837 initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && |
| 815 !is_world_regdom(last_request->alpha2)) | 838 !is_world_regdom(last_request->alpha2)) |
| 816 return true; | 839 return true; |
| 817 return false; | 840 return false; |
| 818 } | 841 } |
| 819 | 842 |
| 820 static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator) | 843 static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator) |
| 821 { | 844 { |
| 822 struct cfg80211_registered_device *rdev; | 845 struct cfg80211_registered_device *rdev; |
| 823 | 846 |
| 824 list_for_each_entry(rdev, &cfg80211_rdev_list, list) | 847 list_for_each_entry(rdev, &cfg80211_rdev_list, list) |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1026 | 1049 |
| 1027 void wiphy_update_regulatory(struct wiphy *wiphy, | 1050 void wiphy_update_regulatory(struct wiphy *wiphy, |
| 1028 enum nl80211_reg_initiator initiator) | 1051 enum nl80211_reg_initiator initiator) |
| 1029 { | 1052 { |
| 1030 enum ieee80211_band band; | 1053 enum ieee80211_band band; |
| 1031 | 1054 |
| 1032 if (ignore_reg_update(wiphy, initiator)) | 1055 if (ignore_reg_update(wiphy, initiator)) |
| 1033 goto out; | 1056 goto out; |
| 1034 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 1057 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
| 1035 if (wiphy->bands[band]) | 1058 if (wiphy->bands[band]) |
| 1036 » » » handle_band(wiphy, band); | 1059 » » » handle_band(wiphy, band, initiator); |
| 1037 } | 1060 } |
| 1038 out: | 1061 out: |
| 1039 reg_process_beacons(wiphy); | 1062 reg_process_beacons(wiphy); |
| 1040 reg_process_ht_flags(wiphy); | 1063 reg_process_ht_flags(wiphy); |
| 1041 if (wiphy->reg_notifier) | 1064 if (wiphy->reg_notifier) |
| 1042 wiphy->reg_notifier(wiphy, last_request); | 1065 wiphy->reg_notifier(wiphy, last_request); |
| 1043 } | 1066 } |
| 1044 | 1067 |
| 1045 static void handle_channel_custom(struct wiphy *wiphy, | 1068 static void handle_channel_custom(struct wiphy *wiphy, |
| 1046 enum ieee80211_band band, | 1069 enum ieee80211_band band, |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1163 return -EALREADY; | 1186 return -EALREADY; |
| 1164 } | 1187 } |
| 1165 /* | 1188 /* |
| 1166 * Two consecutive Country IE hints on the same wiphy. | 1189 * Two consecutive Country IE hints on the same wiphy. |
| 1167 * This should be picked up early by the driver/stack | 1190 * This should be picked up early by the driver/stack |
| 1168 */ | 1191 */ |
| 1169 if (WARN_ON(regdom_changes(pending_request->alpha2))) | 1192 if (WARN_ON(regdom_changes(pending_request->alpha2))) |
| 1170 return 0; | 1193 return 0; |
| 1171 return -EALREADY; | 1194 return -EALREADY; |
| 1172 } | 1195 } |
| 1173 » » return REG_INTERSECT; | 1196 » » return 0; |
| 1174 case NL80211_REGDOM_SET_BY_DRIVER: | 1197 case NL80211_REGDOM_SET_BY_DRIVER: |
| 1175 if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) { | 1198 if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) { |
| 1176 if (regdom_changes(pending_request->alpha2)) | 1199 if (regdom_changes(pending_request->alpha2)) |
| 1177 return 0; | 1200 return 0; |
| 1178 return -EALREADY; | 1201 return -EALREADY; |
| 1179 } | 1202 } |
| 1180 | 1203 |
| 1181 /* | 1204 /* |
| 1182 * This would happen if you unplug and plug your card | 1205 * This would happen if you unplug and plug your card |
| 1183 * back in or if you add a new device for which the previously | 1206 * back in or if you add a new device for which the previously |
| (...skipping 887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2071 ®_requests_list, list) { | 2094 ®_requests_list, list) { |
| 2072 list_del(®_request->list); | 2095 list_del(®_request->list); |
| 2073 kfree(reg_request); | 2096 kfree(reg_request); |
| 2074 } | 2097 } |
| 2075 } | 2098 } |
| 2076 spin_unlock(®_requests_lock); | 2099 spin_unlock(®_requests_lock); |
| 2077 | 2100 |
| 2078 mutex_unlock(®_mutex); | 2101 mutex_unlock(®_mutex); |
| 2079 mutex_unlock(&cfg80211_mutex); | 2102 mutex_unlock(&cfg80211_mutex); |
| 2080 } | 2103 } |
| OLD | NEW |