From ea3d5fd9df90708b5b996a96dc694c7939e0305d Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 13 Jun 2020 22:20:02 +0000 Subject: [PATCH] [net80211] separate out node allocation and node initialisation. This is a new, optional (for now!) method that drivers can use to separate node allocation and node initialisation. Right now they're the same, and drivers that need to do node allocation via firmware commands need to sleep and thus they need to defer node allocation into an internal taskqueue. Right now they're just separate but not deferred. Later on if I get the time we'll start deferring the node and key related operations but that requires making a bunch of other stuff (notably things that generate frames!) also async/deferred. Tested: * RT3593, STA/DWDS mode * AR9380, STA/AP modes * QCA9880 (athp) - STA/AP modes --- sys/net80211/ieee80211_node.c | 27 +++++++++++++++++++++++++++ sys/net80211/ieee80211_var.h | 13 ++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index 1aecc01089d..14e1e762aa8 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -80,6 +80,7 @@ static int ieee80211_sta_join1(struct ieee80211_node *); static struct ieee80211_node *node_alloc(struct ieee80211vap *, const uint8_t [IEEE80211_ADDR_LEN]); +static int node_init(struct ieee80211_node *); static void node_cleanup(struct ieee80211_node *); static void node_free(struct ieee80211_node *); static void node_age(struct ieee80211_node *); @@ -116,6 +117,7 @@ ieee80211_node_attach(struct ieee80211com *ic) ieee80211_node_timeout, ic); ic->ic_node_alloc = node_alloc; + ic->ic_node_init = node_init; ic->ic_node_free = node_free; ic->ic_node_cleanup = node_cleanup; ic->ic_node_age = node_age; @@ -1074,6 +1076,12 @@ node_alloc(struct ieee80211vap *vap, const uint8_t macaddr[IEEE80211_ADDR_LEN]) return ni; } +static int +node_init(struct ieee80211_node *ni) +{ + return 0; +} + /* * Initialize an ie blob with the specified data. If previous * data exists re-use the data block. As a side effect we clear @@ -1414,6 +1422,15 @@ ieee80211_alloc_node(struct ieee80211_node_table *nt, ni->ni_ic = ic; IEEE80211_NODE_UNLOCK(nt); + /* handle failure; free node state */ + if (ic->ic_node_init(ni) != 0) { + vap->iv_stats.is_rx_nodealloc++; + ieee80211_psq_cleanup(&ni->ni_psq); + ieee80211_ratectl_node_deinit(ni); + _ieee80211_free_node(ni); + return NULL; + } + IEEE80211_NOTE(vap, IEEE80211_MSG_INACT, ni, "%s: inact_reload %u", __func__, ni->ni_inact_reload); @@ -1456,6 +1473,16 @@ ieee80211_tmp_node(struct ieee80211vap *vap, ieee80211_psq_init(&ni->ni_psq, "unknown"); ieee80211_ratectl_node_init(ni); + + /* handle failure; free node state */ + if (ic->ic_node_init(ni) != 0) { + vap->iv_stats.is_rx_nodealloc++; + ieee80211_psq_cleanup(&ni->ni_psq); + ieee80211_ratectl_node_deinit(ni); + _ieee80211_free_node(ni); + return NULL; + } + } else { /* XXX msg */ vap->iv_stats.is_rx_nodealloc++; diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index 6af94ed343c..6bdbd609a41 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -310,11 +310,22 @@ struct ieee80211com { /* TDMA update notification */ void (*ic_tdma_update)(struct ieee80211_node *, const struct ieee80211_tdma_param *, int); - /* node state management */ + + /* Node state management */ + + /* Allocate a new node */ struct ieee80211_node* (*ic_node_alloc)(struct ieee80211vap *, const uint8_t [IEEE80211_ADDR_LEN]); + + /* Driver node initialisation after net80211 setup */ + int (*ic_node_init)(struct ieee80211_node *); + + /* Driver node deallocation */ void (*ic_node_free)(struct ieee80211_node *); + + /* Driver node state cleanup before deallocation */ void (*ic_node_cleanup)(struct ieee80211_node *); + void (*ic_node_age)(struct ieee80211_node *); void (*ic_node_drain)(struct ieee80211_node *); int8_t (*ic_node_getrssi)(const struct ieee80211_node*); -- 2.45.0