1 /*- 2 * Copyright (c) 2013 Adrian Chadd <adrian@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 */ 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <unistd.h> 33 #include <errno.h> 34 #include <string.h> 35 #include <err.h> 36 #include <fcntl.h> 37 #include <sys/endian.h> 38 #include <sys/types.h> 39 #include <sys/stat.h> 40 41 #include <libusb.h> 42 43 #include "ath3k_fw.h" 44 #include "ath3k_hw.h" 45 #include "ath3k_dbg.h" 46 47 #define XMIN(x, y) ((x) < (y) ? (x) : (y)) 48 49 int 50 ath3k_load_fwfile(struct libusb_device_handle *hdl, 51 const struct ath3k_firmware *fw) 52 { 53 int size, count, sent = 0; 54 int ret, r; 55 56 count = fw->len; 57 58 size = XMIN(count, FW_HDR_SIZE); 59 60 ath3k_debug("%s: file=%s, size=%d\n", 61 __func__, fw->fwname, count); 62 63 /* 64 * Flip the device over to configuration mode. 65 */ 66 ret = libusb_control_transfer(hdl, 67 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, 68 ATH3K_DNLOAD, 69 0, 70 0, 71 fw->buf + sent, 72 size, 73 1000); /* XXX timeout */ 74 75 if (ret != size) { 76 fprintf(stderr, "Can't switch to config mode; ret=%d\n", 77 ret); 78 return (-1); 79 } 80 81 sent += size; 82 count -= size; 83 84 /* Load in the rest of the data */ 85 while (count) { 86 size = XMIN(count, BULK_SIZE); 87 ath3k_debug("%s: transferring %d bytes, offset %d\n", 88 __func__, 89 sent, 90 size); 91 92 ret = libusb_bulk_transfer(hdl, 93 0x2, 94 fw->buf + sent, 95 size, 96 &r, 97 1000); 98 99 if (ret < 0 || r != size) { 100 fprintf(stderr, "Can't load firmware: err=%s, size=%d\n", 101 libusb_strerror(ret), 102 size); 103 return (-1); 104 } 105 sent += size; 106 count -= size; 107 } 108 return (0); 109 } 110 111 int 112 ath3k_get_state(struct libusb_device_handle *hdl, unsigned char *state) 113 { 114 int ret; 115 116 ret = libusb_control_transfer(hdl, 117 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN, 118 ATH3K_GETSTATE, 119 0, 120 0, 121 state, 122 1, 123 1000); /* XXX timeout */ 124 125 if (ret < 0) { 126 fprintf(stderr, 127 "%s: libusb_control_transfer() failed: code=%d\n", 128 __func__, 129 ret); 130 return (0); 131 } 132 133 return (ret == 1); 134 } 135 136 int 137 ath3k_get_version(struct libusb_device_handle *hdl, 138 struct ath3k_version *version) 139 { 140 int ret; 141 142 ret = libusb_control_transfer(hdl, 143 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN, 144 ATH3K_GETVERSION, 145 0, 146 0, 147 (unsigned char *) version, 148 sizeof(struct ath3k_version), 149 1000); /* XXX timeout */ 150 151 if (ret < 0) { 152 fprintf(stderr, 153 "%s: libusb_control_transfer() failed: code=%d\n", 154 __func__, 155 ret); 156 return (0); 157 } 158 159 /* XXX endian fix! */ 160 161 return (ret == sizeof(struct ath3k_version)); 162 } 163 164 int 165 ath3k_load_patch(libusb_device_handle *hdl, const char *fw_path) 166 { 167 int ret; 168 unsigned char fw_state; 169 struct ath3k_version fw_ver, pt_ver; 170 char fwname[FILENAME_MAX]; 171 struct ath3k_firmware fw; 172 uint32_t tmp; 173 174 ret = ath3k_get_state(hdl, &fw_state); 175 if (ret < 0) { 176 ath3k_err("%s: Can't get state\n", __func__); 177 return (ret); 178 } 179 180 if (fw_state & ATH3K_PATCH_UPDATE) { 181 ath3k_info("%s: Patch already downloaded\n", 182 __func__); 183 return (0); 184 } 185 186 ret = ath3k_get_version(hdl, &fw_ver); 187 if (ret < 0) { 188 ath3k_debug("%s: Can't get version\n", __func__); 189 return (ret); 190 } 191 192 /* XXX path info? */ 193 snprintf(fwname, FILENAME_MAX, "%s/ar3k/AthrBT_0x%08x.dfu", 194 fw_path, 195 fw_ver.rom_version); 196 197 /* Read in the firmware */ 198 if (ath3k_fw_read(&fw, fwname) <= 0) { 199 ath3k_debug("%s: ath3k_fw_read() failed\n", 200 __func__); 201 return (-1); 202 } 203 204 /* 205 * Extract the ROM/build version from the patch file. 206 */ 207 memcpy(&tmp, fw.buf + fw.len - 8, sizeof(tmp)); 208 pt_ver.rom_version = le32toh(tmp); 209 memcpy(&tmp, fw.buf + fw.len - 4, sizeof(tmp)); 210 pt_ver.build_version = le32toh(tmp); 211 212 ath3k_info("%s: file %s: rom_ver=%d, build_ver=%d\n", 213 __func__, 214 fwname, 215 (int) pt_ver.rom_version, 216 (int) pt_ver.build_version); 217 218 /* Check the ROM/build version against the firmware */ 219 if ((pt_ver.rom_version != fw_ver.rom_version) || 220 (pt_ver.build_version <= fw_ver.build_version)) { 221 ath3k_debug("Patch file version mismatch!\n"); 222 ath3k_fw_free(&fw); 223 return (-1); 224 } 225 226 /* Load in the firmware */ 227 ret = ath3k_load_fwfile(hdl, &fw); 228 229 /* free it */ 230 ath3k_fw_free(&fw); 231 232 return (ret); 233 } 234 235 int 236 ath3k_load_syscfg(libusb_device_handle *hdl, const char *fw_path) 237 { 238 unsigned char fw_state; 239 char filename[FILENAME_MAX]; 240 struct ath3k_firmware fw; 241 struct ath3k_version fw_ver; 242 int clk_value, ret; 243 244 ret = ath3k_get_state(hdl, &fw_state); 245 if (ret < 0) { 246 ath3k_err("Can't get state to change to load configuration err"); 247 return (-EBUSY); 248 } 249 250 ret = ath3k_get_version(hdl, &fw_ver); 251 if (ret < 0) { 252 ath3k_err("Can't get version to change to load ram patch err"); 253 return (ret); 254 } 255 256 switch (fw_ver.ref_clock) { 257 case ATH3K_XTAL_FREQ_26M: 258 clk_value = 26; 259 break; 260 case ATH3K_XTAL_FREQ_40M: 261 clk_value = 40; 262 break; 263 case ATH3K_XTAL_FREQ_19P2: 264 clk_value = 19; 265 break; 266 default: 267 clk_value = 0; 268 break; 269 } 270 271 snprintf(filename, FILENAME_MAX, "%s/ar3k/ramps_0x%08x_%d%s", 272 fw_path, 273 fw_ver.rom_version, 274 clk_value, 275 ".dfu"); 276 277 ath3k_info("%s: syscfg file = %s\n", 278 __func__, 279 filename); 280 281 /* Read in the firmware */ 282 if (ath3k_fw_read(&fw, filename) <= 0) { 283 ath3k_err("%s: ath3k_fw_read() failed\n", 284 __func__); 285 return (-1); 286 } 287 288 ret = ath3k_load_fwfile(hdl, &fw); 289 290 ath3k_fw_free(&fw); 291 return (ret); 292 } 293 294 int 295 ath3k_set_normal_mode(libusb_device_handle *hdl) 296 { 297 int ret; 298 unsigned char fw_state; 299 300 ret = ath3k_get_state(hdl, &fw_state); 301 if (ret < 0) { 302 ath3k_err("%s: can't get state\n", __func__); 303 return (ret); 304 } 305 306 /* 307 * This isn't a fatal error - the device may have detached 308 * already. 309 */ 310 if ((fw_state & ATH3K_MODE_MASK) == ATH3K_NORMAL_MODE) { 311 ath3k_debug("%s: firmware is already in normal mode\n", 312 __func__); 313 return (0); 314 } 315 316 ret = libusb_control_transfer(hdl, 317 LIBUSB_REQUEST_TYPE_VENDOR, /* XXX out direction? */ 318 ATH3K_SET_NORMAL_MODE, 319 0, 320 0, 321 NULL, 322 0, 323 1000); /* XXX timeout */ 324 325 if (ret < 0) { 326 ath3k_err("%s: libusb_control_transfer() failed: code=%d\n", 327 __func__, 328 ret); 329 return (0); 330 } 331 332 return (ret == 0); 333 } 334 335 int 336 ath3k_switch_pid(libusb_device_handle *hdl) 337 { 338 int ret; 339 ret = libusb_control_transfer(hdl, 340 LIBUSB_REQUEST_TYPE_VENDOR, /* XXX set an out flag? */ 341 USB_REG_SWITCH_VID_PID, 342 0, 343 0, 344 NULL, 345 0, 346 1000); /* XXX timeout */ 347 348 if (ret < 0) { 349 ath3k_debug("%s: libusb_control_transfer() failed: code=%d\n", 350 __func__, 351 ret); 352 return (0); 353 } 354 355 return (ret == 0); 356 } 357