2020-06-04 07:12:03

by John Crispin

[permalink] [raw]
Subject: [PATCH 00/12] mac80211: add multiple bssid support

Multiple bssid allows us to share a single beacon amongst several VAPs.
This essentially safes airtime. This feature is achieved by adding an
additional IE to the transmitting VAPs beacon. This new IE contains
the additional SSIDs and their non-inheritance information.

This series is still missing handling for TIM, which will be sent in a
follow-up series.

John Crispin (12):
nl80211: add basic multiple bssid support
nl80211: add attributes for multiple bssid related settings
nl80211: add attributes to set beacon transmit mode
mac80211: add multiple bssid support
mac80211: add multiple bssid IE parsing
mac80211: propagate multi bssid settings when starting an AP
mac80211: propagate beacon tx mode to the driver
ath11k: pass multiple bssid info to FW when a new vdev is created
ath11k: add a struct to pass parameters into ath11k_wmi_vdev_up
ath11k: add the multiple bssid IE offset to the beacon template
ath11k: set beacon tx mode
ath11k: set the multiple bssid hw cap

drivers/net/wireless/ath/ath11k/mac.c | 72 ++++++++++++++++++++++++---
drivers/net/wireless/ath/ath11k/wmi.c | 20 +++++---
drivers/net/wireless/ath/ath11k/wmi.h | 22 +++++++-
include/net/cfg80211.h | 23 +++++++++
include/net/mac80211.h | 29 +++++++++++
include/uapi/linux/nl80211.h | 49 ++++++++++++++++++
net/mac80211/cfg.c | 64 ++++++++++++++++++++++++
net/mac80211/ieee80211_i.h | 2 +
net/mac80211/iface.c | 16 ++++++
net/mac80211/tx.c | 10 ++++
net/mac80211/util.c | 31 ++++++++++++
net/wireless/nl80211.c | 36 ++++++++++++++
12 files changed, 358 insertions(+), 16 deletions(-)

--
2.20.1


2020-06-04 07:12:11

by John Crispin

[permalink] [raw]
Subject: [PATCH 03/12] nl80211: add attributes to set beacon transmit mode

Beacons on a radio can be sent out in burst (back to back) or staggered
(equally spread out over time) mode. This patch adds the required nl80211
attributes allowing us to configure this from userland.

