Commit 28aa895b authored by Johannes Berg's avatar Johannes Berg

wifi: mac80211: convert ieee80211_ie_build_he_cap() to SKB use

Convert ieee80211_ie_build_he_cap() to the SKB-put function
style, renaming it to ieee80211_put_he_cap().

Link: https://msgid.link/20240129202041.e6ef888980d9.Ied9e014314b5d27611e693e3d4cb63bdc8d7de17@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 9d0480a7
...@@ -2502,9 +2502,6 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, ...@@ -2502,9 +2502,6 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
const struct cfg80211_chan_def *chandef); const struct cfg80211_chan_def *chandef);
u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata); u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata);
u8 *ieee80211_ie_build_he_cap(const struct ieee80211_conn_settings *conn,
const struct ieee80211_sta_he_cap *he_cap,
u8 *pos, u8 *end);
u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef); u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef);
u8 *ieee80211_ie_build_eht_oper(u8 *pos, struct cfg80211_chan_def *chandef, u8 *ieee80211_ie_build_eht_oper(u8 *pos, struct cfg80211_chan_def *chandef,
const struct ieee80211_sta_eht_cap *eht_cap); const struct ieee80211_sta_eht_cap *eht_cap);
...@@ -2523,6 +2520,10 @@ int ieee80211_put_srates_elem(struct sk_buff *skb, ...@@ -2523,6 +2520,10 @@ int ieee80211_put_srates_elem(struct sk_buff *skb,
const struct ieee80211_supported_band *sband, const struct ieee80211_supported_band *sband,
u32 basic_rates, u32 rate_flags, u32 masked_rates, u32 basic_rates, u32 rate_flags, u32 masked_rates,
u8 element_id); u8 element_id);
int ieee80211_put_he_cap(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata,
const struct ieee80211_supported_band *sband,
const struct ieee80211_conn_settings *conn);
int ieee80211_put_he_6ghz_cap(struct sk_buff *skb, int ieee80211_put_he_6ghz_cap(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata, struct ieee80211_sub_if_data *sdata,
enum ieee80211_smps_mode smps_mode); enum ieee80211_smps_mode smps_mode);
......
...@@ -567,29 +567,18 @@ int mesh_add_vht_oper_ie(struct ieee80211_sub_if_data *sdata, ...@@ -567,29 +567,18 @@ int mesh_add_vht_oper_ie(struct ieee80211_sub_if_data *sdata,
int mesh_add_he_cap_ie(struct ieee80211_sub_if_data *sdata, int mesh_add_he_cap_ie(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, u8 ie_len) struct sk_buff *skb, u8 ie_len)
{ {
const struct ieee80211_sta_he_cap *he_cap;
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
u8 *pos;
sband = ieee80211_get_sband(sdata); sband = ieee80211_get_sband(sdata);
if (!sband) if (!sband)
return -EINVAL; return -EINVAL;
he_cap = ieee80211_get_he_iftype_cap(sband, NL80211_IFTYPE_MESH_POINT); if (sdata->vif.bss_conf.chanreq.oper.width == NL80211_CHAN_WIDTH_20_NOHT ||
if (!he_cap ||
sdata->vif.bss_conf.chanreq.oper.width == NL80211_CHAN_WIDTH_20_NOHT ||
sdata->vif.bss_conf.chanreq.oper.width == NL80211_CHAN_WIDTH_5 || sdata->vif.bss_conf.chanreq.oper.width == NL80211_CHAN_WIDTH_5 ||
sdata->vif.bss_conf.chanreq.oper.width == NL80211_CHAN_WIDTH_10) sdata->vif.bss_conf.chanreq.oper.width == NL80211_CHAN_WIDTH_10)
return 0; return 0;
if (skb_tailroom(skb) < ie_len) return ieee80211_put_he_cap(skb, sdata, sband, NULL);
return -ENOMEM;
pos = skb_put(skb, ie_len);
ieee80211_ie_build_he_cap(NULL, he_cap, pos, pos + ie_len);
return 0;
} }
int mesh_add_he_oper_ie(struct ieee80211_sub_if_data *sdata, int mesh_add_he_oper_ie(struct ieee80211_sub_if_data *sdata,
......
...@@ -1038,38 +1038,6 @@ static bool ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata, ...@@ -1038,38 +1038,6 @@ static bool ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
return mu_mimo_owner; return mu_mimo_owner;
} }
/* This function determines HE capability flags for the association
* and builds the IE.
*/
static void ieee80211_add_he_ie(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb,
struct ieee80211_supported_band *sband,
enum ieee80211_smps_mode smps_mode,
const struct ieee80211_conn_settings *conn)
{
u8 *pos, *pre_he_pos;
const struct ieee80211_sta_he_cap *he_cap;
u8 he_cap_size;
he_cap = ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);
if (WARN_ON(!he_cap))
return;
/* get a max size estimate */
he_cap_size =
2 + 1 + sizeof(he_cap->he_cap_elem) +
ieee80211_he_mcs_nss_size(&he_cap->he_cap_elem) +
ieee80211_he_ppe_size(he_cap->ppe_thres[0],
he_cap->he_cap_elem.phy_cap_info);
pos = skb_put(skb, he_cap_size);
pre_he_pos = pos;
pos = ieee80211_ie_build_he_cap(conn, he_cap, pos, pos + he_cap_size);
/* trim excess if any */
skb_trim(skb, skb->len - (pre_he_pos + he_cap_size - pos));
ieee80211_put_he_6ghz_cap(skb, sdata, smps_mode);
}
static void ieee80211_add_eht_ie(struct ieee80211_sub_if_data *sdata, static void ieee80211_add_eht_ie(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, struct sk_buff *skb,
struct ieee80211_supported_band *sband, struct ieee80211_supported_band *sband,
...@@ -1403,9 +1371,10 @@ static size_t ieee80211_assoc_link_elems(struct ieee80211_sub_if_data *sdata, ...@@ -1403,9 +1371,10 @@ static size_t ieee80211_assoc_link_elems(struct ieee80211_sub_if_data *sdata,
offset); offset);
if (assoc_data->link[link_id].conn.mode >= IEEE80211_CONN_MODE_HE) { if (assoc_data->link[link_id].conn.mode >= IEEE80211_CONN_MODE_HE) {
ieee80211_add_he_ie(sdata, skb, sband, smps_mode, ieee80211_put_he_cap(skb, sdata, sband,
&assoc_data->link[link_id].conn); &assoc_data->link[link_id].conn);
ADD_PRESENT_EXT_ELEM(WLAN_EID_EXT_HE_CAPABILITY); ADD_PRESENT_EXT_ELEM(WLAN_EID_EXT_HE_CAPABILITY);
ieee80211_put_he_6ghz_cap(skb, sdata, smps_mode);
} }
/* /*
......
...@@ -548,19 +548,10 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_link_data *link, ...@@ -548,19 +548,10 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_link_data *link,
} }
/* build the HE-cap from sband */ /* build the HE-cap from sband */
if (he_cap && if (action_code == WLAN_TDLS_SETUP_REQUEST ||
(action_code == WLAN_TDLS_SETUP_REQUEST || action_code == WLAN_TDLS_SETUP_RESPONSE ||
action_code == WLAN_TDLS_SETUP_RESPONSE || action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) {
action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES)) { ieee80211_put_he_cap(skb, sdata, sband, NULL);
u8 cap_size;
cap_size =
2 + 1 + sizeof(he_cap->he_cap_elem) +
ieee80211_he_mcs_nss_size(&he_cap->he_cap_elem) +
ieee80211_he_ppe_size(he_cap->ppe_thres[0],
he_cap->he_cap_elem.phy_cap_info);
pos = skb_put(skb, cap_size);
pos = ieee80211_ie_build_he_cap(NULL, he_cap, pos, pos + cap_size);
/* Build HE 6Ghz capa IE from sband */ /* Build HE 6Ghz capa IE from sband */
if (sband->band == NL80211_BAND_6GHZ) if (sband->band == NL80211_BAND_6GHZ)
......
...@@ -1352,19 +1352,14 @@ static int ieee80211_put_preq_ies_band(struct sk_buff *skb, ...@@ -1352,19 +1352,14 @@ static int ieee80211_put_preq_ies_band(struct sk_buff *skb,
*offset = noffset; *offset = noffset;
} }
he_cap = ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif); if (cfg80211_any_usable_channels(local->hw.wiphy, BIT(sband->band),
if (he_cap &&
cfg80211_any_usable_channels(local->hw.wiphy, BIT(sband->band),
IEEE80211_CHAN_NO_HE)) { IEEE80211_CHAN_NO_HE)) {
u8 *pos = skb_tail_pointer(skb); err = ieee80211_put_he_cap(skb, sdata, sband, NULL);
u8 *end = pos + skb_tailroom(skb); if (err)
return err;
pos = ieee80211_ie_build_he_cap(NULL, he_cap, pos, end);
if (!pos)
return -ENOBUFS;
skb_put(skb, pos - skb_tail_pointer(skb));
} }
he_cap = ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);
eht_cap = ieee80211_get_eht_iftype_cap_vif(sband, &sdata->vif); eht_cap = ieee80211_get_eht_iftype_cap_vif(sband, &sdata->vif);
if (eht_cap && if (eht_cap &&
...@@ -2408,7 +2403,7 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, ...@@ -2408,7 +2403,7 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
return pos; return pos;
} }
/* this may return more than ieee80211_ie_build_he_cap() will need */ /* this may return more than ieee80211_put_he_6ghz_cap() will need */
u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata) u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata)
{ {
const struct ieee80211_sta_he_cap *he_cap; const struct ieee80211_sta_he_cap *he_cap;
...@@ -2479,21 +2474,23 @@ ieee80211_get_adjusted_he_cap(const struct ieee80211_conn_settings *conn, ...@@ -2479,21 +2474,23 @@ ieee80211_get_adjusted_he_cap(const struct ieee80211_conn_settings *conn,
} }
} }
u8 *ieee80211_ie_build_he_cap(const struct ieee80211_conn_settings *conn, int ieee80211_put_he_cap(struct sk_buff *skb,
const struct ieee80211_sta_he_cap *he_cap, struct ieee80211_sub_if_data *sdata,
u8 *pos, u8 *end) const struct ieee80211_supported_band *sband,
const struct ieee80211_conn_settings *conn)
{ {
const struct ieee80211_sta_he_cap *he_cap;
struct ieee80211_he_cap_elem elem; struct ieee80211_he_cap_elem elem;
u8 *len;
u8 n; u8 n;
u8 ie_len; u8 ie_len;
u8 *orig_pos = pos;
if (!conn) if (!conn)
conn = &ieee80211_conn_settings_unlimited; conn = &ieee80211_conn_settings_unlimited;
/* Make sure we have place for the IE */ he_cap = ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);
if (!he_cap) if (!he_cap)
return orig_pos; return 0;
/* modify on stack first to calculate 'n' and 'ie_len' correctly */ /* modify on stack first to calculate 'n' and 'ie_len' correctly */
ieee80211_get_adjusted_he_cap(conn, he_cap, &elem); ieee80211_get_adjusted_he_cap(conn, he_cap, &elem);
...@@ -2504,19 +2501,17 @@ u8 *ieee80211_ie_build_he_cap(const struct ieee80211_conn_settings *conn, ...@@ -2504,19 +2501,17 @@ u8 *ieee80211_ie_build_he_cap(const struct ieee80211_conn_settings *conn,
ieee80211_he_ppe_size(he_cap->ppe_thres[0], ieee80211_he_ppe_size(he_cap->ppe_thres[0],
he_cap->he_cap_elem.phy_cap_info); he_cap->he_cap_elem.phy_cap_info);
if ((end - pos) < ie_len) if (skb_tailroom(skb) < ie_len)
return orig_pos; return -ENOBUFS;
*pos++ = WLAN_EID_EXTENSION; skb_put_u8(skb, WLAN_EID_EXTENSION);
pos++; /* We'll set the size later below */ len = skb_put(skb, 1); /* We'll set the size later below */
*pos++ = WLAN_EID_EXT_HE_CAPABILITY; skb_put_u8(skb, WLAN_EID_EXT_HE_CAPABILITY);
/* Fixed data */ /* Fixed data */
memcpy(pos, &elem, sizeof(elem)); skb_put_data(skb, &elem, sizeof(elem));
pos += sizeof(elem);
memcpy(pos, &he_cap->he_mcs_nss_supp, n); skb_put_data(skb, &he_cap->he_mcs_nss_supp, n);
pos += n;
/* Check if PPE Threshold should be present */ /* Check if PPE Threshold should be present */
if ((he_cap->he_cap_elem.phy_cap_info[6] & if ((he_cap->he_cap_elem.phy_cap_info[6] &
...@@ -2540,12 +2535,11 @@ u8 *ieee80211_ie_build_he_cap(const struct ieee80211_conn_settings *conn, ...@@ -2540,12 +2535,11 @@ u8 *ieee80211_ie_build_he_cap(const struct ieee80211_conn_settings *conn,
n = DIV_ROUND_UP(n, 8); n = DIV_ROUND_UP(n, 8);
/* Copy PPE Thresholds */ /* Copy PPE Thresholds */
memcpy(pos, &he_cap->ppe_thres, n); skb_put_data(skb, &he_cap->ppe_thres, n);
pos += n;
end: end:
orig_pos[1] = (pos - orig_pos) - 2; *len = skb_tail_pointer(skb) - len - 1;
return pos; return 0;
} }
int ieee80211_put_he_6ghz_cap(struct sk_buff *skb, int ieee80211_put_he_6ghz_cap(struct sk_buff *skb,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment