[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
This commit is contained in:
parent
d60bdf8569
commit
ea3d5fd9df
@ -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++;
|
||||
|
@ -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*);
|
||||
|
Loading…
Reference in New Issue
Block a user