Signed-off-by: John Crispin <[email protected]>
---
include/net/cfg80211.h | 3 +++
include/uapi/linux/nl80211.h | 17 +++++++++++++++++
net/wireless/nl80211.c | 7 +++++++
3 files changed, 27 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 77cd2f780c6a..157d37f74efb 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1094,6 +1094,8 @@ enum cfg80211_ap_settings_flags {
* @he_obss_pd: OBSS Packet Detection settings
* @he_bss_color: BSS Color settings
* @he_oper: HE operation IE (or %NULL if HE isn't enabled)
+ * @beacon_tx_mode: can be set to tell the driver to sent the beacons in staggered
+ * or burst mode.
*/
struct cfg80211_ap_settings {
struct cfg80211_chan_def chandef;
@@ -1125,6 +1127,7 @@ struct cfg80211_ap_settings {
struct ieee80211_he_obss_pd he_obss_pd;
struct cfg80211_he_bss_color he_bss_color;
struct ieee80211_multi_bssid multi_bssid;
+ enum nl80211_beacon_tx_mode beacon_tx_mode;
};

/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f18f681796ed..2c4950aeb474 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2481,6 +2481,8 @@ enum nl80211_commands {
*
* @NL80211_ATTR_MULTI_BSSID_COUNT: The number of BSSs inside the multi bssid IE.
*
+ * @NL80211_ATTR_BEACON_TX_MODE: Set the beacon tx mode to staggered or burst.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2961,6 +2963,8 @@ enum nl80211_attrs {
NL80211_ATTR_MULTI_BSSID_INDEX,
NL80211_ATTR_MULTI_BSSID_COUNT,

+ NL80211_ATTR_BEACON_TX_MODE,
+
/* add attributes here, update the policy in nl80211.c */

__NL80211_ATTR_AFTER_LAST,
@@ -6732,6 +6736,19 @@ enum nl80211_multi_bssid_mode {
NL80211_MULTIPLE_BSSID_NON_TRANSMITTED,
};

+/**
+ * enum nl80211_beacon_tx_mode - Beacon tx mode settings
+ *
+ * @BEACON_TX_MODE_DEFAULT: The beacons shall be sent out in its default mode
+ * @BEACON_TX_MODE_STAGGERED: The beacons shall be sent out in staggered mode
+ * @BEACON_TX_MODE_BURST: The beacons shall be sent out in burst mode
+ * beacon
+ */
+enum nl80211_beacon_tx_mode {
+ NL80211_BEACON_TX_MODE_STAGGERED = 0,
+ NL80211_BEACON_TX_MODE_BURST,
+};
+
/**
* 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 58ce67bc31da..1f6f8ecbfb57 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -669,6 +669,9 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_MULTI_BSSID_PARENT] = { .type = NLA_U32 },
[NL80211_ATTR_MULTI_BSSID_INDEX] = { .type = NLA_U32 },
[NL80211_ATTR_MULTI_BSSID_COUNT] = { .type = NLA_U32 },
+ [NL80211_ATTR_BEACON_TX_MODE] = NLA_POLICY_RANGE(NLA_U8,
+ NL80211_BEACON_TX_MODE_STAGGERED,
+ NL80211_BEACON_TX_MODE_BURST),
};

/* policy for the key attributes */
@@ -5165,6 +5168,10 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
params.multi_bssid.count = nla_get_u32(
info->attrs[NL80211_ATTR_MULTI_BSSID_COUNT]);

+ if (info->attrs[NL80211_ATTR_BEACON_TX_MODE])
+ params.beacon_tx_mode =
+ nla_get_u8(info->attrs[NL80211_ATTR_BEACON_TX_MODE]);
+
nl80211_calculate_ap_params(&params);

if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
--
2.20.1

2020-06-04 07:12:38

by John Crispin

[permalink] [raw]
Subject: [PATCH 06/12] mac80211: propagate multi bssid settings when starting an AP

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 <[email protected]>
---
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 1a98b3907aa7..3812adcef7d7 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -606,6 +606,7 @@ struct ieee80211_ftm_responder_params {
* @he_operation: 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;
@@ -669,6 +670,7 @@ struct ieee80211_bss_conf {
struct ieee80211_he_operation he_operation;
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 e4f73567d873..f6f7323c66ab 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1130,6 +1130,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.20.1

2020-06-04 07:12:53

by John Crispin

[permalink] [raw]
Subject: [PATCH 09/12] ath11k: add a struct to pass parameters into ath11k_wmi_vdev_up

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 <[email protected]>
---
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 b38b687d1100..63099607065b 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -668,9 +668,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);
@@ -735,6 +739,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);
@@ -762,9 +773,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);
@@ -1685,6 +1702,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;

@@ -1733,7 +1755,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);
@@ -4987,6 +5009,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))
@@ -5007,8 +5031,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 a46aa831d8be..3fca51c3f943 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 761e27a3a306..548fa05cb1f6 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -2410,6 +2410,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;
@@ -4732,8 +4741,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.20.1

2020-06-04 07:14:25

by John Crispin

[permalink] [raw]
Subject: [PATCH 08/12] ath11k: pass multiple bssid info to FW when a new vdev is created

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 <[email protected]>
---
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 2f11259de24a..b38b687d1100 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -4163,17 +4163,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;
@@ -4183,6 +4202,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
@@ -4334,7 +4354,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 5b35d06a0d81..a46aa831d8be 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 82929415e119..761e27a3a306 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.
*/
@@ -2376,6 +2382,8 @@ struct vdev_create_params {
u8 rx;
} chains[NUM_NL80211_BANDS];
u32 pdev_id;
+ u32 flags;
+ u32 vdevid_trans;
};

struct wmi_vdev_create_cmd {
@@ -2386,6 +2394,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.20.1

2020-06-04 07:14:25

by John Crispin

[permalink] [raw]
Subject: [PATCH 02/12] nl80211: add attributes for multiple bssid related settings

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

Signed-off-by: John Crispin <[email protected]>
---
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 f0fc65f900b4..77cd2f780c6a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -448,6 +448,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
@@ -1113,6 +1124,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 a586567f18ea..f18f681796ed 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2476,6 +2476,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
@@ -2953,6 +2958,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 3b502514944c..58ce67bc31da 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -667,6 +667,8 @@ 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 */
@@ -4996,6 +4998,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;
@@ -5150,6 +5157,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.20.1

2020-06-04 07:14:25

by John Crispin

[permalink] [raw]
Subject: [PATCH 01/12] nl80211: add basic multiple bssid support

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 <[email protected]>
---
include/net/cfg80211.h | 8 ++++++++
include/uapi/linux/nl80211.h | 25 +++++++++++++++++++++++++
net/wireless/nl80211.c | 14 ++++++++++++++
3 files changed, 47 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index deaa3668d47a..f0fc65f900b4 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -601,6 +601,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;
};

