ath10k: enable multi-channel on supported devices
authorMichal Kazior <michal.kazior@tieto.com>
Tue, 31 Mar 2015 10:26:25 +0000 (10:26 +0000)
committerKalle Valo <kvalo@qca.qualcomm.com>
Wed, 1 Apr 2015 17:31:15 +0000 (20:31 +0300)
This effectively enables multi-channel operation
on qca6174 WLAN.RM.2.0-00073 (and possibly any
newer firmware release for qca6174).

This adds appopriate interface combinations and
initializes firmware channel scheduler.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath10k/mac.c

index 2da66ca635fd9e88222e78ccc27b0281ff84f219..e455dabedd1a26ebd69033561295a937edff663d 100644 (file)
@@ -3735,6 +3735,15 @@ static int ath10k_start(struct ieee80211_hw *hw)
                goto err_core_stop;
        }
 
+       if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
+               ret = ath10k_wmi_adaptive_qcs(ar, true);
+               if (ret) {
+                       ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
+                                   ret);
+                       goto err_core_stop;
+               }
+       }
+
        if (ar->cfg_tx_chainmask)
                __ath10k_set_antenna(ar, ar->cfg_tx_chainmask,
                                     ar->cfg_rx_chainmask);
@@ -6487,6 +6496,64 @@ static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
        },
 };
 
+static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
+       {
+               .max = 2,
+               .types = BIT(NL80211_IFTYPE_STATION) |
+                        BIT(NL80211_IFTYPE_AP) |
+                        BIT(NL80211_IFTYPE_P2P_CLIENT) |
+                        BIT(NL80211_IFTYPE_P2P_GO),
+       },
+       {
+               .max = 1,
+               .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
+       },
+};
+
+static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
+       {
+               .max = 1,
+               .types = BIT(NL80211_IFTYPE_STATION),
+       },
+       {
+               .max = 1,
+               .types = BIT(NL80211_IFTYPE_ADHOC),
+       },
+};
+
+/* FIXME: This is not thouroughly tested. These combinations may over- or
+ * underestimate hw/fw capabilities.
+ */
+static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
+       {
+               .limits = ath10k_tlv_if_limit,
+               .num_different_channels = 1,
+               .max_interfaces = 3,
+               .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
+       },
+       {
+               .limits = ath10k_tlv_if_limit_ibss,
+               .num_different_channels = 1,
+               .max_interfaces = 2,
+               .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
+       },
+};
+
+static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
+       {
+               .limits = ath10k_tlv_if_limit,
+               .num_different_channels = 2,
+               .max_interfaces = 3,
+               .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
+       },
+       {
+               .limits = ath10k_tlv_if_limit_ibss,
+               .num_different_channels = 1,
+               .max_interfaces = 2,
+               .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
+       },
+};
+
 static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
 {
        struct ieee80211_sta_vht_cap vht_cap = {0};
@@ -6781,12 +6848,24 @@ int ath10k_mac_register(struct ath10k *ar)
 
        switch (ar->wmi.op_version) {
        case ATH10K_FW_WMI_OP_VERSION_MAIN:
-       case ATH10K_FW_WMI_OP_VERSION_TLV:
                ar->hw->wiphy->iface_combinations = ath10k_if_comb;
                ar->hw->wiphy->n_iface_combinations =
                        ARRAY_SIZE(ath10k_if_comb);
                ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
                break;
+       case ATH10K_FW_WMI_OP_VERSION_TLV:
+               if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
+                       ar->hw->wiphy->iface_combinations =
+                               ath10k_tlv_qcs_if_comb;
+                       ar->hw->wiphy->n_iface_combinations =
+                               ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
+               } else {
+                       ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
+                       ar->hw->wiphy->n_iface_combinations =
+                               ARRAY_SIZE(ath10k_tlv_if_comb);
+               }
+               ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
+               break;
        case ATH10K_FW_WMI_OP_VERSION_10_1:
        case ATH10K_FW_WMI_OP_VERSION_10_2:
        case ATH10K_FW_WMI_OP_VERSION_10_2_4: