aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/chan.c6
-rw-r--r--net/wireless/genregdb.awk2
-rw-r--r--net/wireless/ibss.c7
-rw-r--r--net/wireless/mesh.c6
-rw-r--r--net/wireless/nl80211.c33
-rw-r--r--net/wireless/rdev-ops.h9
-rw-r--r--net/wireless/reg.c83
-rw-r--r--net/wireless/trace.h12
-rw-r--r--net/wireless/util.c31
9 files changed, 96 insertions, 93 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 2d4268c5529d..cd10c1985074 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -705,12 +705,8 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
705 case NL80211_IFTYPE_MONITOR: 705 case NL80211_IFTYPE_MONITOR:
706 case NL80211_IFTYPE_AP_VLAN: 706 case NL80211_IFTYPE_AP_VLAN:
707 case NL80211_IFTYPE_WDS: 707 case NL80211_IFTYPE_WDS:
708 /* these interface types don't really have a channel */
709 return;
710 case NL80211_IFTYPE_P2P_DEVICE: 708 case NL80211_IFTYPE_P2P_DEVICE:
711 if (wdev->wiphy->features & 709 /* these interface types don't really have a channel */
712 NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL)
713 *chanmode = CHAN_MODE_EXCLUSIVE;
714 return; 710 return;
715 case NL80211_IFTYPE_UNSPECIFIED: 711 case NL80211_IFTYPE_UNSPECIFIED:
716 case NUM_NL80211_IFTYPES: 712 case NUM_NL80211_IFTYPES:
diff --git a/net/wireless/genregdb.awk b/net/wireless/genregdb.awk
index 9a8217d2a908..fdfd3f063a9b 100644
--- a/net/wireless/genregdb.awk
+++ b/net/wireless/genregdb.awk
@@ -105,6 +105,8 @@ function parse_reg_rule()
105 flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " 105 flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
106 } else if (flagarray[arg] == "NO-IR") { 106 } else if (flagarray[arg] == "NO-IR") {
107 flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " 107 flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
108 } else if (flagarray[arg] == "AUTO-BW") {
109 flags = flags "\n\t\t\tNL80211_RRF_AUTO_BW | "
108 } 110 }
109 111
110 } 112 }
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 1470b90e438f..349db9ddc0d1 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -128,12 +128,11 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
128#endif 128#endif
129 check_chan = params->chandef.chan; 129 check_chan = params->chandef.chan;
130 if (params->userspace_handles_dfs) { 130 if (params->userspace_handles_dfs) {
131 /* use channel NULL to check for radar even if the current 131 /* Check for radar even if the current channel is not
132 * channel is not a radar channel - it might decide to change 132 * a radar channel - it might decide to change to DFS
133 * to DFS channel later. 133 * channel later.
134 */ 134 */
135 radar_detect_width = BIT(params->chandef.width); 135 radar_detect_width = BIT(params->chandef.width);
136 check_chan = NULL;
137 } 136 }
138 137
139 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 138 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index d42a3fcb2f67..5af5cc6b2c4c 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -236,6 +236,12 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
236 if (!netif_running(wdev->netdev)) 236 if (!netif_running(wdev->netdev))
237 return -ENETDOWN; 237 return -ENETDOWN;
238 238
239 /* cfg80211_can_use_chan() calls
240 * cfg80211_can_use_iftype_chan() with no radar
241 * detection, so if we're trying to use a radar
242 * channel here, something is wrong.
243 */
244 WARN_ON_ONCE(chandef->chan->flags & IEEE80211_CHAN_RADAR);
239 err = cfg80211_can_use_chan(rdev, wdev, chandef->chan, 245 err = cfg80211_can_use_chan(rdev, wdev, chandef->chan,
240 CHAN_MODE_SHARED); 246 CHAN_MODE_SHARED);
241 if (err) 247 if (err)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8e6b6a2d35cb..2c38b28a85b9 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -384,6 +384,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
384 .len = IEEE80211_QOS_MAP_LEN_MAX }, 384 .len = IEEE80211_QOS_MAP_LEN_MAX },
385 [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN }, 385 [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
386 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, 386 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
387 [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
387}; 388};
388 389
389/* policy for the key attributes */ 390/* policy for the key attributes */
@@ -4627,6 +4628,8 @@ static int parse_reg_rule(struct nlattr *tb[],
4627 return -EINVAL; 4628 return -EINVAL;
4628 if (!tb[NL80211_ATTR_FREQ_RANGE_END]) 4629 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
4629 return -EINVAL; 4630 return -EINVAL;
4631 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
4632 return -EINVAL;
4630 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]) 4633 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
4631 return -EINVAL; 4634 return -EINVAL;
4632 4635
@@ -4636,9 +4639,8 @@ static int parse_reg_rule(struct nlattr *tb[],
4636 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]); 4639 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
4637 freq_range->end_freq_khz = 4640 freq_range->end_freq_khz =
4638 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]); 4641 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
4639 if (tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) 4642 freq_range->max_bandwidth_khz =
4640 freq_range->max_bandwidth_khz = 4643 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
4641 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
4642 4644
4643 power_rule->max_eirp = 4645 power_rule->max_eirp =
4644 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]); 4646 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
@@ -5710,8 +5712,8 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
5710 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF; 5712 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
5711 } 5713 }
5712 5714
5713 if (info->attrs[NL80211_ATTR_IE]) { 5715 if (ie_len) {
5714 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 5716 request->ie_len = ie_len;
5715 memcpy((void *)request->ie, 5717 memcpy((void *)request->ie,
5716 nla_data(info->attrs[NL80211_ATTR_IE]), 5718 nla_data(info->attrs[NL80211_ATTR_IE]),
5717 request->ie_len); 5719 request->ie_len);
@@ -5911,17 +5913,22 @@ skip_beacons:
5911 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef)) 5913 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
5912 return -EINVAL; 5914 return -EINVAL;
5913 5915
5914 if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP || 5916 switch (dev->ieee80211_ptr->iftype) {
5915 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO || 5917 case NL80211_IFTYPE_AP:
5916 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_ADHOC) { 5918 case NL80211_IFTYPE_P2P_GO:
5919 case NL80211_IFTYPE_ADHOC:
5920 case NL80211_IFTYPE_MESH_POINT:
5917 err = cfg80211_chandef_dfs_required(wdev->wiphy, 5921 err = cfg80211_chandef_dfs_required(wdev->wiphy,
5918 &params.chandef); 5922 &params.chandef);
5919 if (err < 0) { 5923 if (err < 0)
5920 return err; 5924 return err;
5921 } else if (err) { 5925 if (err) {
5922 radar_detect_width = BIT(params.chandef.width); 5926 radar_detect_width = BIT(params.chandef.width);
5923 params.radar_required = true; 5927 params.radar_required = true;
5924 } 5928 }
5929 break;
5930 default:
5931 break;
5925 } 5932 }
5926 5933
5927 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 5934 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
@@ -7269,6 +7276,7 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
7269 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 7276 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7270 struct net_device *dev = info->user_ptr[1]; 7277 struct net_device *dev = info->user_ptr[1];
7271 u8 action_code, dialog_token; 7278 u8 action_code, dialog_token;
7279 u32 peer_capability = 0;
7272 u16 status_code; 7280 u16 status_code;
7273 u8 *peer; 7281 u8 *peer;
7274 7282
@@ -7287,9 +7295,12 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
7287 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]); 7295 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
7288 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]); 7296 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
7289 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]); 7297 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
7298 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
7299 peer_capability =
7300 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
7290 7301
7291 return rdev_tdls_mgmt(rdev, dev, peer, action_code, 7302 return rdev_tdls_mgmt(rdev, dev, peer, action_code,
7292 dialog_token, status_code, 7303 dialog_token, status_code, peer_capability,
7293 nla_data(info->attrs[NL80211_ATTR_IE]), 7304 nla_data(info->attrs[NL80211_ATTR_IE]),
7294 nla_len(info->attrs[NL80211_ATTR_IE])); 7305 nla_len(info->attrs[NL80211_ATTR_IE]));
7295} 7306}
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index c8e225947adb..74d97d33c938 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -769,13 +769,16 @@ static inline int rdev_set_rekey_data(struct cfg80211_registered_device *rdev,
769static inline int rdev_tdls_mgmt(struct cfg80211_registered_device *rdev, 769static inline int rdev_tdls_mgmt(struct cfg80211_registered_device *rdev,
770 struct net_device *dev, u8 *peer, 770 struct net_device *dev, u8 *peer,
771 u8 action_code, u8 dialog_token, 771 u8 action_code, u8 dialog_token,
772 u16 status_code, const u8 *buf, size_t len) 772 u16 status_code, u32 peer_capability,
773 const u8 *buf, size_t len)
773{ 774{
774 int ret; 775 int ret;
775 trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code, 776 trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
776 dialog_token, status_code, buf, len); 777 dialog_token, status_code, peer_capability,
778 buf, len);
777 ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code, 779 ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
778 dialog_token, status_code, buf, len); 780 dialog_token, status_code, peer_capability,
781 buf, len);
779 trace_rdev_return_int(&rdev->wiphy, ret); 782 trace_rdev_return_int(&rdev->wiphy, ret);
780 return ret; 783 return ret;
781} 784}
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 24c257cd706b..90b82e08ae69 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -563,9 +563,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd,
563 if (freq_range_tmp->end_freq_khz < freq_range->start_freq_khz) 563 if (freq_range_tmp->end_freq_khz < freq_range->start_freq_khz)
564 break; 564 break;
565 565
566 if (freq_range_tmp->max_bandwidth_khz)
567 break;
568
569 freq_range = freq_range_tmp; 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,
582 if (freq_range_tmp->start_freq_khz > freq_range->end_freq_khz) 579 if (freq_range_tmp->start_freq_khz > freq_range->end_freq_khz)
583 break; 580 break;
584 581
585 if (freq_range_tmp->max_bandwidth_khz)
586 break;
587
588 freq_range = freq_range_tmp; 582 freq_range = freq_range_tmp;
589 } 583 }
590 584
@@ -729,21 +723,29 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
729 max_bandwidth1 = freq_range1->max_bandwidth_khz; 723 max_bandwidth1 = freq_range1->max_bandwidth_khz;
730 max_bandwidth2 = freq_range2->max_bandwidth_khz; 724 max_bandwidth2 = freq_range2->max_bandwidth_khz;
731 725
732 /* 726 if (rule1->flags & NL80211_RRF_AUTO_BW)
733 * In case max_bandwidth1 == 0 and max_bandwith2 == 0 set 727 max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1);
734 * output bandwidth as 0 (auto calculation). Next we will 728 if (rule2->flags & NL80211_RRF_AUTO_BW)
735 * calculate this correctly in handle_channel function. 729 max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2);
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 }
744 730
745 freq_range->max_bandwidth_khz = min(max_bandwidth1, max_bandwidth2); 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 freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz; 749 freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
748 if (freq_range->max_bandwidth_khz > freq_diff) 750 if (freq_range->max_bandwidth_khz > freq_diff)
749 freq_range->max_bandwidth_khz = freq_diff; 751 freq_range->max_bandwidth_khz = freq_diff;
@@ -753,8 +755,6 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
753 power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain, 755 power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
754 power_rule2->max_antenna_gain); 756 power_rule2->max_antenna_gain);
755 757
756 intersected_rule->flags = rule1->flags | rule2->flags;
757
758 if (!is_valid_reg_rule(intersected_rule)) 758 if (!is_valid_reg_rule(intersected_rule))
759 return -EINVAL; 759 return -EINVAL;
760 760
@@ -938,31 +938,42 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator)
938EXPORT_SYMBOL(reg_initiator_name); 938EXPORT_SYMBOL(reg_initiator_name);
939 939
940#ifdef CONFIG_CFG80211_REG_DEBUG 940#ifdef CONFIG_CFG80211_REG_DEBUG
941static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, 941static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
942 struct ieee80211_channel *chan,
942 const struct ieee80211_reg_rule *reg_rule) 943 const struct ieee80211_reg_rule *reg_rule)
943{ 944{
944 const struct ieee80211_power_rule *power_rule; 945 const struct ieee80211_power_rule *power_rule;
945 const struct ieee80211_freq_range *freq_range; 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 power_rule = &reg_rule->power_rule; 949 power_rule = &reg_rule->power_rule;
949 freq_range = &reg_rule->freq_range; 950 freq_range = &reg_rule->freq_range;
950 951
951 if (!power_rule->max_antenna_gain) 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 else 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 REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n", 966 REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n",
957 chan->center_freq); 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 freq_range->start_freq_khz, freq_range->end_freq_khz, 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 power_rule->max_eirp); 972 power_rule->max_eirp);
963} 973}
964#else 974#else
965static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, 975static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
976 struct ieee80211_channel *chan,
966 const struct ieee80211_reg_rule *reg_rule) 977 const struct ieee80211_reg_rule *reg_rule)
967{ 978{
968 return; 979 return;
@@ -1022,17 +1033,16 @@ static void handle_channel(struct wiphy *wiphy,
1022 return; 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 power_rule = &reg_rule->power_rule; 1039 power_rule = &reg_rule->power_rule;
1028 freq_range = &reg_rule->freq_range; 1040 freq_range = &reg_rule->freq_range;
1029 1041
1030 max_bandwidth_khz = freq_range->max_bandwidth_khz; 1042 max_bandwidth_khz = freq_range->max_bandwidth_khz;
1031 /* Check if auto calculation requested */ 1043 /* Check if auto calculation requested */
1032 if (!max_bandwidth_khz) { 1044 if (reg_rule->flags & NL80211_RRF_AUTO_BW)
1033 regd = reg_get_regdomain(wiphy);
1034 max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); 1045 max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
1035 }
1036 1046
1037 if (max_bandwidth_khz < MHZ_TO_KHZ(40)) 1047 if (max_bandwidth_khz < MHZ_TO_KHZ(40))
1038 bw_flags = IEEE80211_CHAN_NO_HT40; 1048 bw_flags = IEEE80211_CHAN_NO_HT40;
@@ -1437,14 +1447,14 @@ static void handle_channel_custom(struct wiphy *wiphy,
1437 return; 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 power_rule = &reg_rule->power_rule; 1452 power_rule = &reg_rule->power_rule;
1443 freq_range = &reg_rule->freq_range; 1453 freq_range = &reg_rule->freq_range;
1444 1454
1445 max_bandwidth_khz = freq_range->max_bandwidth_khz; 1455 max_bandwidth_khz = freq_range->max_bandwidth_khz;
1446 /* Check if auto calculation requested */ 1456 /* Check if auto calculation requested */
1447 if (!max_bandwidth_khz) 1457 if (reg_rule->flags & NL80211_RRF_AUTO_BW)
1448 max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); 1458 max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
1449 1459
1450 if (max_bandwidth_khz < MHZ_TO_KHZ(40)) 1460 if (max_bandwidth_khz < MHZ_TO_KHZ(40))
@@ -2254,11 +2264,12 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
2254 freq_range = &reg_rule->freq_range; 2264 freq_range = &reg_rule->freq_range;
2255 power_rule = &reg_rule->power_rule; 2265 power_rule = &reg_rule->power_rule;
2256 2266
2257 if (!freq_range->max_bandwidth_khz) 2267 if (reg_rule->flags & NL80211_RRF_AUTO_BW)
2258 snprintf(bw, 32, "%d KHz, AUTO", 2268 snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO",
2269 freq_range->max_bandwidth_khz,
2259 reg_get_max_bandwidth(rd, reg_rule)); 2270 reg_get_max_bandwidth(rd, reg_rule));
2260 else 2271 else
2261 snprintf(bw, 32, "%d KHz", 2272 snprintf(bw, sizeof(bw), "%d KHz",
2262 freq_range->max_bandwidth_khz); 2273 freq_range->max_bandwidth_khz);
2263 2274
2264 /* 2275 /*
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 5eaeed59db07..aabccf13e07b 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1468,9 +1468,10 @@ TRACE_EVENT(rdev_sched_scan_start,
1468TRACE_EVENT(rdev_tdls_mgmt, 1468TRACE_EVENT(rdev_tdls_mgmt,
1469 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, 1469 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
1470 u8 *peer, u8 action_code, u8 dialog_token, 1470 u8 *peer, u8 action_code, u8 dialog_token,
1471 u16 status_code, const u8 *buf, size_t len), 1471 u16 status_code, u32 peer_capability,
1472 const u8 *buf, size_t len),
1472 TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code, 1473 TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code,
1473 buf, len), 1474 peer_capability, buf, len),
1474 TP_STRUCT__entry( 1475 TP_STRUCT__entry(
1475 WIPHY_ENTRY 1476 WIPHY_ENTRY
1476 NETDEV_ENTRY 1477 NETDEV_ENTRY
@@ -1478,6 +1479,7 @@ TRACE_EVENT(rdev_tdls_mgmt,
1478 __field(u8, action_code) 1479 __field(u8, action_code)
1479 __field(u8, dialog_token) 1480 __field(u8, dialog_token)
1480 __field(u16, status_code) 1481 __field(u16, status_code)
1482 __field(u32, peer_capability)
1481 __dynamic_array(u8, buf, len) 1483 __dynamic_array(u8, buf, len)
1482 ), 1484 ),
1483 TP_fast_assign( 1485 TP_fast_assign(
@@ -1487,13 +1489,15 @@ TRACE_EVENT(rdev_tdls_mgmt,
1487 __entry->action_code = action_code; 1489 __entry->action_code = action_code;
1488 __entry->dialog_token = dialog_token; 1490 __entry->dialog_token = dialog_token;
1489 __entry->status_code = status_code; 1491 __entry->status_code = status_code;
1492 __entry->peer_capability = peer_capability;
1490 memcpy(__get_dynamic_array(buf), buf, len); 1493 memcpy(__get_dynamic_array(buf), buf, len);
1491 ), 1494 ),
1492 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, " 1495 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, "
1493 "dialog_token: %u, status_code: %u, buf: %#.2x ", 1496 "dialog_token: %u, status_code: %u, peer_capability: %u buf: %#.2x ",
1494 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), 1497 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer),
1495 __entry->action_code, __entry->dialog_token, 1498 __entry->action_code, __entry->dialog_token,
1496 __entry->status_code, ((u8 *)__get_dynamic_array(buf))[0]) 1499 __entry->status_code, __entry->peer_capability,
1500 ((u8 *)__get_dynamic_array(buf))[0])
1497); 1501);
1498 1502
1499TRACE_EVENT(rdev_dump_survey, 1503TRACE_EVENT(rdev_dump_survey,
diff --git a/net/wireless/util.c b/net/wireless/util.c
index ad03af385556..2bb685f3e8fc 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1285,7 +1285,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1285 enum cfg80211_chan_mode chmode; 1285 enum cfg80211_chan_mode chmode;
1286 int num_different_channels = 0; 1286 int num_different_channels = 0;
1287 int total = 1; 1287 int total = 1;
1288 bool radar_required = false;
1289 int i, j; 1288 int i, j;
1290 1289
1291 ASSERT_RTNL(); 1290 ASSERT_RTNL();
@@ -1293,35 +1292,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1293 if (WARN_ON(hweight32(radar_detect) > 1)) 1292 if (WARN_ON(hweight32(radar_detect) > 1))
1294 return -EINVAL; 1293 return -EINVAL;
1295 1294
1296 switch (iftype) { 1295 if (WARN_ON(iftype >= NUM_NL80211_IFTYPES))
1297 case NL80211_IFTYPE_ADHOC:
1298 case NL80211_IFTYPE_AP:
1299 case NL80211_IFTYPE_AP_VLAN:
1300 case NL80211_IFTYPE_MESH_POINT:
1301 case NL80211_IFTYPE_P2P_GO:
1302 case NL80211_IFTYPE_WDS:
1303 /* if the interface could potentially choose a DFS channel,
1304 * then mark DFS as required.
1305 */
1306 if (!chan) {
1307 if (chanmode != CHAN_MODE_UNDEFINED && radar_detect)
1308 radar_required = true;
1309 break;
1310 }
1311 radar_required = !!(chan->flags & IEEE80211_CHAN_RADAR);
1312 break;
1313 case NL80211_IFTYPE_P2P_CLIENT:
1314 case NL80211_IFTYPE_STATION:
1315 case NL80211_IFTYPE_P2P_DEVICE:
1316 case NL80211_IFTYPE_MONITOR:
1317 break;
1318 case NUM_NL80211_IFTYPES:
1319 case NL80211_IFTYPE_UNSPECIFIED:
1320 default:
1321 return -EINVAL;
1322 }
1323
1324 if (radar_required && !radar_detect)
1325 return -EINVAL; 1296 return -EINVAL;
1326 1297
1327 /* Always allow software iftypes */ 1298 /* Always allow software iftypes */