1*7f32f0e2SVladimir Kondratyev /*- 2*7f32f0e2SVladimir Kondratyev * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*7f32f0e2SVladimir Kondratyev * 4*7f32f0e2SVladimir Kondratyev * Copyright (c) 2013 Adrian Chadd <adrian@freebsd.org> 5*7f32f0e2SVladimir Kondratyev * Copyright (c) 2019 Vladimir Kondratyev <wulf@FreeBSD.org> 6*7f32f0e2SVladimir Kondratyev * 7*7f32f0e2SVladimir Kondratyev * Redistribution and use in source and binary forms, with or without 8*7f32f0e2SVladimir Kondratyev * modification, are permitted provided that the following conditions 9*7f32f0e2SVladimir Kondratyev * are met: 10*7f32f0e2SVladimir Kondratyev * 1. Redistributions of source code must retain the above copyright 11*7f32f0e2SVladimir Kondratyev * notice, this list of conditions and the following disclaimer. 12*7f32f0e2SVladimir Kondratyev * 2. Redistributions in binary form must reproduce the above copyright 13*7f32f0e2SVladimir Kondratyev * notice, this list of conditions and the following disclaimer in the 14*7f32f0e2SVladimir Kondratyev * documentation and/or other materials provided with the distribution. 15*7f32f0e2SVladimir Kondratyev * 16*7f32f0e2SVladimir Kondratyev * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17*7f32f0e2SVladimir Kondratyev * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*7f32f0e2SVladimir Kondratyev * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*7f32f0e2SVladimir Kondratyev * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20*7f32f0e2SVladimir Kondratyev * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*7f32f0e2SVladimir Kondratyev * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22*7f32f0e2SVladimir Kondratyev * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23*7f32f0e2SVladimir Kondratyev * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24*7f32f0e2SVladimir Kondratyev * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25*7f32f0e2SVladimir Kondratyev * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*7f32f0e2SVladimir Kondratyev * SUCH DAMAGE. 27*7f32f0e2SVladimir Kondratyev * 28*7f32f0e2SVladimir Kondratyev * $FreeBSD$ 29*7f32f0e2SVladimir Kondratyev */ 30*7f32f0e2SVladimir Kondratyev 31*7f32f0e2SVladimir Kondratyev #include <sys/types.h> 32*7f32f0e2SVladimir Kondratyev #include <sys/endian.h> 33*7f32f0e2SVladimir Kondratyev #include <sys/stat.h> 34*7f32f0e2SVladimir Kondratyev 35*7f32f0e2SVladimir Kondratyev #include <err.h> 36*7f32f0e2SVladimir Kondratyev #include <errno.h> 37*7f32f0e2SVladimir Kondratyev #include <fcntl.h> 38*7f32f0e2SVladimir Kondratyev #include <stdio.h> 39*7f32f0e2SVladimir Kondratyev #include <stdlib.h> 40*7f32f0e2SVladimir Kondratyev #include <string.h> 41*7f32f0e2SVladimir Kondratyev #include <unistd.h> 42*7f32f0e2SVladimir Kondratyev 43*7f32f0e2SVladimir Kondratyev #include "iwmbt_fw.h" 44*7f32f0e2SVladimir Kondratyev #include "iwmbt_dbg.h" 45*7f32f0e2SVladimir Kondratyev 46*7f32f0e2SVladimir Kondratyev int 47*7f32f0e2SVladimir Kondratyev iwmbt_fw_read(struct iwmbt_firmware *fw, const char *fwname) 48*7f32f0e2SVladimir Kondratyev { 49*7f32f0e2SVladimir Kondratyev int fd; 50*7f32f0e2SVladimir Kondratyev struct stat sb; 51*7f32f0e2SVladimir Kondratyev unsigned char *buf; 52*7f32f0e2SVladimir Kondratyev ssize_t r; 53*7f32f0e2SVladimir Kondratyev int i; 54*7f32f0e2SVladimir Kondratyev 55*7f32f0e2SVladimir Kondratyev fd = open(fwname, O_RDONLY); 56*7f32f0e2SVladimir Kondratyev if (fd < 0) { 57*7f32f0e2SVladimir Kondratyev warn("%s: open: %s", __func__, fwname); 58*7f32f0e2SVladimir Kondratyev return (0); 59*7f32f0e2SVladimir Kondratyev } 60*7f32f0e2SVladimir Kondratyev 61*7f32f0e2SVladimir Kondratyev if (fstat(fd, &sb) != 0) { 62*7f32f0e2SVladimir Kondratyev warn("%s: stat: %s", __func__, fwname); 63*7f32f0e2SVladimir Kondratyev close(fd); 64*7f32f0e2SVladimir Kondratyev return (0); 65*7f32f0e2SVladimir Kondratyev } 66*7f32f0e2SVladimir Kondratyev 67*7f32f0e2SVladimir Kondratyev buf = calloc(1, sb.st_size); 68*7f32f0e2SVladimir Kondratyev if (buf == NULL) { 69*7f32f0e2SVladimir Kondratyev warn("%s: calloc", __func__); 70*7f32f0e2SVladimir Kondratyev close(fd); 71*7f32f0e2SVladimir Kondratyev return (0); 72*7f32f0e2SVladimir Kondratyev } 73*7f32f0e2SVladimir Kondratyev 74*7f32f0e2SVladimir Kondratyev i = 0; 75*7f32f0e2SVladimir Kondratyev /* XXX handle partial reads */ 76*7f32f0e2SVladimir Kondratyev r = read(fd, buf, sb.st_size); 77*7f32f0e2SVladimir Kondratyev if (r < 0) { 78*7f32f0e2SVladimir Kondratyev warn("%s: read", __func__); 79*7f32f0e2SVladimir Kondratyev free(buf); 80*7f32f0e2SVladimir Kondratyev close(fd); 81*7f32f0e2SVladimir Kondratyev return (0); 82*7f32f0e2SVladimir Kondratyev } 83*7f32f0e2SVladimir Kondratyev 84*7f32f0e2SVladimir Kondratyev if (r != sb.st_size) { 85*7f32f0e2SVladimir Kondratyev iwmbt_err("read len %d != file size %d", 86*7f32f0e2SVladimir Kondratyev (int) r, 87*7f32f0e2SVladimir Kondratyev (int) sb.st_size); 88*7f32f0e2SVladimir Kondratyev free(buf); 89*7f32f0e2SVladimir Kondratyev close(fd); 90*7f32f0e2SVladimir Kondratyev return (0); 91*7f32f0e2SVladimir Kondratyev } 92*7f32f0e2SVladimir Kondratyev 93*7f32f0e2SVladimir Kondratyev /* We have everything, so! */ 94*7f32f0e2SVladimir Kondratyev 95*7f32f0e2SVladimir Kondratyev memset(fw, 0, sizeof(*fw)); 96*7f32f0e2SVladimir Kondratyev 97*7f32f0e2SVladimir Kondratyev fw->fwname = strdup(fwname); 98*7f32f0e2SVladimir Kondratyev fw->len = sb.st_size; 99*7f32f0e2SVladimir Kondratyev fw->buf = buf; 100*7f32f0e2SVladimir Kondratyev 101*7f32f0e2SVladimir Kondratyev close(fd); 102*7f32f0e2SVladimir Kondratyev return (1); 103*7f32f0e2SVladimir Kondratyev } 104*7f32f0e2SVladimir Kondratyev 105*7f32f0e2SVladimir Kondratyev void 106*7f32f0e2SVladimir Kondratyev iwmbt_fw_free(struct iwmbt_firmware *fw) 107*7f32f0e2SVladimir Kondratyev { 108*7f32f0e2SVladimir Kondratyev if (fw->fwname) 109*7f32f0e2SVladimir Kondratyev free(fw->fwname); 110*7f32f0e2SVladimir Kondratyev if (fw->buf) 111*7f32f0e2SVladimir Kondratyev free(fw->buf); 112*7f32f0e2SVladimir Kondratyev memset(fw, 0, sizeof(*fw)); 113*7f32f0e2SVladimir Kondratyev } 114*7f32f0e2SVladimir Kondratyev 115*7f32f0e2SVladimir Kondratyev char * 116*7f32f0e2SVladimir Kondratyev iwmbt_get_fwname(struct iwmbt_version *ver, struct iwmbt_boot_params *params, 117*7f32f0e2SVladimir Kondratyev const char *prefix, const char *suffix) 118*7f32f0e2SVladimir Kondratyev { 119*7f32f0e2SVladimir Kondratyev char *fwname; 120*7f32f0e2SVladimir Kondratyev 121*7f32f0e2SVladimir Kondratyev switch (ver->hw_variant) { 122*7f32f0e2SVladimir Kondratyev case 0x0b: /* 8260 */ 123*7f32f0e2SVladimir Kondratyev case 0x0c: /* 8265 */ 124*7f32f0e2SVladimir Kondratyev asprintf(&fwname, "%s/ibt-%u-%u.%s", 125*7f32f0e2SVladimir Kondratyev prefix, 126*7f32f0e2SVladimir Kondratyev le16toh(ver->hw_variant), 127*7f32f0e2SVladimir Kondratyev le16toh(params->dev_revid), 128*7f32f0e2SVladimir Kondratyev suffix); 129*7f32f0e2SVladimir Kondratyev break; 130*7f32f0e2SVladimir Kondratyev 131*7f32f0e2SVladimir Kondratyev case 0x11: /* 9560 */ 132*7f32f0e2SVladimir Kondratyev case 0x12: /* 9260 */ 133*7f32f0e2SVladimir Kondratyev case 0x13: 134*7f32f0e2SVladimir Kondratyev case 0x14: /* 22161 */ 135*7f32f0e2SVladimir Kondratyev asprintf(&fwname, "%s/ibt-%u-%u-%u.%s", 136*7f32f0e2SVladimir Kondratyev prefix, 137*7f32f0e2SVladimir Kondratyev le16toh(ver->hw_variant), 138*7f32f0e2SVladimir Kondratyev le16toh(ver->hw_revision), 139*7f32f0e2SVladimir Kondratyev le16toh(ver->fw_revision), 140*7f32f0e2SVladimir Kondratyev suffix); 141*7f32f0e2SVladimir Kondratyev break; 142*7f32f0e2SVladimir Kondratyev 143*7f32f0e2SVladimir Kondratyev default: 144*7f32f0e2SVladimir Kondratyev fwname = NULL; 145*7f32f0e2SVladimir Kondratyev } 146*7f32f0e2SVladimir Kondratyev 147*7f32f0e2SVladimir Kondratyev return (fwname); 148*7f32f0e2SVladimir Kondratyev } 149