/**
@@ -5060,6 +5062,9 @@ struct cfg80211_cqm_config;
* @pmsr_list: (private) peer measurement requests
* @pmsr_lock: (private) peer measurements requests/results lock
* @pmsr_free_wk: (private) peer measurements cleanup work
+ * @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;
@@ -5136,6 +5141,9 @@ struct wireless_dev {
struct list_head pmsr_list;
spinlock_t pmsr_lock;
struct work_struct pmsr_free_wk;
+ 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 966887bd654c..a586567f18ea 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2470,6 +2470,12 @@ enum nl80211_commands {
* no roaming occurs between the reauth threshold and PMK expiration,
* disassociation is still forced.
*
+ * @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
@@ -2945,6 +2951,9 @@ enum nl80211_attrs {
NL80211_ATTR_PMK_LIFETIME,
NL80211_ATTR_PMK_REAUTH_THRESHOLD,

+ NL80211_ATTR_MULTI_BSSID_MODE,
+ NL80211_ATTR_MULTI_BSSID_PARENT,
+
/* add attributes here, update the policy in nl80211.c */

__NL80211_ATTR_AFTER_LAST,
@@ -6700,6 +6709,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 ed545b2a958d..3b502514944c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -663,6 +663,10 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_CONTROL_PORT_NO_PREAUTH] = { .type = NLA_FLAG },
[NL80211_ATTR_PMK_LIFETIME] = NLA_POLICY_MIN(NLA_U32, 1),
[NL80211_ATTR_PMK_REAUTH_THRESHOLD] = NLA_POLICY_RANGE(NLA_U8, 1, 100),
+ [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 */
@@ -3756,6 +3760,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.20.1

2020-06-04 07:14:26

by John Crispin

[permalink] [raw]
Subject: [PATCH 05/12] mac80211: add multiple bssid IE parsing

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 <[email protected]>
---
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 bb2edace71a9..1a98b3907aa7 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -4717,12 +4717,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 2502726d0a58..abe488424287 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1520,6 +1520,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;
@@ -1540,6 +1541,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 49d35936cc9d..5e2879cd24b0 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4747,11 +4747,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 a7c4d6a44e21..bbe2f1d9166c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1311,6 +1311,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.20.1

2020-06-04 07:14:26

by John Crispin

[permalink] [raw]
Subject: [PATCH 07/12] mac80211: propagate beacon tx mode to the driver

Now that we can set the beacon xmit mode via nl80211 we want to also
propagate that info to the device driver. This patch sets the field
inside bss_config.

Signed-off-by: John Crispin <[email protected]>
---
include/net/mac80211.h | 2 ++
net/mac80211/cfg.c | 1 +
2 files changed, 3 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 3812adcef7d7..f99abd5e8bc6 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -607,6 +607,7 @@ struct ieee80211_ftm_responder_params {
* @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.
+ * @beacon_tx_mode: the beacon tx mode. This can be staggered or burst.
*/
struct ieee80211_bss_conf {
const u8 *bssid;
@@ -671,6 +672,7 @@ struct ieee80211_bss_conf {
struct ieee80211_he_obss_pd he_obss_pd;
struct cfg80211_he_bss_color he_bss_color;
struct ieee80211_multi_bssid multi_bssid;
+ enum nl80211_beacon_tx_mode beacon_tx_mode;
};

/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index f6f7323c66ab..1f3c93b8f265 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1071,6 +1071,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,

prev_beacon_int = sdata->vif.bss_conf.beacon_int;
sdata->vif.bss_conf.beacon_int = params->beacon_interval;
+ sdata->vif.bss_conf.beacon_tx_mode = params->beacon_tx_mode;

if (params->he_cap && params->he_oper) {
sdata->vif.bss_conf.he_support = true;
--
2.20.1

2020-06-04 07:27:33

by John Crispin

[permalink] [raw]
Subject: [PATCH 11/12] ath11k: set beacon tx mode

The beacon can be sent out in staggered or burst mode. Set this mode
according to what mac80211 tells us to use whenever the beacon changes.

Signed-off-by: John Crispin <[email protected]>
---
drivers/net/wireless/ath/ath11k/mac.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 63099607065b..8ec11c654b3e 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -1907,6 +1907,8 @@ 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 (info->beacon_tx_mode == NL80211_BEACON_TX_MODE_BURST)
+ param_value = WMI_BEACON_BURST_MODE;
ret = ath11k_wmi_pdev_set_param(ar, param_id,
param_value, ar->pdev->pdev_id);
if (ret)
--
2.20.1

2020-06-04 07:27:36

by John Crispin

[permalink] [raw]
Subject: [PATCH 10/12] ath11k: add the multiple bssid IE offset to the beacon template

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

Signed-off-by: John Crispin <[email protected]>
---
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 3fca51c3f943..2fe4b65850ef 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.20.1

2020-06-04 07:27:40

by John Crispin

[permalink] [raw]
Subject: [PATCH 12/12] ath11k: set the multiple bssid hw cap

This patch sets the SUPPORTS_MULTI_BSSID inside ath11k.

Signed-off-by: John Crispin <[email protected]>
---
drivers/net/wireless/ath/ath11k/mac.c | 4 ++++
drivers/net/wireless/ath/ath11k/wmi.h | 4 ++--
2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 8ec11c654b3e..55876600b7c5 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -5980,17 +5980,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,
};
@@ -6101,6 +6104,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);
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index 548fa05cb1f6..14cffda43ed0 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -109,8 +109,8 @@ enum {

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_HOST_VDEV_FLAGS_NON_TRANSMIT_AP = 2,
+ WMI_HOST_VDEV_FLAGS_TRANSMIT_AP = 4,
};

/*
--
2.20.1

2020-06-08 11:12:28

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 12/12] ath11k: set the multiple bssid hw cap

John Crispin <[email protected]> writes:

> This patch sets the SUPPORTS_MULTI_BSSID inside ath11k.
>
> Signed-off-by: John Crispin <[email protected]>

On what hardware and firmware did you test this?

> --- a/drivers/net/wireless/ath/ath11k/wmi.h
> +++ b/drivers/net/wireless/ath/ath11k/wmi.h
> @@ -109,8 +109,8 @@ enum {
>
> 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_HOST_VDEV_FLAGS_NON_TRANSMIT_AP = 2,
> + WMI_HOST_VDEV_FLAGS_TRANSMIT_AP = 4,

I wonder if this is a safe thing to do? Do all firmware branches use
these new values?

--
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2020-06-08 11:30:47

by John Crispin

[permalink] [raw]
Subject: Re: [PATCH 12/12] ath11k: set the multiple bssid hw cap

On 08.06.20 13:09, Kalle Valo wrote:
> John Crispin <[email protected]> writes:
>
>> This patch sets the SUPPORTS_MULTI_BSSID inside ath11k.
>>
>> Signed-off-by: John Crispin <[email protected]>
>
> On what hardware and firmware did you test this?
>
>> --- a/drivers/net/wireless/ath/ath11k/wmi.h
>> +++ b/drivers/net/wireless/ath/ath11k/wmi.h
>> @@ -109,8 +109,8 @@ enum {
>>
>> 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_HOST_VDEV_FLAGS_NON_TRANSMIT_AP = 2,
>> + WMI_HOST_VDEV_FLAGS_TRANSMIT_AP = 4,
>
> I wonder if this is a safe thing to do? Do all firmware branches use
> these new values?
>

Hi,
looks like i folded the fix patch into the wrong patch. these values get
added in this same patchset. Johannes commented on the nl80211 part
already and i will send out a V2 this week.
John

2020-06-09 03:36:24

by Rajkumar Manoharan

[permalink] [raw]
Subject: Re: [PATCH 00/12] mac80211: add multiple bssid support

On 2020-06-04 00:09, John Crispin wrote:
> Multiple bssid allows us to share a single beacon amongst several VAPs.
> This essentially safes airtime. This feature is achieved by adding an
> additional IE to the transmitting VAPs beacon. This new IE contains
> the additional SSIDs and their non-inheritance information.
>
> This series is still missing handling for TIM, which will be sent in a
> follow-up series.
>
> John Crispin (12):
> nl80211: add basic multiple bssid support
> nl80211: add attributes for multiple bssid related settings
> nl80211: add attributes to set beacon transmit mode
> mac80211: add multiple bssid support
> mac80211: add multiple bssid IE parsing
> mac80211: propagate multi bssid settings when starting an AP
> mac80211: propagate beacon tx mode to the driver
> ath11k: pass multiple bssid info to FW when a new vdev is created
> ath11k: add a struct to pass parameters into ath11k_wmi_vdev_up
> ath11k: add the multiple bssid IE offset to the beacon template
> ath11k: set beacon tx mode
> ath11k: set the multiple bssid hw cap
>
Great work :)

-Rajkumar

2020-06-10 00:30:26

by Rajkumar Manoharan

[permalink] [raw]
Subject: Re: [PATCH 01/12] nl80211: add basic multiple bssid support

On 2020-06-04 00:09, John Crispin wrote:
[...]
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -663,6 +663,10 @@ const struct nla_policy
> nl80211_policy[NUM_NL80211_ATTR] = {
> [NL80211_ATTR_CONTROL_PORT_NO_PREAUTH] = { .type = NLA_FLAG },
> [NL80211_ATTR_PMK_LIFETIME] = NLA_POLICY_MIN(NLA_U32, 1),
> [NL80211_ATTR_PMK_REAUTH_THRESHOLD] = NLA_POLICY_RANGE(NLA_U8, 1,
> 100),
> + [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 },
>
If it is read as u8, better define as NLA_U8.

> };
>
> /* policy for the key attributes */
> @@ -3756,6 +3760,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;
> +
Are you expecting BSSID or ifindex in multi_bssid_parent? If it is
ifindex, it can be 0. no

-Rajkumar

2020-06-11 04:25:31

by Rajkumar Manoharan

[permalink] [raw]
Subject: Re: [PATCH 02/12] nl80211: add attributes for multiple bssid related settings

On 2020-06-04 00:09, John Crispin wrote:
> When we start a multiple bssid AP we need to pass the index and number
> of
> peers aswell to the kernel. This info needs to be propagated to the
> driver.
>
> Signed-off-by: John Crispin <[email protected]>
> ---
> include/net/cfg80211.h | 12 ++++++++++++
> include/uapi/linux/nl80211.h | 7 +++++++
> net/wireless/nl80211.c | 15 +++++++++++++++
> 3 files changed, 34 insertions(+)
>
[...]
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index 3b502514944c..58ce67bc31da 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -667,6 +667,8 @@ 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 */
> @@ -4996,6 +4998,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;
> @@ -5150,6 +5157,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]);
> +
John,

