summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_iwn.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/if_iwn.c')
-rw-r--r--sys/dev/pci/if_iwn.c114
1 files changed, 84 insertions, 30 deletions
diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c
index 6ab337672e4..75754651bba 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.46 2009/01/26 19:18:52 damien Exp $ */
+/* $OpenBSD: if_iwn.c,v 1.47 2009/02/15 08:58:22 damien Exp $ */
/*-
* Copyright (c) 2007, 2008
@@ -76,7 +76,17 @@ static const struct pci_matchid iwn_devices[] = {
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_WL_5300AGN_1 },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_WL_5300AGN_2 },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_WL_5350AGN_1 },
- { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_WL_5350AGN_2 }
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_WL_5350AGN_2 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_6000_1 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_6000_2 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_6000_3 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_6000_4 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_6050_1 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_6050_2 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_6050_3 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_6050_4 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_100_1 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_100_2 }
};
int iwn_match(struct device *, void *, void *);
@@ -190,14 +200,15 @@ int iwn_set_key(struct ieee80211com *, struct ieee80211_node *,
struct ieee80211_key *);
void iwn_delete_key(struct ieee80211com *, struct ieee80211_node *,
struct ieee80211_key *);
+#ifndef IEEE80211_NO_HT
int iwn_ampdu_rx_start(struct ieee80211com *,
- struct ieee80211_node *, uint8_t, uint16_t);
+ struct ieee80211_node *, uint8_t);
void iwn_ampdu_rx_stop(struct ieee80211com *,
- struct ieee80211_node *, uint8_t, uint16_t);
+ struct ieee80211_node *, uint8_t);
int iwn_ampdu_tx_start(struct ieee80211com *,
- struct ieee80211_node *, uint8_t, uint16_t);
+ struct ieee80211_node *, uint8_t);
void iwn_ampdu_tx_stop(struct ieee80211com *,
- struct ieee80211_node *, uint8_t, uint16_t);
+ struct ieee80211_node *, uint8_t);
void iwn4965_ampdu_tx_start(struct iwn_softc *,
struct ieee80211_node *, uint8_t, uint16_t);
void iwn4965_ampdu_tx_stop(struct iwn_softc *,
@@ -206,6 +217,7 @@ void iwn5000_ampdu_tx_start(struct iwn_softc *,
struct ieee80211_node *, uint8_t, uint16_t);
void iwn5000_ampdu_tx_stop(struct iwn_softc *,
uint8_t, uint16_t);
+#endif
int iwn5000_query_calibration(struct iwn_softc *);
int iwn5000_send_calibration(struct iwn_softc *);
int iwn4965_post_alive(struct iwn_softc *);
@@ -252,8 +264,10 @@ static const struct iwn_hal iwn4965_hal = {
iwn4965_set_gains,
iwn4965_add_node,
iwn4965_tx_done,
+#ifndef IEEE80211_NO_HT
iwn4965_ampdu_tx_start,
iwn4965_ampdu_tx_stop,
+#endif
&iwn4965_sensitivity_limits,
IWN4965_NTXQUEUES,
IWN4965_ID_BROADCAST,
@@ -279,8 +293,10 @@ static const struct iwn_hal iwn5000_hal = {
iwn5000_set_gains,
iwn5000_add_node,
iwn5000_tx_done,
+#ifndef IEEE80211_NO_HT
iwn5000_ampdu_tx_start,
iwn5000_ampdu_tx_stop,
+#endif
&iwn5000_sensitivity_limits,
IWN5000_NTXQUEUES,
IWN5000_ID_BROADCAST,
@@ -470,6 +486,12 @@ iwn_attach(struct device *parent, struct device *self, void *aux)
ic->ic_updateedca = iwn_updateedca;
ic->ic_set_key = iwn_set_key;
ic->ic_delete_key = iwn_delete_key;
+#ifndef IEEE80211_NO_HT
+ ic->ic_ampdu_rx_start = iwn_ampdu_rx_start;
+ ic->ic_ampdu_rx_stop = iwn_ampdu_rx_stop;
+ ic->ic_ampdu_tx_start = iwn_ampdu_tx_start;
+ ic->ic_ampdu_tx_stop = iwn_ampdu_tx_stop;
+#endif
/* Override 802.11 state transition machine. */
sc->sc_newstate = ic->ic_newstate;
@@ -541,6 +563,33 @@ iwn_hal_attach(struct iwn_softc *sc)
sc->txantmsk = sc->rxantmsk = IWN_ANT_ABC;
sc->ntxchains = sc->nrxchains = 3;
break;
+ case IWN_HW_REV_TYPE_100:
+ sc->sc_hal = &iwn5000_hal;
+ sc->fwname = "iwn-100";
+ sc->critical_temp = 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_6000:
+ sc->sc_hal = &iwn5000_hal;
+ sc->fwname = "iwn-6000";
+ sc->critical_temp = 110;
+ sc->txantmsk = IWN_ANT_ABC;
+ sc->rxantmsk = IWN_ANT_ABC;
+ sc->ntxchains = 3;
+ sc->nrxchains = 3;
+ break;
+ case IWN_HW_REV_TYPE_6050:
+ sc->sc_hal = &iwn5000_hal;
+ sc->fwname = "iwn-6050";
+ sc->critical_temp = 110;
+ sc->txantmsk = IWN_ANT_ABC;
+ sc->rxantmsk = IWN_ANT_ABC;
+ sc->ntxchains = 3;
+ sc->nrxchains = 3;
+ break;
default:
printf(": adapter type %d not supported\n", sc->hw_type);
return NULL;
@@ -3437,6 +3486,10 @@ iwn5000_init_gains(struct iwn_softc *sc)
{
struct iwn_phy_calib cmd;
+ if (sc->hw_type == IWN_HW_REV_TYPE_6000 ||
+ sc->hw_type == IWN_HW_REV_TYPE_6050)
+ return 0;
+
memset(&cmd, 0, sizeof cmd);
cmd.code = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
cmd.ngroups = 1;
@@ -3484,6 +3537,10 @@ iwn5000_set_gains(struct iwn_softc *sc)
struct iwn_phy_calib_gain cmd;
int i, delta;
+ if (sc->hw_type == IWN_HW_REV_TYPE_6000 ||
+ sc->hw_type == IWN_HW_REV_TYPE_6050)
+ return 0;
+
memset(&cmd, 0, sizeof cmd);
cmd.code = IWN5000_PHY_CALIB_NOISE_GAIN;
cmd.ngroups = 1;
@@ -4158,14 +4215,16 @@ iwn_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
(void)hal->add_node(sc, &node, 1);
}
+#ifndef IEEE80211_NO_HT
/*
- * This function is called by upper layer when a ADDBA request is received
+ * This function is called by upper layer when an ADDBA request is received
* from another STA and before the ADDBA response is sent.
*/
int
iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
- uint8_t tid, uint16_t ssn)
+ uint8_t tid)
{
+ struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
struct iwn_softc *sc = ic->ic_softc;
struct iwn_node *wn = (void *)ni;
struct iwn_node_info node;
@@ -4175,18 +4234,19 @@ iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
node.control = IWN_NODE_UPDATE;
node.flags = IWN_FLAG_SET_ADDBA;
node.addba_tid = tid;
- node.addba_ssn = htole16(ssn);
- DPRINTFN(2, ("ADDBA RA=%d TID=%d SSN=%d\n", wn->id, tid, ssn));
+ node.addba_ssn = htole16(ba->ba_winstart);
+ DPRINTFN(2, ("ADDBA RA=%d TID=%d SSN=%d\n", wn->id, tid,
+ ba->ba_winstart));
return sc->sc_hal->add_node(sc, &node, 1);
}
/*
* This function is called by upper layer on teardown of an HT-immediate
- * Block Ack (eg. uppon receipt of a DELBA frame.)
+ * Block Ack agreement (eg. uppon receipt of a DELBA frame.)
*/
void
iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
- uint8_t tid, uint16_t ssn)
+ uint8_t tid)
{
struct iwn_softc *sc = ic->ic_softc;
struct iwn_node *wn = (void *)ni;
@@ -4202,13 +4262,14 @@ iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
}
/*
- * This function is called by upper layer when a ADDBA response is received
+ * This function is called by upper layer when an ADDBA response is received
* from another STA.
*/
int
iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
- uint8_t tid, uint16_t ssn)
+ uint8_t tid)
{
+ struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
struct iwn_softc *sc = ic->ic_softc;
const struct iwn_hal *hal = sc->sc_hal;
struct iwn_node *wn = (void *)ni;
@@ -4228,20 +4289,21 @@ iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
if ((error = iwn_nic_lock(sc)) != 0)
return error;
- hal->ampdu_tx_start(sc, ni, tid, ssn);
+ hal->ampdu_tx_start(sc, ni, tid, ba->ba_winstart);
iwn_nic_unlock(sc);
return 0;
}
void
iwn_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
- uint8_t tid, uint16_t ssn)
+ uint8_t tid)
{
+ struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
struct iwn_softc *sc = ic->ic_softc;
if (iwn_nic_lock(sc) != 0)
return;
- sc->sc_hal->ampdu_tx_stop(sc, tid, ssn);
+ sc->sc_hal->ampdu_tx_stop(sc, tid, ba->ba_winstart);
iwn_nic_unlock(sc);
}
@@ -4364,6 +4426,7 @@ iwn5000_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
IWN5000_TXQ_STATUS_INACTIVE | iwn_tid2fifo[tid]);
}
+#endif /* !IEEE80211_NO_HT */
/*
* Query calibration tables from the initialization firmware. We do this
@@ -4873,7 +4936,10 @@ iwn5000_apm_init(struct iwn_softc *sc)
/* Enable HAP to move adapter from L1a to L0s. */
IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_HAP_WAKE_L1A);
- IWN_SETBITS(sc, IWN_ANA_PLL, IWN_ANA_PLL_INIT);
+
+ if (sc->hw_type != IWN_HW_REV_TYPE_6000 &&
+ sc->hw_type != IWN_HW_REV_TYPE_6050)
+ IWN_SETBITS(sc, IWN_ANA_PLL, IWN_ANA_PLL_INIT);
if ((error = iwn_clock_wait(sc)) != 0)
return error;
@@ -4919,18 +4985,6 @@ int
iwn4965_nic_config(struct iwn_softc *sc)
{
pcireg_t reg;
- uint8_t rev;
-
- reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_CLASS_REG);
- rev = PCI_REVISION(reg);
- if ((rev & 0x80) && (rev & 0x7f) < 8) {
- reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
- sc->sc_cap_off + PCI_PCIE_DCSR);
- /* Clear PCIe "Enable No Snoop" bit. */
- reg &= ~PCI_PCIE_DCSR_ENA_NO_SNOOP;
- pci_conf_write(sc->sc_pct, sc->sc_pcitag,
- sc->sc_cap_off + PCI_PCIE_DCSR, reg);
- }
/* Retrieve PCIe Active State Power Management (ASPM). */
reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,