ath10k: Add QMI CAP request support
PATCH 8/12 ath10k: Add QMI CAP request support
Add support for target capablity request
qmi message for wcn3990 target.
--- drivers/net/wireless/ath/ath10k/qmi.c | 91 +++++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/qmi.h | 25 ++++++++++ 2 files changed, 116 insertions(+)
drivers/net/wireless/ath/ath10k/qmi.c +91 -0
@@ -270,6 +270,93 @@ static int ath10k_qmi_msa_ready_send_sync_msg(struct ath10k_qmi *qmi)return ret; } +static int ath10k_qmi_cap_send_sync_msg (struct ath10k_qmi *qmi) +{ +struct wlfw_cap_resp_msg_v01 *resp; +struct wlfw_cap_req_msg_v01 *req; +struct qmi_txn txn; +int ret; + + req =kzalloc (sizeof (*req),GFP_KERNEL ); +if (!req) +return -ENOMEM ; + + resp =kzalloc (sizeof (*resp),GFP_KERNEL ); +if (!resp) { +kfree (req); +return -ENOMEM ; + } + + ret =qmi_txn_init (&qmi->qmi_hdl, &txn, wlfw_cap_resp_msg_v01_ei, resp); +if (ret <0 ) { +pr_err ("fail to init txn for capability resp %d\n" , ret); + goto out; + } + + ret =qmi_send_request (&qmi->qmi_hdl,NULL , &txn, +QMI_WLFW_CAP_REQ_V01 , +WLFW_CAP_REQ_MSG_V01_MAX_MSG_LEN , + wlfw_cap_req_msg_v01_ei, req); +if (ret <0 ) { +qmi_txn_cancel (&txn); +pr_err ("fail to send capability req %d\n" , ret); + goto out; + } + + ret =qmi_txn_wait (&txn,WLFW_TIMEOUT *HZ ); +if (ret <0 ) + goto out; + +if (resp->resp.result !=QMI_RESULT_SUCCESS_V01 ) { +pr_err ("qmi capability request rejected, result:%d error:%d\n" , + resp->resp.result, resp->resp.error); + ret = -resp->resp.result; + goto out; + } + +if (resp->chip_info_valid) { + qmi->chip_info.chip_id = resp->chip_info.chip_id; + qmi->chip_info.chip_family = resp->chip_info.chip_family; + } + +if (resp->board_info_valid) + qmi->board_info.board_id = resp->board_info.board_id; +else + qmi->board_info.board_id =0xFF ; + +if (resp->soc_info_valid) + qmi->soc_info.soc_id = resp->soc_info.soc_id; + +if (resp->fw_version_info_valid) { + qmi->fw_version_info.fw_version = + resp->fw_version_info.fw_version; +strlcpy (qmi->fw_version_info.fw_build_timestamp, + resp->fw_version_info.fw_build_timestamp, +MAX_TIMESTAMP_LEN +1 ); + } + +if (resp->fw_build_id_valid) +strlcpy (qmi->fw_build_id, resp->fw_build_id, +MAX_BUILD_ID_LEN +1 ); + +pr_debug ("chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x, fw_version: 0x%x, fw_build_timestamp: %s, fw_build_id: %s" , + qmi->chip_info.chip_id, qmi->chip_info.chip_family, + qmi->board_info.board_id, qmi->soc_info.soc_id, + qmi->fw_version_info.fw_version, + qmi->fw_version_info.fw_build_timestamp, + qmi->fw_build_id); + +pr_debug ("target cap request completed\n" ); +kfree (resp); +kfree (req); + +return 0 ; +out: +kfree (resp); +kfree (req); +return ret; +} +static int ath10k_qmi_ind_register_send_sync_msg (struct ath10k_qmi *qmi) {
@@ -425,6 +512,10 @@ static void ath10k_qmi_event_server_arrive(struct work_struct *work)if (ret) goto err_setup_msa; + ret =ath10k_qmi_cap_send_sync_msg (qmi); +if (ret) + goto err_setup_msa; +return ; err_setup_msa:
drivers/net/wireless/ath/ath10k/qmi.h +25 -0
@@ -17,6 +17,8 @@#define _QMI_H_#define MAX_NUM_MEMORY_REGIONS 2 +#define MAX_TIMESTAMP_LEN 32 +#define MAX_BUILD_ID_LEN 128enum ath10k_qmi_driver_event_type {ATH10K_QMI_EVENT_SERVER_ARRIVE ,
@@ -31,6 +33,24 @@ struct ath10k_msa_mem_region_info {u8 secure_flag; }; +struct ath10k_qmi_chip_info { +u32 chip_id; +u32 chip_family; +}; + +struct ath10k_qmi_board_info { +u32 board_id; +}; + +struct ath10k_qmi_soc_info { +u32 soc_id; +}; + +struct ath10k_qmi_fw_version_info { +u32 fw_version; +char fw_build_timestamp[MAX_TIMESTAMP_LEN +1 ]; +}; +struct ath10k_qmi {struct platform_device *pdev;struct qmi_handle qmi_hdl;
@@ -47,5 +67,10 @@ struct ath10k_qmi {phys_addr_t msa_pa;u32 msa_mem_size;void *msa_va; +struct ath10k_qmi_chip_info chip_info; +struct ath10k_qmi_board_info board_info; +struct ath10k_qmi_soc_info soc_info; +struct ath10k_qmi_fw_version_info fw_version_info; + char fw_build_id[MAX_BUILD_ID_LEN + 1]; };#endif /* _QMI_H_ */
Signature · 1 line
1.9.1
Quoted 14 lines · Govind Singh
Add support for target capablity request
qmi message for wcn3990 target.Signed-off-by Govind Singh <[email protected]>--- drivers/net/wireless/ath/ath10k/qmi.c | 91 +++++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/qmi.h | 25 ++++++++++ 2 files changed, 116 insertions(+)drivers/net/wireless/ath/ath10k/qmi.c +0
-0
drivers/net/wireless/ath/ath10k/qmi.c static int ath10k_qmi_msa_ready_send_sync_msg(struct ath10k_qmi *qmi) · line 275
Quoted 6 lines
drivers/net/wireless/ath/ath10k/qmi.c +3
-0@@ -270,6 +270,93 @@ static int ath10k_qmi_msa_ready_send_sync_msg(struct ath10k_qmi *qmi)return ret; } +static int ath10k_qmi_cap_send_sync_msg (struct ath10k_qmi *qmi) +{ +struct wlfw_cap_resp_msg_v01 *resp;
I think this is 207 bytes, so it makes sense to allocate this on the heap.
drivers/net/wireless/ath/ath10k/qmi.c static int ath10k_qmi_msa_ready_send_sync_msg(struct ath10k_qmi *qmi) · line 276
Quoted 1 line
drivers/net/wireless/ath/ath10k/qmi.c +1
-0+struct wlfw_cap_req_msg_v01 *req;
But this is 1 bytes, so keep it on the stack.
Quoted 6 lines
drivers/net/wireless/ath/ath10k/qmi.c +6
-0+struct qmi_txn txn; +int ret; + + req =kzalloc (sizeof (*req),GFP_KERNEL ); +if (!req) +return -ENOMEM ;
drivers/net/wireless/ath/ath10k/qmi.c static int ath10k_qmi_msa_ready_send_sync_msg(struct ath10k_qmi *qmi) · line 292
Quoted 10 lines
drivers/net/wireless/ath/ath10k/qmi.c +10
-0+ + resp =kzalloc (sizeof (*resp),GFP_KERNEL ); +if (!resp) { +kfree (req); +return -ENOMEM ; + } + + ret =qmi_txn_init (&qmi->qmi_hdl, &txn, wlfw_cap_resp_msg_v01_ei, resp); +if (ret <0 ) { +pr_err ("fail to init txn for capability resp %d\n" , ret);
Same comments as in previous patches.
Quoted 33 lines
drivers/net/wireless/ath/ath10k/qmi.c +33
-0+ goto out; + } + + ret =qmi_send_request (&qmi->qmi_hdl,NULL , &txn, +QMI_WLFW_CAP_REQ_V01 , +WLFW_CAP_REQ_MSG_V01_MAX_MSG_LEN , + wlfw_cap_req_msg_v01_ei, req); +if (ret <0 ) { +qmi_txn_cancel (&txn); +pr_err ("fail to send capability req %d\n" , ret); + goto out; + } + + ret =qmi_txn_wait (&txn,WLFW_TIMEOUT *HZ ); +if (ret <0 ) + goto out; + +if (resp->resp.result !=QMI_RESULT_SUCCESS_V01 ) { +pr_err ("qmi capability request rejected, result:%d error:%d\n" , + resp->resp.result, resp->resp.error); + ret = -resp->resp.result; + goto out; + } + +if (resp->chip_info_valid) { + qmi->chip_info.chip_id = resp->chip_info.chip_id; + qmi->chip_info.chip_family = resp->chip_info.chip_family; + } + +if (resp->board_info_valid) + qmi->board_info.board_id = resp->board_info.board_id; +else + qmi->board_info.board_id =0xFF ;
drivers/net/wireless/ath/ath10k/qmi.c static int ath10k_qmi_msa_ready_send_sync_msg(struct ath10k_qmi *qmi) · line 335
Quoted 10 lines
drivers/net/wireless/ath/ath10k/qmi.c +10
-0+ +if (resp->soc_info_valid) + qmi->soc_info.soc_id = resp->soc_info.soc_id; + +if (resp->fw_version_info_valid) { + qmi->fw_version_info.fw_version = + resp->fw_version_info.fw_version; +strlcpy (qmi->fw_version_info.fw_build_timestamp, + resp->fw_version_info.fw_build_timestamp, +MAX_TIMESTAMP_LEN +1 );
Use sizeof(qmi->fw_version_info.fw_build_timestamp) to remove the risk of them getting out of sync.
drivers/net/wireless/ath/ath10k/qmi.c static int ath10k_qmi_msa_ready_send_sync_msg(struct ath10k_qmi *qmi) · line 347
Quoted 12 lines
drivers/net/wireless/ath/ath10k/qmi.c +12
-0+ } + +if (resp->fw_build_id_valid) +strlcpy (qmi->fw_build_id, resp->fw_build_id, +MAX_BUILD_ID_LEN +1 ); + +pr_debug ("chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x, fw_version: 0x%x, fw_build_timestamp: %s, fw_build_id: %s" , + qmi->chip_info.chip_id, qmi->chip_info.chip_family, + qmi->board_info.board_id, qmi->soc_info.soc_id, + qmi->fw_version_info.fw_version, + qmi->fw_version_info.fw_build_timestamp, + qmi->fw_build_id);
Use dev_dbg(), but perhaps this could even be a dev_info()?
Quoted 50 lines
drivers/net/wireless/ath/ath10k/qmi.c +16
-0+ +pr_debug ("target cap request completed\n" ); +kfree (resp); +kfree (req); + +return 0 ; +out: +kfree (resp); +kfree (req); +return ret; +} +static int ath10k_qmi_ind_register_send_sync_msg (struct ath10k_qmi *qmi) {@@ -425,6 +512,10 @@ static void ath10k_qmi_event_server_arrive(struct work_struct *work)if (ret) goto err_setup_msa; + ret =ath10k_qmi_cap_send_sync_msg (qmi); +if (ret) + goto err_setup_msa; +return ; err_setup_msa:drivers/net/wireless/ath/ath10k/qmi.h +9
-0@@ -17,6 +17,8 @@#define _QMI_H_#define MAX_NUM_MEMORY_REGIONS 2 +#define MAX_TIMESTAMP_LEN 32 +#define MAX_BUILD_ID_LEN 128enum ath10k_qmi_driver_event_type {ATH10K_QMI_EVENT_SERVER_ARRIVE ,@@ -31,6 +33,24 @@ struct ath10k_msa_mem_region_info {u8 secure_flag; }; +struct ath10k_qmi_chip_info { +u32 chip_id; +u32 chip_family; +}; + +struct ath10k_qmi_board_info { +u32 board_id;
drivers/net/wireless/ath/ath10k/qmi.h struct ath10k_msa_mem_region_info { · line 52
Quoted 10 lines
drivers/net/wireless/ath/ath10k/qmi.h +10
-0+}; + +struct ath10k_qmi_soc_info { +u32 soc_id; +}; + +struct ath10k_qmi_fw_version_info { +u32 fw_version; +char fw_build_timestamp[MAX_TIMESTAMP_LEN +1 ]; +};
I don't see the benefit off lugging these around as separate structs, why not just put them in the ath10k_qmi struct directly.
But in particular, I don't see a reason for stashing the data that will never be used, store the parts that you're actually using.
Quoted 5 lines
drivers/net/wireless/ath/ath10k/qmi.h +1
-0+struct ath10k_qmi {struct platform_device *pdev;struct qmi_handle qmi_hdl;
drivers/net/wireless/ath/ath10k/qmi.h struct ath10k_qmi { · line 76
Quoted 10 lines
drivers/net/wireless/ath/ath10k/qmi.h +5
-0@@ -47,5 +67,10 @@ struct ath10k_qmi {phys_addr_t msa_pa;u32 msa_mem_size;void *msa_va; +struct ath10k_qmi_chip_info chip_info; +struct ath10k_qmi_board_info board_info; +struct ath10k_qmi_soc_info soc_info; +struct ath10k_qmi_fw_version_info fw_version_info; + char fw_build_id[MAX_BUILD_ID_LEN + 1]; };#endif /* _QMI_H_ */
Regards,
Bjorn