File Index
Files and directories
Sign in
FILE

qmi.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/ath/ath12k/qmi.c C
   1// SPDX-License-Identifier: BSD-3-Clause-Clear
   2/*
   3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
   4 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
   5 */
   6
   7#include <linux/elf.h>
   8
   9#include "qmi.h"
  10#include "core.h"
  11#include "debug.h"
  12#include <linux/of.h>
  13#include <linux/firmware.h>
  14#include <linux/of_address.h>
  15#include <linux/ioport.h>
  16
  17#define SLEEP_CLOCK_SELECT_INTERNAL_BIT	0x02
  18#define HOST_CSTATE_BIT			0x04
  19#define PLATFORM_CAP_PCIE_GLOBAL_RESET	0x08
  20#define ATH12K_QMI_MAX_CHUNK_SIZE	2097152
  21
  22static const struct qmi_elem_info wlfw_host_mlo_chip_info_s_v01_ei[] = {
  23	{
  24		.data_type      = QMI_UNSIGNED_1_BYTE,
  25		.elem_len       = 1,
  26		.elem_size      = sizeof(u8),
  27		.array_type	= NO_ARRAY,
  28		.tlv_type       = 0,
  29		.offset         = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
  30					   chip_id),
  31	},
  32	{
  33		.data_type      = QMI_UNSIGNED_1_BYTE,
  34		.elem_len       = 1,
  35		.elem_size      = sizeof(u8),
  36		.array_type	= NO_ARRAY,
  37		.tlv_type       = 0,
  38		.offset         = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
  39					   num_local_links),
  40	},
  41	{
  42		.data_type      = QMI_UNSIGNED_1_BYTE,
  43		.elem_len       = QMI_WLFW_MAX_NUM_MLO_LINKS_PER_CHIP_V01,
  44		.elem_size      = sizeof(u8),
  45		.array_type     = STATIC_ARRAY,
  46		.tlv_type       = 0,
  47		.offset         = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
  48					   hw_link_id),
  49	},
  50	{
  51		.data_type      = QMI_UNSIGNED_1_BYTE,
  52		.elem_len       = QMI_WLFW_MAX_NUM_MLO_LINKS_PER_CHIP_V01,
  53		.elem_size      = sizeof(u8),
  54		.array_type     = STATIC_ARRAY,
  55		.tlv_type       = 0,
  56		.offset         = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
  57					   valid_mlo_link_id),
  58	},
  59	{
  60		.data_type      = QMI_EOTI,
  61		.array_type	= NO_ARRAY,
  62		.tlv_type       = QMI_COMMON_TLV_TYPE,
  63	},
  64};
  65
  66static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
  67	{
  68		.data_type	= QMI_OPT_FLAG,
  69		.elem_len	= 1,
  70		.elem_size	= sizeof(u8),
  71		.array_type	= NO_ARRAY,
  72		.tlv_type	= 0x10,
  73		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  74					   num_clients_valid),
  75	},
  76	{
  77		.data_type	= QMI_UNSIGNED_4_BYTE,
  78		.elem_len	= 1,
  79		.elem_size	= sizeof(u32),
  80		.array_type	= NO_ARRAY,
  81		.tlv_type	= 0x10,
  82		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  83					   num_clients),
  84	},
  85	{
  86		.data_type	= QMI_OPT_FLAG,
  87		.elem_len	= 1,
  88		.elem_size	= sizeof(u8),
  89		.array_type	= NO_ARRAY,
  90		.tlv_type	= 0x11,
  91		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  92					   wake_msi_valid),
  93	},
  94	{
  95		.data_type	= QMI_UNSIGNED_4_BYTE,
  96		.elem_len	= 1,
  97		.elem_size	= sizeof(u32),
  98		.array_type	= NO_ARRAY,
  99		.tlv_type	= 0x11,
 100		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 101					   wake_msi),
 102	},
 103	{
 104		.data_type	= QMI_OPT_FLAG,
 105		.elem_len	= 1,
 106		.elem_size	= sizeof(u8),
 107		.array_type	= NO_ARRAY,
 108		.tlv_type	= 0x12,
 109		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 110					   gpios_valid),
 111	},
 112	{
 113		.data_type	= QMI_DATA_LEN,
 114		.elem_len	= 1,
 115		.elem_size	= sizeof(u8),
 116		.array_type	= NO_ARRAY,
 117		.tlv_type	= 0x12,
 118		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 119					   gpios_len),
 120	},
 121	{
 122		.data_type	= QMI_UNSIGNED_4_BYTE,
 123		.elem_len	= QMI_WLFW_MAX_NUM_GPIO_V01,
 124		.elem_size	= sizeof(u32),
 125		.array_type	= VAR_LEN_ARRAY,
 126		.tlv_type	= 0x12,
 127		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 128					   gpios),
 129	},
 130	{
 131		.data_type	= QMI_OPT_FLAG,
 132		.elem_len	= 1,
 133		.elem_size	= sizeof(u8),
 134		.array_type	= NO_ARRAY,
 135		.tlv_type	= 0x13,
 136		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 137					   nm_modem_valid),
 138	},
 139	{
 140		.data_type	= QMI_UNSIGNED_1_BYTE,
 141		.elem_len	= 1,
 142		.elem_size	= sizeof(u8),
 143		.array_type	= NO_ARRAY,
 144		.tlv_type	= 0x13,
 145		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 146					   nm_modem),
 147	},
 148	{
 149		.data_type	= QMI_OPT_FLAG,
 150		.elem_len	= 1,
 151		.elem_size	= sizeof(u8),
 152		.array_type	= NO_ARRAY,
 153		.tlv_type	= 0x14,
 154		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 155					   bdf_support_valid),
 156	},
 157	{
 158		.data_type	= QMI_UNSIGNED_1_BYTE,
 159		.elem_len	= 1,
 160		.elem_size	= sizeof(u8),
 161		.array_type	= NO_ARRAY,
 162		.tlv_type	= 0x14,
 163		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 164					   bdf_support),
 165	},
 166	{
 167		.data_type	= QMI_OPT_FLAG,
 168		.elem_len	= 1,
 169		.elem_size	= sizeof(u8),
 170		.array_type	= NO_ARRAY,
 171		.tlv_type	= 0x15,
 172		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 173					   bdf_cache_support_valid),
 174	},
 175	{
 176		.data_type	= QMI_UNSIGNED_1_BYTE,
 177		.elem_len	= 1,
 178		.elem_size	= sizeof(u8),
 179		.array_type	= NO_ARRAY,
 180		.tlv_type	= 0x15,
 181		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 182					   bdf_cache_support),
 183	},
 184	{
 185		.data_type	= QMI_OPT_FLAG,
 186		.elem_len	= 1,
 187		.elem_size	= sizeof(u8),
 188		.array_type	= NO_ARRAY,
 189		.tlv_type	= 0x16,
 190		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 191					   m3_support_valid),
 192	},
 193	{
 194		.data_type	= QMI_UNSIGNED_1_BYTE,
 195		.elem_len	= 1,
 196		.elem_size	= sizeof(u8),
 197		.array_type	= NO_ARRAY,
 198		.tlv_type	= 0x16,
 199		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 200					   m3_support),
 201	},
 202	{
 203		.data_type	= QMI_OPT_FLAG,
 204		.elem_len	= 1,
 205		.elem_size	= sizeof(u8),
 206		.array_type	= NO_ARRAY,
 207		.tlv_type	= 0x17,
 208		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 209					   m3_cache_support_valid),
 210	},
 211	{
 212		.data_type	= QMI_UNSIGNED_1_BYTE,
 213		.elem_len	= 1,
 214		.elem_size	= sizeof(u8),
 215		.array_type	= NO_ARRAY,
 216		.tlv_type	= 0x17,
 217		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 218					   m3_cache_support),
 219	},
 220	{
 221		.data_type	= QMI_OPT_FLAG,
 222		.elem_len	= 1,
 223		.elem_size	= sizeof(u8),
 224		.array_type	= NO_ARRAY,
 225		.tlv_type	= 0x18,
 226		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 227					   cal_filesys_support_valid),
 228	},
 229	{
 230		.data_type	= QMI_UNSIGNED_1_BYTE,
 231		.elem_len	= 1,
 232		.elem_size	= sizeof(u8),
 233		.array_type	= NO_ARRAY,
 234		.tlv_type	= 0x18,
 235		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 236					   cal_filesys_support),
 237	},
 238	{
 239		.data_type	= QMI_OPT_FLAG,
 240		.elem_len	= 1,
 241		.elem_size	= sizeof(u8),
 242		.array_type	= NO_ARRAY,
 243		.tlv_type	= 0x19,
 244		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 245					   cal_cache_support_valid),
 246	},
 247	{
 248		.data_type	= QMI_UNSIGNED_1_BYTE,
 249		.elem_len	= 1,
 250		.elem_size	= sizeof(u8),
 251		.array_type	= NO_ARRAY,
 252		.tlv_type	= 0x19,
 253		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 254					   cal_cache_support),
 255	},
 256	{
 257		.data_type	= QMI_OPT_FLAG,
 258		.elem_len	= 1,
 259		.elem_size	= sizeof(u8),
 260		.array_type	= NO_ARRAY,
 261		.tlv_type	= 0x1A,
 262		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 263					   cal_done_valid),
 264	},
 265	{
 266		.data_type	= QMI_UNSIGNED_1_BYTE,
 267		.elem_len	= 1,
 268		.elem_size	= sizeof(u8),
 269		.array_type	= NO_ARRAY,
 270		.tlv_type	= 0x1A,
 271		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 272					   cal_done),
 273	},
 274	{
 275		.data_type	= QMI_OPT_FLAG,
 276		.elem_len	= 1,
 277		.elem_size	= sizeof(u8),
 278		.array_type	= NO_ARRAY,
 279		.tlv_type	= 0x1B,
 280		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 281					   mem_bucket_valid),
 282	},
 283	{
 284		.data_type	= QMI_UNSIGNED_4_BYTE,
 285		.elem_len	= 1,
 286		.elem_size	= sizeof(u32),
 287		.array_type	= NO_ARRAY,
 288		.tlv_type	= 0x1B,
 289		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 290					   mem_bucket),
 291	},
 292	{
 293		.data_type	= QMI_OPT_FLAG,
 294		.elem_len	= 1,
 295		.elem_size	= sizeof(u8),
 296		.array_type	= NO_ARRAY,
 297		.tlv_type	= 0x1C,
 298		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 299					   mem_cfg_mode_valid),
 300	},
 301	{
 302		.data_type	= QMI_UNSIGNED_1_BYTE,
 303		.elem_len	= 1,
 304		.elem_size	= sizeof(u8),
 305		.array_type	= NO_ARRAY,
 306		.tlv_type	= 0x1C,
 307		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 308					   mem_cfg_mode),
 309	},
 310	{
 311		.data_type	= QMI_OPT_FLAG,
 312		.elem_len	= 1,
 313		.elem_size	= sizeof(u8),
 314		.array_type	= NO_ARRAY,
 315		.tlv_type	= 0x1D,
 316		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 317					   cal_duration_valid),
 318	},
 319	{
 320		.data_type	= QMI_UNSIGNED_2_BYTE,
 321		.elem_len	= 1,
 322		.elem_size	= sizeof(u16),
 323		.array_type	= NO_ARRAY,
 324		.tlv_type	= 0x1D,
 325		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 326					   cal_duraiton),
 327	},
 328	{
 329		.data_type	= QMI_OPT_FLAG,
 330		.elem_len	= 1,
 331		.elem_size	= sizeof(u8),
 332		.array_type	= NO_ARRAY,
 333		.tlv_type	= 0x1E,
 334		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 335					   platform_name_valid),
 336	},
 337	{
 338		.data_type	= QMI_STRING,
 339		.elem_len	= QMI_WLANFW_MAX_PLATFORM_NAME_LEN_V01 + 1,
 340		.elem_size	= sizeof(char),
 341		.array_type	= NO_ARRAY,
 342		.tlv_type	= 0x1E,
 343		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 344					   platform_name),
 345	},
 346	{
 347		.data_type	= QMI_OPT_FLAG,
 348		.elem_len	= 1,
 349		.elem_size	= sizeof(u8),
 350		.array_type	= NO_ARRAY,
 351		.tlv_type	= 0x1F,
 352		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 353					   ddr_range_valid),
 354	},
 355	{
 356		.data_type	= QMI_STRUCT,
 357		.elem_len	= QMI_WLANFW_MAX_HOST_DDR_RANGE_SIZE_V01,
 358		.elem_size	= sizeof(struct qmi_wlanfw_host_ddr_range),
 359		.array_type	= STATIC_ARRAY,
 360		.tlv_type	= 0x1F,
 361		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 362					   ddr_range),
 363	},
 364	{
 365		.data_type	= QMI_OPT_FLAG,
 366		.elem_len	= 1,
 367		.elem_size	= sizeof(u8),
 368		.array_type	= NO_ARRAY,
 369		.tlv_type	= 0x20,
 370		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 371					   host_build_type_valid),
 372	},
 373	{
 374		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
 375		.elem_len	= 1,
 376		.elem_size	= sizeof(enum qmi_wlanfw_host_build_type),
 377		.array_type	= NO_ARRAY,
 378		.tlv_type	= 0x20,
 379		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 380					   host_build_type),
 381	},
 382	{
 383		.data_type	= QMI_OPT_FLAG,
 384		.elem_len	= 1,
 385		.elem_size	= sizeof(u8),
 386		.array_type	= NO_ARRAY,
 387		.tlv_type	= 0x21,
 388		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 389					   mlo_capable_valid),
 390	},
 391	{
 392		.data_type	= QMI_UNSIGNED_1_BYTE,
 393		.elem_len	= 1,
 394		.elem_size	= sizeof(u8),
 395		.array_type	= NO_ARRAY,
 396		.tlv_type	= 0x21,
 397		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 398					   mlo_capable),
 399	},
 400	{
 401		.data_type	= QMI_OPT_FLAG,
 402		.elem_len	= 1,
 403		.elem_size	= sizeof(u8),
 404		.array_type	= NO_ARRAY,
 405		.tlv_type	= 0x22,
 406		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 407					   mlo_chip_id_valid),
 408	},
 409	{
 410		.data_type	= QMI_UNSIGNED_2_BYTE,
 411		.elem_len	= 1,
 412		.elem_size	= sizeof(u16),
 413		.array_type	= NO_ARRAY,
 414		.tlv_type	= 0x22,
 415		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 416					   mlo_chip_id),
 417	},
 418	{
 419		.data_type	= QMI_OPT_FLAG,
 420		.elem_len	= 1,
 421		.elem_size	= sizeof(u8),
 422		.array_type	= NO_ARRAY,
 423		.tlv_type	= 0x23,
 424		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 425					   mlo_group_id_valid),
 426	},
 427	{
 428		.data_type	= QMI_UNSIGNED_1_BYTE,
 429		.elem_len	= 1,
 430		.elem_size	= sizeof(u8),
 431		.array_type	= NO_ARRAY,
 432		.tlv_type	= 0x23,
 433		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 434					   mlo_group_id),
 435	},
 436	{
 437		.data_type	= QMI_OPT_FLAG,
 438		.elem_len	= 1,
 439		.elem_size	= sizeof(u8),
 440		.array_type	= NO_ARRAY,
 441		.tlv_type	= 0x24,
 442		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 443					   max_mlo_peer_valid),
 444	},
 445	{
 446		.data_type	= QMI_UNSIGNED_2_BYTE,
 447		.elem_len	= 1,
 448		.elem_size	= sizeof(u16),
 449		.array_type	= NO_ARRAY,
 450		.tlv_type	= 0x24,
 451		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 452					   max_mlo_peer),
 453	},
 454	{
 455		.data_type	= QMI_OPT_FLAG,
 456		.elem_len	= 1,
 457		.elem_size	= sizeof(u8),
 458		.array_type	= NO_ARRAY,
 459		.tlv_type	= 0x25,
 460		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 461					   mlo_num_chips_valid),
 462	},
 463	{
 464		.data_type	= QMI_UNSIGNED_1_BYTE,
 465		.elem_len	= 1,
 466		.elem_size	= sizeof(u8),
 467		.array_type	= NO_ARRAY,
 468		.tlv_type	= 0x25,
 469		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 470					   mlo_num_chips),
 471	},
 472	{
 473		.data_type	= QMI_OPT_FLAG,
 474		.elem_len	= 1,
 475		.elem_size	= sizeof(u8),
 476		.array_type	= NO_ARRAY,
 477		.tlv_type	= 0x26,
 478		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 479					   mlo_chip_info_valid),
 480	},
 481	{
 482		.data_type	= QMI_STRUCT,
 483		.elem_len	= QMI_WLFW_MAX_NUM_MLO_CHIPS_V01,
 484		.elem_size	= sizeof(struct wlfw_host_mlo_chip_info_s_v01),
 485		.array_type	= STATIC_ARRAY,
 486		.tlv_type	= 0x26,
 487		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 488					   mlo_chip_info),
 489		.ei_array	= wlfw_host_mlo_chip_info_s_v01_ei,
 490	},
 491	{
 492		.data_type	= QMI_OPT_FLAG,
 493		.elem_len	= 1,
 494		.elem_size	= sizeof(u8),
 495		.array_type	= NO_ARRAY,
 496		.tlv_type	= 0x27,
 497		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 498					   feature_list_valid),
 499	},
 500	{
 501		.data_type	= QMI_UNSIGNED_8_BYTE,
 502		.elem_len	= 1,
 503		.elem_size	= sizeof(u64),
 504		.array_type	= NO_ARRAY,
 505		.tlv_type	= 0x27,
 506		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
 507					   feature_list),
 508	},
 509	{
 510		.data_type	= QMI_EOTI,
 511		.array_type	= NO_ARRAY,
 512		.tlv_type	= QMI_COMMON_TLV_TYPE,
 513	},
 514};
 515
 516static const struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = {
 517	{
 518		.data_type	= QMI_STRUCT,
 519		.elem_len	= 1,
 520		.elem_size	= sizeof(struct qmi_response_type_v01),
 521		.array_type	= NO_ARRAY,
 522		.tlv_type	= 0x02,
 523		.offset		= offsetof(struct qmi_wlanfw_host_cap_resp_msg_v01, resp),
 524		.ei_array	= qmi_response_type_v01_ei,
 525	},
 526	{
 527		.data_type	= QMI_EOTI,
 528		.array_type	= NO_ARRAY,
 529		.tlv_type	= QMI_COMMON_TLV_TYPE,
 530	},
 531};
 532
 533static const struct qmi_elem_info qmi_wlanfw_phy_cap_req_msg_v01_ei[] = {
 534	{
 535		.data_type	= QMI_EOTI,
 536		.array_type	= NO_ARRAY,
 537		.tlv_type	= QMI_COMMON_TLV_TYPE,
 538	},
 539};
 540
 541static const struct qmi_elem_info qmi_wlanfw_phy_cap_resp_msg_v01_ei[] = {
 542	{
 543		.data_type	= QMI_STRUCT,
 544		.elem_len	= 1,
 545		.elem_size	= sizeof(struct qmi_response_type_v01),
 546		.array_type	= NO_ARRAY,
 547		.tlv_type	= 0x02,
 548		.offset		= offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01, resp),
 549		.ei_array	= qmi_response_type_v01_ei,
 550	},
 551	{
 552		.data_type	= QMI_OPT_FLAG,
 553		.elem_len	= 1,
 554		.elem_size	= sizeof(u8),
 555		.array_type	= NO_ARRAY,
 556		.tlv_type	= 0x10,
 557		.offset		= offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
 558					   num_phy_valid),
 559	},
 560	{
 561		.data_type	= QMI_UNSIGNED_1_BYTE,
 562		.elem_len	= 1,
 563		.elem_size	= sizeof(u8),
 564		.array_type	= NO_ARRAY,
 565		.tlv_type	= 0x10,
 566		.offset		= offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
 567					   num_phy),
 568	},
 569	{
 570		.data_type	= QMI_OPT_FLAG,
 571		.elem_len	= 1,
 572		.elem_size	= sizeof(u8),
 573		.array_type	= NO_ARRAY,
 574		.tlv_type	= 0x11,
 575		.offset		= offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
 576					   board_id_valid),
 577	},
 578	{
 579		.data_type	= QMI_UNSIGNED_4_BYTE,
 580		.elem_len	= 1,
 581		.elem_size	= sizeof(u32),
 582		.array_type	= NO_ARRAY,
 583		.tlv_type	= 0x11,
 584		.offset		= offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
 585					   board_id),
 586	},
 587	{
 588		.data_type      = QMI_OPT_FLAG,
 589		.elem_len       = 1,
 590		.elem_size      = sizeof(u8),
 591		.array_type     = NO_ARRAY,
 592		.tlv_type       = 0x13,
 593		.offset         = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
 594					   single_chip_mlo_support_valid),
 595	},
 596	{
 597		.data_type      = QMI_UNSIGNED_1_BYTE,
 598		.elem_len       = 1,
 599		.elem_size      = sizeof(u8),
 600		.array_type     = NO_ARRAY,
 601		.tlv_type       = 0x13,
 602		.offset         = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
 603					   single_chip_mlo_support),
 604	},
 605	{
 606		.data_type	= QMI_EOTI,
 607		.array_type	= NO_ARRAY,
 608		.tlv_type	= QMI_COMMON_TLV_TYPE,
 609	},
 610};
 611
 612static const struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = {
 613	{
 614		.data_type	= QMI_OPT_FLAG,
 615		.elem_len	= 1,
 616		.elem_size	= sizeof(u8),
 617		.array_type	= NO_ARRAY,
 618		.tlv_type	= 0x10,
 619		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 620					   fw_ready_enable_valid),
 621	},
 622	{
 623		.data_type	= QMI_UNSIGNED_1_BYTE,
 624		.elem_len	= 1,
 625		.elem_size	= sizeof(u8),
 626		.array_type	= NO_ARRAY,
 627		.tlv_type	= 0x10,
 628		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 629					   fw_ready_enable),
 630	},
 631	{
 632		.data_type	= QMI_OPT_FLAG,
 633		.elem_len	= 1,
 634		.elem_size	= sizeof(u8),
 635		.array_type	= NO_ARRAY,
 636		.tlv_type	= 0x11,
 637		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 638					   initiate_cal_download_enable_valid),
 639	},
 640	{
 641		.data_type	= QMI_UNSIGNED_1_BYTE,
 642		.elem_len	= 1,
 643		.elem_size	= sizeof(u8),
 644		.array_type	= NO_ARRAY,
 645		.tlv_type	= 0x11,
 646		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 647					   initiate_cal_download_enable),
 648	},
 649	{
 650		.data_type	= QMI_OPT_FLAG,
 651		.elem_len	= 1,
 652		.elem_size	= sizeof(u8),
 653		.array_type	= NO_ARRAY,
 654		.tlv_type	= 0x12,
 655		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 656					   initiate_cal_update_enable_valid),
 657	},
 658	{
 659		.data_type	= QMI_UNSIGNED_1_BYTE,
 660		.elem_len	= 1,
 661		.elem_size	= sizeof(u8),
 662		.array_type	= NO_ARRAY,
 663		.tlv_type	= 0x12,
 664		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 665					   initiate_cal_update_enable),
 666	},
 667	{
 668		.data_type	= QMI_OPT_FLAG,
 669		.elem_len	= 1,
 670		.elem_size	= sizeof(u8),
 671		.array_type	= NO_ARRAY,
 672		.tlv_type	= 0x13,
 673		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 674					   msa_ready_enable_valid),
 675	},
 676	{
 677		.data_type	= QMI_UNSIGNED_1_BYTE,
 678		.elem_len	= 1,
 679		.elem_size	= sizeof(u8),
 680		.array_type	= NO_ARRAY,
 681		.tlv_type	= 0x13,
 682		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 683					   msa_ready_enable),
 684	},
 685	{
 686		.data_type	= QMI_OPT_FLAG,
 687		.elem_len	= 1,
 688		.elem_size	= sizeof(u8),
 689		.array_type	= NO_ARRAY,
 690		.tlv_type	= 0x14,
 691		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 692					   pin_connect_result_enable_valid),
 693	},
 694	{
 695		.data_type	= QMI_UNSIGNED_1_BYTE,
 696		.elem_len	= 1,
 697		.elem_size	= sizeof(u8),
 698		.array_type	= NO_ARRAY,
 699		.tlv_type	= 0x14,
 700		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 701					   pin_connect_result_enable),
 702	},
 703	{
 704		.data_type	= QMI_OPT_FLAG,
 705		.elem_len	= 1,
 706		.elem_size	= sizeof(u8),
 707		.array_type	= NO_ARRAY,
 708		.tlv_type	= 0x15,
 709		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 710					   client_id_valid),
 711	},
 712	{
 713		.data_type	= QMI_UNSIGNED_4_BYTE,
 714		.elem_len	= 1,
 715		.elem_size	= sizeof(u32),
 716		.array_type	= NO_ARRAY,
 717		.tlv_type	= 0x15,
 718		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 719					   client_id),
 720	},
 721	{
 722		.data_type	= QMI_OPT_FLAG,
 723		.elem_len	= 1,
 724		.elem_size	= sizeof(u8),
 725		.array_type	= NO_ARRAY,
 726		.tlv_type	= 0x16,
 727		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 728					   request_mem_enable_valid),
 729	},
 730	{
 731		.data_type	= QMI_UNSIGNED_1_BYTE,
 732		.elem_len	= 1,
 733		.elem_size	= sizeof(u8),
 734		.array_type	= NO_ARRAY,
 735		.tlv_type	= 0x16,
 736		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 737					   request_mem_enable),
 738	},
 739	{
 740		.data_type	= QMI_OPT_FLAG,
 741		.elem_len	= 1,
 742		.elem_size	= sizeof(u8),
 743		.array_type	= NO_ARRAY,
 744		.tlv_type	= 0x17,
 745		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 746					   fw_mem_ready_enable_valid),
 747	},
 748	{
 749		.data_type	= QMI_UNSIGNED_1_BYTE,
 750		.elem_len	= 1,
 751		.elem_size	= sizeof(u8),
 752		.array_type	= NO_ARRAY,
 753		.tlv_type	= 0x17,
 754		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 755					   fw_mem_ready_enable),
 756	},
 757	{
 758		.data_type	= QMI_OPT_FLAG,
 759		.elem_len	= 1,
 760		.elem_size	= sizeof(u8),
 761		.array_type	= NO_ARRAY,
 762		.tlv_type	= 0x18,
 763		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 764					   fw_init_done_enable_valid),
 765	},
 766	{
 767		.data_type	= QMI_UNSIGNED_1_BYTE,
 768		.elem_len	= 1,
 769		.elem_size	= sizeof(u8),
 770		.array_type	= NO_ARRAY,
 771		.tlv_type	= 0x18,
 772		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 773					   fw_init_done_enable),
 774	},
 775
 776	{
 777		.data_type	= QMI_OPT_FLAG,
 778		.elem_len	= 1,
 779		.elem_size	= sizeof(u8),
 780		.array_type	= NO_ARRAY,
 781		.tlv_type	= 0x19,
 782		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 783					   rejuvenate_enable_valid),
 784	},
 785	{
 786		.data_type	= QMI_UNSIGNED_1_BYTE,
 787		.elem_len	= 1,
 788		.elem_size	= sizeof(u8),
 789		.array_type	= NO_ARRAY,
 790		.tlv_type	= 0x19,
 791		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 792					   rejuvenate_enable),
 793	},
 794	{
 795		.data_type	= QMI_OPT_FLAG,
 796		.elem_len	= 1,
 797		.elem_size	= sizeof(u8),
 798		.array_type	= NO_ARRAY,
 799		.tlv_type	= 0x1A,
 800		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 801					   xo_cal_enable_valid),
 802	},
 803	{
 804		.data_type	= QMI_UNSIGNED_1_BYTE,
 805		.elem_len	= 1,
 806		.elem_size	= sizeof(u8),
 807		.array_type	= NO_ARRAY,
 808		.tlv_type	= 0x1A,
 809		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 810					   xo_cal_enable),
 811	},
 812	{
 813		.data_type	= QMI_OPT_FLAG,
 814		.elem_len	= 1,
 815		.elem_size	= sizeof(u8),
 816		.array_type	= NO_ARRAY,
 817		.tlv_type	= 0x1B,
 818		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 819					   cal_done_enable_valid),
 820	},
 821	{
 822		.data_type	= QMI_UNSIGNED_1_BYTE,
 823		.elem_len	= 1,
 824		.elem_size	= sizeof(u8),
 825		.array_type	= NO_ARRAY,
 826		.tlv_type	= 0x1B,
 827		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
 828					   cal_done_enable),
 829	},
 830	{
 831		.data_type	= QMI_EOTI,
 832		.array_type	= NO_ARRAY,
 833		.tlv_type	= QMI_COMMON_TLV_TYPE,
 834	},
 835};
 836
 837static const struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = {
 838	{
 839		.data_type	= QMI_STRUCT,
 840		.elem_len	= 1,
 841		.elem_size	= sizeof(struct qmi_response_type_v01),
 842		.array_type	= NO_ARRAY,
 843		.tlv_type	= 0x02,
 844		.offset		= offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
 845					   resp),
 846		.ei_array	= qmi_response_type_v01_ei,
 847	},
 848	{
 849		.data_type	= QMI_OPT_FLAG,
 850		.elem_len	= 1,
 851		.elem_size	= sizeof(u8),
 852		.array_type	= NO_ARRAY,
 853		.tlv_type	= 0x10,
 854		.offset		= offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
 855					   fw_status_valid),
 856	},
 857	{
 858		.data_type	= QMI_UNSIGNED_8_BYTE,
 859		.elem_len	= 1,
 860		.elem_size	= sizeof(u64),
 861		.array_type	= NO_ARRAY,
 862		.tlv_type	= 0x10,
 863		.offset		= offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
 864					   fw_status),
 865	},
 866	{
 867		.data_type	= QMI_EOTI,
 868		.array_type	= NO_ARRAY,
 869		.tlv_type	= QMI_COMMON_TLV_TYPE,
 870	},
 871};
 872
 873static const struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = {
 874	{
 875		.data_type	= QMI_UNSIGNED_8_BYTE,
 876		.elem_len	= 1,
 877		.elem_size	= sizeof(u64),
 878		.array_type	= NO_ARRAY,
 879		.tlv_type	= 0,
 880		.offset		= offsetof(struct qmi_wlanfw_mem_cfg_s_v01, offset),
 881	},
 882	{
 883		.data_type	= QMI_UNSIGNED_4_BYTE,
 884		.elem_len	= 1,
 885		.elem_size	= sizeof(u32),
 886		.array_type	= NO_ARRAY,
 887		.tlv_type	= 0,
 888		.offset		= offsetof(struct qmi_wlanfw_mem_cfg_s_v01, size),
 889	},
 890	{
 891		.data_type	= QMI_UNSIGNED_1_BYTE,
 892		.elem_len	= 1,
 893		.elem_size	= sizeof(u8),
 894		.array_type	= NO_ARRAY,
 895		.tlv_type	= 0,
 896		.offset		= offsetof(struct qmi_wlanfw_mem_cfg_s_v01, secure_flag),
 897	},
 898	{
 899		.data_type	= QMI_EOTI,
 900		.array_type	= NO_ARRAY,
 901		.tlv_type	= QMI_COMMON_TLV_TYPE,
 902	},
 903};
 904
 905static const struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = {
 906	{
 907		.data_type	= QMI_UNSIGNED_4_BYTE,
 908		.elem_len	= 1,
 909		.elem_size	= sizeof(u32),
 910		.array_type	= NO_ARRAY,
 911		.tlv_type	= 0,
 912		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01,
 913				  size),
 914	},
 915	{
 916		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
 917		.elem_len	= 1,
 918		.elem_size	= sizeof(enum qmi_wlanfw_mem_type_enum_v01),
 919		.array_type	= NO_ARRAY,
 920		.tlv_type	= 0,
 921		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01, type),
 922	},
 923	{
 924		.data_type	= QMI_DATA_LEN,
 925		.elem_len	= 1,
 926		.elem_size	= sizeof(u8),
 927		.array_type	= NO_ARRAY,
 928		.tlv_type	= 0,
 929		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg_len),
 930	},
 931	{
 932		.data_type	= QMI_STRUCT,
 933		.elem_len	= QMI_WLANFW_MAX_NUM_MEM_CFG_V01,
 934		.elem_size	= sizeof(struct qmi_wlanfw_mem_cfg_s_v01),
 935		.array_type	= VAR_LEN_ARRAY,
 936		.tlv_type	= 0,
 937		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg),
 938		.ei_array	= qmi_wlanfw_mem_cfg_s_v01_ei,
 939	},
 940	{
 941		.data_type	= QMI_EOTI,
 942		.array_type	= NO_ARRAY,
 943		.tlv_type	= QMI_COMMON_TLV_TYPE,
 944	},
 945};
 946
 947static const struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = {
 948	{
 949		.data_type	= QMI_DATA_LEN,
 950		.elem_len	= 1,
 951		.elem_size	= sizeof(u8),
 952		.array_type	= NO_ARRAY,
 953		.tlv_type	= 0x01,
 954		.offset		= offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,
 955					   mem_seg_len),
 956	},
 957	{
 958		.data_type	= QMI_STRUCT,
 959		.elem_len	= ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,
 960		.elem_size	= sizeof(struct qmi_wlanfw_mem_seg_s_v01),
 961		.array_type	= VAR_LEN_ARRAY,
 962		.tlv_type	= 0x01,
 963		.offset		= offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,
 964					   mem_seg),
 965		.ei_array	= qmi_wlanfw_mem_seg_s_v01_ei,
 966	},
 967	{
 968		.data_type	= QMI_EOTI,
 969		.array_type	= NO_ARRAY,
 970		.tlv_type	= QMI_COMMON_TLV_TYPE,
 971	},
 972};
 973
 974static const struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = {
 975	{
 976		.data_type	= QMI_UNSIGNED_8_BYTE,
 977		.elem_len	= 1,
 978		.elem_size	= sizeof(u64),
 979		.array_type	= NO_ARRAY,
 980		.tlv_type	= 0,
 981		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, addr),
 982	},
 983	{
 984		.data_type	= QMI_UNSIGNED_4_BYTE,
 985		.elem_len	= 1,
 986		.elem_size	= sizeof(u32),
 987		.array_type	= NO_ARRAY,
 988		.tlv_type	= 0,
 989		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, size),
 990	},
 991	{
 992		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
 993		.elem_len	= 1,
 994		.elem_size	= sizeof(enum qmi_wlanfw_mem_type_enum_v01),
 995		.array_type	= NO_ARRAY,
 996		.tlv_type	= 0,
 997		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, type),
 998	},
 999	{
1000		.data_type	= QMI_UNSIGNED_1_BYTE,
1001		.elem_len	= 1,
1002		.elem_size	= sizeof(u8),
1003		.array_type	= NO_ARRAY,
1004		.tlv_type	= 0,
1005		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, restore),
1006	},
1007	{
1008		.data_type	= QMI_EOTI,
1009		.array_type	= NO_ARRAY,
1010		.tlv_type	= QMI_COMMON_TLV_TYPE,
1011	},
1012};
1013
1014static const struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = {
1015	{
1016		.data_type	= QMI_DATA_LEN,
1017		.elem_len	= 1,
1018		.elem_size	= sizeof(u8),
1019		.array_type	= NO_ARRAY,
1020		.tlv_type	= 0x01,
1021		.offset		= offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,
1022					   mem_seg_len),
1023	},
1024	{
1025		.data_type	= QMI_STRUCT,
1026		.elem_len	= ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,
1027		.elem_size	= sizeof(struct qmi_wlanfw_mem_seg_resp_s_v01),
1028		.array_type	= VAR_LEN_ARRAY,
1029		.tlv_type	= 0x01,
1030		.offset		= offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,
1031					   mem_seg),
1032		.ei_array	= qmi_wlanfw_mem_seg_resp_s_v01_ei,
1033	},
1034	{
1035		.data_type	= QMI_EOTI,
1036		.array_type	= NO_ARRAY,
1037		.tlv_type	= QMI_COMMON_TLV_TYPE,
1038	},
1039};
1040
1041static const struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = {
1042	{
1043		.data_type	= QMI_STRUCT,
1044		.elem_len	= 1,
1045		.elem_size	= sizeof(struct qmi_response_type_v01),
1046		.array_type	= NO_ARRAY,
1047		.tlv_type	= 0x02,
1048		.offset		= offsetof(struct qmi_wlanfw_respond_mem_resp_msg_v01,
1049					   resp),
1050		.ei_array	= qmi_response_type_v01_ei,
1051	},
1052	{
1053		.data_type	= QMI_EOTI,
1054		.array_type	= NO_ARRAY,
1055		.tlv_type	= QMI_COMMON_TLV_TYPE,
1056	},
1057};
1058
1059static const struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = {
1060	{
1061		.data_type	= QMI_EOTI,
1062		.array_type	= NO_ARRAY,
1063		.tlv_type	= QMI_COMMON_TLV_TYPE,
1064	},
1065};
1066
1067static const struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = {
1068	{
1069		.data_type	= QMI_UNSIGNED_4_BYTE,
1070		.elem_len	= 1,
1071		.elem_size	= sizeof(u32),
1072		.array_type	= NO_ARRAY,
1073		.tlv_type	= 0,
1074		.offset		= offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,
1075					   chip_id),
1076	},
1077	{
1078		.data_type	= QMI_UNSIGNED_4_BYTE,
1079		.elem_len	= 1,
1080		.elem_size	= sizeof(u32),
1081		.array_type	= NO_ARRAY,
1082		.tlv_type	= 0,
1083		.offset		= offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,
1084					   chip_family),
1085	},
1086	{
1087		.data_type	= QMI_EOTI,
1088		.array_type	= NO_ARRAY,
1089		.tlv_type	= QMI_COMMON_TLV_TYPE,
1090	},
1091};
1092
1093static const struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = {
1094	{
1095		.data_type	= QMI_UNSIGNED_4_BYTE,
1096		.elem_len	= 1,
1097		.elem_size	= sizeof(u32),
1098		.array_type	= NO_ARRAY,
1099		.tlv_type	= 0,
1100		.offset		= offsetof(struct qmi_wlanfw_rf_board_info_s_v01,
1101					   board_id),
1102	},
1103	{
1104		.data_type	= QMI_EOTI,
1105		.array_type	= NO_ARRAY,
1106		.tlv_type	= QMI_COMMON_TLV_TYPE,
1107	},
1108};
1109
1110static const struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = {
1111	{
1112		.data_type	= QMI_UNSIGNED_4_BYTE,
1113		.elem_len	= 1,
1114		.elem_size	= sizeof(u32),
1115		.array_type	= NO_ARRAY,
1116		.tlv_type	= 0,
1117		.offset		= offsetof(struct qmi_wlanfw_soc_info_s_v01, soc_id),
1118	},
1119	{
1120		.data_type	= QMI_EOTI,
1121		.array_type	= NO_ARRAY,
1122		.tlv_type	= QMI_COMMON_TLV_TYPE,
1123	},
1124};
1125
1126static const struct qmi_elem_info qmi_wlanfw_dev_mem_info_s_v01_ei[] = {
1127	{
1128		.data_type	= QMI_UNSIGNED_8_BYTE,
1129		.elem_len	= 1,
1130		.elem_size	= sizeof(u64),
1131		.array_type	= NO_ARRAY,
1132		.tlv_type	= 0,
1133		.offset		= offsetof(struct qmi_wlanfw_dev_mem_info_s_v01,
1134					   start),
1135	},
1136	{
1137		.data_type	= QMI_UNSIGNED_8_BYTE,
1138		.elem_len	= 1,
1139		.elem_size	= sizeof(u64),
1140		.array_type	= NO_ARRAY,
1141		.tlv_type	= 0,
1142		.offset		= offsetof(struct qmi_wlanfw_dev_mem_info_s_v01,
1143					   size),
1144	},
1145	{
1146		.data_type	= QMI_EOTI,
1147		.array_type	= NO_ARRAY,
1148		.tlv_type	= QMI_COMMON_TLV_TYPE,
1149	},
1150};
1151
1152static const struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = {
1153	{
1154		.data_type	= QMI_UNSIGNED_4_BYTE,
1155		.elem_len	= 1,
1156		.elem_size	= sizeof(u32),
1157		.array_type	= NO_ARRAY,
1158		.tlv_type	= 0,
1159		.offset		= offsetof(struct qmi_wlanfw_fw_version_info_s_v01,
1160					   fw_version),
1161	},
1162	{
1163		.data_type	= QMI_STRING,
1164		.elem_len	= ATH12K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1,
1165		.elem_size	= sizeof(char),
1166		.array_type	= NO_ARRAY,
1167		.tlv_type	= 0,
1168		.offset		= offsetof(struct qmi_wlanfw_fw_version_info_s_v01,
1169					   fw_build_timestamp),
1170	},
1171	{
1172		.data_type	= QMI_EOTI,
1173		.array_type	= NO_ARRAY,
1174		.tlv_type	= QMI_COMMON_TLV_TYPE,
1175	},
1176};
1177
1178static const struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = {
1179	{
1180		.data_type	= QMI_STRUCT,
1181		.elem_len	= 1,
1182		.elem_size	= sizeof(struct qmi_response_type_v01),
1183		.array_type	= NO_ARRAY,
1184		.tlv_type	= 0x02,
1185		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01, resp),
1186		.ei_array	= qmi_response_type_v01_ei,
1187	},
1188	{
1189		.data_type	= QMI_OPT_FLAG,
1190		.elem_len	= 1,
1191		.elem_size	= sizeof(u8),
1192		.array_type	= NO_ARRAY,
1193		.tlv_type	= 0x10,
1194		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1195					   chip_info_valid),
1196	},
1197	{
1198		.data_type	= QMI_STRUCT,
1199		.elem_len	= 1,
1200		.elem_size	= sizeof(struct qmi_wlanfw_rf_chip_info_s_v01),
1201		.array_type	= NO_ARRAY,
1202		.tlv_type	= 0x10,
1203		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1204					   chip_info),
1205		.ei_array	= qmi_wlanfw_rf_chip_info_s_v01_ei,
1206	},
1207	{
1208		.data_type	= QMI_OPT_FLAG,
1209		.elem_len	= 1,
1210		.elem_size	= sizeof(u8),
1211		.array_type	= NO_ARRAY,
1212		.tlv_type	= 0x11,
1213		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1214					   board_info_valid),
1215	},
1216	{
1217		.data_type	= QMI_STRUCT,
1218		.elem_len	= 1,
1219		.elem_size	= sizeof(struct qmi_wlanfw_rf_board_info_s_v01),
1220		.array_type	= NO_ARRAY,
1221		.tlv_type	= 0x11,
1222		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1223					   board_info),
1224		.ei_array	= qmi_wlanfw_rf_board_info_s_v01_ei,
1225	},
1226	{
1227		.data_type	= QMI_OPT_FLAG,
1228		.elem_len	= 1,
1229		.elem_size	= sizeof(u8),
1230		.array_type	= NO_ARRAY,
1231		.tlv_type	= 0x12,
1232		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1233					   soc_info_valid),
1234	},
1235	{
1236		.data_type	= QMI_STRUCT,
1237		.elem_len	= 1,
1238		.elem_size	= sizeof(struct qmi_wlanfw_soc_info_s_v01),
1239		.array_type	= NO_ARRAY,
1240		.tlv_type	= 0x12,
1241		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1242					   soc_info),
1243		.ei_array	= qmi_wlanfw_soc_info_s_v01_ei,
1244	},
1245	{
1246		.data_type	= QMI_OPT_FLAG,
1247		.elem_len	= 1,
1248		.elem_size	= sizeof(u8),
1249		.array_type	= NO_ARRAY,
1250		.tlv_type	= 0x13,
1251		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1252					   fw_version_info_valid),
1253	},
1254	{
1255		.data_type	= QMI_STRUCT,
1256		.elem_len	= 1,
1257		.elem_size	= sizeof(struct qmi_wlanfw_fw_version_info_s_v01),
1258		.array_type	= NO_ARRAY,
1259		.tlv_type	= 0x13,
1260		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1261					   fw_version_info),
1262		.ei_array	= qmi_wlanfw_fw_version_info_s_v01_ei,
1263	},
1264	{
1265		.data_type	= QMI_OPT_FLAG,
1266		.elem_len	= 1,
1267		.elem_size	= sizeof(u8),
1268		.array_type	= NO_ARRAY,
1269		.tlv_type	= 0x14,
1270		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1271					   fw_build_id_valid),
1272	},
1273	{
1274		.data_type	= QMI_STRING,
1275		.elem_len	= ATH12K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1,
1276		.elem_size	= sizeof(char),
1277		.array_type	= NO_ARRAY,
1278		.tlv_type	= 0x14,
1279		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1280					   fw_build_id),
1281	},
1282	{
1283		.data_type	= QMI_OPT_FLAG,
1284		.elem_len	= 1,
1285		.elem_size	= sizeof(u8),
1286		.array_type	= NO_ARRAY,
1287		.tlv_type	= 0x15,
1288		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1289					   num_macs_valid),
1290	},
1291	{
1292		.data_type	= QMI_UNSIGNED_1_BYTE,
1293		.elem_len	= 1,
1294		.elem_size	= sizeof(u8),
1295		.array_type	= NO_ARRAY,
1296		.tlv_type	= 0x15,
1297		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1298					   num_macs),
1299	},
1300	{
1301		.data_type	= QMI_OPT_FLAG,
1302		.elem_len	= 1,
1303		.elem_size	= sizeof(u8),
1304		.array_type	= NO_ARRAY,
1305		.tlv_type	= 0x16,
1306		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1307					   voltage_mv_valid),
1308	},
1309	{
1310		.data_type	= QMI_UNSIGNED_4_BYTE,
1311		.elem_len	= 1,
1312		.elem_size	= sizeof(u32),
1313		.array_type	= NO_ARRAY,
1314		.tlv_type	= 0x16,
1315		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1316					   voltage_mv),
1317	},
1318	{
1319		.data_type	= QMI_OPT_FLAG,
1320		.elem_len	= 1,
1321		.elem_size	= sizeof(u8),
1322		.array_type	= NO_ARRAY,
1323		.tlv_type	= 0x17,
1324		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1325					   time_freq_hz_valid),
1326	},
1327	{
1328		.data_type	= QMI_UNSIGNED_4_BYTE,
1329		.elem_len	= 1,
1330		.elem_size	= sizeof(u32),
1331		.array_type	= NO_ARRAY,
1332		.tlv_type	= 0x17,
1333		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1334					   time_freq_hz),
1335	},
1336	{
1337		.data_type	= QMI_OPT_FLAG,
1338		.elem_len	= 1,
1339		.elem_size	= sizeof(u8),
1340		.array_type	= NO_ARRAY,
1341		.tlv_type	= 0x18,
1342		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1343					   otp_version_valid),
1344	},
1345	{
1346		.data_type	= QMI_UNSIGNED_4_BYTE,
1347		.elem_len	= 1,
1348		.elem_size	= sizeof(u32),
1349		.array_type	= NO_ARRAY,
1350		.tlv_type	= 0x18,
1351		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1352					   otp_version),
1353	},
1354	{
1355		.data_type	= QMI_OPT_FLAG,
1356		.elem_len	= 1,
1357		.elem_size	= sizeof(u8),
1358		.array_type	= NO_ARRAY,
1359		.tlv_type	= 0x19,
1360		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1361					   eeprom_caldata_read_timeout_valid),
1362	},
1363	{
1364		.data_type	= QMI_UNSIGNED_4_BYTE,
1365		.elem_len	= 1,
1366		.elem_size	= sizeof(u32),
1367		.array_type	= NO_ARRAY,
1368		.tlv_type	= 0x19,
1369		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1370					   eeprom_caldata_read_timeout),
1371	},
1372	{
1373		.data_type	= QMI_OPT_FLAG,
1374		.elem_len	= 1,
1375		.elem_size	= sizeof(u8),
1376		.array_type	= NO_ARRAY,
1377		.tlv_type	= 0x1A,
1378		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1379					   fw_caps_valid),
1380	},
1381	{
1382		.data_type	= QMI_UNSIGNED_8_BYTE,
1383		.elem_len	= 1,
1384		.elem_size	= sizeof(u64),
1385		.array_type	= NO_ARRAY,
1386		.tlv_type	= 0x1A,
1387		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01, fw_caps),
1388	},
1389	{
1390		.data_type	= QMI_OPT_FLAG,
1391		.elem_len	= 1,
1392		.elem_size	= sizeof(u8),
1393		.array_type	= NO_ARRAY,
1394		.tlv_type	= 0x1B,
1395		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1396					   rd_card_chain_cap_valid),
1397	},
1398	{
1399		.data_type	= QMI_UNSIGNED_4_BYTE,
1400		.elem_len	= 1,
1401		.elem_size	= sizeof(u32),
1402		.array_type	= NO_ARRAY,
1403		.tlv_type	= 0x1B,
1404		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1405					   rd_card_chain_cap),
1406	},
1407	{
1408		.data_type	= QMI_OPT_FLAG,
1409		.elem_len	= 1,
1410		.elem_size	= sizeof(u8),
1411		.array_type	= NO_ARRAY,
1412		.tlv_type	= 0x1C,
1413		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1414					   dev_mem_info_valid),
1415	},
1416	{
1417		.data_type	= QMI_STRUCT,
1418		.elem_len	= ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01,
1419		.elem_size	= sizeof(struct qmi_wlanfw_dev_mem_info_s_v01),
1420		.array_type	= STATIC_ARRAY,
1421		.tlv_type	= 0x1C,
1422		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01, dev_mem),
1423		.ei_array	= qmi_wlanfw_dev_mem_info_s_v01_ei,
1424	},
1425	{
1426		.data_type	= QMI_EOTI,
1427		.array_type	= NO_ARRAY,
1428		.tlv_type	= QMI_COMMON_TLV_TYPE,
1429	},
1430};
1431
1432static const struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = {
1433	{
1434		.data_type	= QMI_UNSIGNED_1_BYTE,
1435		.elem_len	= 1,
1436		.elem_size	= sizeof(u8),
1437		.array_type	= NO_ARRAY,
1438		.tlv_type	= 0x01,
1439		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1440					   valid),
1441	},
1442	{
1443		.data_type	= QMI_OPT_FLAG,
1444		.elem_len	= 1,
1445		.elem_size	= sizeof(u8),
1446		.array_type	= NO_ARRAY,
1447		.tlv_type	= 0x10,
1448		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1449					   file_id_valid),
1450	},
1451	{
1452		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
1453		.elem_len	= 1,
1454		.elem_size	= sizeof(enum qmi_wlanfw_cal_temp_id_enum_v01),
1455		.array_type	= NO_ARRAY,
1456		.tlv_type	= 0x10,
1457		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1458					   file_id),
1459	},
1460	{
1461		.data_type	= QMI_OPT_FLAG,
1462		.elem_len	= 1,
1463		.elem_size	= sizeof(u8),
1464		.array_type	= NO_ARRAY,
1465		.tlv_type	= 0x11,
1466		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1467					   total_size_valid),
1468	},
1469	{
1470		.data_type	= QMI_UNSIGNED_4_BYTE,
1471		.elem_len	= 1,
1472		.elem_size	= sizeof(u32),
1473		.array_type	= NO_ARRAY,
1474		.tlv_type	= 0x11,
1475		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1476					   total_size),
1477	},
1478	{
1479		.data_type	= QMI_OPT_FLAG,
1480		.elem_len	= 1,
1481		.elem_size	= sizeof(u8),
1482		.array_type	= NO_ARRAY,
1483		.tlv_type	= 0x12,
1484		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1485					   seg_id_valid),
1486	},
1487	{
1488		.data_type	= QMI_UNSIGNED_4_BYTE,
1489		.elem_len	= 1,
1490		.elem_size	= sizeof(u32),
1491		.array_type	= NO_ARRAY,
1492		.tlv_type	= 0x12,
1493		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1494					   seg_id),
1495	},
1496	{
1497		.data_type	= QMI_OPT_FLAG,
1498		.elem_len	= 1,
1499		.elem_size	= sizeof(u8),
1500		.array_type	= NO_ARRAY,
1501		.tlv_type	= 0x13,
1502		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1503					   data_valid),
1504	},
1505	{
1506		.data_type	= QMI_DATA_LEN,
1507		.elem_len	= 1,
1508		.elem_size	= sizeof(u16),
1509		.array_type	= NO_ARRAY,
1510		.tlv_type	= 0x13,
1511		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1512					   data_len),
1513	},
1514	{
1515		.data_type	= QMI_UNSIGNED_1_BYTE,
1516		.elem_len	= QMI_WLANFW_MAX_DATA_SIZE_V01,
1517		.elem_size	= sizeof(u8),
1518		.array_type	= VAR_LEN_ARRAY,
1519		.tlv_type	= 0x13,
1520		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1521					   data),
1522	},
1523	{
1524		.data_type	= QMI_OPT_FLAG,
1525		.elem_len	= 1,
1526		.elem_size	= sizeof(u8),
1527		.array_type	= NO_ARRAY,
1528		.tlv_type	= 0x14,
1529		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1530					   end_valid),
1531	},
1532	{
1533		.data_type	= QMI_UNSIGNED_1_BYTE,
1534		.elem_len	= 1,
1535		.elem_size	= sizeof(u8),
1536		.array_type	= NO_ARRAY,
1537		.tlv_type	= 0x14,
1538		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1539					   end),
1540	},
1541	{
1542		.data_type	= QMI_OPT_FLAG,
1543		.elem_len	= 1,
1544		.elem_size	= sizeof(u8),
1545		.array_type	= NO_ARRAY,
1546		.tlv_type	= 0x15,
1547		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1548					   bdf_type_valid),
1549	},
1550	{
1551		.data_type	= QMI_UNSIGNED_1_BYTE,
1552		.elem_len	= 1,
1553		.elem_size	= sizeof(u8),
1554		.array_type	= NO_ARRAY,
1555		.tlv_type	= 0x15,
1556		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1557					   bdf_type),
1558	},
1559
1560	{
1561		.data_type	= QMI_EOTI,
1562		.array_type	= NO_ARRAY,
1563		.tlv_type	= QMI_COMMON_TLV_TYPE,
1564	},
1565};
1566
1567static const struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = {
1568	{
1569		.data_type	= QMI_STRUCT,
1570		.elem_len	= 1,
1571		.elem_size	= sizeof(struct qmi_response_type_v01),
1572		.array_type	= NO_ARRAY,
1573		.tlv_type	= 0x02,
1574		.offset		= offsetof(struct qmi_wlanfw_bdf_download_resp_msg_v01,
1575					   resp),
1576		.ei_array	= qmi_response_type_v01_ei,
1577	},
1578	{
1579		.data_type	= QMI_EOTI,
1580		.array_type	= NO_ARRAY,
1581		.tlv_type	= QMI_COMMON_TLV_TYPE,
1582	},
1583};
1584
1585static const struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = {
1586	{
1587		.data_type	= QMI_UNSIGNED_8_BYTE,
1588		.elem_len	= 1,
1589		.elem_size	= sizeof(u64),
1590		.array_type	= NO_ARRAY,
1591		.tlv_type	= 0x01,
1592		.offset		= offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, addr),
1593	},
1594	{
1595		.data_type	= QMI_UNSIGNED_4_BYTE,
1596		.elem_len	= 1,
1597		.elem_size	= sizeof(u32),
1598		.array_type	= NO_ARRAY,
1599		.tlv_type	= 0x02,
1600		.offset		= offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, size),
1601	},
1602	{
1603		.data_type	= QMI_EOTI,
1604		.array_type	= NO_ARRAY,
1605		.tlv_type	= QMI_COMMON_TLV_TYPE,
1606	},
1607};
1608
1609static const struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = {
1610	{
1611		.data_type	= QMI_STRUCT,
1612		.elem_len	= 1,
1613		.elem_size	= sizeof(struct qmi_response_type_v01),
1614		.array_type	= NO_ARRAY,
1615		.tlv_type	= 0x02,
1616		.offset		= offsetof(struct qmi_wlanfw_m3_info_resp_msg_v01, resp),
1617		.ei_array	= qmi_response_type_v01_ei,
1618	},
1619	{
1620		.data_type	= QMI_EOTI,
1621		.array_type	= NO_ARRAY,
1622		.tlv_type	= QMI_COMMON_TLV_TYPE,
1623	},
1624};
1625
1626static const struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = {
1627	{
1628		.data_type	= QMI_UNSIGNED_4_BYTE,
1629		.elem_len	= 1,
1630		.elem_size	= sizeof(u32),
1631		.array_type	= NO_ARRAY,
1632		.tlv_type	= 0,
1633		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1634					   pipe_num),
1635	},
1636	{
1637		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
1638		.elem_len	= 1,
1639		.elem_size	= sizeof(enum qmi_wlanfw_pipedir_enum_v01),
1640		.array_type	= NO_ARRAY,
1641		.tlv_type	= 0,
1642		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1643					   pipe_dir),
1644	},
1645	{
1646		.data_type	= QMI_UNSIGNED_4_BYTE,
1647		.elem_len	= 1,
1648		.elem_size	= sizeof(u32),
1649		.array_type	= NO_ARRAY,
1650		.tlv_type	= 0,
1651		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1652					   nentries),
1653	},
1654	{
1655		.data_type	= QMI_UNSIGNED_4_BYTE,
1656		.elem_len	= 1,
1657		.elem_size	= sizeof(u32),
1658		.array_type	= NO_ARRAY,
1659		.tlv_type	= 0,
1660		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1661					   nbytes_max),
1662	},
1663	{
1664		.data_type	= QMI_UNSIGNED_4_BYTE,
1665		.elem_len	= 1,
1666		.elem_size	= sizeof(u32),
1667		.array_type	= NO_ARRAY,
1668		.tlv_type	= 0,
1669		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1670					   flags),
1671	},
1672	{
1673		.data_type	= QMI_EOTI,
1674		.array_type	= NO_ARRAY,
1675		.tlv_type	= QMI_COMMON_TLV_TYPE,
1676	},
1677};
1678
1679static const struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = {
1680	{
1681		.data_type	= QMI_UNSIGNED_4_BYTE,
1682		.elem_len	= 1,
1683		.elem_size	= sizeof(u32),
1684		.array_type	= NO_ARRAY,
1685		.tlv_type	= 0,
1686		.offset		= offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1687					   service_id),
1688	},
1689	{
1690		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
1691		.elem_len	= 1,
1692		.elem_size	= sizeof(enum qmi_wlanfw_pipedir_enum_v01),
1693		.array_type	= NO_ARRAY,
1694		.tlv_type	= 0,
1695		.offset		= offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1696					   pipe_dir),
1697	},
1698	{
1699		.data_type	= QMI_UNSIGNED_4_BYTE,
1700		.elem_len	= 1,
1701		.elem_size	= sizeof(u32),
1702		.array_type	= NO_ARRAY,
1703		.tlv_type	= 0,
1704		.offset		= offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1705					   pipe_num),
1706	},
1707	{
1708		.data_type	= QMI_EOTI,
1709		.array_type	= NO_ARRAY,
1710		.tlv_type	= QMI_COMMON_TLV_TYPE,
1711	},
1712};
1713
1714static const struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = {
1715	{
1716		.data_type	= QMI_UNSIGNED_2_BYTE,
1717		.elem_len	= 1,
1718		.elem_size	= sizeof(u16),
1719		.array_type	= NO_ARRAY,
1720		.tlv_type	= 0,
1721		.offset		= offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01, id),
1722	},
1723	{
1724		.data_type	= QMI_UNSIGNED_2_BYTE,
1725		.elem_len	= 1,
1726		.elem_size	= sizeof(u16),
1727		.array_type	= NO_ARRAY,
1728		.tlv_type	= 0,
1729		.offset		= offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01,
1730					   offset),
1731	},
1732	{
1733		.data_type	= QMI_EOTI,
1734		.array_type	= QMI_COMMON_TLV_TYPE,
1735	},
1736};
1737
1738static const struct qmi_elem_info qmi_wlanfw_shadow_reg_v3_cfg_s_v01_ei[] = {
1739	{
1740		.data_type	= QMI_UNSIGNED_4_BYTE,
1741		.elem_len	= 1,
1742		.elem_size	= sizeof(u32),
1743		.array_type	= NO_ARRAY,
1744		.tlv_type	= 0,
1745		.offset		= offsetof(struct qmi_wlanfw_shadow_reg_v3_cfg_s_v01,
1746					   addr),
1747	},
1748	{
1749		.data_type	= QMI_EOTI,
1750		.array_type	= NO_ARRAY,
1751		.tlv_type	= QMI_COMMON_TLV_TYPE,
1752	},
1753};
1754
1755static const struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = {
1756	{
1757		.data_type	= QMI_UNSIGNED_4_BYTE,
1758		.elem_len	= 1,
1759		.elem_size	= sizeof(u32),
1760		.array_type	= NO_ARRAY,
1761		.tlv_type	= 0x01,
1762		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1763					   mode),
1764	},
1765	{
1766		.data_type	= QMI_OPT_FLAG,
1767		.elem_len	= 1,
1768		.elem_size	= sizeof(u8),
1769		.array_type	= NO_ARRAY,
1770		.tlv_type	= 0x10,
1771		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1772					   hw_debug_valid),
1773	},
1774	{
1775		.data_type	= QMI_UNSIGNED_1_BYTE,
1776		.elem_len	= 1,
1777		.elem_size	= sizeof(u8),
1778		.array_type	= NO_ARRAY,
1779		.tlv_type	= 0x10,
1780		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1781					   hw_debug),
1782	},
1783	{
1784		.data_type	= QMI_EOTI,
1785		.array_type	= NO_ARRAY,
1786		.tlv_type	= QMI_COMMON_TLV_TYPE,
1787	},
1788};
1789
1790static const struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = {
1791	{
1792		.data_type	= QMI_STRUCT,
1793		.elem_len	= 1,
1794		.elem_size	= sizeof(struct qmi_response_type_v01),
1795		.array_type	= NO_ARRAY,
1796		.tlv_type	= 0x02,
1797		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_resp_msg_v01,
1798					   resp),
1799		.ei_array	= qmi_response_type_v01_ei,
1800	},
1801	{
1802		.data_type	= QMI_EOTI,
1803		.array_type	= NO_ARRAY,
1804		.tlv_type	= QMI_COMMON_TLV_TYPE,
1805	},
1806};
1807
1808static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {
1809	{
1810		.data_type	= QMI_OPT_FLAG,
1811		.elem_len	= 1,
1812		.elem_size	= sizeof(u8),
1813		.array_type	= NO_ARRAY,
1814		.tlv_type	= 0x10,
1815		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1816					   host_version_valid),
1817	},
1818	{
1819		.data_type	= QMI_STRING,
1820		.elem_len	= QMI_WLANFW_MAX_STR_LEN_V01 + 1,
1821		.elem_size	= sizeof(char),
1822		.array_type	= NO_ARRAY,
1823		.tlv_type	= 0x10,
1824		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1825					   host_version),
1826	},
1827	{
1828		.data_type	= QMI_OPT_FLAG,
1829		.elem_len	= 1,
1830		.elem_size	= sizeof(u8),
1831		.array_type	= NO_ARRAY,
1832		.tlv_type	= 0x11,
1833		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1834					   tgt_cfg_valid),
1835	},
1836	{
1837		.data_type	= QMI_DATA_LEN,
1838		.elem_len	= 1,
1839		.elem_size	= sizeof(u8),
1840		.array_type	= NO_ARRAY,
1841		.tlv_type	= 0x11,
1842		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1843					   tgt_cfg_len),
1844	},
1845	{
1846		.data_type	= QMI_STRUCT,
1847		.elem_len	= QMI_WLANFW_MAX_NUM_CE_V01,
1848		.elem_size	= sizeof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01),
1849		.array_type	= VAR_LEN_ARRAY,
1850		.tlv_type	= 0x11,
1851		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1852					   tgt_cfg),
1853		.ei_array	= qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei,
1854	},
1855	{
1856		.data_type	= QMI_OPT_FLAG,
1857		.elem_len	= 1,
1858		.elem_size	= sizeof(u8),
1859		.array_type	= NO_ARRAY,
1860		.tlv_type	= 0x12,
1861		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1862					   svc_cfg_valid),
1863	},
1864	{
1865		.data_type	= QMI_DATA_LEN,
1866		.elem_len	= 1,
1867		.elem_size	= sizeof(u8),
1868		.array_type	= NO_ARRAY,
1869		.tlv_type	= 0x12,
1870		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1871					   svc_cfg_len),
1872	},
1873	{
1874		.data_type	= QMI_STRUCT,
1875		.elem_len	= QMI_WLANFW_MAX_NUM_SVC_V01,
1876		.elem_size	= sizeof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01),
1877		.array_type	= VAR_LEN_ARRAY,
1878		.tlv_type	= 0x12,
1879		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1880					   svc_cfg),
1881		.ei_array	= qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei,
1882	},
1883	{
1884		.data_type	= QMI_OPT_FLAG,
1885		.elem_len	= 1,
1886		.elem_size	= sizeof(u8),
1887		.array_type = NO_ARRAY,
1888		.tlv_type	= 0x13,
1889		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1890					   shadow_reg_valid),
1891	},
1892	{
1893		.data_type	= QMI_DATA_LEN,
1894		.elem_len	= 1,
1895		.elem_size	= sizeof(u8),
1896		.array_type = NO_ARRAY,
1897		.tlv_type	= 0x13,
1898		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1899					   shadow_reg_len),
1900	},
1901	{
1902		.data_type	= QMI_STRUCT,
1903		.elem_len	= QMI_WLANFW_MAX_NUM_SHADOW_REG_V01,
1904		.elem_size	= sizeof(struct qmi_wlanfw_shadow_reg_cfg_s_v01),
1905		.array_type = VAR_LEN_ARRAY,
1906		.tlv_type	= 0x13,
1907		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1908					   shadow_reg),
1909		.ei_array	= qmi_wlanfw_shadow_reg_cfg_s_v01_ei,
1910	},
1911	{
1912		.data_type	= QMI_OPT_FLAG,
1913		.elem_len	= 1,
1914		.elem_size	= sizeof(u8),
1915		.array_type	= NO_ARRAY,
1916		.tlv_type	= 0x17,
1917		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1918					   shadow_reg_v3_valid),
1919	},
1920	{
1921		.data_type	= QMI_DATA_LEN,
1922		.elem_len	= 1,
1923		.elem_size	= sizeof(u8),
1924		.array_type	= NO_ARRAY,
1925		.tlv_type	= 0x17,
1926		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1927					   shadow_reg_v3_len),
1928	},
1929	{
1930		.data_type	= QMI_STRUCT,
1931		.elem_len	= QMI_WLANFW_MAX_NUM_SHADOW_REG_V3_V01,
1932		.elem_size	= sizeof(struct qmi_wlanfw_shadow_reg_v3_cfg_s_v01),
1933		.array_type	= VAR_LEN_ARRAY,
1934		.tlv_type	= 0x17,
1935		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1936					   shadow_reg_v3),
1937		.ei_array	= qmi_wlanfw_shadow_reg_v3_cfg_s_v01_ei,
1938	},
1939	{
1940		.data_type	= QMI_EOTI,
1941		.array_type	= NO_ARRAY,
1942		.tlv_type	= QMI_COMMON_TLV_TYPE,
1943	},
1944};
1945
1946static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = {
1947	{
1948		.data_type	= QMI_STRUCT,
1949		.elem_len	= 1,
1950		.elem_size	= sizeof(struct qmi_response_type_v01),
1951		.array_type	= NO_ARRAY,
1952		.tlv_type	= 0x02,
1953		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_resp_msg_v01, resp),
1954		.ei_array	= qmi_response_type_v01_ei,
1955	},
1956	{
1957		.data_type	= QMI_EOTI,
1958		.array_type	= NO_ARRAY,
1959		.tlv_type	= QMI_COMMON_TLV_TYPE,
1960	},
1961};
1962
1963static const struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = {
1964	{
1965		.data_type = QMI_EOTI,
1966		.array_type = NO_ARRAY,
1967	},
1968};
1969
1970static const struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = {
1971	{
1972		.data_type = QMI_EOTI,
1973		.array_type = NO_ARRAY,
1974	},
1975};
1976
1977static const struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = {
1978	{
1979		.data_type	= QMI_OPT_FLAG,
1980		.elem_len	= 1,
1981		.elem_size	= sizeof(u8),
1982		.array_type	= NO_ARRAY,
1983		.tlv_type	= 0x10,
1984		.offset		= offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,
1985					   enable_fwlog_valid),
1986	},
1987	{
1988		.data_type	= QMI_UNSIGNED_1_BYTE,
1989		.elem_len	= 1,
1990		.elem_size	= sizeof(u8),
1991		.array_type	= NO_ARRAY,
1992		.tlv_type	= 0x10,
1993		.offset		= offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,
1994					   enable_fwlog),
1995	},
1996	{
1997		.data_type	= QMI_EOTI,
1998		.array_type	= NO_ARRAY,
1999		.tlv_type	= QMI_COMMON_TLV_TYPE,
2000	},
2001};
2002
2003static const struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = {
2004	{
2005		.data_type	= QMI_STRUCT,
2006		.elem_len	= 1,
2007		.elem_size	= sizeof(struct qmi_response_type_v01),
2008		.array_type	= NO_ARRAY,
2009		.tlv_type	= 0x02,
2010		.offset		= offsetof(struct qmi_wlanfw_wlan_ini_resp_msg_v01,
2011					   resp),
2012		.ei_array	= qmi_response_type_v01_ei,
2013	},
2014	{
2015		.data_type	= QMI_EOTI,
2016		.array_type	= NO_ARRAY,
2017		.tlv_type	= QMI_COMMON_TLV_TYPE,
2018	},
2019};
2020
2021static void ath12k_host_cap_hw_link_id_init(struct ath12k_hw_group *ag)
2022{
2023	struct ath12k_base *ab, *partner_ab;
2024	int i, j, hw_id_base;
2025
2026	for (i = 0; i < ag->num_devices; i++) {
2027		hw_id_base = 0;
2028		ab = ag->ab[i];
2029
2030		for (j = 0; j < ag->num_devices; j++) {
2031			partner_ab = ag->ab[j];
2032
2033			if (partner_ab->wsi_info.index >= ab->wsi_info.index)
2034				continue;
2035
2036			hw_id_base += partner_ab->qmi.num_radios;
2037		}
2038
2039		ab->wsi_info.hw_link_id_base = hw_id_base;
2040	}
2041
2042	ag->hw_link_id_init_done = true;
2043}
2044
2045static int ath12k_host_cap_parse_mlo(struct ath12k_base *ab,
2046				     struct qmi_wlanfw_host_cap_req_msg_v01 *req)
2047{
2048	struct wlfw_host_mlo_chip_info_s_v01 *info;
2049	struct ath12k_hw_group *ag = ab->ag;
2050	struct ath12k_base *partner_ab;
2051	u8 hw_link_id = 0;
2052	int i, j, ret;
2053
2054	if (!ag->mlo_capable) {
2055		ath12k_dbg(ab, ATH12K_DBG_QMI,
2056			   "MLO is disabled hence skip QMI MLO cap");
2057		return 0;
2058	}
2059
2060	if (!ab->qmi.num_radios || ab->qmi.num_radios == U8_MAX) {
2061		ag->mlo_capable = false;
2062		ath12k_dbg(ab, ATH12K_DBG_QMI,
2063			   "skip QMI MLO cap due to invalid num_radio %d\n",
2064			   ab->qmi.num_radios);
2065		return 0;
2066	}
2067
2068	if (ab->device_id == ATH12K_INVALID_DEVICE_ID) {
2069		ath12k_err(ab, "failed to send MLO cap due to invalid device id\n");
2070		return -EINVAL;
2071	}
2072
2073	req->mlo_capable_valid = 1;
2074	req->mlo_capable = 1;
2075	req->mlo_chip_id_valid = 1;
2076	req->mlo_chip_id = ab->device_id;
2077	req->mlo_group_id_valid = 1;
2078	req->mlo_group_id = ag->id;
2079	req->max_mlo_peer_valid = 1;
2080	/* Max peer number generally won't change for the same device
2081	 * but needs to be synced with host driver.
2082	 */
2083	req->max_mlo_peer = ab->hw_params->max_mlo_peer;
2084	req->mlo_num_chips_valid = 1;
2085	req->mlo_num_chips = ag->num_devices;
2086
2087	ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo capability advertisement device_id %d group_id %d num_devices %d",
2088		   req->mlo_chip_id, req->mlo_group_id, req->mlo_num_chips);
2089
2090	mutex_lock(&ag->mutex);
2091
2092	if (!ag->hw_link_id_init_done)
2093		ath12k_host_cap_hw_link_id_init(ag);
2094
2095	for (i = 0; i < ag->num_devices; i++) {
2096		info = &req->mlo_chip_info[i];
2097		partner_ab = ag->ab[i];
2098
2099		if (partner_ab->device_id == ATH12K_INVALID_DEVICE_ID) {
2100			ath12k_err(ab, "failed to send MLO cap due to invalid partner device id\n");
2101			ret = -EINVAL;
2102			goto device_cleanup;
2103		}
2104
2105		info->chip_id = partner_ab->device_id;
2106		info->num_local_links = partner_ab->qmi.num_radios;
2107
2108		ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo device id %d num_link %d\n",
2109			   info->chip_id, info->num_local_links);
2110
2111		for (j = 0; j < info->num_local_links; j++) {
2112			info->hw_link_id[j] = partner_ab->wsi_info.hw_link_id_base + j;
2113			info->valid_mlo_link_id[j] = 1;
2114
2115			ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo hw_link_id %d\n",
2116				   info->hw_link_id[j]);
2117
2118			hw_link_id++;
2119		}
2120	}
2121
2122	if (hw_link_id <= 0)
2123		ag->mlo_capable = false;
2124
2125	req->mlo_chip_info_valid = 1;
2126
2127	mutex_unlock(&ag->mutex);
2128
2129	return 0;
2130
2131device_cleanup:
2132	for (i = i - 1; i >= 0; i--) {
2133		info = &req->mlo_chip_info[i];
2134
2135		memset(info, 0, sizeof(*info));
2136	}
2137
2138	req->mlo_num_chips = 0;
2139	req->mlo_num_chips_valid = 0;
2140
2141	req->max_mlo_peer = 0;
2142	req->max_mlo_peer_valid = 0;
2143	req->mlo_group_id = 0;
2144	req->mlo_group_id_valid = 0;
2145	req->mlo_chip_id = 0;
2146	req->mlo_chip_id_valid = 0;
2147	req->mlo_capable = 0;
2148	req->mlo_capable_valid = 0;
2149
2150	ag->mlo_capable = false;
2151
2152	mutex_unlock(&ag->mutex);
2153
2154	return ret;
2155}
2156
2157/* clang stack usage explodes if this is inlined */
2158static noinline_for_stack
2159int ath12k_qmi_host_cap_send(struct ath12k_base *ab)
2160{
2161	struct qmi_wlanfw_host_cap_req_msg_v01 req = {};
2162	struct qmi_wlanfw_host_cap_resp_msg_v01 resp = {};
2163	struct qmi_txn txn;
2164	int ret = 0;
2165
2166	req.num_clients_valid = 1;
2167	req.num_clients = 1;
2168	req.mem_cfg_mode = ab->qmi.target_mem_mode;
2169	req.mem_cfg_mode_valid = 1;
2170	req.bdf_support_valid = 1;
2171	req.bdf_support = 1;
2172
2173	if (ab->hw_params->fw.m3_loader == ath12k_m3_fw_loader_driver) {
2174		req.m3_support_valid = 1;
2175		req.m3_support = 1;
2176		req.m3_cache_support_valid = 1;
2177		req.m3_cache_support = 1;
2178	}
2179
2180	req.cal_done_valid = 1;
2181	req.cal_done = ab->qmi.cal_done;
2182
2183	if (ab->hw_params->qmi_cnss_feature_bitmap) {
2184		req.feature_list_valid = 1;
2185		req.feature_list = ab->hw_params->qmi_cnss_feature_bitmap;
2186	}
2187
2188	/* BRINGUP: here we are piggybacking a lot of stuff using
2189	 * internal_sleep_clock, should it be split?
2190	 */
2191	if (ab->hw_params->internal_sleep_clock) {
2192		req.nm_modem_valid = 1;
2193
2194		/* Notify firmware that this is non-qualcomm platform. */
2195		req.nm_modem |= HOST_CSTATE_BIT;
2196
2197		/* Notify firmware about the sleep clock selection,
2198		 * nm_modem_bit[1] is used for this purpose. Host driver on
2199		 * non-qualcomm platforms should select internal sleep
2200		 * clock.
2201		 */
2202		req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT;
2203		req.nm_modem |= PLATFORM_CAP_PCIE_GLOBAL_RESET;
2204	}
2205
2206	ret = ath12k_host_cap_parse_mlo(ab, &req);
2207	if (ret < 0)
2208		goto out;
2209
2210	ret = qmi_txn_init(&ab->qmi.handle, &txn,
2211			   qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);
2212	if (ret < 0)
2213		goto out;
2214
2215	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2216			       QMI_WLANFW_HOST_CAP_REQ_V01,
2217			       QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN,
2218			       qmi_wlanfw_host_cap_req_msg_v01_ei, &req);
2219	if (ret < 0) {
2220		qmi_txn_cancel(&txn);
2221		ath12k_warn(ab, "Failed to send host capability request,err = %d\n", ret);
2222		goto out;
2223	}
2224
2225	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2226	if (ret < 0)
2227		goto out;
2228
2229	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2230		ath12k_warn(ab, "Host capability request failed, result: %d, err: %d\n",
2231			    resp.resp.result, resp.resp.error);
2232		ret = -EINVAL;
2233		goto out;
2234	}
2235
2236out:
2237	return ret;
2238}
2239
2240static void ath12k_qmi_phy_cap_send(struct ath12k_base *ab)
2241{
2242	struct qmi_wlanfw_phy_cap_req_msg_v01 req = {};
2243	struct qmi_wlanfw_phy_cap_resp_msg_v01 resp = {};
2244	struct qmi_txn txn;
2245	int ret;
2246
2247	ret = qmi_txn_init(&ab->qmi.handle, &txn,
2248			   qmi_wlanfw_phy_cap_resp_msg_v01_ei, &resp);
2249	if (ret < 0)
2250		goto out;
2251
2252	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2253			       QMI_WLANFW_PHY_CAP_REQ_V01,
2254			       QMI_WLANFW_PHY_CAP_REQ_MSG_V01_MAX_LEN,
2255			       qmi_wlanfw_phy_cap_req_msg_v01_ei, &req);
2256	if (ret < 0) {
2257		qmi_txn_cancel(&txn);
2258		ath12k_warn(ab, "failed to send phy capability request: %d\n", ret);
2259		goto out;
2260	}
2261
2262	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2263	if (ret < 0)
2264		goto out;
2265
2266	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2267		ret = -EOPNOTSUPP;
2268		goto out;
2269	}
2270
2271	if (resp.single_chip_mlo_support_valid && resp.single_chip_mlo_support)
2272		ab->single_chip_mlo_support = true;
2273
2274	if (!resp.num_phy_valid) {
2275		ret = -ENODATA;
2276		goto out;
2277	}
2278
2279	ab->qmi.num_radios = resp.num_phy;
2280
2281	ath12k_dbg(ab, ATH12K_DBG_QMI,
2282		   "phy capability resp valid %d single_chip_mlo_support %d valid %d num_phy %d valid %d board_id %d\n",
2283		   resp.single_chip_mlo_support_valid, resp.single_chip_mlo_support,
2284		   resp.num_phy_valid, resp.num_phy,
2285		   resp.board_id_valid, resp.board_id);
2286
2287	return;
2288
2289out:
2290	/* If PHY capability not advertised then rely on default num link */
2291	ab->qmi.num_radios = ab->hw_params->def_num_link;
2292
2293	ath12k_dbg(ab, ATH12K_DBG_QMI,
2294		   "no valid response from PHY capability, choose default num_phy %d\n",
2295		   ab->qmi.num_radios);
2296}
2297
2298static int ath12k_qmi_fw_ind_register_send(struct ath12k_base *ab)
2299{
2300	struct qmi_wlanfw_ind_register_req_msg_v01 *req;
2301	struct qmi_wlanfw_ind_register_resp_msg_v01 *resp;
2302	struct qmi_handle *handle = &ab->qmi.handle;
2303	struct qmi_txn txn;
2304	int ret;
2305
2306	req = kzalloc(sizeof(*req), GFP_KERNEL);
2307	if (!req)
2308		return -ENOMEM;
2309
2310	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
2311	if (!resp) {
2312		ret = -ENOMEM;
2313		goto resp_out;
2314	}
2315
2316	req->client_id_valid = 1;
2317	req->client_id = QMI_WLANFW_CLIENT_ID;
2318	req->fw_ready_enable_valid = 1;
2319	req->fw_ready_enable = 1;
2320	req->request_mem_enable_valid = 1;
2321	req->request_mem_enable = 1;
2322	req->fw_mem_ready_enable_valid = 1;
2323	req->fw_mem_ready_enable = 1;
2324	req->cal_done_enable_valid = 1;
2325	req->cal_done_enable = 1;
2326	req->fw_init_done_enable_valid = 1;
2327	req->fw_init_done_enable = 1;
2328
2329	req->pin_connect_result_enable_valid = 0;
2330	req->pin_connect_result_enable = 0;
2331
2332	ret = qmi_txn_init(handle, &txn,
2333			   qmi_wlanfw_ind_register_resp_msg_v01_ei, resp);
2334	if (ret < 0)
2335		goto out;
2336
2337	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2338			       QMI_WLANFW_IND_REGISTER_REQ_V01,
2339			       QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,
2340			       qmi_wlanfw_ind_register_req_msg_v01_ei, req);
2341	if (ret < 0) {
2342		qmi_txn_cancel(&txn);
2343		ath12k_warn(ab, "Failed to send indication register request, err = %d\n",
2344			    ret);
2345		goto out;
2346	}
2347
2348	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2349	if (ret < 0) {
2350		ath12k_warn(ab, "failed to register fw indication %d\n", ret);
2351		goto out;
2352	}
2353
2354	if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
2355		ath12k_warn(ab, "FW Ind register request failed, result: %d, err: %d\n",
2356			    resp->resp.result, resp->resp.error);
2357		ret = -EINVAL;
2358		goto out;
2359	}
2360
2361out:
2362	kfree(resp);
2363resp_out:
2364	kfree(req);
2365	return ret;
2366}
2367
2368/* clang stack usage explodes if this is inlined */
2369static noinline_for_stack
2370int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab)
2371{
2372	struct qmi_wlanfw_respond_mem_req_msg_v01 *req;
2373	struct qmi_wlanfw_respond_mem_resp_msg_v01 resp = {};
2374	struct qmi_txn txn;
2375	int ret = 0, i;
2376	bool delayed;
2377
2378	req = kzalloc(sizeof(*req), GFP_KERNEL);
2379	if (!req)
2380		return -ENOMEM;
2381
2382	/* Some targets by default request a block of big contiguous
2383	 * DMA memory, it's hard to allocate from kernel. So host returns
2384	 * failure to firmware and firmware then request multiple blocks of
2385	 * small chunk size memory.
2386	 */
2387	if (!test_bit(ATH12K_FLAG_FIXED_MEM_REGION, &ab->dev_flags) &&
2388	    ab->qmi.target_mem_delayed) {
2389		delayed = true;
2390		ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi delays mem_request %d\n",
2391			   ab->qmi.mem_seg_count);
2392	} else {
2393		delayed = false;
2394		req->mem_seg_len = ab->qmi.mem_seg_count;
2395		for (i = 0; i < req->mem_seg_len ; i++) {
2396			req->mem_seg[i].addr = ab->qmi.target_mem[i].paddr;
2397			req->mem_seg[i].size = ab->qmi.target_mem[i].size;
2398			req->mem_seg[i].type = ab->qmi.target_mem[i].type;
2399			ath12k_dbg(ab, ATH12K_DBG_QMI,
2400				   "qmi req mem_seg[%d] %pad %u %u\n", i,
2401				   &ab->qmi.target_mem[i].paddr,
2402				   ab->qmi.target_mem[i].size,
2403				   ab->qmi.target_mem[i].type);
2404		}
2405	}
2406
2407	ret = qmi_txn_init(&ab->qmi.handle, &txn,
2408			   qmi_wlanfw_respond_mem_resp_msg_v01_ei, &resp);
2409	if (ret < 0)
2410		goto out;
2411
2412	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2413			       QMI_WLANFW_RESPOND_MEM_REQ_V01,
2414			       QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,
2415			       qmi_wlanfw_respond_mem_req_msg_v01_ei, req);
2416	if (ret < 0) {
2417		qmi_txn_cancel(&txn);
2418		ath12k_warn(ab, "qmi failed to respond memory request, err = %d\n",
2419			    ret);
2420		goto out;
2421	}
2422
2423	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2424	if (ret < 0) {
2425		ath12k_warn(ab, "qmi failed memory request, err = %d\n", ret);
2426		goto out;
2427	}
2428
2429	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2430		/* the error response is expected when
2431		 * target_mem_delayed is true.
2432		 */
2433		if (delayed && resp.resp.error == 0)
2434			goto out;
2435
2436		ath12k_warn(ab, "Respond mem req failed, result: %d, err: %d\n",
2437			    resp.resp.result, resp.resp.error);
2438		ret = -EINVAL;
2439		goto out;
2440	}
2441out:
2442	kfree(req);
2443	return ret;
2444}
2445
2446void ath12k_qmi_reset_mlo_mem(struct ath12k_hw_group *ag)
2447{
2448	struct target_mem_chunk *mlo_chunk;
2449	int i;
2450
2451	lockdep_assert_held(&ag->mutex);
2452
2453	if (!ag->mlo_mem.init_done || ag->num_started)
2454		return;
2455
2456	for (i = 0; i < ARRAY_SIZE(ag->mlo_mem.chunk); i++) {
2457		mlo_chunk = &ag->mlo_mem.chunk[i];
2458
2459		if (mlo_chunk->v.addr)
2460			/* TODO: Mode 0 recovery is the default mode hence resetting the
2461			 * whole memory region for now. Once Mode 1 support is added, this
2462			 * needs to be handled properly
2463			 */
2464			memset(mlo_chunk->v.addr, 0, mlo_chunk->size);
2465	}
2466}
2467
2468static void ath12k_qmi_free_mlo_mem_chunk(struct ath12k_base *ab,
2469					  struct target_mem_chunk *chunk,
2470					  int idx)
2471{
2472	struct ath12k_hw_group *ag = ab->ag;
2473	struct target_mem_chunk *mlo_chunk;
2474	bool fixed_mem;
2475
2476	lockdep_assert_held(&ag->mutex);
2477
2478	if (!ag->mlo_mem.init_done || ag->num_started)
2479		return;
2480
2481	if (idx >= ARRAY_SIZE(ag->mlo_mem.chunk)) {
2482		ath12k_warn(ab, "invalid index for MLO memory chunk free: %d\n", idx);
2483		return;
2484	}
2485
2486	fixed_mem = test_bit(ATH12K_FLAG_FIXED_MEM_REGION, &ab->dev_flags);
2487	mlo_chunk = &ag->mlo_mem.chunk[idx];
2488
2489	if (fixed_mem && mlo_chunk->v.ioaddr) {
2490		iounmap(mlo_chunk->v.ioaddr);
2491		mlo_chunk->v.ioaddr = NULL;
2492	} else if (mlo_chunk->v.addr) {
2493		dma_free_coherent(ab->dev,
2494				  mlo_chunk->size,
2495				  mlo_chunk->v.addr,
2496				  mlo_chunk->paddr);
2497		mlo_chunk->v.addr = NULL;
2498	}
2499
2500	mlo_chunk->paddr = 0;
2501	mlo_chunk->size = 0;
2502	if (fixed_mem)
2503		chunk->v.ioaddr = NULL;
2504	else
2505		chunk->v.addr = NULL;
2506	chunk->paddr = 0;
2507	chunk->size = 0;
2508}
2509
2510static void ath12k_qmi_free_target_mem_chunk(struct ath12k_base *ab)
2511{
2512	struct ath12k_hw_group *ag = ab->ag;
2513	int i, mlo_idx;
2514
2515	for (i = 0, mlo_idx = 0; i < ab->qmi.mem_seg_count; i++) {
2516		if (ab->qmi.target_mem[i].type == MLO_GLOBAL_MEM_REGION_TYPE) {
2517			ath12k_qmi_free_mlo_mem_chunk(ab,
2518						      &ab->qmi.target_mem[i],
2519						      mlo_idx++);
2520		} else {
2521			if (test_bit(ATH12K_FLAG_FIXED_MEM_REGION, &ab->dev_flags) &&
2522			    ab->qmi.target_mem[i].v.ioaddr) {
2523				iounmap(ab->qmi.target_mem[i].v.ioaddr);
2524				ab->qmi.target_mem[i].v.ioaddr = NULL;
2525			} else {
2526				if (!ab->qmi.target_mem[i].v.addr)
2527					continue;
2528				dma_free_coherent(ab->dev,
2529						  ab->qmi.target_mem[i].prev_size,
2530						  ab->qmi.target_mem[i].v.addr,
2531						  ab->qmi.target_mem[i].paddr);
2532				ab->qmi.target_mem[i].v.addr = NULL;
2533			}
2534		}
2535	}
2536
2537	if (!ag->num_started && ag->mlo_mem.init_done) {
2538		ag->mlo_mem.init_done = false;
2539		ag->mlo_mem.mlo_mem_size = 0;
2540	}
2541}
2542
2543static int ath12k_qmi_alloc_chunk(struct ath12k_base *ab,
2544				  struct target_mem_chunk *chunk)
2545{
2546	/* Firmware reloads in recovery/resume.
2547	 * In such cases, no need to allocate memory for FW again.
2548	 */
2549	if (chunk->v.addr) {
2550		if (chunk->prev_type == chunk->type &&
2551		    chunk->prev_size == chunk->size)
2552			goto this_chunk_done;
2553
2554		/* cannot reuse the existing chunk */
2555		dma_free_coherent(ab->dev, chunk->prev_size,
2556				  chunk->v.addr, chunk->paddr);
2557		chunk->v.addr = NULL;
2558	}
2559
2560	chunk->v.addr = dma_alloc_coherent(ab->dev,
2561					   chunk->size,
2562					   &chunk->paddr,
2563					   GFP_KERNEL | __GFP_NOWARN);
2564	if (!chunk->v.addr) {
2565		if (chunk->size > ATH12K_QMI_MAX_CHUNK_SIZE) {
2566			ab->qmi.target_mem_delayed = true;
2567			ath12k_warn(ab,
2568				    "qmi dma allocation failed (%d B type %u), will try later with small size\n",
2569				    chunk->size,
2570				    chunk->type);
2571			ath12k_qmi_free_target_mem_chunk(ab);
2572			return -EAGAIN;
2573		}
2574		ath12k_warn(ab, "memory allocation failure for %u size: %d\n",
2575			    chunk->type, chunk->size);
2576		return -ENOMEM;
2577	}
2578	chunk->prev_type = chunk->type;
2579	chunk->prev_size = chunk->size;
2580this_chunk_done:
2581	return 0;
2582}
2583
2584static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
2585{
2586	struct target_mem_chunk *chunk, *mlo_chunk;
2587	struct ath12k_hw_group *ag = ab->ag;
2588	int i, mlo_idx, ret;
2589	int mlo_size = 0;
2590
2591	mutex_lock(&ag->mutex);
2592
2593	if (!ag->mlo_mem.init_done) {
2594		memset(ag->mlo_mem.chunk, 0, sizeof(ag->mlo_mem.chunk));
2595		ag->mlo_mem.init_done = true;
2596	}
2597
2598	ab->qmi.target_mem_delayed = false;
2599
2600	for (i = 0, mlo_idx = 0; i < ab->qmi.mem_seg_count; i++) {
2601		chunk = &ab->qmi.target_mem[i];
2602
2603		/* Allocate memory for the region and the functionality supported
2604		 * on the host. For the non-supported memory region, host does not
2605		 * allocate memory, assigns NULL and FW will handle this without crashing.
2606		 */
2607		switch (chunk->type) {
2608		case HOST_DDR_REGION_TYPE:
2609		case M3_DUMP_REGION_TYPE:
2610		case PAGEABLE_MEM_REGION_TYPE:
2611		case CALDB_MEM_REGION_TYPE:
2612			ret = ath12k_qmi_alloc_chunk(ab, chunk);
2613			if (ret)
2614				goto err;
2615			break;
2616		case MLO_GLOBAL_MEM_REGION_TYPE:
2617			mlo_size += chunk->size;
2618			if (ag->mlo_mem.mlo_mem_size &&
2619			    mlo_size > ag->mlo_mem.mlo_mem_size) {
2620				ath12k_err(ab, "QMI MLO memory allocation failure, requested size %d is more than allocated size %d",
2621					   mlo_size, ag->mlo_mem.mlo_mem_size);
2622				ret = -EINVAL;
2623				goto err;
2624			}
2625
2626			mlo_chunk = &ag->mlo_mem.chunk[mlo_idx];
2627			if (mlo_chunk->paddr) {
2628				if (chunk->size != mlo_chunk->size) {
2629					ath12k_err(ab, "QMI MLO chunk memory allocation failure for index %d, requested size %d is more than allocated size %d",
2630						   mlo_idx, chunk->size, mlo_chunk->size);
2631					ret = -EINVAL;
2632					goto err;
2633				}
2634			} else {
2635				mlo_chunk->size = chunk->size;
2636				mlo_chunk->type = chunk->type;
2637				ret = ath12k_qmi_alloc_chunk(ab, mlo_chunk);
2638				if (ret)
2639					goto err;
2640				memset(mlo_chunk->v.addr, 0, mlo_chunk->size);
2641			}
2642
2643			chunk->paddr = mlo_chunk->paddr;
2644			chunk->v.addr = mlo_chunk->v.addr;
2645			mlo_idx++;
2646
2647			break;
2648		default:
2649			ath12k_warn(ab, "memory type %u not supported\n",
2650				    chunk->type);
2651			chunk->paddr = 0;
2652			chunk->v.addr = NULL;
2653			break;
2654		}
2655	}
2656
2657	if (!ag->mlo_mem.mlo_mem_size) {
2658		ag->mlo_mem.mlo_mem_size = mlo_size;
2659	} else if (ag->mlo_mem.mlo_mem_size != mlo_size) {
2660		ath12k_err(ab, "QMI MLO memory size error, expected size is %d but requested size is %d",
2661			   ag->mlo_mem.mlo_mem_size, mlo_size);
2662		ret = -EINVAL;
2663		goto err;
2664	}
2665
2666	mutex_unlock(&ag->mutex);
2667
2668	return 0;
2669
2670err:
2671	ath12k_qmi_free_target_mem_chunk(ab);
2672
2673	mutex_unlock(&ag->mutex);
2674
2675	/* The firmware will attempt to request memory in smaller chunks
2676	 * on the next try. However, the current caller should be notified
2677	 * that this instance of request parsing was successful.
2678	 * Therefore, return 0 only.
2679	 */
2680	if (ret == -EAGAIN)
2681		ret = 0;
2682
2683	return ret;
2684}
2685
2686static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
2687{
2688	struct reserved_mem *rmem;
2689	size_t avail_rmem_size;
2690	int i, idx, ret;
2691
2692	for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
2693		switch (ab->qmi.target_mem[i].type) {
2694		case HOST_DDR_REGION_TYPE:
2695			rmem = ath12k_core_get_reserved_mem(ab, 0);
2696			if (!rmem) {
2697				ret = -ENODEV;
2698				goto out;
2699			}
2700
2701			avail_rmem_size = rmem->size;
2702			if (avail_rmem_size < ab->qmi.target_mem[i].size) {
2703				ath12k_dbg(ab, ATH12K_DBG_QMI,
2704					   "failed to assign mem type %u req size %u avail size %zu\n",
2705					   ab->qmi.target_mem[i].type,
2706					   ab->qmi.target_mem[i].size,
2707					   avail_rmem_size);
2708				ret = -EINVAL;
2709				goto out;
2710			}
2711
2712			ab->qmi.target_mem[idx].paddr = rmem->base;
2713			ab->qmi.target_mem[idx].v.ioaddr =
2714				ioremap(ab->qmi.target_mem[idx].paddr,
2715					ab->qmi.target_mem[i].size);
2716			if (!ab->qmi.target_mem[idx].v.ioaddr) {
2717				ret = -EIO;
2718				goto out;
2719			}
2720			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
2721			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
2722			idx++;
2723			break;
2724		case BDF_MEM_REGION_TYPE:
2725			rmem = ath12k_core_get_reserved_mem(ab, 0);
2726			if (!rmem) {
2727				ret = -ENODEV;
2728				goto out;
2729			}
2730
2731			avail_rmem_size = rmem->size - ab->hw_params->bdf_addr_offset;
2732			if (avail_rmem_size < ab->qmi.target_mem[i].size) {
2733				ath12k_dbg(ab, ATH12K_DBG_QMI,
2734					   "failed to assign mem type %u req size %u avail size %zu\n",
2735					   ab->qmi.target_mem[i].type,
2736					   ab->qmi.target_mem[i].size,
2737					   avail_rmem_size);
2738				ret = -EINVAL;
2739				goto out;
2740			}
2741			ab->qmi.target_mem[idx].paddr =
2742				rmem->base + ab->hw_params->bdf_addr_offset;
2743			ab->qmi.target_mem[idx].v.ioaddr =
2744				ioremap(ab->qmi.target_mem[idx].paddr,
2745					ab->qmi.target_mem[i].size);
2746			if (!ab->qmi.target_mem[idx].v.ioaddr) {
2747				ret = -EIO;
2748				goto out;
2749			}
2750			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
2751			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
2752			idx++;
2753			break;
2754		case CALDB_MEM_REGION_TYPE:
2755			/* Cold boot calibration is not enabled in Ath12k. Hence,
2756			 * assign paddr = 0.
2757			 * Once cold boot calibration is enabled add support to
2758			 * assign reserved memory from DT.
2759			 */
2760			ab->qmi.target_mem[idx].paddr = 0;
2761			ab->qmi.target_mem[idx].v.ioaddr = NULL;
2762			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
2763			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
2764			idx++;
2765			break;
2766		case M3_DUMP_REGION_TYPE:
2767			rmem = ath12k_core_get_reserved_mem(ab, 1);
2768			if (!rmem) {
2769				ret = -EINVAL;
2770				goto out;
2771			}
2772
2773			avail_rmem_size = rmem->size;
2774			if (avail_rmem_size < ab->qmi.target_mem[i].size) {
2775				ath12k_dbg(ab, ATH12K_DBG_QMI,
2776					   "failed to assign mem type %u req size %u avail size %zu\n",
2777					   ab->qmi.target_mem[i].type,
2778					   ab->qmi.target_mem[i].size,
2779					   avail_rmem_size);
2780				ret = -EINVAL;
2781				goto out;
2782			}
2783
2784			ab->qmi.target_mem[idx].paddr = rmem->base;
2785			ab->qmi.target_mem[idx].v.ioaddr =
2786				ioremap(ab->qmi.target_mem[idx].paddr,
2787					ab->qmi.target_mem[i].size);
2788			if (!ab->qmi.target_mem[idx].v.ioaddr) {
2789				ret = -EIO;
2790				goto out;
2791			}
2792			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
2793			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
2794			idx++;
2795			break;
2796		default:
2797			ath12k_warn(ab, "qmi ignore invalid mem req type %u\n",
2798				    ab->qmi.target_mem[i].type);
2799			break;
2800		}
2801	}
2802	ab->qmi.mem_seg_count = idx;
2803
2804	return 0;
2805out:
2806	ath12k_qmi_free_target_mem_chunk(ab);
2807	return ret;
2808}
2809
2810/* clang stack usage explodes if this is inlined */
2811static noinline_for_stack
2812int ath12k_qmi_request_target_cap(struct ath12k_base *ab)
2813{
2814	struct qmi_wlanfw_cap_req_msg_v01 req = {};
2815	struct qmi_wlanfw_cap_resp_msg_v01 resp = {};
2816	struct qmi_txn txn;
2817	unsigned int board_id = ATH12K_BOARD_ID_DEFAULT;
2818	int ret = 0;
2819	int r;
2820	int i;
2821
2822	ret = qmi_txn_init(&ab->qmi.handle, &txn,
2823			   qmi_wlanfw_cap_resp_msg_v01_ei, &resp);
2824	if (ret < 0)
2825		goto out;
2826
2827	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2828			       QMI_WLANFW_CAP_REQ_V01,
2829			       QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,
2830			       qmi_wlanfw_cap_req_msg_v01_ei, &req);
2831	if (ret < 0) {
2832		qmi_txn_cancel(&txn);
2833		ath12k_warn(ab, "qmi failed to send target cap request, err = %d\n",
2834			    ret);
2835		goto out;
2836	}
2837
2838	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2839	if (ret < 0) {
2840		ath12k_warn(ab, "qmi failed target cap request %d\n", ret);
2841		goto out;
2842	}
2843
2844	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2845		ath12k_warn(ab, "qmi targetcap req failed, result: %d, err: %d\n",
2846			    resp.resp.result, resp.resp.error);
2847		ret = -EINVAL;
2848		goto out;
2849	}
2850
2851	if (resp.chip_info_valid) {
2852		ab->qmi.target.chip_id = resp.chip_info.chip_id;
2853		ab->qmi.target.chip_family = resp.chip_info.chip_family;
2854	}
2855
2856	if (resp.board_info_valid)
2857		ab->qmi.target.board_id = resp.board_info.board_id;
2858	else
2859		ab->qmi.target.board_id = board_id;
2860
2861	if (resp.soc_info_valid)
2862		ab->qmi.target.soc_id = resp.soc_info.soc_id;
2863
2864	if (resp.fw_version_info_valid) {
2865		ab->qmi.target.fw_version = resp.fw_version_info.fw_version;
2866		strscpy(ab->qmi.target.fw_build_timestamp,
2867			resp.fw_version_info.fw_build_timestamp,
2868			sizeof(ab->qmi.target.fw_build_timestamp));
2869	}
2870
2871	if (resp.fw_build_id_valid)
2872		strscpy(ab->qmi.target.fw_build_id, resp.fw_build_id,
2873			sizeof(ab->qmi.target.fw_build_id));
2874
2875	if (resp.dev_mem_info_valid) {
2876		for (i = 0; i < ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01; i++) {
2877			ab->qmi.dev_mem[i].start =
2878				resp.dev_mem[i].start;
2879			ab->qmi.dev_mem[i].size =
2880				resp.dev_mem[i].size;
2881			ath12k_dbg(ab, ATH12K_DBG_QMI,
2882				   "devmem [%d] start 0x%llx size %llu\n", i,
2883				   ab->qmi.dev_mem[i].start,
2884				   ab->qmi.dev_mem[i].size);
2885		}
2886	}
2887
2888	if (resp.eeprom_caldata_read_timeout_valid) {
2889		ab->qmi.target.eeprom_caldata = resp.eeprom_caldata_read_timeout;
2890		ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi cal data supported from eeprom\n");
2891	}
2892
2893	ath12k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n",
2894		    ab->qmi.target.chip_id, ab->qmi.target.chip_family,
2895		    ab->qmi.target.board_id, ab->qmi.target.soc_id);
2896
2897	ath12k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s",
2898		    ab->qmi.target.fw_version,
2899		    ab->qmi.target.fw_build_timestamp,
2900		    ab->qmi.target.fw_build_id);
2901
2902	r = ath12k_core_check_smbios(ab);
2903	if (r)
2904		ath12k_dbg(ab, ATH12K_DBG_QMI, "SMBIOS bdf variant name not set.\n");
2905
2906	r = ath12k_acpi_start(ab);
2907	if (r)
2908		/* ACPI is optional so continue in case of an error */
2909		ath12k_dbg(ab, ATH12K_DBG_BOOT, "acpi failed: %d\n", r);
2910
2911	r = ath12k_acpi_check_bdf_variant_name(ab);
2912	if (r)
2913		ath12k_dbg(ab, ATH12K_DBG_BOOT, "ACPI bdf variant name not set.\n");
2914
2915out:
2916	return ret;
2917}
2918
2919static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab,
2920					   const u8 *data, u32 len, u8 type)
2921{
2922	struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
2923	struct qmi_wlanfw_bdf_download_resp_msg_v01 resp = {};
2924	struct qmi_txn txn;
2925	const u8 *temp = data;
2926	int ret = 0;
2927	u32 remaining = len;
2928
2929	req = kzalloc(sizeof(*req), GFP_KERNEL);
2930	if (!req)
2931		return -ENOMEM;
2932
2933	while (remaining) {
2934		req->valid = 1;
2935		req->file_id_valid = 1;
2936		req->file_id = ab->qmi.target.board_id;
2937		req->total_size_valid = 1;
2938		req->total_size = remaining;
2939		req->seg_id_valid = 1;
2940		req->data_valid = 1;
2941		req->bdf_type = type;
2942		req->bdf_type_valid = 1;
2943		req->end_valid = 1;
2944		req->end = 0;
2945
2946		if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) {
2947			req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01;
2948		} else {
2949			req->data_len = remaining;
2950			req->end = 1;
2951		}
2952
2953		if (type == ATH12K_QMI_FILE_TYPE_EEPROM) {
2954			req->data_valid = 0;
2955			req->end = 1;
2956			req->data_len = ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE;
2957		} else {
2958			memcpy(req->data, temp, req->data_len);
2959		}
2960
2961		ret = qmi_txn_init(&ab->qmi.handle, &txn,
2962				   qmi_wlanfw_bdf_download_resp_msg_v01_ei,
2963				   &resp);
2964		if (ret < 0)
2965			goto out;
2966
2967		ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi bdf download req fixed addr type %d\n",
2968			   type);
2969
2970		ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2971				       QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
2972				       QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
2973				       qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
2974		if (ret < 0) {
2975			qmi_txn_cancel(&txn);
2976			goto out;
2977		}
2978
2979		ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2980		if (ret < 0)
2981			goto out;
2982
2983		if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2984			ath12k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n",
2985				    resp.resp.result, resp.resp.error);
2986			ret = -EINVAL;
2987			goto out;
2988		}
2989
2990		if (type == ATH12K_QMI_FILE_TYPE_EEPROM) {
2991			remaining = 0;
2992		} else {
2993			remaining -= req->data_len;
2994			temp += req->data_len;
2995			req->seg_id++;
2996			ath12k_dbg(ab, ATH12K_DBG_QMI,
2997				   "qmi bdf download request remaining %i\n",
2998				   remaining);
2999		}
3000	}
3001
3002out:
3003	kfree(req);
3004	return ret;
3005}
3006
3007/* clang stack usage explodes if this is inlined */
3008static noinline_for_stack
3009int ath12k_qmi_load_bdf_qmi(struct ath12k_base *ab,
3010			    enum ath12k_qmi_bdf_type type)
3011{
3012	struct device *dev = ab->dev;
3013	char filename[ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE];
3014	const struct firmware *fw_entry;
3015	struct ath12k_board_data bd;
3016	u32 fw_size, file_type;
3017	int ret = 0;
3018	const u8 *tmp;
3019
3020	memset(&bd, 0, sizeof(bd));
3021
3022	switch (type) {
3023	case ATH12K_QMI_BDF_TYPE_ELF:
3024		ret = ath12k_core_fetch_bdf(ab, &bd);
3025		if (ret) {
3026			ath12k_warn(ab, "qmi failed to load bdf:\n");
3027			goto out;
3028		}
3029
3030		if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0)
3031			type = ATH12K_QMI_BDF_TYPE_ELF;
3032		else
3033			type = ATH12K_QMI_BDF_TYPE_BIN;
3034
3035		break;
3036	case ATH12K_QMI_BDF_TYPE_REGDB:
3037		ret = ath12k_core_fetch_regdb(ab, &bd);
3038		if (ret) {
3039			ath12k_warn(ab, "qmi failed to load regdb bin:\n");
3040			goto out;
3041		}
3042		break;
3043	case ATH12K_QMI_BDF_TYPE_CALIBRATION:
3044
3045		if (ab->qmi.target.eeprom_caldata) {
3046			file_type = ATH12K_QMI_FILE_TYPE_EEPROM;
3047			tmp = filename;
3048			fw_size = ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE;
3049		} else {
3050			file_type = ATH12K_QMI_FILE_TYPE_CALDATA;
3051
3052			/* cal-<bus>-<id>.bin */
3053			snprintf(filename, sizeof(filename), "cal-%s-%s.bin",
3054				 ath12k_bus_str(ab->hif.bus), dev_name(dev));
3055			fw_entry = ath12k_core_firmware_request(ab, filename);
3056			if (!IS_ERR(fw_entry))
3057				goto success;
3058
3059			fw_entry = ath12k_core_firmware_request(ab,
3060								ATH12K_DEFAULT_CAL_FILE);
3061			if (IS_ERR(fw_entry)) {
3062				ret = PTR_ERR(fw_entry);
3063				ath12k_warn(ab,
3064					    "qmi failed to load CAL data file:%s\n",
3065					    filename);
3066				goto out;
3067			}
3068
3069success:
3070			fw_size = min_t(u32, ab->hw_params->fw.board_size,
3071					fw_entry->size);
3072			tmp = fw_entry->data;
3073		}
3074		ret = ath12k_qmi_load_file_target_mem(ab, tmp, fw_size, file_type);
3075		if (ret < 0) {
3076			ath12k_warn(ab, "qmi failed to load caldata\n");
3077			goto out_qmi_cal;
3078		}
3079
3080		ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi caldata downloaded: type: %u\n",
3081			   file_type);
3082
3083out_qmi_cal:
3084		if (!ab->qmi.target.eeprom_caldata)
3085			release_firmware(fw_entry);
3086		return ret;
3087	default:
3088		ath12k_warn(ab, "unknown file type for load %d", type);
3089		goto out;
3090	}
3091
3092	ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi bdf_type %d\n", type);
3093
3094	fw_size = min_t(u32, ab->hw_params->fw.board_size, bd.len);
3095
3096	ret = ath12k_qmi_load_file_target_mem(ab, bd.data, fw_size, type);
3097	if (ret < 0)
3098		ath12k_warn(ab, "qmi failed to load bdf file\n");
3099
3100out:
3101	ath12k_core_free_bdf(ab, &bd);
3102	ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi BDF download sequence completed\n");
3103
3104	return ret;
3105}
3106
3107static void ath12k_qmi_m3_free(struct ath12k_base *ab)
3108{
3109	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
3110
3111	if (ab->hw_params->fw.m3_loader == ath12k_m3_fw_loader_remoteproc)
3112		return;
3113
3114	if (!m3_mem->vaddr)
3115		return;
3116
3117	dma_free_coherent(ab->dev, m3_mem->total_size,
3118			  m3_mem->vaddr, m3_mem->paddr);
3119	m3_mem->vaddr = NULL;
3120	m3_mem->total_size = 0;
3121	m3_mem->size = 0;
3122}
3123
3124static int ath12k_qmi_m3_load(struct ath12k_base *ab)
3125{
3126	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
3127	const struct firmware *fw = NULL;
3128	const void *m3_data;
3129	char path[100];
3130	size_t m3_len;
3131	int ret;
3132
3133	if (ab->fw.m3_data && ab->fw.m3_len > 0) {
3134		/* firmware-N.bin had a m3 firmware file so use that */
3135		m3_data = ab->fw.m3_data;
3136		m3_len = ab->fw.m3_len;
3137	} else {
3138		/* No m3 file in firmware-N.bin so try to request old
3139		 * separate m3.bin.
3140		 */
3141		fw = ath12k_core_firmware_request(ab, ATH12K_M3_FILE);
3142		if (IS_ERR(fw)) {
3143			ret = PTR_ERR(fw);
3144			ath12k_core_create_firmware_path(ab, ATH12K_M3_FILE,
3145							 path, sizeof(path));
3146			ath12k_err(ab, "failed to load %s: %d\n", path, ret);
3147			return ret;
3148		}
3149
3150		m3_data = fw->data;
3151		m3_len = fw->size;
3152	}
3153
3154	/* In recovery/resume cases, M3 buffer is not freed, try to reuse that */
3155	if (m3_mem->vaddr) {
3156		if (m3_mem->total_size >= m3_len)
3157			goto skip_m3_alloc;
3158
3159		/* Old buffer is too small, free and reallocate */
3160		ath12k_qmi_m3_free(ab);
3161	}
3162
3163	m3_mem->vaddr = dma_alloc_coherent(ab->dev,
3164					   m3_len, &m3_mem->paddr,
3165					   GFP_KERNEL);
3166	if (!m3_mem->vaddr) {
3167		ath12k_err(ab, "failed to allocate memory for M3 with size %zu\n",
3168			   m3_len);
3169		ret = -ENOMEM;
3170		goto out;
3171	}
3172
3173	m3_mem->total_size = m3_len;
3174
3175skip_m3_alloc:
3176	memcpy(m3_mem->vaddr, m3_data, m3_len);
3177	m3_mem->size = m3_len;
3178
3179	ret = 0;
3180
3181out:
3182	release_firmware(fw);
3183
3184	return ret;
3185}
3186
3187/* clang stack usage explodes if this is inlined */
3188static noinline_for_stack
3189int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab)
3190{
3191	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
3192	struct qmi_wlanfw_m3_info_req_msg_v01 req = {};
3193	struct qmi_wlanfw_m3_info_resp_msg_v01 resp = {};
3194	struct qmi_txn txn;
3195	int ret = 0;
3196
3197	if (ab->hw_params->fw.m3_loader == ath12k_m3_fw_loader_driver) {
3198		ret = ath12k_qmi_m3_load(ab);
3199		if (ret) {
3200			ath12k_err(ab, "failed to load m3 firmware: %d", ret);
3201			return ret;
3202		}
3203		req.addr = m3_mem->paddr;
3204		req.size = m3_mem->size;
3205	}
3206
3207	ret = qmi_txn_init(&ab->qmi.handle, &txn,
3208			   qmi_wlanfw_m3_info_resp_msg_v01_ei, &resp);
3209	if (ret < 0)
3210		goto out;
3211
3212	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3213			       QMI_WLANFW_M3_INFO_REQ_V01,
3214			       QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,
3215			       qmi_wlanfw_m3_info_req_msg_v01_ei, &req);
3216	if (ret < 0) {
3217		qmi_txn_cancel(&txn);
3218		ath12k_warn(ab, "qmi failed to send M3 information request, err = %d\n",
3219			    ret);
3220		goto out;
3221	}
3222
3223	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3224	if (ret < 0) {
3225		ath12k_warn(ab, "qmi failed M3 information request %d\n", ret);
3226		goto out;
3227	}
3228
3229	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3230		ath12k_warn(ab, "qmi M3 info request failed, result: %d, err: %d\n",
3231			    resp.resp.result, resp.resp.error);
3232		ret = -EINVAL;
3233		goto out;
3234	}
3235out:
3236	return ret;
3237}
3238
3239static int ath12k_qmi_wlanfw_mode_send(struct ath12k_base *ab,
3240				       u32 mode)
3241{
3242	struct qmi_wlanfw_wlan_mode_req_msg_v01 req = {};
3243	struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp = {};
3244	struct qmi_txn txn;
3245	int ret = 0;
3246
3247	req.mode = mode;
3248	req.hw_debug_valid = 1;
3249	req.hw_debug = 0;
3250
3251	ret = qmi_txn_init(&ab->qmi.handle, &txn,
3252			   qmi_wlanfw_wlan_mode_resp_msg_v01_ei, &resp);
3253	if (ret < 0)
3254		goto out;
3255
3256	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3257			       QMI_WLANFW_WLAN_MODE_REQ_V01,
3258			       QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,
3259			       qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);
3260	if (ret < 0) {
3261		qmi_txn_cancel(&txn);
3262		ath12k_warn(ab, "qmi failed to send mode request, mode: %d, err = %d\n",
3263			    mode, ret);
3264		goto out;
3265	}
3266
3267	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3268	if (ret < 0) {
3269		if (mode == ATH12K_FIRMWARE_MODE_OFF && ret == -ENETRESET) {
3270			ath12k_warn(ab, "WLFW service is dis-connected\n");
3271			return 0;
3272		}
3273		ath12k_warn(ab, "qmi failed set mode request, mode: %d, err = %d\n",
3274			    mode, ret);
3275		goto out;
3276	}
3277
3278	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3279		ath12k_warn(ab, "Mode request failed, mode: %d, result: %d err: %d\n",
3280			    mode, resp.resp.result, resp.resp.error);
3281		ret = -EINVAL;
3282		goto out;
3283	}
3284
3285out:
3286	return ret;
3287}
3288
3289static int ath12k_qmi_wlanfw_wlan_cfg_send(struct ath12k_base *ab)
3290{
3291	struct qmi_wlanfw_wlan_cfg_req_msg_v01 *req;
3292	struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp = {};
3293	struct ce_pipe_config *ce_cfg;
3294	struct service_to_pipe *svc_cfg;
3295	struct qmi_txn txn;
3296	int ret = 0, pipe_num;
3297
3298	ce_cfg	= (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce;
3299	svc_cfg	= (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map;
3300
3301	req = kzalloc(sizeof(*req), GFP_KERNEL);
3302	if (!req)
3303		return -ENOMEM;
3304
3305	req->host_version_valid = 1;
3306	strscpy(req->host_version, ATH12K_HOST_VERSION_STRING,
3307		sizeof(req->host_version));
3308
3309	req->tgt_cfg_valid = 1;
3310	/* This is number of CE configs */
3311	req->tgt_cfg_len = ab->qmi.ce_cfg.tgt_ce_len;
3312	for (pipe_num = 0; pipe_num < req->tgt_cfg_len ; pipe_num++) {
3313		req->tgt_cfg[pipe_num].pipe_num =
3314			__le32_to_cpu(ce_cfg[pipe_num].pipenum);
3315		req->tgt_cfg[pipe_num].pipe_dir =
3316			__le32_to_cpu(ce_cfg[pipe_num].pipedir);
3317		req->tgt_cfg[pipe_num].nentries =
3318			__le32_to_cpu(ce_cfg[pipe_num].nentries);
3319		req->tgt_cfg[pipe_num].nbytes_max =
3320			__le32_to_cpu(ce_cfg[pipe_num].nbytes_max);
3321		req->tgt_cfg[pipe_num].flags =
3322			__le32_to_cpu(ce_cfg[pipe_num].flags);
3323	}
3324
3325	req->svc_cfg_valid = 1;
3326	/* This is number of Service/CE configs */
3327	req->svc_cfg_len = ab->qmi.ce_cfg.svc_to_ce_map_len;
3328	for (pipe_num = 0; pipe_num < req->svc_cfg_len; pipe_num++) {
3329		req->svc_cfg[pipe_num].service_id =
3330			__le32_to_cpu(svc_cfg[pipe_num].service_id);
3331		req->svc_cfg[pipe_num].pipe_dir =
3332			__le32_to_cpu(svc_cfg[pipe_num].pipedir);
3333		req->svc_cfg[pipe_num].pipe_num =
3334			__le32_to_cpu(svc_cfg[pipe_num].pipenum);
3335	}
3336
3337	/* set shadow v3 configuration */
3338	if (ab->hw_params->supports_shadow_regs) {
3339		req->shadow_reg_v3_valid = 1;
3340		req->shadow_reg_v3_len = min_t(u32,
3341					       ab->qmi.ce_cfg.shadow_reg_v3_len,
3342					       QMI_WLANFW_MAX_NUM_SHADOW_REG_V3_V01);
3343		memcpy(&req->shadow_reg_v3, ab->qmi.ce_cfg.shadow_reg_v3,
3344		       sizeof(u32) * req->shadow_reg_v3_len);
3345	} else {
3346		req->shadow_reg_v3_valid = 0;
3347	}
3348
3349	ret = qmi_txn_init(&ab->qmi.handle, &txn,
3350			   qmi_wlanfw_wlan_cfg_resp_msg_v01_ei, &resp);
3351	if (ret < 0)
3352		goto out;
3353
3354	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3355			       QMI_WLANFW_WLAN_CFG_REQ_V01,
3356			       QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,
3357			       qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);
3358	if (ret < 0) {
3359		qmi_txn_cancel(&txn);
3360		ath12k_warn(ab, "qmi failed to send wlan config request, err = %d\n",
3361			    ret);
3362		goto out;
3363	}
3364
3365	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3366	if (ret < 0) {
3367		ath12k_warn(ab, "qmi failed wlan config request, err = %d\n", ret);
3368		goto out;
3369	}
3370
3371	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3372		ath12k_warn(ab, "qmi wlan config request failed, result: %d, err: %d\n",
3373			    resp.resp.result, resp.resp.error);
3374		ret = -EINVAL;
3375		goto out;
3376	}
3377
3378out:
3379	kfree(req);
3380	return ret;
3381}
3382
3383static int ath12k_qmi_wlanfw_wlan_ini_send(struct ath12k_base *ab)
3384{
3385	struct qmi_wlanfw_wlan_ini_resp_msg_v01 resp = {};
3386	struct qmi_wlanfw_wlan_ini_req_msg_v01 req = {};
3387	struct qmi_txn txn;
3388	int ret;
3389
3390	req.enable_fwlog_valid = true;
3391	req.enable_fwlog = 1;
3392
3393	ret = qmi_txn_init(&ab->qmi.handle, &txn,
3394			   qmi_wlanfw_wlan_ini_resp_msg_v01_ei, &resp);
3395	if (ret < 0)
3396		goto out;
3397
3398	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3399			       ATH12K_QMI_WLANFW_WLAN_INI_REQ_V01,
3400			       QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN,
3401			       qmi_wlanfw_wlan_ini_req_msg_v01_ei, &req);
3402	if (ret < 0) {
3403		qmi_txn_cancel(&txn);
3404		ath12k_warn(ab, "failed to send QMI wlan ini request: %d\n",
3405			    ret);
3406		goto out;
3407	}
3408
3409	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3410	if (ret < 0) {
3411		ath12k_warn(ab, "failed to receive QMI wlan ini request: %d\n", ret);
3412		goto out;
3413	}
3414
3415	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3416		ath12k_warn(ab, "QMI wlan ini response failure: %d %d\n",
3417			    resp.resp.result, resp.resp.error);
3418		ret = -EINVAL;
3419		goto out;
3420	}
3421
3422out:
3423	return ret;
3424}
3425
3426void ath12k_qmi_firmware_stop(struct ath12k_base *ab)
3427{
3428	int ret;
3429
3430	clear_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE, &ab->dev_flags);
3431
3432	ret = ath12k_qmi_wlanfw_mode_send(ab, ATH12K_FIRMWARE_MODE_OFF);
3433	if (ret < 0) {
3434		ath12k_warn(ab, "qmi failed to send wlan mode off\n");
3435		return;
3436	}
3437}
3438
3439int ath12k_qmi_firmware_start(struct ath12k_base *ab,
3440			      u32 mode)
3441{
3442	int ret;
3443
3444	ret = ath12k_qmi_wlanfw_wlan_ini_send(ab);
3445	if (ret < 0) {
3446		ath12k_warn(ab, "qmi failed to send wlan fw ini: %d\n", ret);
3447		return ret;
3448	}
3449
3450	ret = ath12k_qmi_wlanfw_wlan_cfg_send(ab);
3451	if (ret < 0) {
3452		ath12k_warn(ab, "qmi failed to send wlan cfg:%d\n", ret);
3453		return ret;
3454	}
3455
3456	ret = ath12k_qmi_wlanfw_mode_send(ab, mode);
3457	if (ret < 0) {
3458		ath12k_warn(ab, "qmi failed to send wlan fw mode:%d\n", ret);
3459		return ret;
3460	}
3461
3462	return 0;
3463}
3464
3465static int
3466ath12k_qmi_driver_event_post(struct ath12k_qmi *qmi,
3467			     enum ath12k_qmi_event_type type,
3468			     void *data)
3469{
3470	struct ath12k_qmi_driver_event *event;
3471
3472	event = kzalloc(sizeof(*event), GFP_ATOMIC);
3473	if (!event)
3474		return -ENOMEM;
3475
3476	event->type = type;
3477	event->data = data;
3478
3479	spin_lock(&qmi->event_lock);
3480	list_add_tail(&event->list, &qmi->event_list);
3481	spin_unlock(&qmi->event_lock);
3482
3483	queue_work(qmi->event_wq, &qmi->event_work);
3484
3485	return 0;
3486}
3487
3488void ath12k_qmi_trigger_host_cap(struct ath12k_base *ab)
3489{
3490	struct ath12k_qmi *qmi = &ab->qmi;
3491
3492	spin_lock(&qmi->event_lock);
3493
3494	if (ath12k_qmi_get_event_block(qmi))
3495		ath12k_qmi_set_event_block(qmi, false);
3496
3497	spin_unlock(&qmi->event_lock);
3498
3499	ath12k_dbg(ab, ATH12K_DBG_QMI, "trigger host cap for device id %d\n",
3500		   ab->device_id);
3501
3502	ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_HOST_CAP, NULL);
3503}
3504
3505static bool ath12k_qmi_hw_group_host_cap_ready(struct ath12k_hw_group *ag)
3506{
3507	struct ath12k_base *ab;
3508	int i;
3509
3510	for (i = 0; i < ag->num_devices; i++) {
3511		ab = ag->ab[i];
3512
3513		if (!(ab && ab->qmi.num_radios != U8_MAX))
3514			return false;
3515	}
3516
3517	return true;
3518}
3519
3520static struct ath12k_base *ath12k_qmi_hw_group_find_blocked(struct ath12k_hw_group *ag)
3521{
3522	struct ath12k_base *ab;
3523	int i;
3524
3525	lockdep_assert_held(&ag->mutex);
3526
3527	for (i = 0; i < ag->num_devices; i++) {
3528		ab = ag->ab[i];
3529		if (!ab)
3530			continue;
3531
3532		spin_lock(&ab->qmi.event_lock);
3533
3534		if (ath12k_qmi_get_event_block(&ab->qmi)) {
3535			spin_unlock(&ab->qmi.event_lock);
3536			return ab;
3537		}
3538
3539		spin_unlock(&ab->qmi.event_lock);
3540	}
3541
3542	return NULL;
3543}
3544
3545/* clang stack usage explodes if this is inlined */
3546static noinline_for_stack
3547int ath12k_qmi_event_server_arrive(struct ath12k_qmi *qmi)
3548{
3549	struct ath12k_base *ab = qmi->ab, *block_ab;
3550	struct ath12k_hw_group *ag = ab->ag;
3551	int ret;
3552
3553	ath12k_qmi_phy_cap_send(ab);
3554
3555	ret = ath12k_qmi_fw_ind_register_send(ab);
3556	if (ret < 0) {
3557		ath12k_warn(ab, "qmi failed to send FW indication QMI:%d\n", ret);
3558		return ret;
3559	}
3560
3561	spin_lock(&qmi->event_lock);
3562
3563	ath12k_qmi_set_event_block(qmi, true);
3564
3565	spin_unlock(&qmi->event_lock);
3566
3567	mutex_lock(&ag->mutex);
3568
3569	if (ath12k_qmi_hw_group_host_cap_ready(ag)) {
3570		ath12k_core_hw_group_set_mlo_capable(ag);
3571
3572		block_ab = ath12k_qmi_hw_group_find_blocked(ag);
3573		if (block_ab)
3574			ath12k_qmi_trigger_host_cap(block_ab);
3575	}
3576
3577	mutex_unlock(&ag->mutex);
3578
3579	return ret;
3580}
3581
3582/* clang stack usage explodes if this is inlined */
3583static noinline_for_stack
3584int ath12k_qmi_event_mem_request(struct ath12k_qmi *qmi)
3585{
3586	struct ath12k_base *ab = qmi->ab;
3587	int ret;
3588
3589	ret = ath12k_qmi_respond_fw_mem_request(ab);
3590	if (ret < 0) {
3591		ath12k_warn(ab, "qmi failed to respond fw mem req:%d\n", ret);
3592		return ret;
3593	}
3594
3595	return ret;
3596}
3597
3598/* clang stack usage explodes if this is inlined */
3599static noinline_for_stack
3600int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi)
3601{
3602	struct ath12k_base *ab = qmi->ab;
3603	int ret;
3604
3605	ret = ath12k_qmi_request_target_cap(ab);
3606	if (ret < 0) {
3607		ath12k_warn(ab, "qmi failed to req target capabilities:%d\n", ret);
3608		return ret;
3609	}
3610
3611	ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_REGDB);
3612	if (ret < 0) {
3613		ath12k_warn(ab, "qmi failed to load regdb file:%d\n", ret);
3614		return ret;
3615	}
3616
3617	ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_ELF);
3618	if (ret < 0) {
3619		ath12k_warn(ab, "qmi failed to load board data file:%d\n", ret);
3620		return ret;
3621	}
3622
3623	if (ab->hw_params->download_calib) {
3624		ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_CALIBRATION);
3625		if (ret < 0)
3626			ath12k_warn(ab, "qmi failed to load calibrated data :%d\n", ret);
3627	}
3628
3629	ret = ath12k_qmi_wlanfw_m3_info_send(ab);
3630	if (ret < 0) {
3631		ath12k_warn(ab, "qmi failed to send m3 info req:%d\n", ret);
3632		return ret;
3633	}
3634
3635	return ret;
3636}
3637
3638static void ath12k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,
3639					  struct sockaddr_qrtr *sq,
3640					  struct qmi_txn *txn,
3641					  const void *data)
3642{
3643	struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3644	struct ath12k_base *ab = qmi->ab;
3645	const struct qmi_wlanfw_request_mem_ind_msg_v01 *msg = data;
3646	int i, ret;
3647
3648	ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware request memory request\n");
3649
3650	if (msg->mem_seg_len == 0 ||
3651	    msg->mem_seg_len > ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01)
3652		ath12k_warn(ab, "Invalid memory segment length: %u\n",
3653			    msg->mem_seg_len);
3654
3655	ab->qmi.mem_seg_count = msg->mem_seg_len;
3656
3657	for (i = 0; i < qmi->mem_seg_count ; i++) {
3658		ab->qmi.target_mem[i].type = msg->mem_seg[i].type;
3659		ab->qmi.target_mem[i].size = msg->mem_seg[i].size;
3660		ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi mem seg type %d size %d\n",
3661			   msg->mem_seg[i].type, msg->mem_seg[i].size);
3662	}
3663
3664	if (test_bit(ATH12K_FLAG_FIXED_MEM_REGION, &ab->dev_flags)) {
3665		ret = ath12k_qmi_assign_target_mem_chunk(ab);
3666		if (ret) {
3667			ath12k_warn(ab, "failed to assign qmi target memory: %d\n",
3668				    ret);
3669			return;
3670		}
3671	} else {
3672		ret = ath12k_qmi_alloc_target_mem_chunk(ab);
3673		if (ret) {
3674			ath12k_warn(ab, "qmi failed to alloc target memory: %d\n",
3675				    ret);
3676			return;
3677		}
3678	}
3679
3680	ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_REQUEST_MEM, NULL);
3681}
3682
3683static void ath12k_qmi_msg_mem_ready_cb(struct qmi_handle *qmi_hdl,
3684					struct sockaddr_qrtr *sq,
3685					struct qmi_txn *txn,
3686					const void *decoded)
3687{
3688	struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3689	struct ath12k_base *ab = qmi->ab;
3690
3691	ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware memory ready indication\n");
3692	ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_FW_MEM_READY, NULL);
3693}
3694
3695static void ath12k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl,
3696				       struct sockaddr_qrtr *sq,
3697				       struct qmi_txn *txn,
3698				       const void *decoded)
3699{
3700	struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3701	struct ath12k_base *ab = qmi->ab;
3702
3703	ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware ready\n");
3704	ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_FW_READY, NULL);
3705}
3706
3707static const struct qmi_msg_handler ath12k_qmi_msg_handlers[] = {
3708	{
3709		.type = QMI_INDICATION,
3710		.msg_id = QMI_WLFW_REQUEST_MEM_IND_V01,
3711		.ei = qmi_wlanfw_request_mem_ind_msg_v01_ei,
3712		.decoded_size = sizeof(struct qmi_wlanfw_request_mem_ind_msg_v01),
3713		.fn = ath12k_qmi_msg_mem_request_cb,
3714	},
3715	{
3716		.type = QMI_INDICATION,
3717		.msg_id = QMI_WLFW_FW_MEM_READY_IND_V01,
3718		.ei = qmi_wlanfw_mem_ready_ind_msg_v01_ei,
3719		.decoded_size = sizeof(struct qmi_wlanfw_fw_mem_ready_ind_msg_v01),
3720		.fn = ath12k_qmi_msg_mem_ready_cb,
3721	},
3722	{
3723		.type = QMI_INDICATION,
3724		.msg_id = QMI_WLFW_FW_READY_IND_V01,
3725		.ei = qmi_wlanfw_fw_ready_ind_msg_v01_ei,
3726		.decoded_size = sizeof(struct qmi_wlanfw_fw_ready_ind_msg_v01),
3727		.fn = ath12k_qmi_msg_fw_ready_cb,
3728	},
3729
3730	/* end of list */
3731	{},
3732};
3733
3734static int ath12k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
3735				     struct qmi_service *service)
3736{
3737	struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3738	struct ath12k_base *ab = qmi->ab;
3739	struct sockaddr_qrtr *sq = &qmi->sq;
3740	int ret;
3741
3742	sq->sq_family = AF_QIPCRTR;
3743	sq->sq_node = service->node;
3744	sq->sq_port = service->port;
3745
3746	ret = kernel_connect(qmi_hdl->sock, (struct sockaddr_unsized *)sq,
3747			     sizeof(*sq), 0);
3748	if (ret) {
3749		ath12k_warn(ab, "qmi failed to connect to remote service %d\n", ret);
3750		return ret;
3751	}
3752
3753	ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi wifi fw qmi service connected\n");
3754	ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_SERVER_ARRIVE, NULL);
3755
3756	return ret;
3757}
3758
3759static void ath12k_qmi_ops_del_server(struct qmi_handle *qmi_hdl,
3760				      struct qmi_service *service)
3761{
3762	struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3763	struct ath12k_base *ab = qmi->ab;
3764
3765	ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi wifi fw del server\n");
3766	ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_SERVER_EXIT, NULL);
3767}
3768
3769static const struct qmi_ops ath12k_qmi_ops = {
3770	.new_server = ath12k_qmi_ops_new_server,
3771	.del_server = ath12k_qmi_ops_del_server,
3772};
3773
3774static int ath12k_qmi_event_host_cap(struct ath12k_qmi *qmi)
3775{
3776	struct ath12k_base *ab = qmi->ab;
3777	int ret;
3778
3779	ret = ath12k_qmi_host_cap_send(ab);
3780	if (ret < 0) {
3781		ath12k_warn(ab, "failed to send qmi host cap for device id %d: %d\n",
3782			    ab->device_id, ret);
3783		return ret;
3784	}
3785
3786	return ret;
3787}
3788
3789static void ath12k_qmi_driver_event_work(struct work_struct *work)
3790{
3791	struct ath12k_qmi *qmi = container_of(work, struct ath12k_qmi,
3792					      event_work);
3793	struct ath12k_qmi_driver_event *event;
3794	struct ath12k_base *ab = qmi->ab;
3795	int ret;
3796
3797	spin_lock(&qmi->event_lock);
3798	while (!list_empty(&qmi->event_list)) {
3799		event = list_first_entry(&qmi->event_list,
3800					 struct ath12k_qmi_driver_event, list);
3801		list_del(&event->list);
3802		spin_unlock(&qmi->event_lock);
3803
3804		if (test_bit(ATH12K_FLAG_UNREGISTERING, &ab->dev_flags))
3805			goto skip;
3806
3807		switch (event->type) {
3808		case ATH12K_QMI_EVENT_SERVER_ARRIVE:
3809			ret = ath12k_qmi_event_server_arrive(qmi);
3810			if (ret < 0)
3811				set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3812			break;
3813		case ATH12K_QMI_EVENT_SERVER_EXIT:
3814			set_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
3815			break;
3816		case ATH12K_QMI_EVENT_REQUEST_MEM:
3817			ret = ath12k_qmi_event_mem_request(qmi);
3818			if (ret < 0)
3819				set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3820			break;
3821		case ATH12K_QMI_EVENT_FW_MEM_READY:
3822			ret = ath12k_qmi_event_load_bdf(qmi);
3823			if (ret < 0)
3824				set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3825			break;
3826		case ATH12K_QMI_EVENT_FW_READY:
3827			clear_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3828			if (test_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE, &ab->dev_flags)) {
3829				if (ab->is_reset)
3830					ath12k_hal_dump_srng_stats(ab);
3831
3832				set_bit(ATH12K_FLAG_RECOVERY, &ab->dev_flags);
3833				queue_work(ab->workqueue, &ab->restart_work);
3834				break;
3835			}
3836
3837			clear_bit(ATH12K_FLAG_CRASH_FLUSH,
3838				  &ab->dev_flags);
3839			ret = ath12k_core_qmi_firmware_ready(ab);
3840			if (!ret)
3841				set_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE,
3842					&ab->dev_flags);
3843
3844			break;
3845		case ATH12K_QMI_EVENT_HOST_CAP:
3846			ret = ath12k_qmi_event_host_cap(qmi);
3847			if (ret < 0)
3848				set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3849			break;
3850		default:
3851			ath12k_warn(ab, "invalid event type: %d", event->type);
3852			break;
3853		}
3854
3855skip:
3856		kfree(event);
3857		spin_lock(&qmi->event_lock);
3858	}
3859	spin_unlock(&qmi->event_lock);
3860}
3861
3862int ath12k_qmi_init_service(struct ath12k_base *ab)
3863{
3864	int ret;
3865
3866	memset(&ab->qmi.target, 0, sizeof(struct target_info));
3867	memset(&ab->qmi.target_mem, 0, sizeof(struct target_mem_chunk));
3868	ab->qmi.ab = ab;
3869
3870	ab->qmi.target_mem_mode = ab->target_mem_mode;
3871	ret = qmi_handle_init(&ab->qmi.handle, ATH12K_QMI_RESP_LEN_MAX,
3872			      &ath12k_qmi_ops, ath12k_qmi_msg_handlers);
3873	if (ret < 0) {
3874		ath12k_warn(ab, "failed to initialize qmi handle\n");
3875		return ret;
3876	}
3877
3878	ab->qmi.event_wq = alloc_ordered_workqueue("ath12k_qmi_driver_event", 0);
3879	if (!ab->qmi.event_wq) {
3880		ath12k_err(ab, "failed to allocate workqueue\n");
3881		return -EFAULT;
3882	}
3883
3884	INIT_LIST_HEAD(&ab->qmi.event_list);
3885	spin_lock_init(&ab->qmi.event_lock);
3886	INIT_WORK(&ab->qmi.event_work, ath12k_qmi_driver_event_work);
3887
3888	ret = qmi_add_lookup(&ab->qmi.handle, ATH12K_QMI_WLFW_SERVICE_ID_V01,
3889			     ATH12K_QMI_WLFW_SERVICE_VERS_V01,
3890			     ab->qmi.service_ins_id);
3891	if (ret < 0) {
3892		ath12k_warn(ab, "failed to add qmi lookup\n");
3893		destroy_workqueue(ab->qmi.event_wq);
3894		return ret;
3895	}
3896
3897	return ret;
3898}
3899
3900void ath12k_qmi_deinit_service(struct ath12k_base *ab)
3901{
3902	if (!ab->qmi.ab)
3903		return;
3904
3905	qmi_handle_release(&ab->qmi.handle);
3906	cancel_work_sync(&ab->qmi.event_work);
3907	destroy_workqueue(ab->qmi.event_wq);
3908	ath12k_qmi_m3_free(ab);
3909	ath12k_qmi_free_target_mem_chunk(ab);
3910	ab->qmi.ab = NULL;
3911}
3912
3913void ath12k_qmi_free_resource(struct ath12k_base *ab)
3914{
3915	ath12k_qmi_free_target_mem_chunk(ab);
3916	ath12k_qmi_m3_free(ab);
3917}
~/ Read-only file preview.