Skip to content

Commit

Permalink
cfg80211: save multi-bssid properties
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sara Sharon authored and Johannes Berg committed Feb 8, 2019
1 parent 7ece9c3 commit 0cd01ef
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 21 deletions.
5 changes: 5 additions & 0 deletions include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -2038,6 +2038,8 @@ struct cfg80211_bss_ies {
* @signal: signal strength value (type depends on the wiphy's signal_type)
* @chains: bitmask for filled values in @chain_signal.
* @chain_signal: per-chain signal strength of last received BSS in dBm.
* @bssid_index: index in the multiple BSS set
* @max_bssid_indicator: max number of members in the BSS set
* @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
*/
struct cfg80211_bss {
Expand All @@ -2061,6 +2063,9 @@ struct cfg80211_bss {
u8 chains;
s8 chain_signal[IEEE80211_MAX_CHAINS];

u8 bssid_index;
u8 max_bssid_indicator;

u8 priv[0] __aligned(sizeof(void *));
};

Expand Down
69 changes: 48 additions & 21 deletions net/wireless/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,11 +1022,16 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev,
return true;
}

struct cfg80211_non_tx_bss {
struct cfg80211_bss *tx_bss;
u8 max_bssid_indicator;
u8 bssid_index;
};

/* Returned bss is reference counted and must be cleaned up appropriately. */
static struct cfg80211_internal_bss *
cfg80211_bss_update(struct cfg80211_registered_device *rdev,
struct cfg80211_internal_bss *tmp,
struct cfg80211_bss *trans_bss,
bool signal_valid)
{
struct cfg80211_internal_bss *found = NULL;
Expand Down Expand Up @@ -1126,6 +1131,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
memcpy(found->pub.chain_signal, tmp->pub.chain_signal,
IEEE80211_MAX_CHAINS);
ether_addr_copy(found->parent_bssid, tmp->parent_bssid);
found->pub.max_bssid_indicator = tmp->pub.max_bssid_indicator;
found->pub.bssid_index = tmp->pub.bssid_index;
} else {
struct cfg80211_internal_bss *new;
struct cfg80211_internal_bss *hidden;
Expand Down Expand Up @@ -1185,13 +1192,13 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
}

/* This must be before the call to bss_ref_get */
if (trans_bss) {
if (tmp->pub.transmitted_bss) {
struct cfg80211_internal_bss *pbss =
container_of(trans_bss,
container_of(tmp->pub.transmitted_bss,
struct cfg80211_internal_bss,
pub);

new->pub.transmitted_bss = trans_bss;
new->pub.transmitted_bss = tmp->pub.transmitted_bss;
bss_ref_get(rdev, pbss);
}

Expand Down Expand Up @@ -1289,7 +1296,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
enum cfg80211_bss_frame_type ftype,
const u8 *bssid, u64 tsf, u16 capability,
u16 beacon_interval, const u8 *ie, size_t ielen,
struct cfg80211_bss *trans_bss,
struct cfg80211_non_tx_bss *non_tx_data,
gfp_t gfp)
{
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
Expand Down Expand Up @@ -1318,6 +1325,11 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
tmp.pub.beacon_interval = beacon_interval;
tmp.pub.capability = capability;
tmp.ts_boottime = data->boottime_ns;
if (non_tx_data) {
tmp.pub.transmitted_bss = non_tx_data->tx_bss;
tmp.pub.bssid_index = non_tx_data->bssid_index;
tmp.pub.max_bssid_indicator = non_tx_data->max_bssid_indicator;
}

/*
* If we do not know here whether the IEs are from a Beacon or Probe
Expand Down Expand Up @@ -1350,8 +1362,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,

signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
wiphy->max_adj_channel_rssi_comp;
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, trans_bss,
signal_valid);
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid);
if (!res)
return NULL;

Expand All @@ -1365,11 +1376,12 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
regulatory_hint_found_beacon(wiphy, channel, gfp);
}

if (trans_bss) {
if (non_tx_data && non_tx_data->tx_bss) {
/* this is a nontransmitting bss, we need to add it to
* transmitting bss' list if it is not there
*/
if (cfg80211_add_nontrans_list(trans_bss, &res->pub)) {
if (cfg80211_add_nontrans_list(non_tx_data->tx_bss,
&res->pub)) {
if (__cfg80211_unlink_bss(rdev, res))
rdev->bss_generation++;
}
Expand All @@ -1386,7 +1398,7 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
const u8 *bssid, u64 tsf,
u16 beacon_interval, const u8 *ie,
size_t ielen,
struct cfg80211_bss *trans_bss,
struct cfg80211_non_tx_bss *non_tx_data,
gfp_t gfp)
{
const u8 *mbssid_index_ie;
Expand All @@ -1397,7 +1409,7 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
u16 capability;
struct cfg80211_bss *bss;

if (!trans_bss)
if (!non_tx_data)
return;
if (!cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
return;
Expand Down Expand Up @@ -1439,8 +1451,12 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
continue;
}

cfg80211_gen_new_bssid(bssid, elem->data[0],
mbssid_index_ie[2],
non_tx_data->bssid_index = mbssid_index_ie[2];
non_tx_data->max_bssid_indicator = elem->data[0];

cfg80211_gen_new_bssid(bssid,
non_tx_data->max_bssid_indicator,
non_tx_data->bssid_index,
new_bssid);
memset(new_ie, 0, IEEE80211_MAX_DATA_LEN);
new_ie_len = cfg80211_gen_new_ie(ie, ielen, sub->data,
Expand All @@ -1457,7 +1473,8 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
beacon_interval,
new_ie,
new_ie_len,
trans_bss, gfp);
non_tx_data,
gfp);
if (!bss)
break;
cfg80211_put_bss(wiphy, bss);
Expand All @@ -1476,12 +1493,15 @@ cfg80211_inform_bss_data(struct wiphy *wiphy,
gfp_t gfp)
{
struct cfg80211_bss *res;
struct cfg80211_non_tx_bss non_tx_data;

res = cfg80211_inform_single_bss_data(wiphy, data, ftype, bssid, tsf,
capability, beacon_interval, ie,
ielen, NULL, gfp);
non_tx_data.tx_bss = res;
cfg80211_parse_mbssid_data(wiphy, data, ftype, bssid, tsf,
beacon_interval, ie, ielen, res, gfp);
beacon_interval, ie, ielen, &non_tx_data,
gfp);
return res;
}
EXPORT_SYMBOL(cfg80211_inform_bss_data);
Expand All @@ -1490,7 +1510,7 @@ static void
cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy,
struct cfg80211_inform_bss *data,
struct ieee80211_mgmt *mgmt, size_t len,
struct cfg80211_bss *trans_bss,
struct cfg80211_non_tx_bss *non_tx_data,
gfp_t gfp)
{
enum cfg80211_bss_frame_type ftype;
Expand All @@ -1504,7 +1524,7 @@ cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy,
cfg80211_parse_mbssid_data(wiphy, data, ftype, mgmt->bssid,
le64_to_cpu(mgmt->u.probe_resp.timestamp),
le16_to_cpu(mgmt->u.probe_resp.beacon_int),
ie, ielen, trans_bss, gfp);
ie, ielen, non_tx_data, gfp);
}

static void
Expand Down Expand Up @@ -1594,7 +1614,7 @@ static struct cfg80211_bss *
cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
struct cfg80211_inform_bss *data,
struct ieee80211_mgmt *mgmt, size_t len,
struct cfg80211_bss *trans_bss,
struct cfg80211_non_tx_bss *non_tx_data,
gfp_t gfp)
{
struct cfg80211_internal_bss tmp = {}, *res;
Expand Down Expand Up @@ -1653,11 +1673,15 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
tmp.pub.chains = data->chains;
memcpy(tmp.pub.chain_signal, data->chain_signal, IEEE80211_MAX_CHAINS);
ether_addr_copy(tmp.parent_bssid, data->parent_bssid);
if (non_tx_data) {
tmp.pub.transmitted_bss = non_tx_data->tx_bss;
tmp.pub.bssid_index = non_tx_data->bssid_index;
tmp.pub.max_bssid_indicator = non_tx_data->max_bssid_indicator;
}

signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
wiphy->max_adj_channel_rssi_comp;
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, trans_bss,
signal_valid);
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid);
if (!res)
return NULL;

Expand Down Expand Up @@ -1687,6 +1711,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
const struct cfg80211_bss_ies *ies1, *ies2;
size_t ielen = len - offsetof(struct ieee80211_mgmt,
u.probe_resp.variable);
struct cfg80211_non_tx_bss non_tx_data;

res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt,
len, NULL, gfp);
Expand All @@ -1697,8 +1722,10 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
!cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ie, ielen))
return res;

non_tx_data.tx_bss = res;
/* process each non-transmitting bss */
cfg80211_parse_mbssid_frame_data(wiphy, data, mgmt, len, res, gfp);
cfg80211_parse_mbssid_frame_data(wiphy, data, mgmt, len,
&non_tx_data, gfp);

/* check if the res has other nontransmitting bss which is not
* in MBSSID IE
Expand Down

0 comments on commit 0cd01ef

Please sign in to comment.