Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp533541pxa; Wed, 12 Aug 2020 08:02:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwgr+Dy8reRPhVkr40p1uDzeYUy/+m39wUMLpbP0OkuXamCnE2HohBIOyH+TSuGts+a2C/l X-Received: by 2002:a17:906:80d3:: with SMTP id a19mr176825ejx.217.1597244526759; Wed, 12 Aug 2020 08:02:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597244526; cv=none; d=google.com; s=arc-20160816; b=TnIYf/3FROQoYWWVVHnyCXcNkPYOkapRQqZPWR7ffUEsucMob1jMbDxiVrntrYbROU AE/EAsXuyDtx4M4UlVHTCKIFCHP4Ukbb5HUT2X/J0qkiAilXYhR+D5ccPw2Ot49vbzX2 YSwzB6rUG0EDWQE1Sgucp350zBAxD6ODrpsaMkxCbFi2k+dfWvFrzEp9ORWdgxdt85GR oIdDAbHvHdaNMdJg+YIr2UDluIeb8TiIvz2+gPCd3kv8Ziwgyp+slfTse5vMEkzdQZIt GkgNhKl6oiBcEH02+fOewtX57bnY26o4fVPgs6XkR2jOsIsDt2hgFk6NH0ziBGLvUK7L CrdA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=wtMYiWhDmUT4+AbOYJ+tZgCVGj5JM6GHW8CYgUkrAN8=; b=KSNkrJiFAqMWHho4fQR0+bSI4qTDDe6UE6D3K2mRcdpcMctNlYoblkwNLrMNnspXOY KIzte1b8hsjAapCQuOW5WXq+d8vztDZYO5nPcjau3VZ1IVoyb9HyD+OKmJ0m7fRI6OrD MkpxgWjuG151eIMXjJaV76O+1bR9xWfeLyhtaqHeOxbNU/JEaiWhXsjUShn3EZAcg33V ReqQZNiuax/Ql7r1r35hS92EgcVOzEsG9AREDz91dIHqhyis/cpTYRDZ2+dWcU1r2sdT MOs94yp4kc1uLvsN6yFbzZ6qNMpmuUhk2d73Dcc94Fp1cquno6kIoYbYEU0DXg32riIg zKyQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k7si1150433ejx.93.2020.08.12.08.01.38; Wed, 12 Aug 2020 08:02:06 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726651AbgHLPBK (ORCPT + 99 others); Wed, 12 Aug 2020 11:01:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51346 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726531AbgHLPBA (ORCPT ); Wed, 12 Aug 2020 11:01:00 -0400 Received: from nbd.name (nbd.name [IPv6:2a01:4f8:221:3d45::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42921C061383 for ; Wed, 12 Aug 2020 08:01:00 -0700 (PDT) Received: from [149.224.82.90] (helo=localhost.localdomain) by ds12 with esmtpa (Exim 4.89) (envelope-from ) id 1k5sFN-0002OP-SK; Wed, 12 Aug 2020 17:00:57 +0200 From: John Crispin To: Johannes Berg Cc: linux-wireless@vger.kernel.org, ath11k@lists.infradead.org, John Crispin Subject: [PATCH V3 4/9] mac80211: add multiple bssid/ema support to bcn templating Date: Wed, 12 Aug 2020 17:00:45 +0200 Message-Id: <20200812150050.2683396-5-john@phrozen.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200812150050.2683396-1-john@phrozen.org> References: <20200812150050.2683396-1-john@phrozen.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Extend ieee80211_beacon_get_template() to allow generation of EMA beacons. Drivers for hardware that does not support ema offloading can use this function to update their becaons after they receive beacon completion events from the hardware. Signed-off-by: John Crispin --- include/net/mac80211.h | 27 +++++++++++++++++++++ net/mac80211/ieee80211_i.h | 1 + net/mac80211/tx.c | 49 ++++++++++++++++++++++++++++++++++---- 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index a2145092697f..5b2fa0b3b34c 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -4792,12 +4792,17 @@ void ieee80211_report_low_ack(struct ieee80211_sta *sta, u32 num_packets); * @cntdwn_counter_offs: array of IEEE80211_MAX_CNTDWN_COUNTERS_NUM offsets * to countdown counters. This array can contain zero values which * should be ignored. + * @multiple_bssid_offset: position of the multiple bssid element + * @multiple_bssid_length: size of the multiple bssid element */ struct ieee80211_mutable_offsets { u16 tim_offset; u16 tim_length; u16 cntdwn_counter_offs[IEEE80211_MAX_CNTDWN_COUNTERS_NUM]; + + u16 multiple_bssid_offset; + u16 multiple_bssid_length; }; /** @@ -4824,6 +4829,28 @@ ieee80211_beacon_get_template(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_mutable_offsets *offs); +/** + * ieee80211_beacon_get_template - beacon template generation function + * @hw: pointer obtained from ieee80211_alloc_hw(). + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * @offs: &struct ieee80211_mutable_offsets pointer to struct that will + * receive the offsets that may be updated by the driver. + * + * This function differs from ieee80211_beacon_get_template in the sense that + * it generates EMA VAP templates. When we use multiple_bssid, the beacons can + * get very large costing a lot of airtime. To work around this, we iterate + * over the multiple bssid elements and only send one inside the beacon for 1..n. + * + * This function needs to follow the same rules as ieee80211_beacon_get_template + * + * Return: The beacon template. %NULL on error. + */ + +struct sk_buff * +ieee80211_beacon_get_template_ema(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_mutable_offsets *offs); + /** * ieee80211_beacon_get_tim - beacon generation function * @hw: pointer obtained from ieee80211_alloc_hw(). diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 016bed63e74e..33f1cf33fb54 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -269,6 +269,7 @@ struct beacon_data { u16 cntdwn_counter_offsets[IEEE80211_MAX_CNTDWN_COUNTERS_NUM]; u8 cntdwn_current_counter; struct cfg80211_multiple_bssid_data multiple_bssid; + u16 ema_index; struct rcu_head rcu_head; }; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 481dd7cc36d3..95c2593437ca 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -4735,11 +4735,26 @@ static int ieee80211_beacon_protect(struct sk_buff *skb, return 0; } +static void +ieee80211_beacon_add_multiple_bssid_config(struct ieee80211_vif *vif, struct sk_buff *skb, + struct cfg80211_multiple_bssid_data *config) +{ + u8 *pos = skb_put(skb, 6); + + *pos++ = WLAN_EID_EXTENSION; + *pos++ = 4; + *pos++ = WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION; + *pos++ = 2; + *pos++ = vif->bss_conf.multiple_bssid.count; + *pos++ = config->cnt; +} + static struct sk_buff * __ieee80211_beacon_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_mutable_offsets *offs, - bool is_template) + bool is_template, + bool is_ema) { struct ieee80211_local *local = hw_to_local(hw); struct beacon_data *beacon = NULL; @@ -4767,6 +4782,8 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw, beacon = rcu_dereference(ap->beacon); if (beacon) { + int ema_len = 0; + if (beacon->cntdwn_counter_offsets[0]) { if (!is_template) ieee80211_beacon_update_cntdwn(vif); @@ -4774,6 +4791,9 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw, ieee80211_set_beacon_cntdwn(sdata, beacon); } + if (is_ema && beacon->multiple_bssid.cnt) + ema_len = beacon->multiple_bssid.len[beacon->ema_index]; + /* * headroom, head length, * tail length and maximum TIM length @@ -4781,7 +4801,8 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw, skb = dev_alloc_skb(local->tx_headroom + beacon->head_len + beacon->tail_len + 256 + - local->hw.extra_beacon_tailroom); + local->hw.extra_beacon_tailroom + + ema_len); if (!skb) goto out; @@ -4800,6 +4821,17 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw, csa_off_base = skb->len; } + if (ema_len) { + ieee80211_beacon_add_multiple_bssid_config(vif, skb, + &beacon->multiple_bssid); + skb_put_data(skb, beacon->multiple_bssid.ies[beacon->ema_index], + beacon->multiple_bssid.len[beacon->ema_index]); + if (offs) + offs->multiple_bssid_offset = skb->len - ema_len; + beacon->ema_index++; + beacon->ema_index %= beacon->multiple_bssid.cnt; + } + if (beacon->tail) skb_put_data(skb, beacon->tail, beacon->tail_len); @@ -4928,16 +4960,25 @@ ieee80211_beacon_get_template(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_mutable_offsets *offs) { - return __ieee80211_beacon_get(hw, vif, offs, true); + return __ieee80211_beacon_get(hw, vif, offs, true, false); } EXPORT_SYMBOL(ieee80211_beacon_get_template); +struct sk_buff * +ieee80211_beacon_get_template_ema(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_mutable_offsets *offs) +{ + return __ieee80211_beacon_get(hw, vif, offs, true, true); +} +EXPORT_SYMBOL(ieee80211_beacon_get_template_ema); + struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 *tim_offset, u16 *tim_length) { struct ieee80211_mutable_offsets offs = {}; - struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false); + struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false, false); struct sk_buff *copy; struct ieee80211_supported_band *sband; int shift; -- 2.25.1