aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/subsys/312-mac80211-split-beacon-retrieval-functions.patch
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2022-01-28 14:13:58 +0100
committerFelix Fietkau <nbd@nbd.name>2022-02-03 15:16:47 +0100
commit03ea0405a6db0e5144d486a682e97a0be47a47c1 (patch)
tree892588d04993da9fa9c5d40859ff9ac3644f0c39 /package/kernel/mac80211/patches/subsys/312-mac80211-split-beacon-retrieval-functions.patch
parent543ada64edb88ff68328bcde5418eac7afcc3634 (diff)
downloadupstream-03ea0405a6db0e5144d486a682e97a0be47a47c1.tar.gz
upstream-03ea0405a6db0e5144d486a682e97a0be47a47c1.tar.bz2
upstream-03ea0405a6db0e5144d486a682e97a0be47a47c1.zip
mac80211: backport MBSSID/EMA support patches
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'package/kernel/mac80211/patches/subsys/312-mac80211-split-beacon-retrieval-functions.patch')
-rw-r--r--package/kernel/mac80211/patches/subsys/312-mac80211-split-beacon-retrieval-functions.patch262
1 files changed, 262 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/subsys/312-mac80211-split-beacon-retrieval-functions.patch b/package/kernel/mac80211/patches/subsys/312-mac80211-split-beacon-retrieval-functions.patch
new file mode 100644
index 0000000000..18b1951f6e
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/312-mac80211-split-beacon-retrieval-functions.patch
@@ -0,0 +1,262 @@
+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;