Does the count include transmitting and non-transmitting APs? Or just
child-node counts.
Are you expecting start_ap() for all non-trasmitting AP as well? Hope
this count can be
set only for parent AP?

-Rajkumar

2020-06-11 04:47:50

by Rajkumar Manoharan

[permalink] [raw]
Subject: Re: [PATCH 12/12] ath11k: set the multiple bssid hw cap

On 2020-06-04 00:09, John Crispin wrote:
> This patch sets the SUPPORTS_MULTI_BSSID inside ath11k.
>
> Signed-off-by: John Crispin <[email protected]>
>
[...]

> diff --git a/drivers/net/wireless/ath/ath11k/wmi.h
> b/drivers/net/wireless/ath/ath11k/wmi.h
> index 548fa05cb1f6..14cffda43ed0 100644
> --- a/drivers/net/wireless/ath/ath11k/wmi.h
> +++ b/drivers/net/wireless/ath/ath11k/wmi.h
> @@ -109,8 +109,8 @@ enum {
>
> 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_HOST_VDEV_FLAGS_NON_TRANSMIT_AP = 2,
> + WMI_HOST_VDEV_FLAGS_TRANSMIT_AP = 4,
> };
>
John,

Not sure how you got the above values? Please confirm.

#define VDEV_FLAGS_NON_MBSSID_AP 0x00000001 /* legacy AP */
#define VDEV_FLAGS_TRANSMIT_AP 0x00000002 /* indicate if this
vdev is transmitting AP */
#define VDEV_FLAGS_NON_TRANSMIT_AP 0x00000004 /* explicitly
indicate this vdev is non-transmitting AP */
#define VDEV_FLAGS_EMA_MODE 0x00000008 /* vdev is EMA and
supports multiple beacon profiles. */

-Rajkumar