- Changes in MAC80211 add support for enhanced multiple BSSID (EMA AP).
This patch is the next version for the following series:
https://patchwork.kernel.org/project/linux-wireless/list/?series=558285&state=%2A&archive=both
The changes are now rebased on top of wireless-testing tree which
includes this series:
https://patchwork.kernel.org/project/linux-wireless/list/?series=617531&state=%2A&archive=both
- Patches for ath11k split the changes from following patch in
logical separate patches:
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/
And also use the latest API changes in MAC80211 which were different
at the time of V6.
Aloka Dixit (9):
mac80211: generate EMA beacons in AP mode
ath11k: add WMI resource config for EMA
ath11k: set MBSSID and EMA driver capabilities
ath11k: MBSSID configuration during vdev create/start
ath11k: create a structure for WMI vdev up parameters
ath11k: configure MBSSID device parameters
ath11k: move vif parameter setting in a different function
ath11k: EMA beacon support
ath11k: configure WPA and RSNE parameters for nontransmitting
interface
drivers/net/wireless/ath/ath11k/core.h | 2 +
drivers/net/wireless/ath/ath11k/hw.c | 3 +
drivers/net/wireless/ath/ath11k/hw.h | 1 +
drivers/net/wireless/ath/ath11k/mac.c | 361 ++++++++++++++++++++++---
drivers/net/wireless/ath/ath11k/wmi.c | 27 +-
drivers/net/wireless/ath/ath11k/wmi.h | 66 ++++-
include/net/mac80211.h | 77 ++++++
net/mac80211/cfg.c | 9 +-
net/mac80211/ieee80211_i.h | 9 +-
net/mac80211/tx.c | 110 +++++++-
10 files changed, 603 insertions(+), 62 deletions(-)
base-commit: 9335156ac0e174721921c404bd173526c8509124
--
2.31.1
Configure multiple BSSID flags and index of the transmitting interface
in vdev create/start commands depending on the service bit
WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT.
Signed-off-by: Aloka Dixit <[email protected]>
Co-developed-by: John Crispin <[email protected]>
Signed-off-by: John Crispin <[email protected]>
---
drivers/net/wireless/ath/ath11k/mac.c | 70 +++++++++++++++++++++++++--
drivers/net/wireless/ath/ath11k/wmi.c | 5 ++
drivers/net/wireless/ath/ath11k/wmi.h | 22 +++++++++
3 files changed, 93 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 075a307797d8..8f629e54a53d 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -5938,17 +5938,62 @@ static void ath11k_mac_op_stop(struct ieee80211_hw *hw)
atomic_set(&ar->num_pending_mgmt_tx, 0);
}
-static void
-ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,
- struct vdev_create_params *params)
+static int ath11k_mac_setup_vdev_params_mbssid(struct ath11k_vif *arvif,
+ u32 *flags, u32 *tx_vdev_id)
+{
+ struct ath11k *ar = arvif->ar;
+ struct ath11k_vif *tx_arvif;
+ struct ieee80211_vif *tx_vif;
+
+ *tx_vdev_id = 0;
+ tx_vif = arvif->vif->mbssid_tx_vif;
+ if (!tx_vif) {
+ *flags = WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP;
+ return 0;
+ }
+
+ tx_arvif = (void *)tx_vif->drv_priv;
+
+ if (arvif->vif->bss_conf.nontransmitted) {
+ if (ar->hw->wiphy != ieee80211_vif_to_wdev(tx_vif)->wiphy)
+ return -EINVAL;
+
+ *flags = WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP;
+ *tx_vdev_id = ath11k_vif_to_arvif(tx_vif)->vdev_id;
+ } else if (tx_arvif == arvif) {
+ *flags = WMI_HOST_VDEV_FLAGS_TRANSMIT_AP;
+ } else {
+ return -EINVAL;
+ }
+
+ if (arvif->vif->bss_conf.ema_ap)
+ *flags |= WMI_HOST_VDEV_FLAGS_EMA_MODE;
+
+ return 0;
+}
+
+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;
+ int ret;
params->if_id = arvif->vdev_id;
params->type = arvif->vdev_type;
params->subtype = arvif->vdev_subtype;
params->pdev_id = pdev->pdev_id;
+ params->mbssid_flags = 0;
+ params->mbssid_tx_vdev_id = 0;
+
+ if (!test_bit(WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT,
+ ar->ab->wmi_ab.svc_map)) {
+ ret = ath11k_mac_setup_vdev_params_mbssid(arvif,
+ ¶ms->mbssid_flags,
+ ¶ms->mbssid_tx_vdev_id);
+ if (ret)
+ return ret;
+ }
if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) {
params->chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains;
@@ -5963,6 +6008,7 @@ ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,
params->chains[NL80211_BAND_6GHZ].tx = ar->num_tx_chains;
params->chains[NL80211_BAND_6GHZ].rx = ar->num_rx_chains;
}
+ return 0;
}
static u32
@@ -6279,7 +6325,12 @@ 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 create vdev parameters %d: %d\n",
+ arvif->vdev_id, ret);
+ goto err;
+ }
ret = ath11k_wmi_vdev_create(ar, vif->addr, &vdev_param);
if (ret) {
@@ -6705,6 +6756,17 @@ ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif,
arg.pref_tx_streams = ar->num_tx_chains;
arg.pref_rx_streams = ar->num_rx_chains;
+ arg.mbssid_flags = 0;
+ arg.mbssid_tx_vdev_id = 0;
+ if (test_bit(WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT,
+ ar->ab->wmi_ab.svc_map)) {
+ ret = ath11k_mac_setup_vdev_params_mbssid(arvif,
+ &arg.mbssid_flags,
+ &arg.mbssid_tx_vdev_id);
+ if (ret)
+ return ret;
+ }
+
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
arg.ssid = arvif->u.ap.ssid;
arg.ssid_len = arvif->u.ap.ssid_len;
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index b71f68d675f1..d0716f6208b2 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -720,6 +720,9 @@ 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->mbssid_flags = param->mbssid_flags;
+ cmd->mbssid_tx_vdev_id = param->mbssid_tx_vdev_id;
+
ether_addr_copy(cmd->vdev_macaddr.addr, macaddr);
ptr = skb->data + sizeof(*cmd);
@@ -936,6 +939,8 @@ int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,
cmd->cac_duration_ms = arg->cac_duration_ms;
cmd->regdomain = arg->regdomain;
cmd->he_ops = arg->he_ops;
+ cmd->mbssid_flags = arg->mbssid_flags;
+ cmd->mbssid_tx_vdev_id = arg->mbssid_tx_vdev_id;
if (!restart) {
if (arg->ssid) {
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index 842c074c7efa..c572774b9659 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -137,6 +137,14 @@ enum {
WMI_AUTORATE_3200NS_GI = BIT(11),
};
+enum {
+ WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP = 0x00000001,
+ WMI_HOST_VDEV_FLAGS_TRANSMIT_AP = 0x00000002,
+ WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP = 0x00000004,
+ WMI_HOST_VDEV_FLAGS_EMA_MODE = 0x00000008,
+ WMI_HOST_VDEV_FLAGS_SCAN_MODE_VAP = 0x00000010,
+};
+
/*
* wmi command groups.
*/
@@ -2091,6 +2099,10 @@ enum wmi_tlv_service {
WMI_TLV_SERVICE_FREQINFO_IN_METADATA = 219,
WMI_TLV_SERVICE_EXT2_MSG = 220,
WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249,
+ WMI_TLV_REQUEST_CTRL_PATH_STATS_REQUEST = 250,
+ WMI_TLV_SERVICE_TPC_STATS_EVENT = 251,
+ WMI_TLV_SERVICE_NO_INTERBAND_MCC_SUPPORT = 252,
+ WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT = 253,
/* The second 128 bits */
WMI_MAX_EXT_SERVICE = 256,
@@ -2571,6 +2583,8 @@ struct vdev_create_params {
u8 rx;
} chains[NUM_NL80211_BANDS];
u32 pdev_id;
+ u32 mbssid_flags;
+ u32 mbssid_tx_vdev_id;
};
struct wmi_vdev_create_cmd {
@@ -2581,6 +2595,8 @@ struct wmi_vdev_create_cmd {
struct wmi_mac_addr vdev_macaddr;
u32 num_cfg_txrx_streams;
u32 pdev_id;
+ u32 mbssid_flags;
+ u32 mbssid_tx_vdev_id;
} __packed;
struct wmi_vdev_txrx_streams {
@@ -2644,6 +2660,9 @@ struct wmi_vdev_start_request_cmd {
u32 he_ops;
u32 cac_duration_ms;
u32 regdomain;
+ u32 min_data_rate;
+ u32 mbssid_flags;
+ u32 mbssid_tx_vdev_id;
} __packed;
#define MGMT_TX_DL_FRM_LEN 64
@@ -2813,6 +2832,9 @@ struct wmi_vdev_start_req_arg {
u32 pref_rx_streams;
u32 pref_tx_streams;
u32 num_noa_descriptors;
+ u32 min_data_rate;
+ u32 mbssid_flags;
+ u32 mbssid_tx_vdev_id;
};
struct peer_create_params {
--
2.31.1
Add new fields in structures target_resource_config and
wmi_resource_config to configure maximum vdev count and profile
periodicity when enhanced multiple BSSID advertisements (EMA) are
enabled.
Signed-off-by: Aloka Dixit <[email protected]>
Co-developed-by: John Crispin <[email protected]>
Signed-off-by: John Crispin <[email protected]>
---
- This patch-set splits the changes from following patch in
logical separate patches:
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/
And also use the latest API changes in MAC80211 which were different
at the time of V6.
drivers/net/wireless/ath/ath11k/hw.c | 3 +++
drivers/net/wireless/ath/ath11k/hw.h | 1 +
drivers/net/wireless/ath/ath11k/wmi.c | 3 +++
drivers/net/wireless/ath/ath11k/wmi.h | 16 ++++++++++++++++
4 files changed, 23 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c
index 96db85c55585..5672def09e32 100644
--- a/drivers/net/wireless/ath/ath11k/hw.c
+++ b/drivers/net/wireless/ath/ath11k/hw.c
@@ -201,6 +201,9 @@ static void ath11k_init_wmi_config_ipq8074(struct ath11k_base *ab,
config->twt_ap_pdev_count = ab->num_radios;
config->twt_ap_sta_count = 1000;
config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64;
+ config->ema_max_vap_cnt = ab->num_radios;
+ config->ema_max_profile_period = TARGET_EMA_MAX_PROFILE_PERIOD;
+ config->beacon_tx_offload_max_vdev += config->ema_max_vap_cnt;
}
static int ath11k_hw_mac_id_to_pdev_id_ipq8074(struct ath11k_hw_params *hw,
diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h
index 77dc5c851c9b..a9e8d325a059 100644
--- a/drivers/net/wireless/ath/ath11k/hw.h
+++ b/drivers/net/wireless/ath/ath11k/hw.h
@@ -64,6 +64,7 @@
#define TARGET_NUM_WDS_ENTRIES 32
#define TARGET_DMA_BURST_SIZE 1
#define TARGET_RX_BATCHMODE 1
+#define TARGET_EMA_MAX_PROFILE_PERIOD 8
#define ATH11K_HW_MAX_QUEUES 4
#define ATH11K_QUEUE_LEN 4096
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index 84d1c7054013..b71f68d675f1 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -3934,6 +3934,9 @@ ath11k_wmi_copy_resource_config(struct wmi_resource_config *wmi_cfg,
wmi_cfg->sched_params = tg_cfg->sched_params;
wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count;
wmi_cfg->twt_ap_sta_count = tg_cfg->twt_ap_sta_count;
+ wmi_cfg->flags2 = WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET;
+ wmi_cfg->ema_max_vap_cnt = tg_cfg->ema_max_vap_cnt;
+ wmi_cfg->ema_max_profile_period = tg_cfg->ema_max_profile_period;
}
static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index b1fad4707dc6..842c074c7efa 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -2308,6 +2308,7 @@ struct wmi_init_cmd {
} __packed;
#define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)
+#define WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET BIT(9)
struct wmi_resource_config {
u32 tlv_header;
@@ -2368,6 +2369,18 @@ struct wmi_resource_config {
u32 sched_params;
u32 twt_ap_pdev_count;
u32 twt_ap_sta_count;
+ u32 max_nlo_ssids;
+ u32 num_pkt_filters;
+ u32 num_max_sta_vdevs;
+ u32 max_bssid_indicator;
+ u32 ul_resp_config;
+ u32 msdu_flow_override_config0;
+ u32 msdu_flow_override_config1;
+ u32 flags2;
+ u32 host_service_flags;
+ u32 max_rnr_neighbours;
+ u32 ema_max_vap_cnt;
+ u32 ema_max_profile_period;
} __packed;
struct wmi_service_ready_event {
@@ -5326,6 +5339,9 @@ struct target_resource_config {
u32 sched_params;
u32 twt_ap_pdev_count;
u32 twt_ap_sta_count;
+ bool is_reg_cc_ext_event_supported;
+ u32 ema_max_vap_cnt;
+ u32 ema_max_profile_period;
};
enum wmi_sys_cap_info_flags {
--
2.31.1
Add APIs to generate an array of beacons for an EMA AP (enhanced
multiple BSSID advertisements), each including a single MBSSID element.
EMA profile periodicity equals the count of elements.
- ieee80211_beacon_get_template_ema_list() - Generate and return all
EMA beacon templates. Drivers must call ieee80211_beacon_free_ema_list()
to free the memory. No change in the prototype for the existing API,
ieee80211_beacon_get_template(), which should be used for non-EMA AP.
- ieee80211_beacon_get_template_ema_index() - Generate a beacon which
includes the multiple BSSID element at the given index. Drivers can use
this function in a loop until NULL is returned which indicates end of
available MBSSID elements.
- ieee80211_beacon_free_ema_list() - free the memory allocated for the
list of EMA beacon templates.
Add new macro IEEE80211_MBSSID_ELEMS_ALL to be used for basic MBSSID
implementation without EMA.
Modify exsiting functions ieee80211_beacon_get_ap(),
ieee80211_get_mbssid_beacon_len() and ieee80211_beacon_add_mbssid()
to accept a new parameter for EMA index.
Signed-off-by: Aloka Dixit <[email protected]>
Co-developed-by: John Crispin <[email protected]>
Signed-off-by: John Crispin <[email protected]>
---
- This patch is the next version for the following series:
https://patchwork.kernel.org/project/linux-wireless/list/?series=558285&state=%2A&archive=both
The changes are now rebased on top of wireless-testing tree which
includes this series:
https://patchwork.kernel.org/project/linux-wireless/list/?series=617531&state=%2A&archive=both
- Replaced GFP_KERNEL with GFP_ATOMIC for the memory allocation
under RCU lock.
- CONFIG_DEBUG_ATOMIC_SLEEP, CONFIG_PROVE_LOCKING, CONFIG_PROVE_RCU
flags were enabled during compilation.
include/net/mac80211.h | 77 ++++++++++++++++++++++++++
net/mac80211/cfg.c | 9 ++-
net/mac80211/ieee80211_i.h | 9 ++-
net/mac80211/tx.c | 110 +++++++++++++++++++++++++++++++++----
4 files changed, 189 insertions(+), 16 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index ebadb2103968..ae6e50c64edb 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -5050,6 +5050,83 @@ ieee80211_beacon_get_template(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_mutable_offsets *offs);
+/**
+ * This macro should be used to get total length for all MBSSID elements
+ * in the beacon, and also to generate a single beacon template with
+ * all MBSSID elements.
+ */
+#define IEEE80211_MBSSID_ELEMS_ALL -1
+
+/**
+ * ieee80211_beacon_get_template_ema_index - EMA beacon template generation
+ * function for drivers using the sw offload path.
+ * @hw: pointer obtained from ieee80211_alloc_hw().
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ * @offs: &struct ieee80211_mutable_offsets pointer to struct that will
+ * receive the offsets that may be updated by the driver.
+ * @ema_index: index of the beacon in the EMA set, should be more than
+ * IEEE80211_MBSSID_ELEMS_ALL otherwise the set/get functions include all
+ * MBSSID elements in a single beacon template.
+ *
+ * This function follows the same rules as ieee80211_beacon_get_template()
+ * but returns a beacon template which includes multiple BSSID element at the
+ * requested index.
+ *
+ * Return: The beacon template. %NULL indicates the end of EMA beacon templates.
+ */
+struct sk_buff *
+ieee80211_beacon_get_template_ema_index(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_mutable_offsets *offs,
+ u8 ema_index);
+
+/**
+ * struct ieee80211_ema_beacons - List of EMA beacons
+ * @cnt: count of EMA beacons.
+ *
+ * @bcn: array of EMA beacons.
+ * @bcn.skb: the skb containing this specific beacon
+ * @bcn.offs: &struct ieee80211_mutable_offsets pointer to struct that will
+ * receive the offsets that may be updated by the driver.
+ */
+struct ieee80211_ema_beacons {
+ u8 cnt;
+ struct {
+ struct sk_buff *skb;
+ struct ieee80211_mutable_offsets offs;
+ } bcn[];
+};
+
+/**
+ * ieee80211_beacon_get_template_ema_list - EMA beacon template generation
+ * function for drivers using the hw offload.
+ * @hw: pointer obtained from ieee80211_alloc_hw().
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ * @ema_beacons: list of EMA beacons of type &struct ieee80211_ema_beacons.
+ *
+ * This function follows the same rules as ieee80211_beacon_get_template()
+ * but allocates and returns a pointer to list of all beacon templates required
+ * to cover all profiles in the multiple BSSID set. Each template includes only
+ * one multiple BSSID element.
+ *
+ * Driver must call ieee80211_beacon_free_ema_list() to free the memory.
+ *
+ * Return: EMA beacon templates of type struct ieee80211_ema_beacons *.
+ * %NULL on error.
+ */
+struct ieee80211_ema_beacons *
+ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
+
+/**
+ * ieee80211_beacon_free_ema_list - free an EMA beacon template list
+ * @ema_beacons: list of EMA beacons of type &struct ieee80211_ema_beacons pointers.
+ *
+ * This function will free a list previously acquired by calling
+ * ieee80211_beacon_get_template_ema_list()
+ */
+void ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *ema_beacons);
+
/**
* ieee80211_beacon_get_tim - beacon generation function
* @hw: pointer obtained from ieee80211_alloc_hw().
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index bbec7d778084..42ea37647e5e 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1044,11 +1044,13 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
if (params->mbssid_ies) {
mbssid = params->mbssid_ies;
size += struct_size(new->mbssid_ies, elem, mbssid->cnt);
- size += ieee80211_get_mbssid_beacon_len(mbssid);
+ size += ieee80211_get_mbssid_beacon_len(mbssid,
+ IEEE80211_MBSSID_ELEMS_ALL);
} else if (old && old->mbssid_ies) {
mbssid = old->mbssid_ies;
size += struct_size(new->mbssid_ies, elem, mbssid->cnt);
- size += ieee80211_get_mbssid_beacon_len(mbssid);
+ size += ieee80211_get_mbssid_beacon_len(mbssid,
+ IEEE80211_MBSSID_ELEMS_ALL);
}
new = kzalloc(size, GFP_KERNEL);
@@ -3189,7 +3191,8 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon)
len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len +
beacon->proberesp_ies_len + beacon->assocresp_ies_len +
beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len +
- ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies);
+ ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies,
+ IEEE80211_MBSSID_ELEMS_ALL);
new_beacon = kzalloc(sizeof(*new_beacon) + len, GFP_KERNEL);
if (!new_beacon)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 86ef0a46a68c..c81c07c9ba3e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1086,12 +1086,17 @@ ieee80211_vif_get_shift(struct ieee80211_vif *vif)
}
static inline int
-ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems)
+ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems, int i)
{
- int i, len = 0;
+ int len = 0;
if (!elems)
return 0;
+ else if (i < IEEE80211_MBSSID_ELEMS_ALL || i >= elems->cnt)
+ return -1;
+
+ if (i != IEEE80211_MBSSID_ELEMS_ALL)
+ return elems->elem[i].len;
for (i = 0; i < elems->cnt; i++)
len += elems->elem[i].len;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 0e4efc08c762..56eb1f32a03b 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -5041,12 +5041,18 @@ ieee80211_beacon_get_finish(struct ieee80211_hw *hw,
}
static void
-ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon)
+ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon,
+ int i)
{
- int i;
+ if (!beacon->mbssid_ies || !beacon->mbssid_ies->cnt ||
+ i < IEEE80211_MBSSID_ELEMS_ALL || i >= beacon->mbssid_ies->cnt)
+ return;
- if (!beacon->mbssid_ies)
+ if (i != IEEE80211_MBSSID_ELEMS_ALL) {
+ skb_put_data(skb, beacon->mbssid_ies->elem[i].data,
+ beacon->mbssid_ies->elem[i].len);
return;
+ }
for (i = 0; i < beacon->mbssid_ies->cnt; i++)
skb_put_data(skb, beacon->mbssid_ies->elem[i].data,
@@ -5059,7 +5065,8 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
struct ieee80211_mutable_offsets *offs,
bool is_template,
struct beacon_data *beacon,
- struct ieee80211_chanctx_conf *chanctx_conf)
+ struct ieee80211_chanctx_conf *chanctx_conf,
+ int ema_index)
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
@@ -5078,7 +5085,11 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
/* headroom, head length,
* tail length, maximum TIM length and multiple BSSID length
*/
- mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies);
+ mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies,
+ ema_index);
+ if (mbssid_len == -1)
+ return NULL;
+
skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
beacon->tail_len + 256 +
local->hw.extra_beacon_tailroom + mbssid_len);
@@ -5096,7 +5107,7 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0];
if (mbssid_len) {
- ieee80211_beacon_add_mbssid(skb, beacon);
+ ieee80211_beacon_add_mbssid(skb, beacon, ema_index);
offs->mbssid_off = skb->len - mbssid_len;
}
@@ -5115,11 +5126,47 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
return skb;
}
+static void
+ieee80211_beacon_get_ap_ema_list(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_mutable_offsets *offs,
+ bool is_template, struct beacon_data *beacon,
+ struct ieee80211_chanctx_conf *chanctx_conf,
+ struct ieee80211_ema_beacons **ema_beacons)
+{
+ struct ieee80211_ema_beacons *beacons;
+
+ *ema_beacons = NULL;
+ beacons = kzalloc(struct_size(beacons, bcn, beacon->mbssid_ies->cnt),
+ GFP_ATOMIC);
+ if (!beacons)
+ return;
+
+ for (beacons->cnt = 0;
+ beacons->cnt < beacon->mbssid_ies->cnt;
+ beacons->cnt++) {
+ beacons->bcn[beacons->cnt].skb =
+ ieee80211_beacon_get_ap(hw, vif,
+ &beacons->bcn[beacons->cnt].offs,
+ is_template, beacon,
+ chanctx_conf, beacons->cnt);
+ if (!beacons->bcn[beacons->cnt].skb)
+ break;
+ }
+
+ if (!beacons->cnt || beacons->cnt < beacon->mbssid_ies->cnt)
+ ieee80211_beacon_free_ema_list(beacons);
+ else
+ *ema_beacons = beacons;
+}
+
static struct sk_buff *
__ieee80211_beacon_get(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_mutable_offsets *offs,
- bool is_template)
+ bool is_template,
+ int ema_index,
+ struct ieee80211_ema_beacons **ema_beacons)
{
struct ieee80211_local *local = hw_to_local(hw);
struct beacon_data *beacon = NULL;
@@ -5145,8 +5192,15 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
if (!beacon)
goto out;
- skb = ieee80211_beacon_get_ap(hw, vif, offs, is_template,
- beacon, chanctx_conf);
+ if (ema_beacons)
+ ieee80211_beacon_get_ap_ema_list(hw, vif, offs,
+ is_template, beacon,
+ chanctx_conf,
+ ema_beacons);
+ else
+ skb = ieee80211_beacon_get_ap(hw, vif, offs,
+ is_template, beacon,
+ chanctx_conf, ema_index);
} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_hdr *hdr;
@@ -5232,16 +5286,50 @@ ieee80211_beacon_get_template(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_mutable_offsets *offs)
{
- return __ieee80211_beacon_get(hw, vif, offs, true);
+ return __ieee80211_beacon_get(hw, vif, offs, true,
+ IEEE80211_MBSSID_ELEMS_ALL, NULL);
}
EXPORT_SYMBOL(ieee80211_beacon_get_template);
+struct sk_buff *
+ieee80211_beacon_get_template_ema_index(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_mutable_offsets *offs,
+ u8 ema_index)
+{
+ return __ieee80211_beacon_get(hw, vif, offs, true, ema_index, NULL);
+}
+EXPORT_SYMBOL(ieee80211_beacon_get_template_ema_index);
+
+void ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *ema_beacons)
+{
+ u8 i;
+
+ for (i = 0; i < ema_beacons->cnt; i++)
+ kfree_skb(ema_beacons->bcn[i].skb);
+
+ kfree(ema_beacons);
+}
+EXPORT_SYMBOL(ieee80211_beacon_free_ema_list);
+
+struct ieee80211_ema_beacons *
+ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct ieee80211_ema_beacons *ema_beacons = NULL;
+ (void)__ieee80211_beacon_get(hw, vif, NULL, false, 0, &ema_beacons);
+ return ema_beacons;
+}
+EXPORT_SYMBOL(ieee80211_beacon_get_template_ema_list);
+
struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
u16 *tim_offset, u16 *tim_length)
{
struct ieee80211_mutable_offsets offs = {};
- struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false);
+ struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false,
+ IEEE80211_MBSSID_ELEMS_ALL,
+ NULL);
struct sk_buff *copy;
struct ieee80211_supported_band *sband;
int shift;
--
2.31.1
Move the configuration of struct ath11k_vif parameters rsnie_present,
and wpaie_present to a separate function.
Signed-off-by: Aloka Dixit <[email protected]>
---
drivers/net/wireless/ath/ath11k/mac.c | 41 ++++++++++++++++-----------
1 file changed, 24 insertions(+), 17 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 10d35cdfafdb..ff50341f1574 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -1350,28 +1350,14 @@ static int ath11k_mac_op_config(struct ieee80211_hw *hw, u32 changed)
return ret;
}
-static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
+static void ath11k_mac_setup_bcn_tmpl_vif_params(struct ath11k_vif *arvif,
+ struct sk_buff *bcn)
{
- struct ath11k *ar = arvif->ar;
- struct ath11k_base *ab = ar->ab;
- struct ieee80211_hw *hw = ar->hw;
- struct ieee80211_vif *vif = arvif->vif;
- struct ieee80211_mutable_offsets offs = {};
- struct sk_buff *bcn;
struct ieee80211_mgmt *mgmt;
u8 *ies;
- int ret;
-
- if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
- return 0;
-
- bcn = ieee80211_beacon_get_template(hw, vif, &offs);
- if (!bcn) {
- ath11k_warn(ab, "failed to get beacon template from mac80211\n");
- return -EPERM;
- }
ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
+ mgmt = (struct ieee80211_mgmt *)bcn->data;
ies += sizeof(mgmt->u.beacon);
if (cfg80211_find_ie(WLAN_EID_RSN, ies, (skb_tail_pointer(bcn) - ies)))
@@ -1385,7 +1371,28 @@ static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
arvif->wpaie_present = true;
else
arvif->wpaie_present = false;
+}
+
+static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
+{
+ struct ath11k *ar = arvif->ar;
+ struct ath11k_base *ab = ar->ab;
+ struct ieee80211_hw *hw = ar->hw;
+ struct ieee80211_vif *vif = arvif->vif;
+ struct ieee80211_mutable_offsets offs = {};
+ struct sk_buff *bcn;
+ int ret;
+
+ if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
+ return 0;
+
+ bcn = ieee80211_beacon_get_template(hw, vif, &offs);
+ if (!bcn) {
+ ath11k_warn(ab, "failed to get beacon template from mac80211\n");
+ return -EPERM;
+ }
+ ath11k_mac_setup_bcn_tmpl_vif_params(arvif, bcn);
ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
kfree_skb(bcn);
--
2.31.1
Add new field nontransmitting_vif_count in struct ath11k_vif which
keeps track of non-transmitting interfaces associated with a
transmitting interface when MBSSID is enabled.
The count is decremented when WMI vdev down is invoked and incremented
when WMI vdev up is invoked.
Use this field to set the profile index and total profile count during
WMI vdev up operation.
Signed-off-by: Aloka Dixit <[email protected]>
Co-developed-by: John Crispin <[email protected]>
Signed-off-by: John Crispin <[email protected]>
---
drivers/net/wireless/ath/ath11k/core.h | 2 ++
drivers/net/wireless/ath/ath11k/mac.c | 32 +++++++++++++++++++++++---
2 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index 95bca0b078b1..750dc9b46860 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -357,6 +357,8 @@ struct ath11k_vif {
#ifdef CONFIG_ATH11K_DEBUGFS
struct dentry *debugfs_twt;
#endif /* CONFIG_ATH11K_DEBUGFS */
+
+ u8 nontransmitting_vif_count;
};
struct ath11k_vif_iter {
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 32ddb80f4cec..10d35cdfafdb 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -1421,9 +1421,13 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
struct ieee80211_bss_conf *info)
{
struct ath11k *ar = arvif->ar;
+ struct ath11k_vif *tx_arvif = NULL;
int ret = 0;
struct vdev_up_params params = { 0 };
+ if (arvif->vif->mbssid_tx_vif)
+ tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv;
+
lockdep_assert_held(&arvif->ar->conf_mutex);
if (!info->enable_beacon) {
@@ -1433,6 +1437,9 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
arvif->vdev_id, ret);
arvif->is_up = false;
+ if (tx_arvif)
+ tx_arvif->nontransmitting_vif_count = 0;
+
return;
}
@@ -1453,6 +1460,13 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
params.vdev_id = arvif->vdev_id;
params.aid = arvif->aid;
params.bssid = arvif->bssid;
+ if (tx_arvif) {
+ params.tx_bssid = tx_arvif->bssid;
+ params.profile_idx = info->bssid_index;
+ if (params.profile_idx >= tx_arvif->nontransmitting_vif_count)
+ tx_arvif->nontransmitting_vif_count = params.profile_idx;
+ params.profile_count = tx_arvif->nontransmitting_vif_count;
+ }
ret = ath11k_wmi_vdev_up(arvif->ar, ¶ms);
if (ret) {
ath11k_warn(ar->ab, "failed to bring up vdev %d: %i\n",
@@ -2813,7 +2827,7 @@ static void ath11k_bss_disassoc(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct ath11k *ar = hw->priv;
- struct ath11k_vif *arvif = (void *)vif->drv_priv;
+ struct ath11k_vif *arvif = (void *)vif->drv_priv, *tx_arvif;
int ret;
lockdep_assert_held(&ar->conf_mutex);
@@ -2827,6 +2841,11 @@ static void ath11k_bss_disassoc(struct ieee80211_hw *hw,
arvif->vdev_id, ret);
arvif->is_up = false;
+ if (arvif->vif->mbssid_tx_vif) {
+ tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv;
+ if (tx_arvif != arvif)
+ tx_arvif->nontransmitting_vif_count--;
+ }
memset(&arvif->rekey_data, 0, sizeof(arvif->rekey_data));
@@ -3372,7 +3391,8 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
ret = ath11k_wmi_send_obss_color_collision_cfg_cmd(
ar, arvif->vdev_id, info->he_bss_color.color,
ATH11K_BSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS,
- info->he_bss_color.enabled);
+ arvif->vif->bss_conf.nontransmitted ?
+ 0 : info->he_bss_color.enabled);
if (ret)
ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n",
arvif->vdev_id, ret);
@@ -6952,7 +6972,7 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
int n_vifs)
{
struct ath11k_base *ab = ar->ab;
- struct ath11k_vif *arvif;
+ struct ath11k_vif *arvif, *tx_arvif;
int ret;
int i;
bool monitor_vif = false;
@@ -7011,6 +7031,12 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
params.vdev_id = arvif->vdev_id;
params.aid = arvif->aid;
params.bssid = arvif->bssid;
+ if (arvif->vif->mbssid_tx_vif) {
+ tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv;
+ params.tx_bssid = tx_arvif->bssid;
+ params.profile_idx = arvif->vif->bss_conf.bssid_index;
+ params.profile_count = tx_arvif->nontransmitting_vif_count;
+ }
ret = ath11k_wmi_vdev_up(arvif->ar, ¶ms);
if (ret) {
ath11k_warn(ab, "failed to bring vdev up %d: %d\n",
--
2.31.1
Set rsnie_present and wpaie_present fields for the non-transmitting
interfaces when MBSSID is enabled.
Signed-off-by: Aloka Dixit <[email protected]>
---
drivers/net/wireless/ath/ath11k/mac.c | 99 ++++++++++++++++++++++++++-
1 file changed, 98 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 4ead94554724..cee505a1bada 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -1373,6 +1373,89 @@ static void ath11k_mac_setup_bcn_tmpl_vif_params(struct ath11k_vif *arvif,
arvif->wpaie_present = false;
}
+static void ath11k_mac_setup_bcn_tmpl_nontx_vif_rsnie(struct ath11k_vif *arvif,
+ bool tx_arvif_rsnie_present,
+ const u8 *profile,
+ u8 profile_len)
+{
+ if (cfg80211_find_ie(WLAN_EID_RSN, profile, profile_len)) {
+ arvif->rsnie_present = true;
+ } else if (tx_arvif_rsnie_present) {
+ int i;
+ u8 nie_len;
+ const u8 *nie = cfg80211_find_ext_ie(WLAN_EID_EXT_NON_INHERITANCE,
+ profile, profile_len);
+ if (!nie)
+ return;
+
+ nie_len = nie[1];
+ nie += 2;
+ for (i = 0; i < nie_len; i++) {
+ if (nie[i] == WLAN_EID_RSN) {
+ arvif->rsnie_present = false;
+ break;
+ }
+ }
+ }
+}
+
+static bool ath11k_mac_setup_bcn_tmpl_nontx_vif_params(struct ath11k_vif *tx_arvif,
+ struct ath11k_vif *arvif,
+ struct sk_buff *bcn)
+{
+ struct ieee80211_mgmt *mgmt;
+ const u8 *ies, *profile, *next_profile;
+ int ies_len;
+
+ if (arvif == tx_arvif)
+ return true;
+
+ arvif->rsnie_present = tx_arvif->rsnie_present;
+
+ ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
+ mgmt = (struct ieee80211_mgmt *)bcn->data;
+ ies += sizeof(mgmt->u.beacon);
+ ies_len = skb_tail_pointer(bcn) - ies;
+
+ ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ies, ies_len);
+
+ while (ies) {
+ u8 mbssid_len;
+
+ ies_len -= (2 + ies[1]);
+ mbssid_len = ies[1] - 1;
+ profile = &ies[3];
+
+ while (mbssid_len) {
+ u8 profile_len;
+
+ profile_len = profile[1];
+ next_profile = profile + (2 + profile_len);
+ mbssid_len -= (2 + profile_len);
+
+ profile += 2;
+ profile_len -= (2 + profile[1]);
+ profile += (2 + profile[1]); /* nontx capabilities */
+ profile_len -= (2 + profile[1]);
+ profile += (2 + profile[1]); /* SSID */
+ if (profile[2] == arvif->vif->bss_conf.bssid_index) {
+ profile_len -= 5;
+ profile = profile + 5;
+ ath11k_mac_setup_bcn_tmpl_nontx_vif_rsnie(arvif,
+ tx_arvif->rsnie_present,
+ profile,
+ profile_len);
+ return true;
+ }
+ profile = next_profile;
+ }
+ ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, profile,
+ ies_len);
+ }
+
+ return false;
+}
+
static int __ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif,
struct sk_buff *bcn,
struct ieee80211_mutable_offsets offs,
@@ -1399,6 +1482,7 @@ static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
struct ieee80211_ema_beacons *beacons;
u8 i = 0;
int ret = 0;
+ bool found_vdev = false;
if (!arvif->vif->mbssid_tx_vif)
return -1;
@@ -1412,11 +1496,21 @@ static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
return -EPERM;
}
- if (tx_arvif == arvif)
+ if (tx_arvif == arvif) {
ath11k_mac_setup_bcn_tmpl_vif_params(tx_arvif,
beacons->bcn[0].skb);
+ found_vdev = true;
+ } else {
+ arvif->wpaie_present = tx_arvif->wpaie_present;
+ }
for (i = 0; i < beacons->cnt; i++) {
+ if (!found_vdev)
+ found_vdev =
+ ath11k_mac_setup_bcn_tmpl_nontx_vif_params(tx_arvif,
+ arvif,
+ beacons->bcn[i].skb);
+
ret = __ath11k_mac_setup_bcn_tmpl(tx_arvif, beacons->bcn[i].skb,
beacons->bcn[i].offs,
i, beacons->cnt);
@@ -1452,6 +1546,9 @@ static int ath11k_mac_setup_bcn_tmpl_non_ema(struct ath11k_vif *arvif)
if (tx_arvif == arvif)
ath11k_mac_setup_bcn_tmpl_vif_params(tx_arvif, bcn);
+ else
+ (void)ath11k_mac_setup_bcn_tmpl_nontx_vif_params(tx_arvif,
+ arvif, bcn);
ret = __ath11k_mac_setup_bcn_tmpl(tx_arvif, bcn, offs, 0, 0);
if (ret)
--
2.31.1
Include an instance of the structure instead of individual parameters
as input to ath11k_wmi_vdev_up().
Signed-off-by: Aloka Dixit <[email protected]>
Co-developed-by: John Crispin <[email protected]>
Signed-off-by: John Crispin <[email protected]>
---
drivers/net/wireless/ath/ath11k/mac.c | 31 +++++++++++++++++++++------
drivers/net/wireless/ath/ath11k/wmi.c | 15 +++++++------
drivers/net/wireless/ath/ath11k/wmi.h | 16 ++++++++++----
3 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 8f629e54a53d..32ddb80f4cec 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -920,6 +920,7 @@ static int ath11k_mac_monitor_vdev_start(struct ath11k *ar, int vdev_id,
struct ieee80211_channel *channel;
struct wmi_vdev_start_req_arg arg = {};
int ret;
+ struct vdev_up_params params = { 0 };
lockdep_assert_held(&ar->conf_mutex);
@@ -960,7 +961,9 @@ static int ath11k_mac_monitor_vdev_start(struct ath11k *ar, int vdev_id,
return ret;
}
- ret = ath11k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
+ params.vdev_id = vdev_id,
+ params.bssid = ar->mac_addr,
+ ret = ath11k_wmi_vdev_up(ar, ¶ms);
if (ret) {
ath11k_warn(ar->ab, "failed to put up monitor vdev %i: %d\n",
vdev_id, ret);
@@ -1419,6 +1422,7 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
{
struct ath11k *ar = arvif->ar;
int ret = 0;
+ struct vdev_up_params params = { 0 };
lockdep_assert_held(&arvif->ar->conf_mutex);
@@ -1446,8 +1450,10 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
ether_addr_copy(arvif->bssid, info->bssid);
- ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
- arvif->bssid);
+ params.vdev_id = arvif->vdev_id;
+ params.aid = arvif->aid;
+ params.bssid = arvif->bssid;
+ ret = ath11k_wmi_vdev_up(arvif->ar, ¶ms);
if (ret) {
ath11k_warn(ar->ab, "failed to bring up vdev %d: %i\n",
arvif->vdev_id, ret);
@@ -2704,6 +2710,7 @@ static void ath11k_bss_assoc(struct ieee80211_hw *hw,
struct ath11k_peer *peer;
bool is_auth = false;
int ret;
+ struct vdev_up_params params = { 0 };
lockdep_assert_held(&ar->conf_mutex);
@@ -2752,7 +2759,10 @@ 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);
+ params.vdev_id = arvif->vdev_id;
+ params.aid = arvif->aid;
+ params.bssid = arvif->bssid;
+ ret = ath11k_wmi_vdev_up(ar, ¶ms);
if (ret) {
ath11k_warn(ar->ab, "failed to set vdev %d up: %d\n",
arvif->vdev_id, ret);
@@ -6956,6 +6966,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 = { 0 };
+
arvif = (void *)vifs[i].vif->drv_priv;
if (WARN_ON(!arvif->is_started))
@@ -6996,8 +7008,10 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n",
ret);
- ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
- arvif->bssid);
+ params.vdev_id = arvif->vdev_id;
+ params.aid = arvif->aid;
+ params.bssid = arvif->bssid;
+ ret = ath11k_wmi_vdev_up(arvif->ar, ¶ms);
if (ret) {
ath11k_warn(ab, "failed to bring vdev up %d: %d\n",
arvif->vdev_id, ret);
@@ -7089,6 +7103,7 @@ static int ath11k_start_vdev_delay(struct ieee80211_hw *hw,
struct ath11k_base *ab = ar->ab;
struct ath11k_vif *arvif = (void *)vif->drv_priv;
int ret;
+ struct vdev_up_params params = { 0 };
if (WARN_ON(arvif->is_started))
return -EBUSY;
@@ -7115,7 +7130,9 @@ static int ath11k_start_vdev_delay(struct ieee80211_hw *hw,
}
if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
- ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, 0, ar->mac_addr);
+ params.vdev_id = arvif->vdev_id,
+ params.bssid = ar->mac_addr,
+ ret = ath11k_wmi_vdev_up(ar, ¶ms);
if (ret) {
ath11k_warn(ab, "failed put monitor up: %d\n", ret);
return ret;
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index d0716f6208b2..fa443a2646b5 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -996,7 +996,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;
@@ -1011,10 +1011,13 @@ 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;
-
- ether_addr_copy(cmd->vdev_bssid.addr, bssid);
+ cmd->vdev_id = params->vdev_id;
+ cmd->vdev_assoc_id = params->aid;
+ ether_addr_copy(cmd->vdev_bssid.addr, params->bssid);
+ cmd->profile_idx = params->profile_idx;
+ cmd->profile_count = params->profile_count;
+ if (params->tx_bssid)
+ ether_addr_copy(cmd->tx_vdev_bssid.addr, params->tx_bssid);
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_UP_CMDID);
if (ret) {
@@ -1024,7 +1027,7 @@ 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);
+ params->vdev_id, params->aid, params->bssid);
return ret;
}
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index c572774b9659..fa46fb6ef1ad 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -2611,14 +2611,23 @@ struct wmi_vdev_delete_cmd {
u32 vdev_id;
} __packed;
+struct vdev_up_params {
+ u32 vdev_id;
+ u16 aid;
+ const u8 *bssid;
+ u32 profile_idx;
+ u32 profile_count;
+ u8 *tx_bssid;
+};
+
struct wmi_vdev_up_cmd {
u32 tlv_header;
u32 vdev_id;
u32 vdev_assoc_id;
struct wmi_mac_addr vdev_bssid;
- struct wmi_mac_addr trans_bssid;
+ struct wmi_mac_addr tx_vdev_bssid;
u32 profile_idx;
- u32 profile_num;
+ u32 profile_count;
} __packed;
struct wmi_vdev_stop_cmd {
@@ -5998,8 +6007,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.31.1
Add new function ath11k_mac_setup_bcn_tmpl_ema() which invokes the new
API provided by MAC80211 to retrieve EMA beacons. For non EMA APs,
ath11k_mac_setup_bcn_tmpl_legacy() is added which maintains the current
functionality.
Signed-off-by: Aloka Dixit <[email protected]>
Co-developed-by: John Crispin <[email protected]>
Signed-off-by: John Crispin <[email protected]>
---
drivers/net/wireless/ath/ath11k/mac.c | 103 ++++++++++++++++++++++----
drivers/net/wireless/ath/ath11k/wmi.c | 4 +-
drivers/net/wireless/ath/ath11k/wmi.h | 12 ++-
3 files changed, 104 insertions(+), 15 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index ff50341f1574..4ead94554724 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -1373,37 +1373,114 @@ static void ath11k_mac_setup_bcn_tmpl_vif_params(struct ath11k_vif *arvif,
arvif->wpaie_present = false;
}
-static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
+static int __ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif,
+ struct sk_buff *bcn,
+ struct ieee80211_mutable_offsets offs,
+ int ema_idx, int ema_cnt)
{
struct ath11k *ar = arvif->ar;
- struct ath11k_base *ab = ar->ab;
- struct ieee80211_hw *hw = ar->hw;
- struct ieee80211_vif *vif = arvif->vif;
+ u32 ema_param = 0;
+
+ if (ema_cnt) {
+ ema_param = (ema_cnt << WMI_BEACON_EMA_PARAM_PERIODICITY_SHIFT);
+ ema_param |= (ema_idx << WMI_BEACON_EMA_PARAM_TMPL_IDX_SHIFT);
+ ema_param |= ((!ema_idx ? 1 : 0) <<
+ WMI_BEACON_EMA_PARAM_FIRST_TMPL_SHIFT);
+ ema_param |= ((ema_idx + 1 == ema_cnt ? 1 : 0) <<
+ WMI_BEACON_EMA_PARAM_LAST_TMPL_SHIFT);
+ }
+
+ return ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, ema_param);
+}
+
+static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
+{
+ struct ath11k_vif *tx_arvif;
+ struct ieee80211_ema_beacons *beacons;
+ u8 i = 0;
+ int ret = 0;
+
+ if (!arvif->vif->mbssid_tx_vif)
+ return -1;
+
+ tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv;
+ beacons = ieee80211_beacon_get_template_ema_list(tx_arvif->ar->hw,
+ tx_arvif->vif);
+ if (!beacons || !beacons->cnt) {
+ ath11k_warn(arvif->ar->ab,
+ "failed to get ema beacon templates from mac80211\n");
+ return -EPERM;
+ }
+
+ if (tx_arvif == arvif)
+ ath11k_mac_setup_bcn_tmpl_vif_params(tx_arvif,
+ beacons->bcn[0].skb);
+
+ for (i = 0; i < beacons->cnt; i++) {
+ ret = __ath11k_mac_setup_bcn_tmpl(tx_arvif, beacons->bcn[i].skb,
+ beacons->bcn[i].offs,
+ i, beacons->cnt);
+ if (ret) {
+ ath11k_warn(arvif->ar->ab,
+ "failed to set ema beacon template id %i error %d\n",
+ i, ret);
+ break;
+ }
+ }
+
+ ieee80211_beacon_free_ema_list(beacons);
+ return ret;
+}
+
+static int ath11k_mac_setup_bcn_tmpl_non_ema(struct ath11k_vif *arvif)
+{
+ struct ath11k_vif *tx_arvif = arvif;
struct ieee80211_mutable_offsets offs = {};
struct sk_buff *bcn;
int ret;
- if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
- return 0;
+ if (arvif->vif->mbssid_tx_vif)
+ tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv;
- bcn = ieee80211_beacon_get_template(hw, vif, &offs);
+ bcn = ieee80211_beacon_get_template(tx_arvif->ar->hw, tx_arvif->vif,
+ &offs);
if (!bcn) {
- ath11k_warn(ab, "failed to get beacon template from mac80211\n");
+ ath11k_warn(arvif->ar->ab,
+ "failed to get beacon template from mac80211\n");
return -EPERM;
}
- ath11k_mac_setup_bcn_tmpl_vif_params(arvif, bcn);
- ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
-
- kfree_skb(bcn);
+ if (tx_arvif == arvif)
+ ath11k_mac_setup_bcn_tmpl_vif_params(tx_arvif, bcn);
+ ret = __ath11k_mac_setup_bcn_tmpl(tx_arvif, bcn, offs, 0, 0);
if (ret)
- ath11k_warn(ab, "failed to submit beacon template command: %d\n",
+ ath11k_warn(arvif->ar->ab,
+ "failed to submit beacon template command: %d\n",
ret);
+ kfree_skb(bcn);
return ret;
}
+static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
+{
+ struct ieee80211_vif *vif = arvif->vif;
+
+ if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
+ return 0;
+
+ if (vif->mbssid_tx_vif &&
+ arvif != (void *)vif->mbssid_tx_vif->drv_priv &&
+ arvif->is_up)
+ return 0;
+
+ if (vif->bss_conf.ema_ap)
+ return ath11k_mac_setup_bcn_tmpl_ema(arvif);
+ else
+ return ath11k_mac_setup_bcn_tmpl_non_ema(arvif);
+}
+
void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif)
{
struct ieee80211_vif *vif = arvif->vif;
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index fa443a2646b5..362c516db07f 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -1676,7 +1676,7 @@ int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k *ar,
int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
struct ieee80211_mutable_offsets *offs,
- struct sk_buff *bcn)
+ struct sk_buff *bcn, u32 ema_params)
{
struct ath11k_pdev_wmi *wmi = ar->wmi;
struct wmi_bcn_tmpl_cmd *cmd;
@@ -1714,6 +1714,8 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
}
cmd->buf_len = bcn->len;
+ cmd->mbssid_ie_offset = offs->mbssid_off;
+ cmd->ema_params = ema_params;
ptr = skb->data + sizeof(*cmd);
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index fa46fb6ef1ad..f66131d915c8 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -3554,6 +3554,11 @@ struct wmi_get_pdev_temperature_cmd {
#define WMI_BEACON_TX_BUFFER_SIZE 512
+#define WMI_BEACON_EMA_PARAM_PERIODICITY_SHIFT 0
+#define WMI_BEACON_EMA_PARAM_TMPL_IDX_SHIFT 8
+#define WMI_BEACON_EMA_PARAM_FIRST_TMPL_SHIFT 16
+#define WMI_BEACON_EMA_PARAM_LAST_TMPL_SHIFT 24
+
struct wmi_bcn_tmpl_cmd {
u32 tlv_header;
u32 vdev_id;
@@ -3564,6 +3569,11 @@ struct wmi_bcn_tmpl_cmd {
u32 csa_event_bitmap;
u32 mbssid_ie_offset;
u32 esp_ie_offset;
+ u32 csc_switch_count_offset;
+ u32 csc_event_bitmap;
+ u32 mu_edca_ie_offset;
+ u32 feature_enable_bitmap;
+ u32 ema_params;
} __packed;
struct wmi_key_seq_counter {
@@ -6005,7 +6015,7 @@ int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
struct sk_buff *frame);
int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
struct ieee80211_mutable_offsets *offs,
- struct sk_buff *bcn);
+ struct sk_buff *bcn, u32 ema_param);
int ath11k_wmi_vdev_down(struct ath11k *ar, u8 vdev_id);
int ath11k_wmi_vdev_up(struct ath11k *ar, struct vdev_up_params *params);
int ath11k_wmi_vdev_stop(struct ath11k *ar, u8 vdev_id);
--
2.31.1
On 5/22/2022 11:01 PM, Aloka Dixit wrote:
> Include an instance of the structure instead of individual parameters
> as input to ath11k_wmi_vdev_up().
>
> Signed-off-by: Aloka Dixit <[email protected]>
> Co-developed-by: John Crispin <[email protected]>
> Signed-off-by: John Crispin <[email protected]>
> ---
> drivers/net/wireless/ath/ath11k/mac.c | 31 +++++++++++++++++++++------
> drivers/net/wireless/ath/ath11k/wmi.c | 15 +++++++------
> drivers/net/wireless/ath/ath11k/wmi.h | 16 ++++++++++----
> 3 files changed, 45 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
> index 8f629e54a53d..32ddb80f4cec 100644
> --- a/drivers/net/wireless/ath/ath11k/mac.c
> +++ b/drivers/net/wireless/ath/ath11k/mac.c
> @@ -920,6 +920,7 @@ static int ath11k_mac_monitor_vdev_start(struct ath11k *ar, int vdev_id,
> struct ieee80211_channel *channel;
> struct wmi_vdev_start_req_arg arg = {};
> int ret;
> + struct vdev_up_params params = { 0 };
>
> lockdep_assert_held(&ar->conf_mutex);
>
> @@ -960,7 +961,9 @@ static int ath11k_mac_monitor_vdev_start(struct ath11k *ar, int vdev_id,
> return ret;
> }
>
> - ret = ath11k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
> + params.vdev_id = vdev_id,
> + params.bssid = ar->mac_addr,
> + ret = ath11k_wmi_vdev_up(ar, ¶ms);
> if (ret) {
> ath11k_warn(ar->ab, "failed to put up monitor vdev %i: %d\n",
> vdev_id, ret);
> @@ -1419,6 +1422,7 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
> {
> struct ath11k *ar = arvif->ar;
> int ret = 0;
> + struct vdev_up_params params = { 0 };
>
> lockdep_assert_held(&arvif->ar->conf_mutex);
>
> @@ -1446,8 +1450,10 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
>
> ether_addr_copy(arvif->bssid, info->bssid);
>
> - ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
> - arvif->bssid);
> + params.vdev_id = arvif->vdev_id;
> + params.aid = arvif->aid;
> + params.bssid = arvif->bssid;
> + ret = ath11k_wmi_vdev_up(arvif->ar, ¶ms);
> if (ret) {
> ath11k_warn(ar->ab, "failed to bring up vdev %d: %i\n",
> arvif->vdev_id, ret);
> @@ -2704,6 +2710,7 @@ static void ath11k_bss_assoc(struct ieee80211_hw *hw,
> struct ath11k_peer *peer;
> bool is_auth = false;
> int ret;
> + struct vdev_up_params params = { 0 };
>
> lockdep_assert_held(&ar->conf_mutex);
>
> @@ -2752,7 +2759,10 @@ 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);
> + params.vdev_id = arvif->vdev_id;
> + params.aid = arvif->aid;
> + params.bssid = arvif->bssid;
> + ret = ath11k_wmi_vdev_up(ar, ¶ms);
> if (ret) {
> ath11k_warn(ar->ab, "failed to set vdev %d up: %d\n",
> arvif->vdev_id, ret);
> @@ -6956,6 +6966,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 = { 0 };
> +
> arvif = (void *)vifs[i].vif->drv_priv;
>
> if (WARN_ON(!arvif->is_started))
> @@ -6996,8 +7008,10 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
> ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n",
> ret);
>
> - ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
> - arvif->bssid);
> + params.vdev_id = arvif->vdev_id;
> + params.aid = arvif->aid;
> + params.bssid = arvif->bssid;
> + ret = ath11k_wmi_vdev_up(arvif->ar, ¶ms);
> if (ret) {
> ath11k_warn(ab, "failed to bring vdev up %d: %d\n",
> arvif->vdev_id, ret);
> @@ -7089,6 +7103,7 @@ static int ath11k_start_vdev_delay(struct ieee80211_hw *hw,
> struct ath11k_base *ab = ar->ab;
> struct ath11k_vif *arvif = (void *)vif->drv_priv;
> int ret;
> + struct vdev_up_params params = { 0 };
>
> if (WARN_ON(arvif->is_started))
> return -EBUSY;
> @@ -7115,7 +7130,9 @@ static int ath11k_start_vdev_delay(struct ieee80211_hw *hw,
> }
>
> if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
> - ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, 0, ar->mac_addr);
> + params.vdev_id = arvif->vdev_id,
> + params.bssid = ar->mac_addr,
> + ret = ath11k_wmi_vdev_up(ar, ¶ms);
> if (ret) {
> ath11k_warn(ab, "failed put monitor up: %d\n", ret);
> return ret;
> diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
> index d0716f6208b2..fa443a2646b5 100644
> --- a/drivers/net/wireless/ath/ath11k/wmi.c
> +++ b/drivers/net/wireless/ath/ath11k/wmi.c
> @@ -996,7 +996,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;
> @@ -1011,10 +1011,13 @@ 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;
> -
> - ether_addr_copy(cmd->vdev_bssid.addr, bssid);
> + cmd->vdev_id = params->vdev_id;
> + cmd->vdev_assoc_id = params->aid;
> + ether_addr_copy(cmd->vdev_bssid.addr, params->bssid);
> + cmd->profile_idx = params->profile_idx;
> + cmd->profile_count = params->profile_count;
> + if (params->tx_bssid)
> + ether_addr_copy(cmd->tx_vdev_bssid.addr, params->tx_bssid);
>
> ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_UP_CMDID);
> if (ret) {
> @@ -1024,7 +1027,7 @@ 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);
> + params->vdev_id, params->aid, params->bssid);
>
> return ret;
> }
> diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
> index c572774b9659..fa46fb6ef1ad 100644
> --- a/drivers/net/wireless/ath/ath11k/wmi.h
> +++ b/drivers/net/wireless/ath/ath11k/wmi.h
> @@ -2611,14 +2611,23 @@ struct wmi_vdev_delete_cmd {
> u32 vdev_id;
> } __packed;
>
> +struct vdev_up_params {
> + u32 vdev_id;
> + u16 aid;
> + const u8 *bssid;
imo the above 3 are the only things that should be handled by this
patch. you should only be converting the existing params to the struct:
u32 vdev_id, u32 aid, const u8 *bssid
(why did aid change from u32 in the param list to u16 in the struct?)
the members below should be added later when the associated
functionality is added to the callers
> + u32 profile_idx;
> + u32 profile_count;
> + u8 *tx_bssid;
> +};
> +
> struct wmi_vdev_up_cmd {
> u32 tlv_header;
> u32 vdev_id;
> u32 vdev_assoc_id;
> struct wmi_mac_addr vdev_bssid;
> - struct wmi_mac_addr trans_bssid;
> + struct wmi_mac_addr tx_vdev_bssid;
> u32 profile_idx;
> - u32 profile_num;
> + u32 profile_count;
> } __packed;
imo the above changes should not be in this patch. if you want to rename
members, do it in a separate patch for that purpose
>
> struct wmi_vdev_stop_cmd {
> @@ -5998,8 +6007,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);
so to reiterate IMO you should have:
one patch that is just moving the existing params into a struct
one (or more) patch that adds support for the new params
one patch that renames the wmi_vdev_up_cmd members
let each patch do one and only one thing
>
> +++ b/include/net/mac80211.h
> @@ -5050,6 +5050,83 @@ ieee80211_beacon_get_template(struct ieee80211_hw *hw,
> struct ieee80211_vif *vif,
> struct ieee80211_mutable_offsets *offs);
>
> +/**
> + * This macro should be used to get total length for all MBSSID elements
> + * in the beacon, and also to generate a single beacon template with
> + * all MBSSID elements.
> + */
> +#define IEEE80211_MBSSID_ELEMS_ALL -1
Not sure where the driver should use this? Why is it defined in the
driver API?
> + * @ema_index: index of the beacon in the EMA set, should be more than
> + * IEEE80211_MBSSID_ELEMS_ALL otherwise the set/get functions include all
> + * MBSSID elements in a single beacon template.
The parameter is a u8 so it cannot be negative anyway ...?
> +struct sk_buff *
> +ieee80211_beacon_get_template_ema_index(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif,
> + struct ieee80211_mutable_offsets *offs,
> + u8 ema_index);
here ^^
> static inline int
> -ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems)
> +ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems, int i)
> {
> - int i, len = 0;
> + int len = 0;
>
> if (!elems)
> return 0;
> + else if (i < IEEE80211_MBSSID_ELEMS_ALL || i >= elems->cnt)
> + return -1;
-1 is a strange return value (it means -EPERM but you didn't say it);
maybe use -EINVAL?
> @@ -5059,7 +5065,8 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
> struct ieee80211_mutable_offsets *offs,
> bool is_template,
> struct beacon_data *beacon,
> - struct ieee80211_chanctx_conf *chanctx_conf)
> + struct ieee80211_chanctx_conf *chanctx_conf,
> + int ema_index)
A lot of this stuff is now conflicting with MLO work, so also needs a
rebase.
> - mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies);
> + mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies,
> + ema_index);
> + if (mbssid_len == -1)
< 0 then here
> +static void
> +ieee80211_beacon_get_ap_ema_list(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif,
> + struct ieee80211_mutable_offsets *offs,
> + bool is_template, struct beacon_data *beacon,
> + struct ieee80211_chanctx_conf *chanctx_conf,
> + struct ieee80211_ema_beacons **ema_beacons)
The API here is weird, why not *return* what goes into *ema_beacons?
> +struct ieee80211_ema_beacons *
> +ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif)
> +{
> + struct ieee80211_ema_beacons *ema_beacons = NULL;
> + (void)__ieee80211_beacon_get(hw, vif, NULL, false, 0, &ema_beacons);
> + return ema_beacons;
couple of blank lines would be nice, and maybe check the return value
and WARN_ON() it not being NULL? It should be NULL in this case, I
think?
johannes