| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- From: Aloka Dixit <[email protected]>
- 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 <[email protected]>
- Link: https://lore.kernel.org/r/[email protected]
- Signed-off-by: Johannes Berg <[email protected]>
- ---
- --- a/net/mac80211/tx.c
- +++ b/net/mac80211/tx.c
- @@ -4988,6 +4988,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,
- @@ -4997,12 +5106,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();
-
- @@ -5019,48 +5124,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;
- @@ -5086,6 +5154,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;
-
- @@ -5125,51 +5196,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;
|