diff --git a/drivers/net/wireless/cnss2/Makefile b/drivers/net/wireless/cnss2/Makefile index c6d55eed00c6..023dd437adec 100644 --- a/drivers/net/wireless/cnss2/Makefile +++ b/drivers/net/wireless/cnss2/Makefile @@ -8,4 +8,4 @@ cnss2-y += debug.o cnss2-y += pci.o cnss2-y += power.o cnss2-y += genl.o -cnss2-$(CONFIG_CNSS2_QMI) += qmi.o wlan_firmware_service_v01.o coexistence_service_v01.o ip_multimedia_subsystem_private_service_v01.o +cnss2-$(CONFIG_CNSS2_QMI) += qmi.o wlan_firmware_service_v01.o coexistence_service_v01.o ip_multimedia_subsystem_private_service_v01.o device_management_service_v01.o diff --git a/drivers/net/wireless/cnss2/debug.c b/drivers/net/wireless/cnss2/debug.c index 4bb083bd1009..a2e0c6201217 100644 --- a/drivers/net/wireless/cnss2/debug.c +++ b/drivers/net/wireless/cnss2/debug.c @@ -122,6 +122,9 @@ static int cnss_stats_show_state(struct seq_file *s, case CNSS_QMI_DEL_SERVER: seq_puts(s, "DEL_SERVER_IN_PROGRESS"); continue; + case CNSS_QMI_DMS_CONNECTED: + seq_puts(s, "DMS_CONNECTED"); + continue; } seq_printf(s, "UNKNOWN-%d", i); diff --git a/drivers/net/wireless/cnss2/device_management_service_v01.c b/drivers/net/wireless/cnss2/device_management_service_v01.c new file mode 100644 index 000000000000..a714d64239a5 --- /dev/null +++ b/drivers/net/wireless/cnss2/device_management_service_v01.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (c) 2020, The Linux Foundation. All rights reserved. */ + +#include + +#include "device_management_service_v01.h" + +struct qmi_elem_info dms_get_mac_address_req_msg_v01_ei[] = { + { + .data_type = QMI_SIGNED_4_BYTE_ENUM, + .elem_len = 1, + .elem_size = sizeof(enum dms_device_mac_enum_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct + dms_get_mac_address_req_msg_v01, + device), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct qmi_elem_info dms_get_mac_address_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 + dms_get_mac_address_resp_msg_v01, + resp), + .ei_array = qmi_response_type_v01_ei, + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct + dms_get_mac_address_resp_msg_v01, + mac_address_valid), + }, + { + .data_type = QMI_DATA_LEN, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct + dms_get_mac_address_resp_msg_v01, + mac_address_len), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = QMI_DMS_MAC_ADDR_MAX_V01, + .elem_size = sizeof(u8), + .array_type = VAR_LEN_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct + dms_get_mac_address_resp_msg_v01, + mac_address), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; diff --git a/drivers/net/wireless/cnss2/device_management_service_v01.h b/drivers/net/wireless/cnss2/device_management_service_v01.h new file mode 100644 index 000000000000..ba0a40402f8c --- /dev/null +++ b/drivers/net/wireless/cnss2/device_management_service_v01.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef DEVICE_MANAGEMENT_SERVICE_V01_H +#define DEVICE_MANAGEMENT_SERVICE_V01_H + +#define DMS_SERVICE_ID_V01 0x02 +#define DMS_SERVICE_VERS_V01 0x01 + +#define QMI_DMS_GET_MAC_ADDRESS_RESP_V01 0x005C +#define QMI_DMS_GET_MAC_ADDRESS_REQ_V01 0x005C +#define QMI_DMS_MAC_ADDR_MAX_V01 8 + +enum dms_device_mac_enum_v01 { + DMS_DEVICE_MAC_ENUM_MIN_VAL_V01 = INT_MIN, + DMS_DEVICE_MAC_WLAN_V01 = 0, + DMS_DEVICE_MAC_BT_V01 = 1, + DMS_DEVICE_MAC_ENUM_MAX_VAL_V01 = INT_MAX, +}; + +struct dms_get_mac_address_req_msg_v01 { + enum dms_device_mac_enum_v01 device; +}; + +#define DMS_GET_MAC_ADDRESS_REQ_MSG_V01_MAX_MSG_LEN 7 +extern struct qmi_elem_info dms_get_mac_address_req_msg_v01_ei[]; + +struct dms_get_mac_address_resp_msg_v01 { + struct qmi_response_type_v01 resp; + u8 mac_address_valid; + u32 mac_address_len; + u8 mac_address[QMI_DMS_MAC_ADDR_MAX_V01]; +}; + +#define DMS_GET_MAC_ADDRESS_RESP_MSG_V01_MAX_MSG_LEN 19 +extern struct qmi_elem_info dms_get_mac_address_resp_msg_v01_ei[]; + +#endif diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index 1c3bc5865a7d..a509bdafd3f7 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -405,6 +405,40 @@ static void cnss_release_antenna_sharing(struct cnss_plat_data *plat_priv) coex_antenna_switch_to_mdm_send_sync_msg(plat_priv); } +#define CNSS_DMS_QMI_CONNECTION_WAIT_MS 50 +#define CNSS_DMS_QMI_CONNECTION_WAIT_RETRY 200 +static int cnss_setup_dms_mac(struct cnss_plat_data *plat_priv) +{ + u32 i; + int ret = 0; + + /* DTSI property use-nv-mac is used to force DMS MAC address for WLAN. + * Thus assert on failure to get MAC from DMS even after retries + */ + if (plat_priv->use_nv_mac) { + for (i = 0; i < CNSS_DMS_QMI_CONNECTION_WAIT_RETRY; i++) { + if (plat_priv->dms.mac_valid) + break; + + ret = cnss_qmi_get_dms_mac(plat_priv); + if (ret == 0) + break; + msleep(CNSS_DMS_QMI_CONNECTION_WAIT_MS); + } + if (!plat_priv->dms.mac_valid) { + cnss_pr_err("Unable to get MAC from DMS\n"); + CNSS_ASSERT(0); + return -EINVAL; + } + } + if (plat_priv->dms.mac_valid) + ret = + cnss_wlfw_wlan_mac_req_send_sync(plat_priv, plat_priv->dms.mac, + ARRAY_SIZE(plat_priv->dms.mac)); + + return ret; +} + static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv) { int ret = 0; @@ -432,6 +466,7 @@ static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv) ret = cnss_wlfw_wlan_mode_send_sync(plat_priv, CNSS_CALIBRATION); } else { + ret = cnss_setup_dms_mac(plat_priv); ret = cnss_bus_call_driver_probe(plat_priv); } @@ -493,6 +528,10 @@ static char *cnss_driver_event_to_str(enum cnss_driver_event_type type) return "QDSS_TRACE_SAVE"; case CNSS_DRIVER_EVENT_QDSS_TRACE_FREE: return "QDSS_TRACE_FREE"; + case CNSS_DRIVER_EVENT_DMS_SERVER_ARRIVE: + return "DMS_SERVER_ARRIVE"; + case CNSS_DRIVER_EVENT_DMS_SERVER_EXIT: + return "DMS_SERVER_EXIT"; case CNSS_DRIVER_EVENT_MAX: return "EVENT_MAX"; } @@ -1638,6 +1677,12 @@ static void cnss_driver_event_work(struct work_struct *work) case CNSS_DRIVER_EVENT_QDSS_TRACE_FREE: ret = cnss_qdss_trace_free_hdlr(plat_priv); break; + case CNSS_DRIVER_EVENT_DMS_SERVER_ARRIVE: + ret = cnss_dms_server_arrive(plat_priv, event->data); + break; + case CNSS_DRIVER_EVENT_DMS_SERVER_EXIT: + ret = cnss_dms_server_exit(plat_priv); + break; default: cnss_pr_err("Invalid driver event type: %d", event->type); @@ -2773,10 +2818,14 @@ static int cnss_probe(struct platform_device *plat_dev) if (ret) goto deinit_event_work; - ret = cnss_debugfs_create(plat_priv); + ret = cnss_dms_init(plat_priv); if (ret) goto deinit_qmi; + ret = cnss_debugfs_create(plat_priv); + if (ret) + goto deinit_dms; + ret = cnss_misc_init(plat_priv); if (ret) goto destroy_debugfs; @@ -2794,6 +2843,8 @@ static int cnss_probe(struct platform_device *plat_dev) destroy_debugfs: cnss_debugfs_destroy(plat_priv); +deinit_dms: + cnss_dms_deinit(plat_priv); deinit_qmi: cnss_qmi_deinit(plat_priv); deinit_event_work: @@ -2829,6 +2880,7 @@ static int cnss_remove(struct platform_device *plat_dev) cnss_misc_deinit(plat_priv); cnss_debugfs_destroy(plat_priv); cnss_qmi_deinit(plat_priv); + cnss_dms_deinit(plat_priv); cnss_event_work_deinit(plat_priv); cnss_remove_sysfs(plat_priv); cnss_unregister_bus_scale(plat_priv); diff --git a/drivers/net/wireless/cnss2/main.h b/drivers/net/wireless/cnss2/main.h index c58161caae33..224aaac73699 100644 --- a/drivers/net/wireless/cnss2/main.h +++ b/drivers/net/wireless/cnss2/main.h @@ -258,6 +258,8 @@ enum cnss_driver_event_type { CNSS_DRIVER_EVENT_QDSS_TRACE_REQ_MEM, CNSS_DRIVER_EVENT_QDSS_TRACE_SAVE, CNSS_DRIVER_EVENT_QDSS_TRACE_FREE, + CNSS_DRIVER_EVENT_DMS_SERVER_ARRIVE, + CNSS_DRIVER_EVENT_DMS_SERVER_EXIT, CNSS_DRIVER_EVENT_MAX, }; @@ -282,6 +284,7 @@ enum cnss_driver_state { CNSS_COLD_BOOT_CAL_DONE, CNSS_IN_PANIC, CNSS_QMI_DEL_SERVER, + CNSS_QMI_DMS_CONNECTED = 20, }; struct cnss_recovery_data { @@ -376,6 +379,11 @@ enum cnss_ce_index { CNSS_CE_COMMON, }; +struct cnss_dms_data { + u32 mac_valid; + u8 mac[QMI_WLFW_MAC_ADDR_SIZE_V01]; +}; + struct cnss_plat_data { struct platform_device *plat_dev; void *bus_priv; @@ -409,6 +417,7 @@ struct cnss_plat_data { struct workqueue_struct *event_wq; struct work_struct recovery_work; struct qmi_handle qmi_wlfw; + struct qmi_handle qmi_dms; struct wlfw_rf_chip_info chip_info; struct wlfw_rf_board_info board_info; struct wlfw_soc_info soc_info; @@ -458,6 +467,7 @@ struct cnss_plat_data { struct cnss_tcs_info tcs_info; bool fw_pcie_gen_switch; u8 pcie_gen_speed; + struct cnss_dms_data dms; }; #ifdef CONFIG_ARCH_QCOM diff --git a/drivers/net/wireless/cnss2/qmi.c b/drivers/net/wireless/cnss2/qmi.c index 13e10f3b8f73..323a9bdf65bc 100644 --- a/drivers/net/wireless/cnss2/qmi.c +++ b/drivers/net/wireless/cnss2/qmi.c @@ -27,6 +27,7 @@ #define QMI_WLFW_MAX_RECV_BUF_SIZE SZ_8K #define IMSPRIVATE_SERVICE_MAX_MSG_LEN SZ_8K +#define DMS_QMI_MAX_MSG_LEN SZ_256 #define QMI_WLFW_MAC_READY_TIMEOUT_MS 50 #define QMI_WLFW_MAC_READY_MAX_RETRY 200 @@ -752,35 +753,19 @@ out: return ret; } -static int cnss_wlfw_wlan_mac_req_send_sync(struct cnss_plat_data *plat_priv, - u8 *mac, u32 mac_len) +int cnss_wlfw_wlan_mac_req_send_sync(struct cnss_plat_data *plat_priv, + u8 *mac, u32 mac_len) { - struct wlfw_mac_addr_req_msg_v01 *req; - struct wlfw_mac_addr_resp_msg_v01 *resp; + struct wlfw_mac_addr_req_msg_v01 req; + struct wlfw_mac_addr_resp_msg_v01 resp = {0}; struct qmi_txn txn; int ret; - u8 is_query; - if (!plat_priv) - return -ENODEV; - - /* NULL mac && zero mac_len means querying the status of MAC in FW */ - if ((mac && mac_len != QMI_WLFW_MAC_ADDR_SIZE_V01) || - (!mac && mac_len != 0)) + if (!plat_priv || !mac || mac_len != QMI_WLFW_MAC_ADDR_SIZE_V01) return -EINVAL; - req = kzalloc(sizeof(*req), GFP_KERNEL); - if (!req) - return -ENOMEM; - - resp = kzalloc(sizeof(*resp), GFP_KERNEL); - if (!resp) { - kfree(req); - return -ENOMEM; - } - ret = qmi_txn_init(&plat_priv->qmi_wlfw, &txn, - wlfw_mac_addr_resp_msg_v01_ei, resp); + wlfw_mac_addr_resp_msg_v01_ei, &resp); if (ret < 0) { cnss_pr_err("Failed to initialize txn for mac req, err: %d\n", ret); @@ -788,25 +773,18 @@ static int cnss_wlfw_wlan_mac_req_send_sync(struct cnss_plat_data *plat_priv, goto out; } - is_query = !mac; - if (!is_query) { - /* DO NOT print this for mac query, that might be too many */ cnss_pr_dbg("Sending WLAN mac req [%pM], state: 0x%lx\n", mac, plat_priv->driver_state); - memcpy(req->mac_addr, mac, mac_len); - - /* 0 - query status of wlfw MAC; 1 - set wlfw MAC */ - req->mac_addr_valid = 1; - } + memcpy(req.mac_addr, mac, mac_len); + req.mac_addr_valid = 1; ret = qmi_send_request(&plat_priv->qmi_wlfw, NULL, &txn, QMI_WLFW_MAC_ADDR_REQ_V01, WLFW_MAC_ADDR_REQ_MSG_V01_MAX_MSG_LEN, - wlfw_mac_addr_req_msg_v01_ei, req); + wlfw_mac_addr_req_msg_v01_ei, &req); if (ret < 0) { qmi_txn_cancel(&txn); cnss_pr_err("Failed to send mac req, err: %d\n", ret); - ret = -EIO; goto out; } @@ -815,68 +793,19 @@ static int cnss_wlfw_wlan_mac_req_send_sync(struct cnss_plat_data *plat_priv, if (ret < 0) { cnss_pr_err("Failed to wait for resp of mac req, err: %d\n", ret); - ret = -EIO; goto out; } - if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { + if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { cnss_pr_err("WLAN mac req failed, result: %d, err: %d\n", - resp->resp.result); - - ret = -EIO; - goto out; + resp.resp.result); + ret = -resp.resp.result; } - - if (resp->resp.error != QMI_ERR_NONE_V01) { - ret = ((resp->resp.error == QMI_ERR_NETWORK_NOT_READY_V01 && - is_query) ? -EAGAIN : -EIO); - if (ret != -EAGAIN) - cnss_pr_err("Got error resp for mac req, err: %d\n", - resp->resp.error); - goto out; - } - - cnss_pr_dbg("WLAN mac req completed\n"); - out: - kfree(req); - kfree(resp); return ret; } -static void cnss_wait_for_wlfw_mac_ready(struct cnss_plat_data *plat_priv) -{ - int ret, retry = 0; - - if (!plat_priv) - return; - - cnss_pr_dbg("Checking wlfw mac, state: 0x%lx\n", - plat_priv->driver_state); - do { - /* query the current status of WLAN MAC */ - ret = cnss_wlfw_wlan_mac_req_send_sync(plat_priv, NULL, 0); - if (!ret) { - cnss_pr_dbg("wlfw mac is ready\n"); - break; - } - - if (ret != -EAGAIN) { - cnss_pr_err("failed to query wlfw mac, error: %d\n", - ret); - break; - } - - if (++retry >= QMI_WLFW_MAC_READY_MAX_RETRY) { - cnss_pr_err("Timeout to wait for wlfw mac ready\n"); - break; - } - - msleep(QMI_WLFW_MAC_READY_TIMEOUT_MS); - } while (true); -} - int cnss_wlfw_wlan_mode_send_sync(struct cnss_plat_data *plat_priv, enum cnss_driver_mode mode) { @@ -888,9 +817,6 @@ int cnss_wlfw_wlan_mode_send_sync(struct cnss_plat_data *plat_priv, if (!plat_priv) return -ENODEV; - if (mode == CNSS_MISSION && plat_priv->use_nv_mac) - cnss_wait_for_wlfw_mac_ready(plat_priv); - cnss_pr_dbg("Sending mode message, mode: %s(%d), state: 0x%lx\n", cnss_qmi_mode_to_str(mode), mode, plat_priv->driver_state); @@ -2467,14 +2393,15 @@ int cnss_qmi_init(struct cnss_plat_data *plat_priv) QMI_WLFW_MAX_RECV_BUF_SIZE, &qmi_wlfw_ops, qmi_wlfw_msg_handlers); if (ret < 0) { - cnss_pr_err("Failed to initialize QMI handle, err: %d\n", ret); + cnss_pr_err("Failed to initialize WLFW QMI handle, err: %d\n", + ret); goto out; } ret = qmi_add_lookup(&plat_priv->qmi_wlfw, WLFW_SERVICE_ID_V01, WLFW_SERVICE_VERS_V01, WLFW_SERVICE_INS_ID_V01); if (ret < 0) - cnss_pr_err("Failed to add QMI lookup, err: %d\n", ret); + cnss_pr_err("Failed to add WLFW QMI lookup, err: %d\n", ret); out: return ret; @@ -2485,6 +2412,181 @@ void cnss_qmi_deinit(struct cnss_plat_data *plat_priv) qmi_handle_release(&plat_priv->qmi_wlfw); } +int cnss_qmi_get_dms_mac(struct cnss_plat_data *plat_priv) +{ + struct dms_get_mac_address_req_msg_v01 req; + struct dms_get_mac_address_resp_msg_v01 resp; + struct qmi_txn txn; + int ret = 0; + + if (!test_bit(CNSS_QMI_DMS_CONNECTED, &plat_priv->driver_state)) { + cnss_pr_err("DMS QMI connection not established\n"); + return -EINVAL; + } + cnss_pr_dbg("Requesting DMS MAC address"); + + memset(&resp, 0, sizeof(resp)); + ret = qmi_txn_init(&plat_priv->qmi_dms, &txn, + dms_get_mac_address_resp_msg_v01_ei, &resp); + if (ret < 0) { + cnss_pr_err("Failed to initialize txn for dms, err: %d\n", + ret); + goto out; + } + req.device = DMS_DEVICE_MAC_WLAN_V01; + ret = qmi_send_request(&plat_priv->qmi_dms, NULL, &txn, + QMI_DMS_GET_MAC_ADDRESS_REQ_V01, + DMS_GET_MAC_ADDRESS_REQ_MSG_V01_MAX_MSG_LEN, + dms_get_mac_address_req_msg_v01_ei, &req); + if (ret < 0) { + qmi_txn_cancel(&txn); + cnss_pr_err("Failed to send QMI_DMS_GET_MAC_ADDRESS_REQ_V01, err: %d\n", + ret); + goto out; + } + ret = qmi_txn_wait(&txn, QMI_WLFW_TIMEOUT_JF); + if (ret < 0) { + cnss_pr_err("Failed to wait for QMI_DMS_GET_MAC_ADDRESS_RESP_V01, err: %d\n", + ret); + goto out; + } + + if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { + cnss_pr_err("QMI_DMS_GET_MAC_ADDRESS_REQ_V01 failed, result: %d, err: %d\n", + resp.resp.result, resp.resp.error); + ret = -resp.resp.result; + goto out; + } + if (!resp.mac_address_valid || + resp.mac_address_len != QMI_WLFW_MAC_ADDR_SIZE_V01) { + cnss_pr_err("Invalid MAC address received from DMS\n"); + plat_priv->dms.mac_valid = false; + goto out; + } + plat_priv->dms.mac_valid = true; + memcpy(plat_priv->dms.mac, resp.mac_address, QMI_WLFW_MAC_ADDR_SIZE_V01); + cnss_pr_info("Received DMS MAC: [%pM]\n", plat_priv->dms.mac); +out: + return ret; +} + +static int cnss_dms_connect_to_server(struct cnss_plat_data *plat_priv, + void *data) +{ + struct cnss_qmi_event_server_arrive_data *event_data = data; + struct qmi_handle *qmi_dms = &plat_priv->qmi_dms; + struct sockaddr_qrtr sq = {0}; + int ret = 0; + + if (!event_data) + return -EINVAL; + + sq.sq_family = AF_QIPCRTR; + sq.sq_node = event_data->node; + sq.sq_port = event_data->port; + kfree(data); + + ret = kernel_connect(qmi_dms->sock, (struct sockaddr *)&sq, + sizeof(sq), 0); + if (ret < 0) { + cnss_pr_err("Failed to connect to QMI DMS remote service port\n"); + goto out; + } + + set_bit(CNSS_QMI_DMS_CONNECTED, &plat_priv->driver_state); + cnss_pr_info("QMI DMS service connected, state: 0x%lx\n", + plat_priv->driver_state); + cnss_qmi_get_dms_mac(plat_priv); +out: + return ret; +} + +int cnss_dms_server_arrive(struct cnss_plat_data *plat_priv, void *data) +{ + int ret = 0; + + if (!plat_priv) { + cnss_pr_err("Platform not initialized on DMS server arrive\n"); + return -ENODEV; + } + ret = cnss_dms_connect_to_server(plat_priv, data); + return ret; +} + +int cnss_dms_server_exit(struct cnss_plat_data *plat_priv) +{ + if (!plat_priv) + return -ENODEV; + + clear_bit(CNSS_QMI_DMS_CONNECTED, &plat_priv->driver_state); + cnss_pr_info("QMI DMS service disconnected, state: 0x%lx\n", + plat_priv->driver_state); + return 0; +} + +static int dms_new_server(struct qmi_handle *qmi_dms, + struct qmi_service *service) +{ + struct cnss_plat_data *plat_priv = + container_of(qmi_dms, struct cnss_plat_data, qmi_dms); + struct cnss_qmi_event_server_arrive_data *event_data; + + cnss_pr_err("DMS server arriving: node %u port %u\n", + service->node, service->port); + + event_data = kzalloc(sizeof(*event_data), GFP_KERNEL); + if (!event_data) + return -ENOMEM; + + event_data->node = service->node; + event_data->port = service->port; + + cnss_driver_event_post(plat_priv, CNSS_DRIVER_EVENT_DMS_SERVER_ARRIVE, + 0, event_data); + + return 0; +} + +static void dms_del_server(struct qmi_handle *qmi_dms, + struct qmi_service *service) +{ + struct cnss_plat_data *plat_priv = + container_of(qmi_dms, struct cnss_plat_data, qmi_dms); + + cnss_pr_dbg("DMS server exiting\n"); + cnss_driver_event_post(plat_priv, CNSS_DRIVER_EVENT_DMS_SERVER_EXIT, 0, + NULL); +} + +static struct qmi_ops qmi_dms_ops = { + .new_server = dms_new_server, + .del_server = dms_del_server, +}; + +int cnss_dms_init(struct cnss_plat_data *plat_priv) +{ + int ret = 0; + + ret = qmi_handle_init(&plat_priv->qmi_dms, DMS_QMI_MAX_MSG_LEN, + &qmi_dms_ops, NULL); + if (ret < 0) { + cnss_pr_err("Failed to initialize DMS handle, err: %d\n", ret); + goto out; + } + + ret = qmi_add_lookup(&plat_priv->qmi_dms, DMS_SERVICE_ID_V01, + DMS_SERVICE_VERS_V01, 0); + if (ret < 0) + cnss_pr_err("Failed to add DMS lookup, err: %d\n", ret); +out: + return ret; +} + +void cnss_dms_deinit(struct cnss_plat_data *plat_priv) +{ + qmi_handle_release(&plat_priv->qmi_dms); +} + int coex_antenna_switch_to_wlan_send_sync_msg(struct cnss_plat_data *plat_priv) { int ret; diff --git a/drivers/net/wireless/cnss2/qmi.h b/drivers/net/wireless/cnss2/qmi.h index 9413a93dac70..0b39ffd8d46f 100644 --- a/drivers/net/wireless/cnss2/qmi.h +++ b/drivers/net/wireless/cnss2/qmi.h @@ -31,6 +31,7 @@ struct cnss_qmi_event_qdss_trace_save_data { #ifdef CONFIG_CNSS2_QMI #include "coexistence_service_v01.h" #include "ip_multimedia_subsystem_private_service_v01.h" +#include "device_management_service_v01.h" int cnss_qmi_init(struct cnss_plat_data *plat_priv); void cnss_qmi_deinit(struct cnss_plat_data *plat_priv); @@ -69,6 +70,13 @@ int cnss_register_ims_service(struct cnss_plat_data *plat_priv); void cnss_unregister_ims_service(struct cnss_plat_data *plat_priv); int cnss_wlfw_send_pcie_gen_speed_sync(struct cnss_plat_data *plat_priv); void cnss_ignore_qmi_failure(bool ignore); +int cnss_qmi_get_dms_mac(struct cnss_plat_data *plat_priv); +int cnss_wlfw_wlan_mac_req_send_sync(struct cnss_plat_data *plat_priv, + u8 *mac, u32 mac_len); +int cnss_dms_server_arrive(struct cnss_plat_data *plat_priv, void *data); +int cnss_dms_server_exit(struct cnss_plat_data *plat_priv); +int cnss_dms_init(struct cnss_plat_data *plat_priv); +void cnss_dms_deinit(struct cnss_plat_data *plat_priv); #else #define QMI_WLFW_TIMEOUT_MS 10000 @@ -222,6 +230,34 @@ void cnss_unregister_ims_service(struct cnss_plat_data *plat_priv) {} static inline int cnss_wlfw_send_pcie_gen_speed_sync(struct cnss_plat_data *plat_priv) {} void cnss_ignore_qmi_failure(bool ignore) {}; +static inline int cnss_qmi_get_dms_mac(struct cnss_plat_data *plat_priv) +{ + return 0; +} + +int cnss_wlfw_wlan_mac_req_send_sync(struct cnss_plat_data *plat_priv, + u8 *mac, u32 mac_len) +{ + return 0; +} + +static inline +int cnss_dms_server_arrive(struct cnss_plat_data *plat_priv, void *data) +{ + return 0; +} + +static inline int cnss_dms_server_exit(struct cnss_plat_data *plat_priv) +{ + return 0; +} + +static inline int cnss_dms_init(struct cnss_plat_data *plat_priv) +{ + return 0; +} + +static inline void cnss_dms_deinit(struct cnss_plat_data *plat_priv) {} #endif /* CONFIG_CNSS2_QMI */ #endif /* _CNSS_QMI_H */