|Summary:||Since r318216 iwm firmware loading aborts with "unknown firmware section 512"|
|Component:||wireless||Assignee:||Bjoern A. Zeeb <bz>|
|Severity:||Affects Only Me||CC:||avos, bz, freebsd|
Description iz-rpi03 2017-05-31 12:09:23 UTC
After changing the wireless card in a laptop running 32 bit FreeBSD 12.0 into a Intel 7260 I get a firmware loading error. The kernel messages are # kldload if_iwm iwm0: <Intel(R) Dual Band Wireless AC 7260> mem 0xf69fe000-0xf69fffff irq 17 at device 0.0 on pci1 iwm0: iwm_read_firmware: unknown firmware section 512, abort iwm0: firmware parse error 22, section type 512 iwm0: iwm_read_firmware: failed 22 iwm0: Failed to start INIT ucode: 22 # Using the older, 16th, version of the firmware causes the same error message. So I think it is not firmware version related. Going back to r318215 fixes the firmware loading, while with r318216 the error shows up. The r318216 log message is related to iwm's firmware handling: [iwm] Sync iwm_read_firmware()'s loop to iwlwifi's code. Obtained from: dragonflybsd.git d1c10ccfcf2d6d2a664f17197add0b4f93333181 Regards Ralf
Comment 1 Mark Linimon 2017-05-31 17:57:34 UTC
Over to committer of r318215.
Comment 2 iz-rpi03 2017-07-10 06:58:16 UTC
Hi, this is error is caused because I am using a 32 bit kernel (and world). Booting the machine with a 64 bit kernel via USB stick and doing k"ldload if_iwm" is working fine. Booting the machine with a 32 bit kernel  shows the known error message. Both kernel have the same release. The used kernel are  FreeBSD-12.0-CURRENT-amd64-20170703-r320599-memstick.img  FreeBSD-12.0-CURRENT-i386-20170703-r320599-memstick.img Ralf
Comment 3 commit-hook 2019-01-15 22:32:05 UTC
A commit references this bug: Author: bz Date: Tue Jan 15 22:31:54 UTC 2019 New revision: 343065 URL: https://svnweb.freebsd.org/changeset/base/343065 Log: With the sync from Dragonfly BSD in r318216 a bug slipped in (also still present upstream it seems). The tlv variable was changed to a pointer but the advancement of the data pointer was left as sizeof(tlv). While the sizeof the (now) pointer equals the sizeof 2 x uint32_t (size of the struct) on 64bit platforms, on 32bit platforms the size of the advancement of the data pointer was wrong leading to firmware load issues. Correctly advance the data pointer by the size of the structure and not by the size of a pointer. PR: 219683 Submitted by: waddlesplash gamil.com (Haiku) on irc MFC after: 1 week Changes: head/sys/dev/iwm/if_iwm.c
Comment 4 iz-rpi03 2019-01-21 14:38:54 UTC
I can confirm that r343065 fixes the bug on the original hardware as reported. Thank you.
Comment 5 commit-hook 2019-04-08 18:15:50 UTC
A commit references this bug: Author: kevans Date: Mon Apr 8 18:15:11 UTC 2019 New revision: 346037 URL: https://svnweb.freebsd.org/changeset/base/346037 Log: MFC r343065, r343373-r343390, r343477 r343065: With the sync from Dragonfly BSD in r318216 a bug slipped in (also still present upstream it seems). The tlv variable was changed to a pointer but the advancement of the data pointer was left as sizeof(tlv). While the sizeof the (now) pointer equals the sizeof 2 x uint32_t (size of the struct) on 64bit platforms, on 32bit platforms the size of the advancement of the data pointer was wrong leading to firmware load issues. Correctly advance the data pointer by the size of the structure and not by the size of a pointer. r343373: if_iwm - Update firmware rs table, instead of indexing the table in tx cmds. * Rather than providing a non-zero index into the firmware RS table, we should always use index 0 and update the firmware RS table whenever our chosen tx rate for data-frames changes. * Send IWM_LQ_CMD updates when the tx rate gets updated by the net80211 rate control (which is after we tell the tx status to the net80211 rate-control in iwm_mvm_rx_tx_cmd_single()). * Disregard frames transferred with a different tx rate than the currently selected rate for the rate-control calculations. This way we avoid counting management frames (which are sent at a slow, and fixed rate), as well as frames we added to the tx queue just before a new IWM_LQ_CMD update took effect. r343374: if_iwm - The iwm_prepare_card_hw() in iwm_attach() is only needed on 8K hw. * Doing the iwm_prepare_card_hw() call in iwm_attach() only on Family 8000 hardware matches the code in Linux iwlwifi. * While there remove DEFAULT_MAX_TX_POWER definition which is unused, and has a value different from IWL_DEFAULT_MAX_TX_POWER in iwlwifi. r343375: 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. r343376: if_iwm - Check sc->sc_attached flag in suspend/resume callbacks. * There is (almost) nothing to do in suspend/resume if if_iwm has failed during initialization (e.g. because of firmware load failure) and was already uninitialized by iwm_detach_local(). r343377: iwm - Reduce gratuitous differences with Linux iwlwifi in struct naming. * Rename some structs and struct members for firmware handling. r343378: if_iwm - Update struct iwm_scan_results_notif. Remove old/unused definitions * Remove outdated notifications IWM_SCAN_ABORT_CMD, IWM_SCAN_START_NOTIFICATION and IWM_SCAN_RESULTS_NOTIFICATION. * Remove unused enum iwm_scan_complete_status. * Use the updated FW Api version 3 of struct iwm_scan_results_notif. * No functional change, since struct iwm_scan_results_notif is never accessed in iwm at the moment. Taken-From: Linux iwlwifi commits 1083fd7391e989be52022f0f338e9dadc048b063 and 75118fdb63496e4611ab50380499ddd62b9de69f. r343379: if_iwm - Configure the PCIe LTR, fix PCI express capability accesses. Taken-From: Linux iwlwifi r343380: if_iwm - Add firmware API definitions for TX power commands. * While there remove unused IWM_UCODE_TLV_CAPA_LMAC_UPLOAD definition, which isn't defined in iwlwifi. Taken-From: Linux iwlwifi r343381: iwm - Track firmware state better, and improve handling in iwm_newstate(). * This avoids firmware resets in all the cases in iwm_newstate(). Instead iwm_bring_down_firmware() is called, which tears down all the STA connection state, according to the sc->sc_firmware_state value. * Improve the behaviour of the LED blinking a bit, so it only blinks when there really is a wireless scan going on. * Print the newstate arg in debug output of iwm_newstate(), to help in debugging. This is inspired by the firmware state maintaining change in OpenBSD's iwm, by email@example.com (OpenBSD Git 0ddb056fb7370664b1d4b84392697cb17d1a414a). r343382: iwm - Avoid Tx watchdog timeout, when dropping a connection. r343383: iwm - Improve firmware Time Event handling. * This is a mix of the OpenBSD Git 7fd9664469d1b717a307eebd74aeececbd3c41cc change, and syncing with the Linux iwlwifi code. Taken-From: Linux iwlwifi, and OpenBSD r343384: iwm - Clear Time Event active state, when receiving End Notification. * This hopefully avoids some firmware panics, I was occasionally seeing, when iwm disconnects upon losing signal to an access point at some point. * This is synchronizing the if_iwm_time_event.c file a bit more from the corresponding Linux iwlwifi/mvm/time-event.c. Taken-From: Linux iwlwifi r343385: iwm - Always clear watchdog timer, when bringing down firmware state. r343386: if_iwm - Stop iwm_watchdog callout when idle. r343387: iwm - Fix race during detach, where a callout is left after driver is gone. r343388: iwm - Update alive response handling, add v4 and remove old versions. r343389: iwm - Remove unused REPLY_MAX Taken-From: Linux git e4eb275ac5cfe71686612d929a9829345b2a4ada r343390: iwm - Remove unused TX_CMD_NEXT_FRAME_* Taken-From: Linux git b1e06c65fb69c5e3fddcd91987561e225eaa9bfa r343477: Fix logic errors in iwm_pcie_load_firmware_chunk introduced in r314065. * There's no reason to have a while() loop here, because: - if msleep returns 0, that means we were woken up by the interrupt handler, and we are going to exit immediately as sc_fw_chunk_done will now be 1 (there is nothing else that sleeps on sc_fw.) - if msleep doesn't return 0 (i.e. it returned ETIMEDOUT) then we will exit immediately because of the if-test. So, just use a single msleep() and then check sc_fw_chunk_done as before. * The comment said we were sleeping for 5 seconds, but the msleep was only for 1. Before r314065, this was 1 second and so was the comment, and in that commit the comment was changed and the function call wasn't. Possibly fixes failures to initialize uCode on certain devices. PR: 219683 Changes: _U stable/12/ stable/12/sys/dev/iwm/if_iwm.c stable/12/sys/dev/iwm/if_iwm_config.h stable/12/sys/dev/iwm/if_iwm_debug.h stable/12/sys/dev/iwm/if_iwm_fw.c stable/12/sys/dev/iwm/if_iwm_fw.h stable/12/sys/dev/iwm/if_iwm_led.c stable/12/sys/dev/iwm/if_iwm_mac_ctxt.c stable/12/sys/dev/iwm/if_iwm_pcie_trans.c stable/12/sys/dev/iwm/if_iwm_phy_db.c stable/12/sys/dev/iwm/if_iwm_scan.c stable/12/sys/dev/iwm/if_iwm_sta.c stable/12/sys/dev/iwm/if_iwm_time_event.c stable/12/sys/dev/iwm/if_iwm_time_event.h stable/12/sys/dev/iwm/if_iwmreg.h stable/12/sys/dev/iwm/if_iwmvar.h