aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/util.c')
-rw-r--r--net/wireless/util.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 16d76a807c2f..37a56ee1e1ed 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1184,7 +1184,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1184 struct wireless_dev *wdev, 1184 struct wireless_dev *wdev,
1185 enum nl80211_iftype iftype, 1185 enum nl80211_iftype iftype,
1186 struct ieee80211_channel *chan, 1186 struct ieee80211_channel *chan,
1187 enum cfg80211_chan_mode chanmode) 1187 enum cfg80211_chan_mode chanmode,
1188 u8 radar_detect)
1188{ 1189{
1189 struct wireless_dev *wdev_iter; 1190 struct wireless_dev *wdev_iter;
1190 u32 used_iftypes = BIT(iftype); 1191 u32 used_iftypes = BIT(iftype);
@@ -1195,14 +1196,46 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1195 enum cfg80211_chan_mode chmode; 1196 enum cfg80211_chan_mode chmode;
1196 int num_different_channels = 0; 1197 int num_different_channels = 0;
1197 int total = 1; 1198 int total = 1;
1199 bool radar_required;
1198 int i, j; 1200 int i, j;
1199 1201
1200 ASSERT_RTNL(); 1202 ASSERT_RTNL();
1201 lockdep_assert_held(&rdev->devlist_mtx); 1203 lockdep_assert_held(&rdev->devlist_mtx);
1202 1204
1205 if (WARN_ON(hweight32(radar_detect) > 1))
1206 return -EINVAL;
1207
1208 switch (iftype) {
1209 case NL80211_IFTYPE_ADHOC:
1210 case NL80211_IFTYPE_AP:
1211 case NL80211_IFTYPE_AP_VLAN:
1212 case NL80211_IFTYPE_MESH_POINT:
1213 case NL80211_IFTYPE_P2P_GO:
1214 case NL80211_IFTYPE_WDS:
1215 radar_required = !!(chan &&
1216 (chan->flags & IEEE80211_CHAN_RADAR));
1217 break;
1218 case NL80211_IFTYPE_P2P_CLIENT:
1219 case NL80211_IFTYPE_STATION:
1220 case NL80211_IFTYPE_P2P_DEVICE:
1221 case NL80211_IFTYPE_MONITOR:
1222 radar_required = false;
1223 break;
1224 case NUM_NL80211_IFTYPES:
1225 case NL80211_IFTYPE_UNSPECIFIED:
1226 default:
1227 return -EINVAL;
1228 }
1229
1230 if (radar_required && !radar_detect)
1231 return -EINVAL;
1232
1203 /* Always allow software iftypes */ 1233 /* Always allow software iftypes */
1204 if (rdev->wiphy.software_iftypes & BIT(iftype)) 1234 if (rdev->wiphy.software_iftypes & BIT(iftype)) {
1235 if (radar_detect)
1236 return -EINVAL;
1205 return 0; 1237 return 0;
1238 }
1206 1239
1207 memset(num, 0, sizeof(num)); 1240 memset(num, 0, sizeof(num));
1208 memset(used_channels, 0, sizeof(used_channels)); 1241 memset(used_channels, 0, sizeof(used_channels));
@@ -1275,7 +1308,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1275 used_iftypes |= BIT(wdev_iter->iftype); 1308 used_iftypes |= BIT(wdev_iter->iftype);
1276 } 1309 }
1277 1310
1278 if (total == 1) 1311 if (total == 1 && !radar_detect)
1279 return 0; 1312 return 0;
1280 1313
1281 for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) { 1314 for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) {
@@ -1308,6 +1341,9 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1308 } 1341 }
1309 } 1342 }
1310 1343
1344 if (radar_detect && !(c->radar_detect_widths & radar_detect))
1345 goto cont;
1346
1311 /* 1347 /*
1312 * Finally check that all iftypes that we're currently 1348 * Finally check that all iftypes that we're currently
1313 * using are actually part of this combination. If they 1349 * using are actually part of this combination. If they