mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 06:57:57 +00:00
03ea0405a6
Signed-off-by: Felix Fietkau <nbd@nbd.name>
263 lines
7.4 KiB
Diff
263 lines
7.4 KiB
Diff
From: Aloka Dixit <alokad@codeaurora.org>
|
|
Date: Tue, 5 Oct 2021 21:09:36 -0700
|
|
Subject: [PATCH] mac80211: split beacon retrieval functions
|
|
|
|
Split __ieee80211_beacon_get() into a separate function for AP mode
|
|
ieee80211_beacon_get_ap().
|
|
Also, move the code common to all modes (AP, adhoc and mesh) to
|
|
a separate function ieee80211_beacon_get_finish().
|
|
|
|
Signed-off-by: Aloka Dixit <alokad@codeaurora.org>
|
|
Link: https://lore.kernel.org/r/20211006040938.9531-2-alokad@codeaurora.org
|
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
|
---
|
|
|
|
--- a/net/mac80211/tx.c
|
|
+++ b/net/mac80211/tx.c
|
|
@@ -4987,6 +4987,115 @@ static int ieee80211_beacon_protect(stru
|
|
return 0;
|
|
}
|
|
|
|
+static void
|
|
+ieee80211_beacon_get_finish(struct ieee80211_hw *hw,
|
|
+ struct ieee80211_vif *vif,
|
|
+ struct ieee80211_mutable_offsets *offs,
|
|
+ struct beacon_data *beacon,
|
|
+ struct sk_buff *skb,
|
|
+ struct ieee80211_chanctx_conf *chanctx_conf,
|
|
+ u16 csa_off_base)
|
|
+{
|
|
+ struct ieee80211_local *local = hw_to_local(hw);
|
|
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
|
+ struct ieee80211_tx_info *info;
|
|
+ enum nl80211_band band;
|
|
+ struct ieee80211_tx_rate_control txrc;
|
|
+
|
|
+ /* CSA offsets */
|
|
+ if (offs && beacon) {
|
|
+ u16 i;
|
|
+
|
|
+ for (i = 0; i < IEEE80211_MAX_CNTDWN_COUNTERS_NUM; i++) {
|
|
+ u16 csa_off = beacon->cntdwn_counter_offsets[i];
|
|
+
|
|
+ if (!csa_off)
|
|
+ continue;
|
|
+
|
|
+ offs->cntdwn_counter_offs[i] = csa_off_base + csa_off;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ band = chanctx_conf->def.chan->band;
|
|
+ info = IEEE80211_SKB_CB(skb);
|
|
+ info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
|
|
+ info->flags |= IEEE80211_TX_CTL_NO_ACK;
|
|
+ info->band = band;
|
|
+
|
|
+ memset(&txrc, 0, sizeof(txrc));
|
|
+ txrc.hw = hw;
|
|
+ txrc.sband = local->hw.wiphy->bands[band];
|
|
+ txrc.bss_conf = &sdata->vif.bss_conf;
|
|
+ txrc.skb = skb;
|
|
+ txrc.reported_rate.idx = -1;
|
|
+ if (sdata->beacon_rate_set && sdata->beacon_rateidx_mask[band])
|
|
+ txrc.rate_idx_mask = sdata->beacon_rateidx_mask[band];
|
|
+ else
|
|
+ txrc.rate_idx_mask = sdata->rc_rateidx_mask[band];
|
|
+ txrc.bss = true;
|
|
+ rate_control_get_rate(sdata, NULL, &txrc);
|
|
+
|
|
+ info->control.vif = vif;
|
|
+ info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT |
|
|
+ IEEE80211_TX_CTL_ASSIGN_SEQ |
|
|
+ IEEE80211_TX_CTL_FIRST_FRAGMENT;
|
|
+}
|
|
+
|
|
+static struct sk_buff *
|
|
+ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
|
|
+ struct ieee80211_vif *vif,
|
|
+ struct ieee80211_mutable_offsets *offs,
|
|
+ bool is_template,
|
|
+ struct beacon_data *beacon,
|
|
+ struct ieee80211_chanctx_conf *chanctx_conf)
|
|
+{
|
|
+ struct ieee80211_local *local = hw_to_local(hw);
|
|
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
|
+ struct ieee80211_if_ap *ap = &sdata->u.ap;
|
|
+ struct sk_buff *skb = NULL;
|
|
+ u16 csa_off_base = 0;
|
|
+
|
|
+ if (beacon->cntdwn_counter_offsets[0]) {
|
|
+ if (!is_template)
|
|
+ ieee80211_beacon_update_cntdwn(vif);
|
|
+
|
|
+ ieee80211_set_beacon_cntdwn(sdata, beacon);
|
|
+ }
|
|
+
|
|
+ /* headroom, head length,
|
|
+ * tail length and maximum TIM length
|
|
+ */
|
|
+ skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
|
|
+ beacon->tail_len + 256 +
|
|
+ local->hw.extra_beacon_tailroom);
|
|
+ if (!skb)
|
|
+ return NULL;
|
|
+
|
|
+ skb_reserve(skb, local->tx_headroom);
|
|
+ skb_put_data(skb, beacon->head, beacon->head_len);
|
|
+
|
|
+ ieee80211_beacon_add_tim(sdata, &ap->ps, skb, is_template);
|
|
+
|
|
+ if (offs) {
|
|
+ offs->tim_offset = beacon->head_len;
|
|
+ offs->tim_length = skb->len - beacon->head_len;
|
|
+ offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0];
|
|
+
|
|
+ /* for AP the csa offsets are from tail */
|
|
+ csa_off_base = skb->len;
|
|
+ }
|
|
+
|
|
+ if (beacon->tail)
|
|
+ skb_put_data(skb, beacon->tail, beacon->tail_len);
|
|
+
|
|
+ if (ieee80211_beacon_protect(skb, local, sdata) < 0)
|
|
+ return NULL;
|
|
+
|
|
+ ieee80211_beacon_get_finish(hw, vif, offs, beacon, skb, chanctx_conf,
|
|
+ csa_off_base);
|
|
+ return skb;
|
|
+}
|
|
+
|
|
static struct sk_buff *
|
|
__ieee80211_beacon_get(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
@@ -4996,12 +5105,8 @@ __ieee80211_beacon_get(struct ieee80211_
|
|
struct ieee80211_local *local = hw_to_local(hw);
|
|
struct beacon_data *beacon = NULL;
|
|
struct sk_buff *skb = NULL;
|
|
- struct ieee80211_tx_info *info;
|
|
struct ieee80211_sub_if_data *sdata = NULL;
|
|
- enum nl80211_band band;
|
|
- struct ieee80211_tx_rate_control txrc;
|
|
struct ieee80211_chanctx_conf *chanctx_conf;
|
|
- int csa_off_base = 0;
|
|
|
|
rcu_read_lock();
|
|
|
|
@@ -5018,48 +5123,11 @@ __ieee80211_beacon_get(struct ieee80211_
|
|
struct ieee80211_if_ap *ap = &sdata->u.ap;
|
|
|
|
beacon = rcu_dereference(ap->beacon);
|
|
- if (beacon) {
|
|
- if (beacon->cntdwn_counter_offsets[0]) {
|
|
- if (!is_template)
|
|
- ieee80211_beacon_update_cntdwn(vif);
|
|
-
|
|
- ieee80211_set_beacon_cntdwn(sdata, beacon);
|
|
- }
|
|
-
|
|
- /*
|
|
- * headroom, head length,
|
|
- * tail length and maximum TIM length
|
|
- */
|
|
- skb = dev_alloc_skb(local->tx_headroom +
|
|
- beacon->head_len +
|
|
- beacon->tail_len + 256 +
|
|
- local->hw.extra_beacon_tailroom);
|
|
- if (!skb)
|
|
- goto out;
|
|
-
|
|
- skb_reserve(skb, local->tx_headroom);
|
|
- skb_put_data(skb, beacon->head, beacon->head_len);
|
|
-
|
|
- ieee80211_beacon_add_tim(sdata, &ap->ps, skb,
|
|
- is_template);
|
|
-
|
|
- if (offs) {
|
|
- offs->tim_offset = beacon->head_len;
|
|
- offs->tim_length = skb->len - beacon->head_len;
|
|
- offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0];
|
|
-
|
|
- /* for AP the csa offsets are from tail */
|
|
- csa_off_base = skb->len;
|
|
- }
|
|
-
|
|
- if (beacon->tail)
|
|
- skb_put_data(skb, beacon->tail,
|
|
- beacon->tail_len);
|
|
-
|
|
- if (ieee80211_beacon_protect(skb, local, sdata) < 0)
|
|
- goto out;
|
|
- } else
|
|
+ if (!beacon)
|
|
goto out;
|
|
+
|
|
+ skb = ieee80211_beacon_get_ap(hw, vif, offs, is_template,
|
|
+ beacon, chanctx_conf);
|
|
} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
|
|
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
|
|
struct ieee80211_hdr *hdr;
|
|
@@ -5085,6 +5153,9 @@ __ieee80211_beacon_get(struct ieee80211_
|
|
hdr = (struct ieee80211_hdr *) skb->data;
|
|
hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
|
IEEE80211_STYPE_BEACON);
|
|
+
|
|
+ ieee80211_beacon_get_finish(hw, vif, offs, beacon, skb,
|
|
+ chanctx_conf, 0);
|
|
} else if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
|
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
|
|
|
@@ -5124,51 +5195,13 @@ __ieee80211_beacon_get(struct ieee80211_
|
|
}
|
|
|
|
skb_put_data(skb, beacon->tail, beacon->tail_len);
|
|
+ ieee80211_beacon_get_finish(hw, vif, offs, beacon, skb,
|
|
+ chanctx_conf, 0);
|
|
} else {
|
|
WARN_ON(1);
|
|
goto out;
|
|
}
|
|
|
|
- /* CSA offsets */
|
|
- if (offs && beacon) {
|
|
- int i;
|
|
-
|
|
- for (i = 0; i < IEEE80211_MAX_CNTDWN_COUNTERS_NUM; i++) {
|
|
- u16 csa_off = beacon->cntdwn_counter_offsets[i];
|
|
-
|
|
- if (!csa_off)
|
|
- continue;
|
|
-
|
|
- offs->cntdwn_counter_offs[i] = csa_off_base + csa_off;
|
|
- }
|
|
- }
|
|
-
|
|
- band = chanctx_conf->def.chan->band;
|
|
-
|
|
- info = IEEE80211_SKB_CB(skb);
|
|
-
|
|
- info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
|
|
- info->flags |= IEEE80211_TX_CTL_NO_ACK;
|
|
- info->band = band;
|
|
-
|
|
- memset(&txrc, 0, sizeof(txrc));
|
|
- txrc.hw = hw;
|
|
- txrc.sband = local->hw.wiphy->bands[band];
|
|
- txrc.bss_conf = &sdata->vif.bss_conf;
|
|
- txrc.skb = skb;
|
|
- txrc.reported_rate.idx = -1;
|
|
- if (sdata->beacon_rate_set && sdata->beacon_rateidx_mask[band])
|
|
- txrc.rate_idx_mask = sdata->beacon_rateidx_mask[band];
|
|
- else
|
|
- txrc.rate_idx_mask = sdata->rc_rateidx_mask[band];
|
|
- txrc.bss = true;
|
|
- rate_control_get_rate(sdata, NULL, &txrc);
|
|
-
|
|
- info->control.vif = vif;
|
|
-
|
|
- info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT |
|
|
- IEEE80211_TX_CTL_ASSIGN_SEQ |
|
|
- IEEE80211_TX_CTL_FIRST_FRAGMENT;
|
|
out:
|
|
rcu_read_unlock();
|
|
return skb;
|