diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2021-07-07 08:52:55 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2021-07-07 08:52:55 +0000 |
commit | 404e4b6b410d59453c8f6c3ec92bd6b8834594ae (patch) | |
tree | e8b898eb8ee4435997f34669bf2e30908b3bc4bc /sys/dev/pci/if_iwm.c | |
parent | 02038dfd9b1a168394ad1778756e47c1758d4ab1 (diff) |
Parse CMD_VERSION TLV found in iwm(4) fw images and add iwm_lookup_cmd_ver().
It seems Intel saw a risk of eventually running out of firmware capability
support and API support flags, so yet another such mechanism was added.
If you want to know which variant of a command needs to be used there are
now at least three places to check for related information.
Diffstat (limited to 'sys/dev/pci/if_iwm.c')
-rw-r--r-- | sys/dev/pci/if_iwm.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c index c691f19b0e2..f7335e2fa8b 100644 --- a/sys/dev/pci/if_iwm.c +++ b/sys/dev/pci/if_iwm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwm.c,v 1.337 2021/07/07 08:32:00 stsp Exp $ */ +/* $OpenBSD: if_iwm.c,v 1.338 2021/07/07 08:52:54 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh <info@genua.de> @@ -549,6 +549,21 @@ int iwm_resume(struct iwm_softc *); void iwm_radiotap_attach(struct iwm_softc *); #endif +uint8_t +iwm_lookup_cmd_ver(struct iwm_softc *sc, uint8_t grp, uint8_t cmd) +{ + const struct iwm_fw_cmd_version *entry; + int i; + + for (i = 0; i < sc->n_cmd_versions; i++) { + entry = &sc->cmd_versions[i]; + if (entry->group == grp && entry->cmd == cmd) + return entry->cmd_ver; + } + + return IWM_FW_CMD_VER_UNKNOWN; +} + int iwm_is_mimo_ht_plcp(uint8_t ht_plcp) { @@ -680,6 +695,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) sc->sc_capaflags = 0; sc->sc_capa_n_scan_channels = IWM_DEFAULT_SCAN_CHANNELS; memset(sc->sc_enabled_capa, 0, sizeof(sc->sc_enabled_capa)); + sc->n_cmd_versions = 0; memset(sc->sc_fw_mcc, 0, sizeof(sc->sc_fw_mcc)); uhdr = (void *)fw->fw_rawdata; @@ -850,7 +866,23 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) break; } - case 48: /* undocumented TLV */ + case IWM_UCODE_TLV_CMD_VERSIONS: + if (tlv_len % sizeof(struct iwm_fw_cmd_version)) { + tlv_len /= sizeof(struct iwm_fw_cmd_version); + tlv_len *= sizeof(struct iwm_fw_cmd_version); + } + if (sc->n_cmd_versions != 0) { + err = EINVAL; + goto parse_out; + } + if (tlv_len > sizeof(sc->cmd_versions)) { + err = EINVAL; + goto parse_out; + } + memcpy(&sc->cmd_versions[0], tlv_data, tlv_len); + sc->n_cmd_versions = tlv_len / sizeof(struct iwm_fw_cmd_version); + break; + case IWM_UCODE_TLV_SDIO_ADMA_ADDR: case IWM_UCODE_TLV_FW_GSCAN_CAPA: /* ignore, not used by current driver */ |