summaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2019-01-22 02:50:50 -0500
committerJohannes Berg <johannes.berg@intel.com>2019-02-08 07:51:50 -0500
commit0cd01efb03396c5368b1a32eed0ccb2aa453bdc8 (patch)
tree6588f20889f7c16fde761db03817dc426d688b13 /net/wireless
parent7ece9c372b21635120e7ab5ea3fc41ce9892ead8 (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.c69
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
1025struct 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. */
1026static struct cfg80211_internal_bss * 1032static struct cfg80211_internal_bss *
1027cfg80211_bss_update(struct cfg80211_registered_device *rdev, 1033cfg80211_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}
1487EXPORT_SYMBOL(cfg80211_inform_bss_data); 1507EXPORT_SYMBOL(cfg80211_inform_bss_data);
@@ -1490,7 +1510,7 @@ static void
1490cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy, 1510cfg80211_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
1510static void 1530static void
@@ -1594,7 +1614,7 @@ static struct cfg80211_bss *
1594cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy, 1614cfg80211_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