Loading drivers/net/wireless/cnss_utils/wlan_firmware_service_v01.c +36 −0 Original line number Original line Diff line number Diff line Loading @@ -3205,6 +3205,42 @@ struct qmi_elem_info wlfw_fw_mem_ready_ind_msg_v01_ei[] = { EXPORT_SYMBOL(wlfw_fw_mem_ready_ind_msg_v01_ei); EXPORT_SYMBOL(wlfw_fw_mem_ready_ind_msg_v01_ei); struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[] = { struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(u8), .array_type = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_fw_init_done_ind_msg_v01, hang_data_addr_offset_valid), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, .elem_size = sizeof(u32), .array_type = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_fw_init_done_ind_msg_v01, hang_data_addr_offset), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(u8), .array_type = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_fw_init_done_ind_msg_v01, hang_data_length_valid), }, { .data_type = QMI_UNSIGNED_2_BYTE, .elem_len = 1, .elem_size = sizeof(u16), .array_type = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_fw_init_done_ind_msg_v01, hang_data_length), }, { { .data_type = QMI_EOTI, .data_type = QMI_EOTI, .array_type = NO_ARRAY, .array_type = NO_ARRAY, Loading drivers/net/wireless/cnss_utils/wlan_firmware_service_v01.h +6 −2 Original line number Original line Diff line number Diff line Loading @@ -768,9 +768,13 @@ struct wlfw_fw_mem_ready_ind_msg_v01 { extern struct qmi_elem_info wlfw_fw_mem_ready_ind_msg_v01_ei[]; extern struct qmi_elem_info wlfw_fw_mem_ready_ind_msg_v01_ei[]; struct wlfw_fw_init_done_ind_msg_v01 { struct wlfw_fw_init_done_ind_msg_v01 { char placeholder; u8 hang_data_addr_offset_valid; u32 hang_data_addr_offset; u8 hang_data_length_valid; u16 hang_data_length; }; }; #define WLFW_FW_INIT_DONE_IND_MSG_V01_MAX_MSG_LEN 0 #define WLFW_FW_INIT_DONE_IND_MSG_V01_MAX_MSG_LEN 12 extern struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[]; extern struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[]; struct wlfw_rejuvenate_ind_msg_v01 { struct wlfw_rejuvenate_ind_msg_v01 { Loading drivers/soc/qcom/icnss2/main.c +1 −2 Original line number Original line Diff line number Diff line Loading @@ -1189,7 +1189,6 @@ static int icnss_driver_event_pd_service_down(struct icnss_priv *priv, if (priv->force_err_fatal) if (priv->force_err_fatal) ICNSS_ASSERT(0); ICNSS_ASSERT(0); if (priv->device_id == ADRASTEA_DEVICE_ID) icnss_send_hang_event_data(priv); icnss_send_hang_event_data(priv); if (priv->early_crash_ind) { if (priv->early_crash_ind) { Loading drivers/soc/qcom/icnss2/qmi.c +59 −0 Original line number Original line Diff line number Diff line Loading @@ -1752,6 +1752,10 @@ static void fw_init_done_ind_cb(struct qmi_handle *qmi, struct qmi_txn *txn, const void *data) struct qmi_txn *txn, const void *data) { { struct icnss_priv *priv = container_of(qmi, struct icnss_priv, qmi); struct icnss_priv *priv = container_of(qmi, struct icnss_priv, qmi); struct device *dev = &priv->pdev->dev; const struct wlfw_fw_init_done_ind_msg_v01 *ind_msg = data; uint64_t msa_base_addr = priv->msa_pa; phys_addr_t hang_data_phy_addr; icnss_pr_dbg("Received QMI WLFW FW initialization done indication\n"); icnss_pr_dbg("Received QMI WLFW FW initialization done indication\n"); Loading @@ -1760,8 +1764,63 @@ static void fw_init_done_ind_cb(struct qmi_handle *qmi, return; return; } } /* Check if the length is valid & * the length should not be 0 and * should be <= WLFW_MAX_HANG_EVENT_DATA_SIZE(400) */ if (ind_msg->hang_data_length_valid && ind_msg->hang_data_length && ind_msg->hang_data_length <= WLFW_MAX_HANG_EVENT_DATA_SIZE) priv->hang_event_data_len = ind_msg->hang_data_length; else goto out; /* Check if the offset is valid & * the offset should be in range of 0 to msa_mem_size-hang_data_length */ if (ind_msg->hang_data_addr_offset_valid && (ind_msg->hang_data_addr_offset <= (priv->msa_mem_size - ind_msg->hang_data_length))) hang_data_phy_addr = msa_base_addr + ind_msg->hang_data_addr_offset; else goto out; if (priv->hang_event_data_pa == hang_data_phy_addr) goto exit; priv->hang_event_data_pa = hang_data_phy_addr; priv->hang_event_data_va = devm_ioremap(dev, priv->hang_event_data_pa, ind_msg->hang_data_length); if (!priv->hang_event_data_va) { icnss_pr_err("Hang Data ioremap failed: phy addr: %pa\n", &priv->hang_event_data_pa); goto fail; } exit: icnss_pr_dbg("Hang Event Data details,Offset:0x%x, Length:0x%x,va_addr: 0x%pK\n", ind_msg->hang_data_addr_offset, ind_msg->hang_data_length, priv->hang_event_data_va); goto post; out: icnss_pr_err("Invalid Hang Data details, Offset:0x%x, Length:0x%x", ind_msg->hang_data_addr_offset, ind_msg->hang_data_length); fail: priv->hang_event_data_va = NULL; priv->hang_event_data_pa = 0; priv->hang_event_data_len = 0; post: icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_FW_INIT_DONE_IND, icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_FW_INIT_DONE_IND, 0, NULL); 0, NULL); } } static void wlfw_qdss_trace_req_mem_ind_cb(struct qmi_handle *qmi, static void wlfw_qdss_trace_req_mem_ind_cb(struct qmi_handle *qmi, Loading Loading
drivers/net/wireless/cnss_utils/wlan_firmware_service_v01.c +36 −0 Original line number Original line Diff line number Diff line Loading @@ -3205,6 +3205,42 @@ struct qmi_elem_info wlfw_fw_mem_ready_ind_msg_v01_ei[] = { EXPORT_SYMBOL(wlfw_fw_mem_ready_ind_msg_v01_ei); EXPORT_SYMBOL(wlfw_fw_mem_ready_ind_msg_v01_ei); struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[] = { struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(u8), .array_type = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_fw_init_done_ind_msg_v01, hang_data_addr_offset_valid), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, .elem_size = sizeof(u32), .array_type = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_fw_init_done_ind_msg_v01, hang_data_addr_offset), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(u8), .array_type = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_fw_init_done_ind_msg_v01, hang_data_length_valid), }, { .data_type = QMI_UNSIGNED_2_BYTE, .elem_len = 1, .elem_size = sizeof(u16), .array_type = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_fw_init_done_ind_msg_v01, hang_data_length), }, { { .data_type = QMI_EOTI, .data_type = QMI_EOTI, .array_type = NO_ARRAY, .array_type = NO_ARRAY, Loading
drivers/net/wireless/cnss_utils/wlan_firmware_service_v01.h +6 −2 Original line number Original line Diff line number Diff line Loading @@ -768,9 +768,13 @@ struct wlfw_fw_mem_ready_ind_msg_v01 { extern struct qmi_elem_info wlfw_fw_mem_ready_ind_msg_v01_ei[]; extern struct qmi_elem_info wlfw_fw_mem_ready_ind_msg_v01_ei[]; struct wlfw_fw_init_done_ind_msg_v01 { struct wlfw_fw_init_done_ind_msg_v01 { char placeholder; u8 hang_data_addr_offset_valid; u32 hang_data_addr_offset; u8 hang_data_length_valid; u16 hang_data_length; }; }; #define WLFW_FW_INIT_DONE_IND_MSG_V01_MAX_MSG_LEN 0 #define WLFW_FW_INIT_DONE_IND_MSG_V01_MAX_MSG_LEN 12 extern struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[]; extern struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[]; struct wlfw_rejuvenate_ind_msg_v01 { struct wlfw_rejuvenate_ind_msg_v01 { Loading
drivers/soc/qcom/icnss2/main.c +1 −2 Original line number Original line Diff line number Diff line Loading @@ -1189,7 +1189,6 @@ static int icnss_driver_event_pd_service_down(struct icnss_priv *priv, if (priv->force_err_fatal) if (priv->force_err_fatal) ICNSS_ASSERT(0); ICNSS_ASSERT(0); if (priv->device_id == ADRASTEA_DEVICE_ID) icnss_send_hang_event_data(priv); icnss_send_hang_event_data(priv); if (priv->early_crash_ind) { if (priv->early_crash_ind) { Loading
drivers/soc/qcom/icnss2/qmi.c +59 −0 Original line number Original line Diff line number Diff line Loading @@ -1752,6 +1752,10 @@ static void fw_init_done_ind_cb(struct qmi_handle *qmi, struct qmi_txn *txn, const void *data) struct qmi_txn *txn, const void *data) { { struct icnss_priv *priv = container_of(qmi, struct icnss_priv, qmi); struct icnss_priv *priv = container_of(qmi, struct icnss_priv, qmi); struct device *dev = &priv->pdev->dev; const struct wlfw_fw_init_done_ind_msg_v01 *ind_msg = data; uint64_t msa_base_addr = priv->msa_pa; phys_addr_t hang_data_phy_addr; icnss_pr_dbg("Received QMI WLFW FW initialization done indication\n"); icnss_pr_dbg("Received QMI WLFW FW initialization done indication\n"); Loading @@ -1760,8 +1764,63 @@ static void fw_init_done_ind_cb(struct qmi_handle *qmi, return; return; } } /* Check if the length is valid & * the length should not be 0 and * should be <= WLFW_MAX_HANG_EVENT_DATA_SIZE(400) */ if (ind_msg->hang_data_length_valid && ind_msg->hang_data_length && ind_msg->hang_data_length <= WLFW_MAX_HANG_EVENT_DATA_SIZE) priv->hang_event_data_len = ind_msg->hang_data_length; else goto out; /* Check if the offset is valid & * the offset should be in range of 0 to msa_mem_size-hang_data_length */ if (ind_msg->hang_data_addr_offset_valid && (ind_msg->hang_data_addr_offset <= (priv->msa_mem_size - ind_msg->hang_data_length))) hang_data_phy_addr = msa_base_addr + ind_msg->hang_data_addr_offset; else goto out; if (priv->hang_event_data_pa == hang_data_phy_addr) goto exit; priv->hang_event_data_pa = hang_data_phy_addr; priv->hang_event_data_va = devm_ioremap(dev, priv->hang_event_data_pa, ind_msg->hang_data_length); if (!priv->hang_event_data_va) { icnss_pr_err("Hang Data ioremap failed: phy addr: %pa\n", &priv->hang_event_data_pa); goto fail; } exit: icnss_pr_dbg("Hang Event Data details,Offset:0x%x, Length:0x%x,va_addr: 0x%pK\n", ind_msg->hang_data_addr_offset, ind_msg->hang_data_length, priv->hang_event_data_va); goto post; out: icnss_pr_err("Invalid Hang Data details, Offset:0x%x, Length:0x%x", ind_msg->hang_data_addr_offset, ind_msg->hang_data_length); fail: priv->hang_event_data_va = NULL; priv->hang_event_data_pa = 0; priv->hang_event_data_len = 0; post: icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_FW_INIT_DONE_IND, icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_FW_INIT_DONE_IND, 0, NULL); 0, NULL); } } static void wlfw_qdss_trace_req_mem_ind_cb(struct qmi_handle *qmi, static void wlfw_qdss_trace_req_mem_ind_cb(struct qmi_handle *qmi, Loading