mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-24 04:42:20 +00:00
669 lines
20 KiB
Diff
669 lines
20 KiB
Diff
Index: backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/qmi.c
|
|
===================================================================
|
|
--- backports-20210222-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/qmi.c
|
|
+++ backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/qmi.c
|
|
@@ -10,6 +10,7 @@
|
|
#include "debug.h"
|
|
#include <linux/of.h>
|
|
#include <linux/firmware.h>
|
|
+#include <linux/devcoredump.h>
|
|
|
|
#define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02
|
|
#define HOST_CSTATE_BIT 0x04
|
|
@@ -470,6 +471,24 @@ static struct qmi_elem_info qmi_wlanfw_h
|
|
.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 = 0x20,
|
|
+ .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
|
|
+ m3_dump_upload_req_enable_valid),
|
|
+ },
|
|
+ {
|
|
+ .data_type = QMI_UNSIGNED_1_BYTE,
|
|
+ .elem_len = 1,
|
|
+ .elem_size = sizeof(u8),
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = 0x20,
|
|
+ .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
|
|
+ m3_dump_upload_req_enable),
|
|
+ },
|
|
+ {
|
|
.data_type = QMI_EOTI,
|
|
.array_type = NO_ARRAY,
|
|
.tlv_type = QMI_COMMON_TLV_TYPE,
|
|
@@ -695,6 +714,24 @@ static struct qmi_elem_info qmi_wlanfw_i
|
|
cal_done_enable),
|
|
},
|
|
{
|
|
+ .data_type = QMI_OPT_FLAG,
|
|
+ .elem_len = 1,
|
|
+ .elem_size = sizeof(u8),
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = 0x20,
|
|
+ .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
|
|
+ m3_dump_upload_req_enable_valid),
|
|
+ },
|
|
+ {
|
|
+ .data_type = QMI_UNSIGNED_1_BYTE,
|
|
+ .elem_len = 1,
|
|
+ .elem_size = sizeof(u8),
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = 0x20,
|
|
+ .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
|
|
+ m3_dump_upload_req_enable),
|
|
+ },
|
|
+ {
|
|
.data_type = QMI_EOTI,
|
|
.array_type = NO_ARRAY,
|
|
.tlv_type = QMI_COMMON_TLV_TYPE,
|
|
@@ -1771,6 +1808,87 @@ static struct qmi_elem_info qmi_wlanfw_c
|
|
},
|
|
};
|
|
|
|
+static struct qmi_elem_info qmi_wlanfw_m3_dump_upload_req_ind_msg_v01_ei[] = {
|
|
+ {
|
|
+ .data_type = QMI_UNSIGNED_4_BYTE,
|
|
+ .elem_len = 1,
|
|
+ .elem_size = sizeof(u32),
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = 0x01,
|
|
+ .offset = offsetof(struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01,
|
|
+ pdev_id),
|
|
+ },
|
|
+ {
|
|
+ .data_type = QMI_UNSIGNED_8_BYTE,
|
|
+ .elem_len = 1,
|
|
+ .elem_size = sizeof(u64),
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = 0x02,
|
|
+ .offset = offsetof(struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01,
|
|
+ addr),
|
|
+ },
|
|
+ {
|
|
+ .data_type = QMI_UNSIGNED_8_BYTE,
|
|
+ .elem_len = 1,
|
|
+ .elem_size = sizeof(u64),
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = 0x03,
|
|
+ .offset = offsetof(struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01,
|
|
+ size),
|
|
+ },
|
|
+ {
|
|
+ .data_type = QMI_EOTI,
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = QMI_COMMON_TLV_TYPE,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct qmi_elem_info qmi_wlanfw_m3_dump_upload_done_req_msg_v01_ei[] = {
|
|
+ {
|
|
+ .data_type = QMI_UNSIGNED_4_BYTE,
|
|
+ .elem_len = 1,
|
|
+ .elem_size = sizeof(u32),
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = 0x01,
|
|
+ .offset = offsetof(struct
|
|
+ qmi_wlanfw_m3_dump_upload_done_req_msg_v01,
|
|
+ pdev_id),
|
|
+ },
|
|
+ {
|
|
+ .data_type = QMI_UNSIGNED_4_BYTE,
|
|
+ .elem_len = 1,
|
|
+ .elem_size = sizeof(u32),
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = 0x02,
|
|
+ .offset = offsetof(struct
|
|
+ qmi_wlanfw_m3_dump_upload_done_req_msg_v01,
|
|
+ status),
|
|
+ },
|
|
+ {
|
|
+ .data_type = QMI_EOTI,
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = QMI_COMMON_TLV_TYPE,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct qmi_elem_info qmi_wlanfw_m3_dump_upload_done_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 qmi_wlanfw_m3_dump_upload_done_resp_msg_v01,
|
|
+ resp),
|
|
+ .ei_array = qmi_response_type_v01_ei,
|
|
+ },
|
|
+ {
|
|
+ .data_type = QMI_EOTI,
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = QMI_COMMON_TLV_TYPE,
|
|
+ },
|
|
+};
|
|
+
|
|
int wlfw_send_qdss_trace_config_download_req(struct ath11k_base *ab,
|
|
const u8 *buffer, unsigned int file_len)
|
|
{
|
|
@@ -2034,6 +2152,8 @@ static int ath11k_qmi_fw_ind_register_se
|
|
req->qdss_trace_free_enable = 1;
|
|
req->pin_connect_result_enable_valid = 0;
|
|
req->pin_connect_result_enable = 0;
|
|
+ req->m3_dump_upload_req_enable_valid = 1;
|
|
+ req->m3_dump_upload_req_enable = 1;
|
|
|
|
ret = qmi_txn_init(handle, &txn,
|
|
qmi_wlanfw_ind_register_resp_msg_v01_ei, resp);
|
|
@@ -2252,6 +2372,24 @@ static int ath11k_qmi_assign_target_mem_
|
|
ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
|
|
idx++;
|
|
break;
|
|
+ case M3_DUMP_REGION_TYPE:
|
|
+ if (!ab->qmi.target_mem[i].size) {
|
|
+ ath11k_info(ab, "qmi mem size is zero\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ if (ab->qmi.target_mem[i].size > ATH11K_QMI_M3_DUMP_SIZE) {
|
|
+ ath11k_warn(ab, "qmi mem size is low to dump m3 ssr\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
|
|
+ ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
|
|
+ if (of_property_read_u32(dev->of_node, "m3-dump-addr", &addr))
|
|
+ ab->qmi.target_mem[idx].paddr = ab->hw_params.m3_addr;
|
|
+ else
|
|
+ ab->qmi.target_mem[idx].paddr = (phys_addr_t)addr;
|
|
+ idx++;
|
|
+ break;
|
|
default:
|
|
ath11k_warn(ab, "qmi ignore invalid mem req type %d\n",
|
|
ab->qmi.target_mem[i].type);
|
|
@@ -2854,6 +2992,114 @@ static int ath11k_qmi_process_coldboot_c
|
|
return 0;
|
|
}
|
|
|
|
+static int ath11k_qmi_m3_dump_upload_done_ind_send(struct ath11k_base *ab,
|
|
+ u32 pdev_id, int status)
|
|
+{
|
|
+ struct qmi_wlanfw_m3_dump_upload_done_req_msg_v01 *req;
|
|
+ struct qmi_wlanfw_m3_dump_upload_done_resp_msg_v01 *resp;
|
|
+ struct qmi_txn txn = {};
|
|
+ int ret = 0;
|
|
+
|
|
+ req = kzalloc(sizeof(*req), GFP_KERNEL);
|
|
+ if (!req)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ resp = kzalloc(sizeof(*resp), GFP_KERNEL);
|
|
+ if (!resp) {
|
|
+ kfree(req);
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
+ req->pdev_id = pdev_id;
|
|
+ req->status = status;
|
|
+
|
|
+ ret = qmi_txn_init(&ab->qmi.handle, &txn,
|
|
+ qmi_wlanfw_m3_dump_upload_done_resp_msg_v01_ei, resp);
|
|
+ if (ret < 0)
|
|
+ goto out;
|
|
+
|
|
+ ret =
|
|
+ qmi_send_request(&ab->qmi.handle, NULL, &txn,
|
|
+ QMI_WLFW_M3_DUMP_UPLOAD_DONE_REQ_V01,
|
|
+ QMI_WLANFW_M3_DUMP_UPLOAD_DONE_REQ_MSG_V01_MAX_MSG_LEN,
|
|
+ qmi_wlanfw_m3_dump_upload_done_req_msg_v01_ei, req);
|
|
+ if (ret < 0) {
|
|
+ qmi_txn_cancel(&txn);
|
|
+ ath11k_warn(ab, "Failed to send M3 dump upload done request, err %d\n",
|
|
+ ret);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
|
|
+ if (ret < 0)
|
|
+ goto out;
|
|
+
|
|
+ if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
|
|
+ ath11k_warn(ab, "qmi M3 upload done req failed, result: %d, err: %d\n",
|
|
+ resp->resp.result, resp->resp.error);
|
|
+ ret = -EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
+ ath11k_info(ab, "qmi m3 dump uploaded\n");
|
|
+
|
|
+out:
|
|
+ kfree(req);
|
|
+ kfree(resp);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static void ath11k_qmi_event_m3_dump_upload_req(struct ath11k_qmi *qmi,
|
|
+ void *data)
|
|
+{
|
|
+ struct ath11k_base *ab = qmi->ab;
|
|
+ struct target_mem_chunk *target_mem = ab->qmi.target_mem;
|
|
+ struct ath11k_qmi_m3_dump_upload_req_data *event_data = data;
|
|
+ struct ath11k_qmi_m3_dump_data *m3_dump_data;
|
|
+ void *dump;
|
|
+ int i, ret = 0;
|
|
+
|
|
+ m3_dump_data = kzalloc(sizeof(*m3_dump_data), GFP_KERNEL);
|
|
+ if (!m3_dump_data)
|
|
+ return;
|
|
+
|
|
+ dump = vzalloc(event_data->size);
|
|
+ if (!dump) {
|
|
+ kfree(m3_dump_data);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < ab->qmi.mem_seg_count; i++) {
|
|
+ if (target_mem[i].paddr == event_data->addr &&
|
|
+ event_data->size <= target_mem[i].size)
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (i == ab->qmi.mem_seg_count) {
|
|
+ ath11k_warn(ab, "qmi invalid paddr from firmware for M3 dump\n");
|
|
+ ret = -EINVAL;
|
|
+ vfree(dump);
|
|
+ goto send_resp;
|
|
+ }
|
|
+
|
|
+ m3_dump_data->addr = target_mem[i].vaddr;
|
|
+ m3_dump_data->size = event_data->size;
|
|
+ m3_dump_data->pdev_id = event_data->pdev_id;
|
|
+ m3_dump_data->timestamp = ktime_to_ms(ktime_get());
|
|
+
|
|
+ memcpy(dump, m3_dump_data->addr, m3_dump_data->size);
|
|
+
|
|
+ dev_coredumpv(ab->dev, dump, le32_to_cpu(m3_dump_data->size),
|
|
+ GFP_KERNEL);
|
|
+
|
|
+send_resp:
|
|
+ ret = ath11k_qmi_m3_dump_upload_done_ind_send(ab, event_data->pdev_id, ret);
|
|
+ if (ret < 0)
|
|
+ ath11k_warn(ab, "qmi M3 dump upload done failed\n");
|
|
+
|
|
+ kfree(m3_dump_data);
|
|
+ return;
|
|
+}
|
|
+
|
|
static int
|
|
ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi,
|
|
enum ath11k_qmi_event_type type,
|
|
@@ -3020,6 +3266,30 @@ static void ath11k_qmi_msg_cold_boot_cal
|
|
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi cold boot calibration done\n");
|
|
}
|
|
|
|
+static void ath11k_qmi_m3_dump_upload_req_ind_cb(struct qmi_handle *qmi_hdl,
|
|
+ struct sockaddr_qrtr *sq,
|
|
+ struct qmi_txn *txn,
|
|
+ const void *data)
|
|
+{
|
|
+ struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
|
|
+ struct ath11k_base *ab = qmi->ab;
|
|
+ const struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01 *msg = data;
|
|
+ struct ath11k_qmi_m3_dump_upload_req_data *event_data;
|
|
+
|
|
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi m3 dump memory request\n");
|
|
+
|
|
+ event_data = kzalloc(sizeof(*event_data), GFP_KERNEL);
|
|
+ if (!event_data)
|
|
+ return;
|
|
+
|
|
+ event_data->pdev_id = msg->pdev_id;
|
|
+ event_data->addr = msg->addr;
|
|
+ event_data->size = msg->size;
|
|
+
|
|
+ ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_M3_DUMP_UPLOAD_REQ,
|
|
+ event_data);
|
|
+}
|
|
+
|
|
static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {
|
|
{
|
|
.type = QMI_INDICATION,
|
|
@@ -3050,6 +3320,14 @@ static const struct qmi_msg_handler ath1
|
|
sizeof(struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01),
|
|
.fn = ath11k_qmi_msg_cold_boot_cal_done_cb,
|
|
},
|
|
+ {
|
|
+ .type = QMI_INDICATION,
|
|
+ .msg_id = QMI_WLFW_M3_DUMP_UPLOAD_REQ_IND_V01,
|
|
+ .ei = qmi_wlanfw_m3_dump_upload_req_ind_msg_v01_ei,
|
|
+ .decoded_size =
|
|
+ sizeof(struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01),
|
|
+ .fn = ath11k_qmi_m3_dump_upload_req_ind_cb,
|
|
+ },
|
|
};
|
|
|
|
static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
|
|
@@ -3152,6 +3430,9 @@ static void ath11k_qmi_driver_event_work
|
|
break;
|
|
case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:
|
|
break;
|
|
+ case ATH11K_QMI_EVENT_M3_DUMP_UPLOAD_REQ:
|
|
+ ath11k_qmi_event_m3_dump_upload_req(qmi, event->data);
|
|
+ break;
|
|
default:
|
|
ath11k_warn(ab, "invalid event type: %d", event->type);
|
|
break;
|
|
Index: backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/qmi.h
|
|
===================================================================
|
|
--- backports-20210222-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/qmi.h
|
|
+++ backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/qmi.h
|
|
@@ -32,11 +32,16 @@
|
|
#define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT 3
|
|
#define ATH11K_QMI_MAX_QDSS_CONFIG_FILE_NAME_SIZE 64
|
|
#define ATH11K_QMI_DEFAULT_QDSS_CONFIG_FILE_NAME "qdss_trace_config.bin"
|
|
+#define ATH11K_QMI_IPQ8074_M3_DUMP_ADDRESS 0x51000000
|
|
+#define ATH11K_QMI_IPQ6018_M3_DUMP_ADDRESS 0x50100000
|
|
+#define ATH11K_QMI_M3_DUMP_SIZE 0x100000
|
|
|
|
#define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035
|
|
#define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037
|
|
#define QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01 0x0021
|
|
#define QMI_WLFW_FW_READY_IND_V01 0x0038
|
|
+#define QMI_WLFW_M3_DUMP_UPLOAD_DONE_REQ_V01 0x004E
|
|
+#define QMI_WLFW_M3_DUMP_UPLOAD_REQ_IND_V01 0x004D
|
|
|
|
#define QMI_WLANFW_MAX_DATA_SIZE_V01 6144
|
|
#define ATH11K_FIRMWARE_MODE_OFF 4
|
|
@@ -71,6 +76,7 @@ enum ath11k_qmi_event_type {
|
|
ATH11K_QMI_EVENT_FORCE_FW_ASSERT,
|
|
ATH11K_QMI_EVENT_POWER_UP,
|
|
ATH11K_QMI_EVENT_POWER_DOWN,
|
|
+ ATH11K_QMI_EVENT_M3_DUMP_UPLOAD_REQ,
|
|
ATH11K_QMI_EVENT_MAX,
|
|
};
|
|
|
|
@@ -80,6 +86,13 @@ struct ath11k_qmi_driver_event {
|
|
void *data;
|
|
};
|
|
|
|
+struct ath11k_qmi_m3_dump_data {
|
|
+ u32 pdev_id;
|
|
+ u32 size;
|
|
+ u64 timestamp;
|
|
+ char *addr;
|
|
+};
|
|
+
|
|
struct ath11k_qmi_ce_cfg {
|
|
const struct ce_pipe_config *tgt_ce;
|
|
int tgt_ce_len;
|
|
@@ -142,6 +155,12 @@ struct ath11k_qmi {
|
|
wait_queue_head_t cold_boot_waitq;
|
|
};
|
|
|
|
+struct ath11k_qmi_m3_dump_upload_req_data {
|
|
+ u32 pdev_id;
|
|
+ u64 addr;
|
|
+ u64 size;
|
|
+};
|
|
+
|
|
#define QMI_WLANFW_QDSS_TRACE_CONFIG_DOWNLOAD_REQ_MSG_V01_MAX_LEN 6167
|
|
#define QMI_WLANFW_QDSS_TRACE_CONFIG_DOWNLOAD_RESP_MSG_V01_MAX_LEN 7
|
|
#define QMI_WLANFW_QDSS_TRACE_CONFIG_DOWNLOAD_REQ_V01 0x0044
|
|
@@ -163,6 +182,15 @@ struct qmi_wlanfw_qdss_trace_config_down
|
|
struct qmi_response_type_v01 resp;
|
|
};
|
|
|
|
+struct qmi_wlanfw_m3_dump_upload_done_req_msg_v01 {
|
|
+ u32 pdev_id;
|
|
+ u32 status;
|
|
+};
|
|
+
|
|
+struct qmi_wlanfw_m3_dump_upload_done_resp_msg_v01 {
|
|
+ struct qmi_response_type_v01 resp;
|
|
+};
|
|
+
|
|
#define QMI_WLANFW_QDSS_TRACE_MODE_REQ_V01 0x0045
|
|
#define QMI_WLANFW_QDSS_TRACE_MODE_REQ_MSG_V01_MAX_LEN 18
|
|
#define QMI_WLANFW_QDSS_TRACE_MODE_RESP_MSG_V01_MAX_LEN 7
|
|
@@ -270,6 +298,10 @@ struct qmi_wlanfw_ind_register_req_msg_v
|
|
u8 qdss_trace_save_enable;
|
|
u8 qdss_trace_free_enable_valid;
|
|
u8 qdss_trace_free_enable;
|
|
+ u8 respond_get_info_enable_valid;
|
|
+ u8 respond_get_info_enable;
|
|
+ u8 m3_dump_upload_req_enable_valid;
|
|
+ u8 m3_dump_upload_req_enable;
|
|
};
|
|
|
|
struct qmi_wlanfw_ind_register_resp_msg_v01 {
|
|
@@ -343,6 +375,12 @@ struct qmi_wlanfw_fw_cold_cal_done_ind_m
|
|
char placeholder;
|
|
};
|
|
|
|
+struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01 {
|
|
+ u32 pdev_id;
|
|
+ u64 addr;
|
|
+ u64 size;
|
|
+};
|
|
+
|
|
#define QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN 0
|
|
#define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 235
|
|
#define QMI_WLANFW_CAP_REQ_V01 0x0024
|
|
@@ -473,6 +511,8 @@ struct qmi_wlanfw_bdf_download_resp_msg_
|
|
#define QMI_WLANFW_M3_INFO_RESP_V01 0x003C
|
|
#define QMI_WLANFW_M3_INFO_REQ_V01 0x003C
|
|
|
|
+#define QMI_WLANFW_M3_DUMP_UPLOAD_DONE_REQ_MSG_V01_MAX_MSG_LEN 14
|
|
+
|
|
struct qmi_wlanfw_m3_info_req_msg_v01 {
|
|
u64 addr;
|
|
u32 size;
|
|
Index: backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/core.h
|
|
===================================================================
|
|
--- backports-20210222-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/core.h
|
|
+++ backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/core.h
|
|
@@ -467,6 +467,7 @@ struct ath11k_debug {
|
|
bool is_pkt_logging;
|
|
#endif
|
|
u32 rx_filter;
|
|
+ bool enable_m3_dump;
|
|
};
|
|
|
|
struct ath11k_per_peer_tx_stats {
|
|
Index: backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/debugfs.c
|
|
===================================================================
|
|
--- backports-20210222-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/debugfs.c
|
|
+++ backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/debugfs.c
|
|
@@ -1679,6 +1679,68 @@ static const struct file_operations fops
|
|
.open = simple_open
|
|
};
|
|
|
|
+static ssize_t ath11k_write_enable_m3_dump(struct file *file,
|
|
+ const char __user *ubuf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ath11k *ar = file->private_data;
|
|
+ bool enable;
|
|
+ int ret;
|
|
+
|
|
+ if (kstrtobool_from_user(ubuf, count, &enable))
|
|
+ return -EINVAL;
|
|
+
|
|
+ mutex_lock(&ar->conf_mutex);
|
|
+
|
|
+ if (ar->state != ATH11K_STATE_ON) {
|
|
+ ret = -ENETDOWN;
|
|
+ goto exit;
|
|
+ }
|
|
+
|
|
+ if (enable == ar->debug.enable_m3_dump) {
|
|
+ ret = count;
|
|
+ goto exit;
|
|
+ }
|
|
+
|
|
+ ret = ath11k_wmi_pdev_m3_dump_enable(ar, enable);
|
|
+ if (ret) {
|
|
+ ath11k_warn(ar->ab,
|
|
+ "failed to enable m3 ssr dump %d\n",
|
|
+ ret);
|
|
+ goto exit;
|
|
+ }
|
|
+
|
|
+ ar->debug.enable_m3_dump = enable;
|
|
+ ret = count;
|
|
+
|
|
+exit:
|
|
+ mutex_unlock(&ar->conf_mutex);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static ssize_t ath11k_read_enable_m3_dump(struct file *file,
|
|
+ char __user *ubuf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ath11k *ar = file->private_data;
|
|
+ char buf[32];
|
|
+ size_t len = 0;
|
|
+
|
|
+ mutex_lock(&ar->conf_mutex);
|
|
+ len = scnprintf(buf, sizeof(buf) - len, "%d\n",
|
|
+ ar->debug.enable_m3_dump);
|
|
+ mutex_unlock(&ar->conf_mutex);
|
|
+
|
|
+ return simple_read_from_buffer(ubuf, count, ppos, buf, len);
|
|
+
|
|
+}
|
|
+
|
|
+static const struct file_operations fops_enable_m3_dump = {
|
|
+ .read = ath11k_read_enable_m3_dump,
|
|
+ .write = ath11k_write_enable_m3_dump,
|
|
+ .open = simple_open
|
|
+};
|
|
+
|
|
int ath11k_debugfs_register(struct ath11k *ar)
|
|
{
|
|
struct ath11k_base *ab = ar->ab;
|
|
@@ -1737,6 +1799,10 @@ int ath11k_debugfs_register(struct ath11
|
|
&ar->dfs_block_radar_events);
|
|
}
|
|
|
|
+ debugfs_create_file("enable_m3_dump", 0644,
|
|
+ ar->debug.debugfs_pdev, ar,
|
|
+ &fops_enable_m3_dump);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
Index: backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/wmi.c
|
|
===================================================================
|
|
--- backports-20210222-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/wmi.c
|
|
+++ backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/wmi.c
|
|
@@ -7838,6 +7838,36 @@ int ath11k_wmi_simulate_radar(struct ath
|
|
return ath11k_wmi_send_unit_test_cmd(ar, wmi_ut, dfs_args);
|
|
}
|
|
|
|
+int ath11k_wmi_pdev_m3_dump_enable(struct ath11k *ar, u32 enable) {
|
|
+ struct ath11k_vif *arvif;
|
|
+ u32 m3_args[WMI_M3_MAX_TEST_ARGS];
|
|
+ struct wmi_unit_test_cmd wmi_ut;
|
|
+ bool arvif_found = false;
|
|
+
|
|
+ list_for_each_entry(arvif, &ar->arvifs, list) {
|
|
+ if (arvif->is_started) {
|
|
+ arvif_found = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!arvif_found)
|
|
+ return -EINVAL;
|
|
+
|
|
+ m3_args[WMI_M3_TEST_CMDID] = WMI_DBG_ENABLE_M3_SSR;
|
|
+ m3_args[WMI_M3_TEST_ENABLE] = enable;
|
|
+
|
|
+ wmi_ut.vdev_id = arvif->vdev_id;
|
|
+ wmi_ut.module_id = WMI_M3_UNIT_TEST_MODULE;
|
|
+ wmi_ut.num_args = WMI_M3_MAX_TEST_ARGS;
|
|
+ wmi_ut.diag_token = WMI_M3_UNIT_TEST_TOKEN;
|
|
+
|
|
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "%s M3 SSR dump\n",
|
|
+ enable ? "Enabling" : "Disabling");
|
|
+
|
|
+ return ath11k_wmi_send_unit_test_cmd(ar, wmi_ut, m3_args);
|
|
+}
|
|
+
|
|
int ath11k_wmi_connect(struct ath11k_base *ab)
|
|
{
|
|
u32 i;
|
|
Index: backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/wmi.h
|
|
===================================================================
|
|
--- backports-20210222-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/wmi.h
|
|
+++ backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/wmi.h
|
|
@@ -2078,6 +2078,11 @@ enum wmi_tlv_service {
|
|
WMI_MAX_EXT_SERVICE
|
|
};
|
|
|
|
+enum wmi_unit_test_cmdid {
|
|
+ /* TODO: Add the remaining cmd ids if needed */
|
|
+ WMI_DBG_ENABLE_M3_SSR = 36,
|
|
+};
|
|
+
|
|
enum {
|
|
WMI_SMPS_FORCED_MODE_NONE = 0,
|
|
WMI_SMPS_FORCED_MODE_DISABLED,
|
|
@@ -3921,6 +3926,15 @@ struct wmi_dfs_unit_test_arg {
|
|
u32 radar_param;
|
|
};
|
|
|
|
+#define WMI_M3_UNIT_TEST_MODULE 0x22
|
|
+#define WMI_M3_UNIT_TEST_TOKEN 0
|
|
+
|
|
+enum wmi_m3_test_args_idx {
|
|
+ WMI_M3_TEST_CMDID,
|
|
+ WMI_M3_TEST_ENABLE,
|
|
+ WMI_M3_MAX_TEST_ARGS,
|
|
+};
|
|
+
|
|
struct wmi_unit_test_cmd {
|
|
u32 tlv_header;
|
|
u32 vdev_id;
|
|
@@ -5653,5 +5667,6 @@ int ath11k_wmi_set_hw_mode(struct ath11k
|
|
enum wmi_host_hw_mode_config_type mode);
|
|
int ath11k_wmi_wow_host_wakeup_ind(struct ath11k *ar);
|
|
int ath11k_wmi_wow_enable(struct ath11k *ar);
|
|
+int ath11k_wmi_pdev_m3_dump_enable(struct ath11k *ar, u32 enable);
|
|
|
|
#endif
|
|
Index: backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/core.c
|
|
===================================================================
|
|
--- backports-20210222-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/core.c
|
|
+++ backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/core.c
|
|
@@ -43,6 +43,7 @@ static const struct ath11k_hw_params ath
|
|
.bdf_addr = 0x4B0C0000,
|
|
.hw_ops = &ipq8074_ops,
|
|
.credit_flow = false,
|
|
+ .m3_addr = ATH11K_QMI_IPQ8074_M3_DUMP_ADDRESS,
|
|
.ring_mask = &ath11k_hw_ring_mask_ipq8074,
|
|
.internal_sleep_clock = false,
|
|
.regs = &ipq8074_regs,
|
|
@@ -84,6 +85,7 @@ static const struct ath11k_hw_params ath
|
|
.bdf_addr = 0x4ABC0000,
|
|
.hw_ops = &ipq6018_ops,
|
|
.credit_flow = false,
|
|
+ .m3_addr = ATH11K_QMI_IPQ6018_M3_DUMP_ADDRESS,
|
|
.ring_mask = &ath11k_hw_ring_mask_ipq8074,
|
|
.internal_sleep_clock = false,
|
|
.regs = &ipq8074_regs,
|
|
Index: backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/hw.h
|
|
===================================================================
|
|
--- backports-20210222-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/hw.h
|
|
+++ backports-20210222-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/hw.h
|
|
@@ -166,6 +166,7 @@ struct ath11k_hw_params {
|
|
bool cold_boot_calib;
|
|
bool supports_suspend;
|
|
u32 hal_desc_sz;
|
|
+ u32 m3_addr;
|
|
};
|
|
|
|
struct ath11k_hw_ops {
|