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