Linux-Wireless Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH V2 01/10] nl80211: add basic multiple bssid support
@ 2020-07-06 11:52 John Crispin
  2020-07-06 11:52 ` [PATCH V2 02/10] nl80211: add attributes for multiple bssid related settings John Crispin
                   ` (11 more replies)
  0 siblings, 12 replies; 19+ messages in thread
From: John Crispin @ 2020-07-06 11:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, ath11k, John Crispin

This patch adds support for passing the multiple bssid config to the
kernel when adding an interface. A bss can be legacy, transmitting or
non-transmitting. A non-transmitting BSSID will have a parent interface,
which needs to be transmitting.

Signed-off-by: John Crispin <john@phrozen.org>
---
 include/net/cfg80211.h       |  9 +++++++++
 include/uapi/linux/nl80211.h | 25 +++++++++++++++++++++++++
 net/wireless/nl80211.c       | 14 ++++++++++++++
 3 files changed, 48 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index fc7e8807838d..ba8f3c8df0ca 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -604,6 +604,8 @@ struct vif_params {
 	u8 macaddr[ETH_ALEN];
 	const u8 *vht_mumimo_groups;
 	const u8 *vht_mumimo_follow_addr;
+	enum nl80211_multi_bssid_mode multi_bssid_mode;
+	u32 multi_bssid_parent;
 };
 
 /**
@@ -5109,6 +5111,9 @@ struct cfg80211_cqm_config;
  * @pmsr_free_wk: (private) peer measurements cleanup work
  * @unprot_beacon_reported: (private) timestamp of last
  *	unprotected beacon report
+ * @multi_bssid_mode: Is this a legacy, transmitted or non-transmitted bssid
+ * @multi_bssid_parent: a non-transmitted bssid has a transmitted parent
+ * @multi_bssid_list: linked list for tracking parent - child relations.
  */
 struct wireless_dev {
 	struct wiphy *wiphy;
@@ -5188,6 +5193,10 @@ struct wireless_dev {
 	struct work_struct pmsr_free_wk;
 
 	unsigned long unprot_beacon_reported;
+
+	enum nl80211_multi_bssid_mode multi_bssid_mode;
+	struct wireless_dev *multi_bssid_parent;
+	struct list_head multi_bssid_list;
 };
 
 static inline u8 *wdev_address(struct wireless_dev *wdev)
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 4e6339ab1fce..b7a5d1de7aff 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2505,6 +2505,12 @@ enum nl80211_commands {
  * @NL80211_ATTR_HE_6GHZ_CAPABILITY: HE 6 GHz Band Capability element (from
  *	association request when used with NL80211_CMD_NEW_STATION).
  *
+ * @NL80211_ATTR_MULTI_BSSID_MODE: Set the (Non-)Transmitted flag for this
+ *	BSSIDs beacon.
+ *
+ * @NL80211_ATTR_MULTI_BSSID_PARENT: If this is a Non-Transmitted BSSID, define
+ *	the parent interface.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2987,6 +2993,9 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_HE_6GHZ_CAPABILITY,
 
+	NL80211_ATTR_MULTI_BSSID_MODE,
+	NL80211_ATTR_MULTI_BSSID_PARENT,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -6769,6 +6778,22 @@ enum nl80211_peer_measurement_ftm_failure_reasons {
 	NL80211_PMSR_FTM_FAILURE_BAD_CHANGED_PARAMS,
 };
 
+/**
+ * enum nl80211_multi_bssid_mode - Multiple BSSID beacon type
+ *
+ * Used by cfg80211_ap_settings
+ *
+ * @MULTIPLE_BSSID_LEGACY: This BSS is not part of a multiple BSSID group
+ * @MULTIPLE_BSSID_TRANSMITTED: This BSS is broadcasting a multiple BSSID
+ *                                    beacon
+ * @MULTIPLE_BSSID_NON_TRANSMITTED: This BSS is not broadcasting a beacon
+ */
+enum nl80211_multi_bssid_mode {
+	NL80211_MULTIPLE_BSSID_LEGACY = 0,
+	NL80211_MULTIPLE_BSSID_TRANSMITTED,
+	NL80211_MULTIPLE_BSSID_NON_TRANSMITTED,
+};
+
 /**
  * enum nl80211_peer_measurement_ftm_resp - FTM response attributes
  * @__NL80211_PMSR_FTM_RESP_ATTR_INVALID: invalid
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 263ae395ad44..e29f834f8d12 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -658,6 +658,10 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 		.type = NLA_EXACT_LEN,
 		.len = sizeof(struct ieee80211_he_6ghz_capa),
 	},
+	[NL80211_ATTR_MULTI_BSSID_MODE] = NLA_POLICY_RANGE(NLA_U8,
+					NL80211_MULTIPLE_BSSID_LEGACY,
+					NL80211_MULTIPLE_BSSID_NON_TRANSMITTED),
+	[NL80211_ATTR_MULTI_BSSID_PARENT] = { .type = NLA_U32 },
 };
 
 /* policy for the key attributes */
@@ -3761,6 +3765,16 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
 	if (err < 0)
 		return err;
 
+	if (info->attrs[NL80211_ATTR_MULTI_BSSID_MODE])
+		params.multi_bssid_mode =
+			nla_get_u8(info->attrs[NL80211_ATTR_MULTI_BSSID_MODE]);
+	if (info->attrs[NL80211_ATTR_MULTI_BSSID_PARENT])
+		params.multi_bssid_parent =
+			nla_get_u8(info->attrs[NL80211_ATTR_MULTI_BSSID_PARENT]);
+	if (params.multi_bssid_mode == NL80211_MULTIPLE_BSSID_NON_TRANSMITTED &&
+	    !params.multi_bssid_parent)
+		return -EOPNOTSUPP;
+
 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 	if (!msg)
 		return -ENOMEM;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH V2 02/10] nl80211: add attributes for multiple bssid related settings
  2020-07-06 11:52 [PATCH V2 01/10] nl80211: add basic multiple bssid support John Crispin
@ 2020-07-06 11:52 ` John Crispin
  2020-07-30 12:57   ` Johannes Berg
  2020-07-06 11:52 ` [PATCH V2 03/10] mac80211: add multiple bssid support John Crispin
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: John Crispin @ 2020-07-06 11:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, ath11k, John Crispin

When we start a multiple bssid AP we need to pass the index and number of
peers to the kernel. This info needs to be propagated to the driver.

Signed-off-by: John Crispin <john@phrozen.org>
---
 include/net/cfg80211.h       | 12 ++++++++++++
 include/uapi/linux/nl80211.h |  7 +++++++
 net/wireless/nl80211.c       | 15 +++++++++++++++
 3 files changed, 34 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ba8f3c8df0ca..ba0d25f95cf9 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -453,6 +453,17 @@ struct ieee80211_supported_band {
 	const struct ieee80211_sband_iftype_data *iftype_data;
 };
 
+/**
+ * struct ieee80211_multi_bssid - AP settings for multi bssid
+ *
+ * @index: the index of this AP in the multi bssid group.
+ * @count: the total number of multi bssid peer APs.
+ */
+struct ieee80211_multi_bssid {
+	u32 index;
+	u32 count;
+};
+
 /**
  * ieee80211_get_sband_iftype_data - return sband data for a given iftype
  * @sband: the sband to search for the STA on
@@ -1126,6 +1137,7 @@ struct cfg80211_ap_settings {
 	u32 flags;
 	struct ieee80211_he_obss_pd he_obss_pd;
 	struct cfg80211_he_bss_color he_bss_color;
+	struct ieee80211_multi_bssid multi_bssid;
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index b7a5d1de7aff..45b88f1221b0 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2511,6 +2511,11 @@ enum nl80211_commands {
  * @NL80211_ATTR_MULTI_BSSID_PARENT: If this is a Non-Transmitted BSSID, define
  *	the parent interface.
  *
+ * @NL80211_ATTR_MULTI_BSSID_INDEX: The index of this BSS inside the multi bssid
+ *	IE.
+ *
+ * @NL80211_ATTR_MULTI_BSSID_COUNT: The number of BSSs inside the multi bssid IE.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2995,6 +3000,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_MULTI_BSSID_MODE,
 	NL80211_ATTR_MULTI_BSSID_PARENT,
+	NL80211_ATTR_MULTI_BSSID_INDEX,
+	NL80211_ATTR_MULTI_BSSID_COUNT,
 
 	/* add attributes here, update the policy in nl80211.c */
 
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e29f834f8d12..e1696a4c965b 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -662,6 +662,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 					NL80211_MULTIPLE_BSSID_LEGACY,
 					NL80211_MULTIPLE_BSSID_NON_TRANSMITTED),
 	[NL80211_ATTR_MULTI_BSSID_PARENT] = { .type = NLA_U32 },
+	[NL80211_ATTR_MULTI_BSSID_INDEX] = { .type = NLA_U32 },
+	[NL80211_ATTR_MULTI_BSSID_COUNT] = { .type = NLA_U32 },
 };
 
 /* policy for the key attributes */
@@ -4885,6 +4887,11 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
 	    !info->attrs[NL80211_ATTR_BEACON_HEAD])
 		return -EINVAL;
 
+	if (wdev->multi_bssid_mode == NL80211_MULTIPLE_BSSID_NON_TRANSMITTED &&
+	    (!info->attrs[NL80211_ATTR_MULTI_BSSID_INDEX] ||
+	     !info->attrs[NL80211_ATTR_MULTI_BSSID_COUNT]))
+		return -EINVAL;
+
 	err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon);
 	if (err)
 		return err;
@@ -5041,6 +5048,14 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
 			return err;
 	}
 
+	if (info->attrs[NL80211_ATTR_MULTI_BSSID_INDEX])
+		params.multi_bssid.index = nla_get_u32(
+				info->attrs[NL80211_ATTR_MULTI_BSSID_INDEX]);
+
+	if (info->attrs[NL80211_ATTR_MULTI_BSSID_COUNT])
+		params.multi_bssid.count = nla_get_u32(
+				info->attrs[NL80211_ATTR_MULTI_BSSID_COUNT]);
+
 	nl80211_calculate_ap_params(&params);
 
 	if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH V2 03/10] mac80211: add multiple bssid support
  2020-07-06 11:52 [PATCH V2 01/10] nl80211: add basic multiple bssid support John Crispin
  2020-07-06 11:52 ` [PATCH V2 02/10] nl80211: add attributes for multiple bssid related settings John Crispin
@ 2020-07-06 11:52 ` John Crispin
  2020-07-30 13:03   ` Johannes Berg
  2020-07-06 11:52 ` [PATCH V2 04/10] mac80211: add multiple bssid IE parsing John Crispin
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: John Crispin @ 2020-07-06 11:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, ath11k, John Crispin

When bringing up multi bssid APs we need to track the parent-child relation
of non-transmitting and transmitting VAPs.

The patch warns when
* a parent is deleted while it has children
* a parent is opened before all children are opened
* a child is closed when its parent is open

This patch checks the above by using a linked list to track the relations.

Signed-off-by: John Crispin <john@phrozen.org>
---
 include/net/mac80211.h | 20 +++++++++++++
 net/mac80211/cfg.c     | 68 ++++++++++++++++++++++++++++++++++++++++++
 net/mac80211/iface.c   | 19 ++++++++++++
 net/mac80211/util.c    | 27 +++++++++++++++++
 4 files changed, 134 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 11d5610d2ad5..3617a2742c4d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -6558,4 +6558,24 @@ u32 ieee80211_calc_tx_airtime(struct ieee80211_hw *hw,
  */
 bool ieee80211_set_hw_80211_encap(struct ieee80211_vif *vif, bool enable);
 
+/**
+ * ieee80211_get_multi_bssid_mode - get a vifs multi bssid mode.
+ *
+ * This function is used to help look up the multi bssid mode which is tracked
+ * inside the wdev.
+ *
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ */
+enum nl80211_multi_bssid_mode ieee80211_get_multi_bssid_mode(struct ieee80211_vif *vif);
+
+/**
+ * ieee80211_get_multi_bssid_parent - get a vifs multi bssid parent.
+ *
+ * This function is used to help look up the multi bssid parent which is tracked
+ * inside the wdev.
+ *
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ */
+struct ieee80211_vif *ieee80211_get_multi_bssid_parent(struct ieee80211_vif *vif);
+
 #endif /* MAC80211_H */
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 9b360544ad6f..d315120799c0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -111,6 +111,42 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,
 	return 0;
 }
 
+static int ieee80211_set_multi_bssid_options(struct ieee80211_sub_if_data *sdata,
+					     struct vif_params *params)
+{
+	struct ieee80211_local *local = sdata->local;
+	struct wiphy *wiphy = local->hw.wiphy;
+	struct net_device *parent;
+
+	if (params->multi_bssid_mode &&
+	    !ieee80211_hw_check(&local->hw, SUPPORTS_MULTI_BSSID))
+		return -ENOTSUPP;
+
+	switch (params->multi_bssid_mode) {
+	case NL80211_MULTIPLE_BSSID_NON_TRANSMITTED:
+		parent = __dev_get_by_index(wiphy_net(wiphy),
+					    params->multi_bssid_parent);
+		if (!parent || !parent->ieee80211_ptr ||
+		    parent->ieee80211_ptr->multi_bssid_mode !=
+					NL80211_MULTIPLE_BSSID_TRANSMITTED)
+			return -EINVAL;
+		sdata->wdev.multi_bssid_parent = parent->ieee80211_ptr;
+		list_add(&sdata->wdev.multi_bssid_list,
+			 &parent->ieee80211_ptr->multi_bssid_list);
+		break;
+
+	case NL80211_MULTIPLE_BSSID_TRANSMITTED:
+		INIT_LIST_HEAD(&sdata->wdev.multi_bssid_list);
+		break;
+
+	default:
+		break;
+	}
+	sdata->wdev.multi_bssid_mode = params->multi_bssid_mode;
+
+	return 0;
+}
+
 static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy,
 						const char *name,
 						unsigned char name_assign_type,
@@ -136,11 +172,43 @@ static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy,
 		}
 	}
 
+	if (type == NL80211_IFTYPE_AP) {
+		err = ieee80211_set_multi_bssid_options(sdata, params);
+		if (err) {
+			ieee80211_if_remove(sdata);
+			return NULL;
+		}
+	}
+
 	return wdev;
 }
 
 static int ieee80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
 {
+	struct ieee80211_sub_if_data *sdata;
+	struct wireless_dev *child, *tmp;
+
+	sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+	switch (sdata->wdev.multi_bssid_mode) {
+	case NL80211_MULTIPLE_BSSID_TRANSMITTED:
+		if (list_empty(&sdata->wdev.multi_bssid_list))
+			break;
+		sdata_info(sdata, "deleting while non-transmitting children still exist\n");
+		list_for_each_entry_safe(child, tmp, &sdata->wdev.multi_bssid_list,
+					 multi_bssid_list) {
+			list_del(&child->multi_bssid_list);
+			child->multi_bssid_parent = NULL;
+		}
+		break;
+
+	case NL80211_MULTIPLE_BSSID_NON_TRANSMITTED:
+		list_del(&sdata->wdev.multi_bssid_list);
+		break;
+
+	default:
+		break;
+	}
+
 	ieee80211_if_remove(IEEE80211_WDEV_TO_SUB_IF(wdev));
 
 	return 0;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index f900c84fb40f..777b530e38d0 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -535,6 +535,18 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 		}
 	case NL80211_IFTYPE_AP:
 		sdata->bss = &sdata->u.ap;
+		if (wdev->multi_bssid_mode == NL80211_MULTIPLE_BSSID_TRANSMITTED) {
+			struct wireless_dev *child;
+			int children_down = 0;
+
+			/* check if all children are already up */
+			list_for_each_entry(child, &wdev->multi_bssid_list,
+					    multi_bssid_list)
+				if (!wdev_running(child))
+					children_down = 1;
+			if (children_down)
+				sdata_info(sdata, "non-transmitting children are not up yet\n");
+		}
 		break;
 	case NL80211_IFTYPE_MESH_POINT:
 	case NL80211_IFTYPE_STATION:
@@ -800,6 +812,7 @@ static int ieee80211_open(struct net_device *dev)
 static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 			      bool going_down)
 {
+	struct wireless_dev *wdev = ieee80211_vif_to_wdev(&sdata->vif);
 	struct ieee80211_local *local = sdata->local;
 	unsigned long flags;
 	struct sk_buff *skb, *tmp;
@@ -810,6 +823,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 	bool cancel_scan;
 	struct cfg80211_nan_func *func;
 
+	if (sdata->vif.type == NL80211_IFTYPE_AP &&
+	    wdev->multi_bssid_mode == NL80211_MULTIPLE_BSSID_NON_TRANSMITTED)
+		/* make sure the parent is already down */
+		if (wdev->multi_bssid_parent && wdev_running(wdev->multi_bssid_parent))
+			sdata_info(sdata, "transmitting parent is still up\n");
+
 	clear_bit(SDATA_STATE_RUNNING, &sdata->state);
 
 	cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 21c94094a699..3e4308c8f690 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -847,6 +847,33 @@ struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif)
 }
 EXPORT_SYMBOL_GPL(ieee80211_vif_to_wdev);
 
+enum nl80211_multi_bssid_mode ieee80211_get_multi_bssid_mode(struct ieee80211_vif *vif)
+{
+	struct ieee80211_sub_if_data *sdata;
+
+	if (!vif)
+		return 0;
+
+	sdata = vif_to_sdata(vif);
+
+	return sdata->wdev.multi_bssid_mode;
+}
+EXPORT_SYMBOL_GPL(ieee80211_get_multi_bssid_mode);
+
+struct ieee80211_vif *ieee80211_get_multi_bssid_parent(struct ieee80211_vif *vif)
+{
+	struct ieee80211_sub_if_data *sdata;
+
+	if (!vif)
+		return NULL;
+
+	sdata = vif_to_sdata(vif);
+	if (sdata->wdev.multi_bssid_parent)
+		return wdev_to_ieee80211_vif(sdata->wdev.multi_bssid_parent);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(ieee80211_get_multi_bssid_parent);
+
 /*
  * Nothing should have been stuffed into the workqueue during
  * the suspend->resume cycle. Since we can't check each caller
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH V2 04/10] mac80211: add multiple bssid IE parsing
  2020-07-06 11:52 [PATCH V2 01/10] nl80211: add basic multiple bssid support John Crispin
  2020-07-06 11:52 ` [PATCH V2 02/10] nl80211: add attributes for multiple bssid related settings John Crispin
  2020-07-06 11:52 ` [PATCH V2 03/10] mac80211: add multiple bssid support John Crispin
@ 2020-07-06 11:52 ` John Crispin
  2020-07-30 13:05   ` Johannes Berg
  2020-07-06 11:52 ` [PATCH V2 05/10] mac80211: propagate multi bssid settings when starting John Crispin
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: John Crispin @ 2020-07-06 11:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, ath11k, John Crispin

Drivers might need to know the offset and length of the IE. Add parsing
code and propagate the values to the driver using the mutable struct.

Signed-off-by: John Crispin <john@phrozen.org>
---
 include/net/mac80211.h     |  5 +++++
 net/mac80211/ieee80211_i.h |  2 ++
 net/mac80211/tx.c          | 10 ++++++++++
 net/mac80211/util.c        |  4 ++++
 4 files changed, 21 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 3617a2742c4d..67729b8fcdb2 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -4744,12 +4744,17 @@ void ieee80211_report_low_ack(struct ieee80211_sta *sta, u32 num_packets);
  * @csa_counter_offs: array of IEEE80211_MAX_CSA_COUNTERS_NUM offsets
  *	to CSA counters.  This array can contain zero values which
  *	should be ignored.
+ * @mbssid_offset: position of mbssid_offset
+ * @mbssid_length: position of mbssid_offset
  */
 struct ieee80211_mutable_offsets {
 	u16 tim_offset;
 	u16 tim_length;
 
 	u16 csa_counter_offs[IEEE80211_MAX_CSA_COUNTERS_NUM];
+
+	u16 multiple_bssid_offset;
+	u16 multiple_bssid_length;
 };
 
 /**
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ec1a71ac65f2..e1cae41a2ea4 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1523,6 +1523,7 @@ struct ieee802_11_elems {
 	u8 dtim_count;
 	u8 dtim_period;
 	const struct ieee80211_addba_ext_ie *addba_ext_ie;
+	u16 multiple_bssid_offset;
 
 	/* length of them, respectively */
 	u8 ext_capab_len;
@@ -1543,6 +1544,7 @@ struct ieee802_11_elems {
 	u8 perr_len;
 	u8 country_elem_len;
 	u8 bssid_index_len;
+	u8 multiple_bssid_len;
 
 	/* whether a parse error occurred while retrieving these elements */
 	bool parse_error;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e9ce658141f5..1e7a71d6853d 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4785,11 +4785,21 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
 						 is_template);
 
 			if (offs) {
+				struct ieee802_11_elems elems;
+
 				offs->tim_offset = beacon->head_len;
 				offs->tim_length = skb->len - beacon->head_len;
 
 				/* for AP the csa offsets are from tail */
 				csa_off_base = skb->len;
+
+				ieee802_11_parse_elems(skb->head, skb->len, true, &elems,
+						       sdata->wdev.address, NULL);
+				if (!elems.parse_error)
+					goto out;
+
+				offs->multiple_bssid_offset = elems.multiple_bssid_offset;
+				offs->multiple_bssid_length = elems.multiple_bssid_len;
 			}
 
 			if (beacon->tail)
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 3e4308c8f690..af6d685cea63 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1315,6 +1315,10 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
 								&crc : NULL,
 							  elem, elems);
 			break;
