ath10k: enable adaptive CCA
authorMaharaja <c_mkenna@qti.qualcomm.com>
Wed, 21 Oct 2015 08:49:18 +0000 (11:49 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Wed, 28 Oct 2015 19:33:03 +0000 (21:33 +0200)
European Union has made it mandatory that all devices working in 2.4 GHz
has to adhere to the ETSI specification (ETSI EN 300 328 V1.9.1)
beginnig this year. The standard basically speaks about interferences
in 2.4Ghz band.
For example, when 802.11 device detects interference, TX must be stopped
as long as interference is present.

Adaptive CCA is a feature, when enabled the device learns from the
environment and configures CCA levels adaptively. This will improve
detecting interferences and the device can stop trasmissions till the
interference is present eventually leading to good performances in
varying interference conditions.

The patch includes code for enabling adaptive CCA for 10.2.4 firmware on
QCA988X.

Signed-off-by: Maharaja <c_mkenna@qti.qualcomm.com>
Signed-off-by: Manikanta Pubbisetty <c_mpubbi@qti.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/core.h
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/wmi-ops.h
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/ath/ath10k/wmi.h

index 13de3617d5abc3e76a5f7dc99eb96f9a500d9b42..e70e715ae1a793a8f4a9a9705495fda41854d939 100644 (file)
@@ -151,6 +151,7 @@ static const char *const ath10k_core_fw_feature_str[] = {
        [ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING] = "no-4addr-pad",
        [ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT] = "skip-clock-init",
        [ATH10K_FW_FEATURE_RAW_MODE_SUPPORT] = "raw-mode",
+       [ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA] = "adaptive-cca",
 };
 
 static unsigned int ath10k_core_get_fw_feature_str(char *buf,
index 7cc7cdd56c9530d45677abf5bda7d4f54a7e639d..3f88aa09086b1ff524a07942a6b58089844fe080 100644 (file)
@@ -497,6 +497,9 @@ enum ath10k_fw_features {
         */
        ATH10K_FW_FEATURE_RAW_MODE_SUPPORT = 10,
 
+       /* Firmware Supports Adaptive CCA*/
+       ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA = 11,
+
        /* keep last */
        ATH10K_FW_FEATURE_COUNT,
 };
index 484c1a10372f13a9fead3d7c4f4368080ab9f10a..769d7d83077045f693bc6a49167280bf6508d863 100644 (file)
@@ -3905,6 +3905,18 @@ static int ath10k_start(struct ieee80211_hw *hw)
                goto err_core_stop;
        }
 
+       if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
+                    ar->fw_features)) {
+               ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
+                                                         WMI_CCA_DETECT_LEVEL_AUTO,
+                                                         WMI_CCA_DETECT_MARGIN_AUTO);
+               if (ret) {
+                       ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
+                                   ret);
+                       goto err_core_stop;
+               }
+       }
+
        ret = ath10k_wmi_pdev_set_param(ar,
                                        ar->wmi.pdev_param->ani_enable, 1);
        if (ret) {
index b54aa08cb25cf74de221333591ab903dfe6032d9..8f4f6a892581c2ac7e976e08138e37740d0b0a33 100644 (file)
@@ -182,6 +182,10 @@ struct wmi_ops {
        void (*fw_stats_fill)(struct ath10k *ar,
                              struct ath10k_fw_stats *fw_stats,
                              char *buf);
+       struct sk_buff *(*gen_pdev_enable_adaptive_cca)(struct ath10k *ar,
+                                                       u8 enable,
+                                                       u32 detect_level,
+                                                       u32 detect_margin);
 };
 
 int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -1302,4 +1306,25 @@ ath10k_wmi_fw_stats_fill(struct ath10k *ar, struct ath10k_fw_stats *fw_stats,
        ar->wmi.ops->fw_stats_fill(ar, fw_stats, buf);
        return 0;
 }
+
+static inline int
+ath10k_wmi_pdev_enable_adaptive_cca(struct ath10k *ar, u8 enable,
+                                   u32 detect_level, u32 detect_margin)
+{
+       struct sk_buff *skb;
+
+       if (!ar->wmi.ops->gen_pdev_enable_adaptive_cca)
+               return -EOPNOTSUPP;
+
+       skb = ar->wmi.ops->gen_pdev_enable_adaptive_cca(ar, enable,
+                                                       detect_level,
+                                                       detect_margin);
+
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
+       return ath10k_wmi_cmd_send(ar, skb,
+                                  ar->wmi.cmd->pdev_enable_adaptive_cca_cmdid);
+}
+
 #endif
index 6e7d7a7f6a97a28724f839809e0526a8bedaa8be..2b32f02992f3e02b0d8bc7a3a94ad6353f7e4cc7 100644 (file)
@@ -148,6 +148,7 @@ static struct wmi_cmd_map wmi_cmd_map = {
        .gpio_config_cmdid = WMI_GPIO_CONFIG_CMDID,
        .gpio_output_cmdid = WMI_GPIO_OUTPUT_CMDID,
        .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED,
+       .pdev_enable_adaptive_cca_cmdid = WMI_CMD_UNSUPPORTED,
        .scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
        .vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
        .vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
@@ -313,6 +314,7 @@ static struct wmi_cmd_map wmi_10x_cmd_map = {
        .gpio_config_cmdid = WMI_10X_GPIO_CONFIG_CMDID,
        .gpio_output_cmdid = WMI_10X_GPIO_OUTPUT_CMDID,
        .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED,
+       .pdev_enable_adaptive_cca_cmdid = WMI_CMD_UNSUPPORTED,
        .scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
        .vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
        .vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
@@ -477,6 +479,7 @@ static struct wmi_cmd_map wmi_10_2_4_cmd_map = {
        .gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID,
        .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID,
        .pdev_get_temperature_cmdid = WMI_10_2_PDEV_GET_TEMPERATURE_CMDID,
+       .pdev_enable_adaptive_cca_cmdid = WMI_10_2_SET_CCA_PARAMS,
        .scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
        .vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
        .vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
@@ -1407,6 +1410,7 @@ static struct wmi_cmd_map wmi_10_2_cmd_map = {
        .gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID,
        .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID,
        .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED,
+       .pdev_enable_adaptive_cca_cmdid = WMI_CMD_UNSUPPORTED,
        .scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
        .vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
        .vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
@@ -6996,6 +7000,28 @@ unlock:
                buf[len] = 0;
 }
 
+static struct sk_buff *
+ath10k_wmi_op_gen_pdev_enable_adaptive_cca(struct ath10k *ar, u8 enable,
+                                          u32 detect_level, u32 detect_margin)
+{
+       struct wmi_pdev_set_adaptive_cca_params *cmd;
+       struct sk_buff *skb;
+
+       skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
+       if (!skb)
+               return ERR_PTR(-ENOMEM);
+
+       cmd = (struct wmi_pdev_set_adaptive_cca_params *)skb->data;
+       cmd->enable = __cpu_to_le32(enable);
+       cmd->cca_detect_level = __cpu_to_le32(detect_level);
+       cmd->cca_detect_margin = __cpu_to_le32(detect_margin);
+
+       ath10k_dbg(ar, ATH10K_DBG_WMI,
+                  "wmi pdev set adaptive cca params enable:%d detection level:%d detection margin:%d\n",
+                  enable, detect_level, detect_margin);
+       return skb;
+}
+
 static const struct wmi_ops wmi_ops = {
        .rx = ath10k_wmi_op_rx,
        .map_svc = wmi_main_svc_map,
@@ -7059,6 +7085,7 @@ static const struct wmi_ops wmi_ops = {
        /* .gen_prb_tmpl not implemented */
        /* .gen_p2p_go_bcn_ie not implemented */
        /* .gen_adaptive_qcs not implemented */
+       /* .gen_pdev_enable_adaptive_cca not implemented */
 };
 
 static const struct wmi_ops wmi_10_1_ops = {
@@ -7125,6 +7152,7 @@ static const struct wmi_ops wmi_10_1_ops = {
        /* .gen_prb_tmpl not implemented */
        /* .gen_p2p_go_bcn_ie not implemented */
        /* .gen_adaptive_qcs not implemented */
+       /* .gen_pdev_enable_adaptive_cca not implemented */
 };
 
 static const struct wmi_ops wmi_10_2_ops = {
@@ -7188,6 +7216,7 @@ static const struct wmi_ops wmi_10_2_ops = {
        .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
        .gen_delba_send = ath10k_wmi_op_gen_delba_send,
        .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
+       /* .gen_pdev_enable_adaptive_cca not implemented */
 };
 
 static const struct wmi_ops wmi_10_2_4_ops = {
@@ -7251,6 +7280,8 @@ static const struct wmi_ops wmi_10_2_4_ops = {
        .gen_delba_send = ath10k_wmi_op_gen_delba_send,
        .gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
        .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
+       .gen_pdev_enable_adaptive_cca =
+               ath10k_wmi_op_gen_pdev_enable_adaptive_cca,
        /* .gen_bcn_tmpl not implemented */
        /* .gen_prb_tmpl not implemented */
        /* .gen_p2p_go_bcn_ie not implemented */
index 6e84d1c1a6ca5e12d8cb7d9df7144c3e8c62b122..c6718e7422f524fc320febd76662469f8048f449 100644 (file)
@@ -772,6 +772,7 @@ struct wmi_cmd_map {
        u32 mu_cal_start_cmdid;
        u32 set_cca_params_cmdid;
        u32 pdev_bss_chan_info_request_cmdid;
+       u32 pdev_enable_adaptive_cca_cmdid;
 };
 
 /*
@@ -1381,6 +1382,9 @@ enum wmi_10_2_cmd_id {
        WMI_10_2_VDEV_ATF_REQUEST_CMDID,
        WMI_10_2_PEER_ATF_REQUEST_CMDID,
        WMI_10_2_PDEV_GET_TEMPERATURE_CMDID,
+       WMI_10_2_MU_CAL_START_CMDID,
+       WMI_10_2_SET_LTEU_CONFIG_CMDID,
+       WMI_10_2_SET_CCA_PARAMS,
        WMI_10_2_PDEV_UTF_CMDID = WMI_10_2_END_CMDID - 1,
 };
 
@@ -6094,6 +6098,15 @@ enum wmi_txbf_conf {
        WMI_TXBF_CONF_AFTER_ASSOC,
 };
 
+#define        WMI_CCA_DETECT_LEVEL_AUTO       0
+#define        WMI_CCA_DETECT_MARGIN_AUTO      0
+
+struct wmi_pdev_set_adaptive_cca_params {
+       __le32 enable;
+       __le32 cca_detect_level;
+       __le32 cca_detect_margin;
+} __packed;
+
 struct ath10k;
 struct ath10k_vif;
 struct ath10k_fw_stats_pdev;