wifi: mac80211: return a beacon for a specific link

Pass the link id through to the get_beacon and return
the beacon for a specific link id.

Signed-off-by: Shaul Triebitz <shaul.triebitz@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Shaul Triebitz 2022-06-06 14:25:54 +03:00 committed by Johannes Berg
parent ae7ba17b49
commit 6e8912a503
43 changed files with 109 additions and 88 deletions

View File

@ -1630,7 +1630,7 @@ static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
return 0;
bcn = ieee80211_beacon_get_template(hw, vif, &offs);
bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0);
if (!bcn) {
ath10k_warn(ar, "failed to get beacon template from mac80211\n");
return -EPERM;

View File

@ -3888,7 +3888,7 @@ void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
continue;
}
bcn = ieee80211_beacon_get(ar->hw, arvif->vif);
bcn = ieee80211_beacon_get(ar->hw, arvif->vif, 0);
if (!bcn) {
ath10k_warn(ar, "could not get mac80211 beacon\n");
continue;

View File

@ -1362,7 +1362,7 @@ static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
return 0;
bcn = ieee80211_beacon_get_template(hw, vif, &offs);
bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0);
if (!bcn) {
ath11k_warn(ab, "failed to get beacon template from mac80211\n");
return -EPERM;

View File

@ -1946,7 +1946,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
goto out;
}
skb = ieee80211_beacon_get(hw, vif);
skb = ieee80211_beacon_get(hw, vif, 0);
if (!skb) {
ret = -ENOMEM;

View File

@ -135,7 +135,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
bf->bf_mpdu = NULL;
}
skb = ieee80211_beacon_get(hw, vif);
skb = ieee80211_beacon_get(hw, vif, 0);
if (skb == NULL)
return NULL;

View File

@ -215,7 +215,7 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv,
}
/* Get a new beacon */
beacon = ieee80211_beacon_get(priv->hw, vif);
beacon = ieee80211_beacon_get(priv->hw, vif, 0);
if (!beacon) {
spin_unlock_bh(&priv->beacon_lock);
return;

View File

@ -1628,7 +1628,7 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
goto out_unlock;
skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif),
NULL, NULL);
NULL, NULL, 0);
if (!skb) {
err = -ENOMEM;

View File

@ -1010,7 +1010,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
wcn36xx_smd_config_bss(wcn, vif, NULL,
vif->addr, false);
skb = ieee80211_beacon_get_tim(hw, vif, &tim_off,
&tim_len);
&tim_len, 0);
if (!skb) {
wcn36xx_err("failed to alloc beacon skb\n");
goto out;

View File

@ -1832,7 +1832,7 @@ static void b43_update_templates(struct b43_wl *wl)
* the TIM field, but that would probably require resizing and
* moving of data within the beacon template.
* Simply request a new beacon and let mac80211 do the hard work. */
beacon = ieee80211_beacon_get(wl->hw, wl->vif);
beacon = ieee80211_beacon_get(wl->hw, wl->vif, 0);
if (unlikely(!beacon))
return;

View File

@ -1241,7 +1241,7 @@ static void b43legacy_update_templates(struct b43legacy_wl *wl)
* field, but that would probably require resizing and moving of data
* within the beacon template. Simply request a new beacon and let
* mac80211 do the hard work. */
beacon = ieee80211_beacon_get(wl->hw, wl->vif);
beacon = ieee80211_beacon_get(wl->hw, wl->vif, 0);
if (unlikely(!beacon))
return;

View File

@ -678,7 +678,7 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
u16 tim_offset = 0;
spin_lock_bh(&wl->lock);
beacon = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL);
beacon = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL, 0);
brcms_c_set_new_beacon(wl->wlc, beacon, tim_offset,
info->dtim_period);
spin_unlock_bh(&wl->lock);
@ -950,7 +950,7 @@ static int brcms_ops_beacon_set_tim(struct ieee80211_hw *hw,
spin_lock_bh(&wl->lock);
if (wl->wlc->vif)
beacon = ieee80211_beacon_get_tim(hw, wl->wlc->vif,
&tim_offset, NULL);
&tim_offset, NULL, 0);
if (beacon)
brcms_c_set_new_beacon(wl->wlc, beacon, tim_offset,
wl->wlc->vif->bss_conf.dtim_period);

