History

cfg80211: check radar interface combinations

To ease further DFS development regarding interface combinations, use the interface combinations structure to test for radar capabilities. Drivers can specify which channel widths they support, and in which modes. Right now only a single AP interface is allowed, but as the DFS code evolves other combinations can be enabled.

Simon Wunderlich committed 13 years ago

Commit 11c4a071 parent cee00a96 files · +60 −8Browse files

Unified · Split

6 files
  1. include/net/cfg80211.h +2 −0
  2. include/uapi/linux/nl80211.h +3 −0
  3. net/wireless/core.c +10 −2
  4. net/wireless/core.h +4 −3
  5. net/wireless/nl80211.c +3 −0
  6. net/wireless/util.c +38 −3
include/net/cfg80211.h+2−0
@@ -2125,6 +2125,7 @@ struct ieee80211_iface_limit { · 2124 unmodified lines
21252125 * @beacon_int_infra_match: In this combination, the beacon intervals
21262126 * between infrastructure and AP types must match. This is required
21272127 * only in special cases.
2128+ * @radar_detect_widths: bitmap of channel widths supported for radar detection
21282129 *
21292130 * These examples can be expressed as follows:
21302131 *
@@ -2177,6 +2178,7 @@ struct ieee80211_iface_combination { · 46 unmodified lines
21772178 u16 max_interfaces;
21782179 u8 n_limits;
21792180 bool beacon_int_infra_match;
2181+ u8 radar_detect_widths;
21802182 };
21812183
21822184 struct mac_address {
include/uapi/linux/nl80211.h+3−0
@@ -2984,6 +2984,8 @@ enum nl80211_iface_limit_attrs { · 2983 unmodified lines
29842984 * the infrastructure network's beacon interval.
29852985 * @NL80211_IFACE_COMB_NUM_CHANNELS: u32 attribute specifying how many
29862986 * different channels may be used within this group.
2987+ * @NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS: u32 attribute containing the bitmap
2988+ * of supported channel widths for radar detection.
29872989 * @NUM_NL80211_IFACE_COMB: number of attributes
29882990 * @MAX_NL80211_IFACE_COMB: highest attribute number
29892991 *
@@ -3016,6 +3018,7 @@ enum nl80211_if_combination_attrs { · 26 unmodified lines
30163018 NL80211_IFACE_COMB_MAXNUM,
30173019 NL80211_IFACE_COMB_STA_AP_BI_MATCH,
30183020 NL80211_IFACE_COMB_NUM_CHANNELS,
3021+ NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
30193022
30203023 /* keep last */
30213024 NUM_NL80211_IFACE_COMB,
net/wireless/core.c+10−2
@@ -382,8 +382,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) · 381 unmodified lines
382382
383383 c = &wiphy->iface_combinations[i];
384384
385− /* Combinations with just one interface aren't real */
386− if (WARN_ON(c->max_interfaces < 2))
385+ /*
386+ * Combinations with just one interface aren't real,
387+ * however we make an exception for DFS.
388+ */
389+ if (WARN_ON((c->max_interfaces < 2) && !c->radar_detect_widths))
387390 return -EINVAL;
388391
389392 /* Need at least one channel */
@@ -398,6 +401,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) · 8 unmodified lines
398401 CFG80211_MAX_NUM_DIFFERENT_CHANNELS))
399402 return -EINVAL;
400403
404+ /* DFS only works on one channel. */
405+ if (WARN_ON(c->radar_detect_widths &&
406+ (c->num_different_channels > 1)))
407+ return -EINVAL;
408+
401409 if (WARN_ON(!c->n_limits))
402410 return -EINVAL;
403411
net/wireless/core.h+4−3
@@ -425,7 +425,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, · 424 unmodified lines
425425 struct wireless_dev *wdev,
426426 enum nl80211_iftype iftype,
427427 struct ieee80211_channel *chan,
428− enum cfg80211_chan_mode chanmode);
428+ enum cfg80211_chan_mode chanmode,
429+ u8 radar_detect);
429430
430431 static inline int
431432 cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
@@ -433,7 +434,7 @@ cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, · 1 unmodified line
433434 enum nl80211_iftype iftype)
434435 {
435436 return cfg80211_can_use_iftype_chan(rdev, wdev, iftype, NULL,
436− CHAN_MODE_UNDEFINED);
437+ CHAN_MODE_UNDEFINED, 0);
437438 }
438439
439440 static inline int
@@ -450,7 +451,7 @@ cfg80211_can_use_chan(struct cfg80211_registered_device *rdev, · 10 unmodified lines
450451 enum cfg80211_chan_mode chanmode)
451452 {
452453 return cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
453− chan, chanmode);
454+ chan, chanmode, 0);
454455 }
455456
456457 void
net/wireless/nl80211.c+3−0
@@ -856,6 +856,9 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy, · 855 unmodified lines
856856 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
857857 c->max_interfaces))
858858 goto nla_put_failure;
859+ if (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
860+ c->radar_detect_widths))
861+ goto nla_put_failure;
859862
860863 nla_nest_end(msg, nl_combi);
861864 }
net/wireless/util.c+38−3
@@ -1184,7 +1184,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, · 1183 unmodified lines
11841184 struct wireless_dev *wdev,
11851185 enum nl80211_iftype iftype,
11861186 struct ieee80211_channel *chan,
1187− enum cfg80211_chan_mode chanmode)
1187+ enum cfg80211_chan_mode chanmode,
1188+ u8 radar_detect)
11881189 {
11891190 struct wireless_dev *wdev_iter;
11901191 u32 used_iftypes = BIT(iftype);
@@ -1195,14 +1196,45 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, · 4 unmodified lines
11951196 enum cfg80211_chan_mode chmode;
11961197 int num_different_channels = 0;
11971198 int total = 1;
1199+ bool radar_required;
11981200 int i, j;
11991201
12001202 ASSERT_RTNL();
12011203 lockdep_assert_held(&rdev->devlist_mtx);
12021204
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->flags & IEEE80211_CHAN_RADAR);
1216+ break;
1217+ case NL80211_IFTYPE_P2P_CLIENT:
1218+ case NL80211_IFTYPE_STATION:
1219+ case NL80211_IFTYPE_MONITOR:
1220+ radar_required = false;
1221+ break;
1222+ case NL80211_IFTYPE_P2P_DEVICE:
1223+ case NUM_NL80211_IFTYPES:
1224+ case NL80211_IFTYPE_UNSPECIFIED:
1225+ default:
1226+ return -EINVAL;
1227+ }
1228+
1229+ if (radar_required && !radar_detect)
1230+ return -EINVAL;
1231+
12031232 /* Always allow software iftypes */
1204− if (rdev->wiphy.software_iftypes & BIT(iftype))
1233+ if (rdev->wiphy.software_iftypes & BIT(iftype)) {
1234+ if (radar_detect)
1235+ return -EINVAL;
12051236 return 0;
1237+ }
12061238
12071239 memset(num, 0, sizeof(num));
12081240 memset(used_channels, 0, sizeof(used_channels));
@@ -1275,7 +1307,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, · 66 unmodified lines
12751307 used_iftypes |= BIT(wdev_iter->iftype);
12761308 }
12771309
1278− if (total == 1)
1310+ if (total == 1 && !radar_detect)
12791311 return 0;
12801312
12811313 for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) {
@@ -1308,6 +1340,9 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, · 26 unmodified lines
13081340 }
13091341 }
13101342
1343+ if (radar_detect && !(c->radar_detect_widths & radar_detect))
1344+ goto cont;
1345+
13111346 /*
13121347 * Finally check that all iftypes that we're currently
13131348 * using are actually part of this combination. If they

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t