+		case WLAN_EID_MULTIPLE_BSSID:
+			elems->multiple_bssid_offset = pos - start;
+			elems->multiple_bssid_len = elen;
+			break;
 		default:
 			break;
 		}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH V2 05/10] mac80211: propagate multi bssid settings when starting
  2020-07-06 11:52 [PATCH V2 01/10] nl80211: add basic multiple bssid support John Crispin
                   ` (2 preceding siblings ...)
  2020-07-06 11:52 ` [PATCH V2 04/10] mac80211: add multiple bssid IE parsing John Crispin
@ 2020-07-06 11:52 ` John Crispin
  2020-07-30 13:06   ` Johannes Berg
  2020-07-06 11:52 ` [PATCH V2 06/10] ath11k: pass multiple bssid info to FW when a new vdev is created John Crispin
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: John Crispin @ 2020-07-06 11:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, ath11k, John Crispin

This patch extends the bss_config allowing us to propagate the multiple
bssid setting down the stack into the driver.

Signed-off-by: John Crispin <john@phrozen.org>
---
 include/net/mac80211.h | 2 ++
 net/mac80211/cfg.c     | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 67729b8fcdb2..d7dce78e261e 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -607,6 +607,7 @@ struct ieee80211_ftm_responder_params {
  * @he_oper: HE operation information of the AP we are connected to
  * @he_obss_pd: OBSS Packet Detection parameters.
  * @he_bss_color: BSS coloring settings, if BSS supports HE
+ * @multi_bssid: the multi bssid settings of the AP.
  */
 struct ieee80211_bss_conf {
 	const u8 *bssid;
@@ -674,6 +675,7 @@ struct ieee80211_bss_conf {
 	} he_oper;
 	struct ieee80211_he_obss_pd he_obss_pd;
 	struct cfg80211_he_bss_color he_bss_color;
+	struct ieee80211_multi_bssid multi_bssid;
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index d315120799c0..e4b1ac89b1c0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1137,6 +1137,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
 	       sizeof(struct ieee80211_he_obss_pd));
 	memcpy(&sdata->vif.bss_conf.he_bss_color, &params->he_bss_color,
 	       sizeof(struct ieee80211_he_bss_color));
+	memcpy(&sdata->vif.bss_conf.multi_bssid, &params->multi_bssid,
+	       sizeof(struct ieee80211_multi_bssid));
 
 	sdata->vif.bss_conf.ssid_len = params->ssid_len;
 	if (params->ssid_len)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH V2 06/10] ath11k: pass multiple bssid info to FW when a new vdev is created
  2020-07-06 11:52 [PATCH V2 01/10] nl80211: add basic multiple bssid support John Crispin
                   ` (3 preceding siblings ...)
  2020-07-06 11:52 ` [PATCH V2 05/10] mac80211: propagate multi bssid settings when starting John Crispin
@ 2020-07-06 11:52 ` John Crispin
  2020-08-02 15:02   ` Shay Bar
  2020-07-06 11:52 ` [PATCH V2 07/10] ath11k: add a struct to pass parameters into ath11k_wmi_vdev_up John Crispin
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: John Crispin @ 2020-07-06 11:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, ath11k, John Crispin