View File

@ -5276,7 +5276,7 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
struct il_priv *il = hw->priv;
unsigned long flags;
__le64 timestamp;
struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
struct sk_buff *skb = ieee80211_beacon_get(hw, vif, 0);
if (!skb)
return;

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/******************************************************************************
*
* Copyright(c) 2003 - 2014, 2018 - 2021 Intel Corporation. All rights reserved.
* Copyright(c) 2003 - 2014, 2018 - 2022 Intel Corporation. All rights reserved.
* Copyright(c) 2015 Intel Deutschland GmbH
*
* Portions of this file are derived from the ipw3945 project, as well
@ -284,7 +284,7 @@ static void iwl_bg_beacon_update(struct work_struct *work)
}
/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif);
beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif, 0);
if (!beacon) {
IWL_ERR(priv, "update beacon failed -- keeping old\n");
goto out;

View File

@ -183,7 +183,7 @@ static int iwlagn_update_beacon(struct iwl_priv *priv,
lockdep_assert_held(&priv->mutex);
dev_kfree_skb(priv->beacon_skb);
priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif);
priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif, 0);
if (!priv->beacon_skb)
return -ENOMEM;
return iwlagn_send_beacon_cmd(priv);

View File

@ -1233,7 +1233,7 @@ static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len)
mvm->hw->extra_beacon_tailroom = len;
beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL);
beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL, 0);
if (!beacon)
goto out_err;

View File

@ -1002,7 +1002,7 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
WARN_ON(vif->type != NL80211_IFTYPE_AP &&
vif->type != NL80211_IFTYPE_ADHOC);
beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL);
beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL, 0);
if (!beacon)
return -ENOMEM;

View File

@ -139,7 +139,7 @@ static int p54_beacon_update(struct p54_common *priv,
struct sk_buff *beacon;
int ret;
beacon = ieee80211_beacon_get(priv->hw, vif);
beacon = ieee80211_beacon_get(priv->hw, vif, 0);
if (!beacon)
return -ENOMEM;
ret = p54_beacon_format_ie_tim(beacon);

View File

@ -1908,7 +1908,7 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
vif->type != NL80211_IFTYPE_OCB)
return;
skb = ieee80211_beacon_get(hw, vif);
skb = ieee80211_beacon_get(hw, vif, 0);
if (skb == NULL)
return;
info = IEEE80211_SKB_CB(skb);

View File

@ -427,7 +427,7 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
switch (priv->vif->type) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_MESH_POINT:
beacon = ieee80211_beacon_get(hw, vif);
beacon = ieee80211_beacon_get(hw, vif, 0);
if (beacon) {
lbtf_beacon_set(priv, beacon);
kfree_skb(beacon);
@ -691,7 +691,7 @@ void lbtf_bcn_sent(struct lbtf_private *priv)
}
}
skb = ieee80211_beacon_get(priv->hw, priv->vif);
skb = ieee80211_beacon_get(priv->hw, priv->vif, 0);
if (skb) {
lbtf_beacon_set(priv, skb);

View File

@ -5147,7 +5147,7 @@ mwl8k_bss_info_changed_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (changed & (BSS_CHANGED_BEACON_INT | BSS_CHANGED_BEACON)) {
struct sk_buff *skb;
skb = ieee80211_beacon_get(hw, vif);
skb = ieee80211_beacon_get(hw, vif, 0);
if (skb != NULL) {
mwl8k_cmd_set_beacon(hw, vif, skb->data, skb->len);
kfree_skb(skb);

View File

@ -20,7 +20,7 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
if (!(mdev->beacon_mask & BIT(mvif->idx)))
return;
skb = ieee80211_beacon_get(mt76_hw(dev), vif);
skb = ieee80211_beacon_get(mt76_hw(dev), vif, 0);
if (!skb)
return;

View File

@ -706,7 +706,7 @@ mt7615_mcu_add_beacon_offload(struct mt7615_dev *dev,
if (!enable)
goto out;
skb = ieee80211_beacon_get_template(hw, vif, &offs);
skb = ieee80211_beacon_get_template(hw, vif, &offs, 0);
if (!skb)
return -EINVAL;
@ -1076,7 +1076,7 @@ mt7615_mcu_uni_add_beacon_offload(struct mt7615_dev *dev,
if (!enable)
goto out;
skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs);
skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs, 0);
if (!skb)
return -EINVAL;

View File

@ -139,7 +139,7 @@ mt76x02_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
if (!(dev->mt76.beacon_mask & BIT(mvif->idx)))
return;
skb = ieee80211_beacon_get(mt76_hw(dev), vif);
skb = ieee80211_beacon_get(mt76_hw(dev), vif, 0);
if (!skb)
return;

View File

@ -2086,7 +2086,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (!en)
goto out;
skb = ieee80211_beacon_get_template(hw, vif, &offs);
skb = ieee80211_beacon_get_template(hw, vif, &offs, 0);
if (!skb)
return -EINVAL;

View File

@ -1258,7 +1258,7 @@ mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev,
if (!enable)
goto out;
skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs);
skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs, 0);
if (!skb)
return -EINVAL;

View File

@ -133,7 +133,7 @@ int plfxlc_restore_settings(struct plfxlc_mac *mac)
return 0;
if (mac->vif) {
beacon = ieee80211_beacon_get(mac->hw, mac->vif);
beacon = ieee80211_beacon_get(mac->hw, mac->vif, 0);
if (beacon) {
/*beacon is hardcoded in firmware */
kfree_skb(beacon);
@ -601,7 +601,7 @@ static void plfxlc_op_bss_info_changed(struct ieee80211_hw *hw,
/* for ADHOC */
associated = true;
if (changes & BSS_CHANGED_BEACON) {
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif, 0);
if (beacon) {
/*beacon is hardcoded in firmware */

View File

@ -758,7 +758,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
*/
rt2x00queue_free_skb(intf->beacon);
intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif);
intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif, 0);
if (!intf->beacon->skb)
return -ENOMEM;

