| @@ -563,9 +563,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd, · 562 unmodified lines |
| 563 | 563 | if (freq_range_tmp->end_freq_khz < freq_range->start_freq_khz) |
| 564 | 564 | break; |
| 565 | 565 | |
| 566 | | − if (freq_range_tmp->max_bandwidth_khz) |
| 567 | | − break; |
| 568 | | − |
| 569 | 566 | freq_range = freq_range_tmp; |
| 570 | 567 | } |
| 571 | 568 | |
| @@ -582,9 +579,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd, · 10 unmodified lines |
| 582 | 579 | if (freq_range_tmp->start_freq_khz > freq_range->end_freq_khz) |
| 583 | 580 | break; |
| 584 | 581 | |
| 585 | | − if (freq_range_tmp->max_bandwidth_khz) |
| 586 | | − break; |
| 587 | | − |
| 588 | 582 | freq_range = freq_range_tmp; |
| 589 | 583 | } |
| 590 | 584 | |
| @@ -729,21 +723,29 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, · 138 unmodified lines |
| 729 | 723 | max_bandwidth1 = freq_range1->max_bandwidth_khz; |
| 730 | 724 | max_bandwidth2 = freq_range2->max_bandwidth_khz; |
| 731 | 725 | |
| 732 | | − /* |
| 733 | | − * In case max_bandwidth1 == 0 and max_bandwith2 == 0 set |
| 734 | | − * output bandwidth as 0 (auto calculation). Next we will |
| 735 | | − * calculate this correctly in handle_channel function. |
| 736 | | − * In other case calculate output bandwidth here. |
| 737 | | − */ |
| 738 | | − if (max_bandwidth1 || max_bandwidth2) { |
| 739 | | − if (!max_bandwidth1) |
| 740 | | − max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1); |
| 741 | | − if (!max_bandwidth2) |
| 742 | | − max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2); |
| 743 | | − } |
| 726 | + if (rule1->flags & NL80211_RRF_AUTO_BW) |
| 727 | + max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1); |
| 728 | + if (rule2->flags & NL80211_RRF_AUTO_BW) |
| 729 | + max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2); |
| 744 | 730 | |
| 745 | 731 | freq_range->max_bandwidth_khz = min(max_bandwidth1, max_bandwidth2); |
| 746 | 732 | |
| 733 | + intersected_rule->flags = rule1->flags | rule2->flags; |
| 734 | + |
| 735 | + /* |
| 736 | + * In case NL80211_RRF_AUTO_BW requested for both rules |
| 737 | + * set AUTO_BW in intersected rule also. Next we will |
| 738 | + * calculate BW correctly in handle_channel function. |
| 739 | + * In other case remove AUTO_BW flag while we calculate |
| 740 | + * maximum bandwidth correctly and auto calculation is |
| 741 | + * not required. |
| 742 | + */ |
| 743 | + if ((rule1->flags & NL80211_RRF_AUTO_BW) && |
| 744 | + (rule2->flags & NL80211_RRF_AUTO_BW)) |
| 745 | + intersected_rule->flags |= NL80211_RRF_AUTO_BW; |
| 746 | + else |
| 747 | + intersected_rule->flags &= ~NL80211_RRF_AUTO_BW; |
| 748 | + |
| 747 | 749 | freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz; |
| 748 | 750 | if (freq_range->max_bandwidth_khz > freq_diff) |
| 749 | 751 | freq_range->max_bandwidth_khz = freq_diff; |
| @@ -753,8 +755,6 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, · 3 unmodified lines |
| 753 | 755 | power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain, |
| 754 | 756 | power_rule2->max_antenna_gain); |
| 755 | 757 | |
| 756 | | − intersected_rule->flags = rule1->flags | rule2->flags; |
| 757 | | − |
| 758 | 758 | if (!is_valid_reg_rule(intersected_rule)) |
| 759 | 759 | return -EINVAL; |
| 760 | 760 | |
| @@ -938,31 +938,42 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator) · 177 unmodified lines |
| 938 | 938 | EXPORT_SYMBOL(reg_initiator_name); |
| 939 | 939 | |
| 940 | 940 | #ifdef CONFIG_CFG80211_REG_DEBUG |
| 941 | | −static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, |
| 941 | +static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd, |
| 942 | + struct ieee80211_channel *chan, |
| 942 | 943 | const struct ieee80211_reg_rule *reg_rule) |
| 943 | 944 | { |
| 944 | 945 | const struct ieee80211_power_rule *power_rule; |
| 945 | 946 | const struct ieee80211_freq_range *freq_range; |
| 946 | | − char max_antenna_gain[32]; |
| 947 | + char max_antenna_gain[32], bw[32]; |
| 947 | 948 | |
| 948 | 949 | power_rule = ®_rule->power_rule; |
| 949 | 950 | freq_range = ®_rule->freq_range; |
| 950 | 951 | |
| 951 | 952 | if (!power_rule->max_antenna_gain) |
| 952 | | − snprintf(max_antenna_gain, 32, "N/A"); |
| 953 | + snprintf(max_antenna_gain, sizeof(max_antenna_gain), "N/A"); |
| 953 | 954 | else |
| 954 | | − snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain); |
| 955 | + snprintf(max_antenna_gain, sizeof(max_antenna_gain), "%d", |
| 956 | + power_rule->max_antenna_gain); |
| 957 | + |
| 958 | + if (reg_rule->flags & NL80211_RRF_AUTO_BW) |
| 959 | + snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO", |
| 960 | + freq_range->max_bandwidth_khz, |
| 961 | + reg_get_max_bandwidth(regd, reg_rule)); |
| 962 | + else |
| 963 | + snprintf(bw, sizeof(bw), "%d KHz", |
| 964 | + freq_range->max_bandwidth_khz); |
| 955 | 965 | |
| 956 | 966 | REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n", |
| 957 | 967 | chan->center_freq); |
| 958 | 968 | |
| 959 | | − REG_DBG_PRINT("%d KHz - %d KHz @ %d KHz), (%s mBi, %d mBm)\n", |
| 969 | + REG_DBG_PRINT("%d KHz - %d KHz @ %s), (%s mBi, %d mBm)\n", |
| 960 | 970 | freq_range->start_freq_khz, freq_range->end_freq_khz, |
| 961 | | − freq_range->max_bandwidth_khz, max_antenna_gain, |
| 971 | + bw, max_antenna_gain, |
| 962 | 972 | power_rule->max_eirp); |
| 963 | 973 | } |
| 964 | 974 | #else |
| 965 | | −static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, |
| 975 | +static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd, |
| 976 | + struct ieee80211_channel *chan, |
| 966 | 977 | const struct ieee80211_reg_rule *reg_rule) |
| 967 | 978 | { |
| 968 | 979 | return; |
| @@ -1022,17 +1033,16 @@ static void handle_channel(struct wiphy *wiphy, · 53 unmodified lines |
| 1022 | 1033 | return; |
| 1023 | 1034 | } |
| 1024 | 1035 | |
| 1025 | | − chan_reg_rule_print_dbg(chan, reg_rule); |
| 1036 | + regd = reg_get_regdomain(wiphy); |
| 1037 | + chan_reg_rule_print_dbg(regd, chan, reg_rule); |
| 1026 | 1038 | |
| 1027 | 1039 | power_rule = ®_rule->power_rule; |
| 1028 | 1040 | freq_range = ®_rule->freq_range; |
| 1029 | 1041 | |
| 1030 | 1042 | max_bandwidth_khz = freq_range->max_bandwidth_khz; |
| 1031 | 1043 | /* Check if auto calculation requested */ |
| 1032 | | − if (!max_bandwidth_khz) { |
| 1033 | | − regd = reg_get_regdomain(wiphy); |
| 1044 | + if (reg_rule->flags & NL80211_RRF_AUTO_BW) |
| 1034 | 1045 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); |
| 1035 | | − } |
| 1036 | 1046 | |
| 1037 | 1047 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) |
| 1038 | 1048 | bw_flags = IEEE80211_CHAN_NO_HT40; |
| @@ -1437,14 +1447,14 @@ static void handle_channel_custom(struct wiphy *wiphy, · 398 unmodified lines |
| 1437 | 1447 | return; |
| 1438 | 1448 | } |
| 1439 | 1449 | |
| 1440 | | − chan_reg_rule_print_dbg(chan, reg_rule); |
| 1450 | + chan_reg_rule_print_dbg(regd, chan, reg_rule); |
| 1441 | 1451 | |
| 1442 | 1452 | power_rule = ®_rule->power_rule; |
| 1443 | 1453 | freq_range = ®_rule->freq_range; |
| 1444 | 1454 | |
| 1445 | 1455 | max_bandwidth_khz = freq_range->max_bandwidth_khz; |
| 1446 | 1456 | /* Check if auto calculation requested */ |
| 1447 | | − if (!max_bandwidth_khz) |
| 1457 | + if (reg_rule->flags & NL80211_RRF_AUTO_BW) |
| 1448 | 1458 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); |
| 1449 | 1459 | |
| 1450 | 1460 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) |
| @@ -2254,11 +2264,12 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd) · 803 unmodified lines |
| 2254 | 2264 | freq_range = ®_rule->freq_range; |
| 2255 | 2265 | power_rule = ®_rule->power_rule; |
| 2256 | 2266 | |
| 2257 | | − if (!freq_range->max_bandwidth_khz) |
| 2258 | | − snprintf(bw, 32, "%d KHz, AUTO", |
| 2267 | + if (reg_rule->flags & NL80211_RRF_AUTO_BW) |
| 2268 | + snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO", |
| 2269 | + freq_range->max_bandwidth_khz, |
| 2259 | 2270 | reg_get_max_bandwidth(rd, reg_rule)); |
| 2260 | 2271 | else |
| 2261 | | − snprintf(bw, 32, "%d KHz", |
| 2272 | + snprintf(bw, sizeof(bw), "%d KHz", |
| 2262 | 2273 | freq_range->max_bandwidth_khz); |
| 2263 | 2274 | |
| 2264 | 2275 | /* |