When we use multiple bssid the FW needs to know if the bssid is
non/transmitting and what the vdev_id of the parent is. This patch adds
the required code to achieve this.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/wireless/ath/ath11k/mac.c | 28 +++++++++++++++++++++++++--
 drivers/net/wireless/ath/ath11k/wmi.c |  2 ++
 drivers/net/wireless/ath/ath11k/wmi.h | 10 ++++++++++
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 2836a0f197ab..498f9a15d0e4 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -4065,17 +4065,36 @@ static void ath11k_mac_op_stop(struct ieee80211_hw *hw)
 	atomic_set(&ar->num_pending_mgmt_tx, 0);
 }
 
-static void
+static int
 ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,
 				    struct vdev_create_params *params)
 {
 	struct ath11k *ar = arvif->ar;
 	struct ath11k_pdev *pdev = ar->pdev;
+	struct ieee80211_vif *parent;
 
 	params->if_id = arvif->vdev_id;
 	params->type = arvif->vdev_type;
 	params->subtype = arvif->vdev_subtype;
 	params->pdev_id = pdev->pdev_id;
+	params->vdevid_trans = 0;
+	switch (ieee80211_get_multi_bssid_mode(arvif->vif)) {
+	case NL80211_MULTIPLE_BSSID_TRANSMITTED:
+		params->flags = WMI_HOST_VDEV_FLAGS_TRANSMIT_AP;
+		break;
+	case NL80211_MULTIPLE_BSSID_NON_TRANSMITTED:
+		params->flags = WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP;
+		parent = ieee80211_get_multi_bssid_parent(arvif->vif);
+		if (!parent)
+			return -ENOENT;
+		if (ar->hw->wiphy != ieee80211_vif_to_wdev(parent)->wiphy)
+			return -EINVAL;
+		params->vdevid_trans = ath11k_vif_to_arvif(parent)->vdev_id;
+		break;
+	default:
+		params->flags = WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP;
+		break;
+	}
 
 	if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) {
 		params->chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains;
@@ -4085,6 +4104,7 @@ ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,
 		params->chains[NL80211_BAND_5GHZ].tx = ar->num_tx_chains;
 		params->chains[NL80211_BAND_5GHZ].rx = ar->num_rx_chains;
 	}
