1*b1906ceaSLachlan Hodges /* SPDX-License-Identifier: GPL-2.0-only */ 2*b1906ceaSLachlan Hodges /* 3*b1906ceaSLachlan Hodges * Copyright (c) 2017-2026 Morse Micro 4*b1906ceaSLachlan Hodges */ 5*b1906ceaSLachlan Hodges 6*b1906ceaSLachlan Hodges #ifndef _MM81X_FW_H_ 7*b1906ceaSLachlan Hodges #define _MM81X_FW_H_ 8*b1906ceaSLachlan Hodges 9*b1906ceaSLachlan Hodges #include <linux/firmware.h> 10*b1906ceaSLachlan Hodges #include <linux/completion.h> 11*b1906ceaSLachlan Hodges #include <linux/elf.h> 12*b1906ceaSLachlan Hodges #include "command_defs.h" 13*b1906ceaSLachlan Hodges #include "yaps_hw.h" 14*b1906ceaSLachlan Hodges 15*b1906ceaSLachlan Hodges #define BCF_DATABASE_SIZE (1024) 16*b1906ceaSLachlan Hodges #define MM81X_FW_DIR "morsemicro/mm81x" 17*b1906ceaSLachlan Hodges #define MM81X_FW_EXT ".bin" 18*b1906ceaSLachlan Hodges 19*b1906ceaSLachlan Hodges #define MM81X_FW_VER_MAX HOST_CMD_SEMVER_MAJOR 20*b1906ceaSLachlan Hodges #define MM81X_FW_VER_MIN 56 21*b1906ceaSLachlan Hodges 22*b1906ceaSLachlan Hodges /* FW_CAPABILITIES_FLAGS_WIDTH = ceil(MM81X_CAPS_MAX_HW_LEN / 32) */ 23*b1906ceaSLachlan Hodges #define FW_CAPABILITIES_FLAGS_WIDTH (4) 24*b1906ceaSLachlan Hodges 25*b1906ceaSLachlan Hodges struct mm81x_elf32_ehdr { 26*b1906ceaSLachlan Hodges unsigned char e_ident[EI_NIDENT]; 27*b1906ceaSLachlan Hodges __le16 e_type; 28*b1906ceaSLachlan Hodges __le16 e_machine; 29*b1906ceaSLachlan Hodges __le32 e_version; 30*b1906ceaSLachlan Hodges __le32 e_entry; 31*b1906ceaSLachlan Hodges __le32 e_phoff; 32*b1906ceaSLachlan Hodges __le32 e_shoff; 33*b1906ceaSLachlan Hodges __le32 e_flags; 34*b1906ceaSLachlan Hodges __le16 e_ehsize; 35*b1906ceaSLachlan Hodges __le16 e_phentsize; 36*b1906ceaSLachlan Hodges __le16 e_phnum; 37*b1906ceaSLachlan Hodges __le16 e_shentsize; 38*b1906ceaSLachlan Hodges __le16 e_shnum; 39*b1906ceaSLachlan Hodges __le16 e_shstrndx; 40*b1906ceaSLachlan Hodges } __packed; 41*b1906ceaSLachlan Hodges 42*b1906ceaSLachlan Hodges struct mm81x_elf32_shdr { 43*b1906ceaSLachlan Hodges __le32 sh_name; 44*b1906ceaSLachlan Hodges __le32 sh_type; 45*b1906ceaSLachlan Hodges __le32 sh_flags; 46*b1906ceaSLachlan Hodges __le32 sh_addr; 47*b1906ceaSLachlan Hodges __le32 sh_offset; 48*b1906ceaSLachlan Hodges __le32 sh_size; 49*b1906ceaSLachlan Hodges __le32 sh_link; 50*b1906ceaSLachlan Hodges __le32 sh_info; 51*b1906ceaSLachlan Hodges __le32 sh_addralign; 52*b1906ceaSLachlan Hodges __le32 sh_entsize; 53*b1906ceaSLachlan Hodges } __packed; 54*b1906ceaSLachlan Hodges 55*b1906ceaSLachlan Hodges struct mm81x_elf32_phdr { 56*b1906ceaSLachlan Hodges __le32 p_type; 57*b1906ceaSLachlan Hodges __le32 p_offset; 58*b1906ceaSLachlan Hodges __le32 p_vaddr; 59*b1906ceaSLachlan Hodges __le32 p_paddr; 60*b1906ceaSLachlan Hodges __le32 p_filesz; 61*b1906ceaSLachlan Hodges __le32 p_memsz; 62*b1906ceaSLachlan Hodges __le32 p_flags; 63*b1906ceaSLachlan Hodges __le32 p_align; 64*b1906ceaSLachlan Hodges } __packed; 65*b1906ceaSLachlan Hodges 66*b1906ceaSLachlan Hodges enum mm81x_fw_info_tlv_type { 67*b1906ceaSLachlan Hodges MM81X_FW_INFO_TLV_BCF_ADDR = 1, 68*b1906ceaSLachlan Hodges }; 69*b1906ceaSLachlan Hodges 70*b1906ceaSLachlan Hodges struct mm81x_fw_info_tlv { 71*b1906ceaSLachlan Hodges __le16 type; 72*b1906ceaSLachlan Hodges __le16 length; 73*b1906ceaSLachlan Hodges u8 val[]; 74*b1906ceaSLachlan Hodges } __packed; 75*b1906ceaSLachlan Hodges 76*b1906ceaSLachlan Hodges enum mm81x_fw_ext_host_tbl_tag { 77*b1906ceaSLachlan Hodges /* The S1G capability tag */ 78*b1906ceaSLachlan Hodges MM81X_FW_HOST_TABLE_TAG_S1G_CAPABILITIES = 0, 79*b1906ceaSLachlan Hodges MM81X_FW_HOST_TABLE_TAG_PAGER_BYPASS_TX_STATUS = 1, 80*b1906ceaSLachlan Hodges MM81X_FW_HOST_TABLE_TAG_INSERT_SKB_CHECKSUM = 2, 81*b1906ceaSLachlan Hodges MM81X_FW_HOST_TABLE_TAG_YAPS_TABLE = 3, 82*b1906ceaSLachlan Hodges MM81X_FW_HOST_TABLE_TAG_PAGER_PKT_MEMORY = 4, 83*b1906ceaSLachlan Hodges MM81X_FW_HOST_TABLE_TAG_PAGER_BYPASS_CMD_RESP = 5, 84*b1906ceaSLachlan Hodges }; 85*b1906ceaSLachlan Hodges 86*b1906ceaSLachlan Hodges struct ext_host_tbl_tlv_hdr { 87*b1906ceaSLachlan Hodges /* The tag used to identify which capability this represents */ 88*b1906ceaSLachlan Hodges __le16 tag; 89*b1906ceaSLachlan Hodges /* The length of the capability structure including this header */ 90*b1906ceaSLachlan Hodges __le16 length; 91*b1906ceaSLachlan Hodges } __packed; 92*b1906ceaSLachlan Hodges 93*b1906ceaSLachlan Hodges struct ext_host_tbl_s1g_caps { 94*b1906ceaSLachlan Hodges struct ext_host_tbl_tlv_hdr header; 95*b1906ceaSLachlan Hodges __le32 flags[FW_CAPABILITIES_FLAGS_WIDTH]; 96*b1906ceaSLachlan Hodges /* 97*b1906ceaSLachlan Hodges * The minimum A-MPDU start spacing required by firmware. 98*b1906ceaSLachlan Hodges * Value | Description 99*b1906ceaSLachlan Hodges * ------|------------ 100*b1906ceaSLachlan Hodges * 0 | No restriction 101*b1906ceaSLachlan Hodges * 1 | 1/4 us 102*b1906ceaSLachlan Hodges * 2 | 1/2 us 103*b1906ceaSLachlan Hodges * 3 | 1 us 104*b1906ceaSLachlan Hodges * 4 | 2 us 105*b1906ceaSLachlan Hodges * 5 | 4 us 106*b1906ceaSLachlan Hodges * 6 | 8 us 107*b1906ceaSLachlan Hodges * 7 | 16 us 108*b1906ceaSLachlan Hodges */ 109*b1906ceaSLachlan Hodges u8 ampdu_mss; 110*b1906ceaSLachlan Hodges u8 beamformee_sts_capability; 111*b1906ceaSLachlan Hodges u8 number_sounding_dimensions; 112*b1906ceaSLachlan Hodges /* 113*b1906ceaSLachlan Hodges * The maximum A-MPDU length. This is the exponent value such that 114*b1906ceaSLachlan Hodges * (2^(13 + exponent) - 1) is the length 115*b1906ceaSLachlan Hodges */ 116*b1906ceaSLachlan Hodges u8 maximum_ampdu_length; 117*b1906ceaSLachlan Hodges /* 118*b1906ceaSLachlan Hodges * Offset to apply to the specification's MMSS table to signal further 119*b1906ceaSLachlan Hodges * minimum MPDU start spacing. 120*b1906ceaSLachlan Hodges */ 121*b1906ceaSLachlan Hodges u8 mm81x_mmss_offset; 122*b1906ceaSLachlan Hodges } __packed; 123*b1906ceaSLachlan Hodges 124*b1906ceaSLachlan Hodges struct ext_host_tbl_insert_skb_checksum { 125*b1906ceaSLachlan Hodges struct ext_host_tbl_tlv_hdr header; 126*b1906ceaSLachlan Hodges u8 insert_and_validate_checksum; 127*b1906ceaSLachlan Hodges }; 128*b1906ceaSLachlan Hodges 129*b1906ceaSLachlan Hodges struct ext_host_tbl_yaps_table { 130*b1906ceaSLachlan Hodges struct ext_host_tbl_tlv_hdr header; 131*b1906ceaSLachlan Hodges struct mm81x_yaps_hw_table yaps_table; 132*b1906ceaSLachlan Hodges } __packed; 133*b1906ceaSLachlan Hodges 134*b1906ceaSLachlan Hodges struct ext_host_tbl { 135*b1906ceaSLachlan Hodges __le32 ext_host_tbl_length; 136*b1906ceaSLachlan Hodges u8 dev_mac_addr[6]; 137*b1906ceaSLachlan Hodges u8 ext_host_table_data_tlvs[]; 138*b1906ceaSLachlan Hodges } __packed; 139*b1906ceaSLachlan Hodges 140*b1906ceaSLachlan Hodges int mm81x_fw_init(struct mm81x *mors, bool reset); 141*b1906ceaSLachlan Hodges int mm81x_fw_parse_ext_host_tbl(struct mm81x *mors); 142*b1906ceaSLachlan Hodges 143*b1906ceaSLachlan Hodges #endif /* !_MM81X_FW_H_ */ 144