Commit 0ab26380 authored by Johannes Berg's avatar Johannes Berg

wifi: mac80211: extend ieee80211_nullfunc_get() for MLO

Add a link_id parameter to ieee80211_nullfunc_get() to be
able to obtain a correctly addressed frame.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent e229f978
...@@ -1113,7 +1113,7 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp, ...@@ -1113,7 +1113,7 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
if (!avp->assoc) if (!avp->assoc)
return false; return false;
skb = ieee80211_nullfunc_get(sc->hw, vif, false); skb = ieee80211_nullfunc_get(sc->hw, vif, -1, false);
if (!skb) if (!skb)
return false; return false;
......
...@@ -1082,10 +1082,10 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw, ...@@ -1082,10 +1082,10 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw,
skb_new = ieee80211_proberesp_get(hw, vif); skb_new = ieee80211_proberesp_get(hw, vif);
break; break;
case RSVD_NULL: case RSVD_NULL:
skb_new = ieee80211_nullfunc_get(hw, vif, false); skb_new = ieee80211_nullfunc_get(hw, vif, -1, false);
break; break;
case RSVD_QOS_NULL: case RSVD_QOS_NULL:
skb_new = ieee80211_nullfunc_get(hw, vif, true); skb_new = ieee80211_nullfunc_get(hw, vif, -1, true);
break; break;
case RSVD_LPS_PG_DPK: case RSVD_LPS_PG_DPK:
skb_new = rtw_lps_pg_dpk_get(hw); skb_new = rtw_lps_pg_dpk_get(hw);
......
...@@ -195,7 +195,7 @@ void __cw1200_cqm_bssloss_sm(struct cw1200_common *priv, ...@@ -195,7 +195,7 @@ void __cw1200_cqm_bssloss_sm(struct cw1200_common *priv,
priv->bss_loss_state++; priv->bss_loss_state++;
skb = ieee80211_nullfunc_get(priv->hw, priv->vif, false); skb = ieee80211_nullfunc_get(priv->hw, priv->vif, -1, false);
WARN_ON(!skb); WARN_ON(!skb);
if (skb) if (skb)
cw1200_tx(priv->hw, NULL, skb); cw1200_tx(priv->hw, NULL, skb);
...@@ -2263,7 +2263,7 @@ static int cw1200_upload_null(struct cw1200_common *priv) ...@@ -2263,7 +2263,7 @@ static int cw1200_upload_null(struct cw1200_common *priv)
.rate = 0xFF, .rate = 0xFF,
}; };
frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif, false); frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif,-1, false);
if (!frame.skb) if (!frame.skb)
return -ENOMEM; return -ENOMEM;
......
...@@ -546,7 +546,7 @@ static int wl1251_build_null_data(struct wl1251 *wl) ...@@ -546,7 +546,7 @@ static int wl1251_build_null_data(struct wl1251 *wl)
size = sizeof(struct wl12xx_null_data_template); size = sizeof(struct wl12xx_null_data_template);
ptr = NULL; ptr = NULL;
} else { } else {
skb = ieee80211_nullfunc_get(wl->hw, wl->vif, false); skb = ieee80211_nullfunc_get(wl->hw, wl->vif, -1, false);
if (!skb) if (!skb)
goto out; goto out;
size = skb->len; size = skb->len;
......
...@@ -1065,7 +1065,7 @@ int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif) ...@@ -1065,7 +1065,7 @@ int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif)
} else { } else {
skb = ieee80211_nullfunc_get(wl->hw, skb = ieee80211_nullfunc_get(wl->hw,
wl12xx_wlvif_to_vif(wlvif), wl12xx_wlvif_to_vif(wlvif),
false); -1, false);
if (!skb) if (!skb)
goto out; goto out;
size = skb->len; size = skb->len;
...@@ -1092,7 +1092,7 @@ int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl, ...@@ -1092,7 +1092,7 @@ int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl,
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
int ret = -ENOMEM; int ret = -ENOMEM;
skb = ieee80211_nullfunc_get(wl->hw, vif, false); skb = ieee80211_nullfunc_get(wl->hw, vif,-1, false);
if (!skb) if (!skb)
goto out; goto out;
......
...@@ -5298,6 +5298,9 @@ struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw, ...@@ -5298,6 +5298,9 @@ struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,
* ieee80211_nullfunc_get - retrieve a nullfunc template * ieee80211_nullfunc_get - retrieve a nullfunc template
* @hw: pointer obtained from ieee80211_alloc_hw(). * @hw: pointer obtained from ieee80211_alloc_hw().
* @vif: &struct ieee80211_vif pointer from the add_interface callback. * @vif: &struct ieee80211_vif pointer from the add_interface callback.
* @link_id: If the vif is an MLD, get a frame with the link addresses
* for the given link ID. For a link_id < 0 you get a frame with
* MLD addresses, however useful that might be.
* @qos_ok: QoS NDP is acceptable to the caller, this should be set * @qos_ok: QoS NDP is acceptable to the caller, this should be set
* if at all possible * if at all possible
* *
...@@ -5315,7 +5318,7 @@ struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw, ...@@ -5315,7 +5318,7 @@ struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,
*/ */
struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw, struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
bool qos_ok); int link_id, bool qos_ok);
/** /**
* ieee80211_probereq_get - retrieve a Probe Request template * ieee80211_probereq_get - retrieve a Probe Request template
......
...@@ -1546,8 +1546,9 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local, ...@@ -1546,8 +1546,9 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
struct ieee80211_hdr_3addr *nullfunc; struct ieee80211_hdr_3addr *nullfunc;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif, skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif, -1,
!ieee80211_hw_check(&local->hw, DOESNT_SUPPORT_QOS_NDP)); !ieee80211_hw_check(&local->hw,
DOESNT_SUPPORT_QOS_NDP));
if (!skb) if (!skb)
return; return;
......
...@@ -5469,33 +5469,39 @@ EXPORT_SYMBOL(ieee80211_pspoll_get); ...@@ -5469,33 +5469,39 @@ EXPORT_SYMBOL(ieee80211_pspoll_get);
struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw, struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
bool qos_ok) int link_id, bool qos_ok)
{ {
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
struct ieee80211_local *local = sdata->local;
struct ieee80211_link_data *link = NULL;
struct ieee80211_hdr_3addr *nullfunc; struct ieee80211_hdr_3addr *nullfunc;
struct ieee80211_sub_if_data *sdata;
struct ieee80211_local *local;
struct sk_buff *skb; struct sk_buff *skb;
bool qos = false; bool qos = false;
if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
return NULL; return NULL;
sdata = vif_to_sdata(vif); skb = dev_alloc_skb(local->hw.extra_tx_headroom +
local = sdata->local; sizeof(*nullfunc) + 2);
if (!skb)
return NULL;
rcu_read_lock();
if (qos_ok) { if (qos_ok) {
struct sta_info *sta; struct sta_info *sta;
rcu_read_lock(); sta = sta_info_get(sdata, vif->cfg.ap_addr);
sta = sta_info_get(sdata, sdata->deflink.u.mgd.bssid);
qos = sta && sta->sta.wme; qos = sta && sta->sta.wme;
rcu_read_unlock();
} }
skb = dev_alloc_skb(local->hw.extra_tx_headroom + if (link_id >= 0) {
sizeof(*nullfunc) + 2); link = rcu_dereference(sdata->link[link_id]);
if (!skb) if (WARN_ON_ONCE(!link)) {
return NULL; rcu_read_unlock();
kfree_skb(skb);
return NULL;
}
}
skb_reserve(skb, local->hw.extra_tx_headroom); skb_reserve(skb, local->hw.extra_tx_headroom);
...@@ -5516,9 +5522,16 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw, ...@@ -5516,9 +5522,16 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
skb_put_data(skb, &qoshdr, sizeof(qoshdr)); skb_put_data(skb, &qoshdr, sizeof(qoshdr));
} }
memcpy(nullfunc->addr1, sdata->deflink.u.mgd.bssid, ETH_ALEN); if (link) {
memcpy(nullfunc->addr2, vif->addr, ETH_ALEN); memcpy(nullfunc->addr1, link->conf->bssid, ETH_ALEN);
memcpy(nullfunc->addr3, sdata->deflink.u.mgd.bssid, ETH_ALEN); memcpy(nullfunc->addr2, link->conf->addr, ETH_ALEN);
memcpy(nullfunc->addr3, link->conf->bssid, ETH_ALEN);
} else {
memcpy(nullfunc->addr1, vif->cfg.ap_addr, ETH_ALEN);
memcpy(nullfunc->addr2, vif->addr, ETH_ALEN);
memcpy(nullfunc->addr3, vif->cfg.ap_addr, ETH_ALEN);
}
rcu_read_unlock();
return skb; return 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