View File

@ -1300,7 +1300,7 @@ static void rtl8180_beacon_work(struct work_struct *work)
goto resched;
/* grab a fresh beacon */
skb = ieee80211_beacon_get(dev, vif);
skb = ieee80211_beacon_get(dev, vif, 0);
if (!skb)
goto resched;

View File

@ -1075,7 +1075,7 @@ static void rtl8187_beacon_work(struct work_struct *work)
goto resched;
/* grab a fresh beacon */
skb = ieee80211_beacon_get(dev, vif);
skb = ieee80211_beacon_get(dev, vif, 0);
if (!skb)
goto resched;

View File

@ -1009,7 +1009,7 @@ static void send_beacon_frame(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
struct sk_buff *skb = ieee80211_beacon_get(hw, vif, 0);
struct rtl_tcb_desc tcb_desc;
if (skb) {

View File

@ -1100,7 +1100,7 @@ static void _rtl_pci_prepare_bcn_tasklet(struct tasklet_struct *t)
}
/*NB: the beacon data buffer must be 32-bit aligned. */
pskb = ieee80211_beacon_get(hw, mac->vif);
pskb = ieee80211_beacon_get(hw, mac->vif, 0);
if (!pskb)
return;
hdr = rtl_get_hdr(pskb);

View File

@ -1070,7 +1070,7 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw,
switch (rsvd_pkt->type) {
case RSVD_BEACON:
skb_new = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL);
skb_new = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL, 0);
rsvd_pkt->tim_offset = tim_offset;
break;
case RSVD_PS_POLL:

View File