+	return 0;
 }
 
 static u32
@@ -4234,7 +4254,11 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
 	for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
 		vif->hw_queue[i] = i % (ATH11K_HW_MAX_QUEUES - 1);
 
-	ath11k_mac_setup_vdev_create_params(arvif, &vdev_param);
+	ret = ath11k_mac_setup_vdev_create_params(arvif, &vdev_param);
+	if (ret) {
+		ath11k_warn(ab, "failed to prepare vdev %d\n", ret);
+		goto err;
+	}
 
 	ret = ath11k_wmi_vdev_create(ar, vif->addr, &vdev_param);
 	if (ret) {
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index c2a972377687..90c68d1d9087 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -603,6 +603,8 @@ int ath11k_wmi_vdev_create(struct ath11k *ar, u8 *macaddr,
 	cmd->vdev_subtype = param->subtype;
 	cmd->num_cfg_txrx_streams = WMI_NUM_SUPPORTED_BAND_MAX;
 	cmd->pdev_id = param->pdev_id;
+	cmd->flags = param->flags;
+	cmd->vdevid_trans = param->vdevid_trans;
 	ether_addr_copy(cmd->vdev_macaddr.addr, macaddr);
 
 	ptr = skb->data + sizeof(*cmd);
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index b9f3e559ced7..fa6665584caf 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -107,6 +107,12 @@ enum {
 	WMI_HOST_WLAN_2G_5G_CAP	= 0x3,
 };
 
+enum {
+	WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP	= 1,
+	WMI_HOST_VDEV_FLAGS_TRANSMIT_AP		= 2,
+	WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP	= 4,
+};
+
 /*
  * wmi command groups.
  */
@@ -2419,6 +2425,8 @@ struct vdev_create_params {
 		u8 rx;
 	} chains[NUM_NL80211_BANDS];
 	u32 pdev_id;
+	u32 flags;
+	u32 vdevid_trans;
 };
 
 struct wmi_vdev_create_cmd {
@@ -2429,6 +2437,8 @@ struct wmi_vdev_create_cmd {
 	struct wmi_mac_addr vdev_macaddr;
 	u32 num_cfg_txrx_streams;
 	u32 pdev_id;
+	u32 flags;
+	u32 vdevid_trans;
 } __packed;
 
 struct wmi_vdev_txrx_streams {
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH V2 07/10] ath11k: add a struct to pass parameters into ath11k_wmi_vdev_up
  2020-07-06 11:52 [PATCH V2 01/10] nl80211: add basic multiple bssid support John Crispin
                   ` (4 preceding siblings ...)
  2020-07-06 11:52 ` [PATCH V2 06/10] ath11k: pass multiple bssid info to FW when a new vdev is created John Crispin
@ 2020-07-06 11:52 ` John Crispin
  2020-07-06 11:52 ` [PATCH V2 08/10] ath11k: add the multiple bssid IE offset to the beacon template John Crispin
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: John Crispin @ 2020-07-06 11:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, ath11k, John Crispin

When setting up a multiple bssid we need to pass additional parameters to
the FW. Doing this as individual parameters would make the call signature
very long. Use an intermediate struct instead and adjust all callees to
make use of it.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/wireless/ath/ath11k/mac.c | 38 ++++++++++++++++++++++-----
 drivers/net/wireless/ath/ath11k/wmi.c | 17 +++++++-----
 drivers/net/wireless/ath/ath11k/wmi.h | 12 +++++++--
 3 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 498f9a15d0e4..65a77f6c27e1 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -657,9 +657,13 @@ void ath11k_mac_peer_cleanup_all(struct ath11k *ar)
 
 static int ath11k_monitor_vdev_up(struct ath11k *ar, int vdev_id)
 {
+	struct vdev_up_params params = {
+		.vdev_id = vdev_id,
+		.bssid = ar->mac_addr,
+	};
 	int ret = 0;
 
-	ret = ath11k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
+	ret = ath11k_wmi_vdev_up(ar, &params);
 	if (ret) {
 		ath11k_warn(ar->ab, "failed to put up monitor vdev %i: %d\n",
 			    vdev_id, ret);
@@ -724,6 +728,13 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
 				     struct ieee80211_bss_conf *info)
 {
 	struct ath11k *ar = arvif->ar;
+	struct ieee80211_vif *parent;
+	struct vdev_up_params params = {
+		.vdev_id = arvif->vdev_id,
+		.bssid = arvif->bssid,
+		.profile_num = info->multi_bssid.count,
+		.profile_idx = info->multi_bssid.index,
+	};
 	int ret = 0;
 
 	lockdep_assert_held(&arvif->ar->conf_mutex);
@@ -751,9 +762,15 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
 	arvif->aid = 0;
 
 	ether_addr_copy(arvif->bssid, info->bssid);
+	parent = ieee80211_get_multi_bssid_parent(arvif->vif);
+	if (parent) {
+		struct ath11k_vif *pvif = (struct ath11k_vif *)parent->drv_priv;
+
+		params.trans_bssid = pvif->bssid;
+	}
+
 
-	ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
-				 arvif->bssid);
+	ret = ath11k_wmi_vdev_up(arvif->ar, &params);
 	if (ret) {
 		ath11k_warn(ar->ab, "failed to bring up vdev %d: %i\n",
 			    arvif->vdev_id, ret);
@@ -1569,6 +1586,11 @@ static void ath11k_bss_assoc(struct ieee80211_hw *hw,
 	struct ath11k *ar = hw->priv;
 	struct ath11k_vif *arvif = (void *)vif->drv_priv;
 	struct peer_assoc_params peer_arg;
+	struct vdev_up_params params = {
+		.vdev_id = arvif->vdev_id,
+		.bssid = bss_conf->bssid,
+		.aid = bss_conf->aid,
+	};
 	struct ieee80211_sta *ap_sta;
 	int ret;
 
@@ -1617,7 +1639,7 @@ static void ath11k_bss_assoc(struct ieee80211_hw *hw,
 	arvif->aid = bss_conf->aid;
 	ether_addr_copy(arvif->bssid, bss_conf->bssid);
 
-	ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
+	ret = ath11k_wmi_vdev_up(ar, &params);
 	if (ret) {
 		ath11k_warn(ar->ab, "failed to set vdev %d up: %d\n",
 			    arvif->vdev_id, ret);
@@ -4895,6 +4917,8 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
 	/* TODO: Update ar->rx_channel */
 
 	for (i = 0; i < n_vifs; i++) {
+		struct vdev_up_params params;
+
 		arvif = (void *)vifs[i].vif->drv_priv;
 
 		if (WARN_ON(!arvif->is_started))
@@ -4915,8 +4939,10 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
 			continue;
 		}
 
-		ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
-					 arvif->bssid);
+		params.vdev_id = arvif->vdev_id,
+		params.bssid = arvif->bssid,
+		params.aid = arvif->aid,
+		ret = ath11k_wmi_vdev_up(arvif->ar, &params);
 		if (ret) {
 			ath11k_warn(ab, "failed to bring vdev up %d: %d\n",
 				    arvif->vdev_id, ret);
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index 90c68d1d9087..b7a4913228bc 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -862,7 +862,7 @@ int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,
 	return ret;
 }
 
-int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
+int ath11k_wmi_vdev_up(struct ath11k *ar, struct vdev_up_params *params)
 {
 	struct ath11k_pdev_wmi *wmi = ar->wmi;
 	struct wmi_vdev_up_cmd *cmd;
@@ -877,10 +877,14 @@ int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
 
 	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_UP_CMD) |
 			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
-	cmd->vdev_id = vdev_id;
-	cmd->vdev_assoc_id = aid;
+	cmd->vdev_id = params->vdev_id;
+	cmd->vdev_assoc_id = params->aid;
+	cmd->profile_idx = params->profile_idx;
+	cmd->profile_num = params->profile_num;
 
-	ether_addr_copy(cmd->vdev_bssid.addr, bssid);
+	if (params->trans_bssid)
+		ether_addr_copy(cmd->trans_bssid.addr, params->trans_bssid);
+	ether_addr_copy(cmd->vdev_bssid.addr, params->bssid);
 
 	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_UP_CMDID);
 	if (ret) {
@@ -889,8 +893,9 @@ int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
 	}
 
 	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
-		   "WMI mgmt vdev up id 0x%x assoc id %d bssid %pM\n",
-		   vdev_id, aid, bssid);
+		   "WMI mgmt vdev up id 0x%x assoc id %d idx %d num %d bssid %pM trans_bssid %pM\n",
+		   params->vdev_id, params->aid, params->profile_idx, params->profile_num,
+		   params->bssid, params->trans_bssid);
 
 	return ret;
 }
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index fa6665584caf..1a436e1885bc 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -2453,6 +2453,15 @@ struct wmi_vdev_delete_cmd {
 	u32 vdev_id;
 } __packed;
 
+struct vdev_up_params {
+	u32 vdev_id;
+	u16 aid;
+	u32 profile_idx;
+	u32 profile_num;
+	const u8 *bssid;
+	u8 *trans_bssid;
+};
+
 struct wmi_vdev_up_cmd {
 	u32 tlv_header;
 	u32 vdev_id;
@@ -4845,8 +4854,7 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
 			struct ieee80211_mutable_offsets *offs,
 			struct sk_buff *bcn);
 int ath11k_wmi_vdev_down(struct ath11k *ar, u8 vdev_id);
-int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid,
-		       const u8 *bssid);
+int ath11k_wmi_vdev_up(struct ath11k *ar, struct vdev_up_params *params);
 int ath11k_wmi_vdev_stop(struct ath11k *ar, u8 vdev_id);
 int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,
 			  bool restart);
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH V2 08/10] ath11k: add the multiple bssid IE offset to the beacon template
  2020-07-06 11:52 [PATCH V2 01/10] nl80211: add basic multiple bssid support John Crispin
                   ` (5 preceding siblings ...)
  2020-07-06 11:52 ` [PATCH V2 07/10] ath11k: add a struct to pass parameters into ath11k_wmi_vdev_up John Crispin
