diff options
-rw-r--r-- | sys/dev/pci/if_iwx.c | 53 | ||||
-rw-r--r-- | sys/dev/pci/if_iwxreg.h | 27 | ||||
-rw-r--r-- | sys/dev/pci/if_iwxvar.h | 6 |
3 files changed, 81 insertions, 5 deletions
diff --git a/sys/dev/pci/if_iwx.c b/sys/dev/pci/if_iwx.c index e1b0d95a939..2a76ad746c0 100644 --- a/sys/dev/pci/if_iwx.c +++ b/sys/dev/pci/if_iwx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwx.c,v 1.16 2020/05/26 11:58:33 stsp Exp $ */ +/* $OpenBSD: if_iwx.c,v 1.17 2020/05/26 11:59:48 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh <info@genua.de> @@ -409,6 +409,7 @@ void iwx_fill_sf_command(struct iwx_softc *, struct iwx_sf_cfg_cmd *, struct ieee80211_node *); int iwx_sf_config(struct iwx_softc *, int); int iwx_send_bt_init_conf(struct iwx_softc *); +int iwx_send_soc_conf(struct iwx_softc *); int iwx_send_update_mcc_cmd(struct iwx_softc *, const char *); int iwx_init_hw(struct iwx_softc *); int iwx_init(struct ifnet *); @@ -437,7 +438,6 @@ int iwx_resume(struct iwx_softc *); void iwx_radiotap_attach(struct iwx_softc *); #endif -#ifdef notyet uint8_t iwx_lookup_cmd_ver(struct iwx_softc *sc, uint8_t grp, uint8_t cmd) { @@ -452,7 +452,6 @@ iwx_lookup_cmd_ver(struct iwx_softc *sc, uint8_t grp, uint8_t cmd) return IWX_FW_CMD_VER_UNKNOWN; } -#endif int iwx_is_mimo_ht_plcp(uint8_t ht_plcp) @@ -6247,6 +6246,44 @@ iwx_send_bt_init_conf(struct iwx_softc *sc) } int +iwx_send_soc_conf(struct iwx_softc *sc) +{ + struct iwx_soc_configuration_cmd cmd; + int err; + uint32_t cmd_id, flags = 0; + + memset(&cmd, 0, sizeof(cmd)); + + /* + * In VER_1 of this command, the discrete value is considered + * an integer; In VER_2, it's a bitmask. Since we have only 2 + * values in VER_1, this is backwards-compatible with VER_2, + * as long as we don't set any other flag bits. + */ + if (!sc->sc_integrated) { /* VER_1 */ + flags = IWX_SOC_CONFIG_CMD_FLAGS_DISCRETE; + } else { /* VER_2 */ + uint8_t scan_cmd_ver; + if (sc->sc_ltr_delay != IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE) + flags |= (sc->sc_ltr_delay & + IWX_SOC_FLAGS_LTR_APPLY_DELAY_MASK); + scan_cmd_ver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, + IWX_SCAN_REQ_UMAC); + if (scan_cmd_ver >= 2 && sc->sc_low_latency_xtal) + flags |= IWX_SOC_CONFIG_CMD_FLAGS_LOW_LATENCY; + } + cmd.flags = htole32(flags); + + cmd.latency = htole32(sc->sc_xtal_latency); + + cmd_id = iwx_cmd_id(IWX_SOC_CONFIGURATION_CMD, IWX_SYSTEM_GROUP, 0); + err = iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd); + if (err) + printf("%s: failed to set soc latency: %d\n", DEVNAME(sc), err); + return err; +} + +int iwx_send_update_mcc_cmd(struct iwx_softc *sc, const char *alpha2) { struct iwx_mcc_update_cmd mcc_cmd; @@ -6338,6 +6375,10 @@ iwx_init_hw(struct iwx_softc *sc) return err; } + err = iwx_send_soc_conf(sc); + if (err) + return err; + err = iwx_send_dqa_cmd(sc); if (err) return err; @@ -7199,6 +7240,9 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *data, struct mbuf_list *ml) case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_DQA_ENABLE_CMD): break; + case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_SOC_CONFIGURATION_CMD): + break; + case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_INIT_EXTENDED_CFG_CMD): break; @@ -7665,6 +7709,9 @@ iwx_attach(struct device *parent, struct device *self, void *aux) sc->sc_fwdmasegsz = IWX_FWDMASEGSZ_8000; sc->sc_nvm_max_section_size = 32768; sc->sc_integrated = 1; + sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE; + sc->sc_low_latency_xtal = 0; + sc->sc_xtal_latency = 0; sc->sc_tx_with_siso_diversity = 0; break; default: diff --git a/sys/dev/pci/if_iwxreg.h b/sys/dev/pci/if_iwxreg.h index 9713622c83a..305adc568db 100644 --- a/sys/dev/pci/if_iwxreg.h +++ b/sys/dev/pci/if_iwxreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwxreg.h,v 1.5 2020/05/26 11:55:54 stsp Exp $ */ +/* $OpenBSD: if_iwxreg.h,v 1.6 2020/05/26 11:59:48 stsp Exp $ */ /*- * Based on BSD-licensed source modules in the Linux iwlwifi driver, @@ -1866,6 +1866,31 @@ struct iwx_alive_resp_v4 { struct iwx_umac_alive umac_data; } __packed; /* ALIVE_RES_API_S_VER_4 */ +#define IWX_SOC_CONFIG_CMD_FLAGS_DISCRETE (1 << 0) +#define IWX_SOC_CONFIG_CMD_FLAGS_LOW_LATENCY (1 << 1) + +#define IWX_SOC_FLAGS_LTR_APPLY_DELAY_MASK 0xc +#define IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE 0 +#define IWX_SOC_FLAGS_LTR_APPLY_DELAY_200 1 +#define IWX_SOC_FLAGS_LTR_APPLY_DELAY_2500 2 +#define IWX_SOC_FLAGS_LTR_APPLY_DELAY_1820 3 + +/** + * struct iwx_soc_configuration_cmd - Set device stabilization latency + * + * @flags: soc settings flags. In VER_1, we can only set the DISCRETE + * flag, because the FW treats the whole value as an integer. In + * VER_2, we can set the bits independently. + * @latency: time for SOC to ensure stable power & XTAL + */ +struct iwx_soc_configuration_cmd { + uint32_t flags; + uint32_t latency; +} __packed; /* + * SOC_CONFIGURATION_CMD_S_VER_1 (see description above) + * SOC_CONFIGURATION_CMD_S_VER_2 + */ + /** * commands driver may send before finishing init flow * @IWX_INIT_DEBUG_CFG: driver is going to send debug config command diff --git a/sys/dev/pci/if_iwxvar.h b/sys/dev/pci/if_iwxvar.h index 62f5c167399..27d4c353069 100644 --- a/sys/dev/pci/if_iwxvar.h +++ b/sys/dev/pci/if_iwxvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwxvar.h,v 1.4 2020/04/03 08:32:21 stsp Exp $ */ +/* $OpenBSD: if_iwxvar.h,v 1.5 2020/05/26 11:59:48 stsp Exp $ */ /* * Copyright (c) 2014 genua mbh <info@genua.de> @@ -496,6 +496,10 @@ struct iwx_softc { int sc_integrated; int sc_tx_with_siso_diversity; int sc_max_tfd_queue_size; + int sc_ltr_delay; + int sc_xtal_latency; + int sc_low_latency_xtal; + #if NBPFILTER > 0 caddr_t sc_drvbpf; |