From 14996cdfd92bc4d6d417274f1eb079e9ee314651 Mon Sep 17 00:00:00 2001 From: Kai Liu Date: Tue, 11 May 2021 08:43:18 +0800 Subject: [PATCH] cnss2: Sending host feature list to FW Update host capability message to inform host capability, FW uses this information to decode host enabled feature list. Enable clock selection feature when xo_clk_gpio is set in DTS. Change-Id: Iea7e5863c67a29cfc9ff1fa7c654aeef6da48524 Signed-off-by: Kai Liu --- drivers/net/wireless/cnss2/main.c | 20 +++++++++++++++++++ drivers/net/wireless/cnss2/main.h | 5 +++++ drivers/net/wireless/cnss2/power.c | 1 + drivers/net/wireless/cnss2/qmi.c | 9 +++++++++ .../cnss_utils/wlan_firmware_service_v01.c | 20 +++++++++++++++++++ .../cnss_utils/wlan_firmware_service_v01.h | 11 +++++++++- 6 files changed, 65 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index 75e69ff96fc8..2579938e9703 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -157,6 +157,26 @@ int cnss_get_mem_segment_info(enum cnss_remote_mem_type type, } EXPORT_SYMBOL(cnss_get_mem_segment_info); +int cnss_set_feature_list(struct cnss_plat_data *plat_priv, + enum cnss_feature_v01 feature) +{ + if (unlikely(!plat_priv || feature >= CNSS_MAX_FEATURE_V01)) + return -EINVAL; + + plat_priv->feature_list |= 1 << feature; + return 0; +} + +int cnss_get_feature_list(struct cnss_plat_data *plat_priv, + u64 *feature_list) +{ + if (unlikely(!plat_priv)) + return -EINVAL; + + *feature_list = plat_priv->feature_list; + return 0; +} + static int cnss_pm_notify(struct notifier_block *b, unsigned long event, void *p) { diff --git a/drivers/net/wireless/cnss2/main.h b/drivers/net/wireless/cnss2/main.h index 828a19365e6e..af4709507c03 100644 --- a/drivers/net/wireless/cnss2/main.h +++ b/drivers/net/wireless/cnss2/main.h @@ -502,6 +502,7 @@ struct cnss_plat_data { u32 hw_trc_override; u32 is_converged_dt; struct device_node *dev_node; + u64 feature_list; }; #ifdef CONFIG_ARCH_QCOM @@ -573,4 +574,8 @@ int cnss_request_firmware_direct(struct cnss_plat_data *plat_priv, const char *filename); void cnss_disable_redundant_vreg(struct cnss_plat_data *plat_priv); int cnss_gpio_get_value(struct cnss_plat_data *plat_priv, int gpio_num); +int cnss_set_feature_list(struct cnss_plat_data *plat_priv, + enum cnss_feature_v01 feature); +int cnss_get_feature_list(struct cnss_plat_data *plat_priv, + u64 *feature_list); #endif /* _CNSS_MAIN_H */ diff --git a/drivers/net/wireless/cnss2/power.c b/drivers/net/wireless/cnss2/power.c index b6db72a2baf2..35a6ad1e4192 100644 --- a/drivers/net/wireless/cnss2/power.c +++ b/drivers/net/wireless/cnss2/power.c @@ -784,6 +784,7 @@ int cnss_get_pinctrl(struct cnss_plat_data *plat_priv) XO_CLK_GPIO, 0); cnss_pr_dbg("QCA6490 XO_CLK GPIO: %d\n", pinctrl_info->xo_clk_gpio); + cnss_set_feature_list(plat_priv, BOOTSTRAP_CLOCK_SELECT_V01); } else { pinctrl_info->xo_clk_gpio = -EINVAL; } diff --git a/drivers/net/wireless/cnss2/qmi.c b/drivers/net/wireless/cnss2/qmi.c index 1e5a6c911e6a..1368b88f0c88 100644 --- a/drivers/net/wireless/cnss2/qmi.c +++ b/drivers/net/wireless/cnss2/qmi.c @@ -186,6 +186,7 @@ static int cnss_wlfw_host_cap_send_sync(struct cnss_plat_data *plat_priv) int ret = 0; u64 iova_start = 0, iova_size = 0, iova_ipa_start = 0, iova_ipa_size = 0; + u64 feature_list = 0; cnss_pr_dbg("Sending host capability message, state: 0x%lx\n", plat_priv->driver_state); @@ -241,6 +242,14 @@ static int cnss_wlfw_host_cap_send_sync(struct cnss_plat_data *plat_priv) req->host_build_type_valid = 1; req->host_build_type = cnss_get_host_build_type(); + ret = cnss_get_feature_list(plat_priv, &feature_list); + if (!ret) { + req->feature_list_valid = 1; + req->feature_list = feature_list; + cnss_pr_dbg("Sending feature list 0x%llx\n", + req->feature_list); + } + ret = qmi_txn_init(&plat_priv->qmi_wlfw, &txn, wlfw_host_cap_resp_msg_v01_ei, resp); if (ret < 0) { diff --git a/drivers/net/wireless/cnss_utils/wlan_firmware_service_v01.c b/drivers/net/wireless/cnss_utils/wlan_firmware_service_v01.c index 99677e444589..a5360a0c0098 100644 --- a/drivers/net/wireless/cnss_utils/wlan_firmware_service_v01.c +++ b/drivers/net/wireless/cnss_utils/wlan_firmware_service_v01.c @@ -3394,6 +3394,26 @@ struct qmi_elem_info wlfw_host_cap_req_msg_v01_ei[] = { mlo_chip_info), .ei_array = wlfw_host_mlo_chip_info_s_v01_ei, }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x27, + .offset = offsetof(struct + wlfw_host_cap_req_msg_v01, + feature_list_valid), + }, + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(u64), + .array_type = NO_ARRAY, + .tlv_type = 0x27, + .offset = offsetof(struct + wlfw_host_cap_req_msg_v01, + feature_list), + }, { .data_type = QMI_EOTI, .array_type = NO_ARRAY, diff --git a/drivers/net/wireless/cnss_utils/wlan_firmware_service_v01.h b/drivers/net/wireless/cnss_utils/wlan_firmware_service_v01.h index df70a18aa224..e54cbce85252 100644 --- a/drivers/net/wireless/cnss_utils/wlan_firmware_service_v01.h +++ b/drivers/net/wireless/cnss_utils/wlan_firmware_service_v01.h @@ -243,6 +243,13 @@ enum wlfw_m3_segment_type_v01 { WLFW_M3_SEGMENT_TYPE_MAX_VAL_V01 = INT_MAX, }; +enum cnss_feature_v01 { + CNSS_FEATURE_MIN_VAL_V01 = INT_MIN, + BOOTSTRAP_CLOCK_SELECT_V01 = 0, + CNSS_MAX_FEATURE_V01 = 64, + CNSS_FEATURE_MAX_VAL_V01 = INT_MAX, +}; + #define QMI_WLFW_CE_ATTR_FLAGS_V01 ((u32)0x00) #define QMI_WLFW_CE_ATTR_NO_SNOOP_V01 ((u32)0x01) #define QMI_WLFW_CE_ATTR_BYTE_SWAP_DATA_V01 ((u32)0x02) @@ -786,9 +793,11 @@ struct wlfw_host_cap_req_msg_v01 { u8 mlo_num_chips; u8 mlo_chip_info_valid; struct wlfw_host_mlo_chip_info_s_v01 mlo_chip_info[QMI_WLFW_MAX_NUM_MLO_CHIPS_V01]; + u8 feature_list_valid; + u64 feature_list; }; -#define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 362 +#define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 373 extern struct qmi_elem_info wlfw_host_cap_req_msg_v01_ei[]; struct wlfw_host_cap_resp_msg_v01 {