@ 2020-07-06 11:52 ` John Crispin
  2020-07-06 11:52 ` [PATCH V2 09/10] ath11k: set beacon tx mode John Crispin
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: John Crispin @ 2020-07-06 11:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, ath11k, John Crispin

The FW needs to know the offset of the multi bssid IE. Add this value to
the WMI TLV.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/wireless/ath/ath11k/wmi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index b7a4913228bc..0c1743caaba7 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -1567,6 +1567,7 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
 	cmd->csa_switch_count_offset = offs->csa_counter_offs[0];
 	cmd->ext_csa_switch_count_offset = offs->csa_counter_offs[1];
 	cmd->buf_len = bcn->len;
+	cmd->mbssid_ie_offset = offs->multiple_bssid_offset;
 
 	ptr = skb->data + sizeof(*cmd);
 
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH V2 09/10] ath11k: set beacon tx mode
  2020-07-06 11:52 [PATCH V2 01/10] nl80211: add basic multiple bssid support John Crispin
                   ` (6 preceding siblings ...)
  2020-07-06 11:52 ` [PATCH V2 08/10] ath11k: add the multiple bssid IE offset to the beacon template John Crispin
@ 2020-07-06 11:52 ` John Crispin
  2020-07-06 11:52 ` [PATCH V2 10/10] ath11k: set the multiple bssid hw cap John Crispin
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: John Crispin @ 2020-07-06 11:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, ath11k, John Crispin

