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