return -EINVAL;
if (params->ht_capa)
- ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
+ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, &sband->ht_cap,
params->ht_capa, link_sta);
/* VHT can override some HT caps such as the A-MSDU max length */
if (params->vht_capa)
ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
+ &sband->vht_cap,
params->vht_capa, NULL,
link_sta);
}
void
-ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_supported_band *sband,
- const u8 *he_cap_ie, u8 he_cap_len,
- const struct ieee80211_he_6ghz_capa *he_6ghz_capa,
- struct link_sta_info *link_sta)
+_ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
+ const struct ieee80211_sta_he_cap *own_he_cap_ptr,
+ const u8 *he_cap_ie, u8 he_cap_len,
+ const struct ieee80211_he_6ghz_capa *he_6ghz_capa,
+ struct link_sta_info *link_sta)
{
struct ieee80211_sta_he_cap *he_cap = &link_sta->pub->he_cap;
- const struct ieee80211_sta_he_cap *own_he_cap_ptr;
struct ieee80211_sta_he_cap own_he_cap;
struct ieee80211_he_cap_elem *he_cap_ie_elem = (void *)he_cap_ie;
u8 he_ppe_size;
memset(he_cap, 0, sizeof(*he_cap));
- if (!he_cap_ie)
- return;
-
- own_he_cap_ptr =
- ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);
- if (!own_he_cap_ptr)
+ if (!he_cap_ie || !own_he_cap_ptr || !own_he_cap_ptr->has_he)
return;
own_he_cap = *own_he_cap_ptr;
link_sta->cur_max_bandwidth = ieee80211_sta_cap_rx_bw(link_sta);
link_sta->pub->bandwidth = ieee80211_sta_cur_vht_bw(link_sta);
- if (sband->band == NL80211_BAND_6GHZ && he_6ghz_capa)
+ if (he_6ghz_capa)
ieee80211_update_from_he_6ghz_capa(he_6ghz_capa, link_sta);
ieee80211_he_mcs_intersection(&own_he_cap.he_mcs_nss_supp.rx_mcs_80,
}
}
+void
+ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_supported_band *sband,
+ const u8 *he_cap_ie, u8 he_cap_len,
+ const struct ieee80211_he_6ghz_capa *he_6ghz_capa,
+ struct link_sta_info *link_sta)
+{
+ const struct ieee80211_sta_he_cap *own_he_cap =
+ ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);
+
+ _ieee80211_he_cap_ie_to_sta_he_cap(sdata, own_he_cap, he_cap_ie,
+ he_cap_len,
+ (sband->band == NL80211_BAND_6GHZ) ?
+ he_6ghz_capa : NULL,
+ link_sta);
+}
+
void
ieee80211_he_op_ie_to_bss_conf(struct ieee80211_vif *vif,
const struct ieee80211_he_operation *he_op_ie)
bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_supported_band *sband,
+ const struct ieee80211_sta_ht_cap *own_cap_ptr,
const struct ieee80211_ht_cap *ht_cap_ie,
struct link_sta_info *link_sta)
{
memset(&ht_cap, 0, sizeof(ht_cap));
- if (!ht_cap_ie || !sband->ht_cap.ht_supported)
+ if (!ht_cap_ie || !own_cap_ptr->ht_supported)
goto apply;
ht_cap.ht_supported = true;
- own_cap = sband->ht_cap;
+ own_cap = *own_cap_ptr;
/*
* If user has specified capability over-rides, take care
ieee80211_chandef_ht_oper(elems->ht_operation, &chandef);
memcpy(&htcap_ie, elems->ht_cap_elem, sizeof(htcap_ie));
- rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
+ rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap(sdata,
+ &sband->ht_cap,
&htcap_ie,
&sta->deflink);
&chandef);
memcpy(&cap_ie, elems->vht_cap_elem, sizeof(cap_ie));
ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
+ &sband->vht_cap,
&cap_ie, NULL,
&sta->deflink);
if (memcmp(&cap, &sta->sta.deflink.vht_cap, sizeof(cap)))
void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
struct ieee80211_sta_ht_cap *ht_cap);
bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_supported_band *sband,
+ const struct ieee80211_sta_ht_cap *own_cap,
const struct ieee80211_ht_cap *ht_cap_ie,
struct link_sta_info *link_sta);
void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
void
ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
struct ieee80211_supported_band *sband,
+ const struct ieee80211_sta_vht_cap *own_vht_cap,
const struct ieee80211_vht_cap *vht_cap_ie,
const struct ieee80211_vht_cap *vht_cap_ie2,
struct link_sta_info *link_sta);
/* HE */
void
+_ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
+ const struct ieee80211_sta_he_cap *own_he_cap,
+ const u8 *he_cap_ie, u8 he_cap_len,
+ const struct ieee80211_he_6ghz_capa *he_6ghz_capa,
+ struct link_sta_info *link_sta);
+void
ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
struct ieee80211_supported_band *sband,
const u8 *he_cap_ie, u8 he_cap_len,
changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
sta->sta.deflink.supp_rates[sband->band] = rates;
- if (ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
+ if (ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, &sband->ht_cap,
elems->ht_cap_elem,
&sta->deflink))
changed |= IEEE80211_RC_BW_CHANGED;
ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
+ &sband->vht_cap,
elems->vht_cap_elem, NULL,
&sta->deflink);
/* Set up internal HT/VHT capabilities */
if (elems->ht_cap_elem && link->u.mgd.conn.mode >= IEEE80211_CONN_MODE_HT)
- ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
+ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, &sband->ht_cap,
elems->ht_cap_elem,
link_sta);
}
ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
+ &sband->vht_cap,
elems->vht_cap_elem,
bss_vht_cap, link_sta);
rcu_read_unlock();
*
* Portions of this file
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH
- * Copyright (C) 2018-2026 Intel Corporation
+ * Copyright (C) 2018 - 2026 Intel Corporation
*/
#include <linux/ieee80211.h>
void
ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
struct ieee80211_supported_band *sband,
+ const struct ieee80211_sta_vht_cap *own_vht_cap,
const struct ieee80211_vht_cap *vht_cap_ie,
const struct ieee80211_vht_cap *vht_cap_ie2,
struct link_sta_info *link_sta)
struct ieee80211_sta_vht_cap *vht_cap = &link_sta->pub->vht_cap;
struct ieee80211_sta_vht_cap own_cap;
u32 cap_info, i;
- bool have_80mhz;
u32 mpdu_len;
memset(vht_cap, 0, sizeof(*vht_cap));
if (!link_sta->pub->ht_cap.ht_supported)
return;
- if (!vht_cap_ie || !sband->vht_cap.vht_supported)
+ if (!vht_cap_ie || !own_vht_cap->vht_supported)
return;
- /* Allow VHT if at least one channel on the sband supports 80 MHz */
- have_80mhz = false;
- for (i = 0; i < sband->n_channels; i++) {
- if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
- IEEE80211_CHAN_NO_80MHZ))
- continue;
+ if (sband) {
+ /* Allow VHT if at least one channel on the sband supports 80 MHz */
+ bool have_80mhz = false;
- have_80mhz = true;
- break;
- }
+ for (i = 0; i < sband->n_channels; i++) {
+ if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
+ IEEE80211_CHAN_NO_80MHZ))
+ continue;
- if (!have_80mhz)
- return;
+ have_80mhz = true;
+ break;
+ }
+
+ if (!have_80mhz)
+ return;
+ }
/*
* A VHT STA must support 40 MHz, but if we verify that here
vht_cap->vht_supported = true;
- own_cap = sband->vht_cap;
+ own_cap = *own_vht_cap;
/*
* If user has specified capability overrides, take care
* of that if the station we're setting up is the AP that