aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern A. Zeeb <bz@FreeBSD.org>2023-09-25 16:57:23 +0000
committerBjoern A. Zeeb <bz@FreeBSD.org>2023-10-06 12:47:40 +0000
commitb6628a233e8e6407a504172a562ba14a66c7e7da (patch)
tree9ab8bcbb0d7252b1a9bca8e8b378892ed5d0066d
parentc18ead9cb26d4199dbea8cc032420ae2164928ad (diff)
downloadsrc-b6628a233e8e6407a504172a562ba14a66c7e7da.tar.gz
src-b6628a233e8e6407a504172a562ba14a66c7e7da.zip
LinuxKPI: 802.11: move ieee80211_chanctx_conf into lkpi private struct
Factor out ieee80211_chanctx_conf into struct lkpi_chanctx in order to keep local state as well. In first instance that is added_to_drv only. For now we stay single-chanctx only but this paves the path to make it a list. Use the new information to implement ieee80211_iter_chan_contexts_atomic(). Sponsored by: The FreeBSD Foundation (cherry picked from commit c5e257985085bd987b1dddffd0455c2230df2d1d)
-rw-r--r--sys/compat/linuxkpi/common/src/linux_80211.c46
-rw-r--r--sys/compat/linuxkpi/common/src/linux_80211.h9
-rw-r--r--sys/compat/linuxkpi/common/src/linux_80211_macops.c8
3 files changed, 57 insertions, 6 deletions
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index 1fee5f6809fd..d2f67230a812 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -922,6 +922,7 @@ static int
lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct linuxkpi_ieee80211_channel *chan;
+ struct lkpi_chanctx *lchanctx;
struct ieee80211_chanctx_conf *conf;
struct lkpi_hw *lhw;
struct ieee80211_hw *hw;
@@ -953,11 +954,13 @@ lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int
/* Add chanctx (or if exists, change it). */
if (vif->chanctx_conf != NULL) {
conf = vif->chanctx_conf;
+ lchanctx = CHANCTX_CONF_TO_LCHANCTX(conf);
IMPROVE("diff changes for changed, working on live copy, rcu");
} else {
/* Keep separate alloc as in Linux this is rcu managed? */
- conf = malloc(sizeof(*conf) + hw->chanctx_data_size,
+ lchanctx = malloc(sizeof(*lchanctx) + hw->chanctx_data_size,
M_LKPI80211, M_WAITOK | M_ZERO);
+ conf = &lchanctx->conf;
}
conf->rx_chains_dynamic = 1;
@@ -1022,7 +1025,8 @@ lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int
error = 0;
if (error != 0) {
lkpi_80211_mo_remove_chanctx(hw, conf);
- free(conf, M_LKPI80211);
+ lchanctx = CHANCTX_CONF_TO_LCHANCTX(conf);
+ free(lchanctx, M_LKPI80211);
goto out;
}
}
@@ -1179,6 +1183,7 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int
/* Take the chan ctx down. */
if (vif->chanctx_conf != NULL) {
+ struct lkpi_chanctx *lchanctx;
struct ieee80211_chanctx_conf *conf;
conf = vif->chanctx_conf;
@@ -1188,7 +1193,8 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int
/* Remove chan ctx. */
lkpi_80211_mo_remove_chanctx(hw, conf);
- free(conf, M_LKPI80211);
+ lchanctx = CHANCTX_CONF_TO_LCHANCTX(conf);
+ free(lchanctx, M_LKPI80211);
}
out:
@@ -1454,6 +1460,7 @@ _lkpi_sta_assoc_to_down(struct ieee80211vap *vap, enum ieee80211_state nstate, i
/* Take the chan ctx down. */
if (vif->chanctx_conf != NULL) {
+ struct lkpi_chanctx *lchanctx;
struct ieee80211_chanctx_conf *conf;
conf = vif->chanctx_conf;
@@ -1463,7 +1470,8 @@ _lkpi_sta_assoc_to_down(struct ieee80211vap *vap, enum ieee80211_state nstate, i
/* Remove chan ctx. */
lkpi_80211_mo_remove_chanctx(hw, conf);
- free(conf, M_LKPI80211);
+ lchanctx = CHANCTX_CONF_TO_LCHANCTX(conf);
+ free(lchanctx, M_LKPI80211);
}
error = EALREADY;
@@ -1916,6 +1924,7 @@ lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int
/* Take the chan ctx down. */
if (vif->chanctx_conf != NULL) {
+ struct lkpi_chanctx *lchanctx;
struct ieee80211_chanctx_conf *conf;
conf = vif->chanctx_conf;
@@ -1925,7 +1934,8 @@ lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int
/* Remove chan ctx. */
lkpi_80211_mo_remove_chanctx(hw, conf);
- free(conf, M_LKPI80211);
+ lchanctx = CHANCTX_CONF_TO_LCHANCTX(conf);
+ free(lchanctx, M_LKPI80211);
}
error = EALREADY;
@@ -3968,8 +3978,32 @@ linuxkpi_ieee80211_iterate_chan_contexts(struct ieee80211_hw *hw,
void *),
void *arg)
{
+ struct lkpi_hw *lhw;
+ struct lkpi_vif *lvif;
+ struct ieee80211_vif *vif;
+ struct lkpi_chanctx *lchanctx;
- UNIMPLEMENTED;
+ KASSERT(hw != NULL && iterfunc != NULL,
+ ("%s: hw %p iterfunc %p arg %p\n", __func__, hw, iterfunc, arg));
+
+ lhw = HW_TO_LHW(hw);
+
+ IMPROVE("lchanctx should be its own list somewhere");
+
+ LKPI_80211_LHW_LVIF_LOCK(lhw);
+ TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
+
+ vif = LVIF_TO_VIF(lvif);
+ if (vif->chanctx_conf == NULL)
+ continue;
+
+ lchanctx = CHANCTX_CONF_TO_LCHANCTX(vif->chanctx_conf);
+ if (!lchanctx->added_to_drv)
+ continue;
+
+ iterfunc(hw, &lchanctx->conf, arg);
+ }
+ LKPI_80211_LHW_LVIF_UNLOCK(lhw);
}
void
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.h b/sys/compat/linuxkpi/common/src/linux_80211.h
index 22a5f5a6377c..93c1e2873206 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.h
+++ b/sys/compat/linuxkpi/common/src/linux_80211.h
@@ -210,6 +210,15 @@ struct lkpi_hw { /* name it mac80211_sc? */
#define LHW_TO_HW(_lhw) (&(_lhw)->hw)
#define HW_TO_LHW(_hw) container_of(_hw, struct lkpi_hw, hw)
+struct lkpi_chanctx {
+ bool added_to_drv; /* Managed by MO */
+ struct ieee80211_chanctx_conf conf __aligned(CACHE_LINE_SIZE);
+};
+#define LCHANCTX_TO_CHANCTX_CONF(_lchanctx) \
+ (&(_lchanctx)->conf)
+#define CHANCTX_CONF_TO_LCHANCTX(_conf) \
+ container_of(_conf, struct lkpi_chanctx, conf)
+
struct lkpi_wiphy {
const struct cfg80211_ops *ops;
diff --git a/sys/compat/linuxkpi/common/src/linux_80211_macops.c b/sys/compat/linuxkpi/common/src/linux_80211_macops.c
index b3b53d23f62e..8f75b1bdf8b1 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211_macops.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211_macops.c
@@ -490,6 +490,7 @@ lkpi_80211_mo_add_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *chanctx_conf)
{
struct lkpi_hw *lhw;
+ struct lkpi_chanctx *lchanctx;
int error;
lhw = HW_TO_LHW(hw);
@@ -500,6 +501,10 @@ lkpi_80211_mo_add_chanctx(struct ieee80211_hw *hw,
LKPI_80211_TRACE_MO("hw %p chanctx_conf %p", hw, chanctx_conf);
error = lhw->ops->add_chanctx(hw, chanctx_conf);
+ if (error == 0) {
+ lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
+ lchanctx->added_to_drv = true;
+ }
out:
return (error);
@@ -524,6 +529,7 @@ lkpi_80211_mo_remove_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *chanctx_conf)
{
struct lkpi_hw *lhw;
+ struct lkpi_chanctx *lchanctx;
lhw = HW_TO_LHW(hw);
if (lhw->ops->remove_chanctx == NULL)
@@ -531,6 +537,8 @@ lkpi_80211_mo_remove_chanctx(struct ieee80211_hw *hw,
LKPI_80211_TRACE_MO("hw %p chanctx_conf %p", hw, chanctx_conf);
lhw->ops->remove_chanctx(hw, chanctx_conf);
+ lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
+ lchanctx->added_to_drv = false;
}
void