From owner-svn-src-all@freebsd.org Thu Jan 24 03:42:25 2019 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DC26914BFEC3; Thu, 24 Jan 2019 03:42:24 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 840BE75932; Thu, 24 Jan 2019 03:42:24 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 77ED622C12; Thu, 24 Jan 2019 03:42:24 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x0O3gOgp025417; Thu, 24 Jan 2019 03:42:24 GMT (envelope-from kevans@FreeBSD.org) Received: (from kevans@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x0O3gOp0025415; Thu, 24 Jan 2019 03:42:24 GMT (envelope-from kevans@FreeBSD.org) Message-Id: <201901240342.x0O3gOp0025415@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kevans set sender to kevans@FreeBSD.org using -f From: Kyle Evans Date: Thu, 24 Jan 2019 03:42:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r343375 - head/sys/dev/iwm X-SVN-Group: head X-SVN-Commit-Author: kevans X-SVN-Commit-Paths: head/sys/dev/iwm X-SVN-Commit-Revision: 343375 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 840BE75932 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.96 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.96)[-0.959,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-1.000,0] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 24 Jan 2019 03:42:25 -0000 Author: kevans Date: Thu Jan 24 03:42:23 2019 New Revision: 343375 URL: https://svnweb.freebsd.org/changeset/base/343375 Log: if_iwm - Move iwm_read_firmware() call into iwm_attach(). * We should load the firmware exactly once before the driver really initializes the hardware the first time, and unload it at detach time. There is no need to retrieve the firmware during execution of iwm_mvm_load_ucode_wait_alive(), we should make sure we already have the firmware data at hand before that. * The existing sc_preinit_hook code fails to deal with the case where if_iwm is loaded by the loader (or is statically linked) and the firmware needs to be loaded from disk. So we can just call iwm_read_firmware() from iwm_attach() directly. * A separate solution will have to be added to properly defer the firmware loading during bootup, until the necessary filesystem is mounted. Submitted by: Augustin Cavalier (Haiku) Obtained from: DragonFlyBSD (0104ee1f4cb6a2313c00c2526c6ae98d42e5041d) Modified: head/sys/dev/iwm/if_iwm.c head/sys/dev/iwm/if_iwmvar.h Modified: head/sys/dev/iwm/if_iwm.c ============================================================================== --- head/sys/dev/iwm/if_iwm.c Thu Jan 24 03:41:44 2019 (r343374) +++ head/sys/dev/iwm/if_iwm.c Thu Jan 24 03:42:23 2019 (r343375) @@ -245,7 +245,7 @@ static int iwm_firmware_store_section(struct iwm_softc const uint8_t *, size_t); static int iwm_set_default_calib(struct iwm_softc *, const void *); static void iwm_fw_info_free(struct iwm_fw_info *); -static int iwm_read_firmware(struct iwm_softc *, enum iwm_ucode_type); +static int iwm_read_firmware(struct iwm_softc *); static int iwm_alloc_fwmem(struct iwm_softc *); static int iwm_alloc_sched(struct iwm_softc *); static int iwm_alloc_kw(struct iwm_softc *); @@ -536,12 +536,11 @@ iwm_fw_info_free(struct iwm_fw_info *fw) { firmware_put(fw->fw_fp, FIRMWARE_UNLOAD); fw->fw_fp = NULL; - /* don't touch fw->fw_status */ memset(fw->fw_sects, 0, sizeof(fw->fw_sects)); } static int -iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) +iwm_read_firmware(struct iwm_softc *sc) { struct iwm_fw_info *fw = &sc->sc_fw; const struct iwm_tlv_ucode_header *uhdr; @@ -558,24 +557,11 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode int error = 0; size_t len; - if (fw->fw_status == IWM_FW_STATUS_DONE && - ucode_type != IWM_UCODE_INIT) - return 0; - - while (fw->fw_status == IWM_FW_STATUS_INPROGRESS) - msleep(&sc->sc_fw, &sc->sc_mtx, 0, "iwmfwp", 0); - fw->fw_status = IWM_FW_STATUS_INPROGRESS; - - if (fw->fw_fp != NULL) - iwm_fw_info_free(fw); - /* * Load firmware into driver memory. * fw_fp will be set. */ - IWM_UNLOCK(sc); fwp = firmware_get(sc->cfg->fw_name); - IWM_LOCK(sc); if (fwp == NULL) { device_printf(sc->sc_dev, "could not read firmware %s (error %d)\n", @@ -634,9 +620,8 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode case IWM_UCODE_TLV_PROBE_MAX_LEN: if (tlv_len != sizeof(uint32_t)) { device_printf(sc->sc_dev, - "%s: PROBE_MAX_LEN (%d) != sizeof(uint32_t)\n", - __func__, - (int) tlv_len); + "%s: PROBE_MAX_LEN (%u) != sizeof(uint32_t)\n", + __func__, tlv_len); error = EINVAL; goto parse_out; } @@ -655,9 +640,8 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode case IWM_UCODE_TLV_PAN: if (tlv_len) { device_printf(sc->sc_dev, - "%s: IWM_UCODE_TLV_PAN: tlv_len (%d) > 0\n", - __func__, - (int) tlv_len); + "%s: IWM_UCODE_TLV_PAN: tlv_len (%u) > 0\n", + __func__, tlv_len); error = EINVAL; goto parse_out; } @@ -666,17 +650,15 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode case IWM_UCODE_TLV_FLAGS: if (tlv_len < sizeof(uint32_t)) { device_printf(sc->sc_dev, - "%s: IWM_UCODE_TLV_FLAGS: tlv_len (%d) < sizeof(uint32_t)\n", - __func__, - (int) tlv_len); + "%s: IWM_UCODE_TLV_FLAGS: tlv_len (%u) < sizeof(uint32_t)\n", + __func__, tlv_len); error = EINVAL; goto parse_out; } if (tlv_len % sizeof(uint32_t)) { device_printf(sc->sc_dev, - "%s: IWM_UCODE_TLV_FLAGS: tlv_len (%d) %% sizeof(uint32_t)\n", - __func__, - (int) tlv_len); + "%s: IWM_UCODE_TLV_FLAGS: tlv_len (%u) %% sizeof(uint32_t)\n", + __func__, tlv_len); error = EINVAL; goto parse_out; } @@ -698,17 +680,15 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode tlv_data, tlv_len)) != 0) { device_printf(sc->sc_dev, "%s: iwm_store_cscheme(): returned %d\n", - __func__, - error); + __func__, error); goto parse_out; } break; case IWM_UCODE_TLV_NUM_OF_CPU: if (tlv_len != sizeof(uint32_t)) { device_printf(sc->sc_dev, - "%s: IWM_UCODE_TLV_NUM_OF_CPU: tlv_len (%d) != sizeof(uint32_t)\n", - __func__, - (int) tlv_len); + "%s: IWM_UCODE_TLV_NUM_OF_CPU: tlv_len (%u) != sizeof(uint32_t)\n", + __func__, tlv_len); error = EINVAL; goto parse_out; } @@ -733,8 +713,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode IWM_UCODE_REGULAR, tlv_data, tlv_len)) != 0) { device_printf(sc->sc_dev, "%s: IWM_UCODE_REGULAR: iwm_firmware_store_section() failed; %d\n", - __func__, - error); + __func__, error); goto parse_out; } break; @@ -743,8 +722,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode IWM_UCODE_INIT, tlv_data, tlv_len)) != 0) { device_printf(sc->sc_dev, "%s: IWM_UCODE_INIT: iwm_firmware_store_section() failed; %d\n", - __func__, - error); + __func__, error); goto parse_out; } break; @@ -753,26 +731,23 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode IWM_UCODE_WOWLAN, tlv_data, tlv_len)) != 0) { device_printf(sc->sc_dev, "%s: IWM_UCODE_WOWLAN: iwm_firmware_store_section() failed; %d\n", - __func__, - error); + __func__, error); goto parse_out; } break; case IWM_UCODE_TLV_DEF_CALIB: if (tlv_len != sizeof(struct iwm_tlv_calib_data)) { device_printf(sc->sc_dev, - "%s: IWM_UCODE_TLV_DEV_CALIB: tlv_len (%d) < sizeof(iwm_tlv_calib_data) (%d)\n", - __func__, - (int) tlv_len, - (int) sizeof(struct iwm_tlv_calib_data)); + "%s: IWM_UCODE_TLV_DEV_CALIB: tlv_len (%u) < sizeof(iwm_tlv_calib_data) (%zu)\n", + __func__, tlv_len, + sizeof(struct iwm_tlv_calib_data)); error = EINVAL; goto parse_out; } if ((error = iwm_set_default_calib(sc, tlv_data)) != 0) { device_printf(sc->sc_dev, "%s: iwm_set_default_calib() failed: %d\n", - __func__, - error); + __func__, error); goto parse_out; } break; @@ -780,9 +755,8 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode if (tlv_len != sizeof(uint32_t)) { error = EINVAL; device_printf(sc->sc_dev, - "%s: IWM_UCODE_TLV_PHY_SKU: tlv_len (%d) < sizeof(uint32_t)\n", - __func__, - (int) tlv_len); + "%s: IWM_UCODE_TLV_PHY_SKU: tlv_len (%u) < sizeof(uint32_t)\n", + __func__, tlv_len); goto parse_out; } sc->sc_fw.phy_config = @@ -907,12 +881,9 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode out: if (error) { - fw->fw_status = IWM_FW_STATUS_NONE; if (fw->fw_fp != NULL) iwm_fw_info_free(fw); - } else - fw->fw_status = IWM_FW_STATUS_DONE; - wakeup(&sc->sc_fw); + } return error; } @@ -2858,11 +2829,6 @@ iwm_mvm_load_ucode_wait_alive(struct iwm_softc *sc, int error; static const uint16_t alive_cmd[] = { IWM_MVM_ALIVE }; - if ((error = iwm_read_firmware(sc, ucode_type)) != 0) { - device_printf(sc->sc_dev, "iwm_read_firmware: failed %d\n", - error); - return error; - } fw = &sc->sc_fw.fw_sects[ucode_type]; sc->cur_ucode = ucode_type; sc->ucode_loaded = FALSE; @@ -5849,7 +5815,7 @@ iwm_attach(device_t dev) sc->sc_wantresp = -1; - /* Check device type */ + /* Match device id */ error = iwm_dev_check(dev); if (error != 0) goto fail; @@ -5987,18 +5953,30 @@ iwm_attach(device_t dev) /* Max RSSI */ sc->sc_max_rssi = IWM_MAX_DBM - IWM_MIN_DBM; - sc->sc_preinit_hook.ich_func = iwm_preinit; - sc->sc_preinit_hook.ich_arg = sc; - if (config_intrhook_establish(&sc->sc_preinit_hook) != 0) { - device_printf(dev, "config_intrhook_establish failed\n"); - goto fail; - } - #ifdef IWM_DEBUG SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "debug", CTLFLAG_RW, &sc->sc_debug, 0, "control debugging"); #endif + + error = iwm_read_firmware(sc); + if (error) { + goto fail; + } else if (sc->sc_fw.fw_fp == NULL) { + /* + * XXX Add a solution for properly deferring firmware load + * during bootup. + */ + goto fail; + } else { + sc->sc_preinit_hook.ich_func = iwm_preinit; + sc->sc_preinit_hook.ich_arg = sc; + if (config_intrhook_establish(&sc->sc_preinit_hook) != 0) { + device_printf(dev, + "config_intrhook_establish failed\n"); + goto fail; + } + } IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_TRACE, "<-%s\n", __func__); Modified: head/sys/dev/iwm/if_iwmvar.h ============================================================================== --- head/sys/dev/iwm/if_iwmvar.h Thu Jan 24 03:41:44 2019 (r343374) +++ head/sys/dev/iwm/if_iwmvar.h Thu Jan 24 03:42:23 2019 (r343375) @@ -139,15 +139,6 @@ struct iwm_tx_radiotap_header { #define IWM_UCODE_SECTION_MAX 16 -/* - * fw_status is used to determine if we've already parsed the firmware file - * - * In addition to the following, status < 0 ==> -error - */ -#define IWM_FW_STATUS_NONE 0 -#define IWM_FW_STATUS_INPROGRESS 1 -#define IWM_FW_STATUS_DONE 2 - /** * enum iwm_ucode_type * @@ -197,7 +188,6 @@ struct iwm_fw_desc { struct iwm_fw_info { const struct firmware *fw_fp; - int fw_status; struct iwm_fw_sects { struct iwm_fw_desc fw_sect[IWM_UCODE_SECTION_MAX];