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 * $FreeBSD$ 30 */ 31 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <unistd.h> 35 #include <errno.h> 36 #include <string.h> 37 #include <err.h> 38 #include <fcntl.h> 39 #include <sys/endian.h> 40 #include <sys/types.h> 41 #include <sys/stat.h> 42 43 #include <libusb.h> 44 45 #include "ath3k_fw.h" 46 #include "ath3k_hw.h" 47 #include "ath3k_dbg.h" 48 49 #define XMIN(x, y) ((x) < (y) ? (x) : (y)) 50 51 int 52 ath3k_load_fwfile(struct libusb_device_handle *hdl, 53 const struct ath3k_firmware *fw) 54 { 55 int size, count, sent = 0; 56 int ret, r; 57 58 count = fw->len; 59 60 size = XMIN(count, FW_HDR_SIZE); 61 62 ath3k_debug("%s: file=%s, size=%d\n", 63 __func__, fw->fwname, count); 64 65 /* 66 * Flip the device over to configuration mode. 67 */ 68 ret = libusb_control_transfer(hdl, 69 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, 70 ATH3K_DNLOAD, 71 0, 72 0, 73 fw->buf + sent, 74 size, 75 1000); /* XXX timeout */ 76 77 if (ret != size) { 78 fprintf(stderr, "Can't switch to config mode; ret=%d\n", 79 ret); 80 return (-1); 81 } 82 83 sent += size; 84 count -= size; 85 86 /* Load in the rest of the data */ 87 while (count) { 88 size = XMIN(count, BULK_SIZE); 89 ath3k_debug("%s: transferring %d bytes, offset %d\n", 90 __func__, 91 sent, 92 size); 93 94 ret = libusb_bulk_transfer(hdl, 95 0x2, 96 fw->buf + sent, 97 size, 98 &r, 99 1000); 100 101 if (ret < 0 || r != size) { 102 fprintf(stderr, "Can't load firmware: err=%s, size=%d\n", 103 libusb_strerror(ret), 104 size); 105 return (-1); 106 } 107 sent += size; 108 count -= size; 109 } 110 return (0); 111 } 112 113 int 114 ath3k_get_state(struct libusb_device_handle *hdl, unsigned char *state) 115 { 116 int ret; 117 118 ret = libusb_control_transfer(hdl, 119 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN, 120 ATH3K_GETSTATE, 121 0, 122 0, 123 state, 124 1, 125 1000); /* XXX timeout */ 126 127 if (ret < 0) { 128 fprintf(stderr, 129 "%s: libusb_control_transfer() failed: code=%d\n", 130 __func__, 131 ret); 132 return (0); 133 } 134 135 return (ret == 1); 136 } 137 138 int 139 ath3k_get_version(struct libusb_device_handle *hdl, 140 struct ath3k_version *version) 141 { 142 int ret; 143 144 ret = libusb_control_transfer(hdl, 145 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN, 146 ATH3K_GETVERSION, 147 0, 148 0, 149 (unsigned char *) version, 150 sizeof(struct ath3k_version), 151 1000); /* XXX timeout */ 152 153 if (ret < 0) { 154 fprintf(stderr, 155 "%s: libusb_control_transfer() failed: code=%d\n", 156 __func__, 157 ret); 158 return (0); 159 } 160 161 /* XXX endian fix! */ 162 163 return (ret == sizeof(struct ath3k_version)); 164 } 165 166 int 167 ath3k_load_patch(libusb_device_handle *hdl, const char *fw_path) 168 { 169 int ret; 170 unsigned char fw_state; 171 struct ath3k_version fw_ver, pt_ver; 172 char fwname[FILENAME_MAX]; 173 struct ath3k_firmware fw; 174 uint32_t tmp; 175 176 ret = ath3k_get_state(hdl, &fw_state); 177 if (ret < 0) { 178 ath3k_err("%s: Can't get state\n", __func__); 179 return (ret); 180 } 181 182 if (fw_state & ATH3K_PATCH_UPDATE) { 183 ath3k_info("%s: Patch already downloaded\n", 184 __func__); 185 return (0); 186 } 187 188 ret = ath3k_get_version(hdl, &fw_ver); 189 if (ret < 0) { 190 ath3k_debug("%s: Can't get version\n", __func__); 191 return (ret); 192 } 193 194 /* XXX path info? */ 195 snprintf(fwname, FILENAME_MAX, "%s/ar3k/AthrBT_0x%08x.dfu", 196 fw_path, 197 fw_ver.rom_version); 198 199 /* Read in the firmware */ 200 if (ath3k_fw_read(&fw, fwname) <= 0) { 201 ath3k_debug("%s: ath3k_fw_read() failed\n", 202 __func__); 203 return (-1); 204 } 205 206 /* 207 * Extract the ROM/build version from the patch file. 208 */ 209 memcpy(&tmp, fw.buf + fw.len - 8, sizeof(tmp)); 210 pt_ver.rom_version = le32toh(tmp); 211 memcpy(&tmp, fw.buf + fw.len - 4, sizeof(tmp)); 212 pt_ver.build_version = le32toh(tmp); 213 214 ath3k_info("%s: file %s: rom_ver=%d, build_ver=%d\n", 215 __func__, 216 fwname, 217 (int) pt_ver.rom_version, 218 (int) pt_ver.build_version); 219 220 /* Check the ROM/build version against the firmware */ 221 if ((pt_ver.rom_version != fw_ver.rom_version) || 222 (pt_ver.build_version <= fw_ver.build_version)) { 223 ath3k_debug("Patch file version mismatch!\n"); 224 ath3k_fw_free(&fw); 225 return (-1); 226 } 227 228 /* Load in the firmware */ 229 ret = ath3k_load_fwfile(hdl, &fw); 230 231 /* free it */ 232 ath3k_fw_free(&fw); 233 234 return (ret); 235 } 236 237 int 238 ath3k_load_syscfg(libusb_device_handle *hdl, const char *fw_path) 239 { 240 unsigned char fw_state; 241 char filename[FILENAME_MAX]; 242 struct ath3k_firmware fw; 243 struct ath3k_version fw_ver; 244 int clk_value, ret; 245 246 ret = ath3k_get_state(hdl, &fw_state); 247 if (ret < 0) { 248 ath3k_err("Can't get state to change to load configuration err"); 249 return (-EBUSY); 250 } 251 252 ret = ath3k_get_version(hdl, &fw_ver); 253 if (ret < 0) { 254 ath3k_err("Can't get version to change to load ram patch err"); 255 return (ret); 256 } 257 258 switch (fw_ver.ref_clock) { 259 case ATH3K_XTAL_FREQ_26M: 260 clk_value = 26; 261 break; 262 case ATH3K_XTAL_FREQ_40M: 263 clk_value = 40; 264 break; 265 case ATH3K_XTAL_FREQ_19P2: 266 clk_value = 19; 267 break; 268 default: 269 clk_value = 0; 270 break; 271 } 272 273 snprintf(filename, FILENAME_MAX, "%s/ar3k/ramps_0x%08x_%d%s", 274 fw_path, 275 fw_ver.rom_version, 276 clk_value, 277 ".dfu"); 278 279 ath3k_info("%s: syscfg file = %s\n", 280 __func__, 281 filename); 282 283 /* Read in the firmware */ 284 if (ath3k_fw_read(&fw, filename) <= 0) { 285 ath3k_err("%s: ath3k_fw_read() failed\n", 286 __func__); 287 return (-1); 288 } 289 290 ret = ath3k_load_fwfile(hdl, &fw); 291 292 ath3k_fw_free(&fw); 293 return (ret); 294 } 295 296 int 297 ath3k_set_normal_mode(libusb_device_handle *hdl) 298 { 299 int ret; 300 unsigned char fw_state; 301 302 ret = ath3k_get_state(hdl, &fw_state); 303 if (ret < 0) { 304 ath3k_err("%s: can't get state\n", __func__); 305 return (ret); 306 } 307 308 /* 309 * This isn't a fatal error - the device may have detached 310 * already. 311 */ 312 if ((fw_state & ATH3K_MODE_MASK) == ATH3K_NORMAL_MODE) { 313 ath3k_debug("%s: firmware is already in normal mode\n", 314 __func__); 315 return (0); 316 } 317 318 ret = libusb_control_transfer(hdl, 319 LIBUSB_REQUEST_TYPE_VENDOR, /* XXX out direction? */ 320 ATH3K_SET_NORMAL_MODE, 321 0, 322 0, 323 NULL, 324 0, 325 1000); /* XXX timeout */ 326 327 if (ret < 0) { 328 ath3k_err("%s: libusb_control_transfer() failed: code=%d\n", 329 __func__, 330 ret); 331 return (0); 332 } 333 334 return (ret == 0); 335 } 336 337 int 338 ath3k_switch_pid(libusb_device_handle *hdl) 339 { 340 int ret; 341 ret = libusb_control_transfer(hdl, 342 LIBUSB_REQUEST_TYPE_VENDOR, /* XXX set an out flag? */ 343 USB_REG_SWITCH_VID_PID, 344 0, 345 0, 346 NULL, 347 0, 348 1000); /* XXX timeout */ 349 350 if (ret < 0) { 351 ath3k_debug("%s: libusb_control_transfer() failed: code=%d\n", 352 __func__, 353 ret); 354 return (0); 355 } 356 357 return (ret == 0); 358 } 359