summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2008-11-06 17:04:56 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2008-11-06 17:04:56 +0000
commitb9de2e0780d54b2847cd243373809c1de0f95d7a (patch)
treef8db6816a065d00fc3f7199da4148d1a0700ae12
parenta1ca4855cc4d69dd9ad707832b98d7830afdcbeb (diff)
The EEPROM is lying about antennas. Hardcode things based on the chip
ID which is also what the vendor driver happens to do. Fixes a firmware SYSASSERT on the 5100 when adding the broadcast node. Reported by Jean-Michel Bessot and Robert <robert at openbsd.pap.st>
-rw-r--r--sys/dev/pci/if_iwn.c49
1 files changed, 26 insertions, 23 deletions
diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c
index d307b9ddba0..28bf060a301 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.26 2008/11/03 17:19:54 damien Exp $ */
+/* $OpenBSD: if_iwn.c,v 1.27 2008/11/06 17:04:55 damien Exp $ */
/*-
* Copyright (c) 2007, 2008
@@ -508,16 +508,33 @@ iwn_hal_attach(struct iwn_softc *sc)
case IWN_HW_REV_TYPE_4965:
sc->sc_hal = &iwn4965_hal;
sc->critical_temp = IWN_CTOK(110);
+ sc->txantmsk = IWN_ANT_A | IWN_ANT_B;
+ sc->rxantmsk = IWN_ANT_ABC;
+ sc->ntxchains = 2;
+ sc->nrxchains = 3;
+ break;
+ case IWN_HW_REV_TYPE_5100:
+ sc->sc_hal = &iwn5000_hal;
+ sc->critical_temp = 110;
+ sc->txantmsk = IWN_ANT_B;
+ sc->rxantmsk = IWN_ANT_A | IWN_ANT_B;
+ sc->ntxchains = 1;
+ sc->nrxchains = 2;
break;
case IWN_HW_REV_TYPE_5150:
sc->sc_hal = &iwn5000_hal;
sc->critical_temp = IWN_CTOK(110);
+ sc->txantmsk = IWN_ANT_A;
+ sc->rxantmsk = IWN_ANT_A | IWN_ANT_B;
+ sc->ntxchains = 1;
+ sc->nrxchains = 2;
break;
- case IWN_HW_REV_TYPE_5100:
case IWN_HW_REV_TYPE_5300:
case IWN_HW_REV_TYPE_5350:
sc->sc_hal = &iwn5000_hal;
sc->critical_temp = 110;
+ sc->txantmsk = sc->rxantmsk = IWN_ANT_ABC;
+ sc->ntxchains = sc->nrxchains = 3;
break;
default:
printf(": adapter type %d not supported\n", sc->hw_type);
@@ -1133,19 +1150,6 @@ iwn_read_eeprom(struct iwn_softc *sc)
iwn_read_prom_data(sc, IWN_EEPROM_RFCFG, &val, 2);
sc->rfcfg = letoh16(val);
DPRINTF(("radio config=0x%04x\n", sc->rfcfg));
- sc->txantmsk = IWN_RFCFG_TXANTMSK(sc->rfcfg);
- sc->rxantmsk = IWN_RFCFG_RXANTMSK(sc->rfcfg);
- /* Count the number of TX and RX chains. */
- sc->ntxchains =
- ((sc->txantmsk >> 3) & 1) +
- ((sc->txantmsk >> 2) & 1) +
- ((sc->txantmsk >> 1) & 1) +
- ((sc->txantmsk >> 0) & 1);
- sc->nrxchains =
- ((sc->rxantmsk >> 3) & 1) +
- ((sc->rxantmsk >> 2) & 1) +
- ((sc->rxantmsk >> 1) & 1) +
- ((sc->rxantmsk >> 0) & 1);
/* Read MAC address. */
iwn_read_prom_data(sc, IWN_EEPROM_MAC, ic->ic_myaddr, 6);
@@ -2826,6 +2830,9 @@ iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni)
return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, 1);
}
+/*
+ * Broadcast node is used to send group-addressed and management frames.
+ */
int
iwn_add_broadcast_node(struct iwn_softc *sc, int async)
{
@@ -2842,21 +2849,17 @@ iwn_add_broadcast_node(struct iwn_softc *sc, int async)
if ((error = hal->add_node(sc, &node, async)) != 0)
return error;
- /*
- * Setup link quality for broadcast node. The broadcast node is
- * used to send group-addressed and management frames.
- */
+ /* Use the first valid TX antenna. */
+ txant = IWN_LSB(sc->txantmsk);
+
memset(&linkq, 0, sizeof linkq);
linkq.id = hal->broadcast_id;
- linkq.antmsk_1stream = IWN_ANT_B;
+ linkq.antmsk_1stream = txant;
linkq.antmsk_2stream = IWN_ANT_A | IWN_ANT_B;
linkq.ampdu_max = 64;
linkq.ampdu_threshold = 3;
linkq.ampdu_limit = htole16(4000); /* 4ms */
- /* Use the first valid TX antenna. */
- txant = IWN_LSB(sc->txantmsk);
-
/* Use lowest mandatory bit-rate. */
if (sc->sc_ic.ic_curmode != IEEE80211_MODE_11A) {
linkq.retry[0].rate = iwn_ridx_to_plcp[IWN_CCK1];