mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-04 06:54:27 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			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;
 |