@ -1043,7 +1043,8 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
u16 tim_offset;
int bcn_total_len;
skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset, NULL);
skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset,
NULL, 0);
if (!skb_beacon) {
rtw89_err(rtwdev, "failed to get beacon skb\n");
return -ENOMEM;

View File

@ -443,7 +443,7 @@ int rsi_prepare_beacon(struct rsi_common *common, struct sk_buff *skb)
return -EINVAL;
mac_bcn = ieee80211_beacon_get_tim(adapter->hw,
vif,
&tim_offset, NULL);
&tim_offset, NULL, 0);
if (!mac_bcn) {
rsi_dbg(ERR_ZONE, "Failed to get beacon from mac80211\n");
return -EINVAL;

View File

@ -339,7 +339,7 @@ static int wfx_upload_ap_templates(struct wfx_vif *wvif)
struct ieee80211_vif *vif = wvif_to_vif(wvif);
struct sk_buff *skb;
skb = ieee80211_beacon_get(wvif->wdev->hw, vif);
skb = ieee80211_beacon_get(wvif->wdev->hw, vif, 0);
if (!skb)
return -ENOMEM;
wfx_hif_set_template_frame(wvif, skb, HIF_TMPLT_BCN, API_RATE_INDEX_B_1MBPS);
@ -356,7 +356,7 @@ static int wfx_upload_ap_templates(struct wfx_vif *wvif)
static void wfx_set_mfp_ap(struct wfx_vif *wvif)
{
struct ieee80211_vif *vif = wvif_to_vif(wvif);
struct sk_buff *skb = ieee80211_beacon_get(wvif->wdev->hw, vif);
struct sk_buff *skb = ieee80211_beacon_get(wvif->wdev->hw, vif, 0);
const int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
const u16 *ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset,
skb->len - ieoffset);
@ -588,7 +588,7 @@ static int wfx_update_tim(struct wfx_vif *wvif)
u8 *tim_ptr;
skb = ieee80211_beacon_get_tim(wvif->wdev->hw, vif, &tim_offset,
&tim_length);
&tim_length, 0);
if (!skb)
return -ENOENT;
tim_ptr = skb->data + tim_offset;

View File

@ -1671,7 +1671,7 @@ static int cw1200_set_tim_impl(struct cw1200_common *priv, bool aid0_bit_set)
pr_debug("[AP] mcast: %s.\n", aid0_bit_set ? "ena" : "dis");
skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
&tim_offset, &tim_length);
&tim_offset, &tim_length, 0);
if (!skb) {
if (!__cw1200_flush(priv, true))
wsm_unlock_tx(priv);
@ -2203,7 +2203,7 @@ static int cw1200_upload_beacon(struct cw1200_common *priv)
frame.rate = WSM_TRANSMIT_RATE_6;
frame.skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
&tim_offset, &tim_len);
&tim_offset, &tim_len, 0);
if (!frame.skb)
return -ENOMEM;

View File

