From 03ea0405a6db0e5144d486a682e97a0be47a47c1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 28 Jan 2022 14:13:58 +0100 Subject: mac80211: backport MBSSID/EMA support patches Signed-off-by: Felix Fietkau --- ...mac80211-split-beacon-retrieval-functions.patch | 262 +++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 package/kernel/mac80211/patches/subsys/312-mac80211-split-beacon-retrieval-functions.patch (limited to 'package/kernel/mac80211/patches/subsys/312-mac80211-split-beacon-retrieval-functions.patch') 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 +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 +Link: https://lore.kernel.org/r/20211006040938.9531-2-alokad@codeaurora.org +Signed-off-by: Johannes Berg +--- + +--- 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; -- cgit v1.2.3