summaryrefslogtreecommitdiff
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index eed88630594f..75122eced104 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -96,6 +96,14 @@ static int sta_info_hash_del(struct ieee80211_local *local,
sta_rht_params);
}
+static int link_sta_info_hash_add(struct ieee80211_local *local,
+ struct link_sta_info *link_sta)
+{
+ return rhltable_insert(&local->link_sta_hash,
+ &link_sta->link_hash_node,
+ link_sta_rht_params);
+}
+
static int link_sta_info_hash_del(struct ieee80211_local *local,
struct link_sta_info *link_sta)
{
@@ -466,8 +474,10 @@ static void sta_info_add_link(struct sta_info *sta,
rcu_assign_pointer(sta->sta.link[link_id], link_sta);
}
-struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
- const u8 *addr, int link_id, gfp_t gfp)
+static struct sta_info *
+__sta_info_alloc(struct ieee80211_sub_if_data *sdata,
+ const u8 *addr, int link_id, const u8 *link_addr,
+ gfp_t gfp)
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_hw *hw = &local->hw;
@@ -513,8 +523,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
memcpy(sta->addr, addr, ETH_ALEN);
memcpy(sta->sta.addr, addr, ETH_ALEN);
- memcpy(sta->deflink.addr, addr, ETH_ALEN);
- memcpy(sta->sta.deflink.addr, addr, ETH_ALEN);
+ memcpy(sta->deflink.addr, link_addr, ETH_ALEN);
+ memcpy(sta->sta.deflink.addr, link_addr, ETH_ALEN);
sta->sta.max_rx_aggregation_subframes =
local->hw.max_rx_aggregation_subframes;
@@ -641,6 +651,21 @@ free:
return NULL;
}
+struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
+ const u8 *addr, gfp_t gfp)
+{
+ return __sta_info_alloc(sdata, addr, -1, addr, gfp);
+}
+
+struct sta_info *sta_info_alloc_with_link(struct ieee80211_sub_if_data *sdata,
+ const u8 *mld_addr,
+ unsigned int link_id,
+ const u8 *link_addr,
+ gfp_t gfp)
+{
+ return __sta_info_alloc(sdata, mld_addr, link_id, link_addr, gfp);
+}
+
static int sta_info_insert_check(struct sta_info *sta)
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -774,6 +799,14 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
if (err)
goto out_drop_sta;
+ if (sta->sta.valid_links) {
+ err = link_sta_info_hash_add(local, &sta->deflink);
+ if (err) {
+ sta_info_hash_del(local, sta);
+ goto out_drop_sta;
+ }
+ }
+
list_add_tail_rcu(&sta->list, &local->sta_list);
/* update channel context before notifying the driver about state
@@ -2697,14 +2730,6 @@ int ieee80211_sta_allocate_link(struct sta_info *sta, unsigned int link_id)
return 0;
}
-static int link_sta_info_hash_add(struct ieee80211_local *local,
- struct link_sta_info *link_sta)
-{
- return rhltable_insert(&local->link_sta_hash,
- &link_sta->link_hash_node,
- link_sta_rht_params);
-}
-
void ieee80211_sta_free_link(struct sta_info *sta, unsigned int link_id)
{
lockdep_assert_held(&sta->sdata->local->sta_mtx);