Loading drivers/net/wireless/cnss2/debug.c +47 −0 Original line number Diff line number Diff line Loading @@ -650,6 +650,51 @@ static const struct file_operations cnss_control_params_debug_fops = { .llseek = seq_lseek, }; static ssize_t cnss_dynamic_feature_write(struct file *fp, const char __user *user_buf, size_t count, loff_t *off) { struct cnss_plat_data *plat_priv = ((struct seq_file *)fp->private_data)->private; int ret = 0; u64 val; ret = kstrtou64_from_user(user_buf, count, 0, &val); if (ret) return ret; plat_priv->dynamic_feature = val; ret = cnss_wlfw_dynamic_feature_mask_send_sync(plat_priv); if (ret < 0) return ret; return count; } static int cnss_dynamic_feature_show(struct seq_file *s, void *data) { struct cnss_plat_data *cnss_priv = s->private; seq_printf(s, "dynamic_feature: 0x%llx\n", cnss_priv->dynamic_feature); return 0; } static int cnss_dynamic_feature_open(struct inode *inode, struct file *file) { return single_open(file, cnss_dynamic_feature_show, inode->i_private); } static const struct file_operations cnss_dynamic_feature_fops = { .read = seq_read, .write = cnss_dynamic_feature_write, .open = cnss_dynamic_feature_open, .owner = THIS_MODULE, .llseek = seq_lseek, }; #ifdef CONFIG_CNSS2_DEBUG static int cnss_create_debug_only_node(struct cnss_plat_data *plat_priv) { Loading @@ -665,6 +710,8 @@ static int cnss_create_debug_only_node(struct cnss_plat_data *plat_priv) &cnss_runtime_pm_debug_fops); debugfs_create_file("control_params", 0600, root_dentry, plat_priv, &cnss_control_params_debug_fops); debugfs_create_file("dynamic_feature", 0600, root_dentry, plat_priv, &cnss_dynamic_feature_fops); return 0; } Loading drivers/net/wireless/cnss2/main.h +1 −0 Original line number Diff line number Diff line Loading @@ -339,6 +339,7 @@ struct cnss_plat_data { struct qmi_handle coex_qmi; struct qmi_handle ims_qmi; struct qmi_txn txn; u64 dynamic_feature; }; #ifdef CONFIG_ARCH_QCOM Loading drivers/net/wireless/cnss2/qmi.c +64 −0 Original line number Diff line number Diff line Loading @@ -1368,6 +1368,70 @@ static int cnss_wlfw_wfc_call_status_send_sync(struct cnss_plat_data *plat_priv, return ret; } int cnss_wlfw_dynamic_feature_mask_send_sync(struct cnss_plat_data *plat_priv) { struct wlfw_dynamic_feature_mask_req_msg_v01 *req; struct wlfw_dynamic_feature_mask_resp_msg_v01 *resp; struct qmi_txn txn; int ret = 0; cnss_pr_dbg("Sending dynamic feature mask 0x%llx, state: 0x%lx\n", plat_priv->dynamic_feature, 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->mask_valid = 1; req->mask = plat_priv->dynamic_feature; ret = qmi_txn_init(&plat_priv->qmi_wlfw, &txn, wlfw_dynamic_feature_mask_resp_msg_v01_ei, resp); if (ret < 0) { cnss_pr_err("Fail to initialize txn for dynamic feature mask request: err %d\n", ret); goto out; } ret = qmi_send_request (&plat_priv->qmi_wlfw, NULL, &txn, QMI_WLFW_DYNAMIC_FEATURE_MASK_REQ_V01, WLFW_DYNAMIC_FEATURE_MASK_REQ_MSG_V01_MAX_MSG_LEN, wlfw_dynamic_feature_mask_req_msg_v01_ei, req); if (ret < 0) { qmi_txn_cancel(&txn); cnss_pr_err("Fail to send dynamic feature mask 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 dynamic feature mask request, err %d\n", ret); goto out; } if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { cnss_pr_err("Dynamic feature mask request failed, result: %d, err: %d\n", resp->resp.result, resp->resp.error); ret = -resp->resp.result; goto out; } 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 drivers/net/wireless/cnss2/qmi.h +7 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ int cnss_wlfw_ini_send_sync(struct cnss_plat_data *plat_priv, u8 fw_log_mode); int cnss_wlfw_antenna_switch_send_sync(struct cnss_plat_data *plat_priv); int cnss_wlfw_antenna_grant_send_sync(struct cnss_plat_data *plat_priv); int cnss_wlfw_dynamic_feature_mask_send_sync(struct cnss_plat_data *plat_priv); int cnss_register_coex_service(struct cnss_plat_data *plat_priv); void cnss_unregister_coex_service(struct cnss_plat_data *plat_priv); int coex_antenna_switch_to_wlan_send_sync_msg(struct cnss_plat_data *plat_priv); Loading Loading @@ -166,6 +167,12 @@ int cnss_wlfw_antenna_grant_send_sync(struct cnss_plat_data *plat_priv) return 0; } static inline int cnss_wlfw_dynamic_feature_mask_send_sync(struct cnss_plat_data *plat_priv) { return 0; } static inline int cnss_register_coex_service(struct cnss_plat_data *plat_priv) { Loading Loading
drivers/net/wireless/cnss2/debug.c +47 −0 Original line number Diff line number Diff line Loading @@ -650,6 +650,51 @@ static const struct file_operations cnss_control_params_debug_fops = { .llseek = seq_lseek, }; static ssize_t cnss_dynamic_feature_write(struct file *fp, const char __user *user_buf, size_t count, loff_t *off) { struct cnss_plat_data *plat_priv = ((struct seq_file *)fp->private_data)->private; int ret = 0; u64 val; ret = kstrtou64_from_user(user_buf, count, 0, &val); if (ret) return ret; plat_priv->dynamic_feature = val; ret = cnss_wlfw_dynamic_feature_mask_send_sync(plat_priv); if (ret < 0) return ret; return count; } static int cnss_dynamic_feature_show(struct seq_file *s, void *data) { struct cnss_plat_data *cnss_priv = s->private; seq_printf(s, "dynamic_feature: 0x%llx\n", cnss_priv->dynamic_feature); return 0; } static int cnss_dynamic_feature_open(struct inode *inode, struct file *file) { return single_open(file, cnss_dynamic_feature_show, inode->i_private); } static const struct file_operations cnss_dynamic_feature_fops = { .read = seq_read, .write = cnss_dynamic_feature_write, .open = cnss_dynamic_feature_open, .owner = THIS_MODULE, .llseek = seq_lseek, }; #ifdef CONFIG_CNSS2_DEBUG static int cnss_create_debug_only_node(struct cnss_plat_data *plat_priv) { Loading @@ -665,6 +710,8 @@ static int cnss_create_debug_only_node(struct cnss_plat_data *plat_priv) &cnss_runtime_pm_debug_fops); debugfs_create_file("control_params", 0600, root_dentry, plat_priv, &cnss_control_params_debug_fops); debugfs_create_file("dynamic_feature", 0600, root_dentry, plat_priv, &cnss_dynamic_feature_fops); return 0; } Loading
drivers/net/wireless/cnss2/main.h +1 −0 Original line number Diff line number Diff line Loading @@ -339,6 +339,7 @@ struct cnss_plat_data { struct qmi_handle coex_qmi; struct qmi_handle ims_qmi; struct qmi_txn txn; u64 dynamic_feature; }; #ifdef CONFIG_ARCH_QCOM Loading
drivers/net/wireless/cnss2/qmi.c +64 −0 Original line number Diff line number Diff line Loading @@ -1368,6 +1368,70 @@ static int cnss_wlfw_wfc_call_status_send_sync(struct cnss_plat_data *plat_priv, return ret; } int cnss_wlfw_dynamic_feature_mask_send_sync(struct cnss_plat_data *plat_priv) { struct wlfw_dynamic_feature_mask_req_msg_v01 *req; struct wlfw_dynamic_feature_mask_resp_msg_v01 *resp; struct qmi_txn txn; int ret = 0; cnss_pr_dbg("Sending dynamic feature mask 0x%llx, state: 0x%lx\n", plat_priv->dynamic_feature, 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->mask_valid = 1; req->mask = plat_priv->dynamic_feature; ret = qmi_txn_init(&plat_priv->qmi_wlfw, &txn, wlfw_dynamic_feature_mask_resp_msg_v01_ei, resp); if (ret < 0) { cnss_pr_err("Fail to initialize txn for dynamic feature mask request: err %d\n", ret); goto out; } ret = qmi_send_request (&plat_priv->qmi_wlfw, NULL, &txn, QMI_WLFW_DYNAMIC_FEATURE_MASK_REQ_V01, WLFW_DYNAMIC_FEATURE_MASK_REQ_MSG_V01_MAX_MSG_LEN, wlfw_dynamic_feature_mask_req_msg_v01_ei, req); if (ret < 0) { qmi_txn_cancel(&txn); cnss_pr_err("Fail to send dynamic feature mask 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 dynamic feature mask request, err %d\n", ret); goto out; } if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { cnss_pr_err("Dynamic feature mask request failed, result: %d, err: %d\n", resp->resp.result, resp->resp.error); ret = -resp->resp.result; goto out; } 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
drivers/net/wireless/cnss2/qmi.h +7 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ int cnss_wlfw_ini_send_sync(struct cnss_plat_data *plat_priv, u8 fw_log_mode); int cnss_wlfw_antenna_switch_send_sync(struct cnss_plat_data *plat_priv); int cnss_wlfw_antenna_grant_send_sync(struct cnss_plat_data *plat_priv); int cnss_wlfw_dynamic_feature_mask_send_sync(struct cnss_plat_data *plat_priv); int cnss_register_coex_service(struct cnss_plat_data *plat_priv); void cnss_unregister_coex_service(struct cnss_plat_data *plat_priv); int coex_antenna_switch_to_wlan_send_sync_msg(struct cnss_plat_data *plat_priv); Loading Loading @@ -166,6 +167,12 @@ int cnss_wlfw_antenna_grant_send_sync(struct cnss_plat_data *plat_priv) return 0; } static inline int cnss_wlfw_dynamic_feature_mask_send_sync(struct cnss_plat_data *plat_priv) { return 0; } static inline int cnss_register_coex_service(struct cnss_plat_data *plat_priv) { Loading