mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 12:25:00 -04:00
Merge "cnss2: Allow WLAN driver register after cold boot calibration"
This commit is contained in:
commit
b6ea26a756
5 changed files with 81 additions and 32 deletions
|
|
@ -71,8 +71,8 @@ static int cnss_stats_show_state(struct seq_file *s,
|
|||
case CNSS_FW_READY:
|
||||
seq_puts(s, "FW_READY");
|
||||
continue;
|
||||
case CNSS_COLD_BOOT_CAL:
|
||||
seq_puts(s, "COLD_BOOT_CAL");
|
||||
case CNSS_IN_COLD_BOOT_CAL:
|
||||
seq_puts(s, "IN_COLD_BOOT_CAL");
|
||||
continue;
|
||||
case CNSS_DRIVER_LOADING:
|
||||
seq_puts(s, "DRIVER_LOADING");
|
||||
|
|
@ -113,6 +113,9 @@ static int cnss_stats_show_state(struct seq_file *s,
|
|||
case CNSS_IN_REBOOT:
|
||||
seq_puts(s, "IN_REBOOT");
|
||||
continue;
|
||||
case CNSS_COLD_BOOT_CAL_DONE:
|
||||
seq_puts(s, "COLD_BOOT_CAL_DONE");
|
||||
continue;
|
||||
}
|
||||
|
||||
seq_printf(s, "UNKNOWN-%d", i);
|
||||
|
|
|
|||
|
|
@ -390,6 +390,7 @@ static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv)
|
|||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
cnss_pr_dbg("Processing FW Init Done..\n");
|
||||
del_timer(&plat_priv->fw_boot_timer);
|
||||
set_bit(CNSS_FW_READY, &plat_priv->driver_state);
|
||||
clear_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state);
|
||||
|
|
@ -402,7 +403,7 @@ static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv)
|
|||
if (test_bit(ENABLE_WALTEST, &plat_priv->ctrl_params.quirks)) {
|
||||
ret = cnss_wlfw_wlan_mode_send_sync(plat_priv,
|
||||
CNSS_WALTEST);
|
||||
} else if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state)) {
|
||||
} else if (test_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state)) {
|
||||
cnss_request_antenna_sharing(plat_priv);
|
||||
ret = cnss_wlfw_wlan_mode_send_sync(plat_priv,
|
||||
CNSS_CALIBRATION);
|
||||
|
|
@ -1273,19 +1274,30 @@ static int cnss_cold_boot_cal_start_hdlr(struct cnss_plat_data *plat_priv)
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
if (test_bit(CNSS_FW_READY, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state)) {
|
||||
cnss_pr_dbg("Device is already active, ignore calibration\n");
|
||||
if (test_bit(CNSS_COLD_BOOT_CAL_DONE, &plat_priv->driver_state)) {
|
||||
cnss_pr_dbg("Calibration complete. Ignore calibration req\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
set_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
|
||||
if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_FW_READY, &plat_priv->driver_state)) {
|
||||
cnss_pr_err("WLAN in mission mode before cold boot calibration\n");
|
||||
CNSS_ASSERT(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
set_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state);
|
||||
reinit_completion(&plat_priv->cal_complete);
|
||||
ret = cnss_bus_dev_powerup(plat_priv);
|
||||
if (ret) {
|
||||
complete(&plat_priv->cal_complete);
|
||||
clear_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
|
||||
clear_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state);
|
||||
/* Set CBC done in driver state to mark attempt and note error
|
||||
* since calibration cannot be retried at boot.
|
||||
*/
|
||||
plat_priv->cal_done = CNSS_CAL_FAILURE;
|
||||
set_bit(CNSS_COLD_BOOT_CAL_DONE, &plat_priv->driver_state);
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
@ -1297,7 +1309,7 @@ static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv,
|
|||
{
|
||||
struct cnss_cal_info *cal_info = data;
|
||||
|
||||
if (!test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state))
|
||||
if (!test_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state))
|
||||
goto out;
|
||||
|
||||
switch (cal_info->cal_status) {
|
||||
|
|
@ -1306,7 +1318,9 @@ static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv,
|
|||
plat_priv->cal_done = true;
|
||||
break;
|
||||
case CNSS_CAL_TIMEOUT:
|
||||
cnss_pr_dbg("Calibration timed out, force shutdown\n");
|
||||
case CNSS_CAL_FAILURE:
|
||||
cnss_pr_dbg("Calibration failed. Status: %d, force shutdown\n",
|
||||
cal_info->cal_status);
|
||||
break;
|
||||
default:
|
||||
cnss_pr_err("Unknown calibration status: %u\n",
|
||||
|
|
@ -1320,7 +1334,8 @@ static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv,
|
|||
cnss_bus_dev_shutdown(plat_priv);
|
||||
msleep(COLD_BOOT_CAL_SHUTDOWN_DELAY_MS);
|
||||
complete(&plat_priv->cal_complete);
|
||||
clear_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
|
||||
clear_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state);
|
||||
set_bit(CNSS_COLD_BOOT_CAL_DONE, &plat_priv->driver_state);
|
||||
|
||||
out:
|
||||
kfree(data);
|
||||
|
|
@ -2022,7 +2037,7 @@ static ssize_t fs_ready_store(struct device *dev,
|
|||
return count;
|
||||
}
|
||||
|
||||
if (fs_ready == FILE_SYSTEM_READY) {
|
||||
if (fs_ready == FILE_SYSTEM_READY && plat_priv->cbc_enabled) {
|
||||
cnss_driver_event_post(plat_priv,
|
||||
CNSS_DRIVER_EVENT_COLD_BOOT_CAL_START,
|
||||
0, NULL);
|
||||
|
|
@ -2179,6 +2194,9 @@ static void cnss_init_control_params(struct cnss_plat_data *plat_priv)
|
|||
"cnss-daemon-support"))
|
||||
plat_priv->ctrl_params.quirks |= BIT(ENABLE_DAEMON_SUPPORT);
|
||||
|
||||
plat_priv->cbc_enabled =
|
||||
of_property_read_bool(plat_priv->plat_dev->dev.of_node,
|
||||
"qcom,wlan-cbc-enabled");
|
||||
plat_priv->ctrl_params.mhi_timeout = CNSS_MHI_TIMEOUT_DEFAULT;
|
||||
plat_priv->ctrl_params.mhi_m2_timeout = CNSS_MHI_M2_TIMEOUT_DEFAULT;
|
||||
plat_priv->ctrl_params.qmi_timeout = CNSS_QMI_TIMEOUT_DEFAULT;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#define CNSS_RDDM_TIMEOUT_MS 20000
|
||||
#define RECOVERY_TIMEOUT 60000
|
||||
#define WLAN_WD_TIMEOUT_MS 60000
|
||||
#define WLAN_COLD_BOOT_CAL_TIMEOUT 60000
|
||||
#define WLAN_DRIVER_LOAD_TIMEOUT 90000
|
||||
#define TIME_CLOCK_FREQ_HZ 19200000
|
||||
#define CNSS_RAMDUMP_MAGIC 0x574C414E
|
||||
#define CNSS_RAMDUMP_VERSION 0
|
||||
|
|
@ -218,23 +220,24 @@ enum cnss_driver_event_type {
|
|||
};
|
||||
|
||||
enum cnss_driver_state {
|
||||
CNSS_QMI_WLFW_CONNECTED,
|
||||
CNSS_QMI_WLFW_CONNECTED = 0,
|
||||
CNSS_FW_MEM_READY,
|
||||
CNSS_FW_READY,
|
||||
CNSS_COLD_BOOT_CAL,
|
||||
CNSS_IN_COLD_BOOT_CAL,
|
||||
CNSS_DRIVER_LOADING,
|
||||
CNSS_DRIVER_UNLOADING,
|
||||
CNSS_DRIVER_UNLOADING = 5,
|
||||
CNSS_DRIVER_IDLE_RESTART,
|
||||
CNSS_DRIVER_IDLE_SHUTDOWN,
|
||||
CNSS_DRIVER_PROBED,
|
||||
CNSS_DRIVER_RECOVERY,
|
||||
CNSS_FW_BOOT_RECOVERY,
|
||||
CNSS_FW_BOOT_RECOVERY = 10,
|
||||
CNSS_DEV_ERR_NOTIFY,
|
||||
CNSS_DRIVER_DEBUG,
|
||||
CNSS_COEX_CONNECTED,
|
||||
CNSS_IMS_CONNECTED,
|
||||
CNSS_IN_SUSPEND_RESUME,
|
||||
CNSS_IN_SUSPEND_RESUME = 15,
|
||||
CNSS_IN_REBOOT,
|
||||
CNSS_COLD_BOOT_CAL_DONE,
|
||||
};
|
||||
|
||||
struct cnss_recovery_data {
|
||||
|
|
@ -285,6 +288,7 @@ enum cnss_bdf_type {
|
|||
enum cnss_cal_status {
|
||||
CNSS_CAL_DONE,
|
||||
CNSS_CAL_TIMEOUT,
|
||||
CNSS_CAL_FAILURE,
|
||||
};
|
||||
|
||||
struct cnss_cal_info {
|
||||
|
|
@ -393,6 +397,7 @@ struct cnss_plat_data {
|
|||
u64 dynamic_feature;
|
||||
void *get_info_cb_ctx;
|
||||
int (*get_info_cb)(void *ctx, void *event, int event_len);
|
||||
bool cbc_enabled;
|
||||
u8 use_nv_mac;
|
||||
u8 set_wlaon_pwr_ctrl;
|
||||
struct kobject *shutdown_kobj;
|
||||
|
|
|
|||
|
|
@ -1497,7 +1497,7 @@ int cnss_pci_call_driver_remove(struct cnss_pci_data *pci_priv)
|
|||
|
||||
plat_priv = pci_priv->plat_priv;
|
||||
|
||||
if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state) ||
|
||||
if (test_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_DEBUG, &plat_priv->driver_state)) {
|
||||
cnss_pr_dbg("Skip driver remove\n");
|
||||
|
|
@ -1843,10 +1843,12 @@ retry:
|
|||
if (ret)
|
||||
goto stop_mhi;
|
||||
} else if (timeout) {
|
||||
if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state))
|
||||
timeout = timeout << 1;
|
||||
if (test_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state))
|
||||
timeout += WLAN_COLD_BOOT_CAL_TIMEOUT;
|
||||
else
|
||||
timeout += WLAN_DRIVER_LOAD_TIMEOUT;
|
||||
mod_timer(&plat_priv->fw_boot_timer,
|
||||
jiffies + msecs_to_jiffies(timeout << 1));
|
||||
jiffies + msecs_to_jiffies(timeout));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -2133,14 +2135,26 @@ int cnss_wlan_register_driver(struct cnss_wlan_driver *driver_ops)
|
|||
return -EEXIST;
|
||||
}
|
||||
|
||||
if (!test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state))
|
||||
if (!plat_priv->cbc_enabled ||
|
||||
test_bit(CNSS_COLD_BOOT_CAL_DONE, &plat_priv->driver_state))
|
||||
goto register_driver;
|
||||
|
||||
cnss_pr_dbg("Start to wait for calibration to complete\n");
|
||||
/* If enabled Cold Boot Calibration is the 1st step in init sequence.
|
||||
* CBC is done on file system_ready trigger. Qcacld should be loaded
|
||||
* from init.target.rc after that. Reject qcacld load from
|
||||
* vendor_modprobe.sh at early boot to satisfy this requirement.
|
||||
*/
|
||||
if (test_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state)) {
|
||||
cnss_pr_dbg("Start to wait for calibration to complete\n");
|
||||
} else {
|
||||
cnss_pr_err("Reject WLAN Driver insmod before CBC\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
timeout = cnss_get_boot_timeout(&pci_priv->pci_dev->dev);
|
||||
ret = wait_for_completion_timeout(&plat_priv->cal_complete,
|
||||
msecs_to_jiffies(timeout) << 2);
|
||||
WLAN_COLD_BOOT_CAL_TIMEOUT +
|
||||
msecs_to_jiffies(timeout));
|
||||
if (!ret) {
|
||||
cnss_pr_err("Timeout waiting for calibration to complete\n");
|
||||
if (!test_bit(CNSS_IN_REBOOT, &plat_priv->driver_state))
|
||||
|
|
@ -2156,12 +2170,11 @@ int cnss_wlan_register_driver(struct cnss_wlan_driver *driver_ops)
|
|||
0, cal_info);
|
||||
}
|
||||
|
||||
register_driver:
|
||||
if (test_bit(CNSS_IN_REBOOT, &plat_priv->driver_state)) {
|
||||
cnss_pr_dbg("Reboot or shutdown is in progress, ignore register driver\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
register_driver:
|
||||
reinit_completion(&plat_priv->power_up_complete);
|
||||
ret = cnss_driver_event_post(plat_priv,
|
||||
CNSS_DRIVER_EVENT_REGISTER_DRIVER,
|
||||
|
|
@ -3222,7 +3235,7 @@ void cnss_pci_fw_boot_timeout_hdlr(struct cnss_pci_data *pci_priv)
|
|||
if (!plat_priv)
|
||||
return;
|
||||
|
||||
if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state)) {
|
||||
if (test_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state)) {
|
||||
cnss_pr_dbg("Ignore FW ready timeout for calibration mode\n");
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,12 +78,11 @@ static int cnss_wlfw_ind_register_send_sync(struct cnss_plat_data *plat_priv)
|
|||
|
||||
req->client_id_valid = 1;
|
||||
req->client_id = WLFW_CLIENT_ID;
|
||||
req->fw_ready_enable_valid = 1;
|
||||
req->fw_ready_enable = 1;
|
||||
req->request_mem_enable_valid = 1;
|
||||
req->request_mem_enable = 1;
|
||||
req->fw_mem_ready_enable_valid = 1;
|
||||
req->fw_mem_ready_enable = 1;
|
||||
/* fw_ready indication is replaced by fw_init_done in HST/HSP */
|
||||
req->fw_init_done_enable_valid = 1;
|
||||
req->fw_init_done_enable = 1;
|
||||
req->pin_connect_result_enable_valid = 1;
|
||||
|
|
@ -1776,6 +1775,12 @@ static void cnss_wlfw_fw_mem_ready_ind_cb(struct qmi_handle *qmi_wlfw,
|
|||
0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* cnss_wlfw_fw_ready_ind_cb: FW ready indication handler (Helium arch)
|
||||
*
|
||||
* This event is not required for HST/ HSP as FW calibration done is
|
||||
* provided in QMI_WLFW_CAL_DONE_IND_V01
|
||||
*/
|
||||
static void cnss_wlfw_fw_ready_ind_cb(struct qmi_handle *qmi_wlfw,
|
||||
struct sockaddr_qrtr *sq,
|
||||
struct qmi_txn *txn, const void *data)
|
||||
|
|
@ -1784,13 +1789,18 @@ static void cnss_wlfw_fw_ready_ind_cb(struct qmi_handle *qmi_wlfw,
|
|||
container_of(qmi_wlfw, struct cnss_plat_data, qmi_wlfw);
|
||||
struct cnss_cal_info *cal_info;
|
||||
|
||||
cnss_pr_dbg("Received QMI WLFW FW ready indication\n");
|
||||
|
||||
if (!txn) {
|
||||
cnss_pr_err("Spurious indication\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (plat_priv->device_id == QCA6390_DEVICE_ID ||
|
||||
plat_priv->device_id == QCA6490_DEVICE_ID) {
|
||||
cnss_pr_dbg("Ignore FW Ready Indication for HST/HSP");
|
||||
return;
|
||||
}
|
||||
|
||||
cnss_pr_dbg("Received QMI WLFW FW ready indication.\n");
|
||||
cal_info = kzalloc(sizeof(*cal_info), GFP_KERNEL);
|
||||
if (!cal_info)
|
||||
return;
|
||||
|
|
|
|||
Loading…
Reference in a new issue