diff options
| author | Arik Nemtsov <arik@wizery.com> | 2015-03-18 02:46:08 -0400 |
|---|---|---|
| committer | Johannes Berg <johannes.berg@intel.com> | 2015-03-30 04:26:36 -0400 |
| commit | a38700dd486f3def34cef47d00e2d360a04a7bc8 (patch) | |
| tree | 8f2deebf8c3c4b9079f844249f3c5201e989ae74 /net/wireless | |
| parent | 3a323d4e17dd5a84f6ad036e6f985d263ca973ed (diff) | |
cfg/mac80211: add regulatory classes IE during TDLS setup
Seems Broadcom TDLS peers (Nexus 5, Xperia Z3) refuse to allow TDLS
connection when channel-switching is supported but the regulatory
classes IE is missing from the setup request.
Add a chandef to reg-class translation function to cfg80211 and use it
to add the required IE during setup. For now add only the current
regulatory class as supported - it is enough to resolve the
compatibility issue.
Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
| -rw-r--r-- | net/wireless/util.c | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/net/wireless/util.c b/net/wireless/util.c index f7b35980af69..f218b151530a 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
| @@ -1314,6 +1314,135 @@ bool ieee80211_operating_class_to_band(u8 operating_class, | |||
| 1314 | } | 1314 | } |
| 1315 | EXPORT_SYMBOL(ieee80211_operating_class_to_band); | 1315 | EXPORT_SYMBOL(ieee80211_operating_class_to_band); |
| 1316 | 1316 | ||
| 1317 | bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef, | ||
| 1318 | u8 *op_class) | ||
| 1319 | { | ||
| 1320 | u8 vht_opclass; | ||
| 1321 | u16 freq = chandef->center_freq1; | ||
| 1322 | |||
| 1323 | if (freq >= 2412 && freq <= 2472) { | ||
| 1324 | if (chandef->width > NL80211_CHAN_WIDTH_40) | ||
| 1325 | return false; | ||
| 1326 | |||
| 1327 | /* 2.407 GHz, channels 1..13 */ | ||
| 1328 | if (chandef->width == NL80211_CHAN_WIDTH_40) { | ||
| 1329 | if (freq > chandef->chan->center_freq) | ||
| 1330 | *op_class = 83; /* HT40+ */ | ||
| 1331 | else | ||
| 1332 | *op_class = 84; /* HT40- */ | ||
| 1333 | } else { | ||
| 1334 | *op_class = 81; | ||
| 1335 | } | ||
| 1336 | |||
| 1337 | return true; | ||
| 1338 | } | ||
| 1339 | |||
| 1340 | if (freq == 2484) { | ||
| 1341 | if (chandef->width > NL80211_CHAN_WIDTH_40) | ||
| 1342 | return false; | ||
| 1343 | |||
| 1344 | *op_class = 82; /* channel 14 */ | ||
| 1345 | return true; | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | switch (chandef->width) { | ||
| 1349 | case NL80211_CHAN_WIDTH_80: | ||
| 1350 | vht_opclass = 128; | ||
| 1351 | break; | ||
| 1352 | case NL80211_CHAN_WIDTH_160: | ||
| 1353 | vht_opclass = 129; | ||
| 1354 | break; | ||
| 1355 | case NL80211_CHAN_WIDTH_80P80: | ||
| 1356 | vht_opclass = 130; | ||
| 1357 | break; | ||
| 1358 | case NL80211_CHAN_WIDTH_10: | ||
| 1359 | case NL80211_CHAN_WIDTH_5: | ||
| 1360 | return false; /* unsupported for now */ | ||
| 1361 | default: | ||
| 1362 | vht_opclass = 0; | ||
| 1363 | break; | ||
| 1364 | } | ||
| 1365 | |||
| 1366 | /* 5 GHz, channels 36..48 */ | ||
| 1367 | if (freq >= 5180 && freq <= 5240) { | ||
| 1368 | if (vht_opclass) { | ||
| 1369 | *op_class = vht_opclass; | ||
| 1370 | } else if (chandef->width == NL80211_CHAN_WIDTH_40) { | ||
| 1371 | if (freq > chandef->chan->center_freq) | ||
| 1372 | *op_class = 116; | ||
| 1373 | else | ||
| 1374 | *op_class = 117; | ||
| 1375 | } else { | ||
| 1376 | *op_class = 115; | ||
| 1377 | } | ||
| 1378 | |||
| 1379 | return true; | ||
| 1380 | } | ||
| 1381 | |||
| 1382 | /* 5 GHz, channels 52..64 */ | ||
| 1383 | if (freq >= 5260 && freq <= 5320) { | ||
| 1384 | if (vht_opclass) { | ||
| 1385 | *op_class = vht_opclass; | ||
| 1386 | } else if (chandef->width == NL80211_CHAN_WIDTH_40) { | ||
| 1387 | if (freq > chandef->chan->center_freq) | ||
| 1388 | *op_class = 119; | ||
| 1389 | else | ||
| 1390 | *op_class = 120; | ||
| 1391 | } else { | ||
| 1392 | *op_class = 118; | ||
| 1393 | } | ||
| 1394 | |||
| 1395 | return true; | ||
| 1396 | } | ||
| 1397 | |||
| 1398 | /* 5 GHz, channels 100..144 */ | ||
| 1399 | if (freq >= 5500 && freq <= 5720) { | ||
| 1400 | if (vht_opclass) { | ||
| 1401 | *op_class = vht_opclass; | ||
| 1402 | } else if (chandef->width == NL80211_CHAN_WIDTH_40) { | ||
| 1403 | if (freq > chandef->chan->center_freq) | ||
| 1404 | *op_class = 122; | ||
| 1405 | else | ||
| 1406 | *op_class = 123; | ||
| 1407 | } else { | ||
| 1408 | *op_class = 121; | ||
| 1409 | } | ||
| 1410 | |||
| 1411 | return true; | ||
| 1412 | } | ||
| 1413 | |||
| 1414 | /* 5 GHz, channels 149..169 */ | ||
| 1415 | if (freq >= 5745 && freq <= 5845) { | ||
| 1416 | if (vht_opclass) { | ||
| 1417 | *op_class = vht_opclass; | ||
| 1418 | } else if (chandef->width == NL80211_CHAN_WIDTH_40) { | ||
| 1419 | if (freq > chandef->chan->center_freq) | ||
| 1420 | *op_class = 126; | ||
| 1421 | else | ||
| 1422 | *op_class = 127; | ||
| 1423 | } else if (freq <= 5805) { | ||
| 1424 | *op_class = 124; | ||
| 1425 | } else { | ||
| 1426 | *op_class = 125; | ||
| 1427 | } | ||
| 1428 | |||
| 1429 | return true; | ||
| 1430 | } | ||
| 1431 | |||
| 1432 | /* 56.16 GHz, channel 1..4 */ | ||
| 1433 | if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) { | ||
| 1434 | if (chandef->width >= NL80211_CHAN_WIDTH_40) | ||
| 1435 | return false; | ||
| 1436 | |||
| 1437 | *op_class = 180; | ||
| 1438 | return true; | ||
| 1439 | } | ||
| 1440 | |||
| 1441 | /* not supported yet */ | ||
| 1442 | return false; | ||
| 1443 | } | ||
| 1444 | EXPORT_SYMBOL(ieee80211_chandef_to_operating_class); | ||
| 1445 | |||
| 1317 | int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, | 1446 | int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, |
| 1318 | u32 beacon_int) | 1447 | u32 beacon_int) |
| 1319 | { | 1448 | { |