The beacon mode needs to be set to bursting when we have multiple bssid
enabled.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/wireless/ath/ath11k/mac.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 65a77f6c27e1..a07773fd5971 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -1791,6 +1791,9 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
 	if (changed & BSS_CHANGED_BEACON) {
 		param_id = WMI_PDEV_PARAM_BEACON_TX_MODE;
 		param_value = WMI_BEACON_STAGGERED_MODE;
+		if (ieee80211_get_multi_bssid_mode(arvif->vif) !=
+		    NL80211_MULTIPLE_BSSID_LEGACY)
+			param_value = WMI_BEACON_BURST_MODE;
 		ret = ath11k_wmi_pdev_set_param(ar, param_id,
 						param_value, ar->pdev->pdev_id);
 		if (ret)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH V2 10/10] ath11k: set the multiple bssid hw cap
  2020-07-06 11:52 [PATCH V2 01/10] nl80211: add basic multiple bssid support John Crispin
                   ` (7 preceding siblings ...)
  2020-07-06 11:52 ` [PATCH V2 09/10] ath11k: set beacon tx mode John Crispin
@ 2020-07-06 11:52 ` John Crispin
  2020-07-30 12:55 ` [PATCH V2 01/10] nl80211: add basic multiple bssid support Johannes Berg
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: John Crispin @ 2020-07-06 11:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, ath11k, John Crispin

