diff options
author | Sara Sharon <sara.sharon@intel.com> | 2019-01-22 02:50:50 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2019-02-08 07:51:50 -0500 |
commit | 0cd01efb03396c5368b1a32eed0ccb2aa453bdc8 (patch) | |
tree | 6588f20889f7c16fde761db03817dc426d688b13 /net/wireless | |
parent | 7ece9c372b21635120e7ab5ea3fc41ce9892ead8 (diff) |
cfg80211: save multi-bssid properties
When the new IEs are generated, the multiple BSSID elements
are not saved. Save aside properties that are needed later
for PS.
Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/scan.c | 69 |
1 files changed, 48 insertions, 21 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index f1b06e9c1038..387e5f868684 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -1022,11 +1022,16 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev, | |||
1022 | return true; | 1022 | return true; |
1023 | } | 1023 | } |
1024 | 1024 | ||
1025 | struct cfg80211_non_tx_bss { | ||
1026 | struct cfg80211_bss *tx_bss; | ||
1027 | u8 max_bssid_indicator; | ||
1028 | u8 bssid_index; | ||
1029 | }; | ||
1030 | |||
1025 | /* Returned bss is reference counted and must be cleaned up appropriately. */ | 1031 | /* Returned bss is reference counted and must be cleaned up appropriately. */ |
1026 | static struct cfg80211_internal_bss * | 1032 | static struct cfg80211_internal_bss * |
1027 | cfg80211_bss_update(struct cfg80211_registered_device *rdev, | 1033 | cfg80211_bss_update(struct cfg80211_registered_device *rdev, |
1028 | struct cfg80211_internal_bss *tmp, | 1034 | struct cfg80211_internal_bss *tmp, |
1029 | struct cfg80211_bss *trans_bss, | ||
1030 | bool signal_valid) | 1035 | bool signal_valid) |
1031 | { | 1036 | { |
1032 | struct cfg80211_internal_bss *found = NULL; | 1037 | struct cfg80211_internal_bss *found = NULL; |
@@ -1126,6 +1131,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, | |||
1126 | memcpy(found->pub.chain_signal, tmp->pub.chain_signal, | 1131 | memcpy(found->pub.chain_signal, tmp->pub.chain_signal, |
1127 | IEEE80211_MAX_CHAINS); | 1132 | IEEE80211_MAX_CHAINS); |
1128 | ether_addr_copy(found->parent_bssid, tmp->parent_bssid); | 1133 | ether_addr_copy(found->parent_bssid, tmp->parent_bssid); |
1134 | found->pub.max_bssid_indicator = tmp->pub.max_bssid_indicator; | ||
1135 | found->pub.bssid_index = tmp->pub.bssid_index; | ||
1129 | } else { | 1136 | } else { |
1130 | struct cfg80211_internal_bss *new; | 1137 | struct cfg80211_internal_bss *new; |
1131 | struct cfg80211_internal_bss *hidden; | 1138 | struct cfg80211_internal_bss *hidden; |
@@ -1185,13 +1192,13 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, | |||
1185 | } | 1192 | } |
1186 | 1193 | ||
1187 | /* This must be before the call to bss_ref_get */ | 1194 | /* This must be before the call to bss_ref_get */ |
1188 | if (trans_bss) { | 1195 | if (tmp->pub.transmitted_bss) { |
1189 | struct cfg80211_internal_bss *pbss = | 1196 | struct cfg80211_internal_bss *pbss = |
1190 | container_of(trans_bss, | 1197 | container_of(tmp->pub.transmitted_bss, |
1191 | struct cfg80211_internal_bss, | 1198 | struct cfg80211_internal_bss, |
1192 | pub); | 1199 | pub); |
1193 | 1200 | ||
1194 | new->pub.transmitted_bss = trans_bss; | 1201 | new->pub.transmitted_bss = tmp->pub.transmitted_bss; |
1195 | bss_ref_get(rdev, pbss); | 1202 | bss_ref_get(rdev, pbss); |
1196 | } | 1203 | } |
1197 | 1204 | ||
@@ -1289,7 +1296,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, | |||
1289 | enum cfg80211_bss_frame_type ftype, | 1296 | enum cfg80211_bss_frame_type ftype, |
1290 | const u8 *bssid, u64 tsf, u16 capability, | 1297 | const u8 *bssid, u64 tsf, u16 capability, |
1291 | u16 beacon_interval, const u8 *ie, size_t ielen, | 1298 | u16 beacon_interval, const u8 *ie, size_t ielen, |
1292 | struct cfg80211_bss *trans_bss, | 1299 | struct cfg80211_non_tx_bss *non_tx_data, |
1293 | gfp_t gfp) | 1300 | gfp_t gfp) |
1294 | { | 1301 | { |
1295 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); | 1302 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
@@ -1318,6 +1325,11 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, | |||
1318 | tmp.pub.beacon_interval = beacon_interval; | 1325 | tmp.pub.beacon_interval = beacon_interval; |
1319 | tmp.pub.capability = capability; | 1326 | tmp.pub.capability = capability; |
1320 | tmp.ts_boottime = data->boottime_ns; | 1327 | tmp.ts_boottime = data->boottime_ns; |
1328 | if (non_tx_data) { | ||
1329 | tmp.pub.transmitted_bss = non_tx_data->tx_bss; | ||
1330 | tmp.pub.bssid_index = non_tx_data->bssid_index; | ||
1331 | tmp.pub.max_bssid_indicator = non_tx_data->max_bssid_indicator; | ||
1332 | } | ||
1321 | 1333 | ||
1322 | /* | 1334 | /* |
1323 | * If we do not know here whether the IEs are from a Beacon or Probe | 1335 | * If we do not know here whether the IEs are from a Beacon or Probe |
@@ -1350,8 +1362,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, | |||
1350 | 1362 | ||
1351 | signal_valid = abs(data->chan->center_freq - channel->center_freq) <= | 1363 | signal_valid = abs(data->chan->center_freq - channel->center_freq) <= |
1352 | wiphy->max_adj_channel_rssi_comp; | 1364 | wiphy->max_adj_channel_rssi_comp; |
1353 | res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, trans_bss, | 1365 | res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid); |
1354 | signal_valid); | ||
1355 | if (!res) | 1366 | if (!res) |
1356 | return NULL; | 1367 | return NULL; |
1357 | 1368 | ||
@@ -1365,11 +1376,12 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, | |||
1365 | regulatory_hint_found_beacon(wiphy, channel, gfp); | 1376 | regulatory_hint_found_beacon(wiphy, channel, gfp); |
1366 | } | 1377 | } |
1367 | 1378 | ||
1368 | if (trans_bss) { | 1379 | if (non_tx_data && non_tx_data->tx_bss) { |
1369 | /* this is a nontransmitting bss, we need to add it to | 1380 | /* this is a nontransmitting bss, we need to add it to |
1370 | * transmitting bss' list if it is not there | 1381 | * transmitting bss' list if it is not there |
1371 | */ | 1382 | */ |
1372 | if (cfg80211_add_nontrans_list(trans_bss, &res->pub)) { | 1383 | if (cfg80211_add_nontrans_list(non_tx_data->tx_bss, |
1384 | &res->pub)) { | ||
1373 | if (__cfg80211_unlink_bss(rdev, res)) | 1385 | if (__cfg80211_unlink_bss(rdev, res)) |
1374 | rdev->bss_generation++; | 1386 | rdev->bss_generation++; |
1375 | } | 1387 | } |
@@ -1386,7 +1398,7 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, | |||
1386 | const u8 *bssid, u64 tsf, | 1398 | const u8 *bssid, u64 tsf, |
1387 | u16 beacon_interval, const u8 *ie, | 1399 | u16 beacon_interval, const u8 *ie, |
1388 | size_t ielen, | 1400 | size_t ielen, |
1389 | struct cfg80211_bss *trans_bss, | 1401 | struct cfg80211_non_tx_bss *non_tx_data, |
1390 | gfp_t gfp) | 1402 | gfp_t gfp) |
1391 | { | 1403 | { |
1392 | const u8 *mbssid_index_ie; | 1404 | const u8 *mbssid_index_ie; |
@@ -1397,7 +1409,7 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, | |||
1397 | u16 capability; | 1409 | u16 capability; |
1398 | struct cfg80211_bss *bss; | 1410 | struct cfg80211_bss *bss; |
1399 | 1411 | ||
1400 | if (!trans_bss) | 1412 | if (!non_tx_data) |
1401 | return; | 1413 | return; |
1402 | if (!cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen)) | 1414 | if (!cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen)) |
1403 | return; | 1415 | return; |
@@ -1439,8 +1451,12 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, | |||
1439 | continue; | 1451 | continue; |
1440 | } | 1452 | } |
1441 | 1453 | ||
1442 | cfg80211_gen_new_bssid(bssid, elem->data[0], | 1454 | non_tx_data->bssid_index = mbssid_index_ie[2]; |
1443 | mbssid_index_ie[2], | 1455 | non_tx_data->max_bssid_indicator = elem->data[0]; |
1456 | |||
1457 | cfg80211_gen_new_bssid(bssid, | ||
1458 | non_tx_data->max_bssid_indicator, | ||
1459 | non_tx_data->bssid_index, | ||
1444 | new_bssid); | 1460 | new_bssid); |
1445 | memset(new_ie, 0, IEEE80211_MAX_DATA_LEN); | 1461 | memset(new_ie, 0, IEEE80211_MAX_DATA_LEN); |
1446 | new_ie_len = cfg80211_gen_new_ie(ie, ielen, sub->data, | 1462 | new_ie_len = cfg80211_gen_new_ie(ie, ielen, sub->data, |
@@ -1457,7 +1473,8 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, | |||
1457 | beacon_interval, | 1473 | beacon_interval, |
1458 | new_ie, | 1474 | new_ie, |
1459 | new_ie_len, | 1475 | new_ie_len, |
1460 | trans_bss, gfp); | 1476 | non_tx_data, |
1477 | gfp); | ||
1461 | if (!bss) | 1478 | if (!bss) |
1462 | break; | 1479 | break; |
1463 | cfg80211_put_bss(wiphy, bss); | 1480 | cfg80211_put_bss(wiphy, bss); |
@@ -1476,12 +1493,15 @@ cfg80211_inform_bss_data(struct wiphy *wiphy, | |||
1476 | gfp_t gfp) | 1493 | gfp_t gfp) |
1477 | { | 1494 | { |
1478 | struct cfg80211_bss *res; | 1495 | struct cfg80211_bss *res; |
1496 | struct cfg80211_non_tx_bss non_tx_data; | ||
1479 | 1497 | ||
1480 | res = cfg80211_inform_single_bss_data(wiphy, data, ftype, bssid, tsf, | 1498 | res = cfg80211_inform_single_bss_data(wiphy, data, ftype, bssid, tsf, |
1481 | capability, beacon_interval, ie, | 1499 | capability, beacon_interval, ie, |
1482 | ielen, NULL, gfp); | 1500 | ielen, NULL, gfp); |
1501 | non_tx_data.tx_bss = res; | ||
1483 | cfg80211_parse_mbssid_data(wiphy, data, ftype, bssid, tsf, | 1502 | cfg80211_parse_mbssid_data(wiphy, data, ftype, bssid, tsf, |
1484 | beacon_interval, ie, ielen, res, gfp); | 1503 | beacon_interval, ie, ielen, &non_tx_data, |
1504 | gfp); | ||
1485 | return res; | 1505 | return res; |
1486 | } | 1506 | } |
1487 | EXPORT_SYMBOL(cfg80211_inform_bss_data); | 1507 | EXPORT_SYMBOL(cfg80211_inform_bss_data); |
@@ -1490,7 +1510,7 @@ static void | |||
1490 | cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy, | 1510 | cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy, |
1491 | struct cfg80211_inform_bss *data, | 1511 | struct cfg80211_inform_bss *data, |
1492 | struct ieee80211_mgmt *mgmt, size_t len, | 1512 | struct ieee80211_mgmt *mgmt, size_t len, |
1493 | struct cfg80211_bss *trans_bss, | 1513 | struct cfg80211_non_tx_bss *non_tx_data, |
1494 | gfp_t gfp) | 1514 | gfp_t gfp) |
1495 | { | 1515 | { |
1496 | enum cfg80211_bss_frame_type ftype; | 1516 | enum cfg80211_bss_frame_type ftype; |
@@ -1504,7 +1524,7 @@ cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy, | |||
1504 | cfg80211_parse_mbssid_data(wiphy, data, ftype, mgmt->bssid, | 1524 | cfg80211_parse_mbssid_data(wiphy, data, ftype, mgmt->bssid, |
1505 | le64_to_cpu(mgmt->u.probe_resp.timestamp), | 1525 | le64_to_cpu(mgmt->u.probe_resp.timestamp), |
1506 | le16_to_cpu(mgmt->u.probe_resp.beacon_int), | 1526 | le16_to_cpu(mgmt->u.probe_resp.beacon_int), |
1507 | ie, ielen, trans_bss, gfp); | 1527 | ie, ielen, non_tx_data, gfp); |
1508 | } | 1528 | } |
1509 | 1529 | ||
1510 | static void | 1530 | static void |
@@ -1594,7 +1614,7 @@ static struct cfg80211_bss * | |||
1594 | cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy, | 1614 | cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy, |
1595 | struct cfg80211_inform_bss *data, | 1615 | struct cfg80211_inform_bss *data, |
1596 | struct ieee80211_mgmt *mgmt, size_t len, | 1616 | struct ieee80211_mgmt *mgmt, size_t len, |
1597 | struct cfg80211_bss *trans_bss, | 1617 | struct cfg80211_non_tx_bss *non_tx_data, |
1598 | gfp_t gfp) | 1618 | gfp_t gfp) |
1599 | { | 1619 | { |
1600 | struct cfg80211_internal_bss tmp = {}, *res; | 1620 | struct cfg80211_internal_bss tmp = {}, *res; |
@@ -1653,11 +1673,15 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy, | |||
1653 | tmp.pub.chains = data->chains; | 1673 | tmp.pub.chains = data->chains; |
1654 | memcpy(tmp.pub.chain_signal, data->chain_signal, IEEE80211_MAX_CHAINS); | 1674 | memcpy(tmp.pub.chain_signal, data->chain_signal, IEEE80211_MAX_CHAINS); |
1655 | ether_addr_copy(tmp.parent_bssid, data->parent_bssid); | 1675 | ether_addr_copy(tmp.parent_bssid, data->parent_bssid); |
1676 | if (non_tx_data) { | ||
1677 | tmp.pub.transmitted_bss = non_tx_data->tx_bss; | ||
1678 | tmp.pub.bssid_index = non_tx_data->bssid_index; | ||
1679 | tmp.pub.max_bssid_indicator = non_tx_data->max_bssid_indicator; | ||
1680 | } | ||
1656 | 1681 | ||
1657 | signal_valid = abs(data->chan->center_freq - channel->center_freq) <= | 1682 | signal_valid = abs(data->chan->center_freq - channel->center_freq) <= |
1658 | wiphy->max_adj_channel_rssi_comp; | 1683 | wiphy->max_adj_channel_rssi_comp; |
1659 | res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, trans_bss, | 1684 | res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid); |
1660 | signal_valid); | ||
1661 | if (!res) | 1685 | if (!res) |
1662 | return NULL; | 1686 | return NULL; |
1663 | 1687 | ||
@@ -1687,6 +1711,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, | |||
1687 | const struct cfg80211_bss_ies *ies1, *ies2; | 1711 | const struct cfg80211_bss_ies *ies1, *ies2; |
1688 | size_t ielen = len - offsetof(struct ieee80211_mgmt, | 1712 | size_t ielen = len - offsetof(struct ieee80211_mgmt, |
1689 | u.probe_resp.variable); | 1713 | u.probe_resp.variable); |
1714 | struct cfg80211_non_tx_bss non_tx_data; | ||
1690 | 1715 | ||
1691 | res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt, | 1716 | res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt, |
1692 | len, NULL, gfp); | 1717 | len, NULL, gfp); |
@@ -1697,8 +1722,10 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, | |||
1697 | !cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ie, ielen)) | 1722 | !cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ie, ielen)) |
1698 | return res; | 1723 | return res; |
1699 | 1724 | ||
1725 | non_tx_data.tx_bss = res; | ||
1700 | /* process each non-transmitting bss */ | 1726 | /* process each non-transmitting bss */ |
1701 | cfg80211_parse_mbssid_frame_data(wiphy, data, mgmt, len, res, gfp); | 1727 | cfg80211_parse_mbssid_frame_data(wiphy, data, mgmt, len, |
1728 | &non_tx_data, gfp); | ||
1702 | 1729 | ||
1703 | /* check if the res has other nontransmitting bss which is not | 1730 | /* check if the res has other nontransmitting bss which is not |
1704 | * in MBSSID IE | 1731 | * in MBSSID IE |