提交 8a4988d1 编写于 作者: J Janusz.Dziedzic@tieto.com 提交者: Johannes Berg

mac80211: IBSS: refactor ieee80211_rx_bss_info

Put station specific code in ieee80211_update_sta_info
function.
Signed-off-by: NJanusz Dziedzic <janusz.dziedzic@tieto.com>
Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
上级 d66c2582
...@@ -965,110 +965,124 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, ...@@ -965,110 +965,124 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0, 0); mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0, 0);
} }
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_mgmt *mgmt, size_t len,
struct ieee80211_rx_status *rx_status, struct ieee80211_rx_status *rx_status,
struct ieee802_11_elems *elems) struct ieee802_11_elems *elems,
struct ieee80211_channel *channel)
{ {
struct ieee80211_local *local = sdata->local;
struct cfg80211_bss *cbss;
struct ieee80211_bss *bss;
struct sta_info *sta; struct sta_info *sta;
struct ieee80211_channel *channel;
u64 beacon_timestamp, rx_timestamp;
u32 supp_rates = 0;
enum ieee80211_band band = rx_status->band; enum ieee80211_band band = rx_status->band;
enum nl80211_bss_scan_width scan_width; enum nl80211_bss_scan_width scan_width;
struct ieee80211_local *local = sdata->local;
struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
bool rates_updated = false; bool rates_updated = false;
u32 supp_rates = 0;
channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq); if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
if (!channel)
return; return;
if (sdata->vif.type == NL80211_IFTYPE_ADHOC && if (!ether_addr_equal(mgmt->bssid, sdata->u.ibss.bssid))
ether_addr_equal(mgmt->bssid, sdata->u.ibss.bssid)) { return;
rcu_read_lock(); rcu_read_lock();
sta = sta_info_get(sdata, mgmt->sa); sta = sta_info_get(sdata, mgmt->sa);
if (elems->supp_rates) { if (elems->supp_rates) {
supp_rates = ieee80211_sta_get_rates(sdata, elems, supp_rates = ieee80211_sta_get_rates(sdata, elems,
band, NULL); band, NULL);
if (sta) { if (sta) {
u32 prev_rates; u32 prev_rates;
prev_rates = sta->sta.supp_rates[band]; prev_rates = sta->sta.supp_rates[band];
/* make sure mandatory rates are always added */ /* make sure mandatory rates are always added */
scan_width = NL80211_BSS_CHAN_WIDTH_20; scan_width = NL80211_BSS_CHAN_WIDTH_20;
if (rx_status->flag & RX_FLAG_5MHZ) if (rx_status->flag & RX_FLAG_5MHZ)
scan_width = NL80211_BSS_CHAN_WIDTH_5; scan_width = NL80211_BSS_CHAN_WIDTH_5;
if (rx_status->flag & RX_FLAG_10MHZ) if (rx_status->flag & RX_FLAG_10MHZ)
scan_width = NL80211_BSS_CHAN_WIDTH_10; scan_width = NL80211_BSS_CHAN_WIDTH_10;
sta->sta.supp_rates[band] = supp_rates | sta->sta.supp_rates[band] = supp_rates |
ieee80211_mandatory_rates(sband, ieee80211_mandatory_rates(sband, scan_width);
scan_width); if (sta->sta.supp_rates[band] != prev_rates) {
if (sta->sta.supp_rates[band] != prev_rates) { ibss_dbg(sdata,
ibss_dbg(sdata, "updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n",
"updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", sta->sta.addr, prev_rates,
sta->sta.addr, prev_rates, sta->sta.supp_rates[band]);
sta->sta.supp_rates[band]); rates_updated = true;
rates_updated = true;
}
} else {
rcu_read_unlock();
sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
mgmt->sa, supp_rates);
} }
} else {
rcu_read_unlock();
sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
mgmt->sa, supp_rates);
} }
}
if (sta && elems->wmm_info) if (sta && elems->wmm_info)
sta->sta.wme = true; sta->sta.wme = true;
if (sta && elems->ht_operation && elems->ht_cap_elem &&
sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_5 &&
sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_10) {
/* we both use HT */
struct ieee80211_ht_cap htcap_ie;
struct cfg80211_chan_def chandef;
ieee80211_ht_oper_to_chandef(channel,
elems->ht_operation,
&chandef);
memcpy(&htcap_ie, elems->ht_cap_elem, sizeof(htcap_ie));
/*
* fall back to HT20 if we don't use or use
* the other extension channel
*/
if (chandef.center_freq1 !=
sdata->u.ibss.chandef.center_freq1)
htcap_ie.cap_info &=
cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40);
rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap(
sdata, sband, &htcap_ie, sta);
}
if (sta && rates_updated) { if (sta && elems->ht_operation && elems->ht_cap_elem &&
u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED; sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
u8 rx_nss = sta->sta.rx_nss; sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_5 &&
sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_10) {
/* we both use HT */
struct ieee80211_ht_cap htcap_ie;
struct cfg80211_chan_def chandef;
/* Force rx_nss recalculation */ ieee80211_ht_oper_to_chandef(channel,
sta->sta.rx_nss = 0; elems->ht_operation,
rate_control_rate_init(sta); &chandef);
if (sta->sta.rx_nss != rx_nss)
changed |= IEEE80211_RC_NSS_CHANGED;
drv_sta_rc_update(local, sdata, &sta->sta, changed); memcpy(&htcap_ie, elems->ht_cap_elem, sizeof(htcap_ie));
}
rcu_read_unlock(); /*
* fall back to HT20 if we don't use or use
* the other extension channel
*/
if (chandef.center_freq1 != sdata->u.ibss.chandef.center_freq1)
htcap_ie.cap_info &=
cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40);
rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
&htcap_ie,
sta);
} }
if (sta && rates_updated) {
u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED;
u8 rx_nss = sta->sta.rx_nss;
/* Force rx_nss recalculation */
sta->sta.rx_nss = 0;
rate_control_rate_init(sta);
if (sta->sta.rx_nss != rx_nss)
changed |= IEEE80211_RC_NSS_CHANGED;
drv_sta_rc_update(local, sdata, &sta->sta, changed);
}
rcu_read_unlock();
}
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len,
struct ieee80211_rx_status *rx_status,
struct ieee802_11_elems *elems)
{
struct ieee80211_local *local = sdata->local;
struct cfg80211_bss *cbss;
struct ieee80211_bss *bss;
struct ieee80211_channel *channel;
u64 beacon_timestamp, rx_timestamp;
u32 supp_rates = 0;
enum ieee80211_band band = rx_status->band;
channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq);
if (!channel)
return;
ieee80211_update_sta_info(sdata, mgmt, len, rx_status, elems, channel);
bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
channel); channel);
if (!bss) if (!bss)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册