ath11k: pass multiple bssid info to FW when a new vdev is created
authorJohn Crispin <john@phrozen.org>
Sat, 9 May 2020 08:39:37 +0000 (10:39 +0200)
committerJohn Crispin <john@phrozen.org>
Sat, 6 Jun 2020 09:21:34 +0000 (11:21 +0200)
When we use multiple bssid the FW needs to know if the bssid is
non/transmitting and what the vdev_id of the parent is. This patch adds
the required code to achieve this.

Signed-off-by: John Crispin <john@phrozen.org>
drivers/net/wireless/ath/ath11k/mac.c
drivers/net/wireless/ath/ath11k/wmi.c
drivers/net/wireless/ath/ath11k/wmi.h

index 2836a0f197ab0112478a8453cf073dd9ac5f0087..a5c5e4534a12bfb9be38911f24dc3fad9be7246b 100644 (file)
@@ -692,6 +692,7 @@ static int ath11k_mac_op_config(struct ieee80211_hw *hw, u32 changed)
 
 static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
 {
+       struct ieee80211_vif *parent;
        struct ath11k *ar = arvif->ar;
        struct ath11k_base *ab = ar->ab;
        struct ieee80211_hw *hw = ar->hw;
@@ -4065,17 +4066,36 @@ static void ath11k_mac_op_stop(struct ieee80211_hw *hw)
        atomic_set(&ar->num_pending_mgmt_tx, 0);
 }
 
-static void
+static int
 ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,
                                    struct vdev_create_params *params)
 {
        struct ath11k *ar = arvif->ar;
        struct ath11k_pdev *pdev = ar->pdev;
+       struct ieee80211_vif *parent;
 
        params->if_id = arvif->vdev_id;
        params->type = arvif->vdev_type;
        params->subtype = arvif->vdev_subtype;
        params->pdev_id = pdev->pdev_id;
+       params->vdevid_trans = 0;
+       switch (ieee80211_get_multi_bssid_mode(arvif->vif)) {
+       case NL80211_MULTIPLE_BSSID_TRANSMITTED:
+               params->flags = WMI_HOST_VDEV_FLAGS_TRANSMIT_AP;
+               break;
+       case NL80211_MULTIPLE_BSSID_NON_TRANSMITTED:
+               params->flags = WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP;
+               parent = ieee80211_get_multi_bssid_parent(arvif->vif);
+               if (!parent)
+                       return -ENOENT;
+               if (ar->hw->wiphy != ieee80211_vif_to_wdev(parent)->wiphy)
+                       return -EINVAL;
+               params->vdevid_trans = ath11k_vif_to_arvif(parent)->vdev_id;
+               break;
+       default:
+               params->flags = WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP;
+               break;
+       }
 
        if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) {
                params->chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains;
@@ -4085,6 +4105,7 @@ ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,
                params->chains[NL80211_BAND_5GHZ].tx = ar->num_tx_chains;
                params->chains[NL80211_BAND_5GHZ].rx = ar->num_rx_chains;
        }
+       return 0;
 }
 
 static u32
@@ -4234,7 +4255,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) {
index c2a97237768740656e833187c242b4d76f4ab049..90c68d1d9087b9c9297dd3b1dcf7c920a8b25e3f 100644 (file)
@@ -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);
index b9f3e559ced77333e93698e58ef3000b28af6aa0..fa6665584cafc4660b5adc94103060d76a1b6989 100644 (file)
@@ -107,6 +107,12 @@ enum {
        WMI_HOST_WLAN_2G_5G_CAP = 0x3,
 };
 
+enum {
+       WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP       = 1,
+       WMI_HOST_VDEV_FLAGS_TRANSMIT_AP         = 2,
+       WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP     = 4,
+};
+
 /*
  * wmi command groups.
  */
@@ -2419,6 +2425,8 @@ struct vdev_create_params {
                u8 rx;
        } chains[NUM_NL80211_BANDS];
        u32 pdev_id;
+       u32 flags;
+       u32 vdevid_trans;
 };
 
 struct wmi_vdev_create_cmd {
@@ -2429,6 +2437,8 @@ struct wmi_vdev_create_cmd {
        struct wmi_mac_addr vdev_macaddr;
        u32 num_cfg_txrx_streams;
        u32 pdev_id;
+       u32 flags;
+       u32 vdevid_trans;
 } __packed;
 
 struct wmi_vdev_txrx_streams {