diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2009-05-27 09:50:32 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2009-05-27 09:50:32 +0000 |
commit | ea385a31dd89cd5ff95c392d4ee23558f2664254 (patch) | |
tree | 27735cfbd4a01d047759488e467d1f303dcfe8a5 /sys/dev | |
parent | a211586afefef84c61a6b8dd42ae9b3d78852cb7 (diff) |
allow iwn(4) to coexist with Intel Active Management Technology (AMT)
which may use WLAN too. for Intel Centrino 2 vPro only.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_iwn.c | 48 | ||||
-rw-r--r-- | sys/dev/pci/if_iwnreg.h | 5 |
2 files changed, 48 insertions, 5 deletions
diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c index b878f846ac5..9d4e84b62ab 100644 --- a/sys/dev/pci/if_iwn.c +++ b/sys/dev/pci/if_iwn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwn.c,v 1.54 2009/05/20 16:31:50 damien Exp $ */ +/* $OpenBSD: if_iwn.c,v 1.55 2009/05/27 09:50:31 damien Exp $ */ /*- * Copyright (c) 2007-2009 Damien Bergamini <damien.bergamini@free.fr> @@ -238,6 +238,7 @@ void iwn_apm_stop_master(struct iwn_softc *); void iwn_apm_stop(struct iwn_softc *); int iwn4965_nic_config(struct iwn_softc *); int iwn5000_nic_config(struct iwn_softc *); +int iwn_hw_prepare(struct iwn_softc *); int iwn_hw_init(struct iwn_softc *); void iwn_hw_stop(struct iwn_softc *); int iwn_init(struct ifnet *); @@ -387,6 +388,11 @@ iwn_attach(struct device *parent, struct device *self, void *aux) if ((hal = iwn_hal_attach(sc)) == NULL) return; + if ((error = iwn_hw_prepare(sc)) != 0) { + printf(": hardware not ready\n"); + return; + } + /* Power ON adapter. */ if ((error = hal->apm_init(sc)) != 0) { printf(": could not power ON adapter\n"); @@ -815,7 +821,7 @@ int iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int count) { uint8_t *out = data; - uint32_t val; + uint32_t val, tmp; int ntries; for (; count > 0; count -= 2, addr++) { @@ -833,7 +839,7 @@ iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int count) } if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) { /* OTPROM, check for ECC errors. */ - uint32_t tmp = IWN_READ(sc, IWN_OTP_GP); + tmp = IWN_READ(sc, IWN_OTP_GP); if (tmp & IWN_OTP_GP_ECC_UNCORR_STTS) { printf("%s: OTPROM ECC error at 0x%x\n", sc->sc_dev.dv_xname, addr); @@ -1199,7 +1205,8 @@ iwn_read_eeprom(struct iwn_softc *sc) int error; /* Check whether adapter has an EEPROM or an OTPROM. */ - if (IWN_READ(sc, IWN_OTP_GP) & IWN_OTP_GP_DEV_SEL_OTP) + if (sc->hw_type >= IWN_HW_REV_TYPE_1000 && + (IWN_READ(sc, IWN_OTP_GP) & IWN_OTP_GP_DEV_SEL_OTP)) sc->sc_flags |= IWN_FLAG_HAS_OTPROM; DPRINTF(("%s found\n", (sc->sc_flags & IWN_FLAG_HAS_OTPROM) ? "OTPROM" : "EEPROM")); @@ -5053,6 +5060,34 @@ iwn5000_nic_config(struct iwn_softc *sc) return 0; } +/* + * Take NIC ownership over Intel Active Management Technology (AMT). + */ +int +iwn_hw_prepare(struct iwn_softc *sc) +{ + int ntries; + + IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_PREPARE); + for (ntries = 0; ntries < 15000; ntries++) { + if (!(IWN_READ(sc, IWN_HW_IF_CONFIG) & + IWN_HW_IF_CONFIG_PREPARE_DONE)) + break; + DELAY(10); + } + if (ntries == 15000) + return ETIMEDOUT; + + IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_NIC_READY); + for (ntries = 0; ntries < 5; ntries++) { + if (IWN_READ(sc, IWN_HW_IF_CONFIG) & + IWN_HW_IF_CONFIG_NIC_READY) + return 0; + DELAY(10); + } + return ETIMEDOUT; +} + int iwn_hw_init(struct iwn_softc *sc) { @@ -5192,6 +5227,11 @@ iwn_init(struct ifnet *ifp) struct ieee80211com *ic = &sc->sc_ic; int error; + if ((error = iwn_hw_prepare(sc)) != 0) { + printf("%s: hardware not ready\n", sc->sc_dev.dv_xname); + goto fail; + } + /* Check that the radio is not disabled by hardware switch. */ if (!(IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)) { printf("%s: radio is disabled by hardware switch\n", diff --git a/sys/dev/pci/if_iwnreg.h b/sys/dev/pci/if_iwnreg.h index b6d602a3693..8c1869e8e1a 100644 --- a/sys/dev/pci/if_iwnreg.h +++ b/sys/dev/pci/if_iwnreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwnreg.h,v 1.24 2009/05/24 18:51:11 damien Exp $ */ +/* $OpenBSD: if_iwnreg.h,v 1.25 2009/05/27 09:50:31 damien Exp $ */ /*- * Copyright (c) 2007, 2008 @@ -150,7 +150,10 @@ #define IWN_HW_IF_CONFIG_MAC_SI (1 << 8) #define IWN_HW_IF_CONFIG_RADIO_SI (1 << 9) #define IWN_HW_IF_CONFIG_EEPROM_LOCKED (1 << 21) +#define IWN_HW_IF_CONFIG_NIC_READY (1 << 22) #define IWN_HW_IF_CONFIG_HAP_WAKE_L1A (1 << 23) +#define IWN_HW_IF_CONFIG_PREPARE_DONE (1 << 25) +#define IWN_HW_IF_CONFIG_PREPARE (1 << 27) /* Possible flags for registers IWN_PRPH_RADDR/IWN_PRPH_WADDR. */ #define IWN_PRPH_DWORD ((sizeof (uint32_t) - 1) << 24) |