Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | /* SPDX-License-Identifier: ISC */ /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2015,2017 Qualcomm Atheros, Inc. */ #ifndef _BMI_H_ #define _BMI_H_ #include "core.h" /* * Bootloader Messaging Interface (BMI) * * BMI is a very simple messaging interface used during initialization * to read memory, write memory, execute code, and to define an * application entry PC. * * It is used to download an application to QCA988x, to provide * patches to code that is already resident on QCA988x, and generally * to examine and modify state. The Host has an opportunity to use * BMI only once during bootup. Once the Host issues a BMI_DONE * command, this opportunity ends. * * The Host writes BMI requests to mailbox0, and reads BMI responses * from mailbox0. BMI requests all begin with a command * (see below for specific commands), and are followed by * command-specific data. * * Flow control: * The Host can only issue a command once the Target gives it a * "BMI Command Credit", using AR8K Counter #4. As soon as the * Target has completed a command, it issues another BMI Command * Credit (so the Host can issue the next command). * * BMI handles all required Target-side cache flushing. */ /* Maximum data size used for BMI transfers */ #define BMI_MAX_DATA_SIZE 256 /* len = cmd + addr + length */ #define BMI_MAX_CMDBUF_SIZE (BMI_MAX_DATA_SIZE + \ sizeof(u32) + \ sizeof(u32) + \ sizeof(u32)) /* Maximum data size used for large BMI transfers */ #define BMI_MAX_LARGE_DATA_SIZE 2048 /* len = cmd + addr + length */ #define BMI_MAX_LARGE_CMDBUF_SIZE (BMI_MAX_LARGE_DATA_SIZE + \ sizeof(u32) + \ sizeof(u32) + \ sizeof(u32)) /* BMI Commands */ enum bmi_cmd_id { BMI_NO_COMMAND = 0, BMI_DONE = 1, BMI_READ_MEMORY = 2, BMI_WRITE_MEMORY = 3, BMI_EXECUTE = 4, BMI_SET_APP_START = 5, BMI_READ_SOC_REGISTER = 6, BMI_READ_SOC_WORD = 6, BMI_WRITE_SOC_REGISTER = 7, BMI_WRITE_SOC_WORD = 7, BMI_GET_TARGET_ID = 8, BMI_GET_TARGET_INFO = 8, BMI_ROMPATCH_INSTALL = 9, BMI_ROMPATCH_UNINSTALL = 10, BMI_ROMPATCH_ACTIVATE = 11, BMI_ROMPATCH_DEACTIVATE = 12, BMI_LZ_STREAM_START = 13, /* should be followed by LZ_DATA */ BMI_LZ_DATA = 14, BMI_NVRAM_PROCESS = 15, }; #define BMI_NVRAM_SEG_NAME_SZ 16 #define BMI_PARAM_GET_EEPROM_BOARD_ID 0x10 #define BMI_PARAM_GET_FLASH_BOARD_ID 0x8000 #define BMI_PARAM_FLASH_SECTION_ALL 0x10000 /* Dual-band Extended Board ID */ #define BMI_PARAM_GET_EXT_BOARD_ID 0x40000 #define ATH10K_BMI_EXT_BOARD_ID_SUPPORT 0x40000 #define ATH10K_BMI_BOARD_ID_FROM_OTP_MASK 0x7c00 #define ATH10K_BMI_BOARD_ID_FROM_OTP_LSB 10 #define ATH10K_BMI_CHIP_ID_FROM_OTP_MASK 0x18000 #define ATH10K_BMI_CHIP_ID_FROM_OTP_LSB 15 #define ATH10K_BMI_BOARD_ID_STATUS_MASK 0xff #define ATH10K_BMI_EBOARD_ID_STATUS_MASK 0xff struct bmi_cmd { __le32 id; /* enum bmi_cmd_id */ union { struct { } done; struct { __le32 addr; __le32 len; } read_mem; struct { __le32 addr; __le32 len; u8 payload[]; } write_mem; struct { __le32 addr; __le32 param; } execute; struct { __le32 addr; } set_app_start; struct { __le32 addr; } read_soc_reg; struct { __le32 addr; __le32 value; } write_soc_reg; struct { } get_target_info; struct { __le32 rom_addr; __le32 ram_addr; /* or value */ __le32 size; __le32 activate; /* 0=install, but dont activate */ } rompatch_install; struct { __le32 patch_id; } rompatch_uninstall; struct { __le32 count; __le32 patch_ids[]; /* length of @count */ } rompatch_activate; struct { __le32 count; __le32 patch_ids[]; /* length of @count */ } rompatch_deactivate; struct { __le32 addr; } lz_start; struct { __le32 len; /* max BMI_MAX_DATA_SIZE */ u8 payload[]; /* length of @len */ } lz_data; struct { u8 name[BMI_NVRAM_SEG_NAME_SZ]; } nvram_process; u8 payload[BMI_MAX_CMDBUF_SIZE]; }; } __packed; union bmi_resp { struct { DECLARE_FLEX_ARRAY(u8, payload); } read_mem; struct { __le32 result; } execute; struct { __le32 value; } read_soc_reg; struct { __le32 len; __le32 version; __le32 type; } get_target_info; struct { __le32 patch_id; } rompatch_install; struct { __le32 patch_id; } rompatch_uninstall; struct { /* 0 = nothing executed * otherwise = NVRAM segment return value */ __le32 result; } nvram_process; u8 payload[BMI_MAX_CMDBUF_SIZE]; } __packed; struct bmi_target_info { u32 version; u32 type; }; struct bmi_segmented_file_header { __le32 magic_num; __le32 file_flags; u8 data[]; }; struct bmi_segmented_metadata { __le32 addr; __le32 length; u8 data[]; }; #define BMI_SGMTFILE_MAGIC_NUM 0x544d4753 /* "SGMT" */ #define BMI_SGMTFILE_FLAG_COMPRESS 1 /* Special values for bmi_segmented_metadata.length (all have high bit set) */ /* end of segmented data */ #define BMI_SGMTFILE_DONE 0xffffffff /* Board Data segment */ #define BMI_SGMTFILE_BDDATA 0xfffffffe /* set beginning address */ #define BMI_SGMTFILE_BEGINADDR 0xfffffffd /* immediate function execution */ #define BMI_SGMTFILE_EXEC 0xfffffffc /* in jiffies */ #define BMI_COMMUNICATION_TIMEOUT_HZ (3 * HZ) #define BMI_CE_NUM_TO_TARG 0 #define BMI_CE_NUM_TO_HOST 1 void ath10k_bmi_start(struct ath10k *ar); int ath10k_bmi_done(struct ath10k *ar); int ath10k_bmi_get_target_info(struct ath10k *ar, struct bmi_target_info *target_info); int ath10k_bmi_get_target_info_sdio(struct ath10k *ar, struct bmi_target_info *target_info); int ath10k_bmi_read_memory(struct ath10k *ar, u32 address, void *buffer, u32 length); int ath10k_bmi_write_memory(struct ath10k *ar, u32 address, const void *buffer, u32 length); #define ath10k_bmi_read32(ar, item, val) \ ({ \ int ret; \ u32 addr; \ __le32 tmp; \ \ addr = host_interest_item_address(HI_ITEM(item)); \ ret = ath10k_bmi_read_memory(ar, addr, (u8 *)&tmp, 4); \ if (!ret) \ *val = __le32_to_cpu(tmp); \ ret; \ }) #define ath10k_bmi_write32(ar, item, val) \ ({ \ int ret; \ u32 address; \ __le32 v = __cpu_to_le32(val); \ \ address = host_interest_item_address(HI_ITEM(item)); \ ret = ath10k_bmi_write_memory(ar, address, \ (u8 *)&v, sizeof(v)); \ ret; \ }) int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result); int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address); int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length); int ath10k_bmi_fast_download(struct ath10k *ar, u32 address, const void *buffer, u32 length); int ath10k_bmi_read_soc_reg(struct ath10k *ar, u32 address, u32 *reg_val); int ath10k_bmi_write_soc_reg(struct ath10k *ar, u32 address, u32 reg_val); int ath10k_bmi_set_start(struct ath10k *ar, u32 address); #endif /* _BMI_H_ */ |