Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cfg80211: refactor cfg80211_can_use_iftype_chan()

Separate the code that counts the interface types and channels from
the code that check the interface combinations. The new function that
checks for combinations is exported so it can be called by the
drivers.

This is done in preparation for moving the interface combinations
checks out of cfg80211.

Signed-off-by: Luciano Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Luciano Coelho and committed by
Johannes Berg
cb2d956d c8866e55

+96 -56
+1
Documentation/DocBook/80211.tmpl
··· 100 100 !Finclude/net/cfg80211.h wdev_priv 101 101 !Finclude/net/cfg80211.h ieee80211_iface_limit 102 102 !Finclude/net/cfg80211.h ieee80211_iface_combination 103 + !Finclude/net/cfg80211.h cfg80211_check_combinations 103 104 </chapter> 104 105 <chapter> 105 106 <title>Actions and configuration</title>
+22
include/net/cfg80211.h
··· 4692 4692 */ 4693 4693 unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy); 4694 4694 4695 + /** 4696 + * cfg80211_check_combinations - check interface combinations 4697 + * 4698 + * @wiphy: the wiphy 4699 + * @num_different_channels: the number of different channels we want 4700 + * to use for verification 4701 + * @radar_detect: a bitmap where each bit corresponds to a channel 4702 + * width where radar detection is needed, as in the definition of 4703 + * &struct ieee80211_iface_combination.@radar_detect_widths 4704 + * @iftype_num: array with the numbers of interfaces of each interface 4705 + * type. The index is the interface type as specified in &enum 4706 + * nl80211_iftype. 4707 + * 4708 + * This function can be called by the driver to check whether a 4709 + * combination of interfaces and their types are allowed according to 4710 + * the interface combinations. 4711 + */ 4712 + int cfg80211_check_combinations(struct wiphy *wiphy, 4713 + const int num_different_channels, 4714 + const u8 radar_detect, 4715 + const int iftype_num[NUM_NL80211_IFTYPES]); 4716 + 4695 4717 /* Logging, debugging and troubleshooting/diagnostic helpers. */ 4696 4718 4697 4719 /* wiphy_printk helpers, similar to dev_printk */
+73 -56
net/wireless/util.c
··· 1268 1268 return res; 1269 1269 } 1270 1270 1271 + int cfg80211_check_combinations(struct wiphy *wiphy, 1272 + const int num_different_channels, 1273 + const u8 radar_detect, 1274 + const int iftype_num[NUM_NL80211_IFTYPES]) 1275 + { 1276 + int i, j, iftype; 1277 + int num_interfaces = 0; 1278 + u32 used_iftypes = 0; 1279 + 1280 + for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { 1281 + num_interfaces += iftype_num[iftype]; 1282 + if (iftype_num[iftype] > 0 && 1283 + !(wiphy->software_iftypes & BIT(iftype))) 1284 + used_iftypes |= BIT(iftype); 1285 + } 1286 + 1287 + for (i = 0; i < wiphy->n_iface_combinations; i++) { 1288 + const struct ieee80211_iface_combination *c; 1289 + struct ieee80211_iface_limit *limits; 1290 + u32 all_iftypes = 0; 1291 + 1292 + c = &wiphy->iface_combinations[i]; 1293 + 1294 + if (num_interfaces > c->max_interfaces) 1295 + continue; 1296 + if (num_different_channels > c->num_different_channels) 1297 + continue; 1298 + 1299 + limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits, 1300 + GFP_KERNEL); 1301 + if (!limits) 1302 + return -ENOMEM; 1303 + 1304 + for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { 1305 + if (wiphy->software_iftypes & BIT(iftype)) 1306 + continue; 1307 + for (j = 0; j < c->n_limits; j++) { 1308 + all_iftypes |= limits[j].types; 1309 + if (!(limits[j].types & BIT(iftype))) 1310 + continue; 1311 + if (limits[j].max < iftype_num[iftype]) 1312 + goto cont; 1313 + limits[j].max -= iftype_num[iftype]; 1314 + } 1315 + } 1316 + 1317 + if (radar_detect && !(c->radar_detect_widths & radar_detect)) 1318 + goto cont; 1319 + 1320 + /* Finally check that all iftypes that we're currently 1321 + * using are actually part of this combination. If they 1322 + * aren't then we can't use this combination and have 1323 + * to continue to the next. 1324 + */ 1325 + if ((all_iftypes & used_iftypes) != used_iftypes) 1326 + goto cont; 1327 + 1328 + /* This combination covered all interface types and 1329 + * supported the requested numbers, so we're good. 1330 + */ 1331 + kfree(limits); 1332 + return 0; 1333 + cont: 1334 + kfree(limits); 1335 + } 1336 + 1337 + return -EBUSY; 1338 + } 1339 + EXPORT_SYMBOL(cfg80211_check_combinations); 1340 + 1271 1341 int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, 1272 1342 struct wireless_dev *wdev, 1273 1343 enum nl80211_iftype iftype, ··· 1346 1276 u8 radar_detect) 1347 1277 { 1348 1278 struct wireless_dev *wdev_iter; 1349 - u32 used_iftypes = BIT(iftype); 1350 1279 int num[NUM_NL80211_IFTYPES]; 1351 1280 struct ieee80211_channel 1352 1281 *used_channels[CFG80211_MAX_NUM_DIFFERENT_CHANNELS]; ··· 1353 1284 enum cfg80211_chan_mode chmode; 1354 1285 int num_different_channels = 0; 1355 1286 int total = 1; 1356 - int i, j; 1287 + int i; 1357 1288 1358 1289 ASSERT_RTNL(); 1359 1290 ··· 1438 1369 1439 1370 num[wdev_iter->iftype]++; 1440 1371 total++; 1441 - used_iftypes |= BIT(wdev_iter->iftype); 1442 1372 } 1443 1373 1444 1374 if (total == 1 && !radar_detect) 1445 1375 return 0; 1446 1376 1447 - for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) { 1448 - const struct ieee80211_iface_combination *c; 1449 - struct ieee80211_iface_limit *limits; 1450 - u32 all_iftypes = 0; 1451 - 1452 - c = &rdev->wiphy.iface_combinations[i]; 1453 - 1454 - if (total > c->max_interfaces) 1455 - continue; 1456 - if (num_different_channels > c->num_different_channels) 1457 - continue; 1458 - 1459 - limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits, 1460 - GFP_KERNEL); 1461 - if (!limits) 1462 - return -ENOMEM; 1463 - 1464 - for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { 1465 - if (rdev->wiphy.software_iftypes & BIT(iftype)) 1466 - continue; 1467 - for (j = 0; j < c->n_limits; j++) { 1468 - all_iftypes |= limits[j].types; 1469 - if (!(limits[j].types & BIT(iftype))) 1470 - continue; 1471 - if (limits[j].max < num[iftype]) 1472 - goto cont; 1473 - limits[j].max -= num[iftype]; 1474 - } 1475 - } 1476 - 1477 - if (radar_detect && !(c->radar_detect_widths & radar_detect)) 1478 - goto cont; 1479 - 1480 - /* 1481 - * Finally check that all iftypes that we're currently 1482 - * using are actually part of this combination. If they 1483 - * aren't then we can't use this combination and have 1484 - * to continue to the next. 1485 - */ 1486 - if ((all_iftypes & used_iftypes) != used_iftypes) 1487 - goto cont; 1488 - 1489 - /* 1490 - * This combination covered all interface types and 1491 - * supported the requested numbers, so we're good. 1492 - */ 1493 - kfree(limits); 1494 - return 0; 1495 - cont: 1496 - kfree(limits); 1497 - } 1498 - 1499 - return -EBUSY; 1377 + return cfg80211_check_combinations(&rdev->wiphy, num_different_channels, 1378 + radar_detect, num); 1500 1379 } 1501 1380 1502 1381 int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,