LinuxKPI: 802.11: split (*bss_info_changed) up for more modern drivers
With the advent of MLO some of the updates (*bss_info_changed) would have done are not per-link. This had (*vif_cfg_changed) and (*link_conf_changed) introduced which are used by iwlwifi, rtw89, select mt76 drivers, and ath12k currently it seems. A driver normally only supports on or the other set. Factor out the call to (*bss_info_changed) into an internal function. There split the options up depending on whether they are for the vif or a link and leave a fallback to (*bss_info_changed) for older drivers. Add the mac80211 ops implementations for the two new calls along with a currently unused backup option for (*bss_info_changed) for each as I assume we will eventually call the directly rather than from the internal wrapper function. Sponsored by: The FreeBSD Foundation MFC after: 3 days
This commit is contained in:
@@ -2242,6 +2242,53 @@ lkpi_remove_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
free(lchanctx, M_LKPI80211);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* Any other options belong here? Check more drivers. */
|
||||
#define BSS_CHANGED_VIF_CFG_BITS \
|
||||
(BSS_CHANGED_SSID | BSS_CHANGED_IDLE | BSS_CHANGED_PS | BSS_CHANGED_ASSOC | \
|
||||
BSS_CHANGED_ARP_FILTER | BSS_CHANGED_MLD_VALID_LINKS | BSS_CHANGED_MLD_TTLM)
|
||||
|
||||
static void
|
||||
lkpi_bss_info_change(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
enum ieee80211_bss_changed bss_changed)
|
||||
{
|
||||
struct lkpi_vif *lvif;
|
||||
enum ieee80211_bss_changed vif_cfg_bits, link_info_bits;
|
||||
|
||||
if (ieee80211_vif_is_mld(vif)) {
|
||||
TODO("This likely needs a subset only; split up into 3 parts.");
|
||||
}
|
||||
|
||||
/* Nothing to do? */
|
||||
if (bss_changed == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If the vif is not known to the driver there is nothing to notifiy for.
|
||||
* We MUST NOT check for !lvif_bss_synched here (the reasonable it seems)
|
||||
* as we need to execute the update(s) or we will have follow-up issues.
|
||||
*/
|
||||
lvif = VIF_TO_LVIF(vif);
|
||||
if (!lvif->added_to_drv)
|
||||
return;
|
||||
|
||||
/*
|
||||
* With the advent of MLO bss_conf got split up into vif and link
|
||||
* change notfications, while historically it was one.
|
||||
* We now need to support all possible models.
|
||||
*/
|
||||
vif_cfg_bits = bss_changed & BSS_CHANGED_VIF_CFG_BITS;
|
||||
if (vif_cfg_bits != 0)
|
||||
lkpi_80211_mo_vif_cfg_changed(hw, vif, vif_cfg_bits, false);
|
||||
|
||||
link_info_bits = bss_changed & ~(BSS_CHANGED_VIF_CFG_BITS);
|
||||
if (link_info_bits != 0)
|
||||
lkpi_80211_mo_link_info_changed(hw, vif, &vif->bss_conf,
|
||||
link_info_bits, 0, false);
|
||||
|
||||
lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@@ -2457,7 +2504,7 @@ lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int
|
||||
|
||||
/* RATES */
|
||||
IMPROVE("bss info: not all needs to come now and rates are missing");
|
||||
lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
|
||||
lkpi_bss_info_change(hw, vif, bss_changed);
|
||||
|
||||
/*
|
||||
* Given ni and lsta are 1:1 from alloc to free we can assert that
|
||||
@@ -2791,7 +2838,7 @@ lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int
|
||||
}
|
||||
|
||||
bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__);
|
||||
lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
|
||||
lkpi_bss_info_change(hw, vif, bss_changed);
|
||||
|
||||
/* - change_chanctx (if needed)
|
||||
* - event_callback
|
||||
@@ -2851,7 +2898,7 @@ lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int
|
||||
|
||||
bss_changed = 0;
|
||||
bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__);
|
||||
lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
|
||||
lkpi_bss_info_change(hw, vif, bss_changed);
|
||||
|
||||
/* Prepare_multicast && configure_filter. */
|
||||
lkpi_update_mcast_filter(vap->iv_ic);
|
||||
@@ -3289,7 +3336,7 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int
|
||||
/* XXX BSS_CHANGED_???? */
|
||||
vif->bss_conf.dtim_period = 0; /* go back to 0. */
|
||||
bss_changed |= BSS_CHANGED_BEACON_INFO;
|
||||
lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
|
||||
lkpi_bss_info_change(hw, vif, bss_changed);
|
||||
|
||||
LKPI_80211_LVIF_LOCK(lvif);
|
||||
/* Remove ni reference for this cache of lsta. */
|
||||
@@ -3653,7 +3700,7 @@ lkpi_wme_update(struct lkpi_hw *lhw, struct ieee80211vap *vap, bool planned)
|
||||
struct chanAccParams chp;
|
||||
struct wmeParams wmeparr[WME_NUM_AC];
|
||||
struct ieee80211_tx_queue_params txqp;
|
||||
enum ieee80211_bss_changed changed;
|
||||
enum ieee80211_bss_changed bss_changed;
|
||||
int error;
|
||||
uint16_t ac;
|
||||
|
||||
@@ -3704,11 +3751,11 @@ lkpi_wme_update(struct lkpi_hw *lhw, struct ieee80211vap *vap, bool planned)
|
||||
ic_printf(ic, "%s: conf_tx ac %u failed %d\n",
|
||||
__func__, ac, error);
|
||||
}
|
||||
changed = BSS_CHANGED_QOS;
|
||||
bss_changed = BSS_CHANGED_QOS;
|
||||
if (!planned)
|
||||
lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed);
|
||||
lkpi_bss_info_change(hw, vif, bss_changed);
|
||||
|
||||
return (changed);
|
||||
return (bss_changed);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3774,7 +3821,7 @@ lkpi_iv_sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
||||
* locking, see if queue_work() is fast enough.
|
||||
*/
|
||||
bss_changed = lkpi_update_dtim_tsf(vif, ni, ni->ni_vap, __func__, __LINE__);
|
||||
lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
|
||||
lkpi_bss_info_change(hw, vif, bss_changed);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3820,7 +3867,7 @@ lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
|
||||
struct ieee80211vap *vap;
|
||||
struct ieee80211_vif *vif;
|
||||
struct ieee80211_tx_queue_params txqp;
|
||||
enum ieee80211_bss_changed changed;
|
||||
enum ieee80211_bss_changed bss_changed;
|
||||
struct sysctl_oid *node;
|
||||
size_t len;
|
||||
int error, i;
|
||||
@@ -3937,8 +3984,8 @@ lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
|
||||
LKPI_80211_LHW_LVIF_UNLOCK(lhw);
|
||||
|
||||
/* Set bss_info. */
|
||||
changed = 0;
|
||||
lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed);
|
||||
bss_changed = 0;
|
||||
lkpi_bss_info_change(hw, vif, bss_changed);
|
||||
|
||||
/* Configure tx queues (conf_tx), default WME & send BSS_CHANGED_QOS. */
|
||||
IMPROVE("Hardcoded values; to fix see 802.11-2016, 9.4.2.29 EDCA Parameter Set element");
|
||||
@@ -3956,8 +4003,8 @@ lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
|
||||
__func__, ac, error);
|
||||
}
|
||||
wiphy_unlock(hw->wiphy);
|
||||
changed = BSS_CHANGED_QOS;
|
||||
lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed);
|
||||
bss_changed = BSS_CHANGED_QOS;
|
||||
lkpi_bss_info_change(hw, vif, bss_changed);
|
||||
|
||||
/* Force MC init. */
|
||||
lkpi_update_mcast_filter(ic);
|
||||
|
||||
@@ -469,6 +469,10 @@ void lkpi_80211_mo_change_chanctx(struct ieee80211_hw *,
|
||||
struct ieee80211_chanctx_conf *, uint32_t);
|
||||
void lkpi_80211_mo_remove_chanctx(struct ieee80211_hw *,
|
||||
struct ieee80211_chanctx_conf *);
|
||||
void lkpi_80211_mo_vif_cfg_changed(struct ieee80211_hw *, struct ieee80211_vif *,
|
||||
uint64_t, bool);
|
||||
void lkpi_80211_mo_link_info_changed(struct ieee80211_hw *, struct ieee80211_vif *,
|
||||
struct ieee80211_bss_conf *, uint64_t, uint8_t, bool);
|
||||
void lkpi_80211_mo_bss_info_changed(struct ieee80211_hw *, struct ieee80211_vif *,
|
||||
struct ieee80211_bss_conf *, uint64_t);
|
||||
int lkpi_80211_mo_conf_tx(struct ieee80211_hw *, struct ieee80211_vif *,
|
||||
|
||||
@@ -546,24 +546,80 @@ lkpi_80211_mo_remove_chanctx(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
void
|
||||
lkpi_80211_mo_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *conf, uint64_t changed)
|
||||
lkpi_80211_mo_vif_cfg_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
uint64_t vif_cfg_bits, bool fallback)
|
||||
{
|
||||
struct lkpi_hw *lhw;
|
||||
|
||||
might_sleep();
|
||||
/* XXX-FINISH all callers for lockdep_assert_wiphy(hw->wiphy); */
|
||||
|
||||
lhw = HW_TO_LHW(hw);
|
||||
if (lhw->ops->vif_cfg_changed == NULL &&
|
||||
lhw->ops->bss_info_changed == NULL)
|
||||
return;
|
||||
|
||||
if (vif_cfg_bits == 0)
|
||||
return;
|
||||
|
||||
LKPI_80211_TRACE_MO("hw %p vif %p vif_cfg_bits %#jx", hw, vif, (uintmax_t)vif_cfg_bits);
|
||||
if (lhw->ops->link_info_changed != NULL)
|
||||
lhw->ops->vif_cfg_changed(hw, vif, vif_cfg_bits);
|
||||
else if (fallback)
|
||||
lhw->ops->bss_info_changed(hw, vif, &vif->bss_conf, vif_cfg_bits);
|
||||
}
|
||||
|
||||
void
|
||||
lkpi_80211_mo_link_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *conf, uint64_t link_info_bits, uint8_t link_id,
|
||||
bool fallback)
|
||||
{
|
||||
struct lkpi_hw *lhw;
|
||||
|
||||
might_sleep();
|
||||
/* XXX-FINISH all callers for lockdep_assert_wiphy(hw->wiphy); */
|
||||
|
||||
lhw = HW_TO_LHW(hw);
|
||||
if (lhw->ops->link_info_changed == NULL &&
|
||||
lhw->ops->bss_info_changed == NULL)
|
||||
return;
|
||||
|
||||
if (changed == 0)
|
||||
if (link_info_bits == 0)
|
||||
return;
|
||||
|
||||
LKPI_80211_TRACE_MO("hw %p vif %p conf %p changed %#jx", hw, vif, conf, (uintmax_t)changed);
|
||||
if (!ieee80211_vif_link_active(vif, link_id))
|
||||
return;
|
||||
|
||||
LKPI_80211_TRACE_MO("hw %p vif %p conf %p link_info_bits %#jx", hw, vif, conf, (uintmax_t)link_info_bits);
|
||||
if (lhw->ops->link_info_changed != NULL)
|
||||
lhw->ops->link_info_changed(hw, vif, conf, changed);
|
||||
else
|
||||
lhw->ops->bss_info_changed(hw, vif, conf, changed);
|
||||
lhw->ops->link_info_changed(hw, vif, conf, link_info_bits);
|
||||
else if (fallback)
|
||||
lhw->ops->bss_info_changed(hw, vif, conf, link_info_bits);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is basically obsolete but one caller.
|
||||
* The functionality is now split between lkpi_80211_mo_link_info_changed() and
|
||||
* lkpi_80211_mo_vif_cfg_changed(). Those functions have a flag whether to call
|
||||
* the (*bss_info_changed) fallback or not. See lkpi_bss_info_change().
|
||||
*/
|
||||
void
|
||||
lkpi_80211_mo_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *conf, uint64_t bss_changed)
|
||||
{
|
||||
struct lkpi_hw *lhw;
|
||||
|
||||
/* XXX-FINISH all callers for lockdep_assert_wiphy(hw->wiphy); */
|
||||
|
||||
lhw = HW_TO_LHW(hw);
|
||||
if (lhw->ops->bss_info_changed == NULL)
|
||||
return;
|
||||
|
||||
if (bss_changed == 0)
|
||||
return;
|
||||
|
||||
LKPI_80211_TRACE_MO("hw %p vif %p conf %p changed %#jx", hw, vif, conf, (uintmax_t)bss_changed);
|
||||
lhw->ops->bss_info_changed(hw, vif, conf, bss_changed);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
Reference in New Issue
Block a user