Loading drivers/net/wireless/cnss2/qmi.c +78 −0 Original line number Diff line number Diff line Loading @@ -1301,6 +1301,73 @@ int cnss_wlfw_qdss_trace_mem_info_send_sync(struct cnss_plat_data *plat_priv) return ret; } static int cnss_wlfw_wfc_call_status_send_sync(struct cnss_plat_data *plat_priv, u32 data_len, const void *data) { struct wlfw_wfc_call_status_req_msg_v01 *req; struct wlfw_wfc_call_status_resp_msg_v01 *resp; struct qmi_txn txn; int ret = 0; cnss_pr_dbg("Sending WFC call status: state: 0x%lx\n", plat_priv->driver_state); req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; resp = kzalloc(sizeof(*resp), GFP_KERNEL); if (!resp) { kfree(req); return -ENOMEM; } req->wfc_call_status_len = data_len; memcpy(req->wfc_call_status, data, req->wfc_call_status_len); ret = qmi_txn_init(&plat_priv->qmi_wlfw, &txn, wlfw_wfc_call_status_resp_msg_v01_ei, resp); if (ret < 0) { cnss_pr_err("Fail to initialize txn for WFC call status request: err %d\n", ret); goto out; } ret = qmi_send_request(&plat_priv->qmi_wlfw, NULL, &txn, QMI_WLFW_WFC_CALL_STATUS_REQ_V01, WLFW_WFC_CALL_STATUS_REQ_MSG_V01_MAX_MSG_LEN, wlfw_wfc_call_status_req_msg_v01_ei, req); if (ret < 0) { qmi_txn_cancel(&txn); cnss_pr_err("Fail to send WFC call status request: err %d\n", ret); goto out; } ret = qmi_txn_wait(&txn, QMI_WLFW_TIMEOUT_JF); if (ret < 0) { cnss_pr_err("Fail to wait for response of WFC call status request, err %d\n", ret); goto out; } if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { cnss_pr_err("WFC call status request failed, result: %d, err: %d\n", resp->resp.result, resp->resp.error); ret = -resp->resp.result; goto out; } kfree(req); kfree(resp); return 0; out: kfree(req); kfree(resp); return ret; } unsigned int cnss_get_qmi_timeout(struct cnss_plat_data *plat_priv) { cnss_pr_dbg("QMI timeout is %u ms\n", QMI_WLFW_TIMEOUT_MS); Loading Loading @@ -2031,8 +2098,11 @@ static void ims_wfc_call_status_ind_cb(struct qmi_handle *ims_qmi, struct sockaddr_qrtr *sq, struct qmi_txn *txn, const void *data) { struct cnss_plat_data *plat_priv = container_of(ims_qmi, struct cnss_plat_data, ims_qmi); const struct ims_private_service_wfc_call_status_ind_msg_v01 *ind_msg = data; u32 data_len = 0; cnss_pr_dbg("Received IMS wfc call status indication\n"); Loading @@ -2045,6 +2115,14 @@ static void ims_wfc_call_status_ind_cb(struct qmi_handle *ims_qmi, cnss_pr_err("Invalid indication\n"); return; } data_len = sizeof(*ind_msg); if (data_len > QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01) { cnss_pr_err("Exceed maxinum data len:%u\n", data_len); return; } cnss_wlfw_wfc_call_status_send_sync(plat_priv, data_len, ind_msg); } static struct qmi_msg_handler qmi_ims_msg_handlers[] = { Loading drivers/net/wireless/cnss2/wlan_firmware_service_v01.c +47 −0 Original line number Diff line number Diff line Loading @@ -3561,3 +3561,50 @@ struct qmi_elem_info wlfw_antenna_grant_resp_msg_v01_ei[] = { }, }; struct qmi_elem_info wlfw_wfc_call_status_req_msg_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, .elem_size = sizeof(u16), .array_type = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct wlfw_wfc_call_status_req_msg_v01, wfc_call_status_len), }, { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01, .elem_size = sizeof(u8), .array_type = VAR_LEN_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct wlfw_wfc_call_status_req_msg_v01, wfc_call_status), }, { .data_type = QMI_EOTI, .array_type = NO_ARRAY, .tlv_type = QMI_COMMON_TLV_TYPE, }, }; struct qmi_elem_info wlfw_wfc_call_status_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, .elem_size = sizeof(struct qmi_response_type_v01), .array_type = NO_ARRAY, .tlv_type = 0x02, .offset = offsetof(struct wlfw_wfc_call_status_resp_msg_v01, resp), .ei_array = qmi_response_type_v01_ei, }, { .data_type = QMI_EOTI, .array_type = NO_ARRAY, .tlv_type = QMI_COMMON_TLV_TYPE, }, }; drivers/net/wireless/cnss2/wlan_firmware_service_v01.h +18 −0 Original line number Diff line number Diff line Loading @@ -9,11 +9,13 @@ #define WLFW_SERVICE_ID_V01 0x45 #define WLFW_SERVICE_VERS_V01 0x01 #define QMI_WLFW_WFC_CALL_STATUS_REQ_V01 0x0049 #define QMI_WLFW_BDF_DOWNLOAD_REQ_V01 0x0025 #define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037 #define QMI_WLFW_QDSS_TRACE_CONFIG_DOWNLOAD_REQ_V01 0x0044 #define QMI_WLFW_INITIATE_CAL_UPDATE_IND_V01 0x002A #define QMI_WLFW_CAL_DONE_IND_V01 0x003E #define QMI_WLFW_WFC_CALL_STATUS_RESP_V01 0x0049 #define QMI_WLFW_HOST_CAP_REQ_V01 0x0034 #define QMI_WLFW_DYNAMIC_FEATURE_MASK_RESP_V01 0x003B #define QMI_WLFW_M3_INFO_REQ_V01 0x003C Loading Loading @@ -86,6 +88,7 @@ #define QMI_WLFW_MAX_NUM_CE_V01 12 #define QMI_WLFW_MAX_TIMESTAMP_LEN_V01 32 #define QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01 6144 #define QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01 256 #define QMI_WLFW_MAX_NUM_GPIO_V01 32 #define QMI_WLFW_MAX_BUILD_ID_LEN_V01 128 #define QMI_WLFW_MAX_NUM_MEM_CFG_V01 2 Loading Loading @@ -931,4 +934,19 @@ struct wlfw_antenna_grant_resp_msg_v01 { #define WLFW_ANTENNA_GRANT_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct qmi_elem_info wlfw_antenna_grant_resp_msg_v01_ei[]; struct wlfw_wfc_call_status_req_msg_v01 { u32 wfc_call_status_len; u8 wfc_call_status[QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01]; }; #define WLFW_WFC_CALL_STATUS_REQ_MSG_V01_MAX_MSG_LEN 261 extern struct qmi_elem_info wlfw_wfc_call_status_req_msg_v01_ei[]; struct wlfw_wfc_call_status_resp_msg_v01 { struct qmi_response_type_v01 resp; }; #define WLFW_WFC_CALL_STATUS_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct qmi_elem_info wlfw_wfc_call_status_resp_msg_v01_ei[]; #endif Loading
drivers/net/wireless/cnss2/qmi.c +78 −0 Original line number Diff line number Diff line Loading @@ -1301,6 +1301,73 @@ int cnss_wlfw_qdss_trace_mem_info_send_sync(struct cnss_plat_data *plat_priv) return ret; } static int cnss_wlfw_wfc_call_status_send_sync(struct cnss_plat_data *plat_priv, u32 data_len, const void *data) { struct wlfw_wfc_call_status_req_msg_v01 *req; struct wlfw_wfc_call_status_resp_msg_v01 *resp; struct qmi_txn txn; int ret = 0; cnss_pr_dbg("Sending WFC call status: state: 0x%lx\n", plat_priv->driver_state); req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; resp = kzalloc(sizeof(*resp), GFP_KERNEL); if (!resp) { kfree(req); return -ENOMEM; } req->wfc_call_status_len = data_len; memcpy(req->wfc_call_status, data, req->wfc_call_status_len); ret = qmi_txn_init(&plat_priv->qmi_wlfw, &txn, wlfw_wfc_call_status_resp_msg_v01_ei, resp); if (ret < 0) { cnss_pr_err("Fail to initialize txn for WFC call status request: err %d\n", ret); goto out; } ret = qmi_send_request(&plat_priv->qmi_wlfw, NULL, &txn, QMI_WLFW_WFC_CALL_STATUS_REQ_V01, WLFW_WFC_CALL_STATUS_REQ_MSG_V01_MAX_MSG_LEN, wlfw_wfc_call_status_req_msg_v01_ei, req); if (ret < 0) { qmi_txn_cancel(&txn); cnss_pr_err("Fail to send WFC call status request: err %d\n", ret); goto out; } ret = qmi_txn_wait(&txn, QMI_WLFW_TIMEOUT_JF); if (ret < 0) { cnss_pr_err("Fail to wait for response of WFC call status request, err %d\n", ret); goto out; } if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { cnss_pr_err("WFC call status request failed, result: %d, err: %d\n", resp->resp.result, resp->resp.error); ret = -resp->resp.result; goto out; } kfree(req); kfree(resp); return 0; out: kfree(req); kfree(resp); return ret; } unsigned int cnss_get_qmi_timeout(struct cnss_plat_data *plat_priv) { cnss_pr_dbg("QMI timeout is %u ms\n", QMI_WLFW_TIMEOUT_MS); Loading Loading @@ -2031,8 +2098,11 @@ static void ims_wfc_call_status_ind_cb(struct qmi_handle *ims_qmi, struct sockaddr_qrtr *sq, struct qmi_txn *txn, const void *data) { struct cnss_plat_data *plat_priv = container_of(ims_qmi, struct cnss_plat_data, ims_qmi); const struct ims_private_service_wfc_call_status_ind_msg_v01 *ind_msg = data; u32 data_len = 0; cnss_pr_dbg("Received IMS wfc call status indication\n"); Loading @@ -2045,6 +2115,14 @@ static void ims_wfc_call_status_ind_cb(struct qmi_handle *ims_qmi, cnss_pr_err("Invalid indication\n"); return; } data_len = sizeof(*ind_msg); if (data_len > QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01) { cnss_pr_err("Exceed maxinum data len:%u\n", data_len); return; } cnss_wlfw_wfc_call_status_send_sync(plat_priv, data_len, ind_msg); } static struct qmi_msg_handler qmi_ims_msg_handlers[] = { Loading
drivers/net/wireless/cnss2/wlan_firmware_service_v01.c +47 −0 Original line number Diff line number Diff line Loading @@ -3561,3 +3561,50 @@ struct qmi_elem_info wlfw_antenna_grant_resp_msg_v01_ei[] = { }, }; struct qmi_elem_info wlfw_wfc_call_status_req_msg_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, .elem_size = sizeof(u16), .array_type = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct wlfw_wfc_call_status_req_msg_v01, wfc_call_status_len), }, { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01, .elem_size = sizeof(u8), .array_type = VAR_LEN_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct wlfw_wfc_call_status_req_msg_v01, wfc_call_status), }, { .data_type = QMI_EOTI, .array_type = NO_ARRAY, .tlv_type = QMI_COMMON_TLV_TYPE, }, }; struct qmi_elem_info wlfw_wfc_call_status_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, .elem_size = sizeof(struct qmi_response_type_v01), .array_type = NO_ARRAY, .tlv_type = 0x02, .offset = offsetof(struct wlfw_wfc_call_status_resp_msg_v01, resp), .ei_array = qmi_response_type_v01_ei, }, { .data_type = QMI_EOTI, .array_type = NO_ARRAY, .tlv_type = QMI_COMMON_TLV_TYPE, }, };
drivers/net/wireless/cnss2/wlan_firmware_service_v01.h +18 −0 Original line number Diff line number Diff line Loading @@ -9,11 +9,13 @@ #define WLFW_SERVICE_ID_V01 0x45 #define WLFW_SERVICE_VERS_V01 0x01 #define QMI_WLFW_WFC_CALL_STATUS_REQ_V01 0x0049 #define QMI_WLFW_BDF_DOWNLOAD_REQ_V01 0x0025 #define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037 #define QMI_WLFW_QDSS_TRACE_CONFIG_DOWNLOAD_REQ_V01 0x0044 #define QMI_WLFW_INITIATE_CAL_UPDATE_IND_V01 0x002A #define QMI_WLFW_CAL_DONE_IND_V01 0x003E #define QMI_WLFW_WFC_CALL_STATUS_RESP_V01 0x0049 #define QMI_WLFW_HOST_CAP_REQ_V01 0x0034 #define QMI_WLFW_DYNAMIC_FEATURE_MASK_RESP_V01 0x003B #define QMI_WLFW_M3_INFO_REQ_V01 0x003C Loading Loading @@ -86,6 +88,7 @@ #define QMI_WLFW_MAX_NUM_CE_V01 12 #define QMI_WLFW_MAX_TIMESTAMP_LEN_V01 32 #define QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01 6144 #define QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01 256 #define QMI_WLFW_MAX_NUM_GPIO_V01 32 #define QMI_WLFW_MAX_BUILD_ID_LEN_V01 128 #define QMI_WLFW_MAX_NUM_MEM_CFG_V01 2 Loading Loading @@ -931,4 +934,19 @@ struct wlfw_antenna_grant_resp_msg_v01 { #define WLFW_ANTENNA_GRANT_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct qmi_elem_info wlfw_antenna_grant_resp_msg_v01_ei[]; struct wlfw_wfc_call_status_req_msg_v01 { u32 wfc_call_status_len; u8 wfc_call_status[QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01]; }; #define WLFW_WFC_CALL_STATUS_REQ_MSG_V01_MAX_MSG_LEN 261 extern struct qmi_elem_info wlfw_wfc_call_status_req_msg_v01_ei[]; struct wlfw_wfc_call_status_resp_msg_v01 { struct qmi_response_type_v01 resp; }; #define WLFW_WFC_CALL_STATUS_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct qmi_elem_info wlfw_wfc_call_status_resp_msg_v01_ei[]; #endif