@ -1186,7 +1186,7 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_BEACON) {
beacon = ieee80211_beacon_get(hw, vif);
beacon = ieee80211_beacon_get(hw, vif, 0);
if (!beacon)
goto out_sleep;

View File

@ -4039,7 +4039,7 @@ static int wlcore_set_beacon_template(struct wl1271 *wl,
u32 min_rate;
int ret;
int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif);
struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif, 0);
u16 tmpl_id;
if (!beacon) {
@ -5493,7 +5493,7 @@ static const void *wlcore_get_beacon_ie(struct wl1271 *wl,
{
int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
struct sk_buff *beacon =
ieee80211_beacon_get(wl->hw, wl12xx_wlvif_to_vif(wlvif));
ieee80211_beacon_get(wl->hw, wl12xx_wlvif_to_vif(wlvif), 0);
if (!beacon)
return NULL;

View File

@ -398,7 +398,7 @@ int zd_restore_settings(struct zd_mac *mac)
mac->type == NL80211_IFTYPE_ADHOC ||
mac->type == NL80211_IFTYPE_AP) {
if (mac->vif != NULL) {
beacon = ieee80211_beacon_get(mac->hw, mac->vif);
beacon = ieee80211_beacon_get(mac->hw, mac->vif, 0);
if (beacon)
zd_mac_config_beacon(mac->hw, beacon, false);
}
@ -1167,7 +1167,7 @@ static void zd_beacon_done(struct zd_mac *mac)
/*
* Fetch next beacon so that tim_count is updated.
*/
beacon = ieee80211_beacon_get(mac->hw, mac->vif);
beacon = ieee80211_beacon_get(mac->hw, mac->vif, 0);
if (beacon)
zd_mac_config_beacon(mac->hw, beacon, true);
@ -1290,7 +1290,8 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
mac->type == NL80211_IFTYPE_AP) {
associated = true;
if (changes & BSS_CHANGED_BEACON) {
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif,
0);
if (beacon) {
zd_chip_disable_hwint(&mac->chip);
@ -1447,7 +1448,7 @@ static void beacon_watchdog_handler(struct work_struct *work)
zd_chip_disable_hwint(&mac->chip);
beacon = ieee80211_beacon_get(mac->hw, mac->vif);
beacon = ieee80211_beacon_get(mac->hw, mac->vif, 0);
if (beacon) {
zd_mac_free_cur_beacon(mac);

View File

@ -1435,7 +1435,7 @@ int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
{
struct sk_buff *beacon;
beacon = ieee80211_beacon_get(priv->hw, vif);
beacon = ieee80211_beacon_get(priv->hw, vif, 0);
if (!beacon)
return -ENOMEM;

View File

@ -699,7 +699,7 @@ int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
{
struct sk_buff *beacon;
beacon = ieee80211_beacon_get(priv->hw, vif);
beacon = ieee80211_beacon_get(priv->hw, vif, 0);
if (!beacon)
return -ENOMEM;

View File

@ -5069,6 +5069,7 @@ struct ieee80211_mutable_offsets {
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
* @offs: &struct ieee80211_mutable_offsets pointer to struct that will
* receive the offsets that may be updated by the driver.
* @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP)
*
* If the driver implements beaconing modes, it must use this function to
* obtain the beacon template.
@ -5085,7 +5086,8 @@ struct ieee80211_mutable_offsets {
struct sk_buff *
ieee80211_beacon_get_template(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_mutable_offsets *offs);
struct ieee80211_mutable_offsets *offs,
unsigned int link_id);
/**
* ieee80211_beacon_get_tim - beacon generation function
@ -5096,6 +5098,7 @@ ieee80211_beacon_get_template(struct ieee80211_hw *hw,
* @tim_length: pointer to variable that will receive the TIM IE length,
* (including the ID and length bytes!).
* Set to 0 if invalid (in non-AP modes).
* @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP)
*
* If the driver implements beaconing modes, it must use this function to
* obtain the beacon frame.
@ -5111,21 +5114,24 @@ ieee80211_beacon_get_template(struct ieee80211_hw *hw,
*/
struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
u16 *tim_offset, u16 *tim_length);
u16 *tim_offset, u16 *tim_length,
unsigned int link_id);
/**
* ieee80211_beacon_get - beacon generation function
* @hw: pointer obtained from ieee80211_alloc_hw().
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
* @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP)
*
* See ieee80211_beacon_get_tim().
*
* Return: See ieee80211_beacon_get_tim().
*/
static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
struct ieee80211_vif *vif,
unsigned int link_id)
{
return ieee80211_beacon_get_tim(hw, vif, NULL, NULL);
return ieee80211_beacon_get_tim(hw, vif, NULL, NULL, link_id);
}
/**

View File

@ -4689,11 +4689,12 @@ void ieee80211_tx_pending(struct tasklet_struct *t)
static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
struct ps_data *ps, struct sk_buff *skb,
bool is_template)
bool is_template, unsigned int link_id)
{
u8 *pos, *tim;
int aid0 = 0;
int i, have_bits = 0, n1, n2;
struct ieee80211_bss_conf *link_conf = sdata->vif.link_conf[link_id];
/* Generate bitmap for TIM only if there are any STAs in power save
* mode. */
@ -4704,7 +4705,7 @@ static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
IEEE80211_MAX_AID+1);
if (!is_template) {
if (ps->dtim_count == 0)
ps->dtim_count = sdata->vif.bss_conf.dtim_period - 1;
ps->dtim_count = link_conf->dtim_period - 1;
else
ps->dtim_count--;
}
@ -4713,7 +4714,7 @@ static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
*pos++ = WLAN_EID_TIM;
*pos++ = 4;
*pos++ = ps->dtim_count;
*pos++ = sdata->vif.bss_conf.dtim_period;
*pos++ = link_conf->dtim_period;
if (ps->dtim_count == 0 && !skb_queue_empty(&ps->bc_buf))
aid0 = 1;
@ -4754,7 +4755,7 @@ static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
static int ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
struct ps_data *ps, struct sk_buff *skb,
bool is_template)
bool is_template, unsigned int link_id)
{
struct ieee80211_local *local = sdata->local;
@ -4766,10 +4767,12 @@ static int ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
* of the tim bitmap in mac80211 and the driver.
*/
if (local->tim_in_locked_section) {
__ieee80211_beacon_add_tim(sdata, ps, skb, is_template);
__ieee80211_beacon_add_tim(sdata, ps, skb, is_template,
link_id);
} else {
spin_lock_bh(&local->tim_lock);
__ieee80211_beacon_add_tim(sdata, ps, skb, is_template);
__ieee80211_beacon_add_tim(sdata, ps, skb, is_template,
link_id);
spin_unlock_bh(&local->tim_lock);
}
@ -4777,7 +4780,8 @@ static int ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
}
static void ieee80211_set_beacon_cntdwn(struct ieee80211_sub_if_data *sdata,
struct beacon_data *beacon)
struct beacon_data *beacon,
unsigned int link_id)
{
u8 *beacon_data, count, max_count = 1;
struct probe_resp *resp;
@ -4803,11 +4807,11 @@ static void ieee80211_set_beacon_cntdwn(struct ieee80211_sub_if_data *sdata,
}
rcu_read_lock();
resp = rcu_dereference(sdata->deflink.u.ap.probe_resp);
resp = rcu_dereference(sdata->link[link_id]->u.ap.probe_resp);
bcn_offsets = beacon->cntdwn_counter_offsets;
count = beacon->cntdwn_current_counter;
if (sdata->vif.bss_conf.csa_active)
if (sdata->vif.link_conf[link_id]->csa_active)
max_count = IEEE80211_MAX_CNTDWN_COUNTERS_NUM;
for (i = 0; i < max_count; ++i) {
@ -4948,14 +4952,15 @@ EXPORT_SYMBOL(ieee80211_beacon_cntdwn_is_complete);
static int ieee80211_beacon_protect(struct sk_buff *skb,
struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata)
struct ieee80211_sub_if_data *sdata,
unsigned int link_id)
{
ieee80211_tx_result res;
struct ieee80211_tx_data tx;
struct sk_buff *check_skb;
memset(&tx, 0, sizeof(tx));
tx.key = rcu_dereference(sdata->deflink.default_beacon_key);
tx.key = rcu_dereference(sdata->link[link_id]->default_beacon_key);
if (!tx.key)
return 0;
tx.local = local;
@ -4979,7 +4984,8 @@ ieee80211_beacon_get_finish(struct ieee80211_hw *hw,
struct beacon_data *beacon,
struct sk_buff *skb,
struct ieee80211_chanctx_conf *chanctx_conf,
u16 csa_off_base)
u16 csa_off_base,
unsigned int link_id)
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
@ -5010,7 +5016,7 @@ ieee80211_beacon_get_finish(struct ieee80211_hw *hw,
memset(&txrc, 0, sizeof(txrc));
txrc.hw = hw;
txrc.sband = local->hw.wiphy->bands[band];
txrc.bss_conf = &sdata->vif.bss_conf;
txrc.bss_conf = sdata->vif.link_conf[link_id];
txrc.skb = skb;
txrc.reported_rate.idx = -1;
if (sdata->beacon_rate_set && sdata->beacon_rateidx_mask[band])
@ -5045,7 +5051,8 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
struct ieee80211_mutable_offsets *offs,
bool is_template,
struct beacon_data *beacon,
struct ieee80211_chanctx_conf *chanctx_conf)
struct ieee80211_chanctx_conf *chanctx_conf,
unsigned int link_id)
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
@ -5058,7 +5065,7 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
if (!is_template)
ieee80211_beacon_update_cntdwn(vif);
ieee80211_set_beacon_cntdwn(sdata, beacon);
ieee80211_set_beacon_cntdwn(sdata, beacon, link_id);
}
/* headroom, head length,
@ -5074,7 +5081,7 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
skb_reserve(skb, local->tx_headroom);
skb_put_data(skb, beacon->head, beacon->head_len);
ieee80211_beacon_add_tim(sdata, &ap->ps, skb, is_template);
ieee80211_beacon_add_tim(sdata, &ap->ps, skb, is_template, link_id);
if (offs) {
offs->tim_offset = beacon->head_len;
@ -5093,11 +5100,11 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
if (beacon->tail)
skb_put_data(skb, beacon->tail, beacon->tail_len);
if (ieee80211_beacon_protect(skb, local, sdata) < 0)
if (ieee80211_beacon_protect(skb, local, sdata, link_id) < 0)
return NULL;
ieee80211_beacon_get_finish(hw, vif, offs, beacon, skb, chanctx_conf,
csa_off_base);
csa_off_base, link_id);
return skb;
}
@ -5105,7 +5112,8 @@ static struct sk_buff *
__ieee80211_beacon_get(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_mutable_offsets *offs,
bool is_template)
bool is_template,
unsigned int link_id)
{
struct ieee80211_local *local = hw_to_local(hw);
struct beacon_data *beacon = NULL;
@ -5116,7 +5124,8 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
rcu_read_lock();
sdata = vif_to_sdata(vif);
chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
chanctx_conf =
rcu_dereference(sdata->vif.link_conf[link_id]->chanctx_conf);
if (!ieee80211_sdata_running(sdata) || !chanctx_conf)
goto out;
@ -5125,12 +5134,12 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
memset(offs, 0, sizeof(*offs));
if (sdata->vif.type == NL80211_IFTYPE_AP) {
beacon = rcu_dereference(sdata->deflink.u.ap.beacon);
beacon = rcu_dereference(sdata->link[link_id]->u.ap.beacon);
if (!beacon)
goto out;
skb = ieee80211_beacon_get_ap(hw, vif, offs, is_template,
beacon, chanctx_conf);
beacon, chanctx_conf, link_id);
} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_hdr *hdr;
@ -5143,7 +5152,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
if (!is_template)
__ieee80211_beacon_update_cntdwn(beacon);
ieee80211_set_beacon_cntdwn(sdata, beacon);
ieee80211_set_beacon_cntdwn(sdata, beacon, link_id);
}
skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
@ -5158,7 +5167,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
IEEE80211_STYPE_BEACON);
ieee80211_beacon_get_finish(hw, vif, offs, beacon, skb,
chanctx_conf, 0);
chanctx_conf, 0, link_id);
} else if (ieee80211_vif_is_mesh(&sdata->vif)) {
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
@ -5175,7 +5184,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
*/
__ieee80211_beacon_update_cntdwn(beacon);
ieee80211_set_beacon_cntdwn(sdata, beacon);
ieee80211_set_beacon_cntdwn(sdata, beacon, link_id);
}
if (ifmsh->sync_ops)
@ -5190,7 +5199,8 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
goto out;
skb_reserve(skb, local->tx_headroom);
skb_put_data(skb, beacon->head, beacon->head_len);
ieee80211_beacon_add_tim(sdata, &ifmsh->ps, skb, is_template);
ieee80211_beacon_add_tim(sdata, &ifmsh->ps, skb, is_template,
link_id);
if (offs) {
offs->tim_offset = beacon->head_len;
@ -5199,7 +5209,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
skb_put_data(skb, beacon->tail, beacon->tail_len);
ieee80211_beacon_get_finish(hw, vif, offs, beacon, skb,
chanctx_conf, 0);
chanctx_conf, 0, link_id);
} else {
WARN_ON(1);
goto out;
@ -5214,18 +5224,21 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
struct sk_buff *
ieee80211_beacon_get_template(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_mutable_offsets *offs)
struct ieee80211_mutable_offsets *offs,
unsigned int link_id)
{
return __ieee80211_beacon_get(hw, vif, offs, true);
return __ieee80211_beacon_get(hw, vif, offs, true, link_id);
}
EXPORT_SYMBOL(ieee80211_beacon_get_template);
struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
u16 *tim_offset, u16 *tim_length)
u16 *tim_offset, u16 *tim_length,
unsigned int link_id)
{
struct ieee80211_mutable_offsets offs = {};
struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false);
struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false,
link_id);
struct sk_buff *copy;
int shift;