Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4813317b authored by Sandeep Singh's avatar Sandeep Singh Committed by Manikandan Mohan
Browse files

cnss2: Setup DMS QMI client for WLAN MAC address



WLAN MAC address can be provisioned using NV memory based setup.
DMS QMI server connection is required to retrieve this MAC address.
Thus setup DMS QMI client in cnss platform driver and send this
MAC address for WLAN FW before mission mode enable.

Change-Id: I4dac4c589910a34952b0f63fd4394f5dd02315b8
Signed-off-by: default avatarSandeep Singh <sandsing@codeaurora.org>
Signed-off-by: default avatarManikandan Mohan <manikand@codeaurora.org>
parent 75a9b99e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -121,6 +121,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);
+73 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2020, The Linux Foundation. All rights reserved. */

#include <linux/soc/qcom/qmi.h>

#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,
	},
};
+39 −0
Original line number Diff line number Diff line
/* 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
+53 −1
Original line number Diff line number Diff line
@@ -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";
	}
@@ -1637,6 +1676,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);
@@ -2767,10 +2812,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;
@@ -2788,6 +2837,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:
@@ -2823,6 +2874,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);
Loading