hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
kernel/net/wireless/reg.c
....@@ -5,7 +5,7 @@
55 * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
66 * Copyright 2013-2014 Intel Mobile Communications GmbH
77 * Copyright 2017 Intel Deutschland GmbH
8
- * Copyright (C) 2018 Intel Corporation
8
+ * Copyright (C) 2018 - 2019 Intel Corporation
99 *
1010 * Permission to use, copy, modify, and/or distribute this software for any
1111 * purpose with or without fee is hereby granted, provided that the above
....@@ -131,7 +131,8 @@
131131 /* Used to track the userspace process controlling the indoor setting */
132132 static u32 reg_is_indoor_portid;
133133
134
-static void restore_regulatory_settings(bool reset_user);
134
+static void restore_regulatory_settings(bool reset_user, bool cached);
135
+static void print_regdomain(const struct ieee80211_regdomain *rd);
135136
136137 static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
137138 {
....@@ -263,6 +264,7 @@
263264
264265 static char *ieee80211_regdom = "00";
265266 static char user_alpha2[2];
267
+static const struct ieee80211_regdomain *cfg80211_user_regdom;
266268
267269 module_param(ieee80211_regdom, charp, 0444);
268270 MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
....@@ -425,14 +427,10 @@
425427 reg_copy_regd(const struct ieee80211_regdomain *src_regd)
426428 {
427429 struct ieee80211_regdomain *regd;
428
- int size_of_regd;
429430 unsigned int i;
430431
431
- size_of_regd =
432
- sizeof(struct ieee80211_regdomain) +
433
- src_regd->n_reg_rules * sizeof(struct ieee80211_reg_rule);
434
-
435
- regd = kzalloc(size_of_regd, GFP_KERNEL);
432
+ regd = kzalloc(struct_size(regd, reg_rules, src_regd->n_reg_rules),
433
+ GFP_KERNEL);
436434 if (!regd)
437435 return ERR_PTR(-ENOMEM);
438436
....@@ -443,6 +441,15 @@
443441 sizeof(struct ieee80211_reg_rule));
444442
445443 return regd;
444
+}
445
+
446
+static void cfg80211_save_user_regdom(const struct ieee80211_regdomain *rd)
447
+{
448
+ ASSERT_RTNL();
449
+
450
+ if (!IS_ERR(cfg80211_user_regdom))
451
+ kfree(cfg80211_user_regdom);
452
+ cfg80211_user_regdom = reg_copy_regd(rd);
446453 }
447454
448455 struct reg_regdb_apply_request {
....@@ -510,7 +517,7 @@
510517 pr_debug("Timeout while waiting for CRDA to reply, restoring regulatory settings\n");
511518 rtnl_lock();
512519 reg_crda_timeouts++;
513
- restore_regulatory_settings(true);
520
+ restore_regulatory_settings(true, false);
514521 rtnl_unlock();
515522 }
516523
....@@ -780,6 +787,8 @@
780787 return 0;
781788 }
782789
790
+MODULE_FIRMWARE("regulatory.db.p7s");
791
+
783792 static bool regdb_has_valid_signature(const u8 *data, unsigned int size)
784793 {
785794 const struct firmware *sig;
....@@ -937,12 +946,10 @@
937946 unsigned int ptr = be16_to_cpu(country->coll_ptr) << 2;
938947 struct fwdb_collection *coll = (void *)((u8 *)db + ptr);
939948 struct ieee80211_regdomain *regdom;
940
- unsigned int size_of_regd, i;
949
+ unsigned int i;
941950
942
- size_of_regd = sizeof(struct ieee80211_regdomain) +
943
- coll->n_rules * sizeof(struct ieee80211_reg_rule);
944
-
945
- regdom = kzalloc(size_of_regd, GFP_KERNEL);
951
+ regdom = kzalloc(struct_size(regdom, reg_rules, coll->n_rules),
952
+ GFP_KERNEL);
946953 if (!regdom)
947954 return -ENOMEM;
948955
....@@ -1024,8 +1031,13 @@
10241031 }
10251032
10261033 rtnl_lock();
1027
- if (WARN_ON(regdb && !IS_ERR(regdb))) {
1028
- /* just restore and free new db */
1034
+ if (regdb && !IS_ERR(regdb)) {
1035
+ /* negative case - a bug
1036
+ * positive case - can happen due to race in case of multiple cb's in
1037
+ * queue, due to usage of asynchronous callback
1038
+ *
1039
+ * Either case, just restore and free new db.
1040
+ */
10291041 } else if (set_error) {
10301042 regdb = ERR_PTR(set_error);
10311043 } else if (fw) {
....@@ -1039,7 +1051,7 @@
10391051 }
10401052
10411053 if (restore)
1042
- restore_regulatory_settings(true);
1054
+ restore_regulatory_settings(true, false);
10431055
10441056 rtnl_unlock();
10451057
....@@ -1048,8 +1060,12 @@
10481060 release_firmware(fw);
10491061 }
10501062
1063
+MODULE_FIRMWARE("regulatory.db");
1064
+
10511065 static int query_regdb_file(const char *alpha2)
10521066 {
1067
+ int err;
1068
+
10531069 ASSERT_RTNL();
10541070
10551071 if (regdb)
....@@ -1059,9 +1075,13 @@
10591075 if (!alpha2)
10601076 return -ENOMEM;
10611077
1062
- return request_firmware_nowait(THIS_MODULE, true, "regulatory.db",
1063
- &reg_pdev->dev, GFP_KERNEL,
1064
- (void *)alpha2, regdb_fw_cb);
1078
+ err = request_firmware_nowait(THIS_MODULE, true, "regulatory.db",
1079
+ &reg_pdev->dev, GFP_KERNEL,
1080
+ (void *)alpha2, regdb_fw_cb);
1081
+ if (err)
1082
+ kfree(alpha2);
1083
+
1084
+ return err;
10651085 }
10661086
10671087 int reg_reload_regdb(void)
....@@ -1473,7 +1493,7 @@
14731493 regdom_intersect(const struct ieee80211_regdomain *rd1,
14741494 const struct ieee80211_regdomain *rd2)
14751495 {
1476
- int r, size_of_regd;
1496
+ int r;
14771497 unsigned int x, y;
14781498 unsigned int num_rules = 0;
14791499 const struct ieee80211_reg_rule *rule1, *rule2;
....@@ -1504,10 +1524,7 @@
15041524 if (!num_rules)
15051525 return NULL;
15061526
1507
- size_of_regd = sizeof(struct ieee80211_regdomain) +
1508
- num_rules * sizeof(struct ieee80211_reg_rule);
1509
-
1510
- rd = kzalloc(size_of_regd, GFP_KERNEL);
1527
+ rd = kzalloc(struct_size(rd, reg_rules, num_rules), GFP_KERNEL);
15111528 if (!rd)
15121529 return NULL;
15131530
....@@ -1562,6 +1579,8 @@
15621579 channel_flags |= IEEE80211_CHAN_NO_80MHZ;
15631580 if (rd_flags & NL80211_RRF_NO_160MHZ)
15641581 channel_flags |= IEEE80211_CHAN_NO_160MHZ;
1582
+ if (rd_flags & NL80211_RRF_NO_HE)
1583
+ channel_flags |= IEEE80211_CHAN_NO_HE;
15651584 return channel_flags;
15661585 }
15671586
....@@ -1585,7 +1604,7 @@
15851604
15861605 /*
15871606 * We only need to know if one frequency rule was
1588
- * was in center_freq's band, that's enough, so lets
1607
+ * in center_freq's band, that's enough, so let's
15891608 * not overwrite it once found
15901609 */
15911610 if (!band_rule_found)
....@@ -1607,10 +1626,12 @@
16071626 __freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 min_bw)
16081627 {
16091628 const struct ieee80211_regdomain *regd = reg_get_regdomain(wiphy);
1610
- const struct ieee80211_reg_rule *reg_rule = NULL;
1629
+ const u32 bws[] = {0, 1, 2, 4, 5, 8, 10, 16, 20};
1630
+ const struct ieee80211_reg_rule *reg_rule;
1631
+ int i = ARRAY_SIZE(bws) - 1;
16111632 u32 bw;
16121633
1613
- for (bw = MHZ_TO_KHZ(20); bw >= min_bw; bw = bw / 2) {
1634
+ for (bw = MHZ_TO_KHZ(bws[i]); bw >= min_bw; bw = MHZ_TO_KHZ(bws[i--])) {
16141635 reg_rule = freq_reg_info_regd(center_freq, regd, bw);
16151636 if (!IS_ERR(reg_rule))
16161637 return reg_rule;
....@@ -1622,7 +1643,9 @@
16221643 const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy,
16231644 u32 center_freq)
16241645 {
1625
- return __freq_reg_info(wiphy, center_freq, MHZ_TO_KHZ(20));
1646
+ u32 min_bw = center_freq < MHZ_TO_KHZ(1000) ? 1 : 20;
1647
+
1648
+ return __freq_reg_info(wiphy, center_freq, MHZ_TO_KHZ(min_bw));
16261649 }
16271650 EXPORT_SYMBOL(freq_reg_info);
16281651
....@@ -1649,88 +1672,92 @@
16491672 const struct ieee80211_channel *chan)
16501673 {
16511674 const struct ieee80211_freq_range *freq_range = NULL;
1652
- u32 max_bandwidth_khz, bw_flags = 0;
1675
+ u32 max_bandwidth_khz, center_freq_khz, bw_flags = 0;
1676
+ bool is_s1g = chan->band == NL80211_BAND_S1GHZ;
16531677
16541678 freq_range = &reg_rule->freq_range;
16551679
16561680 max_bandwidth_khz = freq_range->max_bandwidth_khz;
1681
+ center_freq_khz = ieee80211_channel_to_khz(chan);
16571682 /* Check if auto calculation requested */
16581683 if (reg_rule->flags & NL80211_RRF_AUTO_BW)
16591684 max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
16601685
16611686 /* If we get a reg_rule we can assume that at least 5Mhz fit */
16621687 if (!cfg80211_does_bw_fit_range(freq_range,
1663
- MHZ_TO_KHZ(chan->center_freq),
1688
+ center_freq_khz,
16641689 MHZ_TO_KHZ(10)))
16651690 bw_flags |= IEEE80211_CHAN_NO_10MHZ;
16661691 if (!cfg80211_does_bw_fit_range(freq_range,
1667
- MHZ_TO_KHZ(chan->center_freq),
1692
+ center_freq_khz,
16681693 MHZ_TO_KHZ(20)))
16691694 bw_flags |= IEEE80211_CHAN_NO_20MHZ;
16701695
1671
- if (max_bandwidth_khz < MHZ_TO_KHZ(10))
1672
- bw_flags |= IEEE80211_CHAN_NO_10MHZ;
1673
- if (max_bandwidth_khz < MHZ_TO_KHZ(20))
1674
- bw_flags |= IEEE80211_CHAN_NO_20MHZ;
1675
- if (max_bandwidth_khz < MHZ_TO_KHZ(40))
1676
- bw_flags |= IEEE80211_CHAN_NO_HT40;
1677
- if (max_bandwidth_khz < MHZ_TO_KHZ(80))
1678
- bw_flags |= IEEE80211_CHAN_NO_80MHZ;
1679
- if (max_bandwidth_khz < MHZ_TO_KHZ(160))
1680
- bw_flags |= IEEE80211_CHAN_NO_160MHZ;
1696
+ if (is_s1g) {
1697
+ /* S1G is strict about non overlapping channels. We can
1698
+ * calculate which bandwidth is allowed per channel by finding
1699
+ * the largest bandwidth which cleanly divides the freq_range.
1700
+ */
1701
+ int edge_offset;
1702
+ int ch_bw = max_bandwidth_khz;
1703
+
1704
+ while (ch_bw) {
1705
+ edge_offset = (center_freq_khz - ch_bw / 2) -
1706
+ freq_range->start_freq_khz;
1707
+ if (edge_offset % ch_bw == 0) {
1708
+ switch (KHZ_TO_MHZ(ch_bw)) {
1709
+ case 1:
1710
+ bw_flags |= IEEE80211_CHAN_1MHZ;
1711
+ break;
1712
+ case 2:
1713
+ bw_flags |= IEEE80211_CHAN_2MHZ;
1714
+ break;
1715
+ case 4:
1716
+ bw_flags |= IEEE80211_CHAN_4MHZ;
1717
+ break;
1718
+ case 8:
1719
+ bw_flags |= IEEE80211_CHAN_8MHZ;
1720
+ break;
1721
+ case 16:
1722
+ bw_flags |= IEEE80211_CHAN_16MHZ;
1723
+ break;
1724
+ default:
1725
+ /* If we got here, no bandwidths fit on
1726
+ * this frequency, ie. band edge.
1727
+ */
1728
+ bw_flags |= IEEE80211_CHAN_DISABLED;
1729
+ break;
1730
+ }
1731
+ break;
1732
+ }
1733
+ ch_bw /= 2;
1734
+ }
1735
+ } else {
1736
+ if (max_bandwidth_khz < MHZ_TO_KHZ(10))
1737
+ bw_flags |= IEEE80211_CHAN_NO_10MHZ;
1738
+ if (max_bandwidth_khz < MHZ_TO_KHZ(20))
1739
+ bw_flags |= IEEE80211_CHAN_NO_20MHZ;
1740
+ if (max_bandwidth_khz < MHZ_TO_KHZ(40))
1741
+ bw_flags |= IEEE80211_CHAN_NO_HT40;
1742
+ if (max_bandwidth_khz < MHZ_TO_KHZ(80))
1743
+ bw_flags |= IEEE80211_CHAN_NO_80MHZ;
1744
+ if (max_bandwidth_khz < MHZ_TO_KHZ(160))
1745
+ bw_flags |= IEEE80211_CHAN_NO_160MHZ;
1746
+ }
16811747 return bw_flags;
16821748 }
16831749
1684
-/*
1685
- * Note that right now we assume the desired channel bandwidth
1686
- * is always 20 MHz for each individual channel (HT40 uses 20 MHz
1687
- * per channel, the primary and the extension channel).
1688
- */
1689
-static void handle_channel(struct wiphy *wiphy,
1690
- enum nl80211_reg_initiator initiator,
1691
- struct ieee80211_channel *chan)
1750
+static void handle_channel_single_rule(struct wiphy *wiphy,
1751
+ enum nl80211_reg_initiator initiator,
1752
+ struct ieee80211_channel *chan,
1753
+ u32 flags,
1754
+ struct regulatory_request *lr,
1755
+ struct wiphy *request_wiphy,
1756
+ const struct ieee80211_reg_rule *reg_rule)
16921757 {
1693
- u32 flags, bw_flags = 0;
1694
- const struct ieee80211_reg_rule *reg_rule = NULL;
1758
+ u32 bw_flags = 0;
16951759 const struct ieee80211_power_rule *power_rule = NULL;
1696
- struct wiphy *request_wiphy = NULL;
1697
- struct regulatory_request *lr = get_last_request();
16981760 const struct ieee80211_regdomain *regd;
1699
-
1700
- request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx);
1701
-
1702
- flags = chan->orig_flags;
1703
-
1704
- reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
1705
- if (IS_ERR(reg_rule)) {
1706
- /*
1707
- * We will disable all channels that do not match our
1708
- * received regulatory rule unless the hint is coming
1709
- * from a Country IE and the Country IE had no information
1710
- * about a band. The IEEE 802.11 spec allows for an AP
1711
- * to send only a subset of the regulatory rules allowed,
1712
- * so an AP in the US that only supports 2.4 GHz may only send
1713
- * a country IE with information for the 2.4 GHz band
1714
- * while 5 GHz is still supported.
1715
- */
1716
- if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
1717
- PTR_ERR(reg_rule) == -ERANGE)
1718
- return;
1719
-
1720
- if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
1721
- request_wiphy && request_wiphy == wiphy &&
1722
- request_wiphy->regulatory_flags & REGULATORY_STRICT_REG) {
1723
- pr_debug("Disabling freq %d MHz for good\n",
1724
- chan->center_freq);
1725
- chan->orig_flags |= IEEE80211_CHAN_DISABLED;
1726
- chan->flags = chan->orig_flags;
1727
- } else {
1728
- pr_debug("Disabling freq %d MHz\n",
1729
- chan->center_freq);
1730
- chan->flags |= IEEE80211_CHAN_DISABLED;
1731
- }
1732
- return;
1733
- }
17341761
17351762 regd = reg_get_regdomain(wiphy);
17361763
....@@ -1791,6 +1818,204 @@
17911818 chan->max_reg_power);
17921819 } else
17931820 chan->max_power = chan->max_reg_power;
1821
+}
1822
+
1823
+static void handle_channel_adjacent_rules(struct wiphy *wiphy,
1824
+ enum nl80211_reg_initiator initiator,
1825
+ struct ieee80211_channel *chan,
1826
+ u32 flags,
1827
+ struct regulatory_request *lr,
1828
+ struct wiphy *request_wiphy,
1829
+ const struct ieee80211_reg_rule *rrule1,
1830
+ const struct ieee80211_reg_rule *rrule2,
1831
+ struct ieee80211_freq_range *comb_range)
1832
+{
1833
+ u32 bw_flags1 = 0;
1834
+ u32 bw_flags2 = 0;
1835
+ const struct ieee80211_power_rule *power_rule1 = NULL;
1836
+ const struct ieee80211_power_rule *power_rule2 = NULL;
1837
+ const struct ieee80211_regdomain *regd;
1838
+
1839
+ regd = reg_get_regdomain(wiphy);
1840
+
1841
+ power_rule1 = &rrule1->power_rule;
1842
+ power_rule2 = &rrule2->power_rule;
1843
+ bw_flags1 = reg_rule_to_chan_bw_flags(regd, rrule1, chan);
1844
+ bw_flags2 = reg_rule_to_chan_bw_flags(regd, rrule2, chan);
1845
+
1846
+ if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
1847
+ request_wiphy && request_wiphy == wiphy &&
1848
+ request_wiphy->regulatory_flags & REGULATORY_STRICT_REG) {
1849
+ /* This guarantees the driver's requested regulatory domain
1850
+ * will always be used as a base for further regulatory
1851
+ * settings
1852
+ */
1853
+ chan->flags =
1854
+ map_regdom_flags(rrule1->flags) |
1855
+ map_regdom_flags(rrule2->flags) |
1856
+ bw_flags1 |
1857
+ bw_flags2;
1858
+ chan->orig_flags = chan->flags;
1859
+ chan->max_antenna_gain =
1860
+ min_t(int, MBI_TO_DBI(power_rule1->max_antenna_gain),
1861
+ MBI_TO_DBI(power_rule2->max_antenna_gain));
1862
+ chan->orig_mag = chan->max_antenna_gain;
1863
+ chan->max_reg_power =
1864
+ min_t(int, MBM_TO_DBM(power_rule1->max_eirp),
1865
+ MBM_TO_DBM(power_rule2->max_eirp));
1866
+ chan->max_power = chan->max_reg_power;
1867
+ chan->orig_mpwr = chan->max_reg_power;
1868
+
1869
+ if (chan->flags & IEEE80211_CHAN_RADAR) {
1870
+ chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
1871
+ if (rrule1->dfs_cac_ms || rrule2->dfs_cac_ms)
1872
+ chan->dfs_cac_ms = max_t(unsigned int,
1873
+ rrule1->dfs_cac_ms,
1874
+ rrule2->dfs_cac_ms);
1875
+ }
1876
+
1877
+ return;
1878
+ }
1879
+
1880
+ chan->dfs_state = NL80211_DFS_USABLE;
1881
+ chan->dfs_state_entered = jiffies;
1882
+
1883
+ chan->beacon_found = false;
1884
+ chan->flags = flags | bw_flags1 | bw_flags2 |
1885
+ map_regdom_flags(rrule1->flags) |
1886
+ map_regdom_flags(rrule2->flags);
1887
+
1888
+ /* reg_rule_to_chan_bw_flags may forbids 10 and forbids 20 MHz
1889
+ * (otherwise no adj. rule case), recheck therefore
1890
+ */
1891
+ if (cfg80211_does_bw_fit_range(comb_range,
1892
+ ieee80211_channel_to_khz(chan),
1893
+ MHZ_TO_KHZ(10)))
1894
+ chan->flags &= ~IEEE80211_CHAN_NO_10MHZ;
1895
+ if (cfg80211_does_bw_fit_range(comb_range,
1896
+ ieee80211_channel_to_khz(chan),
1897
+ MHZ_TO_KHZ(20)))
1898
+ chan->flags &= ~IEEE80211_CHAN_NO_20MHZ;
1899
+
1900
+ chan->max_antenna_gain =
1901
+ min_t(int, chan->orig_mag,
1902
+ min_t(int,
1903
+ MBI_TO_DBI(power_rule1->max_antenna_gain),
1904
+ MBI_TO_DBI(power_rule2->max_antenna_gain)));
1905
+ chan->max_reg_power = min_t(int,
1906
+ MBM_TO_DBM(power_rule1->max_eirp),
1907
+ MBM_TO_DBM(power_rule2->max_eirp));
1908
+
1909
+ if (chan->flags & IEEE80211_CHAN_RADAR) {
1910
+ if (rrule1->dfs_cac_ms || rrule2->dfs_cac_ms)
1911
+ chan->dfs_cac_ms = max_t(unsigned int,
1912
+ rrule1->dfs_cac_ms,
1913
+ rrule2->dfs_cac_ms);
1914
+ else
1915
+ chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
1916
+ }
1917
+
1918
+ if (chan->orig_mpwr) {
1919
+ /* Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER
1920
+ * will always follow the passed country IE power settings.
1921
+ */
1922
+ if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
1923
+ wiphy->regulatory_flags & REGULATORY_COUNTRY_IE_FOLLOW_POWER)
1924
+ chan->max_power = chan->max_reg_power;
1925
+ else
1926
+ chan->max_power = min(chan->orig_mpwr,
1927
+ chan->max_reg_power);
1928
+ } else {
1929
+ chan->max_power = chan->max_reg_power;
1930
+ }
1931
+}
1932
+
1933
+/* Note that right now we assume the desired channel bandwidth
1934
+ * is always 20 MHz for each individual channel (HT40 uses 20 MHz
1935
+ * per channel, the primary and the extension channel).
1936
+ */
1937
+static void handle_channel(struct wiphy *wiphy,
1938
+ enum nl80211_reg_initiator initiator,
1939
+ struct ieee80211_channel *chan)
1940
+{
1941
+ const u32 orig_chan_freq = ieee80211_channel_to_khz(chan);
1942
+ struct regulatory_request *lr = get_last_request();
1943
+ struct wiphy *request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx);
1944
+ const struct ieee80211_reg_rule *rrule = NULL;
1945
+ const struct ieee80211_reg_rule *rrule1 = NULL;
1946
+ const struct ieee80211_reg_rule *rrule2 = NULL;
1947
+
1948
+ u32 flags = chan->orig_flags;
1949
+
1950
+ rrule = freq_reg_info(wiphy, orig_chan_freq);
1951
+ if (IS_ERR(rrule)) {
1952
+ /* check for adjacent match, therefore get rules for
1953
+ * chan - 20 MHz and chan + 20 MHz and test
1954
+ * if reg rules are adjacent
1955
+ */
1956
+ rrule1 = freq_reg_info(wiphy,
1957
+ orig_chan_freq - MHZ_TO_KHZ(20));
1958
+ rrule2 = freq_reg_info(wiphy,
1959
+ orig_chan_freq + MHZ_TO_KHZ(20));
1960
+ if (!IS_ERR(rrule1) && !IS_ERR(rrule2)) {
1961
+ struct ieee80211_freq_range comb_range;
1962
+
1963
+ if (rrule1->freq_range.end_freq_khz !=
1964
+ rrule2->freq_range.start_freq_khz)
1965
+ goto disable_chan;
1966
+
1967
+ comb_range.start_freq_khz =
1968
+ rrule1->freq_range.start_freq_khz;
1969
+ comb_range.end_freq_khz =
1970
+ rrule2->freq_range.end_freq_khz;
1971
+ comb_range.max_bandwidth_khz =
1972
+ min_t(u32,
1973
+ rrule1->freq_range.max_bandwidth_khz,
1974
+ rrule2->freq_range.max_bandwidth_khz);
1975
+
1976
+ if (!cfg80211_does_bw_fit_range(&comb_range,
1977
+ orig_chan_freq,
1978
+ MHZ_TO_KHZ(20)))
1979
+ goto disable_chan;
1980
+
1981
+ handle_channel_adjacent_rules(wiphy, initiator, chan,
1982
+ flags, lr, request_wiphy,
1983
+ rrule1, rrule2,
1984
+ &comb_range);
1985
+ return;
1986
+ }
1987
+
1988
+disable_chan:
1989
+ /* We will disable all channels that do not match our
1990
+ * received regulatory rule unless the hint is coming
1991
+ * from a Country IE and the Country IE had no information
1992
+ * about a band. The IEEE 802.11 spec allows for an AP
1993
+ * to send only a subset of the regulatory rules allowed,
1994
+ * so an AP in the US that only supports 2.4 GHz may only send
1995
+ * a country IE with information for the 2.4 GHz band
1996
+ * while 5 GHz is still supported.
1997
+ */
1998
+ if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
1999
+ PTR_ERR(rrule) == -ERANGE)
2000
+ return;
2001
+
2002
+ if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
2003
+ request_wiphy && request_wiphy == wiphy &&
2004
+ request_wiphy->regulatory_flags & REGULATORY_STRICT_REG) {
2005
+ pr_debug("Disabling freq %d.%03d MHz for good\n",
2006
+ chan->center_freq, chan->freq_offset);
2007
+ chan->orig_flags |= IEEE80211_CHAN_DISABLED;
2008
+ chan->flags = chan->orig_flags;
2009
+ } else {
2010
+ pr_debug("Disabling freq %d.%03d MHz\n",
2011
+ chan->center_freq, chan->freq_offset);
2012
+ chan->flags |= IEEE80211_CHAN_DISABLED;
2013
+ }
2014
+ return;
2015
+ }
2016
+
2017
+ handle_channel_single_rule(wiphy, initiator, chan, flags, lr,
2018
+ request_wiphy, rrule);
17942019 }
17952020
17962021 static void handle_band(struct wiphy *wiphy,
....@@ -1927,7 +2152,7 @@
19272152 sband = wiphy->bands[reg_beacon->chan.band];
19282153 chan = &sband->channels[chan_idx];
19292154
1930
- if (likely(chan->center_freq != reg_beacon->chan.center_freq))
2155
+ if (likely(!ieee80211_channel_equal(chan, &reg_beacon->chan)))
19312156 return;
19322157
19332158 if (chan->beacon_found)
....@@ -2260,18 +2485,18 @@
22602485 u32 bw_flags = 0;
22612486 const struct ieee80211_reg_rule *reg_rule = NULL;
22622487 const struct ieee80211_power_rule *power_rule = NULL;
2263
- u32 bw;
2488
+ u32 bw, center_freq_khz;
22642489
2490
+ center_freq_khz = ieee80211_channel_to_khz(chan);
22652491 for (bw = MHZ_TO_KHZ(20); bw >= min_bw; bw = bw / 2) {
2266
- reg_rule = freq_reg_info_regd(MHZ_TO_KHZ(chan->center_freq),
2267
- regd, bw);
2492
+ reg_rule = freq_reg_info_regd(center_freq_khz, regd, bw);
22682493 if (!IS_ERR(reg_rule))
22692494 break;
22702495 }
22712496
22722497 if (IS_ERR_OR_NULL(reg_rule)) {
2273
- pr_debug("Disabling freq %d MHz as custom regd has no rule that fits it\n",
2274
- chan->center_freq);
2498
+ pr_debug("Disabling freq %d.%03d MHz as custom regd has no rule that fits it\n",
2499
+ chan->center_freq, chan->freq_offset);
22752500 if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) {
22762501 chan->flags |= IEEE80211_CHAN_DISABLED;
22772502 } else {
....@@ -2374,7 +2599,7 @@
23742599
23752600 /**
23762601 * reg_process_hint_core - process core regulatory requests
2377
- * @pending_request: a pending core regulatory request
2602
+ * @core_request: a pending core regulatory request
23782603 *
23792604 * The wireless subsystem can use this function to process
23802605 * a regulatory request issued by the regulatory core.
....@@ -2483,6 +2708,7 @@
24832708
24842709 /**
24852710 * reg_process_hint_driver - process driver regulatory requests
2711
+ * @wiphy: the wireless device for the regulatory request
24862712 * @driver_request: a pending driver regulatory request
24872713 *
24882714 * The wireless subsystem can use this function to process
....@@ -2583,6 +2809,7 @@
25832809
25842810 /**
25852811 * reg_process_hint_country_ie - process regulatory requests from country IEs
2812
+ * @wiphy: the wireless device for the regulatory request
25862813 * @country_ie_request: a regulatory request from a country IE
25872814 *
25882815 * The wireless subsystem can use this function to process
....@@ -2770,9 +2997,7 @@
27702997 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
27712998 wiphy = &rdev->wiphy;
27722999 if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
2773
- request->initiator == NL80211_REGDOM_SET_BY_USER &&
2774
- request->user_reg_hint_type ==
2775
- NL80211_USER_REG_HINT_CELL_BASE)
3000
+ request->initiator == NL80211_REGDOM_SET_BY_USER)
27763001 reg_call_notifier(wiphy, request);
27773002 }
27783003 }
....@@ -3160,10 +3385,10 @@
31603385 * - send a user regulatory hint if applicable
31613386 *
31623387 * Device drivers that send a regulatory hint for a specific country
3163
- * keep their own regulatory domain on wiphy->regd so that does does
3388
+ * keep their own regulatory domain on wiphy->regd so that does
31643389 * not need to be remembered.
31653390 */
3166
-static void restore_regulatory_settings(bool reset_user)
3391
+static void restore_regulatory_settings(bool reset_user, bool cached)
31673392 {
31683393 char alpha2[2];
31693394 char world_alpha2[2];
....@@ -3222,15 +3447,41 @@
32223447 restore_custom_reg_settings(&rdev->wiphy);
32233448 }
32243449
3225
- regulatory_hint_core(world_alpha2);
3450
+ if (cached && (!is_an_alpha2(alpha2) ||
3451
+ !IS_ERR_OR_NULL(cfg80211_user_regdom))) {
3452
+ reset_regdomains(false, cfg80211_world_regdom);
3453
+ update_all_wiphy_regulatory(NL80211_REGDOM_SET_BY_CORE);
3454
+ print_regdomain(get_cfg80211_regdom());
3455
+ nl80211_send_reg_change_event(&core_request_world);
3456
+ reg_set_request_processed();
32263457
3227
- /*
3228
- * This restores the ieee80211_regdom module parameter
3229
- * preference or the last user requested regulatory
3230
- * settings, user regulatory settings takes precedence.
3231
- */
3232
- if (is_an_alpha2(alpha2))
3233
- regulatory_hint_user(alpha2, NL80211_USER_REG_HINT_USER);
3458
+ if (is_an_alpha2(alpha2) &&
3459
+ !regulatory_hint_user(alpha2, NL80211_USER_REG_HINT_USER)) {
3460
+ struct regulatory_request *ureq;
3461
+
3462
+ spin_lock(&reg_requests_lock);
3463
+ ureq = list_last_entry(&reg_requests_list,
3464
+ struct regulatory_request,
3465
+ list);
3466
+ list_del(&ureq->list);
3467
+ spin_unlock(&reg_requests_lock);
3468
+
3469
+ notify_self_managed_wiphys(ureq);
3470
+ reg_update_last_request(ureq);
3471
+ set_regdom(reg_copy_regd(cfg80211_user_regdom),
3472
+ REGD_SOURCE_CACHED);
3473
+ }
3474
+ } else {
3475
+ regulatory_hint_core(world_alpha2);
3476
+
3477
+ /*
3478
+ * This restores the ieee80211_regdom module parameter
3479
+ * preference or the last user requested regulatory
3480
+ * settings, user regulatory settings takes precedence.
3481
+ */
3482
+ if (is_an_alpha2(alpha2))
3483
+ regulatory_hint_user(alpha2, NL80211_USER_REG_HINT_USER);
3484
+ }
32343485
32353486 spin_lock(&reg_requests_lock);
32363487 list_splice_tail_init(&tmp_reg_req_list, &reg_requests_list);
....@@ -3290,10 +3541,10 @@
32903541 }
32913542
32923543 pr_debug("All devices are disconnected, going to restore regulatory settings\n");
3293
- restore_regulatory_settings(false);
3544
+ restore_regulatory_settings(false, true);
32943545 }
32953546
3296
-static bool freq_is_chan_12_13_14(u16 freq)
3547
+static bool freq_is_chan_12_13_14(u32 freq)
32973548 {
32983549 if (freq == ieee80211_channel_to_frequency(12, NL80211_BAND_2GHZ) ||
32993550 freq == ieee80211_channel_to_frequency(13, NL80211_BAND_2GHZ) ||
....@@ -3307,8 +3558,8 @@
33073558 struct reg_beacon *pending_beacon;
33083559
33093560 list_for_each_entry(pending_beacon, &reg_pending_beacons, list)
3310
- if (beacon_chan->center_freq ==
3311
- pending_beacon->chan.center_freq)
3561
+ if (ieee80211_channel_equal(beacon_chan,
3562
+ &pending_beacon->chan))
33123563 return true;
33133564 return false;
33143565 }
....@@ -3337,9 +3588,10 @@
33373588 if (!reg_beacon)
33383589 return -ENOMEM;
33393590
3340
- pr_debug("Found new beacon on frequency: %d MHz (Ch %d) on %s\n",
3341
- beacon_chan->center_freq,
3342
- ieee80211_frequency_to_channel(beacon_chan->center_freq),
3591
+ pr_debug("Found new beacon on frequency: %d.%03d MHz (Ch %d) on %s\n",
3592
+ beacon_chan->center_freq, beacon_chan->freq_offset,
3593
+ ieee80211_freq_khz_to_channel(
3594
+ ieee80211_channel_to_khz(beacon_chan)),
33433595 wiphy_name(wiphy));
33443596
33453597 memcpy(&reg_beacon->chan, beacon_chan,
....@@ -3607,6 +3859,9 @@
36073859 bool user_reset = false;
36083860 int r;
36093861
3862
+ if (IS_ERR_OR_NULL(rd))
3863
+ return -ENODATA;
3864
+
36103865 if (!reg_is_valid_request(rd->alpha2)) {
36113866 kfree(rd);
36123867 return -EINVAL;
....@@ -3623,6 +3878,7 @@
36233878 r = reg_set_rd_core(rd);
36243879 break;
36253880 case NL80211_REGDOM_SET_BY_USER:
3881
+ cfg80211_save_user_regdom(rd);
36263882 r = reg_set_rd_user(rd, lr);
36273883 user_reset = true;
36283884 break;
....@@ -3645,7 +3901,7 @@
36453901 break;
36463902 default:
36473903 /* Back to world regulatory in case of errors */
3648
- restore_regulatory_settings(user_reset);
3904
+ restore_regulatory_settings(user_reset, false);
36493905 }
36503906
36513907 kfree(rd);
....@@ -3744,10 +4000,9 @@
37444000 /*
37454001 * The last request may have been received before this
37464002 * registration call. Call the driver notifier if
3747
- * initiator is USER and user type is CELL_BASE.
4003
+ * initiator is USER.
37484004 */
3749
- if (lr->initiator == NL80211_REGDOM_SET_BY_USER &&
3750
- lr->user_reg_hint_type == NL80211_USER_REG_HINT_CELL_BASE)
4005
+ if (lr->initiator == NL80211_REGDOM_SET_BY_USER)
37514006 reg_call_notifier(wiphy, lr);
37524007 }
37534008
....@@ -3756,6 +4011,7 @@
37564011
37574012 wiphy_update_regulatory(wiphy, lr->initiator);
37584013 wiphy_all_share_dfs_chan_state(wiphy);
4014
+ reg_process_self_managed_hints();
37594015 }
37604016
37614017 void wiphy_regulatory_deregister(struct wiphy *wiphy)
....@@ -3782,8 +4038,9 @@
37824038 }
37834039
37844040 /*
3785
- * See http://www.fcc.gov/document/5-ghz-unlicensed-spectrum-unii, for
3786
- * UNII band definitions
4041
+ * See FCC notices for UNII band definitions
4042
+ * 5GHz: https://www.fcc.gov/document/5-ghz-unlicensed-spectrum-unii
4043
+ * 6GHz: https://www.fcc.gov/document/fcc-proposes-more-spectrum-unlicensed-use-0
37874044 */
37884045 int cfg80211_get_unii(int freq)
37894046 {
....@@ -3806,6 +4063,22 @@
38064063 /* UNII-3 */
38074064 if (freq > 5725 && freq <= 5825)
38084065 return 4;
4066
+
4067
+ /* UNII-5 */
4068
+ if (freq > 5925 && freq <= 6425)
4069
+ return 5;
4070
+
4071
+ /* UNII-6 */
4072
+ if (freq > 6425 && freq <= 6525)
4073
+ return 6;
4074
+
4075
+ /* UNII-7 */
4076
+ if (freq > 6525 && freq <= 6875)
4077
+ return 7;
4078
+
4079
+ /* UNII-8 */
4080
+ if (freq > 6875 && freq <= 7125)
4081
+ return 8;
38094082
38104083 return -EINVAL;
38114084 }
....@@ -3842,6 +4115,7 @@
38424115
38434116 return pre_cac_allowed;
38444117 }
4118
+EXPORT_SYMBOL(regulatory_pre_cac_allowed);
38454119
38464120 static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev)
38474121 {
....@@ -3911,8 +4185,10 @@
39114185 return -EINVAL;
39124186
39134187 err = load_builtin_regdb_keys();
3914
- if (err)
4188
+ if (err) {
4189
+ platform_device_unregister(reg_pdev);
39154190 return err;
4191
+ }
39164192
39174193 /* We always try to get an update for the static regdomain */
39184194 err = regulatory_hint_core(cfg80211_world_regdom->alpha2);
....@@ -4002,6 +4278,8 @@
40024278
40034279 if (!IS_ERR_OR_NULL(regdb))
40044280 kfree(regdb);
4281
+ if (!IS_ERR_OR_NULL(cfg80211_user_regdom))
4282
+ kfree(cfg80211_user_regdom);
40054283
40064284 free_regdb_keyring();
40074285 }