This patch sets the SUPPORTS_MULTI_BSSID inside ath11k.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/wireless/ath/ath11k/mac.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index a07773fd5971..44bfa8f470a1 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -5784,17 +5784,20 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
 
 static const u8 ath11k_if_types_ext_capa[] = {
 	[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
+	[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
 	[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
 };
 
 static const u8 ath11k_if_types_ext_capa_sta[] = {
 	[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
+	[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
 	[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
 	[9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT,
 };
 
 static const u8 ath11k_if_types_ext_capa_ap[] = {
 	[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
+	[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
 	[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
 	[9] = WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT,
 };
@@ -5905,6 +5908,7 @@ static int __ath11k_mac_register(struct ath11k *ar)
 	ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
 	ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
 	ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
+	ieee80211_hw_set(ar->hw, SUPPORTS_MULTI_BSSID);
 	if (ht_cap & WMI_HT_CAP_ENABLED) {
 		ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
 		ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 01/10] nl80211: add basic multiple bssid support
  2020-07-06 11:52 [PATCH V2 01/10] nl80211: add basic multiple bssid support John Crispin
                   ` (8 preceding siblings ...)
  2020-07-06 11:52 ` [PATCH V2 10/10] ath11k: set the multiple bssid hw cap John Crispin
@ 2020-07-30 12:55 ` Johannes Berg
  2020-07-30 12:57 ` Johannes Berg
  2020-07-30 14:37 ` Johannes Berg
  11 siblings, 0 replies; 19+ messages in thread
From: Johannes Berg @ 2020-07-30 12:55 UTC (permalink / raw)
  To: John Crispin; +Cc: linux-wireless, ath11k


> +++ b/include/net/cfg80211.h
> @@ -604,6 +604,8 @@ struct vif_params {
>  	u8 macaddr[ETH_ALEN];
>  	const u8 *vht_mumimo_groups;
>  	const u8 *vht_mumimo_follow_addr;
> +	enum nl80211_multi_bssid_mode multi_bssid_mode;
> +	u32 multi_bssid_parent;

Can you put this into a(n anonymous) sub-structure?

This also missed kernel-doc.

>   *	unprotected beacon report
> + * @multi_bssid_mode: Is this a legacy, transmitted or non-transmitted bssid
> + * @multi_bssid_parent: a non-transmitted bssid has a transmitted parent
> + * @multi_bssid_list: linked list for tracking parent - child relations.


FWIW, you can (now?) write

 * @multi_bssid.list: ...

to document data for anonymous sub-structures.

I started applying this and changed it myself, but am having second
thoughts on later patches in this series.

> + * @NL80211_ATTR_MULTI_BSSID_MODE: Set the (Non-)Transmitted flag for this
> + *	BSSIDs beacon.
> + *
> + * @NL80211_ATTR_MULTI_BSSID_PARENT: If this is a Non-Transmitted BSSID, define
> + *	the parent interface.

Maybe clarify

	the parent (transmitted BSSID) interface

or so?

> +/**
> + * enum nl80211_multi_bssid_mode - Multiple BSSID beacon type
> + *
> + * Used by cfg80211_ap_settings

That'd be weird, but it's not true, you have it for
NL80211_ATTR_MULTI_BSSID_MODE. Actually, that documentation should point
here and say the values are from this enum.

> + * @MULTIPLE_BSSID_LEGACY: This BSS is not part of a multiple BSSID group
> + * @MULTIPLE_BSSID_TRANSMITTED: This BSS is broadcasting a multiple BSSID
> + *                                    beacon

Please just use a single tab there :)

> +	[NL80211_ATTR_MULTI_BSSID_MODE] = NLA_POLICY_RANGE(NLA_U8,
> +					NL80211_MULTIPLE_BSSID_LEGACY,
> +					NL80211_MULTIPLE_BSSID_NON_TRANSMITTED),

Maybe nicer as

	[...] = 
		NLA_POLICY_RANGE(...

johannes


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 01/10] nl80211: add basic multiple bssid support
  2020-07-06 11:52 [PATCH V2 01/10] nl80211: add basic multiple bssid support John Crispin
                   ` (9 preceding siblings ...)
  2020-07-30 12:55 ` [PATCH V2 01/10] nl80211: add basic multiple bssid support Johannes Berg
@ 2020-07-30 12:57 ` Johannes Berg
  2020-07-30 14:37 ` Johannes Berg
  11 siblings, 0 replies; 19+ messages in thread
From: Johannes Berg @ 2020-07-30 12:57 UTC (permalink / raw)
  To: John Crispin; +Cc: linux-wireless, ath11k

On Mon, 2020-07-06 at 13:52 +0200, John Crispin wrote:

>  /**
> @@ -5109,6 +5111,9 @@ struct cfg80211_cqm_config;
>   * @pmsr_free_wk: (private) peer measurements cleanup work
>   * @unprot_beacon_reported: (private) timestamp of last
>   *	unprotected beacon report
> + * @multi_bssid_mode: Is this a legacy, transmitted or non-transmitted bssid
> + * @multi_bssid_parent: a non-transmitted bssid has a transmitted parent
> + * @multi_bssid_list: linked list for tracking parent - child relations.
>   */
>  struct wireless_dev {
>  	struct wiphy *wiphy;
> @@ -5188,6 +5193,10 @@ struct wireless_dev {
>  	struct work_struct pmsr_free_wk;
>  
>  	unsigned long unprot_beacon_reported;
> +
> +	enum nl80211_multi_bssid_mode multi_bssid_mode;
> +	struct wireless_dev *multi_bssid_parent;
> +	struct list_head multi_bssid_list;

Ah, I forgot - this was where I thought it'd be better to change ...
after reading the later patches.

Or let me just ask: why is that here? You're passing it down in the
params (code I removed above), and then you're effectively making it the
driver's (mac80211's) responsibility to track it.

So why should it be here? cfg80211 isn't really using this much. I saw
there's a small validation thing here, but that could also be pushed
down, and then this can live in mac80211?

Or do you have any future plans for using this in cfg80211?

johannes


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 02/10] nl80211: add attributes for multiple bssid related settings
  2020-07-06 11:52 ` [PATCH V2 02/10] nl80211: add attributes for multiple bssid related settings John Crispin
@ 2020-07-30 12:57   ` Johannes Berg
  0 siblings, 0 replies; 19+ messages in thread
From: Johannes Berg @ 2020-07-30 12:57 UTC (permalink / raw)
  To: John Crispin; +Cc: linux-wireless, ath11k

On Mon, 2020-07-06 at 13:52 +0200, John Crispin wrote:
> 
> @@ -1126,6 +1137,7 @@ struct cfg80211_ap_settings {
>  	u32 flags;
>  	struct ieee80211_he_obss_pd he_obss_pd;
>  	struct cfg80211_he_bss_color he_bss_color;
> +	struct ieee80211_multi_bssid multi_bssid;

Missing docs?

>  };
>  
>  /**
> diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
> index b7a5d1de7aff..45b88f1221b0 100644
> --- a/include/uapi/linux/nl80211.h
> +++ b/include/uapi/linux/nl80211.h
> @@ -2511,6 +2511,11 @@ enum nl80211_commands {
>   * @NL80211_ATTR_MULTI_BSSID_PARENT: If this is a Non-Transmitted BSSID, define
>   *	the parent interface.
>   *
> + * @NL80211_ATTR_MULTI_BSSID_INDEX: The index of this BSS inside the multi bssid
> + *	IE.

Element, not "IE", these days ... :)

johannes


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 03/10] mac80211: add multiple bssid support
  2020-07-06 11:52 ` [PATCH V2 03/10] mac80211: add multiple bssid support John Crispin
@ 2020-07-30 13:03   ` Johannes Berg
  0 siblings, 0 replies; 19+ messages in thread
From: Johannes Berg @ 2020-07-30 13:03 UTC (permalink / raw)
  To: John Crispin; +Cc: linux-wireless, ath11k

On Mon, 2020-07-06 at 13:52 +0200, John Crispin wrote:
> 
> +/**
> + * ieee80211_get_multi_bssid_mode - get a vifs multi bssid mode.
> + *
> + * This function is used to help look up the multi bssid mode which is tracked
> + * inside the wdev.
> + *
> + * @vif: &struct ieee80211_vif pointer from the add_interface callback.
> + */
> +enum nl80211_multi_bssid_mode ieee80211_get_multi_bssid_mode(struct ieee80211_vif *vif);
> +
> +/**
> + * ieee80211_get_multi_bssid_parent - get a vifs multi bssid parent.
> + *
> + * This function is used to help look up the multi bssid parent which is tracked
> + * inside the wdev.
> + *
> + * @vif: &struct ieee80211_vif pointer from the add_interface callback.
> + */
> +struct ieee80211_vif *ieee80211_get_multi_bssid_parent(struct ieee80211_vif *vif);

All this can be a lot simpler if you don't just push the data that I
just mentioned from the wdev down to the sdata, but actually down to the
vif. Then these are just something like

	vif->multi_bssid.parent

without a need to call a function. That'd probably result in
significantly smaller code too, since exporting a function takes quite a
bit of space.

(Also, if you insist that it must be in the wdev, you can use the
function that obtains the wdev from the vif, and dereference that -
still wouldn't require exporting a lot of new functions.)

> +	if (params->multi_bssid_mode &&
> +	    !ieee80211_hw_check(&local->hw, SUPPORTS_MULTI_BSSID))
> +		return -ENOTSUPP;

IMHO that needs to be a new, separate feature bit, probably even at
nl80211 level. This here was more of a client-side thing, and now you're
doing AP side. I don't think we can mix those (and iwlwifi surely would
have issues with that.)

>  static int ieee80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
>  {
> +	struct ieee80211_sub_if_data *sdata;
> +	struct wireless_dev *child, *tmp;
> +
> +	sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
> +	switch (sdata->wdev.multi_bssid_mode) {
> +	case NL80211_MULTIPLE_BSSID_TRANSMITTED:
> +		if (list_empty(&sdata->wdev.multi_bssid_list))
> +			break;
> +		sdata_info(sdata, "deleting while non-transmitting children still exist\n");

Is that even worth a message? I mean, you could just destroy the
children too, and document it in the API that way?

> +		list_for_each_entry_safe(child, tmp, &sdata->wdev.multi_bssid_list,
> +					 multi_bssid_list) {
> +			list_del(&child->multi_bssid_list);
> +			child->multi_bssid_parent = NULL;
> +		}

It also seems you shouldn't just NULL out the pointer but dev_close()
them so they stop operating?

>  	case NL80211_IFTYPE_AP:
>  		sdata->bss = &sdata->u.ap;
> +		if (wdev->multi_bssid_mode == NL80211_MULTIPLE_BSSID_TRANSMITTED) {
> +			struct wireless_dev *child;
> +			int children_down = 0;
> +
> +			/* check if all children are already up */
> +			list_for_each_entry(child, &wdev->multi_bssid_list,
> +					    multi_bssid_list)
> +				if (!wdev_running(child))
> +					children_down = 1;
> +			if (children_down)
> +				sdata_info(sdata, "non-transmitting children are not up yet\n");

reject it?

> @@ -800,6 +812,7 @@ static int ieee80211_open(struct net_device *dev)
>  static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
>  			      bool going_down)
>  {
> +	struct wireless_dev *wdev = ieee80211_vif_to_wdev(&sdata->vif);
>  	struct ieee80211_local *local = sdata->local;
>  	unsigned long flags;
>  	struct sk_buff *skb, *tmp;
> @@ -810,6 +823,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
>  	bool cancel_scan;
>  	struct cfg80211_nan_func *func;
>  
> +	if (sdata->vif.type == NL80211_IFTYPE_AP &&
> +	    wdev->multi_bssid_mode == NL80211_MULTIPLE_BSSID_NON_TRANSMITTED)
> +		/* make sure the parent is already down */
> +		if (wdev->multi_bssid_parent && wdev_running(wdev->multi_bssid_parent))
> +			sdata_info(sdata, "transmitting parent is still up\n");

Reject it? Or dev_close() the parent?

johannes


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 04/10] mac80211: add multiple bssid IE parsing
  2020-07-06 11:52 ` [PATCH V2 04/10] mac80211: add multiple bssid IE parsing John Crispin
@ 2020-07-30 13:05   ` Johannes Berg
  0 siblings, 0 replies; 19+ messages in thread
From: Johannes Berg @ 2020-07-30 13:05 UTC (permalink / raw)
  To: John Crispin; +Cc: linux-wireless, ath11k

On Mon, 2020-07-06 at 13:52 +0200, John Crispin wrote:
> 
> + * @mbssid_offset: position of mbssid_offset
> + * @mbssid_length: position of mbssid_offset
> 
> +
> +	u16 multiple_bssid_offset;
> +	u16 multiple_bssid_length;

that doesn't match :)


Oh. This patch is both AP- and client-side ... got confused there a bit
:)

johannes


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 05/10] mac80211: propagate multi bssid settings when starting
  2020-07-06 11:52 ` [PATCH V2 05/10] mac80211: propagate multi bssid settings when starting John Crispin
@ 2020-07-30 13:06   ` Johannes Berg
  0 siblings, 0 replies; 19+ messages in thread
From: Johannes Berg @ 2020-07-30 13:06 UTC (permalink / raw)
  To: John Crispin; +Cc: linux-wireless, ath11k

On Mon, 2020-07-06 at 13:52 +0200, John Crispin wrote:
> 
> +	memcpy(&sdata->vif.bss_conf.multi_bssid, &params->multi_bssid,
> +	       sizeof(struct ieee80211_multi_bssid));

What's wrong with struct assignments? :)

	sdata->vif.bss_conf.multi_bssid = params->multi_bssid;

works just fine ...

johannes


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 01/10] nl80211: add basic multiple bssid support
  2020-07-06 11:52 [PATCH V2 01/10] nl80211: add basic multiple bssid support John Crispin
                   ` (10 preceding siblings ...)
  2020-07-30 12:57 ` Johannes Berg
@ 2020-07-30 14:37 ` Johannes Berg
  11 siblings, 0 replies; 19+ messages in thread
From: Johannes Berg @ 2020-07-30 14:37 UTC (permalink / raw)
  To: John Crispin; +Cc: linux-wireless, ath11k

On Mon, 2020-07-06 at 13:52 +0200, John Crispin wrote:
> 
> @@ -3761,6 +3765,16 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
>  	if (err < 0)
>  		return err;
>  
> +	if (info->attrs[NL80211_ATTR_MULTI_BSSID_MODE])
> +		params.multi_bssid_mode =
> +			nla_get_u8(info->attrs[NL80211_ATTR_MULTI_BSSID_MODE]);
[...]

Oh .. missed this completely until I got to the iw patch :)

Why are you adding this in *new interface? IMHO it would be more
applicable to "start_ap"? I don't see a reason why an interface couldn't
change the role here regarding multi-BSSID while it's down?

That might also address some of the whole "cfg80211" vs. "mac80211"
thing I raised previously, since now cfg80211 would have a lot more
knowledge about things if the interface is already operating, i.e. it
could track and validate more of this?

johannes


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 06/10] ath11k: pass multiple bssid info to FW when a new vdev is created
  2020-07-06 11:52 ` [PATCH V2 06/10] ath11k: pass multiple bssid info to FW when a new vdev is created John Crispin
@ 2020-08-02 15:02   ` Shay Bar
  2020-08-02 15:40     ` John Crispin
  0 siblings, 1 reply; 19+ messages in thread
From: Shay Bar @ 2020-08-02 15:02 UTC (permalink / raw)
  To: John Crispin, Johannes Berg; +Cc: linux-wireless, ath11k

On 06/07/2020 14:52, John Crispin wrote:
> -static void
> +static int
>  ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,
>                                     struct vdev_create_params *params)
>  {
>         struct ath11k *ar = arvif->ar;
>         struct ath11k_pdev *pdev = ar->pdev;
> +       struct ieee80211_vif *parent;
>
>         params->if_id = arvif->vdev_id;
>         params->type = arvif->vdev_type;
>         params->subtype = arvif->vdev_subtype;
>         params->pdev_id = pdev->pdev_id;
> +       params->vdevid_trans = 0;
> +       switch (ieee80211_get_multi_bssid_mode(arvif->vif)) {
> +       case NL80211_MULTIPLE_BSSID_TRANSMITTED:
> +               params->flags = WMI_HOST_VDEV_FLAGS_TRANSMIT_AP;
> +               break;
> +       case NL80211_MULTIPLE_BSSID_NON_TRANSMITTED:
> +               params->flags = WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP;
> +               parent = ieee80211_get_multi_bssid_parent(arvif->vif);
> +               if (!parent)
> +                       return -ENOENT;
> +               if (ar->hw->wiphy != ieee80211_vif_to_wdev(parent)->wiphy)
> +                       return -EINVAL;
> +               params->vdevid_trans = ath11k_vif_to_arvif(parent)->vdev_id;
> +               break;
> +       default:
> +               params->flags = WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP;
> +               break;
> +       }

Hi John,
The ath11k_mac_setup_vdev_create_params() is called from the add_interface hook
which is called from ieee80211_do_open() which is, for the first (TRANSMITTED)
interface, before wdev->multi_bssid_mode is set to NL80211_MULTIPLE_BSSID_TRANSMITTED
(set upon start_ap from hostapd).
Can you please explain how wdev->multi_bssid_mode can have
NL80211_MULTIPLE_BSSID_TRANSMITTED value in the above code ?

________________________________
The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any retransmission, dissemination, copying or other use of, or taking of any action in reliance upon this information is prohibited. If you received this in error, please contact the sender and delete the material from any computer. Nothing contained herein shall be deemed as a representation, warranty or a commitment by Celeno. No warranties are expressed or implied, including, but not limited to, any implied warranties of non-infringement, merchantability and fitness for a particular purpose.
________________________________


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH V2 06/10] ath11k: pass multiple bssid info to FW when a new vdev is created
  2020-08-02 15:02   ` Shay Bar
@ 2020-08-02 15:40     ` John Crispin
  0 siblings, 0 replies; 19+ messages in thread
From: John Crispin @ 2020-08-02 15:40 UTC (permalink / raw)
  To: Shay Bar, Johannes Berg; +Cc: linux-wireless, ath11k


On 02.08.20 17:02, Shay Bar wrote:
> On 06/07/2020 14:52, John Crispin wrote:
>> -static void
>> +static int
>>   ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,
>>                                      struct vdev_create_params *params)
>>   {
>>          struct ath11k *ar = arvif->ar;
>>          struct ath11k_pdev *pdev = ar->pdev;
>> +       struct ieee80211_vif *parent;
>>
>>          params->if_id = arvif->vdev_id;
>>          params->type = arvif->vdev_type;
>>          params->subtype = arvif->vdev_subtype;
>>          params->pdev_id = pdev->pdev_id;
>> +       params->vdevid_trans = 0;
>> +       switch (ieee80211_get_multi_bssid_mode(arvif->vif)) {
>> +       case NL80211_MULTIPLE_BSSID_TRANSMITTED:
>> +               params->flags = WMI_HOST_VDEV_FLAGS_TRANSMIT_AP;
>> +               break;
>> +       case NL80211_MULTIPLE_BSSID_NON_TRANSMITTED:
>> +               params->flags = WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP;
>> +               parent = ieee80211_get_multi_bssid_parent(arvif->vif);
>> +               if (!parent)
>> +                       return -ENOENT;
>> +               if (ar->hw->wiphy != ieee80211_vif_to_wdev(parent)->wiphy)
>> +                       return -EINVAL;
>> +               params->vdevid_trans = ath11k_vif_to_arvif(parent)->vdev_id;
>> +               break;
>> +       default:
>> +               params->flags = WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP;
>> +               break;
>> +       }
> Hi John,
> The ath11k_mac_setup_vdev_create_params() is called from the add_interface hook
> which is called from ieee80211_do_open() which is, for the first (TRANSMITTED)
> interface, before wdev->multi_bssid_mode is set to NL80211_MULTIPLE_BSSID_TRANSMITTED
> (set upon start_ap from hostapd).
> Can you please explain how wdev->multi_bssid_mode can have
> NL80211_MULTIPLE_BSSID_TRANSMITTED value in the above code ?

Hi Shay,

https://patchwork.kernel.org/patch/11587085/

     John


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, back to index

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-06 11:52 [PATCH V2 01/10] nl80211: add basic multiple bssid support John Crispin
2020-07-06 11:52 ` [PATCH V2 02/10] nl80211: add attributes for multiple bssid related settings John Crispin
2020-07-30 12:57   ` Johannes Berg
2020-07-06 11:52 ` [PATCH V2 03/10] mac80211: add multiple bssid support John Crispin
2020-07-30 13:03   ` Johannes Berg
2020-07-06 11:52 ` [PATCH V2 04/10] mac80211: add multiple bssid IE parsing John Crispin
2020-07-30 13:05   ` Johannes Berg
2020-07-06 11:52 ` [PATCH V2 05/10] mac80211: propagate multi bssid settings when starting John Crispin
2020-07-30 13:06   ` Johannes Berg
2020-07-06 11:52 ` [PATCH V2 06/10] ath11k: pass multiple bssid info to FW when a new vdev is created John Crispin
2020-08-02 15:02   ` Shay Bar
2020-08-02 15:40     ` John Crispin
2020-07-06 11:52 ` [PATCH V2 07/10] ath11k: add a struct to pass parameters into ath11k_wmi_vdev_up John Crispin
2020-07-06 11:52 ` [PATCH V2 08/10] ath11k: add the multiple bssid IE offset to the beacon template John Crispin
2020-07-06 11:52 ` [PATCH V2 09/10] ath11k: set beacon tx mode John Crispin
2020-07-06 11:52 ` [PATCH V2 10/10] ath11k: set the multiple bssid hw cap John Crispin
2020-07-30 12:55 ` [PATCH V2 01/10] nl80211: add basic multiple bssid support Johannes Berg
2020-07-30 12:57 ` Johannes Berg
2020-07-30 14:37 ` Johannes Berg

Linux-Wireless Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-wireless/0 linux-wireless/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-wireless linux-wireless/ https://lore.kernel.org/linux-wireless \
		linux-wireless@vger.kernel.org
	public-inbox-index linux-wireless

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-wireless


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git