Loading drivers/net/wireless/cnss2/main.c +96 −65 Original line number Original line Diff line number Diff line Loading @@ -573,7 +573,7 @@ static int cnss_driver_call_probe(struct cnss_plat_data *plat_priv) struct cnss_pci_data *pci_priv = plat_priv->bus_priv; struct cnss_pci_data *pci_priv = plat_priv->bus_priv; if (!plat_priv->driver_ops) { if (!plat_priv->driver_ops) { cnss_pr_err("driver_ops is NULL!"); cnss_pr_err("driver_ops is NULL\n"); ret = -EINVAL; ret = -EINVAL; goto out; goto out; } } Loading @@ -587,7 +587,7 @@ static int cnss_driver_call_probe(struct cnss_plat_data *plat_priv) goto out; goto out; } } clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state); clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state); } else { } else if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state)) { ret = plat_priv->driver_ops->probe(pci_priv->pci_dev, ret = plat_priv->driver_ops->probe(pci_priv->pci_dev, pci_priv->pci_device_id); pci_priv->pci_device_id); if (ret) { if (ret) { Loading @@ -605,6 +605,25 @@ out: return ret; return ret; } } static int cnss_driver_call_remove(struct cnss_plat_data *plat_priv) { struct cnss_pci_data *pci_priv = plat_priv->bus_priv; if (!plat_priv->driver_ops) { cnss_pr_err("driver_ops is NULL\n"); return -EINVAL; } if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) { plat_priv->driver_ops->shutdown(pci_priv->pci_dev); } else if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) { plat_priv->driver_ops->remove(pci_priv->pci_dev); clear_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state); } return 0; } static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv) static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv) { { int ret = 0; int ret = 0; Loading @@ -626,8 +645,11 @@ static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv) } else if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state)) { } else if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state)) { ret = cnss_wlfw_wlan_mode_send_sync(plat_priv, ret = cnss_wlfw_wlan_mode_send_sync(plat_priv, QMI_WLFW_CALIBRATION_V01); QMI_WLFW_CALIBRATION_V01); } else { } else if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) || test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) { ret = cnss_driver_call_probe(plat_priv); ret = cnss_driver_call_probe(plat_priv); } else { complete(&plat_priv->power_up_complete); } } if (ret) if (ret) Loading Loading @@ -668,6 +690,10 @@ static char *cnss_driver_event_to_str(enum cnss_driver_event_type type) return "RECOVERY"; return "RECOVERY"; case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT: case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT: return "FORCE_FW_ASSERT"; return "FORCE_FW_ASSERT"; case CNSS_DRIVER_EVENT_POWER_UP: return "POWER_UP"; case CNSS_DRIVER_EVENT_POWER_DOWN: return "POWER_DOWN"; case CNSS_DRIVER_EVENT_MAX: case CNSS_DRIVER_EVENT_MAX: return "EVENT_MAX"; return "EVENT_MAX"; } } Loading Loading @@ -746,64 +772,57 @@ out: int cnss_power_up(struct device *dev) int cnss_power_up(struct device *dev) { { int ret = 0; int ret = 0; void *bus_priv = cnss_bus_dev_to_bus_priv(dev); struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); unsigned int timeout; if (!bus_priv || !plat_priv) if (!plat_priv) { cnss_pr_err("plat_priv is NULL\n"); return -ENODEV; return -ENODEV; if (plat_priv->device_id != QCA6174_DEVICE_ID) { cnss_pr_dbg("Power up is not supported for device ID 0x%lx\n", plat_priv->device_id); return 0; } } ret = cnss_power_on_device(plat_priv); cnss_pr_dbg("Powering up device\n"); if (ret) { cnss_pr_err("Failed to power on device, err = %d\n", ret); goto err_power_on; } ret = cnss_resume_pci_link(bus_priv); ret = cnss_driver_event_post(plat_priv, if (ret) { CNSS_DRIVER_EVENT_POWER_UP, cnss_pr_err("Failed to resume PCI link, err = %d\n", ret); true, NULL); goto err_resume_link; if (ret) goto out; if (plat_priv->device_id == QCA6174_DEVICE_ID) goto out; timeout = cnss_get_qmi_timeout(); reinit_completion(&plat_priv->power_up_complete); ret = wait_for_completion_timeout(&plat_priv->power_up_complete, msecs_to_jiffies(timeout) << 2); if (!ret) { cnss_pr_err("Timeout waiting for power up to complete\n"); ret = -EAGAIN; goto out; } } return 0; return 0; err_resume_link: cnss_power_off_device(plat_priv); out: err_power_on: return ret; return ret; } } EXPORT_SYMBOL(cnss_power_up); EXPORT_SYMBOL(cnss_power_up); int cnss_power_down(struct device *dev) int cnss_power_down(struct device *dev) { { int ret = 0; void *bus_priv = cnss_bus_dev_to_bus_priv(dev); struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); if (!bus_priv || !plat_priv) if (!plat_priv) { cnss_pr_err("plat_priv is NULL\n"); return -ENODEV; return -ENODEV; if (plat_priv->device_id != QCA6174_DEVICE_ID) { cnss_pr_dbg("Power down is not supported for device ID 0x%lx\n", plat_priv->device_id); return 0; } } cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_NONE); cnss_pr_dbg("Powering down device\n"); cnss_pci_set_monitor_wake_intr(bus_priv, false); cnss_pci_set_auto_suspended(bus_priv, 0); ret = cnss_suspend_pci_link(bus_priv); return cnss_driver_event_post(plat_priv, if (ret) CNSS_DRIVER_EVENT_POWER_DOWN, cnss_pr_err("Failed to suspend PCI link, err = %d\n", ret); true, NULL); cnss_power_off_device(plat_priv); return 0; } } EXPORT_SYMBOL(cnss_power_down); EXPORT_SYMBOL(cnss_power_down); Loading Loading @@ -1024,14 +1043,11 @@ static int cnss_qca6174_shutdown(struct cnss_plat_data *plat_priv) if (!plat_priv->driver_ops) if (!plat_priv->driver_ops) return -EINVAL; return -EINVAL; if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) { cnss_driver_call_remove(plat_priv); cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_NONE); cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_NONE); plat_priv->driver_ops->remove(pci_priv->pci_dev); cnss_pci_set_monitor_wake_intr(pci_priv, false); cnss_pci_set_monitor_wake_intr(pci_priv, false); cnss_pci_set_auto_suspended(pci_priv, 0); cnss_pci_set_auto_suspended(pci_priv, 0); } else { plat_priv->driver_ops->shutdown(pci_priv->pci_dev); } ret = cnss_suspend_pci_link(pci_priv); ret = cnss_suspend_pci_link(pci_priv); if (ret) if (ret) Loading @@ -1039,10 +1055,7 @@ static int cnss_qca6174_shutdown(struct cnss_plat_data *plat_priv) cnss_power_off_device(plat_priv); cnss_power_off_device(plat_priv); if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) { clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state); clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state); clear_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state); } return ret; return ret; } } Loading Loading @@ -1134,16 +1147,13 @@ static int cnss_qca6290_shutdown(struct cnss_plat_data *plat_priv) if (!plat_priv->driver_ops) if (!plat_priv->driver_ops) return -EINVAL; return -EINVAL; if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) { cnss_driver_call_remove(plat_priv); skip_driver_remove: cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_NONE); cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_NONE); plat_priv->driver_ops->remove(pci_priv->pci_dev); cnss_pci_set_monitor_wake_intr(pci_priv, false); cnss_pci_set_monitor_wake_intr(pci_priv, false); cnss_pci_set_auto_suspended(pci_priv, 0); cnss_pci_set_auto_suspended(pci_priv, 0); } else { plat_priv->driver_ops->shutdown(pci_priv->pci_dev); } skip_driver_remove: cnss_pci_stop_mhi(pci_priv); cnss_pci_stop_mhi(pci_priv); ret = cnss_suspend_pci_link(pci_priv); ret = cnss_suspend_pci_link(pci_priv); Loading @@ -1154,11 +1164,7 @@ skip_driver_remove: clear_bit(CNSS_FW_READY, &plat_priv->driver_state); clear_bit(CNSS_FW_READY, &plat_priv->driver_state); clear_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state); clear_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state); if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) { clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state); clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state); clear_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state); } return ret; return ret; } } Loading Loading @@ -1661,6 +1667,22 @@ static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv) return 0; return 0; } } static int cnss_power_up_hdlr(struct cnss_plat_data *plat_priv) { struct cnss_subsys_info *subsys_info = &plat_priv->subsys_info; return cnss_powerup(&subsys_info->subsys_desc); } static int cnss_power_down_hdlr(struct cnss_plat_data *plat_priv) { struct cnss_subsys_info *subsys_info = &plat_priv->subsys_info; cnss_shutdown(&subsys_info->subsys_desc, false); return 0; } static void cnss_driver_event_work(struct work_struct *work) static void cnss_driver_event_work(struct work_struct *work) { { struct cnss_plat_data *plat_priv = struct cnss_plat_data *plat_priv = Loading Loading @@ -1728,6 +1750,12 @@ static void cnss_driver_event_work(struct work_struct *work) case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT: case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT: ret = cnss_force_fw_assert_hdlr(plat_priv); ret = cnss_force_fw_assert_hdlr(plat_priv); break; break; case CNSS_DRIVER_EVENT_POWER_UP: ret = cnss_power_up_hdlr(plat_priv); break; case CNSS_DRIVER_EVENT_POWER_DOWN: ret = cnss_power_down_hdlr(plat_priv); break; default: default: cnss_pr_err("Invalid driver event type: %d", cnss_pr_err("Invalid driver event type: %d", event->type); event->type); Loading Loading @@ -2226,6 +2254,8 @@ static int cnss_probe(struct platform_device *plat_dev) cnss_pr_err("Failed to init platform device wakeup source, err = %d\n", cnss_pr_err("Failed to init platform device wakeup source, err = %d\n", ret); ret); init_completion(&plat_priv->power_up_complete); cnss_pr_info("Platform driver probed successfully.\n"); cnss_pr_info("Platform driver probed successfully.\n"); return 0; return 0; Loading Loading @@ -2257,6 +2287,7 @@ static int cnss_remove(struct platform_device *plat_dev) { { struct cnss_plat_data *plat_priv = platform_get_drvdata(plat_dev); struct cnss_plat_data *plat_priv = platform_get_drvdata(plat_dev); complete_all(&plat_priv->power_up_complete); device_init_wakeup(&plat_dev->dev, false); device_init_wakeup(&plat_dev->dev, false); unregister_pm_notifier(&cnss_pm_notifier); unregister_pm_notifier(&cnss_pm_notifier); del_timer(&plat_priv->fw_boot_timer); del_timer(&plat_priv->fw_boot_timer); Loading drivers/net/wireless/cnss2/main.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -126,6 +126,8 @@ enum cnss_driver_event_type { CNSS_DRIVER_EVENT_UNREGISTER_DRIVER, CNSS_DRIVER_EVENT_UNREGISTER_DRIVER, CNSS_DRIVER_EVENT_RECOVERY, CNSS_DRIVER_EVENT_RECOVERY, CNSS_DRIVER_EVENT_FORCE_FW_ASSERT, CNSS_DRIVER_EVENT_FORCE_FW_ASSERT, CNSS_DRIVER_EVENT_POWER_UP, CNSS_DRIVER_EVENT_POWER_DOWN, CNSS_DRIVER_EVENT_MAX, CNSS_DRIVER_EVENT_MAX, }; }; Loading Loading @@ -201,6 +203,7 @@ struct cnss_plat_data { struct dentry *root_dentry; struct dentry *root_dentry; atomic_t pm_count; atomic_t pm_count; struct timer_list fw_boot_timer; struct timer_list fw_boot_timer; struct completion power_up_complete; }; }; void *cnss_bus_dev_to_bus_priv(struct device *dev); void *cnss_bus_dev_to_bus_priv(struct device *dev); Loading drivers/net/wireless/cnss2/wlan_firmware_service_v01.c +53 −0 Original line number Original line Diff line number Diff line Loading @@ -1096,6 +1096,24 @@ struct elem_info wlfw_cal_report_req_msg_v01_ei[] = { .offset = offsetof(struct wlfw_cal_report_req_msg_v01, .offset = offsetof(struct wlfw_cal_report_req_msg_v01, meta_data), meta_data), }, }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_cal_report_req_msg_v01, xo_cal_data_valid), }, { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_cal_report_req_msg_v01, xo_cal_data), }, { { .data_type = QMI_EOTI, .data_type = QMI_EOTI, .is_array = NO_ARRAY, .is_array = NO_ARRAY, Loading Loading @@ -1827,6 +1845,24 @@ struct elem_info wlfw_host_cap_req_msg_v01_ei[] = { .offset = offsetof(struct wlfw_host_cap_req_msg_v01, .offset = offsetof(struct wlfw_host_cap_req_msg_v01, daemon_support), daemon_support), }, }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_host_cap_req_msg_v01, wake_msi_valid), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_host_cap_req_msg_v01, wake_msi), }, { { .data_type = QMI_EOTI, .data_type = QMI_EOTI, .is_array = NO_ARRAY, .is_array = NO_ARRAY, Loading Loading @@ -2166,3 +2202,20 @@ struct elem_info wlfw_m3_info_resp_msg_v01_ei[] = { .is_array = QMI_COMMON_TLV_TYPE, .is_array = QMI_COMMON_TLV_TYPE, }, }, }; }; struct elem_info wlfw_xo_cal_ind_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct wlfw_xo_cal_ind_msg_v01, xo_cal_data), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, .is_array = QMI_COMMON_TLV_TYPE, }, }; drivers/net/wireless/cnss2/wlan_firmware_service_v01.h +14 −2 Original line number Original line Diff line number Diff line Loading @@ -31,6 +31,7 @@ #define QMI_WLFW_M3_INFO_RESP_V01 0x003C #define QMI_WLFW_M3_INFO_RESP_V01 0x003C #define QMI_WLFW_CAL_UPDATE_RESP_V01 0x0029 #define QMI_WLFW_CAL_UPDATE_RESP_V01 0x0029 #define QMI_WLFW_CAL_DOWNLOAD_RESP_V01 0x0027 #define QMI_WLFW_CAL_DOWNLOAD_RESP_V01 0x0027 #define QMI_WLFW_XO_CAL_IND_V01 0x003D #define QMI_WLFW_INI_RESP_V01 0x002F #define QMI_WLFW_INI_RESP_V01 0x002F #define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026 #define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026 #define QMI_WLFW_MAC_ADDR_RESP_V01 0x0033 #define QMI_WLFW_MAC_ADDR_RESP_V01 0x0033 Loading Loading @@ -339,9 +340,11 @@ extern struct elem_info wlfw_bdf_download_resp_msg_v01_ei[]; struct wlfw_cal_report_req_msg_v01 { struct wlfw_cal_report_req_msg_v01 { u32 meta_data_len; u32 meta_data_len; enum wlfw_cal_temp_id_enum_v01 meta_data[QMI_WLFW_MAX_NUM_CAL_V01]; enum wlfw_cal_temp_id_enum_v01 meta_data[QMI_WLFW_MAX_NUM_CAL_V01]; u8 xo_cal_data_valid; u8 xo_cal_data; }; }; #define WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN 24 #define WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN 28 extern struct elem_info wlfw_cal_report_req_msg_v01_ei[]; extern struct elem_info wlfw_cal_report_req_msg_v01_ei[]; struct wlfw_cal_report_resp_msg_v01 { struct wlfw_cal_report_resp_msg_v01 { Loading Loading @@ -532,9 +535,11 @@ extern struct elem_info wlfw_mac_addr_resp_msg_v01_ei[]; struct wlfw_host_cap_req_msg_v01 { struct wlfw_host_cap_req_msg_v01 { u8 daemon_support_valid; u8 daemon_support_valid; u8 daemon_support; u8 daemon_support; u8 wake_msi_valid; u32 wake_msi; }; }; #define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 4 #define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 11 extern struct elem_info wlfw_host_cap_req_msg_v01_ei[]; extern struct elem_info wlfw_host_cap_req_msg_v01_ei[]; struct wlfw_host_cap_resp_msg_v01 { struct wlfw_host_cap_resp_msg_v01 { Loading Loading @@ -642,4 +647,11 @@ struct wlfw_m3_info_resp_msg_v01 { #define WLFW_M3_INFO_RESP_MSG_V01_MAX_MSG_LEN 7 #define WLFW_M3_INFO_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_m3_info_resp_msg_v01_ei[]; extern struct elem_info wlfw_m3_info_resp_msg_v01_ei[]; struct wlfw_xo_cal_ind_msg_v01 { u8 xo_cal_data; }; #define WLFW_XO_CAL_IND_MSG_V01_MAX_MSG_LEN 4 extern struct elem_info wlfw_xo_cal_ind_msg_v01_ei[]; #endif #endif Loading
drivers/net/wireless/cnss2/main.c +96 −65 Original line number Original line Diff line number Diff line Loading @@ -573,7 +573,7 @@ static int cnss_driver_call_probe(struct cnss_plat_data *plat_priv) struct cnss_pci_data *pci_priv = plat_priv->bus_priv; struct cnss_pci_data *pci_priv = plat_priv->bus_priv; if (!plat_priv->driver_ops) { if (!plat_priv->driver_ops) { cnss_pr_err("driver_ops is NULL!"); cnss_pr_err("driver_ops is NULL\n"); ret = -EINVAL; ret = -EINVAL; goto out; goto out; } } Loading @@ -587,7 +587,7 @@ static int cnss_driver_call_probe(struct cnss_plat_data *plat_priv) goto out; goto out; } } clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state); clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state); } else { } else if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state)) { ret = plat_priv->driver_ops->probe(pci_priv->pci_dev, ret = plat_priv->driver_ops->probe(pci_priv->pci_dev, pci_priv->pci_device_id); pci_priv->pci_device_id); if (ret) { if (ret) { Loading @@ -605,6 +605,25 @@ out: return ret; return ret; } } static int cnss_driver_call_remove(struct cnss_plat_data *plat_priv) { struct cnss_pci_data *pci_priv = plat_priv->bus_priv; if (!plat_priv->driver_ops) { cnss_pr_err("driver_ops is NULL\n"); return -EINVAL; } if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) { plat_priv->driver_ops->shutdown(pci_priv->pci_dev); } else if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) { plat_priv->driver_ops->remove(pci_priv->pci_dev); clear_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state); } return 0; } static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv) static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv) { { int ret = 0; int ret = 0; Loading @@ -626,8 +645,11 @@ static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv) } else if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state)) { } else if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state)) { ret = cnss_wlfw_wlan_mode_send_sync(plat_priv, ret = cnss_wlfw_wlan_mode_send_sync(plat_priv, QMI_WLFW_CALIBRATION_V01); QMI_WLFW_CALIBRATION_V01); } else { } else if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) || test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) { ret = cnss_driver_call_probe(plat_priv); ret = cnss_driver_call_probe(plat_priv); } else { complete(&plat_priv->power_up_complete); } } if (ret) if (ret) Loading Loading @@ -668,6 +690,10 @@ static char *cnss_driver_event_to_str(enum cnss_driver_event_type type) return "RECOVERY"; return "RECOVERY"; case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT: case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT: return "FORCE_FW_ASSERT"; return "FORCE_FW_ASSERT"; case CNSS_DRIVER_EVENT_POWER_UP: return "POWER_UP"; case CNSS_DRIVER_EVENT_POWER_DOWN: return "POWER_DOWN"; case CNSS_DRIVER_EVENT_MAX: case CNSS_DRIVER_EVENT_MAX: return "EVENT_MAX"; return "EVENT_MAX"; } } Loading Loading @@ -746,64 +772,57 @@ out: int cnss_power_up(struct device *dev) int cnss_power_up(struct device *dev) { { int ret = 0; int ret = 0; void *bus_priv = cnss_bus_dev_to_bus_priv(dev); struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); unsigned int timeout; if (!bus_priv || !plat_priv) if (!plat_priv) { cnss_pr_err("plat_priv is NULL\n"); return -ENODEV; return -ENODEV; if (plat_priv->device_id != QCA6174_DEVICE_ID) { cnss_pr_dbg("Power up is not supported for device ID 0x%lx\n", plat_priv->device_id); return 0; } } ret = cnss_power_on_device(plat_priv); cnss_pr_dbg("Powering up device\n"); if (ret) { cnss_pr_err("Failed to power on device, err = %d\n", ret); goto err_power_on; } ret = cnss_resume_pci_link(bus_priv); ret = cnss_driver_event_post(plat_priv, if (ret) { CNSS_DRIVER_EVENT_POWER_UP, cnss_pr_err("Failed to resume PCI link, err = %d\n", ret); true, NULL); goto err_resume_link; if (ret) goto out; if (plat_priv->device_id == QCA6174_DEVICE_ID) goto out; timeout = cnss_get_qmi_timeout(); reinit_completion(&plat_priv->power_up_complete); ret = wait_for_completion_timeout(&plat_priv->power_up_complete, msecs_to_jiffies(timeout) << 2); if (!ret) { cnss_pr_err("Timeout waiting for power up to complete\n"); ret = -EAGAIN; goto out; } } return 0; return 0; err_resume_link: cnss_power_off_device(plat_priv); out: err_power_on: return ret; return ret; } } EXPORT_SYMBOL(cnss_power_up); EXPORT_SYMBOL(cnss_power_up); int cnss_power_down(struct device *dev) int cnss_power_down(struct device *dev) { { int ret = 0; void *bus_priv = cnss_bus_dev_to_bus_priv(dev); struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); if (!bus_priv || !plat_priv) if (!plat_priv) { cnss_pr_err("plat_priv is NULL\n"); return -ENODEV; return -ENODEV; if (plat_priv->device_id != QCA6174_DEVICE_ID) { cnss_pr_dbg("Power down is not supported for device ID 0x%lx\n", plat_priv->device_id); return 0; } } cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_NONE); cnss_pr_dbg("Powering down device\n"); cnss_pci_set_monitor_wake_intr(bus_priv, false); cnss_pci_set_auto_suspended(bus_priv, 0); ret = cnss_suspend_pci_link(bus_priv); return cnss_driver_event_post(plat_priv, if (ret) CNSS_DRIVER_EVENT_POWER_DOWN, cnss_pr_err("Failed to suspend PCI link, err = %d\n", ret); true, NULL); cnss_power_off_device(plat_priv); return 0; } } EXPORT_SYMBOL(cnss_power_down); EXPORT_SYMBOL(cnss_power_down); Loading Loading @@ -1024,14 +1043,11 @@ static int cnss_qca6174_shutdown(struct cnss_plat_data *plat_priv) if (!plat_priv->driver_ops) if (!plat_priv->driver_ops) return -EINVAL; return -EINVAL; if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) { cnss_driver_call_remove(plat_priv); cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_NONE); cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_NONE); plat_priv->driver_ops->remove(pci_priv->pci_dev); cnss_pci_set_monitor_wake_intr(pci_priv, false); cnss_pci_set_monitor_wake_intr(pci_priv, false); cnss_pci_set_auto_suspended(pci_priv, 0); cnss_pci_set_auto_suspended(pci_priv, 0); } else { plat_priv->driver_ops->shutdown(pci_priv->pci_dev); } ret = cnss_suspend_pci_link(pci_priv); ret = cnss_suspend_pci_link(pci_priv); if (ret) if (ret) Loading @@ -1039,10 +1055,7 @@ static int cnss_qca6174_shutdown(struct cnss_plat_data *plat_priv) cnss_power_off_device(plat_priv); cnss_power_off_device(plat_priv); if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) { clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state); clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state); clear_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state); } return ret; return ret; } } Loading Loading @@ -1134,16 +1147,13 @@ static int cnss_qca6290_shutdown(struct cnss_plat_data *plat_priv) if (!plat_priv->driver_ops) if (!plat_priv->driver_ops) return -EINVAL; return -EINVAL; if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) { cnss_driver_call_remove(plat_priv); skip_driver_remove: cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_NONE); cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_NONE); plat_priv->driver_ops->remove(pci_priv->pci_dev); cnss_pci_set_monitor_wake_intr(pci_priv, false); cnss_pci_set_monitor_wake_intr(pci_priv, false); cnss_pci_set_auto_suspended(pci_priv, 0); cnss_pci_set_auto_suspended(pci_priv, 0); } else { plat_priv->driver_ops->shutdown(pci_priv->pci_dev); } skip_driver_remove: cnss_pci_stop_mhi(pci_priv); cnss_pci_stop_mhi(pci_priv); ret = cnss_suspend_pci_link(pci_priv); ret = cnss_suspend_pci_link(pci_priv); Loading @@ -1154,11 +1164,7 @@ skip_driver_remove: clear_bit(CNSS_FW_READY, &plat_priv->driver_state); clear_bit(CNSS_FW_READY, &plat_priv->driver_state); clear_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state); clear_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state); if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) { clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state); clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state); clear_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state); } return ret; return ret; } } Loading Loading @@ -1661,6 +1667,22 @@ static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv) return 0; return 0; } } static int cnss_power_up_hdlr(struct cnss_plat_data *plat_priv) { struct cnss_subsys_info *subsys_info = &plat_priv->subsys_info; return cnss_powerup(&subsys_info->subsys_desc); } static int cnss_power_down_hdlr(struct cnss_plat_data *plat_priv) { struct cnss_subsys_info *subsys_info = &plat_priv->subsys_info; cnss_shutdown(&subsys_info->subsys_desc, false); return 0; } static void cnss_driver_event_work(struct work_struct *work) static void cnss_driver_event_work(struct work_struct *work) { { struct cnss_plat_data *plat_priv = struct cnss_plat_data *plat_priv = Loading Loading @@ -1728,6 +1750,12 @@ static void cnss_driver_event_work(struct work_struct *work) case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT: case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT: ret = cnss_force_fw_assert_hdlr(plat_priv); ret = cnss_force_fw_assert_hdlr(plat_priv); break; break; case CNSS_DRIVER_EVENT_POWER_UP: ret = cnss_power_up_hdlr(plat_priv); break; case CNSS_DRIVER_EVENT_POWER_DOWN: ret = cnss_power_down_hdlr(plat_priv); break; default: default: cnss_pr_err("Invalid driver event type: %d", cnss_pr_err("Invalid driver event type: %d", event->type); event->type); Loading Loading @@ -2226,6 +2254,8 @@ static int cnss_probe(struct platform_device *plat_dev) cnss_pr_err("Failed to init platform device wakeup source, err = %d\n", cnss_pr_err("Failed to init platform device wakeup source, err = %d\n", ret); ret); init_completion(&plat_priv->power_up_complete); cnss_pr_info("Platform driver probed successfully.\n"); cnss_pr_info("Platform driver probed successfully.\n"); return 0; return 0; Loading Loading @@ -2257,6 +2287,7 @@ static int cnss_remove(struct platform_device *plat_dev) { { struct cnss_plat_data *plat_priv = platform_get_drvdata(plat_dev); struct cnss_plat_data *plat_priv = platform_get_drvdata(plat_dev); complete_all(&plat_priv->power_up_complete); device_init_wakeup(&plat_dev->dev, false); device_init_wakeup(&plat_dev->dev, false); unregister_pm_notifier(&cnss_pm_notifier); unregister_pm_notifier(&cnss_pm_notifier); del_timer(&plat_priv->fw_boot_timer); del_timer(&plat_priv->fw_boot_timer); Loading
drivers/net/wireless/cnss2/main.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -126,6 +126,8 @@ enum cnss_driver_event_type { CNSS_DRIVER_EVENT_UNREGISTER_DRIVER, CNSS_DRIVER_EVENT_UNREGISTER_DRIVER, CNSS_DRIVER_EVENT_RECOVERY, CNSS_DRIVER_EVENT_RECOVERY, CNSS_DRIVER_EVENT_FORCE_FW_ASSERT, CNSS_DRIVER_EVENT_FORCE_FW_ASSERT, CNSS_DRIVER_EVENT_POWER_UP, CNSS_DRIVER_EVENT_POWER_DOWN, CNSS_DRIVER_EVENT_MAX, CNSS_DRIVER_EVENT_MAX, }; }; Loading Loading @@ -201,6 +203,7 @@ struct cnss_plat_data { struct dentry *root_dentry; struct dentry *root_dentry; atomic_t pm_count; atomic_t pm_count; struct timer_list fw_boot_timer; struct timer_list fw_boot_timer; struct completion power_up_complete; }; }; void *cnss_bus_dev_to_bus_priv(struct device *dev); void *cnss_bus_dev_to_bus_priv(struct device *dev); Loading
drivers/net/wireless/cnss2/wlan_firmware_service_v01.c +53 −0 Original line number Original line Diff line number Diff line Loading @@ -1096,6 +1096,24 @@ struct elem_info wlfw_cal_report_req_msg_v01_ei[] = { .offset = offsetof(struct wlfw_cal_report_req_msg_v01, .offset = offsetof(struct wlfw_cal_report_req_msg_v01, meta_data), meta_data), }, }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_cal_report_req_msg_v01, xo_cal_data_valid), }, { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_cal_report_req_msg_v01, xo_cal_data), }, { { .data_type = QMI_EOTI, .data_type = QMI_EOTI, .is_array = NO_ARRAY, .is_array = NO_ARRAY, Loading Loading @@ -1827,6 +1845,24 @@ struct elem_info wlfw_host_cap_req_msg_v01_ei[] = { .offset = offsetof(struct wlfw_host_cap_req_msg_v01, .offset = offsetof(struct wlfw_host_cap_req_msg_v01, daemon_support), daemon_support), }, }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_host_cap_req_msg_v01, wake_msi_valid), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_host_cap_req_msg_v01, wake_msi), }, { { .data_type = QMI_EOTI, .data_type = QMI_EOTI, .is_array = NO_ARRAY, .is_array = NO_ARRAY, Loading Loading @@ -2166,3 +2202,20 @@ struct elem_info wlfw_m3_info_resp_msg_v01_ei[] = { .is_array = QMI_COMMON_TLV_TYPE, .is_array = QMI_COMMON_TLV_TYPE, }, }, }; }; struct elem_info wlfw_xo_cal_ind_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct wlfw_xo_cal_ind_msg_v01, xo_cal_data), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, .is_array = QMI_COMMON_TLV_TYPE, }, };
drivers/net/wireless/cnss2/wlan_firmware_service_v01.h +14 −2 Original line number Original line Diff line number Diff line Loading @@ -31,6 +31,7 @@ #define QMI_WLFW_M3_INFO_RESP_V01 0x003C #define QMI_WLFW_M3_INFO_RESP_V01 0x003C #define QMI_WLFW_CAL_UPDATE_RESP_V01 0x0029 #define QMI_WLFW_CAL_UPDATE_RESP_V01 0x0029 #define QMI_WLFW_CAL_DOWNLOAD_RESP_V01 0x0027 #define QMI_WLFW_CAL_DOWNLOAD_RESP_V01 0x0027 #define QMI_WLFW_XO_CAL_IND_V01 0x003D #define QMI_WLFW_INI_RESP_V01 0x002F #define QMI_WLFW_INI_RESP_V01 0x002F #define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026 #define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026 #define QMI_WLFW_MAC_ADDR_RESP_V01 0x0033 #define QMI_WLFW_MAC_ADDR_RESP_V01 0x0033 Loading Loading @@ -339,9 +340,11 @@ extern struct elem_info wlfw_bdf_download_resp_msg_v01_ei[]; struct wlfw_cal_report_req_msg_v01 { struct wlfw_cal_report_req_msg_v01 { u32 meta_data_len; u32 meta_data_len; enum wlfw_cal_temp_id_enum_v01 meta_data[QMI_WLFW_MAX_NUM_CAL_V01]; enum wlfw_cal_temp_id_enum_v01 meta_data[QMI_WLFW_MAX_NUM_CAL_V01]; u8 xo_cal_data_valid; u8 xo_cal_data; }; }; #define WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN 24 #define WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN 28 extern struct elem_info wlfw_cal_report_req_msg_v01_ei[]; extern struct elem_info wlfw_cal_report_req_msg_v01_ei[]; struct wlfw_cal_report_resp_msg_v01 { struct wlfw_cal_report_resp_msg_v01 { Loading Loading @@ -532,9 +535,11 @@ extern struct elem_info wlfw_mac_addr_resp_msg_v01_ei[]; struct wlfw_host_cap_req_msg_v01 { struct wlfw_host_cap_req_msg_v01 { u8 daemon_support_valid; u8 daemon_support_valid; u8 daemon_support; u8 daemon_support; u8 wake_msi_valid; u32 wake_msi; }; }; #define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 4 #define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 11 extern struct elem_info wlfw_host_cap_req_msg_v01_ei[]; extern struct elem_info wlfw_host_cap_req_msg_v01_ei[]; struct wlfw_host_cap_resp_msg_v01 { struct wlfw_host_cap_resp_msg_v01 { Loading Loading @@ -642,4 +647,11 @@ struct wlfw_m3_info_resp_msg_v01 { #define WLFW_M3_INFO_RESP_MSG_V01_MAX_MSG_LEN 7 #define WLFW_M3_INFO_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_m3_info_resp_msg_v01_ei[]; extern struct elem_info wlfw_m3_info_resp_msg_v01_ei[]; struct wlfw_xo_cal_ind_msg_v01 { u8 xo_cal_data; }; #define WLFW_XO_CAL_IND_MSG_V01_MAX_MSG_LEN 4 extern struct elem_info wlfw_xo_cal_ind_msg_v01_ei[]; #endif #endif