1 /* 2 * Copyright (c) 2004-2011 Atheros Communications Inc. 3 * Copyright (c) 2011 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 /* 22 * Bootloader Messaging Interface (BMI) 23 * 24 * BMI is a very simple messaging interface used during initialization 25 * to read memory, write memory, execute code, and to define an 26 * application entry PC. 27 * 28 * It is used to download an application to ATH6KL, to provide 29 * patches to code that is already resident on ATH6KL, and generally 30 * to examine and modify state. The Host has an opportunity to use 31 * BMI only once during bootup. Once the Host issues a BMI_DONE 32 * command, this opportunity ends. 33 * 34 * The Host writes BMI requests to mailbox0, and reads BMI responses 35 * from mailbox0. BMI requests all begin with a command 36 * (see below for specific commands), and are followed by 37 * command-specific data. 38 * 39 * Flow control: 40 * The Host can only issue a command once the Target gives it a 41 * "BMI Command Credit", using ATH6KL Counter #4. As soon as the 42 * Target has completed a command, it issues another BMI Command 43 * Credit (so the Host can issue the next command). 44 * 45 * BMI handles all required Target-side cache flushing. 46 */ 47 48 /* BMI Commands */ 49 50 #define BMI_NO_COMMAND 0 51 52 #define BMI_DONE 1 53 /* 54 * Semantics: Host is done using BMI 55 * Request format: 56 * u32 command (BMI_DONE) 57 * Response format: none 58 */ 59 60 #define BMI_READ_MEMORY 2 61 /* 62 * Semantics: Host reads ATH6KL memory 63 * Request format: 64 * u32 command (BMI_READ_MEMORY) 65 * u32 address 66 * u32 length, at most BMI_DATASZ_MAX 67 * Response format: 68 * u8 data[length] 69 */ 70 71 #define BMI_WRITE_MEMORY 3 72 /* 73 * Semantics: Host writes ATH6KL memory 74 * Request format: 75 * u32 command (BMI_WRITE_MEMORY) 76 * u32 address 77 * u32 length, at most BMI_DATASZ_MAX 78 * u8 data[length] 79 * Response format: none 80 */ 81 82 #define BMI_EXECUTE 4 83 /* 84 * Semantics: Causes ATH6KL to execute code 85 * Request format: 86 * u32 command (BMI_EXECUTE) 87 * u32 address 88 * u32 parameter 89 * Response format: 90 * u32 return value 91 */ 92 93 #define BMI_SET_APP_START 5 94 /* 95 * Semantics: Set Target application starting address 96 * Request format: 97 * u32 command (BMI_SET_APP_START) 98 * u32 address 99 * Response format: none 100 */ 101 102 #define BMI_READ_SOC_REGISTER 6 103 /* 104 * Semantics: Read a 32-bit Target SOC register. 105 * Request format: 106 * u32 command (BMI_READ_REGISTER) 107 * u32 address 108 * Response format: 109 * u32 value 110 */ 111 112 #define BMI_WRITE_SOC_REGISTER 7 113 /* 114 * Semantics: Write a 32-bit Target SOC register. 115 * Request format: 116 * u32 command (BMI_WRITE_REGISTER) 117 * u32 address 118 * u32 value 119 * 120 * Response format: none 121 */ 122 123 #define BMI_GET_TARGET_ID 8 124 #define BMI_GET_TARGET_INFO 8 125 /* 126 * Semantics: Fetch the 4-byte Target information 127 * Request format: 128 * u32 command (BMI_GET_TARGET_ID/INFO) 129 * Response format1 (old firmware): 130 * u32 TargetVersionID 131 * Response format2 (newer firmware): 132 * u32 TARGET_VERSION_SENTINAL 133 * struct bmi_target_info; 134 */ 135 136 #define TARGET_VERSION_SENTINAL 0xffffffff 137 #define TARGET_TYPE_AR6003 3 138 #define TARGET_TYPE_AR6004 5 139 #define BMI_ROMPATCH_INSTALL 9 140 /* 141 * Semantics: Install a ROM Patch. 142 * Request format: 143 * u32 command (BMI_ROMPATCH_INSTALL) 144 * u32 Target ROM Address 145 * u32 Target RAM Address or Value (depending on Target Type) 146 * u32 Size, in bytes 147 * u32 Activate? 1-->activate; 148 * 0-->install but do not activate 149 * Response format: 150 * u32 PatchID 151 */ 152 153 #define BMI_ROMPATCH_UNINSTALL 10 154 /* 155 * Semantics: Uninstall a previously-installed ROM Patch, 156 * automatically deactivating, if necessary. 157 * Request format: 158 * u32 command (BMI_ROMPATCH_UNINSTALL) 159 * u32 PatchID 160 * 161 * Response format: none 162 */ 163 164 #define BMI_ROMPATCH_ACTIVATE 11 165 /* 166 * Semantics: Activate a list of previously-installed ROM Patches. 167 * Request format: 168 * u32 command (BMI_ROMPATCH_ACTIVATE) 169 * u32 rompatch_count 170 * u32 PatchID[rompatch_count] 171 * 172 * Response format: none 173 */ 174 175 #define BMI_ROMPATCH_DEACTIVATE 12 176 /* 177 * Semantics: Deactivate a list of active ROM Patches. 178 * Request format: 179 * u32 command (BMI_ROMPATCH_DEACTIVATE) 180 * u32 rompatch_count 181 * u32 PatchID[rompatch_count] 182 * 183 * Response format: none 184 */ 185 186 187 #define BMI_LZ_STREAM_START 13 188 /* 189 * Semantics: Begin an LZ-compressed stream of input 190 * which is to be uncompressed by the Target to an 191 * output buffer at address. The output buffer must 192 * be sufficiently large to hold the uncompressed 193 * output from the compressed input stream. This BMI 194 * command should be followed by a series of 1 or more 195 * BMI_LZ_DATA commands. 196 * u32 command (BMI_LZ_STREAM_START) 197 * u32 address 198 * Note: Not supported on all versions of ROM firmware. 199 */ 200 201 #define BMI_LZ_DATA 14 202 /* 203 * Semantics: Host writes ATH6KL memory with LZ-compressed 204 * data which is uncompressed by the Target. This command 205 * must be preceded by a BMI_LZ_STREAM_START command. A series 206 * of BMI_LZ_DATA commands are considered part of a single 207 * input stream until another BMI_LZ_STREAM_START is issued. 208 * Request format: 209 * u32 command (BMI_LZ_DATA) 210 * u32 length (of compressed data), 211 * at most BMI_DATASZ_MAX 212 * u8 CompressedData[length] 213 * Response format: none 214 * Note: Not supported on all versions of ROM firmware. 215 */ 216 217 #define BMI_COMMUNICATION_TIMEOUT 1000 /* in msec */ 218 219 struct ath6kl; 220 struct ath6kl_bmi_target_info { 221 __le32 byte_count; /* size of this structure */ 222 __le32 version; /* target version id */ 223 __le32 type; /* target type */ 224 } __packed; 225 226 #define ath6kl_bmi_write_hi32(ar, item, val) \ 227 ({ \ 228 u32 addr; \ 229 __le32 v; \ 230 \ 231 addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \ 232 v = cpu_to_le32(val); \ 233 ath6kl_bmi_write(ar, addr, (u8 *) &v, sizeof(v)); \ 234 }) 235 236 #define ath6kl_bmi_read_hi32(ar, item, val) \ 237 ({ \ 238 u32 addr, *check_type = val; \ 239 __le32 tmp; \ 240 int ret; \ 241 \ 242 (void) (check_type == val); \ 243 addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \ 244 ret = ath6kl_bmi_read(ar, addr, (u8 *) &tmp, 4); \ 245 if (!ret) \ 246 *val = le32_to_cpu(tmp); \ 247 ret; \ 248 }) 249 250 int ath6kl_bmi_init(struct ath6kl *ar); 251 void ath6kl_bmi_cleanup(struct ath6kl *ar); 252 void ath6kl_bmi_reset(struct ath6kl *ar); 253 254 int ath6kl_bmi_done(struct ath6kl *ar); 255 int ath6kl_bmi_get_target_info(struct ath6kl *ar, 256 struct ath6kl_bmi_target_info *targ_info); 257 int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len); 258 int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len); 259 int ath6kl_bmi_execute(struct ath6kl *ar, 260 u32 addr, u32 *param); 261 int ath6kl_bmi_set_app_start(struct ath6kl *ar, 262 u32 addr); 263 int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param); 264 int ath6kl_bmi_reg_write(struct ath6kl *ar, u32 addr, u32 param); 265 int ath6kl_bmi_lz_data(struct ath6kl *ar, 266 u8 *buf, u32 len); 267 int ath6kl_bmi_lz_stream_start(struct ath6kl *ar, 268 u32 addr); 269 int ath6kl_bmi_fast_download(struct ath6kl *ar, 270 u32 addr, u8 *buf, u32 len); 271 #endif 272