summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-12-12 22:20:51 -0800
committerDavid S. Miller <davem@davemloft.net>2008-12-12 22:20:51 -0800
commit56bde885903bdb9d9531fd569096ec8c7a2d60ee (patch)
treedcb9428e525b3c57aea00706fa969805251de444
parenta7a81fc060f050ad4ba7f6ef5cdc583dad2f7b21 (diff)
parenta7b75207bd37cbbfa0b4ee7dbaf0dc6bafec8fea (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
-rw-r--r--drivers/net/wireless/ath5k/pcu.c4
-rw-r--r--drivers/net/wireless/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath9k/beacon.c97
-rw-r--r--drivers/net/wireless/ath9k/calib.c98
-rw-r--r--drivers/net/wireless/ath9k/core.h356
-rw-r--r--drivers/net/wireless/ath9k/debug.c102
-rw-r--r--drivers/net/wireless/ath9k/eeprom.c1826
-rw-r--r--drivers/net/wireless/ath9k/hw.c115
-rw-r--r--drivers/net/wireless/ath9k/hw.h140
-rw-r--r--drivers/net/wireless/ath9k/initvals.h1363
-rw-r--r--drivers/net/wireless/ath9k/mac.c5
-rw-r--r--drivers/net/wireless/ath9k/main.c80
-rw-r--r--drivers/net/wireless/ath9k/phy.h5
-rw-r--r--drivers/net/wireless/ath9k/rc.c18
-rw-r--r--drivers/net/wireless/ath9k/recv.c121
-rw-r--r--drivers/net/wireless/ath9k/reg.h109
-rw-r--r--drivers/net/wireless/ath9k/xmit.c141
-rw-r--r--drivers/net/wireless/b43legacy/debugfs.c2
-rw-r--r--drivers/net/wireless/b43legacy/phy.c6
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c28
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-commands.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-io.h20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c59
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c34
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h111
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h31
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c100
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c94
-rw-r--r--drivers/net/wireless/libertas/host.h1
-rw-r--r--drivers/net/wireless/libertas/main.c60
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c4
-rw-r--r--drivers/net/wireless/orinoco/airport.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco.c6
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c8
-rw-r--r--drivers/net/wireless/orinoco/spectrum_cs.c8
-rw-r--r--drivers/net/wireless/p54/p54common.c59
-rw-r--r--drivers/net/wireless/p54/p54pci.c7
-rw-r--r--drivers/net/wireless/p54/p54usb.c151
-rw-r--r--drivers/net/wireless/p54/p54usb.h1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187.h2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c124
-rw-r--r--include/linux/ieee80211.h2
-rw-r--r--include/linux/rfkill.h7
-rw-r--r--include/net/ieee80211.h5
-rw-r--r--include/net/mac80211.h32
-rw-r--r--net/mac80211/Makefile2
-rw-r--r--net/mac80211/cfg.c6
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/main.c26
-rw-r--r--net/mac80211/mlme.c10
-rw-r--r--net/mac80211/rx.c17
-rw-r--r--net/mac80211/tx.c1
-rw-r--r--net/mac80211/wext.c11
-rw-r--r--net/rfkill/rfkill.c83
-rw-r--r--net/wireless/Makefile2
-rw-r--r--net/wireless/nl80211.c40
98 files changed, 4514 insertions, 1501 deletions
diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c
index dabe42219e2..0cac05c6a9c 100644
--- a/drivers/net/wireless/ath5k/pcu.c
+++ b/drivers/net/wireless/ath5k/pcu.c
@@ -1099,9 +1099,9 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
if (ah->ah_combined_mic) {
key_v[0] = rxmic[0];
- key_v[1] = (txmic[0] >> 16) & 0xffff;
+ key_v[1] = cpu_to_le32(le32_to_cpu(txmic[0]) >> 16);
key_v[2] = rxmic[1];
- key_v[3] = txmic[0] & 0xffff;
+ key_v[3] = cpu_to_le32(le32_to_cpu(txmic[0]) & 0xffff);
key_v[4] = txmic[1];
} else {
key_v[0] = rxmic[0];
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
index 9520aa0898e..d2781350295 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -26,6 +26,7 @@
#define AR9160_DEVID_PCI 0x0027
#define AR9280_DEVID_PCI 0x0029
#define AR9280_DEVID_PCIE 0x002a
+#define AR9285_DEVID_PCIE 0x002b
#define AR5416_AR9100_DEVID 0x000b
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index 507299bf013..3ab0b43aaf9 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -26,7 +26,7 @@ static int ath_beaconq_config(struct ath_softc *sc)
struct ath_hal *ah = sc->sc_ah;
struct ath9k_tx_queue_info qi;
- ath9k_hw_get_txq_props(ah, sc->sc_bhalq, &qi);
+ ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
/* Always burst out beacon and CAB traffic. */
qi.tqi_aifs = 1;
@@ -34,17 +34,17 @@ static int ath_beaconq_config(struct ath_softc *sc)
qi.tqi_cwmax = 0;
} else {
/* Adhoc mode; important thing is to use 2x cwmin. */
- qi.tqi_aifs = sc->sc_beacon_qi.tqi_aifs;
- qi.tqi_cwmin = 2*sc->sc_beacon_qi.tqi_cwmin;
- qi.tqi_cwmax = sc->sc_beacon_qi.tqi_cwmax;
+ qi.tqi_aifs = sc->beacon.beacon_qi.tqi_aifs;
+ qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin;
+ qi.tqi_cwmax = sc->beacon.beacon_qi.tqi_cwmax;
}
- if (!ath9k_hw_set_txq_props(ah, sc->sc_bhalq, &qi)) {
+ if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
DPRINTF(sc, ATH_DBG_FATAL,
"unable to update h/w beacon queue parameters\n");
return 0;
} else {
- ath9k_hw_resettxqueue(ah, sc->sc_bhalq); /* push to h/w */
+ ath9k_hw_resettxqueue(ah, sc->beacon.beaconq); /* push to h/w */
return 1;
}
}
@@ -53,7 +53,7 @@ static void ath_bstuck_process(struct ath_softc *sc)
{
DPRINTF(sc, ATH_DBG_BEACON,
"stuck beacon; resetting (bmiss count %u)\n",
- sc->sc_bmisscount);
+ sc->beacon.bmisscnt);
ath_reset(sc, false);
}
@@ -96,7 +96,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
* SWBA's
* XXX assumes two antenna
*/
- antenna = ((sc->ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1);
+ antenna = ((sc->beacon.ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1);
}
ds->ds_data = bf->bf_buf_addr;
@@ -106,7 +106,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
* XXX everything at min xmit rate
*/
rix = 0;
- rt = sc->hw_rate_table[sc->sc_curmode];
+ rt = sc->cur_rate_table;
rate = rt->info[rix].ratecode;
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
rate |= rt->info[rix].short_preamble;
@@ -153,7 +153,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
ASSERT(vif);
avp = (void *)vif->drv_priv;
- cabq = sc->sc_cabq;
+ cabq = sc->beacon.cabq;
if (avp->av_bcbuf == NULL) {
DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n",
@@ -167,6 +167,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
pci_unmap_single(sc->pdev, bf->bf_dmacontext,
skb->len,
PCI_DMA_TODEVICE);
+ dev_kfree_skb_any(skb);
}
skb = ieee80211_beacon_get(sc->hw, vif);
@@ -181,9 +182,9 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
* TX frames)
*/
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- sc->seq_no += 0x10;
+ sc->tx.seq_no += 0x10;
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
- hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
+ hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
}
bf->bf_buf_addr = bf->bf_dmacontext =
@@ -269,10 +270,10 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
ath_beacon_setup(sc, avp, bf);
/* NB: caller is known to have already stopped tx dma */
- ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr);
- ath9k_hw_txstart(ah, sc->sc_bhalq);
+ ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
+ ath9k_hw_txstart(ah, sc->beacon.beaconq);
DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
- sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc);
+ sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
}
int ath_beaconq_setup(struct ath_hal *ah)
@@ -305,7 +306,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
if (!avp->av_bcbuf) {
/* Allocate beacon state for hostap/ibss. We know
* a buffer is available. */
- avp->av_bcbuf = list_first_entry(&sc->sc_bbuf,
+ avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf,
struct ath_buf, list);
list_del(&avp->av_bcbuf->list);
@@ -318,13 +319,13 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
*/
avp->av_bslot = 0;
for (slot = 0; slot < ATH_BCBUF; slot++)
- if (sc->sc_bslot[slot] == ATH_IF_ID_ANY) {
+ if (sc->beacon.bslot[slot] == ATH_IF_ID_ANY) {
/*
* XXX hack, space out slots to better
* deal with misses
*/
if (slot+1 < ATH_BCBUF &&
- sc->sc_bslot[slot+1] ==
+ sc->beacon.bslot[slot+1] ==
ATH_IF_ID_ANY) {
avp->av_bslot = slot+1;
break;
@@ -332,8 +333,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
avp->av_bslot = slot;
/* NB: keep looking for a double slot */
}
- BUG_ON(sc->sc_bslot[avp->av_bslot] != ATH_IF_ID_ANY);
- sc->sc_bslot[avp->av_bslot] = if_id;
+ BUG_ON(sc->beacon.bslot[avp->av_bslot] != ATH_IF_ID_ANY);
+ sc->beacon.bslot[avp->av_bslot] = if_id;
sc->sc_nbcnvaps++;
}
}
@@ -361,7 +362,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
}
tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
- sc->bc_tstamp = le64_to_cpu(tstamp);
+ sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
/*
* Calculate a TSF adjustment factor required for
@@ -421,7 +422,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
struct ath_buf *bf;
if (avp->av_bslot != -1) {
- sc->sc_bslot[avp->av_bslot] = ATH_IF_ID_ANY;
+ sc->beacon.bslot[avp->av_bslot] = ATH_IF_ID_ANY;
sc->sc_nbcnvaps--;
}
@@ -434,7 +435,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
}
- list_add_tail(&bf->list, &sc->sc_bbuf);
+ list_add_tail(&bf->list, &sc->beacon.bbuf);
avp->av_bcbuf = NULL;
}
@@ -468,18 +469,18 @@ void ath9k_beacon_tasklet(unsigned long data)
*
* FIXME: Clean up this mess !!
*/
- if (ath9k_hw_numtxpending(ah, sc->sc_bhalq) != 0) {
- sc->sc_bmisscount++;
+ if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
+ sc->beacon.bmisscnt++;
/* XXX: doth needs the chanchange IE countdown decremented.
* We should consider adding a mac80211 call to indicate
* a beacon miss so appropriate action could be taken
* (in that layer).
*/
- if (sc->sc_bmisscount < BSTUCK_THRESH) {
+ if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
if (sc->sc_flags & SC_OP_NO_RESET) {
DPRINTF(sc, ATH_DBG_BEACON,
"missed %u consecutive beacons\n",
- sc->sc_bmisscount);
+ sc->beacon.bmisscnt);
if (show_cycles) {
/*
* Display cycle counter stats from HW
@@ -498,11 +499,11 @@ void ath9k_beacon_tasklet(unsigned long data)
} else {
DPRINTF(sc, ATH_DBG_BEACON,
"missed %u consecutive beacons\n",
- sc->sc_bmisscount);
+ sc->beacon.bmisscnt);
}
- } else if (sc->sc_bmisscount >= BSTUCK_THRESH) {
+ } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
if (sc->sc_flags & SC_OP_NO_RESET) {
- if (sc->sc_bmisscount == BSTUCK_THRESH) {
+ if (sc->beacon.bmisscnt == BSTUCK_THRESH) {
DPRINTF(sc, ATH_DBG_BEACON,
"beacon is officially "
"stuck\n");
@@ -516,17 +517,17 @@ void ath9k_beacon_tasklet(unsigned long data)
return;
}
- if (sc->sc_bmisscount != 0) {
+ if (sc->beacon.bmisscnt != 0) {
if (sc->sc_flags & SC_OP_NO_RESET) {
DPRINTF(sc, ATH_DBG_BEACON,
"resume beacon xmit after %u misses\n",
- sc->sc_bmisscount);
+ sc->beacon.bmisscnt);
} else {
DPRINTF(sc, ATH_DBG_BEACON,
"resume beacon xmit after %u misses\n",
- sc->sc_bmisscount);
+ sc->beacon.bmisscnt);
}
- sc->sc_bmisscount = 0;
+ sc->beacon.bmisscnt = 0;
}
/*
@@ -541,7 +542,7 @@ void ath9k_beacon_tasklet(unsigned long data)
tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU(tsf>>32, tsf);
slot = ((tsftu % intval) * ATH_BCBUF) / intval;
- if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF];
+ if_id = sc->beacon.bslot[(slot + 1) % ATH_BCBUF];
DPRINTF(sc, ATH_DBG_BEACON,
"slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
@@ -573,12 +574,12 @@ void ath9k_beacon_tasklet(unsigned long data)
* set to ATH_BCBUF so this check is a noop.
*/
/* XXX locking */
- if (sc->sc_updateslot == UPDATE) {
- sc->sc_updateslot = COMMIT; /* commit next beacon */
- sc->sc_slotupdate = slot;
- } else if (sc->sc_updateslot == COMMIT && sc->sc_slotupdate == slot) {
- ath9k_hw_setslottime(sc->sc_ah, sc->sc_slottime);
- sc->sc_updateslot = OK;
+ if (sc->beacon.updateslot == UPDATE) {
+ sc->beacon.updateslot = COMMIT; /* commit next beacon */
+ sc->beacon.slotupdate = slot;
+ } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
+ ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime);
+ sc->beacon.updateslot = OK;
}
if (bfaddr != 0) {
/*
@@ -586,17 +587,17 @@ void ath9k_beacon_tasklet(unsigned long data)
* This should never fail since we check above that no frames
* are still pending on the queue.
*/
- if (!ath9k_hw_stoptxdma(ah, sc->sc_bhalq)) {
+ if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
DPRINTF(sc, ATH_DBG_FATAL,
- "beacon queue %u did not stop?\n", sc->sc_bhalq);
+ "beacon queue %u did not stop?\n", sc->beacon.beaconq);
/* NB: the HAL still stops DMA, so proceed */
}
/* NB: cabq traffic should already be queued and primed */
- ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bfaddr);
- ath9k_hw_txstart(ah, sc->sc_bhalq);
+ ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
+ ath9k_hw_txstart(ah, sc->beacon.beaconq);
- sc->ast_be_xmit += bc; /* XXX per-vap? */
+ sc->beacon.ast_be_xmit += bc; /* XXX per-vap? */
}
}
@@ -643,7 +644,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
/* extract tstamp from last beacon and convert to TU */
- nexttbtt = TSF_TO_TU(sc->bc_tstamp >> 32, sc->bc_tstamp);
+ nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
/* XXX conditionalize multi-bss support? */
if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
@@ -830,7 +831,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
ath_beaconq_config(sc);
}
ath9k_hw_beaconinit(ah, nexttbtt, intval);
- sc->sc_bmisscount = 0;
+ sc->beacon.bmisscnt = 0;
ath9k_hw_set_interrupts(ah, sc->sc_imask);
/*
* When using a self-linked beacon descriptor in
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c
index 51c8a3ce4e6..3c7454fc51b 100644
--- a/drivers/net/wireless/ath9k/calib.c
+++ b/drivers/net/wireless/ath9k/calib.c
@@ -818,6 +818,101 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
return true;
}
+static inline void ath9k_hw_9285_pa_cal(struct ath_hal *ah)
+{
+
+ u32 regVal;
+ int i, offset, offs_6_1, offs_0;
+ u32 ccomp_org, reg_field;
+ u32 regList[][2] = {
+ { 0x786c, 0 },
+ { 0x7854, 0 },
+ { 0x7820, 0 },
+ { 0x7824, 0 },
+ { 0x7868, 0 },
+ { 0x783c, 0 },
+ { 0x7838, 0 },
+ };
+
+ if (AR_SREV_9285_11(ah)) {
+ REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+ udelay(10);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(regList); i++)
+ regList[i][1] = REG_READ(ah, regList[i][0]);
+
+ regVal = REG_READ(ah, 0x7834);
+ regVal &= (~(0x1));
+ REG_WRITE(ah, 0x7834, regVal);
+ regVal = REG_READ(ah, 0x9808);
+ regVal |= (0x1 << 27);
+ REG_WRITE(ah, 0x9808, regVal);
+
+ REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
+ REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
+ REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
+ REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 1);
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
+ ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 7);
+
+ REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
+ udelay(30);
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
+
+ for (i = 6; i > 0; i--) {
+ regVal = REG_READ(ah, 0x7834);
+ regVal |= (1 << (19 + i));
+ REG_WRITE(ah, 0x7834, regVal);
+ udelay(1);
+ regVal = REG_READ(ah, 0x7834);
+ regVal &= (~(0x1 << (19 + i)));
+ reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
+ regVal |= (reg_field << (19 + i));
+ REG_WRITE(ah, 0x7834, regVal);
+ }
+
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
+ udelay(1);
+ reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
+ offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
+ offs_0 = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
+
+ offset = (offs_6_1<<1) | offs_0;
+ offset = offset - 0;
+ offs_6_1 = offset>>1;
+ offs_0 = offset & 1;
+
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
+
+ regVal = REG_READ(ah, 0x7834);
+ regVal |= 0x1;
+ REG_WRITE(ah, 0x7834, regVal);
+ regVal = REG_READ(ah, 0x9808);
+ regVal &= (~(0x1 << 27));
+ REG_WRITE(ah, 0x9808, regVal);
+
+ for (i = 0; i < ARRAY_SIZE(regList); i++)
+ REG_WRITE(ah, regList[i][0], regList[i][1]);
+
+ REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
+
+ if (AR_SREV_9285_11(ah))
+ REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
+
+}
+
bool ath9k_hw_init_cal(struct ath_hal *ah,
struct ath9k_channel *chan)
{
@@ -835,6 +930,9 @@ bool ath9k_hw_init_cal(struct ath_hal *ah,
return false;
}
+ if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
+ ath9k_hw_9285_pa_cal(ah);
+
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
REG_READ(ah, AR_PHY_AGC_CONTROL) |
AR_PHY_AGC_CONTROL_NF);
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index a500d177053..e38f0331cfd 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -61,7 +61,7 @@ struct ath_node;
#define TSF_TO_TU(_h,_l) \
((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
-#define ATH_TXQ_SETUP(sc, i) ((sc)->sc_txqsetup & (1<<i))
+#define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i))
static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@ -88,16 +88,66 @@ enum ATH_DEBUG {
#ifdef CONFIG_ATH9K_DEBUG
+/**
+ * struct ath_interrupt_stats - Contains statistics about interrupts
+ * @total: Total no. of interrupts generated so far
+ * @rxok: RX with no errors
+ * @rxeol: RX with no more RXDESC available
+ * @rxorn: RX FIFO overrun
+ * @txok: TX completed at the requested rate
+ * @txurn: TX FIFO underrun
+ * @mib: MIB regs reaching its threshold
+ * @rxphyerr: RX with phy errors
+ * @rx_keycache_miss: RX with key cache misses
+ * @swba: Software Beacon Alert
+ * @bmiss: Beacon Miss
+ * @bnr: Beacon Not Ready
+ * @cst: Carrier Sense TImeout
+ * @gtt: Global TX Timeout
+ * @tim: RX beacon TIM occurrence
+ * @cabend: RX End of CAB traffic
+ * @dtimsync: DTIM sync lossage
+ * @dtim: RX Beacon with DTIM
+ */
+struct ath_interrupt_stats {
+ u32 total;
+ u32 rxok;
+ u32 rxeol;
+ u32 rxorn;
+ u32 txok;
+ u32 txeol;
+ u32 txurn;
+ u32 mib;
+ u32 rxphyerr;
+ u32 rx_keycache_miss;
+ u32 swba;
+ u32 bmiss;
+ u32 bnr;
+ u32 cst;
+ u32 gtt;
+ u32 tim;
+ u32 cabend;
+ u32 dtimsync;
+ u32 dtim;
+};
+
+struct ath_stats {
+ struct ath_interrupt_stats istats;
+};
+
struct ath9k_debug {
int debug_mask;
struct dentry *debugfs_root;
struct dentry *debugfs_phy;
struct dentry *debugfs_dma;
+ struct dentry *debugfs_interrupt;
+ struct ath_stats stats;
};
void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
int ath9k_init_debug(struct ath_softc *sc);
void ath9k_exit_debug(struct ath_softc *sc);
+void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
#else
@@ -115,6 +165,11 @@ static inline void ath9k_exit_debug(struct ath_softc *sc)
{
}
+static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
+ enum ath9k_int status)
+{
+}
+
#endif /* CONFIG_ATH9K_DEBUG */
struct ath_config {
@@ -235,18 +290,9 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
/* RX / TX */
/***********/
-#define ATH_MAX_ANTENNA 3
-#define ATH_RXBUF 512
-#define WME_NUM_TID 16
-
-int ath_startrecv(struct ath_softc *sc);
-bool ath_stoprecv(struct ath_softc *sc);
-void ath_flushrecv(struct ath_softc *sc);
-u32 ath_calcrxfilter(struct ath_softc *sc);
-int ath_rx_init(struct ath_softc *sc, int nbufs);
-void ath_rx_cleanup(struct ath_softc *sc);
-int ath_rx_tasklet(struct ath_softc *sc, int flush);
-
+#define ATH_MAX_ANTENNA 3
+#define ATH_RXBUF 512
+#define WME_NUM_TID 16
#define ATH_TXBUF 512
#define ATH_TXMAXTRY 13
#define ATH_11N_TXMAXTRY 10
@@ -254,19 +300,61 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush);
#define WME_BA_BMP_SIZE 64
#define WME_MAX_BA WME_BA_BMP_SIZE
#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
+
#define TID_TO_WME_AC(_tid) \
((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
(((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
(((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
WME_AC_VO)
-
#define WME_AC_BE 0
#define WME_AC_BK 1
#define WME_AC_VI 2
#define WME_AC_VO 3
#define WME_NUM_AC 4
+#define ADDBA_EXCHANGE_ATTEMPTS 10
+#define ATH_AGGR_DELIM_SZ 4
+#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
+/* number of delimiters for encryption padding */
+#define ATH_AGGR_ENCRYPTDELIM 10
+/* minimum h/w qdepth to be sustained to maximize aggregation */
+#define ATH_AGGR_MIN_QDEPTH 2
+#define ATH_AMPDU_SUBFRAME_DEFAULT 32
+#define IEEE80211_SEQ_SEQ_SHIFT 4
+#define IEEE80211_SEQ_MAX 4096
+#define IEEE80211_MIN_AMPDU_BUF 0x8
+#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
+
+/* return whether a bit at index _n in bitmap _bm is set
+ * _sz is the size of the bitmap */
+#define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \
+ ((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
+
+/* return block-ack bitmap index given sequence and starting sequence */
+#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
+
+/* returns delimiter padding required given the packet length */
+#define ATH_AGGR_GET_NDELIM(_len) \
+ (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \
+ (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
+
+#define BAW_WITHIN(_start, _bawsz, _seqno) \
+ ((((_seqno) - (_start)) & 4095) < (_bawsz))
+
+#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
+#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
+#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
+#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
+
+enum ATH_AGGR_STATUS {
+ ATH_AGGR_DONE,
+ ATH_AGGR_BAW_CLOSED,
+ ATH_AGGR_LIMITED,
+ ATH_AGGR_SHORTPKT,
+ ATH_AGGR_8K_LIMITED,
+};
+
struct ath_txq {
u32 axq_qnum; /* hardware q number */
u32 *axq_link; /* link ptr in last TX desc */
@@ -276,7 +364,6 @@ struct ath_txq {
u32 axq_depth; /* queue depth */
u8 axq_aggr_depth; /* aggregates queued */
u32 axq_totalqueued; /* total ever queued */
-
bool stopped; /* Is mac80211 queue stopped ? */
struct ath_buf *axq_linkbuf; /* virtual addr of last buffer*/
@@ -322,12 +409,6 @@ struct ath_atx_ac {
struct list_head tid_q; /* queue of TIDs with buffers */
};
-/* per dest tx state */
-struct ath_atx {
- struct ath_atx_tid tid[WME_NUM_TID];
- struct ath_atx_ac ac[WME_NUM_AC];
-};
-
/* per-frame tx control block */
struct ath_tx_control {
struct ath_txq *txq;
@@ -353,13 +434,54 @@ struct ath_tx_stat {
int rateKbps;
int ratecode;
int flags;
-/* if any of ctl,extn chain rssis are valid */
-#define ATH_TX_CHAIN_RSSI_VALID 0x01
-/* if extn chain rssis are valid */
-#define ATH_TX_RSSI_EXTN_VALID 0x02
u32 airtime; /* time on air per final tx rate */
};
+struct aggr_rifs_param {
+ int param_max_frames;
+ int param_max_len;
+ int param_rl;
+ int param_al;
+ struct ath_rc_series *param_rcs;
+};
+
+struct ath_node {
+ struct ath_softc *an_sc;
+ struct ath_atx_tid tid[WME_NUM_TID];
+ struct ath_atx_ac ac[WME_NUM_AC];
+ u16 maxampdu;
+ u8 mpdudensity;
+};
+
+struct ath_tx {
+ u16 seq_no;
+ u32 txqsetup;
+ int hwq_map[ATH9K_WME_AC_VO+1];
+ spinlock_t txbuflock;
+ struct list_head txbuf;
+ struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
+ struct ath_descdma txdma;
+};
+
+struct ath_rx {
+ u8 defant;
+ u8 rxotherant;
+ u32 *rxlink;
+ int bufsize;
+ unsigned int rxfilter;
+ spinlock_t rxflushlock;
+ spinlock_t rxbuflock;
+ struct list_head rxbuf;
+ struct ath_descdma rxdma;
+};
+
+int ath_startrecv(struct ath_softc *sc);
+bool ath_stoprecv(struct ath_softc *sc);
+void ath_flushrecv(struct ath_softc *sc);
+u32 ath_calcrxfilter(struct ath_softc *sc);
+int ath_rx_init(struct ath_softc *sc, int nbufs);
+void ath_rx_cleanup(struct ath_softc *sc);
+int ath_rx_tasklet(struct ath_softc *sc, int flush);
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
int ath_tx_setup(struct ath_softc *sc, int haltype);
@@ -382,73 +504,6 @@ void ath_tx_tasklet(struct ath_softc *sc);
u32 ath_txq_depth(struct ath_softc *sc, int qnum);
u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum);
void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
-
-/**********************/
-/* Node / Aggregation */
-/**********************/
-
-#define ADDBA_EXCHANGE_ATTEMPTS 10
-#define ATH_AGGR_DELIM_SZ 4
-#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
-/* number of delimiters for encryption padding */
-#define ATH_AGGR_ENCRYPTDELIM 10
-/* minimum h/w qdepth to be sustained to maximize aggregation */
-#define ATH_AGGR_MIN_QDEPTH 2
-#define ATH_AMPDU_SUBFRAME_DEFAULT 32
-#define IEEE80211_SEQ_SEQ_SHIFT 4
-#define IEEE80211_SEQ_MAX 4096
-#define IEEE80211_MIN_AMPDU_BUF 0x8
-#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
-
-/* return whether a bit at index _n in bitmap _bm is set
- * _sz is the size of the bitmap */
-#define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \
- ((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
-
-/* return block-ack bitmap index given sequence and starting sequence */
-#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
-
-/* returns delimiter padding required given the packet length */
-#define ATH_AGGR_GET_NDELIM(_len) \
- (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \
- (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
-
-#define BAW_WITHIN(_start, _bawsz, _seqno) \
- ((((_seqno) - (_start)) & 4095) < (_bawsz))
-
-#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
-#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
-#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
-#define ATH_AN_2_TID(_an, _tidno) (&(_an)->an_aggr.tx.tid[(_tidno)])
-
-enum ATH_AGGR_STATUS {
- ATH_AGGR_DONE,
- ATH_AGGR_BAW_CLOSED,
- ATH_AGGR_LIMITED,
- ATH_AGGR_SHORTPKT,
- ATH_AGGR_8K_LIMITED,
-};
-
-struct aggr_rifs_param {
- int param_max_frames;
- int param_max_len;
- int param_rl;
- int param_al;
- struct ath_rc_series *param_rcs;
-};
-
-/* Per-node aggregation state */
-struct ath_node_aggr {
- struct ath_atx tx;
-};
-
-struct ath_node {
- struct ath_softc *an_sc;
- struct ath_node_aggr an_aggr;
- u16 maxampdu;
- u8 mpdudensity;
-};
-
void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid);
bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tidno);
@@ -489,7 +544,7 @@ struct ath_vap {
* number of beacon intervals, the game's up.
*/
#define BSTUCK_THRESH (9 * ATH_BCBUF)
-#define ATH_BCBUF 4
+#define ATH_BCBUF 1
#define ATH_DEFAULT_BINTVAL 100 /* TU */
#define ATH_DEFAULT_BMISS_LIMIT 10
#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
@@ -507,6 +562,26 @@ struct ath_beacon_config {
} u; /* last received beacon/probe response timestamp of this BSS. */
};
+struct ath_beacon {
+ enum {
+ OK, /* no change needed */
+ UPDATE, /* update pending */
+ COMMIT /* beacon sent, commit change */
+ } updateslot; /* slot time update fsm */
+
+ u32 beaconq;
+ u32 bmisscnt;
+ u32 ast_be_xmit;
+ u64 bc_tstamp;
+ int bslot[ATH_BCBUF];
+ int slottime;
+ int slotupdate;
+ struct ath9k_tx_queue_info beacon_qi;
+ struct ath_descdma bdma;
+ struct ath_txq *cabq;
+ struct list_head bbuf;
+};
+
void ath9k_beacon_tasklet(unsigned long data);
void ath_beacon_config(struct ath_softc *sc, int if_id);
int ath_beaconq_setup(struct ath_hal *ah);
@@ -577,7 +652,7 @@ struct ath_rfkill {
#define DEFAULT_CACHELINE 32
#define ATH_DEFAULT_NOISE_FLOOR -95
#define ATH_REGCLASSIDS_MAX 10
-#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
+#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
#define ATH_MAX_SW_RETRIES 10
#define ATH_CHAN_MAX 255
#define IEEE80211_WEP_NKID 4 /* number of key ids */
@@ -590,7 +665,7 @@ struct ath_rfkill {
* Different parts have different size key caches. We handle
* up to ATH_KEYMAX entries (could dynamically allocate state).
*/
-#define ATH_KEYMAX 128 /* max key cache size we handle */
+#define ATH_KEYMAX 128 /* max key cache size we handle */
#define ATH_IF_ID_ANY 0xff
#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
@@ -623,108 +698,51 @@ struct ath_softc {
struct pci_dev *pdev;
struct tasklet_struct intr_tq;
struct tasklet_struct bcon_tasklet;
- struct ath_config sc_config;
struct ath_hal *sc_ah;
void __iomem *mem;
+ spinlock_t sc_resetlock;
u8 sc_curbssid[ETH_ALEN];
u8 sc_myaddr[ETH_ALEN];
u8 sc_bssidmask[ETH_ALEN];
-
-#ifdef CONFIG_ATH9K_DEBUG
- struct ath9k_debug sc_debug;
-#endif
u32 sc_intrstatus;
u32 sc_flags; /* SC_OP_* */
- unsigned int rx_filter;
u16 sc_curtxpow;
u16 sc_curaid;
u16 sc_cachelsz;
- int sc_slotupdate; /* slot to next advance fsm */
- int sc_slottime;
- int sc_bslot[ATH_BCBUF];
+ u8 sc_nbcnvaps;
+ u16 sc_nvaps;
u8 sc_tx_chainmask;
u8 sc_rx_chainmask;
+ u32 sc_keymax;
+ DECLARE_BITMAP(sc_keymap, ATH_KEYMAX);
+ u8 sc_splitmic;
+ u8 sc_protrix;
enum ath9k_int sc_imask;
- enum wireless_mode sc_curmode;
enum PROT_MODE sc_protmode;
-
- u8 sc_nbcnvaps;
- u16 sc_nvaps;
- struct ieee80211_vif *sc_vaps[ATH_BCBUF];
-
- u8 sc_mcastantenna;
- u8 sc_defant;
- u8 sc_rxotherant;
-
- struct ath9k_node_stats sc_halstats;
enum ath9k_ht_extprotspacing sc_ht_extprotspacing;
enum ath9k_ht_macmode tx_chan_width;
-#ifdef CONFIG_SLOW_ANT_DIV
- struct ath_antdiv sc_antdiv;
-#endif
- enum {
- OK, /* no change needed */
- UPDATE, /* update pending */
- COMMIT /* beacon sent, commit change */
- } sc_updateslot; /* slot time update fsm */
-
- /* Crypto */
- u32 sc_keymax;
- DECLARE_BITMAP(sc_keymap, ATH_KEYMAX);
- u8 sc_splitmic; /* split TKIP MIC keys */
-
- /* RX */
- struct list_head sc_rxbuf;
- struct ath_descdma sc_rxdma;
- int sc_rxbufsize;
- u32 *sc_rxlink;
-
- /* TX */
- struct list_head sc_txbuf;
- struct ath_txq sc_txq[ATH9K_NUM_TX_QUEUES];
- struct ath_descdma sc_txdma;
- u32 sc_txqsetup;
- int sc_haltype2q[ATH9K_WME_AC_VO+1];
- u16 seq_no; /* TX sequence number */
-
- /* Beacon */
- struct ath9k_tx_queue_info sc_beacon_qi;
- struct ath_descdma sc_bdma;
- struct ath_txq *sc_cabq;
- struct list_head sc_bbuf;
- u32 sc_bhalq;
- u32 sc_bmisscount;
- u32 ast_be_xmit;
- u64 bc_tstamp;
-
- /* Rate */
+ struct ath_config sc_config;
+ struct ath_rx rx;
+ struct ath_tx tx;
+ struct ath_beacon beacon;
+ struct ieee80211_vif *sc_vaps[ATH_BCBUF];
struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
- u8 sc_protrix;
-
- /* Channel, Band */
+ struct ath_rate_table *cur_rate_table;
struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX];
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
-
- /* Locks */
- spinlock_t sc_rxflushlock;
- spinlock_t sc_rxbuflock;
- spinlock_t sc_txbuflock;
- spinlock_t sc_resetlock;
-
- /* LEDs */
struct ath_led radio_led;
struct ath_led assoc_led;
struct ath_led tx_led;
struct ath_led rx_led;
-
- /* Rfkill */
struct ath_rfkill rf_kill;
-
- /* ANI */
struct ath_ani sc_ani;
+ struct ath9k_node_stats sc_halstats;
+#ifdef CONFIG_ATH9K_DEBUG
+ struct ath9k_debug sc_debug;
+#endif
};
int ath_reset(struct ath_softc *sc, bool retry_tx);
diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath9k/debug.c
index da52812c3a9..a80ed576830 100644
--- a/drivers/net/wireless/ath9k/debug.c
+++ b/drivers/net/wireless/ath9k/debug.c
@@ -128,6 +128,100 @@ static const struct file_operations fops_dma = {
.owner = THIS_MODULE
};
+
+void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
+{
+ if (status)
+ sc->sc_debug.stats.istats.total++;
+ if (status & ATH9K_INT_RX)
+ sc->sc_debug.stats.istats.rxok++;
+ if (status & ATH9K_INT_RXEOL)
+ sc->sc_debug.stats.istats.rxeol++;
+ if (status & ATH9K_INT_RXORN)
+ sc->sc_debug.stats.istats.rxorn++;
+ if (status & ATH9K_INT_TX)
+ sc->sc_debug.stats.istats.txok++;
+ if (status & ATH9K_INT_TXURN)
+ sc->sc_debug.stats.istats.txurn++;
+ if (status & ATH9K_INT_MIB)
+ sc->sc_debug.stats.istats.mib++;
+ if (status & ATH9K_INT_RXPHY)
+ sc->sc_debug.stats.istats.rxphyerr++;
+ if (status & ATH9K_INT_RXKCM)
+ sc->sc_debug.stats.istats.rx_keycache_miss++;
+ if (status & ATH9K_INT_SWBA)
+ sc->sc_debug.stats.istats.swba++;
+ if (status & ATH9K_INT_BMISS)
+ sc->sc_debug.stats.istats.bmiss++;
+ if (status & ATH9K_INT_BNR)
+ sc->sc_debug.stats.istats.bnr++;
+ if (status & ATH9K_INT_CST)
+ sc->sc_debug.stats.istats.cst++;
+ if (status & ATH9K_INT_GTT)
+ sc->sc_debug.stats.istats.gtt++;
+ if (status & ATH9K_INT_TIM)
+ sc->sc_debug.stats.istats.tim++;
+ if (status & ATH9K_INT_CABEND)
+ sc->sc_debug.stats.istats.cabend++;
+ if (status & ATH9K_INT_DTIMSYNC)
+ sc->sc_debug.stats.istats.dtimsync++;
+ if (status & ATH9K_INT_DTIM)
+ sc->sc_debug.stats.istats.dtim++;
+}
+
+static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ char buf[512];
+ unsigned int len = 0;
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "RX", sc->sc_debug.stats.istats.rxok);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "RXEOL", sc->sc_debug.stats.istats.rxeol);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "RXORN", sc->sc_debug.stats.istats.rxorn);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "TX", sc->sc_debug.stats.istats.txok);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "TXURN", sc->sc_debug.stats.istats.txurn);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "MIB", sc->sc_debug.stats.istats.mib);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "RXPHY", sc->sc_debug.stats.istats.rxphyerr);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "RXKCM", sc->sc_debug.stats.istats.rx_keycache_miss);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "SWBA", sc->sc_debug.stats.istats.swba);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "BMISS", sc->sc_debug.stats.istats.bmiss);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "BNR", sc->sc_debug.stats.istats.bnr);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "CST", sc->sc_debug.stats.istats.cst);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "GTT", sc->sc_debug.stats.istats.gtt);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "TIM", sc->sc_debug.stats.istats.tim);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "CABEND", sc->sc_debug.stats.istats.cabend);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "DTIMSYNC", sc->sc_debug.stats.istats.dtimsync);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "DTIM", sc->sc_debug.stats.istats.dtim);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%8s: %10u\n", "TOTAL", sc->sc_debug.stats.istats.total);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_interrupt = {
+ .read = read_file_interrupt,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE
+};
+
int ath9k_init_debug(struct ath_softc *sc)
{
sc->sc_debug.debug_mask = ath9k_debug;
@@ -146,6 +240,13 @@ int ath9k_init_debug(struct ath_softc *sc)
if (!sc->sc_debug.debugfs_dma)
goto err;
+ sc->sc_debug.debugfs_interrupt = debugfs_create_file("interrupt",
+ S_IRUGO,
+ sc->sc_debug.debugfs_phy,
+ sc, &fops_interrupt);
+ if (!sc->sc_debug.debugfs_interrupt)
+ goto err;
+
return 0;
err:
ath9k_exit_debug(sc);
@@ -154,6 +255,7 @@ err:
void ath9k_exit_debug(struct ath_softc *sc)
{
+ debugfs_remove(sc->sc_debug.debugfs_interrupt);
debugfs_remove(sc->sc_debug.debugfs_dma);
debugfs_remove(sc->sc_debug.debugfs_phy);
debugfs_remove(sc->sc_debug.debugfs_root);
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c
index e180c9043df..14f8d40c142 100644
--- a/drivers/net/wireless/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath9k/eeprom.c
@@ -140,61 +140,97 @@ static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, u32 off, u16 *data)
return ath9k_hw_eeprom_read(ah, off, data);
}
-static bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
+static bool ath9k_hw_fill_4k_eeprom(struct ath_hal *ah)
{
+#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom *eep = &ahp->ah_eeprom;
+ struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
u16 *eep_data;
- int addr, ar5416_eep_start_loc = 0;
+ int addr, eep_start_loc = 0;
+
+ eep_start_loc = 64;
if (!ath9k_hw_use_flash(ah)) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"Reading from EEPROM, not flash\n");
- ar5416_eep_start_loc = 256;
}
- if (AR_SREV_9100(ah))
- ar5416_eep_start_loc = 256;
+ eep_data = (u16 *)eep;
+
+ for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
+ if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Unable to read eeprom region \n");
+ return false;
+ }
+ eep_data++;
+ }
+ return true;
+#undef SIZE_EEPROM_4K
+}
+
+static bool ath9k_hw_fill_def_eeprom(struct ath_hal *ah)
+{
+#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
+ struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
+ u16 *eep_data;
+ int addr, ar5416_eep_start_loc = 0x100;
eep_data = (u16 *)eep;
- for (addr = 0; addr < sizeof(struct ar5416_eeprom) / sizeof(u16); addr++) {
+ for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
eep_data)) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Unable to read eeprom region \n");
+ "Unable to read eeprom region\n");
return false;
}
eep_data++;
}
return true;
+#undef SIZE_EEPROM_DEF
+}
+
+bool (*ath9k_fill_eeprom[]) (struct ath_hal *) = {
+ ath9k_hw_fill_def_eeprom,
+ ath9k_hw_fill_4k_eeprom
+};
+
+static inline bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
+
+ return ath9k_fill_eeprom[ahp->ah_eep_map](ah);
}
-static int ath9k_hw_check_eeprom(struct ath_hal *ah)
+static int ath9k_hw_check_def_eeprom(struct ath_hal *ah)
{
struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom *eep =
- (struct ar5416_eeprom *) &ahp->ah_eeprom;
+ struct ar5416_eeprom_def *eep =
+ (struct ar5416_eeprom_def *) &ahp->ah_eeprom.def;
u16 *eepdata, temp, magic, magic2;
u32 sum = 0, el;
bool need_swap = false;
int i, addr, size;
+ if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
+ &magic)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Reading Magic # failed\n");
+ return false;
+ }
+
if (!ath9k_hw_use_flash(ah)) {
- if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
- &magic)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Reading Magic # failed\n");
- return false;
- }
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "Read Magic = 0x%04X\n", magic);
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Read Magic = 0x%04X\n", magic);
if (magic != AR5416_EEPROM_MAGIC) {
magic2 = swab16(magic);
if (magic2 == AR5416_EEPROM_MAGIC) {
- size = sizeof(struct ar5416_eeprom);
+ size = sizeof(struct ar5416_eeprom_def);
need_swap = true;
eepdata = (u16 *) (&ahp->ah_eeprom);
@@ -223,12 +259,12 @@ static int ath9k_hw_check_eeprom(struct ath_hal *ah)
need_swap ? "True" : "False");
if (need_swap)
- el = swab16(ahp->ah_eeprom.baseEepHeader.length);
+ el = swab16(ahp->ah_eeprom.def.baseEepHeader.length);
else
- el = ahp->ah_eeprom.baseEepHeader.length;
+ el = ahp->ah_eeprom.def.baseEepHeader.length;
- if (el > sizeof(struct ar5416_eeprom))
- el = sizeof(struct ar5416_eeprom) / sizeof(u16);
+ if (el > sizeof(struct ar5416_eeprom_def))
+ el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
else
el = el / sizeof(u16);
@@ -297,6 +333,145 @@ static int ath9k_hw_check_eeprom(struct ath_hal *ah)
return 0;
}
+static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
+{
+#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
+ struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ar5416_eeprom_4k *eep =
+ (struct ar5416_eeprom_4k *) &ahp->ah_eeprom.map4k;
+ u16 *eepdata, temp, magic, magic2;
+ u32 sum = 0, el;
+ bool need_swap = false;
+ int i, addr;
+
+
+ if (!ath9k_hw_use_flash(ah)) {
+
+ if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
+ &magic)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Reading Magic # failed\n");
+ return false;
+ }
+
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Read Magic = 0x%04X\n", magic);
+
+ if (magic != AR5416_EEPROM_MAGIC) {
+ magic2 = swab16(magic);
+
+ if (magic2 == AR5416_EEPROM_MAGIC) {
+ need_swap = true;
+ eepdata = (u16 *) (&ahp->ah_eeprom);
+
+ for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
+ temp = swab16(*eepdata);
+ *eepdata = temp;
+ eepdata++;
+
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "0x%04X ", *eepdata);
+
+ if (((addr + 1) % 6) == 0)
+ DPRINTF(ah->ah_sc,
+ ATH_DBG_EEPROM, "\n");
+ }
+ } else {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Invalid EEPROM Magic. "
+ "endianness mismatch.\n");
+ return -EINVAL;
+ }
+ }
+ }
+
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
+ need_swap ? "True" : "False");
+
+ if (need_swap)
+ el = swab16(ahp->ah_eeprom.map4k.baseEepHeader.length);
+ else
+ el = ahp->ah_eeprom.map4k.baseEepHeader.length;
+
+ if (el > sizeof(struct ar5416_eeprom_def))
+ el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
+ else
+ el = el / sizeof(u16);
+
+ eepdata = (u16 *)(&ahp->ah_eeprom);
+
+ for (i = 0; i < el; i++)
+ sum ^= *eepdata++;
+
+ if (need_swap) {
+ u32 integer;
+ u16 word;
+
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "EEPROM Endianness is not native.. Changing \n");
+
+ word = swab16(eep->baseEepHeader.length);
+ eep->baseEepHeader.length = word;
+
+ word = swab16(eep->baseEepHeader.checksum);
+ eep->baseEepHeader.checksum = word;
+
+ word = swab16(eep->baseEepHeader.version);
+ eep->baseEepHeader.version = word;
+
+ word = swab16(eep->baseEepHeader.regDmn[0]);
+ eep->baseEepHeader.regDmn[0] = word;
+
+ word = swab16(eep->baseEepHeader.regDmn[1]);
+ eep->baseEepHeader.regDmn[1] = word;
+
+ word = swab16(eep->baseEepHeader.rfSilent);
+ eep->baseEepHeader.rfSilent = word;
+
+ word = swab16(eep->baseEepHeader.blueToothOptions);
+ eep->baseEepHeader.blueToothOptions = word;
+
+ word = swab16(eep->baseEepHeader.deviceCap);
+ eep->baseEepHeader.deviceCap = word;
+
+ integer = swab32(eep->modalHeader.antCtrlCommon);
+ eep->modalHeader.antCtrlCommon = integer;
+
+ for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+ integer = swab32(eep->modalHeader.antCtrlChain[i]);
+ eep->modalHeader.antCtrlChain[i] = integer;
+ }
+
+ for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+ word = swab16(eep->modalHeader.spurChans[i].spurChan);
+ eep->modalHeader.spurChans[i].spurChan = word;
+ }
+ }
+
+ if (sum != 0xffff || ar5416_get_eep4k_ver(ahp) != AR5416_EEP_VER ||
+ ar5416_get_eep4k_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+ sum, ar5416_get_eep4k_ver(ahp));
+ return -EINVAL;
+ }
+
+ return 0;
+#undef EEPROM_4K_SIZE
+}
+
+int (*ath9k_check_eeprom[]) (struct ath_hal *) = {
+ ath9k_hw_check_def_eeprom,
+ ath9k_hw_check_4k_eeprom
+};
+
+static inline int ath9k_hw_check_eeprom(struct ath_hal *ah)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
+
+ return ath9k_check_eeprom[ahp->ah_eep_map](ah);
+}
+
static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
u8 *pVpdList, u16 numIntercepts,
u8 *pRetVpdList)
@@ -326,7 +501,175 @@ static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
return true;
}
-static void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
+static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah,
+ struct ath9k_channel *chan,
+ struct cal_data_per_freq_4k *pRawDataSet,
+ u8 *bChans, u16 availPiers,
+ u16 tPdGainOverlap, int16_t *pMinCalPower,
+ u16 *pPdGainBoundaries, u8 *pPDADCValues,
+ u16 numXpdGains)
+{
+#define TMP_VAL_VPD_TABLE \
+ ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
+ int i, j, k;
+ int16_t ss;
+ u16 idxL = 0, idxR = 0, numPiers;
+ static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
+ [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+ static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
+ [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+ static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
+ [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+
+ u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+ u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
+ u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
+ int16_t vpdStep;
+ int16_t tmpVal;
+ u16 sizeCurrVpdTable, maxIndex, tgtIndex;
+ bool match;
+ int16_t minDelta = 0;
+ struct chan_centers centers;
+#define PD_GAIN_BOUNDARY_DEFAULT 58;
+
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+ for (numPiers = 0; numPiers < availPiers; numPiers++) {
+ if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
+ break;
+ }
+
+ match = ath9k_hw_get_lower_upper_index(
+ (u8)FREQ2FBIN(centers.synth_center,
+ IS_CHAN_2GHZ(chan)), bChans, numPiers,
+ &idxL, &idxR);
+
+ if (match) {
+ for (i = 0; i < numXpdGains; i++) {
+ minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
+ maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
+ ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+ pRawDataSet[idxL].pwrPdg[i],
+ pRawDataSet[idxL].vpdPdg[i],
+ AR5416_EEP4K_PD_GAIN_ICEPTS,
+ vpdTableI[i]);
+ }
+ } else {
+ for (i = 0; i < numXpdGains; i++) {
+ pVpdL = pRawDataSet[idxL].vpdPdg[i];
+ pPwrL = pRawDataSet[idxL].pwrPdg[i];
+ pVpdR = pRawDataSet[idxR].vpdPdg[i];
+ pPwrR = pRawDataSet[idxR].pwrPdg[i];
+
+ minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
+
+ maxPwrT4[i] =
+ min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1],
+ pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]);
+
+
+ ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+ pPwrL, pVpdL,
+ AR5416_EEP4K_PD_GAIN_ICEPTS,
+ vpdTableL[i]);
+ ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+ pPwrR, pVpdR,
+ AR5416_EEP4K_PD_GAIN_ICEPTS,
+ vpdTableR[i]);
+
+ for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
+ vpdTableI[i][j] =
+ (u8)(ath9k_hw_interpolate((u16)
+ FREQ2FBIN(centers.
+ synth_center,
+ IS_CHAN_2GHZ
+ (chan)),
+ bChans[idxL], bChans[idxR],
+ vpdTableL[i][j], vpdTableR[i][j]));
+ }
+ }
+ }
+
+ *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
+
+ k = 0;
+
+ for (i = 0; i < numXpdGains; i++) {
+ if (i == (numXpdGains - 1))
+ pPdGainBoundaries[i] =
+ (u16)(maxPwrT4[i] / 2);
+ else
+ pPdGainBoundaries[i] =
+ (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
+
+ pPdGainBoundaries[i] =
+ min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
+
+ if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
+ minDelta = pPdGainBoundaries[0] - 23;
+ pPdGainBoundaries[0] = 23;
+ } else {
+ minDelta = 0;
+ }
+
+ if (i == 0) {
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ ss = (int16_t)(0 - (minPwrT4[i] / 2));
+ else
+ ss = 0;
+ } else {
+ ss = (int16_t)((pPdGainBoundaries[i - 1] -
+ (minPwrT4[i] / 2)) -
+ tPdGainOverlap + 1 + minDelta);
+ }
+ vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
+ vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+ while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+ tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
+ pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
+ ss++;
+ }
+
+ sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+ tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
+ (minPwrT4[i] / 2));
+ maxIndex = (tgtIndex < sizeCurrVpdTable) ?
+ tgtIndex : sizeCurrVpdTable;
+
+ while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1)))
+ pPDADCValues[k++] = vpdTableI[i][ss++];
+
+ vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
+ vpdTableI[i][sizeCurrVpdTable - 2]);
+ vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+ if (tgtIndex > maxIndex) {
+ while ((ss <= tgtIndex) &&
+ (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+ tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
+ pPDADCValues[k++] = (u8)((tmpVal > 255) ?
+ 255 : tmpVal);
+ ss++;
+ }
+ }
+ }
+
+ while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) {
+ pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT;
+ i++;
+ }
+
+ while (k < AR5416_NUM_PDADC_VALUES) {
+ pPDADCValues[k] = pPDADCValues[k - 1];
+ k++;
+ }
+
+ return;
+#undef TMP_VAL_VPD_TABLE
+}
+
+static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hal *ah,
struct ath9k_channel *chan,
struct cal_data_per_freq *pRawDataSet,
u8 *bChans, u16 availPiers,
@@ -603,12 +946,12 @@ static void ath9k_hw_get_target_powers(struct ath_hal *ah,
static u16 ath9k_hw_get_max_edge_power(u16 freq,
struct cal_ctl_edges *pRdEdgesPower,
- bool is2GHz)
+ bool is2GHz, int num_band_edges)
{
u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
int i;
- for (i = 0; (i < AR5416_NUM_BAND_EDGES) &&
+ for (i = 0; (i < num_band_edges) &&
(pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
twiceMaxEdgePower = pRdEdgesPower[i].tPower;
@@ -629,207 +972,269 @@ static u16 ath9k_hw_get_max_edge_power(u16 freq,
return twiceMaxEdgePower;
}
-int ath9k_hw_set_txpower(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u16 cfgCtl,
- u8 twiceAntennaReduction,
- u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+static bool ath9k_hw_set_def_power_cal_table(struct ath_hal *ah,
+ struct ath9k_channel *chan,
+ int16_t *pTxPowerIndexOffset)
{
struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom *pEepData = &ahp->ah_eeprom;
- struct modal_eep_header *pModal =
- &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
- int16_t ratesArray[Ar5416RateSize];
- int16_t txPowerIndexOffset = 0;
- u8 ht40PowerIncForPdadc = 2;
- int i;
+ struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
+ struct cal_data_per_freq *pRawDataset;
+ u8 *pCalBChans = NULL;
+ u16 pdGainOverlap_t2;
+ static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+ u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+ u16 numPiers, i, j;
+ int16_t tMinCalPower;
+ u16 numXpdGain, xpdMask;
+ u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+ u32 reg32, regOffset, regChainOffset;
+ int16_t modalIdx;
- memset(ratesArray, 0, sizeof(ratesArray));
+ modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
+ xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
AR5416_EEP_MINOR_VER_2) {
- ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
- }
-
- if (!ath9k_hw_set_power_per_rate_table(ah, chan,
- &ratesArray[0], cfgCtl,
- twiceAntennaReduction,
- twiceMaxRegulatoryPower,
- powerLimit)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "ath9k_hw_set_txpower: unable to set "
- "tx power per rate table\n");
- return -EIO;
+ pdGainOverlap_t2 =
+ pEepData->modalHeader[modalIdx].pdGainOverlap;
+ } else {
+ pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
}
- if (!ath9k_hw_set_power_cal_table(ah, chan, &txPowerIndexOffset)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "ath9k_hw_set_txpower: unable to set power table\n");
- return -EIO;
+ if (IS_CHAN_2GHZ(chan)) {
+ pCalBChans = pEepData->calFreqPier2G;
+ numPiers = AR5416_NUM_2G_CAL_PIERS;
+ } else {
+ pCalBChans = pEepData->calFreqPier5G;
+ numPiers = AR5416_NUM_5G_CAL_PIERS;
}
- for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
- ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
- if (ratesArray[i] > AR5416_MAX_RATE_POWER)
- ratesArray[i] = AR5416_MAX_RATE_POWER;
- }
+ numXpdGain = 0;
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- for (i = 0; i < Ar5416RateSize; i++)
- ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+ for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+ if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+ if (numXpdGain >= AR5416_NUM_PD_GAINS)
+ break;
+ xpdGainValues[numXpdGain] =
+ (u16)(AR5416_PD_GAINS_IN_MASK - i);
+ numXpdGain++;
+ }
}
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
- ATH9K_POW_SM(ratesArray[rate18mb], 24)
- | ATH9K_POW_SM(ratesArray[rate12mb], 16)
- | ATH9K_POW_SM(ratesArray[rate9mb], 8)
- | ATH9K_POW_SM(ratesArray[rate6mb], 0));
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
- ATH9K_POW_SM(ratesArray[rate54mb], 24)
- | ATH9K_POW_SM(ratesArray[rate48mb], 16)
- | ATH9K_POW_SM(ratesArray[rate36mb], 8)
- | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+ (numXpdGain - 1) & 0x3);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+ xpdGainValues[0]);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+ xpdGainValues[1]);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+ xpdGainValues[2]);
- if (IS_CHAN_2GHZ(chan)) {
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
- ATH9K_POW_SM(ratesArray[rate2s], 24)
- | ATH9K_POW_SM(ratesArray[rate2l], 16)
- | ATH9K_POW_SM(ratesArray[rateXr], 8)
- | ATH9K_POW_SM(ratesArray[rate1l], 0));
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
- ATH9K_POW_SM(ratesArray[rate11s], 24)
- | ATH9K_POW_SM(ratesArray[rate11l], 16)
- | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
- | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
- }
+ for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+ if (AR_SREV_5416_V20_OR_LATER(ah) &&
+ (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
+ (i != 0)) {
+ regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+ } else
+ regChainOffset = i * 0x1000;
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
- ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
- | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
- | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
- | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
- ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
- | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
- | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
- | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+ if (pEepData->baseEepHeader.txMask & (1 << i)) {
+ if (IS_CHAN_2GHZ(chan))
+ pRawDataset = pEepData->calPierData2G[i];
+ else
+ pRawDataset = pEepData->calPierData5G[i];
- if (IS_CHAN_HT40(chan)) {
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
- ATH9K_POW_SM(ratesArray[rateHt40_3] +
- ht40PowerIncForPdadc, 24)
- | ATH9K_POW_SM(ratesArray[rateHt40_2] +
- ht40PowerIncForPdadc, 16)
- | ATH9K_POW_SM(ratesArray[rateHt40_1] +
- ht40PowerIncForPdadc, 8)
- | ATH9K_POW_SM(ratesArray[rateHt40_0] +
- ht40PowerIncForPdadc, 0));
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
- ATH9K_POW_SM(ratesArray[rateHt40_7] +
- ht40PowerIncForPdadc, 24)
- | ATH9K_POW_SM(ratesArray[rateHt40_6] +
- ht40PowerIncForPdadc, 16)
- | ATH9K_POW_SM(ratesArray[rateHt40_5] +
- ht40PowerIncForPdadc, 8)
- | ATH9K_POW_SM(ratesArray[rateHt40_4] +
- ht40PowerIncForPdadc, 0));
+ ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan,
+ pRawDataset, pCalBChans,
+ numPiers, pdGainOverlap_t2,
+ &tMinCalPower, gainBoundaries,
+ pdadcValues, numXpdGain);
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
- ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
- | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
- | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
- | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
- }
+ if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
+ REG_WRITE(ah,
+ AR_PHY_TPCRG5 + regChainOffset,
+ SM(pdGainOverlap_t2,
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
+ | SM(gainBoundaries[0],
+ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
+ | SM(gainBoundaries[1],
+ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
+ | SM(gainBoundaries[2],
+ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
+ | SM(gainBoundaries[3],
+ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
+ }
- REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
- ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
- | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
+ regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+ for (j = 0; j < 32; j++) {
+ reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
+ ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
+ ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
+ ((pdadcValues[4 * j + 3] & 0xFF) << 24);
+ REG_WRITE(ah, regOffset, reg32);
- i = rate6mb;
+ DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ "PDADC (%d,%4x): %4.4x %8.8x\n",
+ i, regChainOffset, regOffset,
+ reg32);
+ DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ "PDADC: Chain %d | PDADC %3d "
+ "Value %3d | PDADC %3d Value %3d | "
+ "PDADC %3d Value %3d | PDADC %3d "
+ "Value %3d |\n",
+ i, 4 * j, pdadcValues[4 * j],
+ 4 * j + 1, pdadcValues[4 * j + 1],
+ 4 * j + 2, pdadcValues[4 * j + 2],
+ 4 * j + 3,
+ pdadcValues[4 * j + 3]);
- if (IS_CHAN_HT40(chan))
- i = rateHt40_0;
- else if (IS_CHAN_HT20(chan))
- i = rateHt20_0;
+ regOffset += 4;
+ }
+ }
+ }
- if (AR_SREV_9280_10_OR_LATER(ah))
- ah->ah_maxPowerLevel =
- ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
- else
- ah->ah_maxPowerLevel = ratesArray[i];
+ *pTxPowerIndexOffset = 0;
- return 0;
+ return true;
}
-void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan)
+static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
+ struct ath9k_channel *chan,
+ int16_t *pTxPowerIndexOffset)
{
- struct modal_eep_header *pModal;
struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom *eep = &ahp->ah_eeprom;
- u8 biaslevel;
+ struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
+ struct cal_data_per_freq_4k *pRawDataset;
+ u8 *pCalBChans = NULL;
+ u16 pdGainOverlap_t2;
+ static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+ u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+ u16 numPiers, i, j;
+ int16_t tMinCalPower;
+ u16 numXpdGain, xpdMask;
+ u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+ u32 reg32, regOffset, regChainOffset;
- if (ah->ah_macVersion != AR_SREV_VERSION_9160)
- return;
+ xpdMask = pEepData->modalHeader.xpdGain;
- if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
- return;
+ if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_2) {
+ pdGainOverlap_t2 =
+ pEepData->modalHeader.pdGainOverlap;
+ } else {
+ pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+ }
- pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+ pCalBChans = pEepData->calFreqPier2G;
+ numPiers = AR5416_NUM_2G_CAL_PIERS;
- if (pModal->xpaBiasLvl != 0xff) {
- biaslevel = pModal->xpaBiasLvl;
- } else {
- u16 resetFreqBin, freqBin, freqCount = 0;
- struct chan_centers centers;
+ numXpdGain = 0;
- ath9k_hw_get_channel_centers(ah, chan, &centers);
+ for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+ if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+ if (numXpdGain >= AR5416_NUM_PD_GAINS)
+ break;
+ xpdGainValues[numXpdGain] =
+ (u16)(AR5416_PD_GAINS_IN_MASK - i);
+ numXpdGain++;
+ }
+ }
- resetFreqBin = FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
- freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
- biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+ (numXpdGain - 1) & 0x3);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+ xpdGainValues[0]);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+ xpdGainValues[1]);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+ xpdGainValues[2]);
- freqCount++;
+ for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+ if (AR_SREV_5416_V20_OR_LATER(ah) &&
+ (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
+ (i != 0)) {
+ regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+ } else
+ regChainOffset = i * 0x1000;
- while (freqCount < 3) {
- if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
- break;
+ if (pEepData->baseEepHeader.txMask & (1 << i)) {
+ pRawDataset = pEepData->calPierData2G[i];
- freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
- if (resetFreqBin >= freqBin) {
- biaslevel = (u8)(pModal->xpaBiasLvlFreq[freqCount] >> 14);
- } else {
- break;
+ ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan,
+ pRawDataset, pCalBChans,
+ numPiers, pdGainOverlap_t2,
+ &tMinCalPower, gainBoundaries,
+ pdadcValues, numXpdGain);
+
+ if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
+ REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
+ SM(pdGainOverlap_t2,
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
+ | SM(gainBoundaries[0],
+ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
+ | SM(gainBoundaries[1],
+ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
+ | SM(gainBoundaries[2],
+ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
+ | SM(gainBoundaries[3],
+ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
+ }
+
+ regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+ for (j = 0; j < 32; j++) {
+ reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
+ ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
+ ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
+ ((pdadcValues[4 * j + 3] & 0xFF) << 24);
+ REG_WRITE(ah, regOffset, reg32);
+
+ DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ "PDADC (%d,%4x): %4.4x %8.8x\n",
+ i, regChainOffset, regOffset,
+ reg32);
+ DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ "PDADC: Chain %d | "
+ "PDADC %3d Value %3d | "
+ "PDADC %3d Value %3d | "
+ "PDADC %3d Value %3d | "
+ "PDADC %3d Value %3d |\n",
+ i, 4 * j, pdadcValues[4 * j],
+ 4 * j + 1, pdadcValues[4 * j + 1],
+ 4 * j + 2, pdadcValues[4 * j + 2],
+ 4 * j + 3,
+ pdadcValues[4 * j + 3]);
+
+ regOffset += 4;
}
- freqCount++;
}
}
- if (IS_CHAN_2GHZ(chan)) {
- INI_RA(&ahp->ah_iniAddac, 7, 1) =
- (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
- } else {
- INI_RA(&ahp->ah_iniAddac, 6, 1) =
- (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel << 6;
- }
+ *pTxPowerIndexOffset = 0;
+
+ return true;
}
-bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
+bool ath9k_hw_set_def_power_per_rate_table(struct ath_hal *ah,
struct ath9k_channel *chan,
int16_t *ratesArray,
u16 cfgCtl,
- u8 AntennaReduction,
- u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+ u16 AntennaReduction,
+ u16 twiceMaxRegulatoryPower,
+ u16 powerLimit)
{
+#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
+#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
+
struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom *pEepData = &ahp->ah_eeprom;
- u8 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
+ u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
static const u16 tpScaleReductionTable[5] =
{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
int i;
- int8_t twiceLargestAntenna;
+ int16_t twiceLargestAntenna;
struct cal_ctl_data *rep;
struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
0, { 0, 0, 0, 0}
@@ -841,7 +1246,7 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
0, {0, 0, 0, 0}
};
- u8 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+ u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
u16 ctlModesFor11a[] =
{ CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
u16 ctlModesFor11g[] =
@@ -851,7 +1256,7 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
u16 numCtlModes, *pCtlMode, ctlMode, freq;
struct chan_centers centers;
int tx_chainmask;
- u8 twiceMinEdgePower;
+ u16 twiceMinEdgePower;
tx_chainmask = ahp->ah_txchainmask;
@@ -867,7 +1272,8 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
pEepData->modalHeader
[IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
- twiceLargestAntenna = (int8_t)min(AntennaReduction - twiceLargestAntenna, 0);
+ twiceLargestAntenna = (int16_t)min(AntennaReduction -
+ twiceLargestAntenna, 0);
maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
@@ -882,16 +1288,14 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
case 1:
break;
case 2:
- scaledPower -=
- pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pwrDecreaseFor2Chain;
+ scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
break;
case 3:
- scaledPower -=
- pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pwrDecreaseFor3Chain;
+ scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
break;
}
- scaledPower = max(0, (int32_t) scaledPower);
+ scaledPower = max((u16)0, scaledPower);
if (IS_CHAN_2GHZ(chan)) {
numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
@@ -990,7 +1394,7 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
- IS_CHAN_2GHZ(chan));
+ IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
" MATCH-EE_IDX %d: ch %d is2 %d "
@@ -1021,7 +1425,7 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
case CTL_11B:
for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
targetPowerCck.tPow2x[i] =
- min(targetPowerCck.tPow2x[i],
+ min((u16)targetPowerCck.tPow2x[i],
minCtlPower);
}
break;
@@ -1029,7 +1433,7 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
case CTL_11G:
for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
targetPowerOfdm.tPow2x[i] =
- min(targetPowerOfdm.tPow2x[i],
+ min((u16)targetPowerOfdm.tPow2x[i],
minCtlPower);
}
break;
@@ -1037,24 +1441,26 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
case CTL_2GHT20:
for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
targetPowerHt20.tPow2x[i] =
- min(targetPowerHt20.tPow2x[i],
+ min((u16)targetPowerHt20.tPow2x[i],
minCtlPower);
}
break;
case CTL_11B_EXT:
- targetPowerCckExt.tPow2x[0] =
- min(targetPowerCckExt.tPow2x[0], minCtlPower);
+ targetPowerCckExt.tPow2x[0] = min((u16)
+ targetPowerCckExt.tPow2x[0],
+ minCtlPower);
break;
case CTL_11A_EXT:
case CTL_11G_EXT:
- targetPowerOfdmExt.tPow2x[0] =
- min(targetPowerOfdmExt.tPow2x[0], minCtlPower);
+ targetPowerOfdmExt.tPow2x[0] = min((u16)
+ targetPowerOfdmExt.tPow2x[0],
+ minCtlPower);
break;
case CTL_5GHT40:
case CTL_2GHT40:
for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
targetPowerHt40.tPow2x[i] =
- min(targetPowerHt40.tPow2x[i],
+ min((u16)targetPowerHt40.tPow2x[i],
minCtlPower);
}
break;
@@ -1101,139 +1507,623 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
return true;
}
-bool ath9k_hw_set_power_cal_table(struct ath_hal *ah,
- struct ath9k_channel *chan,
- int16_t *pTxPowerIndexOffset)
+bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
+ struct ath9k_channel *chan,
+ int16_t *ratesArray,
+ u16 cfgCtl,
+ u16 AntennaReduction,
+ u16 twiceMaxRegulatoryPower,
+ u16 powerLimit)
{
struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom *pEepData = &ahp->ah_eeprom;
- struct cal_data_per_freq *pRawDataset;
- u8 *pCalBChans = NULL;
- u16 pdGainOverlap_t2;
- static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
- u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
- u16 numPiers, i, j;
- int16_t tMinCalPower;
- u16 numXpdGain, xpdMask;
- u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
- u32 reg32, regOffset, regChainOffset;
- int16_t modalIdx;
+ struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
+ u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ static const u16 tpScaleReductionTable[5] =
+ { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
- modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
- xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
+ int i;
+ int16_t twiceLargestAntenna;
+ struct cal_ctl_data_4k *rep;
+ struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+ 0, { 0, 0, 0, 0}
+ };
+ struct cal_target_power_leg targetPowerOfdmExt = {
+ 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
+ 0, { 0, 0, 0, 0 }
+ };
+ struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
+ 0, {0, 0, 0, 0}
+ };
+ u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+ u16 ctlModesFor11g[] =
+ { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
+ CTL_2GHT40
+ };
+ u16 numCtlModes, *pCtlMode, ctlMode, freq;
+ struct chan_centers centers;
+ int tx_chainmask;
+ u16 twiceMinEdgePower;
+
+ tx_chainmask = ahp->ah_txchainmask;
+
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+ twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
+
+ twiceLargestAntenna = (int16_t)min(AntennaReduction -
+ twiceLargestAntenna, 0);
+
+ maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+ if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
+ maxRegAllowedPower -=
+ (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
+ }
+
+ scaledPower = min(powerLimit, maxRegAllowedPower);
+ scaledPower = max((u16)0, scaledPower);
+
+ numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
+ pCtlMode = ctlModesFor11g;
+
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPowerCck,
+ AR5416_NUM_2G_CCK_TARGET_POWERS,
+ &targetPowerCck, 4, false);
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPower2G,
+ AR5416_NUM_2G_20_TARGET_POWERS,
+ &targetPowerOfdm, 4, false);
+ ath9k_hw_get_target_powers(ah, chan,
+ pEepData->calTargetPower2GHT20,
+ AR5416_NUM_2G_20_TARGET_POWERS,
+ &targetPowerHt20, 8, false);
+
+ if (IS_CHAN_HT40(chan)) {
+ numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+ ath9k_hw_get_target_powers(ah, chan,
+ pEepData->calTargetPower2GHT40,
+ AR5416_NUM_2G_40_TARGET_POWERS,
+ &targetPowerHt40, 8, true);
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPowerCck,
+ AR5416_NUM_2G_CCK_TARGET_POWERS,
+ &targetPowerCckExt, 4, true);
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPower2G,
+ AR5416_NUM_2G_20_TARGET_POWERS,
+ &targetPowerOfdmExt, 4, true);
+ }
+
+ for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+ bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+ (pCtlMode[ctlMode] == CTL_2GHT40);
+ if (isHt40CtlMode)
+ freq = centers.synth_center;
+ else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+ freq = centers.ext_center;
+ else
+ freq = centers.ctl_center;
+
+ if (ar5416_get_eep_ver(ahp) == 14 &&
+ ar5416_get_eep_rev(ahp) <= 2)
+ twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+
+ DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
+ "EXT_ADDITIVE %d\n",
+ ctlMode, numCtlModes, isHt40CtlMode,
+ (pCtlMode[ctlMode] & EXT_ADDITIVE));
+
+ for (i = 0; (i < AR5416_NUM_CTLS) &&
+ pEepData->ctlIndex[i]; i++) {
+ DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
+ "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
+ "chan %d\n",
+ i, cfgCtl, pCtlMode[ctlMode],
+ pEepData->ctlIndex[i], chan->channel);
+
+ if ((((cfgCtl & ~CTL_MODE_M) |
+ (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+ pEepData->ctlIndex[i]) ||
+ (((cfgCtl & ~CTL_MODE_M) |
+ (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+ ((pEepData->ctlIndex[i] & CTL_MODE_M) |
+ SD_NO_CTL))) {
+ rep = &(pEepData->ctlData[i]);
+
+ twiceMinEdgePower =
+ ath9k_hw_get_max_edge_power(freq,
+ rep->ctlEdges[ar5416_get_ntxchains
+ (tx_chainmask) - 1],
+ IS_CHAN_2GHZ(chan),
+ AR5416_EEP4K_NUM_BAND_EDGES);
+
+ DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ " MATCH-EE_IDX %d: ch %d is2 %d "
+ "2xMinEdge %d chainmask %d chains %d\n",
+ i, freq, IS_CHAN_2GHZ(chan),
+ twiceMinEdgePower, tx_chainmask,
+ ar5416_get_ntxchains
+ (tx_chainmask));
+ if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+ twiceMaxEdgePower =
+ min(twiceMaxEdgePower,
+ twiceMinEdgePower);
+ } else {
+ twiceMaxEdgePower = twiceMinEdgePower;
+ break;
+ }
+ }
+ }
+
+ minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
+
+ DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ " SEL-Min ctlMode %d pCtlMode %d "
+ "2xMaxEdge %d sP %d minCtlPwr %d\n",
+ ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
+ scaledPower, minCtlPower);
+
+ switch (pCtlMode[ctlMode]) {
+ case CTL_11B:
+ for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
+ i++) {
+ targetPowerCck.tPow2x[i] =
+ min((u16)targetPowerCck.tPow2x[i],
+ minCtlPower);
+ }
+ break;
+ case CTL_11G:
+ for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
+ i++) {
+ targetPowerOfdm.tPow2x[i] =
+ min((u16)targetPowerOfdm.tPow2x[i],
+ minCtlPower);
+ }
+ break;
+ case CTL_2GHT20:
+ for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
+ i++) {
+ targetPowerHt20.tPow2x[i] =
+ min((u16)targetPowerHt20.tPow2x[i],
+ minCtlPower);
+ }
+ break;
+ case CTL_11B_EXT:
+ targetPowerCckExt.tPow2x[0] = min((u16)
+ targetPowerCckExt.tPow2x[0],
+ minCtlPower);
+ break;
+ case CTL_11G_EXT:
+ targetPowerOfdmExt.tPow2x[0] = min((u16)
+ targetPowerOfdmExt.tPow2x[0],
+ minCtlPower);
+ break;
+ case CTL_2GHT40:
+ for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
+ i++) {
+ targetPowerHt40.tPow2x[i] =
+ min((u16)targetPowerHt40.tPow2x[i],
+ minCtlPower);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
+ ratesArray[rate18mb] = ratesArray[rate24mb] =
+ targetPowerOfdm.tPow2x[0];
+ ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+ ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+ ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+ ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+ for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+ ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+ ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+ ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
+ ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
+ ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
+
+ if (IS_CHAN_HT40(chan)) {
+ for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+ ratesArray[rateHt40_0 + i] =
+ targetPowerHt40.tPow2x[i];
+ }
+ ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+ ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
+ ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+ ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
+ }
+ return true;
+}
+
+static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
+ struct ath9k_channel *chan,
+ u16 cfgCtl,
+ u8 twiceAntennaReduction,
+ u8 twiceMaxRegulatoryPower,
+ u8 powerLimit)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
+ struct modal_eep_header *pModal =
+ &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
+ int16_t ratesArray[Ar5416RateSize];
+ int16_t txPowerIndexOffset = 0;
+ u8 ht40PowerIncForPdadc = 2;
+ int i;
+
+ memset(ratesArray, 0, sizeof(ratesArray));
if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
AR5416_EEP_MINOR_VER_2) {
- pdGainOverlap_t2 =
- pEepData->modalHeader[modalIdx].pdGainOverlap;
- } else {
- pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
- AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+ ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+ }
+
+ if (!ath9k_hw_set_def_power_per_rate_table(ah, chan,
+ &ratesArray[0], cfgCtl,
+ twiceAntennaReduction,
+ twiceMaxRegulatoryPower,
+ powerLimit)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "ath9k_hw_set_txpower: unable to set "
+ "tx power per rate table\n");
+ return -EIO;
+ }
+
+ if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "ath9k_hw_set_txpower: unable to set power table\n");
+ return -EIO;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+ ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
+ if (ratesArray[i] > AR5416_MAX_RATE_POWER)
+ ratesArray[i] = AR5416_MAX_RATE_POWER;
}
+ if (AR_SREV_9280_10_OR_LATER(ah)) {
+ for (i = 0; i < Ar5416RateSize; i++)
+ ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+ }
+
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
+ ATH9K_POW_SM(ratesArray[rate18mb], 24)
+ | ATH9K_POW_SM(ratesArray[rate12mb], 16)
+ | ATH9K_POW_SM(ratesArray[rate9mb], 8)
+ | ATH9K_POW_SM(ratesArray[rate6mb], 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+ ATH9K_POW_SM(ratesArray[rate54mb], 24)
+ | ATH9K_POW_SM(ratesArray[rate48mb], 16)
+ | ATH9K_POW_SM(ratesArray[rate36mb], 8)
+ | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
if (IS_CHAN_2GHZ(chan)) {
- pCalBChans = pEepData->calFreqPier2G;
- numPiers = AR5416_NUM_2G_CAL_PIERS;
- } else {
- pCalBChans = pEepData->calFreqPier5G;
- numPiers = AR5416_NUM_5G_CAL_PIERS;
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+ ATH9K_POW_SM(ratesArray[rate2s], 24)
+ | ATH9K_POW_SM(ratesArray[rate2l], 16)
+ | ATH9K_POW_SM(ratesArray[rateXr], 8)
+ | ATH9K_POW_SM(ratesArray[rate1l], 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+ ATH9K_POW_SM(ratesArray[rate11s], 24)
+ | ATH9K_POW_SM(ratesArray[rate11l], 16)
+ | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
+ | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
}
- numXpdGain = 0;
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+ ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
+ | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
+ | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
+ | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+ ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
+ | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
+ | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
+ | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
- for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
- if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
- if (numXpdGain >= AR5416_NUM_PD_GAINS)
- break;
- xpdGainValues[numXpdGain] =
- (u16)(AR5416_PD_GAINS_IN_MASK - i);
- numXpdGain++;
- }
+ if (IS_CHAN_HT40(chan)) {
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+ ATH9K_POW_SM(ratesArray[rateHt40_3] +
+ ht40PowerIncForPdadc, 24)
+ | ATH9K_POW_SM(ratesArray[rateHt40_2] +
+ ht40PowerIncForPdadc, 16)
+ | ATH9K_POW_SM(ratesArray[rateHt40_1] +
+ ht40PowerIncForPdadc, 8)
+ | ATH9K_POW_SM(ratesArray[rateHt40_0] +
+ ht40PowerIncForPdadc, 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+ ATH9K_POW_SM(ratesArray[rateHt40_7] +
+ ht40PowerIncForPdadc, 24)
+ | ATH9K_POW_SM(ratesArray[rateHt40_6] +
+ ht40PowerIncForPdadc, 16)
+ | ATH9K_POW_SM(ratesArray[rateHt40_5] +
+ ht40PowerIncForPdadc, 8)
+ | ATH9K_POW_SM(ratesArray[rateHt40_4] +
+ ht40PowerIncForPdadc, 0));
+
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+ ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+ | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
+ | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+ | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
}
- REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
- (numXpdGain - 1) & 0x3);
- REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
- xpdGainValues[0]);
- REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
- xpdGainValues[1]);
- REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
- xpdGainValues[2]);
+ REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
+ ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
+ | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
- for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- if (AR_SREV_5416_V20_OR_LATER(ah) &&
- (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
- (i != 0)) {
- regChainOffset = (i == 1) ? 0x2000 : 0x1000;
- } else
- regChainOffset = i * 0x1000;
+ i = rate6mb;
- if (pEepData->baseEepHeader.txMask & (1 << i)) {
- if (IS_CHAN_2GHZ(chan))
- pRawDataset = pEepData->calPierData2G[i];
- else
- pRawDataset = pEepData->calPierData5G[i];
+ if (IS_CHAN_HT40(chan))
+ i = rateHt40_0;
+ else if (IS_CHAN_HT20(chan))
+ i = rateHt20_0;
- ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
- pRawDataset, pCalBChans,
- numPiers, pdGainOverlap_t2,
- &tMinCalPower, gainBoundaries,
- pdadcValues, numXpdGain);
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ ah->ah_maxPowerLevel =
+ ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
+ else
+ ah->ah_maxPowerLevel = ratesArray[i];
- if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
- REG_WRITE(ah,
- AR_PHY_TPCRG5 + regChainOffset,
- SM(pdGainOverlap_t2,
- AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
- | SM(gainBoundaries[0],
- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
- | SM(gainBoundaries[1],
- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
- | SM(gainBoundaries[2],
- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
- | SM(gainBoundaries[3],
- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
- }
+ return 0;
+}
- regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
- for (j = 0; j < 32; j++) {
- reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
- ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
- ((pdadcValues[4 * j + 2] & 0xFF) << 16) |
- ((pdadcValues[4 * j + 3] & 0xFF) << 24);
- REG_WRITE(ah, regOffset, reg32);
+static int ath9k_hw_4k_set_txpower(struct ath_hal *ah,
+ struct ath9k_channel *chan,
+ u16 cfgCtl,
+ u8 twiceAntennaReduction,
+ u8 twiceMaxRegulatoryPower,
+ u8 powerLimit)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
+ struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
+ int16_t ratesArray[Ar5416RateSize];
+ int16_t txPowerIndexOffset = 0;
+ u8 ht40PowerIncForPdadc = 2;
+ int i;
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
- "PDADC (%d,%4x): %4.4x %8.8x\n",
- i, regChainOffset, regOffset,
- reg32);
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
- "PDADC: Chain %d | PDADC %3d Value %3d | "
- "PDADC %3d Value %3d | PDADC %3d Value %3d | "
- "PDADC %3d Value %3d |\n",
- i, 4 * j, pdadcValues[4 * j],
- 4 * j + 1, pdadcValues[4 * j + 1],
- 4 * j + 2, pdadcValues[4 * j + 2],
- 4 * j + 3,
- pdadcValues[4 * j + 3]);
+ memset(ratesArray, 0, sizeof(ratesArray));
- regOffset += 4;
- }
+ if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_2) {
+ ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+ }
+
+ if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan,
+ &ratesArray[0], cfgCtl,
+ twiceAntennaReduction,
+ twiceMaxRegulatoryPower,
+ powerLimit)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "ath9k_hw_set_txpower: unable to set "
+ "tx power per rate table\n");
+ return -EIO;
+ }
+
+ if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "ath9k_hw_set_txpower: unable to set power table\n");
+ return -EIO;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+ ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
+ if (ratesArray[i] > AR5416_MAX_RATE_POWER)
+ ratesArray[i] = AR5416_MAX_RATE_POWER;
+ }
+
+ if (AR_SREV_9280_10_OR_LATER(ah)) {
+ for (i = 0; i < Ar5416RateSize; i++)
+ ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+ }
+
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
+ ATH9K_POW_SM(ratesArray[rate18mb], 24)
+ | ATH9K_POW_SM(ratesArray[rate12mb], 16)
+ | ATH9K_POW_SM(ratesArray[rate9mb], 8)
+ | ATH9K_POW_SM(ratesArray[rate6mb], 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+ ATH9K_POW_SM(ratesArray[rate54mb], 24)
+ | ATH9K_POW_SM(ratesArray[rate48mb], 16)
+ | ATH9K_POW_SM(ratesArray[rate36mb], 8)
+ | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+ if (IS_CHAN_2GHZ(chan)) {
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+ ATH9K_POW_SM(ratesArray[rate2s], 24)
+ | ATH9K_POW_SM(ratesArray[rate2l], 16)
+ | ATH9K_POW_SM(ratesArray[rateXr], 8)
+ | ATH9K_POW_SM(ratesArray[rate1l], 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+ ATH9K_POW_SM(ratesArray[rate11s], 24)
+ | ATH9K_POW_SM(ratesArray[rate11l], 16)
+ | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
+ | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+ }
+
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+ ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
+ | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
+ | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
+ | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+ ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
+ | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
+ | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
+ | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+ if (IS_CHAN_HT40(chan)) {
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+ ATH9K_POW_SM(ratesArray[rateHt40_3] +
+ ht40PowerIncForPdadc, 24)
+ | ATH9K_POW_SM(ratesArray[rateHt40_2] +
+ ht40PowerIncForPdadc, 16)
+ | ATH9K_POW_SM(ratesArray[rateHt40_1] +
+ ht40PowerIncForPdadc, 8)
+ | ATH9K_POW_SM(ratesArray[rateHt40_0] +
+ ht40PowerIncForPdadc, 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+ ATH9K_POW_SM(ratesArray[rateHt40_7] +
+ ht40PowerIncForPdadc, 24)
+ | ATH9K_POW_SM(ratesArray[rateHt40_6] +
+ ht40PowerIncForPdadc, 16)
+ | ATH9K_POW_SM(ratesArray[rateHt40_5] +
+ ht40PowerIncForPdadc, 8)
+ | ATH9K_POW_SM(ratesArray[rateHt40_4] +
+ ht40PowerIncForPdadc, 0));
+
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+ ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+ | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
+ | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+ | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+ }
+
+ i = rate6mb;
+
+ if (IS_CHAN_HT40(chan))
+ i = rateHt40_0;
+ else if (IS_CHAN_HT20(chan))
+ i = rateHt20_0;
+
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ ah->ah_maxPowerLevel =
+ ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
+ else
+ ah->ah_maxPowerLevel = ratesArray[i];
+
+ return 0;
+}
+
+int (*ath9k_set_txpower[]) (struct ath_hal *,
+ struct ath9k_channel *,
+ u16, u8, u8, u8) = {
+ ath9k_hw_def_set_txpower,
+ ath9k_hw_4k_set_txpower
+};
+
+int ath9k_hw_set_txpower(struct ath_hal *ah,
+ struct ath9k_channel *chan,
+ u16 cfgCtl,
+ u8 twiceAntennaReduction,
+ u8 twiceMaxRegulatoryPower,
+ u8 powerLimit)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
+
+ return ath9k_set_txpower[ahp->ah_eep_map](ah, chan, cfgCtl,
+ twiceAntennaReduction, twiceMaxRegulatoryPower,
+ powerLimit);
+}
+
+static void ath9k_hw_set_def_addac(struct ath_hal *ah,
+ struct ath9k_channel *chan)
+{
+#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
+ struct modal_eep_header *pModal;
+ struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
+ u8 biaslevel;
+
+ if (ah->ah_macVersion != AR_SREV_VERSION_9160)
+ return;
+
+ if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
+ return;
+
+ pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+
+ if (pModal->xpaBiasLvl != 0xff) {
+ biaslevel = pModal->xpaBiasLvl;
+ } else {
+ u16 resetFreqBin, freqBin, freqCount = 0;
+ struct chan_centers centers;
+
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+ resetFreqBin = FREQ2FBIN(centers.synth_center,
+ IS_CHAN_2GHZ(chan));
+ freqBin = XPA_LVL_FREQ(0) & 0xff;
+ biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
+
+ freqCount++;
+
+ while (freqCount < 3) {
+ if (XPA_LVL_FREQ(freqCount) == 0x0)
+ break;
+
+ freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
+ if (resetFreqBin >= freqBin)
+ biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
+ else
+ break;
+ freqCount++;
}
}
- *pTxPowerIndexOffset = 0;
+ if (IS_CHAN_2GHZ(chan)) {
+ INI_RA(&ahp->ah_iniAddac, 7, 1) = (INI_RA(&ahp->ah_iniAddac,
+ 7, 1) & (~0x18)) | biaslevel << 3;
+ } else {
+ INI_RA(&ahp->ah_iniAddac, 6, 1) = (INI_RA(&ahp->ah_iniAddac,
+ 6, 1) & (~0xc0)) | biaslevel << 6;
+ }
+#undef XPA_LVL_FREQ
+}
- return true;
+static void ath9k_hw_set_4k_addac(struct ath_hal *ah,
+ struct ath9k_channel *chan)
+{
+ struct modal_eep_4k_header *pModal;
+ struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
+ u8 biaslevel;
+
+ if (ah->ah_macVersion != AR_SREV_VERSION_9160)
+ return;
+
+ if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
+ return;
+
+ pModal = &eep->modalHeader;
+
+ if (pModal->xpaBiasLvl != 0xff) {
+ biaslevel = pModal->xpaBiasLvl;
+ INI_RA(&ahp->ah_iniAddac, 7, 1) =
+ (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
+ }
+}
+
+void (*ath9k_set_addac[]) (struct ath_hal *, struct ath9k_channel *) = {
+ ath9k_hw_set_def_addac,
+ ath9k_hw_set_4k_addac
+};
+
+void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
+
+ ath9k_set_addac[ahp->ah_eep_map](ah, chan);
}
+
+
/* XXX: Clean me up, make me more legible */
-bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
+static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
struct ath9k_channel *chan)
{
struct modal_eep_header *pModal;
struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom *eep = &ahp->ah_eeprom;
+ struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
int i, regChainOffset;
u8 txRxAttenLocal;
u16 ant_config;
@@ -1462,12 +2352,214 @@ bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
return true;
}
-int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
+static bool ath9k_hw_eeprom_set_4k_board_values(struct ath_hal *ah,
+ struct ath9k_channel *chan)
+{
+ struct modal_eep_4k_header *pModal;
+ struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
+ int regChainOffset;
+ u8 txRxAttenLocal;
+ u16 ant_config = 0;
+ u8 ob[5], db1[5], db2[5];
+ u8 ant_div_control1, ant_div_control2;
+ u32 regVal;
+
+
+ pModal = &eep->modalHeader;
+
+ txRxAttenLocal = 23;
+
+ ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config);
+ REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
+
+ regChainOffset = 0;
+ REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+ pModal->antCtrlChain[0]);
+
+ REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
+ (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
+ ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+ AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+ SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+ SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+ if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_3) {
+ txRxAttenLocal = pModal->txRxAttenCh[0];
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+ pModal->xatten2Margin[0]);
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
+ }
+
+ REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+ AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+ REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+ AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+
+ if (AR_SREV_9285_11(ah))
+ REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+
+ /* Initialize Ant Diversity settings from EEPROM */
+ if (pModal->version == 3) {
+ ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
+ ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
+ regVal = REG_READ(ah, 0x99ac);
+ regVal &= (~(0x7f000000));
+ regVal |= ((ant_div_control1 & 0x1) << 24);
+ regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
+ regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
+ regVal |= ((ant_div_control2 & 0x3) << 25);
+ regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
+ REG_WRITE(ah, 0x99ac, regVal);
+ regVal = REG_READ(ah, 0x99ac);
+ regVal = REG_READ(ah, 0xa208);
+ regVal &= (~(0x1 << 13));
+ regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
+ REG_WRITE(ah, 0xa208, regVal);
+ regVal = REG_READ(ah, 0xa208);
+ }
+
+ if (pModal->version >= 2) {
+ ob[0] = (pModal->ob_01 & 0xf);
+ ob[1] = (pModal->ob_01 >> 4) & 0xf;
+ ob[2] = (pModal->ob_234 & 0xf);
+ ob[3] = ((pModal->ob_234 >> 4) & 0xf);
+ ob[4] = ((pModal->ob_234 >> 8) & 0xf);
+
+ db1[0] = (pModal->db1_01 & 0xf);
+ db1[1] = ((pModal->db1_01 >> 4) & 0xf);
+ db1[2] = (pModal->db1_234 & 0xf);
+ db1[3] = ((pModal->db1_234 >> 4) & 0xf);
+ db1[4] = ((pModal->db1_234 >> 8) & 0xf);
+
+ db2[0] = (pModal->db2_01 & 0xf);
+ db2[1] = ((pModal->db2_01 >> 4) & 0xf);
+ db2[2] = (pModal->db2_234 & 0xf);
+ db2[3] = ((pModal->db2_234 >> 4) & 0xf);
+ db2[4] = ((pModal->db2_234 >> 8) & 0xf);
+
+ } else if (pModal->version == 1) {
+
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "EEPROM Model version is set to 1 \n");
+ ob[0] = (pModal->ob_01 & 0xf);
+ ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
+ db1[0] = (pModal->db1_01 & 0xf);
+ db1[1] = db1[2] = db1[3] =
+ db1[4] = ((pModal->db1_01 >> 4) & 0xf);
+ db2[0] = (pModal->db2_01 & 0xf);
+ db2[1] = db2[2] = db2[3] =
+ db2[4] = ((pModal->db2_01 >> 4) & 0xf);
+ } else {
+ int i;
+ for (i = 0; i < 5; i++) {
+ ob[i] = pModal->ob_01;
+ db1[i] = pModal->db1_01;
+ db2[i] = pModal->db1_01;
+ }
+ }
+
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
+
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
+
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
+
+
+ if (AR_SREV_9285_11(ah))
+ REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
+
+ REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
+ pModal->switchSettling);
+ REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
+ pModal->adcDesiredSize);
+
+ REG_WRITE(ah, AR_PHY_RF_CTL4,
+ SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
+ SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
+ SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) |
+ SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+ REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+ pModal->txEndToRxOn);
+ REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
+ pModal->thresh62);
+ REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
+ pModal->thresh62);
+
+ if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_2) {
+ REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
+ pModal->txFrameToDataStart);
+ REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
+ pModal->txFrameToPaOn);
+ }
+
+ if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_3) {
+ if (IS_CHAN_HT40(chan))
+ REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+ AR_PHY_SETTLING_SWITCH,
+ pModal->swSettleHt40);
+ }
+
+ return true;
+}
+
+bool (*ath9k_eeprom_set_board_values[])(struct ath_hal *,
+ struct ath9k_channel *) = {
+ ath9k_hw_eeprom_set_def_board_values,
+ ath9k_hw_eeprom_set_4k_board_values
+};
+
+bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
+ struct ath9k_channel *chan)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
+
+ return ath9k_eeprom_set_board_values[ahp->ah_eep_map](ah, chan);
+}
+
+static int ath9k_hw_get_def_eeprom_antenna_cfg(struct ath_hal *ah,
struct ath9k_channel *chan,
u8 index, u16 *config)
{
struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom *eep = &ahp->ah_eeprom;
+ struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
struct modal_eep_header *pModal =
&(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
struct base_eep_header *pBase = &eep->baseEepHeader;
@@ -1492,13 +2584,54 @@ int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
return -EINVAL;
}
-u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah,
+static int ath9k_hw_get_4k_eeprom_antenna_cfg(struct ath_hal *ah,
+ struct ath9k_channel *chan,
+ u8 index, u16 *config)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
+ struct modal_eep_4k_header *pModal = &eep->modalHeader;
+
+ switch (index) {
+ case 0:
+ *config = pModal->antCtrlCommon & 0xFFFF;
+ return 0;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+int (*ath9k_get_eeprom_antenna_cfg[])(struct ath_hal *, struct ath9k_channel *,
+ u8, u16 *) = {
+ ath9k_hw_get_def_eeprom_antenna_cfg,
+ ath9k_hw_get_4k_eeprom_antenna_cfg
+};
+
+int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
+ struct ath9k_channel *chan,
+ u8 index, u16 *config)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
+
+ return ath9k_get_eeprom_antenna_cfg[ahp->ah_eep_map](ah, chan,
+ index, config);
+}
+
+u8 ath9k_hw_get_4k_num_ant_config(struct ath_hal *ah,
+ enum ieee80211_band freq_band)
+{
+ return 1;
+}
+
+u8 ath9k_hw_get_def_num_ant_config(struct ath_hal *ah,
enum ieee80211_band freq_band)
{
struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom *eep = &ahp->ah_eeprom;
+ struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
struct modal_eep_header *pModal =
- &(eep->modalHeader[IEEE80211_BAND_5GHZ == freq_band]);
+ &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
struct base_eep_header *pBase = &eep->baseEepHeader;
u8 num_ant_config;
@@ -1511,11 +2644,26 @@ u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah,
return num_ant_config;
}
+u8 (*ath9k_get_num_ant_config[])(struct ath_hal *, enum ieee80211_band) = {
+ ath9k_hw_get_def_num_ant_config,
+ ath9k_hw_get_4k_num_ant_config
+};
+
+u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah,
+ enum ieee80211_band freq_band)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
+
+ return ath9k_get_num_ant_config[ahp->ah_eep_map](ah, freq_band);
+}
+
u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz)
{
+#define EEP_MAP4K_SPURCHAN \
+ (ahp->ah_eeprom.map4k.modalHeader.spurChans[i].spurChan)
+#define EEP_DEF_SPURCHAN \
+ (ahp->ah_eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom *eep =
- (struct ar5416_eeprom *) &ahp->ah_eeprom;
u16 spur_val = AR_NO_SPUR;
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
@@ -1531,19 +2679,66 @@ u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz)
"Getting spur val from new loc. %d\n", spur_val);
break;
case SPUR_ENABLE_EEPROM:
- spur_val = eep->modalHeader[is2GHz].spurChans[i].spurChan;
+ if (ahp->ah_eep_map == EEP_MAP_4KBITS)
+ spur_val = EEP_MAP4K_SPURCHAN;
+ else
+ spur_val = EEP_DEF_SPURCHAN;
break;
}
return spur_val;
+#undef EEP_DEF_SPURCHAN
+#undef EEP_MAP4K_SPURCHAN
}
-u32 ath9k_hw_get_eeprom(struct ath_hal *ah,
- enum eeprom_param param)
+static u32 ath9k_hw_get_eeprom_4k(struct ath_hal *ah,
+ enum eeprom_param param)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
+ struct modal_eep_4k_header *pModal = &eep->modalHeader;
+ struct base_eep_header_4k *pBase = &eep->baseEepHeader;
+
+ switch (param) {
+ case EEP_NFTHRESH_2:
+ return pModal[1].noiseFloorThreshCh[0];
+ case AR_EEPROM_MAC(0):
+ return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+ case AR_EEPROM_MAC(1):
+ return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+ case AR_EEPROM_MAC(2):
+ return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+ case EEP_REG_0:
+ return pBase->regDmn[0];
+ case EEP_REG_1:
+ return pBase->regDmn[1];
+ case EEP_OP_CAP:
+ return pBase->deviceCap;
+ case EEP_OP_MODE:
+ return pBase->opCapFlags;
+ case EEP_RF_SILENT:
+ return pBase->rfSilent;
+ case EEP_OB_2:
+ return pModal->ob_01;
+ case EEP_DB_2:
+ return pModal->db1_01;
+ case EEP_MINOR_REV:
+ return pBase->version & AR5416_EEP_VER_MINOR_MASK;
+ case EEP_TX_MASK:
+ return pBase->txMask;
+ case EEP_RX_MASK:
+ return pBase->rxMask;
+ default:
+ return 0;
+ }
+}
+
+static u32 ath9k_hw_get_eeprom_def(struct ath_hal *ah,
+ enum eeprom_param param)
{
struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom *eep = &ahp->ah_eeprom;
+ struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
struct modal_eep_header *pModal = eep->modalHeader;
struct base_eep_header *pBase = &eep->baseEepHeader;
@@ -1592,13 +2787,32 @@ u32 ath9k_hw_get_eeprom(struct ath_hal *ah,
}
}
+u32 (*ath9k_get_eeprom[])(struct ath_hal *, enum eeprom_param) = {
+ ath9k_hw_get_eeprom_def,
+ ath9k_hw_get_eeprom_4k
+};
+
+u32 ath9k_hw_get_eeprom(struct ath_hal *ah,
+ enum eeprom_param param)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
+
+ return ath9k_get_eeprom[ahp->ah_eep_map](ah, param);
+}
+
int ath9k_hw_eeprom_attach(struct ath_hal *ah)
{
int status;
+ struct ath_hal_5416 *ahp = AH5416(ah);
if (ath9k_hw_use_flash(ah))
ath9k_hw_flash_map(ah);
+ if (AR_SREV_9285(ah))
+ ahp->ah_eep_map = EEP_MAP_4KBITS;
+ else
+ ahp->ah_eep_map = EEP_MAP_DEFAULT;
+
if (!ath9k_hw_fill_eeprom(ah))
return -EIO;
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index 668865dce53..34474edefc9 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -37,7 +37,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type);
static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode);
static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
- struct ar5416_eeprom *pEepData,
+ struct ar5416_eeprom_def *pEepData,
u32 reg, u32 value);
static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan);
static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan);
@@ -392,6 +392,8 @@ static const char *ath9k_hw_devname(u16 devid)
case AR9280_DEVID_PCI:
case AR9280_DEVID_PCIE:
return "Atheros 9280";
+ case AR9285_DEVID_PCIE:
+ return "Atheros 9285";
}
return NULL;
@@ -640,10 +642,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
struct ath_hal_5416 *ahp;
struct ath_hal *ah;
int ecode;
-#ifndef CONFIG_SLOW_ANT_DIV
- u32 i;
- u32 j;
-#endif
+ u32 i, j;
ahp = ath9k_hw_newstate(devid, sc, mem, status);
if (ahp == NULL)
@@ -685,7 +684,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
(ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
(ah->ah_macVersion != AR_SREV_VERSION_9160) &&
- (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) {
+ (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET,
"Mac Chip Rev 0x%02x.%x is not supported by "
"this driver\n", ah->ah_macVersion, ah->ah_macRev);
@@ -736,7 +735,38 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
"This Mac Chip Rev 0x%02x.%x is \n",
ah->ah_macVersion, ah->ah_macRev);
- if (AR_SREV_9280_20_OR_LATER(ah)) {
+ if (AR_SREV_9285_12_OR_LATER(ah)) {
+ INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285_1_2,
+ ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
+ INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285_1_2,
+ ARRAY_SIZE(ar9285Common_9285_1_2), 2);
+
+ if (ah->ah_config.pcie_clock_req) {
+ INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ ar9285PciePhy_clkreq_off_L1_9285_1_2,
+ ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
+ } else {
+ INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
+ ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
+ 2);
+ }
+ } else if (AR_SREV_9285_10_OR_LATER(ah)) {
+ INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285,
+ ARRAY_SIZE(ar9285Modes_9285), 6);
+ INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285,
+ ARRAY_SIZE(ar9285Common_9285), 2);
+
+ if (ah->ah_config.pcie_clock_req) {
+ INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ ar9285PciePhy_clkreq_off_L1_9285,
+ ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
+ } else {
+ INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ ar9285PciePhy_clkreq_always_on_L1_9285,
+ ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
+ }
+ } else if (AR_SREV_9280_20_OR_LATER(ah)) {
INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
ARRAY_SIZE(ar9280Modes_9280_2), 6);
INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
@@ -846,14 +876,13 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
goto bad;
/* rxgain table */
- if (AR_SREV_9280_20_OR_LATER(ah))
+ if (AR_SREV_9280_20(ah))
ath9k_hw_init_rxgain_ini(ah);
/* txgain table */
- if (AR_SREV_9280_20_OR_LATER(ah))
+ if (AR_SREV_9280_20(ah))
ath9k_hw_init_txgain_ini(ah);
-#ifndef CONFIG_SLOW_ANT_DIV
if (ah->ah_devid == AR9280_DEVID_PCI) {
for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
@@ -862,12 +891,13 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
u32 val = INI_RA(&ahp->ah_iniModes, i, j);
INI_RA(&ahp->ah_iniModes, i, j) =
- ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom,
+ ath9k_hw_ini_fixup(ah,
+ &ahp->ah_eeprom.def,
reg, val);
}
}
}
-#endif
+
if (!ath9k_hw_fill_cap_info(ah)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET,
"failed ath9k_hw_fill_cap_info\n");
@@ -1020,8 +1050,6 @@ static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
}
case 0x1:
case 0x2:
- if (!AR_SREV_9280(ah))
- break;
case 0x7:
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
@@ -1166,12 +1194,10 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
case AR9160_DEVID_PCI:
case AR9280_DEVID_PCI:
case AR9280_DEVID_PCIE:
+ case AR9285_DEVID_PCIE:
ah = ath9k_hw_do_attach(devid, sc, mem, error);
break;
default:
- DPRINTF(ah->ah_sc, ATH_DBG_ANY,
- "devid=0x%x not supported.\n", devid);
- ah = NULL;
*error = -ENXIO;
break;
}
@@ -1186,6 +1212,14 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
static void ath9k_hw_override_ini(struct ath_hal *ah,
struct ath9k_channel *chan)
{
+ /*
+ * Set the RX_ABORT and RX_DIS and clear if off only after
+ * RXE is set for MAC. This prevents frames with corrupted
+ * descriptor status.
+ */
+ REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+
+
if (!AR_SREV_5416_V20_OR_LATER(ah) ||
AR_SREV_9280_10_OR_LATER(ah))
return;
@@ -1193,8 +1227,8 @@ static void ath9k_hw_override_ini(struct ath_hal *ah,
REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
}
-static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
- struct ar5416_eeprom *pEepData,
+static u32 ath9k_hw_def_ini_fixup(struct ath_hal *ah,
+ struct ar5416_eeprom_def *pEepData,
u32 reg, u32 value)
{
struct base_eep_header *pBase = &(pEepData->baseEepHeader);
@@ -1227,6 +1261,18 @@ static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
return value;
}
+static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
+ struct ar5416_eeprom_def *pEepData,
+ u32 reg, u32 value)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
+
+ if (ahp->ah_eep_map == EEP_MAP_4KBITS)
+ return value;
+ else
+ return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value);
+}
+
static int ath9k_hw_process_ini(struct ath_hal *ah,
struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode)
@@ -1294,11 +1340,6 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
-#ifdef CONFIG_SLOW_ANT_DIV
- if (ah->ah_devid == AR9280_DEVID_PCI)
- val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg, val);
-#endif
-
REG_WRITE(ah, reg, val);
if (reg >= 0x7800 && reg < 0x78a0
@@ -1309,10 +1350,10 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
DO_DELAY(regWrites);
}
- if (AR_SREV_9280_20_OR_LATER(ah))
+ if (AR_SREV_9280(ah))
REG_WRITE_ARRAY(&ahp->ah_iniModesRxGain, modesIndex, regWrites);
- if (AR_SREV_9280_20_OR_LATER(ah))
+ if (AR_SREV_9280(ah))
REG_WRITE_ARRAY(&ahp->ah_iniModesTxGain, modesIndex, regWrites);
for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
@@ -1585,10 +1626,15 @@ static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode)
{
u32 phymode;
+ u32 enableDacFifo = 0;
struct ath_hal_5416 *ahp = AH5416(ah);
+ if (AR_SREV_9285_10_OR_LATER(ah))
+ enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
+ AR_PHY_FC_ENABLE_DAC_FIFO);
+
phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
- | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH;
+ | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo;
if (IS_CHAN_HT40(chan)) {
phymode |= AR_PHY_FC_DYN2040_EN;
@@ -2771,11 +2817,14 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
if (ah->ah_config.pcie_waen) {
REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
} else {
- if (AR_SREV_9280(ah))
- REG_WRITE(ah, AR_WA, 0x0040073f);
+ if (AR_SREV_9285(ah))
+ REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
+ else if (AR_SREV_9280(ah))
+ REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT);
else
- REG_WRITE(ah, AR_WA, 0x0000073f);
+ REG_WRITE(ah, AR_WA, AR_WA_DEFAULT);
}
+
}
/**********************/
@@ -3326,7 +3375,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
else
pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
- if (AR_SREV_9280(ah))
+ if (AR_SREV_9280(ah) || AR_SREV_9285(ah))
pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
else
pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
@@ -3346,9 +3395,9 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
pCap->num_antcfg_5ghz =
- ath9k_hw_get_num_ant_config(ah, IEEE80211_BAND_5GHZ);
+ ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
pCap->num_antcfg_2ghz =
- ath9k_hw_get_num_ant_config(ah, IEEE80211_BAND_2GHZ);
+ ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
return true;
}
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h
index 02256c3ec07..91d8f594af8 100644
--- a/drivers/net/wireless/ath9k/hw.h
+++ b/drivers/net/wireless/ath9k/hw.h
@@ -448,6 +448,17 @@ struct ar5416Stats {
#define AR5416_EEP_TXGAIN_ORIGINAL 0
#define AR5416_EEP_TXGAIN_HIGH_POWER 1
+#define AR5416_EEP4K_START_LOC 64
+#define AR5416_EEP4K_NUM_2G_CAL_PIERS 3
+#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
+#define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS 3
+#define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS 3
+#define AR5416_EEP4K_NUM_CTLS 12
+#define AR5416_EEP4K_NUM_BAND_EDGES 4
+#define AR5416_EEP4K_NUM_PD_GAINS 2
+#define AR5416_EEP4K_PD_GAINS_IN_MASK 4
+#define AR5416_EEP4K_PD_GAIN_ICEPTS 5
+#define AR5416_EEP4K_MAX_CHAINS 1
enum eeprom_param {
EEP_NFTHRESH_5,
@@ -484,6 +495,11 @@ enum ar5416_rates {
Ar5416RateSize
};
+enum ath9k_hal_freq_band {
+ ATH9K_HAL_FREQ_BAND_5GHZ = 0,
+ ATH9K_HAL_FREQ_BAND_2GHZ = 1
+};
+
struct base_eep_header {
u16 length;
u16 checksum;
@@ -507,6 +523,25 @@ struct base_eep_header {
u8 futureBase_3[25];
} __packed;
+struct base_eep_header_4k {
+ u16 length;
+ u16 checksum;
+ u16 version;
+ u8 opCapFlags;
+ u8 eepMisc;
+ u16 regDmn[2];
+ u8 macAddr[6];
+ u8 rxMask;
+ u8 txMask;
+ u16 rfSilent;
+ u16 blueToothOptions;
+ u16 deviceCap;
+ u32 binBuildNumber;
+ u8 deviceType;
+ u8 futureBase[1];
+} __packed;
+
+
struct spur_chan {
u16 spurChan;
u8 spurRangeLow;
@@ -559,11 +594,58 @@ struct modal_eep_header {
struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
} __packed;
+struct modal_eep_4k_header {
+ u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
+ u32 antCtrlCommon;
+ u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 switchSettling;
+ u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 adcDesiredSize;
+ u8 pgaDesiredSize;
+ u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 txEndToXpaOff;
+ u8 txEndToRxOn;
+ u8 txFrameToXpaOn;
+ u8 thresh62;
+ u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 xpdGain;
+ u8 xpd;
+ u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS];
+ u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 pdGainOverlap;
+ u8 ob_01;
+ u8 db1_01;
+ u8 xpaBiasLvl;
+ u8 txFrameToDataStart;
+ u8 txFrameToPaOn;
+ u8 ht40PowerIncForPdadc;
+ u8 bswAtten[AR5416_EEP4K_MAX_CHAINS];
+ u8 bswMargin[AR5416_EEP4K_MAX_CHAINS];
+ u8 swSettleHt40;
+ u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS];
+ u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
+ u8 db2_01;
+ u8 version;
+ u16 ob_234;
+ u16 db1_234;
+ u16 db2_234;
+ u8 futureModal[4];
+
+ struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+} __packed;
+
+
struct cal_data_per_freq {
u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
} __packed;
+struct cal_data_per_freq_4k {
+ u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+ u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+} __packed;
+
struct cal_target_power_leg {
u8 bChannel;
u8 tPow2x[4];
@@ -574,6 +656,7 @@ struct cal_target_power_ht {
u8 tPow2x[8];
} __packed;
+
#ifdef __BIG_ENDIAN_BITFIELD
struct cal_ctl_edges {
u8 bChannel;
@@ -588,10 +671,15 @@ struct cal_ctl_edges {
struct cal_ctl_data {
struct cal_ctl_edges
- ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+ ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+} __packed;
+
+struct cal_ctl_data_4k {
+ struct cal_ctl_edges
+ ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
} __packed;
-struct ar5416_eeprom {
+struct ar5416_eeprom_def {
struct base_eep_header baseEepHeader;
u8 custData[64];
struct modal_eep_header modalHeader[2];
@@ -620,6 +708,26 @@ struct ar5416_eeprom {
u8 padding;
} __packed;
+struct ar5416_eeprom_4k {
+ struct base_eep_header_4k baseEepHeader;
+ u8 custData[20];
+ struct modal_eep_4k_header modalHeader;
+ u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
+ struct cal_data_per_freq_4k
+ calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
+ struct cal_target_power_leg
+ calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
+ struct cal_target_power_leg
+ calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
+ struct cal_target_power_ht
+ calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
+ struct cal_target_power_ht
+ calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
+ u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
+ struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
+ u8 padding;
+} __packed;
+
struct ar5416IniArray {
u32 *ia_array;
u32 ia_rows;
@@ -687,9 +795,22 @@ struct hal_cal_list {
struct hal_cal_list *calNext;
};
+/*
+ * Enum to indentify the eeprom mappings
+ */
+enum hal_eep_map {
+ EEP_MAP_DEFAULT = 0x0,
+ EEP_MAP_4KBITS,
+ EEP_MAP_MAX
+};
+
+
struct ath_hal_5416 {
struct ath_hal ah;
- struct ar5416_eeprom ah_eeprom;
+ union {
+ struct ar5416_eeprom_def def;
+ struct ar5416_eeprom_4k map4k;
+ } ah_eeprom;
struct ar5416Stats ah_stats;
struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES];
void __iomem *ah_cal_mem;
@@ -813,6 +934,8 @@ struct ath_hal_5416 {
struct ar5416IniArray ah_iniModesAdditional;
struct ar5416IniArray ah_iniModesRxGain;
struct ar5416IniArray ah_iniModesTxGain;
+ /* To indicate EEPROM mapping used */
+ enum hal_eep_map ah_eep_map;
};
#define AH5416(_ah) ((struct ath_hal_5416 *)(_ah))
@@ -854,13 +977,20 @@ struct ath_hal_5416 {
(AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
#define AR5416_EEPROM_MAX 0xae0
#define ar5416_get_eep_ver(_ahp) \
- (((_ahp)->ah_eeprom.baseEepHeader.version >> 12) & 0xF)
+ (((_ahp)->ah_eeprom.def.baseEepHeader.version >> 12) & 0xF)
#define ar5416_get_eep_rev(_ahp) \
- (((_ahp)->ah_eeprom.baseEepHeader.version) & 0xFFF)
+ (((_ahp)->ah_eeprom.def.baseEepHeader.version) & 0xFFF)
#define ar5416_get_ntxchains(_txchainmask) \
(((_txchainmask >> 2) & 1) + \
((_txchainmask >> 1) & 1) + (_txchainmask & 1))
+/* EEPROM 4K bit map definations */
+#define ar5416_get_eep4k_ver(_ahp) \
+ (((_ahp)->ah_eeprom.map4k.baseEepHeader.version >> 12) & 0xF)
+#define ar5416_get_eep4k_rev(_ahp) \
+ (((_ahp)->ah_eeprom.map4k.baseEepHeader.version) & 0xFFF)
+
+
#ifdef __BIG_ENDIAN
#define AR5416_EEPROM_MAGIC 0x5aa5
#else
diff --git a/drivers/net/wireless/ath9k/initvals.h b/drivers/net/wireless/ath9k/initvals.h
index 1b08b54b31d..f3cfa16525e 100644
--- a/drivers/net/wireless/ath9k/initvals.h
+++ b/drivers/net/wireless/ath9k/initvals.h
@@ -3437,3 +3437,1366 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
{0x00004040, 0x00043007 },
{0x00004044, 0x00000000 },
};
+
+/* AR9285 */
+static const u_int32_t ar9285Modes_9285[][6] = {
+ { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+ { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+ { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+ { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
+ { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+ { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
+ { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
+ { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+ { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+ { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+ { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+ { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+ { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+ { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
+ { 0x00009844, 0x0372161e, 0x0372161e, 0x03720020, 0x03720020, 0x037216a0 },
+ { 0x00009848, 0x00001066, 0x00001066, 0x0000004e, 0x0000004e, 0x00001059 },
+ { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
+ { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
+ { 0x0000985c, 0x3139605e, 0x3139605e, 0x3136605e, 0x3136605e, 0x3139605e },
+ { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 },
+ { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+ { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
+ { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
+ { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
+ { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
+ { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
+ { 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1020, 0xdfbc1020, 0xdfbc1010 },
+ { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x000099b8, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c },
+ { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
+ { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
+ { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+ { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
+ { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+ { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+ { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00009a00, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
+ { 0x00009a04, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
+ { 0x00009a08, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
+ { 0x00009a0c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
+ { 0x00009a10, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
+ { 0x00009a14, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
+ { 0x00009a18, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
+ { 0x00009a1c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
+ { 0x00009a20, 0x00000000, 0x00000000, 0x00068114, 0x00068114, 0x00000000 },
+ { 0x00009a24, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
+ { 0x00009a28, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
+ { 0x00009a2c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
+ { 0x00009a30, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
+ { 0x00009a34, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
+ { 0x00009a38, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
+ { 0x00009a3c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
+ { 0x00009a40, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
+ { 0x00009a44, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
+ { 0x00009a48, 0x00000000, 0x00000000, 0x00068284, 0x00068284, 0x00000000 },
+ { 0x00009a4c, 0x00000000, 0x00000000, 0x00068288, 0x00068288, 0x00000000 },
+ { 0x00009a50, 0x00000000, 0x00000000, 0x00068220, 0x00068220, 0x00000000 },
+ { 0x00009a54, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
+ { 0x00009a58, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
+ { 0x00009a5c, 0x00000000, 0x00000000, 0x00068304, 0x00068304, 0x00000000 },
+ { 0x00009a60, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
+ { 0x00009a64, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
+ { 0x00009a68, 0x00000000, 0x00000000, 0x00068380, 0x00068380, 0x00000000 },
+ { 0x00009a6c, 0x00000000, 0x00000000, 0x00068384, 0x00068384, 0x00000000 },
+ { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
+ { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
+ { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
+ { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
+ { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
+ { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
+ { 0x00009a88, 0x00000000, 0x00000000, 0x00068b04, 0x00068b04, 0x00000000 },
+ { 0x00009a8c, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
+ { 0x00009a90, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
+ { 0x00009a94, 0x00000000, 0x00000000, 0x00068b0c, 0x00068b0c, 0x00000000 },
+ { 0x00009a98, 0x00000000, 0x00000000, 0x00068b80, 0x00068b80, 0x00000000 },
+ { 0x00009a9c, 0x00000000, 0x00000000, 0x00068b84, 0x00068b84, 0x00000000 },
+ { 0x00009aa0, 0x00000000, 0x00000000, 0x00068b88, 0x00068b88, 0x00000000 },
+ { 0x00009aa4, 0x00000000, 0x00000000, 0x00068b8c, 0x00068b8c, 0x00000000 },
+ { 0x00009aa8, 0x00000000, 0x00000000, 0x000b8b90, 0x000b8b90, 0x00000000 },
+ { 0x00009aac, 0x00000000, 0x00000000, 0x000b8f80, 0x000b8f80, 0x00000000 },
+ { 0x00009ab0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
+ { 0x00009ab4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
+ { 0x00009ab8, 0x00000000, 0x00000000, 0x000b8f8c, 0x000b8f8c, 0x00000000 },
+ { 0x00009abc, 0x00000000, 0x00000000, 0x000b8f90, 0x000b8f90, 0x00000000 },
+ { 0x00009ac0, 0x00000000, 0x00000000, 0x000bb30c, 0x000bb30c, 0x00000000 },
+ { 0x00009ac4, 0x00000000, 0x00000000, 0x000bb310, 0x000bb310, 0x00000000 },
+ { 0x00009ac8, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
+ { 0x00009acc, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
+ { 0x00009ad0, 0x00000000, 0x00000000, 0x000bb324, 0x000bb324, 0x00000000 },
+ { 0x00009ad4, 0x00000000, 0x00000000, 0x000bb704, 0x000bb704, 0x00000000 },
+ { 0x00009ad8, 0x00000000, 0x00000000, 0x000f96a4, 0x000f96a4, 0x00000000 },
+ { 0x00009adc, 0x00000000, 0x00000000, 0x000f96a8, 0x000f96a8, 0x00000000 },
+ { 0x00009ae0, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
+ { 0x00009ae4, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
+ { 0x00009ae8, 0x00000000, 0x00000000, 0x000f9720, 0x000f9720, 0x00000000 },
+ { 0x00009aec, 0x00000000, 0x00000000, 0x000f9724, 0x000f9724, 0x00000000 },
+ { 0x00009af0, 0x00000000, 0x00000000, 0x000f9728, 0x000f9728, 0x00000000 },
+ { 0x00009af4, 0x00000000, 0x00000000, 0x000f972c, 0x000f972c, 0x00000000 },
+ { 0x00009af8, 0x00000000, 0x00000000, 0x000f97a0, 0x000f97a0, 0x00000000 },
+ { 0x00009afc, 0x00000000, 0x00000000, 0x000f97a4, 0x000f97a4, 0x00000000 },
+ { 0x00009b00, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
+ { 0x00009b04, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
+ { 0x00009b08, 0x00000000, 0x00000000, 0x000fb7b4, 0x000fb7b4, 0x00000000 },
+ { 0x00009b0c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
+ { 0x00009b10, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
+ { 0x00009b14, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
+ { 0x00009b18, 0x00000000, 0x00000000, 0x000fb7ad, 0x000fb7ad, 0x00000000 },
+ { 0x00009b1c, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
+ { 0x00009b20, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
+ { 0x00009b24, 0x00000000, 0x00000000, 0x000fb7b9, 0x000fb7b9, 0x00000000 },
+ { 0x00009b28, 0x00000000, 0x00000000, 0x000fb7c5, 0x000fb7c5, 0x00000000 },
+ { 0x00009b2c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
+ { 0x00009b30, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
+ { 0x00009b34, 0x00000000, 0x00000000, 0x000fb7d5, 0x000fb7d5, 0x00000000 },
+ { 0x00009b38, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
+ { 0x00009b3c, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
+ { 0x00009b40, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
+ { 0x00009b44, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
+ { 0x00009b48, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
+ { 0x00009b4c, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
+ { 0x00009b50, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
+ { 0x00009b54, 0x00000000, 0x00000000, 0x000fb7c7, 0x000fb7c7, 0x00000000 },
+ { 0x00009b58, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
+ { 0x00009b5c, 0x00000000, 0x00000000, 0x000fb7cf, 0x000fb7cf, 0x00000000 },
+ { 0x00009b60, 0x00000000, 0x00000000, 0x000fb7d7, 0x000fb7d7, 0x00000000 },
+ { 0x00009b64, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b68, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b6c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b70, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b74, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b78, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b7c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b80, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b84, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b88, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b8c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b90, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b94, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b98, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b9c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009ba0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009ba4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009ba8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bac, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bb0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bb4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bb8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bbc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bc0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bc4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bc8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bcc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bd0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bd4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bd8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bdc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009be0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009be4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009be8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bec, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bf0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bf4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bf8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bfc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x0000aa00, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
+ { 0x0000aa04, 0x00000000, 0x00000000, 0x00068080, 0x00068080, 0x00000000 },
+ { 0x0000aa08, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
+ { 0x0000aa0c, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
+ { 0x0000aa10, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
+ { 0x0000aa14, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
+ { 0x0000aa18, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
+ { 0x0000aa1c, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
+ { 0x0000aa20, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
+ { 0x0000aa24, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
+ { 0x0000aa28, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
+ { 0x0000aa2c, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
+ { 0x0000aa30, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
+ { 0x0000aa34, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
+ { 0x0000aa38, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
+ { 0x0000aa3c, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
+ { 0x0000aa40, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
+ { 0x0000aa44, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
+ { 0x0000aa48, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
+ { 0x0000aa4c, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
+ { 0x0000aa50, 0x00000000, 0x00000000, 0x000681ac, 0x000681ac, 0x00000000 },
+ { 0x0000aa54, 0x00000000, 0x00000000, 0x0006821c, 0x0006821c, 0x00000000 },
+ { 0x0000aa58, 0x00000000, 0x00000000, 0x00068224, 0x00068224, 0x00000000 },
+ { 0x0000aa5c, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
+ { 0x0000aa60, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
+ { 0x0000aa64, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
+ { 0x0000aa68, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
+ { 0x0000aa6c, 0x00000000, 0x00000000, 0x00068310, 0x00068310, 0x00000000 },
+ { 0x0000aa70, 0x00000000, 0x00000000, 0x00068788, 0x00068788, 0x00000000 },
+ { 0x0000aa74, 0x00000000, 0x00000000, 0x0006878c, 0x0006878c, 0x00000000 },
+ { 0x0000aa78, 0x00000000, 0x00000000, 0x00068790, 0x00068790, 0x00000000 },
+ { 0x0000aa7c, 0x00000000, 0x00000000, 0x00068794, 0x00068794, 0x00000000 },
+ { 0x0000aa80, 0x00000000, 0x00000000, 0x00068798, 0x00068798, 0x00000000 },
+ { 0x0000aa84, 0x00000000, 0x00000000, 0x0006879c, 0x0006879c, 0x00000000 },
+ { 0x0000aa88, 0x00000000, 0x00000000, 0x00068b89, 0x00068b89, 0x00000000 },
+ { 0x0000aa8c, 0x00000000, 0x00000000, 0x00068b8d, 0x00068b8d, 0x00000000 },
+ { 0x0000aa90, 0x00000000, 0x00000000, 0x00068b91, 0x00068b91, 0x00000000 },
+ { 0x0000aa94, 0x00000000, 0x00000000, 0x00068b95, 0x00068b95, 0x00000000 },
+ { 0x0000aa98, 0x00000000, 0x00000000, 0x00068b99, 0x00068b99, 0x00000000 },
+ { 0x0000aa9c, 0x00000000, 0x00000000, 0x00068ba5, 0x00068ba5, 0x00000000 },
+ { 0x0000aaa0, 0x00000000, 0x00000000, 0x00068ba9, 0x00068ba9, 0x00000000 },
+ { 0x0000aaa4, 0x00000000, 0x00000000, 0x00068bad, 0x00068bad, 0x00000000 },
+ { 0x0000aaa8, 0x00000000, 0x00000000, 0x000b8b0c, 0x000b8b0c, 0x00000000 },
+ { 0x0000aaac, 0x00000000, 0x00000000, 0x000b8f10, 0x000b8f10, 0x00000000 },
+ { 0x0000aab0, 0x00000000, 0x00000000, 0x000b8f14, 0x000b8f14, 0x00000000 },
+ { 0x0000aab4, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
+ { 0x0000aab8, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
+ { 0x0000aabc, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
+ { 0x0000aac0, 0x00000000, 0x00000000, 0x000bb380, 0x000bb380, 0x00000000 },
+ { 0x0000aac4, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
+ { 0x0000aac8, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
+ { 0x0000aacc, 0x00000000, 0x00000000, 0x000bb38c, 0x000bb38c, 0x00000000 },
+ { 0x0000aad0, 0x00000000, 0x00000000, 0x000bb394, 0x000bb394, 0x00000000 },
+ { 0x0000aad4, 0x00000000, 0x00000000, 0x000bb798, 0x000bb798, 0x00000000 },
+ { 0x0000aad8, 0x00000000, 0x00000000, 0x000f970c, 0x000f970c, 0x00000000 },
+ { 0x0000aadc, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
+ { 0x0000aae0, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
+ { 0x0000aae4, 0x00000000, 0x00000000, 0x000f9718, 0x000f9718, 0x00000000 },
+ { 0x0000aae8, 0x00000000, 0x00000000, 0x000f9705, 0x000f9705, 0x00000000 },
+ { 0x0000aaec, 0x00000000, 0x00000000, 0x000f9709, 0x000f9709, 0x00000000 },
+ { 0x0000aaf0, 0x00000000, 0x00000000, 0x000f970d, 0x000f970d, 0x00000000 },
+ { 0x0000aaf4, 0x00000000, 0x00000000, 0x000f9711, 0x000f9711, 0x00000000 },
+ { 0x0000aaf8, 0x00000000, 0x00000000, 0x000f9715, 0x000f9715, 0x00000000 },
+ { 0x0000aafc, 0x00000000, 0x00000000, 0x000f9719, 0x000f9719, 0x00000000 },
+ { 0x0000ab00, 0x00000000, 0x00000000, 0x000fb7a4, 0x000fb7a4, 0x00000000 },
+ { 0x0000ab04, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
+ { 0x0000ab08, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
+ { 0x0000ab0c, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
+ { 0x0000ab10, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
+ { 0x0000ab14, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
+ { 0x0000ab18, 0x00000000, 0x00000000, 0x000fb7bc, 0x000fb7bc, 0x00000000 },
+ { 0x0000ab1c, 0x00000000, 0x00000000, 0x000fb7a1, 0x000fb7a1, 0x00000000 },
+ { 0x0000ab20, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
+ { 0x0000ab24, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
+ { 0x0000ab28, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
+ { 0x0000ab2c, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
+ { 0x0000ab30, 0x00000000, 0x00000000, 0x000fb7bd, 0x000fb7bd, 0x00000000 },
+ { 0x0000ab34, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
+ { 0x0000ab38, 0x00000000, 0x00000000, 0x000fb7cd, 0x000fb7cd, 0x00000000 },
+ { 0x0000ab3c, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
+ { 0x0000ab40, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
+ { 0x0000ab44, 0x00000000, 0x00000000, 0x000fb7c2, 0x000fb7c2, 0x00000000 },
+ { 0x0000ab48, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
+ { 0x0000ab4c, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
+ { 0x0000ab50, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
+ { 0x0000ab54, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
+ { 0x0000ab58, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
+ { 0x0000ab5c, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
+ { 0x0000ab60, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
+ { 0x0000ab64, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab68, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab6c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab70, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab74, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab78, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab7c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab80, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab84, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab88, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab8c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab90, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab94, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab98, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab9c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000aba0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000aba4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000aba8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abac, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abb0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abb4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abb8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abbc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abc0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abc4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abc8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abcc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abd0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abd4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abd8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abdc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abe0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abe4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abe8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abec, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abf0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abf4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abf8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abfc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
+ { 0x0000a20c, 0x00000014, 0x00000014, 0x00000000, 0x00000000, 0x0001f000 },
+ { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+ { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+ { 0x0000a250, 0x001ff000, 0x001ff000, 0x001ca000, 0x001ca000, 0x001da000 },
+ { 0x0000a274, 0x0a81c652, 0x0a81c652, 0x0a820652, 0x0a820652, 0x0a82a652 },
+ { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000a304, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
+ { 0x0000a308, 0x00000000, 0x00000000, 0x00010408, 0x00010408, 0x00000000 },
+ { 0x0000a30c, 0x00000000, 0x00000000, 0x0001860a, 0x0001860a, 0x00000000 },
+ { 0x0000a310, 0x00000000, 0x00000000, 0x00020818, 0x00020818, 0x00000000 },
+ { 0x0000a314, 0x00000000, 0x00000000, 0x00024858, 0x00024858, 0x00000000 },
+ { 0x0000a318, 0x00000000, 0x00000000, 0x00026859, 0x00026859, 0x00000000 },
+ { 0x0000a31c, 0x00000000, 0x00000000, 0x0002985b, 0x0002985b, 0x00000000 },
+ { 0x0000a320, 0x00000000, 0x00000000, 0x0002c89a, 0x0002c89a, 0x00000000 },
+ { 0x0000a324, 0x00000000, 0x00000000, 0x0002e89b, 0x0002e89b, 0x00000000 },
+ { 0x0000a328, 0x00000000, 0x00000000, 0x0003089c, 0x0003089c, 0x00000000 },
+ { 0x0000a32c, 0x00000000, 0x00000000, 0x0003289d, 0x0003289d, 0x00000000 },
+ { 0x0000a330, 0x00000000, 0x00000000, 0x0003489e, 0x0003489e, 0x00000000 },
+ { 0x0000a334, 0x00000000, 0x00000000, 0x000388de, 0x000388de, 0x00000000 },
+ { 0x0000a338, 0x00000000, 0x00000000, 0x0003b91e, 0x0003b91e, 0x00000000 },
+ { 0x0000a33c, 0x00000000, 0x00000000, 0x0003d95e, 0x0003d95e, 0x00000000 },
+ { 0x0000a340, 0x00000000, 0x00000000, 0x000419df, 0x000419df, 0x00000000 },
+ { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
+};
+
+static const u_int32_t ar9285Common_9285[][2] = {
+ { 0x0000000c, 0x00000000 },
+ { 0x00000030, 0x00020045 },
+ { 0x00000034, 0x00000005 },
+ { 0x00000040, 0x00000000 },
+ { 0x00000044, 0x00000008 },
+ { 0x00000048, 0x00000008 },
+ { 0x0000004c, 0x00000010 },
+ { 0x00000050, 0x00000000 },
+ { 0x00000054, 0x0000001f },
+ { 0x00000800, 0x00000000 },
+ { 0x00000804, 0x00000000 },
+ { 0x00000808, 0x00000000 },
+ { 0x0000080c, 0x00000000 },
+ { 0x00000810, 0x00000000 },
+ { 0x00000814, 0x00000000 },
+ { 0x00000818, 0x00000000 },
+ { 0x0000081c, 0x00000000 },
+ { 0x00000820, 0x00000000 },
+ { 0x00000824, 0x00000000 },
+ { 0x00001040, 0x002ffc0f },
+ { 0x00001044, 0x002ffc0f },
+ { 0x00001048, 0x002ffc0f },
+ { 0x0000104c, 0x002ffc0f },
+ { 0x00001050, 0x002ffc0f },
+ { 0x00001054, 0x002ffc0f },
+ { 0x00001058, 0x002ffc0f },
+ { 0x0000105c, 0x002ffc0f },
+ { 0x00001060, 0x002ffc0f },
+ { 0x00001064, 0x002ffc0f },
+ { 0x00001230, 0x00000000 },
+ { 0x00001270, 0x00000000 },
+ { 0x00001038, 0x00000000 },
+ { 0x00001078, 0x00000000 },
+ { 0x000010b8, 0x00000000 },
+ { 0x000010f8, 0x00000000 },
+ { 0x00001138, 0x00000000 },
+ { 0x00001178, 0x00000000 },
+ { 0x000011b8, 0x00000000 },
+ { 0x000011f8, 0x00000000 },
+ { 0x00001238, 0x00000000 },
+ { 0x00001278, 0x00000000 },
+ { 0x000012b8, 0x00000000 },
+ { 0x000012f8, 0x00000000 },
+ { 0x00001338, 0x00000000 },
+ { 0x00001378, 0x00000000 },
+ { 0x000013b8, 0x00000000 },
+ { 0x000013f8, 0x00000000 },
+ { 0x00001438, 0x00000000 },
+ { 0x00001478, 0x00000000 },
+ { 0x000014b8, 0x00000000 },
+ { 0x000014f8, 0x00000000 },
+ { 0x00001538, 0x00000000 },
+ { 0x00001578, 0x00000000 },
+ { 0x000015b8, 0x00000000 },
+ { 0x000015f8, 0x00000000 },
+ { 0x00001638, 0x00000000 },
+ { 0x00001678, 0x00000000 },
+ { 0x000016b8, 0x00000000 },
+ { 0x000016f8, 0x00000000 },
+ { 0x00001738, 0x00000000 },
+ { 0x00001778, 0x00000000 },
+ { 0x000017b8, 0x00000000 },
+ { 0x000017f8, 0x00000000 },
+ { 0x0000103c, 0x00000000 },
+ { 0x0000107c, 0x00000000 },
+ { 0x000010bc, 0x00000000 },
+ { 0x000010fc, 0x00000000 },
+ { 0x0000113c, 0x00000000 },
+ { 0x0000117c, 0x00000000 },
+ { 0x000011bc, 0x00000000 },
+ { 0x000011fc, 0x00000000 },
+ { 0x0000123c, 0x00000000 },
+ { 0x0000127c, 0x00000000 },
+ { 0x000012bc, 0x00000000 },
+ { 0x000012fc, 0x00000000 },
+ { 0x0000133c, 0x00000000 },
+ { 0x0000137c, 0x00000000 },
+ { 0x000013bc, 0x00000000 },
+ { 0x000013fc, 0x00000000 },
+ { 0x0000143c, 0x00000000 },
+ { 0x0000147c, 0x00000000 },
+ { 0x00004030, 0x00000002 },
+ { 0x0000403c, 0x00000002 },
+ { 0x00004024, 0x0000001f },
+ { 0x00004060, 0x00000000 },
+ { 0x00004064, 0x00000000 },
+ { 0x00007010, 0x00000031 },
+ { 0x00007034, 0x00000002 },
+ { 0x00007038, 0x000004c2 },
+ { 0x00008004, 0x00000000 },
+ { 0x00008008, 0x00000000 },
+ { 0x0000800c, 0x00000000 },
+ { 0x00008018, 0x00000700 },
+ { 0x00008020, 0x00000000 },
+ { 0x00008038, 0x00000000 },
+ { 0x0000803c, 0x00000000 },
+ { 0x00008048, 0x00000000 },
+ { 0x00008054, 0x00000000 },
+ { 0x00008058, 0x00000000 },
+ { 0x0000805c, 0x000fc78f },
+ { 0x00008060, 0x0000000f },
+ { 0x00008064, 0x00000000 },
+ { 0x00008070, 0x00000000 },
+ { 0x000080c0, 0x2a80001a },
+ { 0x000080c4, 0x05dc01e0 },
+ { 0x000080c8, 0x1f402710 },
+ { 0x000080cc, 0x01f40000 },
+ { 0x000080d0, 0x00001e00 },
+ { 0x000080d4, 0x00000000 },
+ { 0x000080d8, 0x00400000 },
+ { 0x000080e0, 0xffffffff },
+ { 0x000080e4, 0x0000ffff },
+ { 0x000080e8, 0x003f3f3f },
+ { 0x000080ec, 0x00000000 },
+ { 0x000080f0, 0x00000000 },
+ { 0x000080f4, 0x00000000 },
+ { 0x000080f8, 0x00000000 },
+ { 0x000080fc, 0x00020000 },
+ { 0x00008100, 0x00020000 },
+ { 0x00008104, 0x00000001 },
+ { 0x00008108, 0x00000052 },
+ { 0x0000810c, 0x00000000 },
+ { 0x00008110, 0x00000168 },
+ { 0x00008118, 0x000100aa },
+ { 0x0000811c, 0x00003210 },
+ { 0x00008120, 0x08f04800 },
+ { 0x00008124, 0x00000000 },
+ { 0x00008128, 0x00000000 },
+ { 0x0000812c, 0x00000000 },
+ { 0x00008130, 0x00000000 },
+ { 0x00008134, 0x00000000 },
+ { 0x00008138, 0x00000000 },
+ { 0x0000813c, 0x00000000 },
+ { 0x00008144, 0x00000000 },
+ { 0x00008168, 0x00000000 },
+ { 0x0000816c, 0x00000000 },
+ { 0x00008170, 0x32143320 },
+ { 0x00008174, 0xfaa4fa50 },
+ { 0x00008178, 0x00000100 },
+ { 0x0000817c, 0x00000000 },
+ { 0x000081c0, 0x00000000 },
+ { 0x000081d0, 0x00003210 },
+ { 0x000081ec, 0x00000000 },
+ { 0x000081f0, 0x00000000 },
+ { 0x000081f4, 0x00000000 },
+ { 0x000081f8, 0x00000000 },
+ { 0x000081fc, 0x00000000 },
+ { 0x00008200, 0x00000000 },
+ { 0x00008204, 0x00000000 },
+ { 0x00008208, 0x00000000 },
+ { 0x0000820c, 0x00000000 },
+ { 0x00008210, 0x00000000 },
+ { 0x00008214, 0x00000000 },
+ { 0x00008218, 0x00000000 },
+ { 0x0000821c, 0x00000000 },
+ { 0x00008220, 0x00000000 },
+ { 0x00008224, 0x00000000 },
+ { 0x00008228, 0x00000000 },
+ { 0x0000822c, 0x00000000 },
+ { 0x00008230, 0x00000000 },
+ { 0x00008234, 0x00000000 },
+ { 0x00008238, 0x00000000 },
+ { 0x0000823c, 0x00000000 },
+ { 0x00008240, 0x00100000 },
+ { 0x00008244, 0x0010f400 },
+ { 0x00008248, 0x00000100 },
+ { 0x0000824c, 0x0001e800 },
+ { 0x00008250, 0x00000000 },
+ { 0x00008254, 0x00000000 },
+ { 0x00008258, 0x00000000 },
+ { 0x0000825c, 0x400000ff },
+ { 0x00008260, 0x00080922 },
+ { 0x00008264, 0xa8a00010 },
+ { 0x00008270, 0x00000000 },
+ { 0x00008274, 0x40000000 },
+ { 0x00008278, 0x003e4180 },
+ { 0x0000827c, 0x00000000 },
+ { 0x00008284, 0x0000002c },
+ { 0x00008288, 0x0000002c },
+ { 0x0000828c, 0x00000000 },
+ { 0x00008294, 0x00000000 },
+ { 0x00008298, 0x00000000 },
+ { 0x0000829c, 0x00000000 },
+ { 0x00008300, 0x00000040 },
+ { 0x00008314, 0x00000000 },
+ { 0x00008328, 0x00000000 },
+ { 0x0000832c, 0x00000001 },
+ { 0x00008330, 0x00000302 },
+ { 0x00008334, 0x00000e00 },
+ { 0x00008338, 0x00000000 },
+ { 0x0000833c, 0x00000000 },
+ { 0x00008340, 0x00010380 },
+ { 0x00008344, 0x00581043 },
+ { 0x00009808, 0x00000000 },
+ { 0x0000980c, 0xafe68e30 },
+ { 0x00009810, 0xfd14e000 },
+ { 0x00009814, 0x9c0a9f6b },
+ { 0x0000981c, 0x00000000 },
+ { 0x0000982c, 0x0000a000 },
+ { 0x00009830, 0x00000000 },
+ { 0x0000983c, 0x00200400 },
+ { 0x0000984c, 0x0040233c },
+ { 0x00009854, 0x00000044 },
+ { 0x00009900, 0x00000000 },
+ { 0x00009904, 0x00000000 },
+ { 0x00009908, 0x00000000 },
+ { 0x0000990c, 0x00000000 },
+ { 0x00009910, 0x01002310 },
+ { 0x0000991c, 0x10000fff },
+ { 0x00009920, 0x04900000 },
+ { 0x00009928, 0x00000001 },
+ { 0x0000992c, 0x00000004 },
+ { 0x00009934, 0x1e1f2022 },
+ { 0x00009938, 0x0a0b0c0d },
+ { 0x0000993c, 0x00000000 },
+ { 0x00009940, 0x14750604 },
+ { 0x00009948, 0x9280c00a },
+ { 0x0000994c, 0x00020028 },
+ { 0x00009954, 0x5f3ca3de },
+ { 0x00009958, 0x2108ecff },
+ { 0x00009968, 0x000003ce },
+ { 0x00009970, 0x1927b515 },
+ { 0x00009974, 0x00000000 },
+ { 0x00009978, 0x00000001 },
+ { 0x0000997c, 0x00000000 },
+ { 0x00009980, 0x00000000 },
+ { 0x00009984, 0x00000000 },
+ { 0x00009988, 0x00000000 },
+ { 0x0000998c, 0x00000000 },
+ { 0x00009990, 0x00000000 },
+ { 0x00009994, 0x00000000 },
+ { 0x00009998, 0x00000000 },
+ { 0x0000999c, 0x00000000 },
+ { 0x000099a0, 0x00000000 },
+ { 0x000099a4, 0x00000001 },
+ { 0x000099a8, 0x201fff00 },
+ { 0x000099ac, 0x2def0a00 },
+ { 0x000099b0, 0x03051000 },
+ { 0x000099b4, 0x00000820 },
+ { 0x000099dc, 0x00000000 },
+ { 0x000099e0, 0x00000000 },
+ { 0x000099e4, 0xaaaaaaaa },
+ { 0x000099e8, 0x3c466478 },
+ { 0x000099ec, 0x0cc80caa },
+ { 0x000099f0, 0x00000000 },
+ { 0x0000a208, 0x803e6788 },
+ { 0x0000a210, 0x4080a333 },
+ { 0x0000a214, 0x00206c10 },
+ { 0x0000a218, 0x009c4060 },
+ { 0x0000a220, 0x01834061 },
+ { 0x0000a224, 0x00000400 },
+ { 0x0000a228, 0x000003b5 },
+ { 0x0000a22c, 0x00000000 },
+ { 0x0000a234, 0x20202020 },
+ { 0x0000a238, 0x20202020 },
+ { 0x0000a244, 0x00000000 },
+ { 0x0000a248, 0xfffffffc },
+ { 0x0000a24c, 0x00000000 },
+ { 0x0000a254, 0x00000000 },
+ { 0x0000a258, 0x0ccb5380 },
+ { 0x0000a25c, 0x15151501 },
+ { 0x0000a260, 0xdfa90f01 },
+ { 0x0000a268, 0x00000000 },
+ { 0x0000a26c, 0x0ebae9e6 },
+ { 0x0000d270, 0x0d820820 },
+ { 0x0000a278, 0x39ce739c },
+ { 0x0000a27c, 0x050e039c },
+ { 0x0000d35c, 0x07ffffef },
+ { 0x0000d360, 0x0fffffe7 },
+ { 0x0000d364, 0x17ffffe5 },
+ { 0x0000d368, 0x1fffffe4 },
+ { 0x0000d36c, 0x37ffffe3 },
+ { 0x0000d370, 0x3fffffe3 },
+ { 0x0000d374, 0x57ffffe3 },
+ { 0x0000d378, 0x5fffffe2 },
+ { 0x0000d37c, 0x7fffffe2 },
+ { 0x0000d380, 0x7f3c7bba },
+ { 0x0000d384, 0xf3307ff0 },
+ { 0x0000a388, 0x0c000000 },
+ { 0x0000a38c, 0x20202020 },
+ { 0x0000a390, 0x20202020 },
+ { 0x0000a394, 0x39ce739c },
+ { 0x0000a398, 0x0000039c },
+ { 0x0000a39c, 0x00000001 },
+ { 0x0000a3a0, 0x00000000 },
+ { 0x0000a3a4, 0x00000000 },
+ { 0x0000a3a8, 0x00000000 },
+ { 0x0000a3ac, 0x00000000 },
+ { 0x0000a3b0, 0x00000000 },
+ { 0x0000a3b4, 0x00000000 },
+ { 0x0000a3b8, 0x00000000 },
+ { 0x0000a3bc, 0x00000000 },
+ { 0x0000a3c0, 0x00000000 },
+ { 0x0000a3c4, 0x00000000 },
+ { 0x0000a3cc, 0x20202020 },
+ { 0x0000a3d0, 0x20202020 },
+ { 0x0000a3d4, 0x20202020 },
+ { 0x0000a3dc, 0x39ce739c },
+ { 0x0000a3e0, 0x0000039c },
+ { 0x0000a3e4, 0x00000000 },
+ { 0x0000a3e8, 0x18c43433 },
+ { 0x0000a3ec, 0x00f70081 },
+ { 0x00007800, 0x00140000 },
+ { 0x00007804, 0x0e4548d8 },
+ { 0x00007808, 0x54214514 },
+ { 0x0000780c, 0x02025820 },
+ { 0x00007810, 0x71c0d388 },
+ { 0x00007814, 0x924934a8 },
+ { 0x0000781c, 0x00000000 },
+ { 0x00007820, 0x00000c04 },
+ { 0x00007824, 0x00d86fff },
+ { 0x00007828, 0x26d2491b },
+ { 0x0000782c, 0x6e36d97b },
+ { 0x00007830, 0xedb6d96c },
+ { 0x00007834, 0x71400086 },
+ { 0x00007838, 0xfac68800 },
+ { 0x0000783c, 0x0001fffe },
+ { 0x00007840, 0xffeb1a20 },
+ { 0x00007844, 0x000c0db6 },
+ { 0x00007848, 0x6db61b6f },
+ { 0x0000784c, 0x6d9b66db },
+ { 0x00007850, 0x6d8c6dba },
+ { 0x00007854, 0x00040000 },
+ { 0x00007858, 0xdb003012 },
+ { 0x0000785c, 0x04924914 },
+ { 0x00007860, 0x21084210 },
+ { 0x00007864, 0xf7d7ffde },
+ { 0x00007868, 0xc2034080 },
+ { 0x0000786c, 0x48609eb4 },
+ { 0x00007870, 0x10142c00 },
+};
+
+static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
+ {0x00004040, 0x9248fd00 },
+ {0x00004040, 0x24924924 },
+ {0x00004040, 0xa8000019 },
+ {0x00004040, 0x13160820 },
+ {0x00004040, 0xe5980560 },
+ {0x00004040, 0xc01dcffd },
+ {0x00004040, 0x1aaabe41 },
+ {0x00004040, 0xbe105554 },
+ {0x00004040, 0x00043007 },
+ {0x00004044, 0x00000000 },
+};
+
+static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = {
+ {0x00004040, 0x9248fd00 },
+ {0x00004040, 0x24924924 },
+ {0x00004040, 0xa8000019 },
+ {0x00004040, 0x13160820 },
+ {0x00004040, 0xe5980560 },
+ {0x00004040, 0xc01dcffc },
+ {0x00004040, 0x1aaabe41 },
+ {0x00004040, 0xbe105554 },
+ {0x00004040, 0x00043007 },
+ {0x00004044, 0x00000000 },
+};
+
+static const u_int32_t ar9285Modes_9285_1_2[][6] = {
+ { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+ { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+ { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+ { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
+ { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+ { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
+ { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
+ { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+ { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+ { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+ { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+ { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+ { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+ { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
+ { 0x00009844, 0x0372161e, 0x0372161e, 0x03720020, 0x03720020, 0x037216a0 },
+ { 0x00009848, 0x00001066, 0x00001066, 0x00000057, 0x00000057, 0x00001059 },
+ { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
+ { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
+ { 0x0000985c, 0x3139605e, 0x3139605e, 0x3136605e, 0x3136605e, 0x3139605e },
+ { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 },
+ { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+ { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
+ { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
+ { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
+ { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
+ { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
+ { 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010 },
+ { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c },
+ { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
+ { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
+ { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+ { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
+ { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+ { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+ { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00009a00, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
+ { 0x00009a04, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
+ { 0x00009a08, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
+ { 0x00009a0c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
+ { 0x00009a10, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
+ { 0x00009a14, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
+ { 0x00009a18, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
+ { 0x00009a1c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
+ { 0x00009a20, 0x00000000, 0x00000000, 0x00068114, 0x00068114, 0x00000000 },
+ { 0x00009a24, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
+ { 0x00009a28, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
+ { 0x00009a2c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
+ { 0x00009a30, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
+ { 0x00009a34, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
+ { 0x00009a38, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
+ { 0x00009a3c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
+ { 0x00009a40, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
+ { 0x00009a44, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
+ { 0x00009a48, 0x00000000, 0x00000000, 0x00068284, 0x00068284, 0x00000000 },
+ { 0x00009a4c, 0x00000000, 0x00000000, 0x00068288, 0x00068288, 0x00000000 },
+ { 0x00009a50, 0x00000000, 0x00000000, 0x00068220, 0x00068220, 0x00000000 },
+ { 0x00009a54, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
+ { 0x00009a58, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
+ { 0x00009a5c, 0x00000000, 0x00000000, 0x00068304, 0x00068304, 0x00000000 },
+ { 0x00009a60, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
+ { 0x00009a64, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
+ { 0x00009a68, 0x00000000, 0x00000000, 0x00068380, 0x00068380, 0x00000000 },
+ { 0x00009a6c, 0x00000000, 0x00000000, 0x00068384, 0x00068384, 0x00000000 },
+ { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
+ { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
+ { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
+ { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
+ { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
+ { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
+ { 0x00009a88, 0x00000000, 0x00000000, 0x00068b04, 0x00068b04, 0x00000000 },
+ { 0x00009a8c, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
+ { 0x00009a90, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
+ { 0x00009a94, 0x00000000, 0x00000000, 0x00068b0c, 0x00068b0c, 0x00000000 },
+ { 0x00009a98, 0x00000000, 0x00000000, 0x00068b80, 0x00068b80, 0x00000000 },
+ { 0x00009a9c, 0x00000000, 0x00000000, 0x00068b84, 0x00068b84, 0x00000000 },
+ { 0x00009aa0, 0x00000000, 0x00000000, 0x00068b88, 0x00068b88, 0x00000000 },
+ { 0x00009aa4, 0x00000000, 0x00000000, 0x00068b8c, 0x00068b8c, 0x00000000 },
+ { 0x00009aa8, 0x00000000, 0x00000000, 0x000b8b90, 0x000b8b90, 0x00000000 },
+ { 0x00009aac, 0x00000000, 0x00000000, 0x000b8f80, 0x000b8f80, 0x00000000 },
+ { 0x00009ab0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
+ { 0x00009ab4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
+ { 0x00009ab8, 0x00000000, 0x00000000, 0x000b8f8c, 0x000b8f8c, 0x00000000 },
+ { 0x00009abc, 0x00000000, 0x00000000, 0x000b8f90, 0x000b8f90, 0x00000000 },
+ { 0x00009ac0, 0x00000000, 0x00000000, 0x000bb30c, 0x000bb30c, 0x00000000 },
+ { 0x00009ac4, 0x00000000, 0x00000000, 0x000bb310, 0x000bb310, 0x00000000 },
+ { 0x00009ac8, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
+ { 0x00009acc, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
+ { 0x00009ad0, 0x00000000, 0x00000000, 0x000bb324, 0x000bb324, 0x00000000 },
+ { 0x00009ad4, 0x00000000, 0x00000000, 0x000bb704, 0x000bb704, 0x00000000 },
+ { 0x00009ad8, 0x00000000, 0x00000000, 0x000f96a4, 0x000f96a4, 0x00000000 },
+ { 0x00009adc, 0x00000000, 0x00000000, 0x000f96a8, 0x000f96a8, 0x00000000 },
+ { 0x00009ae0, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
+ { 0x00009ae4, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
+ { 0x00009ae8, 0x00000000, 0x00000000, 0x000f9720, 0x000f9720, 0x00000000 },
+ { 0x00009aec, 0x00000000, 0x00000000, 0x000f9724, 0x000f9724, 0x00000000 },
+ { 0x00009af0, 0x00000000, 0x00000000, 0x000f9728, 0x000f9728, 0x00000000 },
+ { 0x00009af4, 0x00000000, 0x00000000, 0x000f972c, 0x000f972c, 0x00000000 },
+ { 0x00009af8, 0x00000000, 0x00000000, 0x000f97a0, 0x000f97a0, 0x00000000 },
+ { 0x00009afc, 0x00000000, 0x00000000, 0x000f97a4, 0x000f97a4, 0x00000000 },
+ { 0x00009b00, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
+ { 0x00009b04, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
+ { 0x00009b08, 0x00000000, 0x00000000, 0x000fb7b4, 0x000fb7b4, 0x00000000 },
+ { 0x00009b0c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
+ { 0x00009b10, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
+ { 0x00009b14, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
+ { 0x00009b18, 0x00000000, 0x00000000, 0x000fb7ad, 0x000fb7ad, 0x00000000 },
+ { 0x00009b1c, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
+ { 0x00009b20, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
+ { 0x00009b24, 0x00000000, 0x00000000, 0x000fb7b9, 0x000fb7b9, 0x00000000 },
+ { 0x00009b28, 0x00000000, 0x00000000, 0x000fb7c5, 0x000fb7c5, 0x00000000 },
+ { 0x00009b2c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
+ { 0x00009b30, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
+ { 0x00009b34, 0x00000000, 0x00000000, 0x000fb7d5, 0x000fb7d5, 0x00000000 },
+ { 0x00009b38, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
+ { 0x00009b3c, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
+ { 0x00009b40, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
+ { 0x00009b44, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
+ { 0x00009b48, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
+ { 0x00009b4c, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
+ { 0x00009b50, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
+ { 0x00009b54, 0x00000000, 0x00000000, 0x000fb7c7, 0x000fb7c7, 0x00000000 },
+ { 0x00009b58, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
+ { 0x00009b5c, 0x00000000, 0x00000000, 0x000fb7cf, 0x000fb7cf, 0x00000000 },
+ { 0x00009b60, 0x00000000, 0x00000000, 0x000fb7d7, 0x000fb7d7, 0x00000000 },
+ { 0x00009b64, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b68, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b6c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b70, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b74, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b78, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b7c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b80, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b84, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b88, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b8c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b90, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b94, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b98, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009b9c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009ba0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009ba4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009ba8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bac, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bb0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bb4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bb8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bbc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bc0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bc4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bc8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bcc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bd0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bd4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bd8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bdc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009be0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009be4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009be8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bec, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bf0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bf4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bf8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x00009bfc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+ { 0x0000aa00, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
+ { 0x0000aa04, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
+ { 0x0000aa08, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
+ { 0x0000aa0c, 0x00000000, 0x00000000, 0x00068080, 0x00068080, 0x00000000 },
+ { 0x0000aa10, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
+ { 0x0000aa14, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
+ { 0x0000aa18, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
+ { 0x0000aa1c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
+ { 0x0000aa20, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
+ { 0x0000aa24, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
+ { 0x0000aa28, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
+ { 0x0000aa2c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
+ { 0x0000aa30, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
+ { 0x0000aa34, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
+ { 0x0000aa38, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
+ { 0x0000aa3c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
+ { 0x0000aa40, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
+ { 0x0000aa44, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
+ { 0x0000aa48, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
+ { 0x0000aa4c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
+ { 0x0000aa50, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
+ { 0x0000aa54, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
+ { 0x0000aa58, 0x00000000, 0x00000000, 0x000681ac, 0x000681ac, 0x00000000 },
+ { 0x0000aa5c, 0x00000000, 0x00000000, 0x0006821c, 0x0006821c, 0x00000000 },
+ { 0x0000aa60, 0x00000000, 0x00000000, 0x00068224, 0x00068224, 0x00000000 },
+ { 0x0000aa64, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
+ { 0x0000aa68, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
+ { 0x0000aa6c, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
+ { 0x0000aa70, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
+ { 0x0000aa74, 0x00000000, 0x00000000, 0x00068310, 0x00068310, 0x00000000 },
+ { 0x0000aa78, 0x00000000, 0x00000000, 0x00068788, 0x00068788, 0x00000000 },
+ { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006878c, 0x0006878c, 0x00000000 },
+ { 0x0000aa80, 0x00000000, 0x00000000, 0x00068790, 0x00068790, 0x00000000 },
+ { 0x0000aa84, 0x00000000, 0x00000000, 0x00068794, 0x00068794, 0x00000000 },
+ { 0x0000aa88, 0x00000000, 0x00000000, 0x00068798, 0x00068798, 0x00000000 },
+ { 0x0000aa8c, 0x00000000, 0x00000000, 0x0006879c, 0x0006879c, 0x00000000 },
+ { 0x0000aa90, 0x00000000, 0x00000000, 0x00068b89, 0x00068b89, 0x00000000 },
+ { 0x0000aa94, 0x00000000, 0x00000000, 0x00068b8d, 0x00068b8d, 0x00000000 },
+ { 0x0000aa98, 0x00000000, 0x00000000, 0x00068b91, 0x00068b91, 0x00000000 },
+ { 0x0000aa9c, 0x00000000, 0x00000000, 0x00068b95, 0x00068b95, 0x00000000 },
+ { 0x0000aaa0, 0x00000000, 0x00000000, 0x00068b99, 0x00068b99, 0x00000000 },
+ { 0x0000aaa4, 0x00000000, 0x00000000, 0x00068ba5, 0x00068ba5, 0x00000000 },
+ { 0x0000aaa8, 0x00000000, 0x00000000, 0x00068ba9, 0x00068ba9, 0x00000000 },
+ { 0x0000aaac, 0x00000000, 0x00000000, 0x00068bad, 0x00068bad, 0x00000000 },
+ { 0x0000aab0, 0x00000000, 0x00000000, 0x000b8b0c, 0x000b8b0c, 0x00000000 },
+ { 0x0000aab4, 0x00000000, 0x00000000, 0x000b8f10, 0x000b8f10, 0x00000000 },
+ { 0x0000aab8, 0x00000000, 0x00000000, 0x000b8f14, 0x000b8f14, 0x00000000 },
+ { 0x0000aabc, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
+ { 0x0000aac0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
+ { 0x0000aac4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
+ { 0x0000aac8, 0x00000000, 0x00000000, 0x000bb380, 0x000bb380, 0x00000000 },
+ { 0x0000aacc, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
+ { 0x0000aad0, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
+ { 0x0000aad4, 0x00000000, 0x00000000, 0x000bb38c, 0x000bb38c, 0x00000000 },
+ { 0x0000aad8, 0x00000000, 0x00000000, 0x000bb394, 0x000bb394, 0x00000000 },
+ { 0x0000aadc, 0x00000000, 0x00000000, 0x000bb798, 0x000bb798, 0x00000000 },
+ { 0x0000aae0, 0x00000000, 0x00000000, 0x000f970c, 0x000f970c, 0x00000000 },
+ { 0x0000aae4, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
+ { 0x0000aae8, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
+ { 0x0000aaec, 0x00000000, 0x00000000, 0x000f9718, 0x000f9718, 0x00000000 },
+ { 0x0000aaf0, 0x00000000, 0x00000000, 0x000f9705, 0x000f9705, 0x00000000 },
+ { 0x0000aaf4, 0x00000000, 0x00000000, 0x000f9709, 0x000f9709, 0x00000000 },
+ { 0x0000aaf8, 0x00000000, 0x00000000, 0x000f970d, 0x000f970d, 0x00000000 },
+ { 0x0000aafc, 0x00000000, 0x00000000, 0x000f9711, 0x000f9711, 0x00000000 },
+ { 0x0000ab00, 0x00000000, 0x00000000, 0x000f9715, 0x000f9715, 0x00000000 },
+ { 0x0000ab04, 0x00000000, 0x00000000, 0x000f9719, 0x000f9719, 0x00000000 },
+ { 0x0000ab08, 0x00000000, 0x00000000, 0x000fb7a4, 0x000fb7a4, 0x00000000 },
+ { 0x0000ab0c, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
+ { 0x0000ab10, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
+ { 0x0000ab14, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
+ { 0x0000ab18, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
+ { 0x0000ab1c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
+ { 0x0000ab20, 0x00000000, 0x00000000, 0x000fb7bc, 0x000fb7bc, 0x00000000 },
+ { 0x0000ab24, 0x00000000, 0x00000000, 0x000fb7a1, 0x000fb7a1, 0x00000000 },
+ { 0x0000ab28, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
+ { 0x0000ab2c, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
+ { 0x0000ab30, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
+ { 0x0000ab34, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
+ { 0x0000ab38, 0x00000000, 0x00000000, 0x000fb7bd, 0x000fb7bd, 0x00000000 },
+ { 0x0000ab3c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
+ { 0x0000ab40, 0x00000000, 0x00000000, 0x000fb7cd, 0x000fb7cd, 0x00000000 },
+ { 0x0000ab44, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
+ { 0x0000ab48, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
+ { 0x0000ab4c, 0x00000000, 0x00000000, 0x000fb7c2, 0x000fb7c2, 0x00000000 },
+ { 0x0000ab50, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
+ { 0x0000ab54, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
+ { 0x0000ab58, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
+ { 0x0000ab5c, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
+ { 0x0000ab60, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
+ { 0x0000ab64, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
+ { 0x0000ab68, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
+ { 0x0000ab6c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab70, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab74, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab78, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab7c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab80, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab84, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab88, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab8c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab90, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab94, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab98, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000ab9c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000aba0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000aba4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000aba8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abac, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abb0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abb4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abb8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abbc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abc0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abc4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abc8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abcc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abd0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abd4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abd8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abdc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abe0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abe4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abe8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abec, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abf0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abf4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abf8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000abfc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
+ { 0x0000a20c, 0x00000014, 0x00000014, 0x00000000, 0x00000000, 0x0001f000 },
+ { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+ { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+ { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
+ { 0x0000a274, 0x0a81c652, 0x0a81c652, 0x0a820652, 0x0a820652, 0x0a82a652 },
+ { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000a304, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
+ { 0x0000a308, 0x00000000, 0x00000000, 0x00010408, 0x00010408, 0x00000000 },
+ { 0x0000a30c, 0x00000000, 0x00000000, 0x0001860a, 0x0001860a, 0x00000000 },
+ { 0x0000a310, 0x00000000, 0x00000000, 0x00020818, 0x00020818, 0x00000000 },
+ { 0x0000a314, 0x00000000, 0x00000000, 0x00024858, 0x00024858, 0x00000000 },
+ { 0x0000a318, 0x00000000, 0x00000000, 0x00026859, 0x00026859, 0x00000000 },
+ { 0x0000a31c, 0x00000000, 0x00000000, 0x0002985b, 0x0002985b, 0x00000000 },
+ { 0x0000a320, 0x00000000, 0x00000000, 0x0002b89a, 0x0002b89a, 0x00000000 },
+ { 0x0000a324, 0x00000000, 0x00000000, 0x0002d89b, 0x0002d89b, 0x00000000 },
+ { 0x0000a328, 0x00000000, 0x00000000, 0x0002f89c, 0x0002f89c, 0x00000000 },
+ { 0x0000a32c, 0x00000000, 0x00000000, 0x0003189d, 0x0003189d, 0x00000000 },
+ { 0x0000a330, 0x00000000, 0x00000000, 0x0003389e, 0x0003389e, 0x00000000 },
+ { 0x0000a334, 0x00000000, 0x00000000, 0x000368de, 0x000368de, 0x00000000 },
+ { 0x0000a338, 0x00000000, 0x00000000, 0x0003891e, 0x0003891e, 0x00000000 },
+ { 0x0000a33c, 0x00000000, 0x00000000, 0x0003a95e, 0x0003a95e, 0x00000000 },
+ { 0x0000a340, 0x00000000, 0x00000000, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
+};
+
+static const u_int32_t ar9285Common_9285_1_2[][2] = {
+ { 0x0000000c, 0x00000000 },
+ { 0x00000030, 0x00020045 },
+ { 0x00000034, 0x00000005 },
+ { 0x00000040, 0x00000000 },
+ { 0x00000044, 0x00000008 },
+ { 0x00000048, 0x00000008 },
+ { 0x0000004c, 0x00000010 },
+ { 0x00000050, 0x00000000 },
+ { 0x00000054, 0x0000001f },
+ { 0x00000800, 0x00000000 },
+ { 0x00000804, 0x00000000 },
+ { 0x00000808, 0x00000000 },
+ { 0x0000080c, 0x00000000 },
+ { 0x00000810, 0x00000000 },
+ { 0x00000814, 0x00000000 },
+ { 0x00000818, 0x00000000 },
+ { 0x0000081c, 0x00000000 },
+ { 0x00000820, 0x00000000 },
+ { 0x00000824, 0x00000000 },
+ { 0x00001040, 0x002ffc0f },
+ { 0x00001044, 0x002ffc0f },
+ { 0x00001048, 0x002ffc0f },
+ { 0x0000104c, 0x002ffc0f },
+ { 0x00001050, 0x002ffc0f },
+ { 0x00001054, 0x002ffc0f },
+ { 0x00001058, 0x002ffc0f },
+ { 0x0000105c, 0x002ffc0f },
+ { 0x00001060, 0x002ffc0f },
+ { 0x00001064, 0x002ffc0f },
+ { 0x00001230, 0x00000000 },
+ { 0x00001270, 0x00000000 },
+ { 0x00001038, 0x00000000 },
+ { 0x00001078, 0x00000000 },
+ { 0x000010b8, 0x00000000 },
+ { 0x000010f8, 0x00000000 },
+ { 0x00001138, 0x00000000 },
+ { 0x00001178, 0x00000000 },
+ { 0x000011b8, 0x00000000 },
+ { 0x000011f8, 0x00000000 },
+ { 0x00001238, 0x00000000 },
+ { 0x00001278, 0x00000000 },
+ { 0x000012b8, 0x00000000 },
+ { 0x000012f8, 0x00000000 },
+ { 0x00001338, 0x00000000 },
+ { 0x00001378, 0x00000000 },
+ { 0x000013b8, 0x00000000 },
+ { 0x000013f8, 0x00000000 },
+ { 0x00001438, 0x00000000 },
+ { 0x00001478, 0x00000000 },
+ { 0x000014b8, 0x00000000 },
+ { 0x000014f8, 0x00000000 },
+ { 0x00001538, 0x00000000 },
+ { 0x00001578, 0x00000000 },
+ { 0x000015b8, 0x00000000 },
+ { 0x000015f8, 0x00000000 },
+ { 0x00001638, 0x00000000 },
+ { 0x00001678, 0x00000000 },
+ { 0x000016b8, 0x00000000 },
+ { 0x000016f8, 0x00000000 },
+ { 0x00001738, 0x00000000 },
+ { 0x00001778, 0x00000000 },
+ { 0x000017b8, 0x00000000 },
+ { 0x000017f8, 0x00000000 },
+ { 0x0000103c, 0x00000000 },
+ { 0x0000107c, 0x00000000 },
+ { 0x000010bc, 0x00000000 },
+ { 0x000010fc, 0x00000000 },
+ { 0x0000113c, 0x00000000 },
+ { 0x0000117c, 0x00000000 },
+ { 0x000011bc, 0x00000000 },
+ { 0x000011fc, 0x00000000 },
+ { 0x0000123c, 0x00000000 },
+ { 0x0000127c, 0x00000000 },
+ { 0x000012bc, 0x00000000 },
+ { 0x000012fc, 0x00000000 },
+ { 0x0000133c, 0x00000000 },
+ { 0x0000137c, 0x00000000 },
+ { 0x000013bc, 0x00000000 },
+ { 0x000013fc, 0x00000000 },
+ { 0x0000143c, 0x00000000 },
+ { 0x0000147c, 0x00000000 },
+ { 0x00004030, 0x00000002 },
+ { 0x0000403c, 0x00000002 },
+ { 0x00004024, 0x0000001f },
+ { 0x00004060, 0x00000000 },
+ { 0x00004064, 0x00000000 },
+ { 0x00007010, 0x00000031 },
+ { 0x00007034, 0x00000002 },
+ { 0x00007038, 0x000004c2 },
+ { 0x00008004, 0x00000000 },
+ { 0x00008008, 0x00000000 },
+ { 0x0000800c, 0x00000000 },
+ { 0x00008018, 0x00000700 },
+ { 0x00008020, 0x00000000 },
+ { 0x00008038, 0x00000000 },
+ { 0x0000803c, 0x00000000 },
+ { 0x00008048, 0x00000000 },
+ { 0x00008054, 0x00000000 },
+ { 0x00008058, 0x00000000 },
+ { 0x0000805c, 0x000fc78f },
+ { 0x00008060, 0x0000000f },
+ { 0x00008064, 0x00000000 },
+ { 0x00008070, 0x00000000 },
+ { 0x000080c0, 0x2a80001a },
+ { 0x000080c4, 0x05dc01e0 },
+ { 0x000080c8, 0x1f402710 },
+ { 0x000080cc, 0x01f40000 },
+ { 0x000080d0, 0x00001e00 },
+ { 0x000080d4, 0x00000000 },
+ { 0x000080d8, 0x00400000 },
+ { 0x000080e0, 0xffffffff },
+ { 0x000080e4, 0x0000ffff },
+ { 0x000080e8, 0x003f3f3f },
+ { 0x000080ec, 0x00000000 },
+ { 0x000080f0, 0x00000000 },
+ { 0x000080f4, 0x00000000 },
+ { 0x000080f8, 0x00000000 },
+ { 0x000080fc, 0x00020000 },
+ { 0x00008100, 0x00020000 },
+ { 0x00008104, 0x00000001 },
+ { 0x00008108, 0x00000052 },
+ { 0x0000810c, 0x00000000 },
+ { 0x00008110, 0x00000168 },
+ { 0x00008118, 0x000100aa },
+ { 0x0000811c, 0x00003210 },
+ { 0x00008120, 0x08f04800 },
+ { 0x00008124, 0x00000000 },
+ { 0x00008128, 0x00000000 },
+ { 0x0000812c, 0x00000000 },
+ { 0x00008130, 0x00000000 },
+ { 0x00008134, 0x00000000 },
+ { 0x00008138, 0x00000000 },
+ { 0x0000813c, 0x00000000 },
+ { 0x00008144, 0xffffffff },
+ { 0x00008168, 0x00000000 },
+ { 0x0000816c, 0x00000000 },
+ { 0x00008170, 0x32143320 },
+ { 0x00008174, 0xfaa4fa50 },
+ { 0x00008178, 0x00000100 },
+ { 0x0000817c, 0x00000000 },
+ { 0x000081c0, 0x00000000 },
+ { 0x000081d0, 0x00003210 },
+ { 0x000081ec, 0x00000000 },
+ { 0x000081f0, 0x00000000 },
+ { 0x000081f4, 0x00000000 },
+ { 0x000081f8, 0x00000000 },
+ { 0x000081fc, 0x00000000 },
+ { 0x00008200, 0x00000000 },
+ { 0x00008204, 0x00000000 },
+ { 0x00008208, 0x00000000 },
+ { 0x0000820c, 0x00000000 },
+ { 0x00008210, 0x00000000 },
+ { 0x00008214, 0x00000000 },
+ { 0x00008218, 0x00000000 },
+ { 0x0000821c, 0x00000000 },
+ { 0x00008220, 0x00000000 },
+ { 0x00008224, 0x00000000 },
+ { 0x00008228, 0x00000000 },
+ { 0x0000822c, 0x00000000 },
+ { 0x00008230, 0x00000000 },
+ { 0x00008234, 0x00000000 },
+ { 0x00008238, 0x00000000 },
+ { 0x0000823c, 0x00000000 },
+ { 0x00008240, 0x00100000 },
+ { 0x00008244, 0x0010f400 },
+ { 0x00008248, 0x00000100 },
+ { 0x0000824c, 0x0001e800 },
+ { 0x00008250, 0x00000000 },
+ { 0x00008254, 0x00000000 },
+ { 0x00008258, 0x00000000 },
+ { 0x0000825c, 0x400000ff },
+ { 0x00008260, 0x00080922 },
+ { 0x00008264, 0xa8a00010 },
+ { 0x00008270, 0x00000000 },
+ { 0x00008274, 0x40000000 },
+ { 0x00008278, 0x003e4180 },
+ { 0x0000827c, 0x00000000 },
+ { 0x00008284, 0x0000002c },
+ { 0x00008288, 0x0000002c },
+ { 0x0000828c, 0x00000000 },
+ { 0x00008294, 0x00000000 },
+ { 0x00008298, 0x00000000 },
+ { 0x0000829c, 0x00000000 },
+ { 0x00008300, 0x00000040 },
+ { 0x00008314, 0x00000000 },
+ { 0x00008328, 0x00000000 },
+ { 0x0000832c, 0x00000001 },
+ { 0x00008330, 0x00000302 },
+ { 0x00008334, 0x00000e00 },
+ { 0x00008338, 0x00ff0000 },
+ { 0x0000833c, 0x00000000 },
+ { 0x00008340, 0x00010380 },
+ { 0x00008344, 0x00581043 },
+ { 0x00009808, 0x00000000 },
+ { 0x0000980c, 0xafe68e30 },
+ { 0x00009810, 0xfd14e000 },
+ { 0x00009814, 0x9c0a9f6b },
+ { 0x0000981c, 0x00000000 },
+ { 0x0000982c, 0x0000a000 },
+ { 0x00009830, 0x00000000 },
+ { 0x0000983c, 0x00200400 },
+ { 0x0000984c, 0x0040233c },
+ { 0x00009854, 0x00000044 },
+ { 0x00009900, 0x00000000 },
+ { 0x00009904, 0x00000000 },
+ { 0x00009908, 0x00000000 },
+ { 0x0000990c, 0x00000000 },
+ { 0x00009910, 0x01002310 },
+ { 0x0000991c, 0x10000fff },
+ { 0x00009920, 0x04900000 },
+ { 0x00009928, 0x00000001 },
+ { 0x0000992c, 0x00000004 },
+ { 0x00009934, 0x1e1f2022 },
+ { 0x00009938, 0x0a0b0c0d },
+ { 0x0000993c, 0x00000000 },
+ { 0x00009940, 0x14750604 },
+ { 0x00009948, 0x9280c00a },
+ { 0x0000994c, 0x00020028 },
+ { 0x00009954, 0x5f3ca3de },
+ { 0x00009958, 0x2108ecff },
+ { 0x00009968, 0x000003ce },
+ { 0x00009970, 0x192bb515 },
+ { 0x00009974, 0x00000000 },
+ { 0x00009978, 0x00000001 },
+ { 0x0000997c, 0x00000000 },
+ { 0x00009980, 0x00000000 },
+ { 0x00009984, 0x00000000 },
+ { 0x00009988, 0x00000000 },
+ { 0x0000998c, 0x00000000 },
+ { 0x00009990, 0x00000000 },
+ { 0x00009994, 0x00000000 },
+ { 0x00009998, 0x00000000 },
+ { 0x0000999c, 0x00000000 },
+ { 0x000099a0, 0x00000000 },
+ { 0x000099a4, 0x00000001 },
+ { 0x000099a8, 0x201fff00 },
+ { 0x000099ac, 0x2def1000 },
+ { 0x000099b0, 0x03051000 },
+ { 0x000099b4, 0x00000820 },
+ { 0x000099dc, 0x00000000 },
+ { 0x000099e0, 0x00000000 },
+ { 0x000099e4, 0xaaaaaaaa },
+ { 0x000099e8, 0x3c466478 },
+ { 0x000099ec, 0x0cc80caa },
+ { 0x000099f0, 0x00000000 },
+ { 0x0000a208, 0x803e6788 },
+ { 0x0000a210, 0x4080a333 },
+ { 0x0000a214, 0x00206c10 },
+ { 0x0000a218, 0x009c4060 },
+ { 0x0000a220, 0x01834061 },
+ { 0x0000a224, 0x00000400 },
+ { 0x0000a228, 0x000003b5 },
+ { 0x0000a22c, 0x00000000 },
+ { 0x0000a234, 0x20202020 },
+ { 0x0000a238, 0x20202020 },
+ { 0x0000a244, 0x00000000 },
+ { 0x0000a248, 0xfffffffc },
+ { 0x0000a24c, 0x00000000 },
+ { 0x0000a254, 0x00000000 },
+ { 0x0000a258, 0x0ccb5380 },
+ { 0x0000a25c, 0x15151501 },
+ { 0x0000a260, 0xdfa90f01 },
+ { 0x0000a268, 0x00000000 },
+ { 0x0000a26c, 0x0ebae9e6 },
+ { 0x0000d270, 0x0d820820 },
+ { 0x0000a278, 0x318c6318 },
+ { 0x0000a27c, 0x050c0318 },
+ { 0x0000d35c, 0x07ffffef },
+ { 0x0000d360, 0x0fffffe7 },
+ { 0x0000d364, 0x17ffffe5 },
+ { 0x0000d368, 0x1fffffe4 },
+ { 0x0000d36c, 0x37ffffe3 },
+ { 0x0000d370, 0x3fffffe3 },
+ { 0x0000d374, 0x57ffffe3 },
+ { 0x0000d378, 0x5fffffe2 },
+ { 0x0000d37c, 0x7fffffe2 },
+ { 0x0000d380, 0x7f3c7bba },
+ { 0x0000d384, 0xf3307ff0 },
+ { 0x0000a388, 0x0c000000 },
+ { 0x0000a38c, 0x20202020 },
+ { 0x0000a390, 0x20202020 },
+ { 0x0000a394, 0x318c6318 },
+ { 0x0000a398, 0x00000318 },
+ { 0x0000a39c, 0x00000001 },
+ { 0x0000a3a0, 0x00000000 },
+ { 0x0000a3a4, 0x00000000 },
+ { 0x0000a3a8, 0x00000000 },
+ { 0x0000a3ac, 0x00000000 },
+ { 0x0000a3b0, 0x00000000 },
+ { 0x0000a3b4, 0x00000000 },
+ { 0x0000a3b8, 0x00000000 },
+ { 0x0000a3bc, 0x00000000 },
+ { 0x0000a3c0, 0x00000000 },
+ { 0x0000a3c4, 0x00000000 },
+ { 0x0000a3cc, 0x20202020 },
+ { 0x0000a3d0, 0x20202020 },
+ { 0x0000a3d4, 0x20202020 },
+ { 0x0000a3dc, 0x318c6318 },
+ { 0x0000a3e0, 0x00000318 },
+ { 0x0000a3e4, 0x00000000 },
+ { 0x0000a3e8, 0x18c43433 },
+ { 0x0000a3ec, 0x00f70081 },
+ { 0x00007800, 0x00140000 },
+ { 0x00007804, 0x0e4548d8 },
+ { 0x00007808, 0x54214514 },
+ { 0x0000780c, 0x02025820 },
+ { 0x00007810, 0x71c0d388 },
+ { 0x00007814, 0x924934a8 },
+ { 0x0000781c, 0x00000000 },
+ { 0x00007820, 0x00000c04 },
+ { 0x00007824, 0x00d86fff },
+ { 0x00007828, 0x26d2491b },
+ { 0x0000782c, 0x6e36d97b },
+ { 0x00007830, 0xedb6d96e },
+ { 0x00007834, 0x71400087 },
+ { 0x00007838, 0xfac68801 },
+ { 0x0000783c, 0x0001fffe },
+ { 0x00007840, 0xffeb1a20 },
+ { 0x00007844, 0x000c0db6 },
+ { 0x00007848, 0x6db61b6f },
+ { 0x0000784c, 0x6d9b66db },
+ { 0x00007850, 0x6d8c6dba },
+ { 0x00007854, 0x00040000 },
+ { 0x00007858, 0xdb003012 },
+ { 0x0000785c, 0x04924914 },
+ { 0x00007860, 0x21084210 },
+ { 0x00007864, 0xf7d7ffde },
+ { 0x00007868, 0xc2034080 },
+ { 0x0000786c, 0x48609eb4 },
+ { 0x00007870, 0x10142c00 },
+};
+
+static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
+ {0x00004040, 0x9248fd00 },
+ {0x00004040, 0x24924924 },
+ {0x00004040, 0xa8000019 },
+ {0x00004040, 0x13160820 },
+ {0x00004040, 0xe5980560 },
+ {0x00004040, 0xc01dcffd },
+ {0x00004040, 0x1aaabe41 },
+ {0x00004040, 0xbe105554 },
+ {0x00004040, 0x00043007 },
+ {0x00004044, 0x00000000 },
+};
+
+static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
+ {0x00004040, 0x9248fd00 },
+ {0x00004040, 0x24924924 },
+ {0x00004040, 0xa8000019 },
+ {0x00004040, 0x13160820 },
+ {0x00004040, 0xe5980560 },
+ {0x00004040, 0xc01dcffc },
+ {0x00004040, 0x1aaabe41 },
+ {0x00004040, 0xbe105554 },
+ {0x00004040, 0x00043007 },
+ {0x00004044, 0x00000000 },
+};
diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath9k/mac.c
index a4e98986dbc..af32d091dc3 100644
--- a/drivers/net/wireless/ath9k/mac.c
+++ b/drivers/net/wireless/ath9k/mac.c
@@ -916,12 +916,11 @@ void ath9k_hw_rxena(struct ath_hal *ah)
void ath9k_hw_startpcureceive(struct ath_hal *ah)
{
- REG_CLR_BIT(ah, AR_DIAG_SW,
- (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
-
ath9k_enable_mib_counters(ah);
ath9k_ani_reset(ah);
+
+ REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
}
void ath9k_hw_stoppcurecv(struct ath_hal *ah)
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 26c47577e18..02e1771bb27 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -34,6 +34,7 @@ static struct pci_device_id ath_pci_id_table[] __devinitdata = {
{ PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */
{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
+ { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
{ 0 }
};
@@ -60,7 +61,8 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz)
static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
{
- sc->sc_curmode = mode;
+ if (!sc->sc_curaid)
+ sc->cur_rate_table = sc->hw_rate_table[mode];
/*
* All protection frames are transmited at 2Mb/s for
* 11g, otherwise at 1Mb/s.
@@ -346,7 +348,7 @@ static void ath_ani_calibrate(unsigned long data)
* don't calibrate when we're scanning.
* we are most likely not on our home channel.
*/
- if (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC)
+ if (sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC)
return;
/* Long calibration runs independently of short calibration. */
@@ -485,9 +487,9 @@ static void ath9k_tasklet(unsigned long data)
if (status &
(ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
- spin_lock_bh(&sc->sc_rxflushlock);
+ spin_lock_bh(&sc->rx.rxflushlock);
ath_rx_tasklet(sc, 0);
- spin_unlock_bh(&sc->sc_rxflushlock);
+ spin_unlock_bh(&sc->rx.rxflushlock);
}
/* XXX: optimize this */
if (status & ATH9K_INT_TX)
@@ -597,6 +599,8 @@ static irqreturn_t ath_isr(int irq, void *dev)
}
} while (0);
+ ath_debug_stat_interrupt(sc, status);
+
if (sched) {
/* turn off every interrupt except SWBA */
ath9k_hw_set_interrupts(ah, (sc->sc_imask & ATH9K_INT_SWBA));
@@ -1302,7 +1306,7 @@ static void ath_detach(struct ath_softc *sc)
/* cleanup tx queues */
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
if (ATH_TXQ_SETUP(sc, i))
- ath_tx_cleanupq(sc, &sc->sc_txq[i]);
+ ath_tx_cleanupq(sc, &sc->tx.txq[i]);
ath9k_hw_detach(sc->sc_ah);
ath9k_exit_debug(sc);
@@ -1393,15 +1397,15 @@ static int ath_init(u16 devid, struct ath_softc *sc)
* priority. Note that the hal handles reseting
* these queues at the needed time.
*/
- sc->sc_bhalq = ath_beaconq_setup(ah);
- if (sc->sc_bhalq == -1) {
+ sc->beacon.beaconq = ath_beaconq_setup(ah);
+ if (sc->beacon.beaconq == -1) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to setup a beacon xmit queue\n");
error = -EIO;
goto bad2;
}
- sc->sc_cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
- if (sc->sc_cabq == NULL) {
+ sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
+ if (sc->beacon.cabq == NULL) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to setup CAB xmit queue\n");
error = -EIO;
@@ -1411,8 +1415,8 @@ static int ath_init(u16 devid, struct ath_softc *sc)
sc->sc_config.cabqReadytime = ATH_CABQ_READY_TIME;
ath_cabq_update(sc);
- for (i = 0; i < ARRAY_SIZE(sc->sc_haltype2q); i++)
- sc->sc_haltype2q[i] = -1;
+ for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
+ sc->tx.hwq_map[i] = -1;
/* Setup data queues */
/* NB: ensure BK queue is the lowest priority h/w queue */
@@ -1492,7 +1496,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask;
ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
- sc->sc_defant = ath9k_hw_getdefantenna(ah);
+ sc->rx.defant = ath9k_hw_getdefantenna(ah);
ath9k_hw_getmac(ah, sc->sc_myaddr);
if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) {
@@ -1501,20 +1505,15 @@ static int ath_init(u16 devid, struct ath_softc *sc)
ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
}
- sc->sc_slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */
+ sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */
/* initialize beacon slots */
- for (i = 0; i < ARRAY_SIZE(sc->sc_bslot); i++)
- sc->sc_bslot[i] = ATH_IF_ID_ANY;
+ for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
+ sc->beacon.bslot[i] = ATH_IF_ID_ANY;
/* save MISC configurations */
sc->sc_config.swBeaconProcess = 1;
-#ifdef CONFIG_SLOW_ANT_DIV
- /* range is 40 - 255, we use something in the middle */
- ath_slow_ant_div_init(&sc->sc_antdiv, sc, 0x127);
-#endif
-
/* setup channels and rates */
sc->sbands[IEEE80211_BAND_2GHZ].channels =
@@ -1536,7 +1535,7 @@ bad2:
/* cleanup tx queues */
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
if (ATH_TXQ_SETUP(sc, i))
- ath_tx_cleanupq(sc, &sc->sc_txq[i]);
+ ath_tx_cleanupq(sc, &sc->tx.txq[i]);
bad:
if (ah)
ath9k_hw_detach(ah);
@@ -1674,9 +1673,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
int i;
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i)) {
- spin_lock_bh(&sc->sc_txq[i].axq_lock);
- ath_txq_schedule(sc, &sc->sc_txq[i]);
- spin_unlock_bh(&sc->sc_txq[i].axq_lock);
+ spin_lock_bh(&sc->tx.txq[i].axq_lock);
+ ath_txq_schedule(sc, &sc->tx.txq[i]);
+ spin_unlock_bh(&sc->tx.txq[i].axq_lock);
}
}
}
@@ -1811,19 +1810,19 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
switch (queue) {
case 0:
- qnum = sc->sc_haltype2q[ATH9K_WME_AC_VO];
+ qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO];
break;
case 1:
- qnum = sc->sc_haltype2q[ATH9K_WME_AC_VI];
+ qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI];
break;
case 2:
- qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE];
+ qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
break;
case 3:
- qnum = sc->sc_haltype2q[ATH9K_WME_AC_BK];
+ qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK];
break;
default:
- qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE];
+ qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
break;
}
@@ -1994,9 +1993,9 @@ static int ath9k_tx(struct ieee80211_hw *hw,
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
- sc->seq_no += 0x10;
+ sc->tx.seq_no += 0x10;
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
- hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
+ hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
}
/* Add the padding after the header if this is not already done */
@@ -2050,7 +2049,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
ath_stoprecv(sc);
ath9k_hw_phy_disable(sc->sc_ah);
} else
- sc->sc_rxlink = NULL;
+ sc->rx.rxlink = NULL;
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
@@ -2126,16 +2125,13 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n");
-#ifdef CONFIG_SLOW_ANT_DIV
- ath_slow_ant_div_stop(&sc->sc_antdiv);
-#endif
/* Stop ANI */
del_timer_sync(&sc->sc_ani.timer);
/* Reclaim beacon resources */
if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP ||
sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) {
- ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
+ ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
ath_beacon_return(sc, avp);
}
@@ -2254,7 +2250,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
* causes reconfiguration; we may be called
* with beacon transmission active.
*/
- ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
+ ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
error = ath_beacon_alloc(sc, 0);
if (error != 0)
@@ -2300,7 +2296,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
changed_flags &= SUPPORTED_FILTERS;
*total_flags &= SUPPORTED_FILTERS;
- sc->rx_filter = *total_flags;
+ sc->rx.rxfilter = *total_flags;
rfilt = ath_calcrxfilter(sc);
ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
@@ -2309,7 +2305,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0);
}
- DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx_filter);
+ DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter);
}
static void ath9k_sta_notify(struct ieee80211_hw *hw,
@@ -2491,11 +2487,6 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
return ret;
}
-static int ath9k_no_fragmentation(struct ieee80211_hw *hw, u32 value)
-{
- return -EOPNOTSUPP;
-}
-
static struct ieee80211_ops ath9k_ops = {
.tx = ath9k_tx,
.start = ath9k_start,
@@ -2512,7 +2503,6 @@ static struct ieee80211_ops ath9k_ops = {
.get_tsf = ath9k_get_tsf,
.reset_tsf = ath9k_reset_tsf,
.ampdu_action = ath9k_ampdu_action,
- .set_frag_threshold = ath9k_no_fragmentation,
};
static struct {
diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath9k/phy.h
index 14702344448..3a406a5c059 100644
--- a/drivers/net/wireless/ath9k/phy.h
+++ b/drivers/net/wireless/ath9k/phy.h
@@ -50,6 +50,9 @@ bool ath9k_hw_init_rf(struct ath_hal *ah,
#define AR_PHY_FC_SHORT_GI_40 0x00000080
#define AR_PHY_FC_WALSH 0x00000100
#define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200
+#define AR_PHY_FC_ENABLE_DAC_FIFO 0x00000800
+
+#define AR_PHY_TEST2 0x9808
#define AR_PHY_TIMING2 0x9810
#define AR_PHY_TIMING3 0x9814
@@ -100,6 +103,8 @@ bool ath9k_hw_init_rf(struct ath_hal *ah,
#define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF
#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0
+#define AR_PHY_TSTDAC_CONST 0x983c
+
#define AR_PHY_SETTLING 0x9844
#define AR_PHY_SETTLING_SWITCH 0x00003F80
#define AR_PHY_SETTLING_SWITCH_S 7
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
index 76acd2b75fc..0ae5988e0b6 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -817,7 +817,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
struct ath_rate_table *rate_table;
struct ieee80211_tx_rate *rates = tx_info->control.rates;
- rate_table = sc->hw_rate_table[sc->sc_curmode];
+ rate_table = sc->cur_rate_table;
rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, 1,
is_probe, is_retry);
nrix = rix;
@@ -874,10 +874,9 @@ static void ath_rc_ratefind(struct ath_softc *sc,
* So, set fourth rate in series to be same as third one for
* above conditions.
*/
- if ((sc->sc_curmode == ATH9K_MODE_11NG_HT20) ||
- (sc->sc_curmode == ATH9K_MODE_11NG_HT40PLUS) ||
- (sc->sc_curmode == ATH9K_MODE_11NG_HT40MINUS)) {
- u8 dot11rate = rate_table->info[rix].dot11rate;
+ if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
+ (sc->hw->conf.ht.enabled)) {
+ u8 dot11rate = rate_table->info[rix].dot11rate;
u8 phy = rate_table->info[rix].phy;
if (i == 4 &&
((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
@@ -1094,7 +1093,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
int rate;
u8 last_per;
bool state_change = false;
- struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode];
+ struct ath_rate_table *rate_table = sc->cur_rate_table;
int size = ath_rc_priv->rate_table_size;
if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
@@ -1254,7 +1253,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
u8 flags;
u32 i = 0, rix;
- rate_table = sc->hw_rate_table[sc->sc_curmode];
+ rate_table = sc->cur_rate_table;
/*
* If the first rate is not the final index, there
@@ -1354,8 +1353,8 @@ static void ath_rc_init(struct ath_softc *sc,
sta->ht_cap.ht_supported,
is_cw_40);
} else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
- /* sc_curmode would be set on init through config() */
- rate_table = sc->hw_rate_table[sc->sc_curmode];
+ /* cur_rate_table would be set on init through config() */
+ rate_table = sc->cur_rate_table;
}
if (!rate_table) {
@@ -1432,6 +1431,7 @@ static void ath_rc_init(struct ath_softc *sc,
ath_rc_priv->max_valid_rate = k;
ath_rc_sort_validrates(rate_table, ath_rc_priv);
ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
+ sc->cur_rate_table = rate_table;
}
/* Rate Control callbacks */
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 7a455468823..f2327d8e9c2 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -41,20 +41,19 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
ASSERT(skb != NULL);
ds->ds_vdata = skb->data;
- /* setup rx descriptors. The sc_rxbufsize here tells the harware
+ /* setup rx descriptors. The rx.bufsize here tells the harware
* how much data it can DMA to us and that we are prepared
* to process */
- ath9k_hw_setuprxdesc(ah,
- ds,
- sc->sc_rxbufsize,
+ ath9k_hw_setuprxdesc(ah, ds,
+ sc->rx.bufsize,
0);
- if (sc->sc_rxlink == NULL)
+ if (sc->rx.rxlink == NULL)
ath9k_hw_putrxbuf(ah, bf->bf_daddr);
else
- *sc->sc_rxlink = bf->bf_daddr;
+ *sc->rx.rxlink = bf->bf_daddr;
- sc->sc_rxlink = &ds->ds_link;
+ sc->rx.rxlink = &ds->ds_link;
ath9k_hw_rxena(ah);
}
@@ -62,8 +61,8 @@ static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
{
/* XXX block beacon interrupts */
ath9k_hw_setantenna(sc->sc_ah, antenna);
- sc->sc_defant = antenna;
- sc->sc_rxotherant = 0;
+ sc->rx.defant = antenna;
+ sc->rx.rxotherant = 0;
}
/*
@@ -148,7 +147,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
struct ieee80211_rx_status *rx_status, bool *decrypt_error,
struct ath_softc *sc)
{
- struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode];
+ struct ath_rate_table *rate_table = sc->cur_rate_table;
struct ieee80211_hdr *hdr;
int ratekbps, rix;
u8 ratecode;
@@ -272,20 +271,20 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
int error = 0;
do {
- spin_lock_init(&sc->sc_rxflushlock);
+ spin_lock_init(&sc->rx.rxflushlock);
sc->sc_flags &= ~SC_OP_RXFLUSH;
- spin_lock_init(&sc->sc_rxbuflock);
+ spin_lock_init(&sc->rx.rxbuflock);
- sc->sc_rxbufsize = roundup(IEEE80211_MAX_MPDU_LEN,
+ sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
min(sc->sc_cachelsz,
(u16)64));
DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
- sc->sc_cachelsz, sc->sc_rxbufsize);
+ sc->sc_cachelsz, sc->rx.bufsize);
/* Initialize rx descriptors */
- error = ath_descdma_setup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
+ error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
"rx", nbufs, 1);
if (error != 0) {
DPRINTF(sc, ATH_DBG_FATAL,
@@ -293,8 +292,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
break;
}
- list_for_each_entry(bf, &sc->sc_rxbuf, list) {
- skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize);
+ list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+ skb = ath_rxbuf_alloc(sc, sc->rx.bufsize);
if (skb == NULL) {
error = -ENOMEM;
break;
@@ -302,8 +301,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
bf->bf_mpdu = skb;
bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data,
- sc->sc_rxbufsize,
- PCI_DMA_FROMDEVICE);
+ sc->rx.bufsize,
+ PCI_DMA_FROMDEVICE);
if (unlikely(pci_dma_mapping_error(sc->pdev,
bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
@@ -315,7 +314,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
}
bf->bf_dmacontext = bf->bf_buf_addr;
}
- sc->sc_rxlink = NULL;
+ sc->rx.rxlink = NULL;
} while (0);
@@ -330,14 +329,14 @@ void ath_rx_cleanup(struct ath_softc *sc)
struct sk_buff *skb;
struct ath_buf *bf;
- list_for_each_entry(bf, &sc->sc_rxbuf, list) {
+ list_for_each_entry(bf, &sc->rx.rxbuf, list) {
skb = bf->bf_mpdu;
if (skb)
dev_kfree_skb(skb);
}
- if (sc->sc_rxdma.dd_desc_len != 0)
- ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf);
+ if (sc->rx.rxdma.dd_desc_len != 0)
+ ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
}
/*
@@ -375,7 +374,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
/* Can't set HOSTAP into promiscous mode */
if (((sc->sc_ah->ah_opmode != NL80211_IFTYPE_AP) &&
- (sc->rx_filter & FIF_PROMISC_IN_BSS)) ||
+ (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
(sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR)) {
rfilt |= ATH9K_RX_FILTER_PROM;
/* ??? To prevent from sending ACK */
@@ -401,25 +400,25 @@ int ath_startrecv(struct ath_softc *sc)
struct ath_hal *ah = sc->sc_ah;
struct ath_buf *bf, *tbf;
- spin_lock_bh(&sc->sc_rxbuflock);
- if (list_empty(&sc->sc_rxbuf))
+ spin_lock_bh(&sc->rx.rxbuflock);
+ if (list_empty(&sc->rx.rxbuf))
goto start_recv;
- sc->sc_rxlink = NULL;
- list_for_each_entry_safe(bf, tbf, &sc->sc_rxbuf, list) {
+ sc->rx.rxlink = NULL;
+ list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
ath_rx_buf_link(sc, bf);
}
/* We could have deleted elements so the list may be empty now */
- if (list_empty(&sc->sc_rxbuf))
+ if (list_empty(&sc->rx.rxbuf))
goto start_recv;
- bf = list_first_entry(&sc->sc_rxbuf, struct ath_buf, list);
+ bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
ath9k_hw_putrxbuf(ah, bf->bf_daddr);
ath9k_hw_rxena(ah);
start_recv:
- spin_unlock_bh(&sc->sc_rxbuflock);
+ spin_unlock_bh(&sc->rx.rxbuflock);
ath_opmode_init(sc);
ath9k_hw_startpcureceive(ah);
@@ -435,25 +434,25 @@ bool ath_stoprecv(struct ath_softc *sc)
ath9k_hw_setrxfilter(ah, 0);
stopped = ath9k_hw_stopdmarecv(ah);
mdelay(3); /* 3ms is long enough for 1 frame */
- sc->sc_rxlink = NULL;
+ sc->rx.rxlink = NULL;
return stopped;
}
void ath_flushrecv(struct ath_softc *sc)
{
- spin_lock_bh(&sc->sc_rxflushlock);
+ spin_lock_bh(&sc->rx.rxflushlock);
sc->sc_flags |= SC_OP_RXFLUSH;
ath_rx_tasklet(sc, 1);
sc->sc_flags &= ~SC_OP_RXFLUSH;
- spin_unlock_bh(&sc->sc_rxflushlock);
+ spin_unlock_bh(&sc->rx.rxflushlock);
}
int ath_rx_tasklet(struct ath_softc *sc, int flush)
{
#define PA2DESC(_sc, _pa) \
- ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
- ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
+ ((struct ath_desc *)((caddr_t)(_sc)->rx.rxdma.dd_desc + \
+ ((_pa) - (_sc)->rx.rxdma.dd_desc_paddr)))
struct ath_buf *bf;
struct ath_desc *ds;
@@ -465,19 +464,19 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
bool decrypt_error = false;
u8 keyix;
- spin_lock_bh(&sc->sc_rxbuflock);
+ spin_lock_bh(&sc->rx.rxbuflock);
do {
/* If handling rx interrupt and flush is in progress => exit */
if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
break;
- if (list_empty(&sc->sc_rxbuf)) {
- sc->sc_rxlink = NULL;
+ if (list_empty(&sc->rx.rxbuf)) {
+ sc->rx.rxlink = NULL;
break;
}
- bf = list_first_entry(&sc->sc_rxbuf, struct ath_buf, list);
+ bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
ds = bf->bf_desc;
/*
@@ -499,8 +498,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
struct ath_buf *tbf;
struct ath_desc *tds;
- if (list_is_last(&bf->list, &sc->sc_rxbuf)) {
- sc->sc_rxlink = NULL;
+ if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
+ sc->rx.rxlink = NULL;
break;
}
@@ -540,7 +539,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
goto requeue;
/* The status portion of the descriptor could get corrupted. */
- if (sc->sc_rxbufsize < ds->ds_rxstat.rs_datalen)
+ if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen)
goto requeue;
if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc))
@@ -548,21 +547,21 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
/* Ensure we always have an skb to requeue once we are done
* processing the current buffer's skb */
- requeue_skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize);
+ requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize);
/* If there is no memory we ignore the current RX'd frame,
* tell hardware it can give us a new frame using the old
- * skb and put it at the tail of the sc->sc_rxbuf list for
+ * skb and put it at the tail of the sc->rx.rxbuf list for
* processing. */
if (!requeue_skb)
goto requeue;
- pci_dma_sync_single_for_cpu(sc->pdev,
- bf->bf_buf_addr,
- sc->sc_rxbufsize,
+ /* Sync and unmap the frame */
+ pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr,
+ sc->rx.bufsize,
PCI_DMA_FROMDEVICE);
pci_unmap_single(sc->pdev, bf->bf_buf_addr,
- sc->sc_rxbufsize,
+ sc->rx.bufsize,
PCI_DMA_FROMDEVICE);
skb_put(skb, ds->ds_rxstat.rs_datalen);
@@ -572,8 +571,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
hdr = (struct ieee80211_hdr *)skb->data;
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- if (hdrlen & 3) {
- padsize = hdrlen % 4;
+ /* The MAC header is padded to have 32-bit boundary if the
+ * packet payload is non-zero. The general calculation for
+ * padsize would take into account odd header lengths:
+ * padsize = (4 - hdrlen % 4) % 4; However, since only
+ * even-length headers are used, padding can only be 0 or 2
+ * bytes and we can optimize this a bit. In addition, we must
+ * not try to remove padding from short control frames that do
+ * not have payload. */
+ padsize = hdrlen & 3;
+ if (padsize && hdrlen >= 24) {
memmove(skb->data + padsize, skb->data, hdrlen);
skb_pull(skb, padsize);
}
@@ -596,7 +603,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
/* We will now give hardware our shiny new allocated skb */
bf->bf_mpdu = requeue_skb;
bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data,
- sc->sc_rxbufsize,
+ sc->rx.bufsize,
PCI_DMA_FROMDEVICE);
if (unlikely(pci_dma_mapping_error(sc->pdev,
bf->bf_buf_addr))) {
@@ -612,18 +619,18 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
* change the default rx antenna if rx diversity chooses the
* other antenna 3 times in a row.
*/
- if (sc->sc_defant != ds->ds_rxstat.rs_antenna) {
- if (++sc->sc_rxotherant >= 3)
+ if (sc->rx.defant != ds->ds_rxstat.rs_antenna) {
+ if (++sc->rx.rxotherant >= 3)
ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna);
} else {
- sc->sc_rxotherant = 0;
+ sc->rx.rxotherant = 0;
}
requeue:
- list_move_tail(&bf->list, &sc->sc_rxbuf);
+ list_move_tail(&bf->list, &sc->rx.rxbuf);
ath_rx_buf_link(sc, bf);
} while (1);
- spin_unlock_bh(&sc->sc_rxbuflock);
+ spin_unlock_bh(&sc->rx.rxbuflock);
return 0;
#undef PA2DESC
diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath9k/reg.h
index 60617ae6620..9fedb4911bc 100644
--- a/drivers/net/wireless/ath9k/reg.h
+++ b/drivers/net/wireless/ath9k/reg.h
@@ -671,7 +671,11 @@
#define AR_RC_APB 0x00000002
#define AR_RC_HOSTIF 0x00000100
-#define AR_WA 0x4004
+#define AR_WA 0x4004
+#define AR9285_WA_DEFAULT 0x004a05cb
+#define AR9280_WA_DEFAULT 0x0040073f
+#define AR_WA_DEFAULT 0x0000073f
+
#define AR_PM_STATE 0x4008
#define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000
@@ -738,6 +742,8 @@
#define AR_SREV_REVISION_9280_21 2
#define AR_SREV_VERSION_9285 0xC0
#define AR_SREV_REVISION_9285_10 0
+#define AR_SREV_REVISION_9285_11 1
+#define AR_SREV_REVISION_9285_12 2
#define AR_SREV_9100_OR_LATER(_ah) \
(((_ah)->ah_macVersion >= AR_SREV_VERSION_5416_PCIE))
@@ -768,6 +774,16 @@
#define AR_SREV_9285(_ah) (((_ah)->ah_macVersion == AR_SREV_VERSION_9285))
#define AR_SREV_9285_10_OR_LATER(_ah) \
(((_ah)->ah_macVersion >= AR_SREV_VERSION_9285))
+#define AR_SREV_9285_11(_ah) \
+ (AR_SREV_9280(ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9285_11))
+#define AR_SREV_9285_11_OR_LATER(_ah) \
+ (((_ah)->ah_macVersion > AR_SREV_VERSION_9285) || \
+ (AR_SREV_9285(ah) && ((_ah)->ah_macRev >= AR_SREV_REVISION_9285_11)))
+#define AR_SREV_9285_12(_ah) \
+ (AR_SREV_9280(ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9285_12))
+#define AR_SREV_9285_12_OR_LATER(_ah) \
+ (((_ah)->ah_macVersion > AR_SREV_VERSION_9285) || \
+ (AR_SREV_9285(ah) && ((_ah)->ah_macRev >= AR_SREV_REVISION_9285_12)))
#define AR_RADIO_SREV_MAJOR 0xf0
#define AR_RAD5133_SREV_MAJOR 0xc0
@@ -1017,6 +1033,97 @@ enum {
#define AR_AN_SYNTH9_REFDIVA 0xf8000000
#define AR_AN_SYNTH9_REFDIVA_S 27
+#define AR9285_AN_RF2G1 0x7820
+#define AR9285_AN_RF2G1_ENPACAL 0x00000800
+#define AR9285_AN_RF2G1_ENPACAL_S 11
+#define AR9285_AN_RF2G1_PDPADRV1 0x02000000
+#define AR9285_AN_RF2G1_PDPADRV1_S 25
+#define AR9285_AN_RF2G1_PDPADRV2 0x01000000
+#define AR9285_AN_RF2G1_PDPADRV2_S 24
+#define AR9285_AN_RF2G1_PDPAOUT 0x00800000
+#define AR9285_AN_RF2G1_PDPAOUT_S 23
+
+
+#define AR9285_AN_RF2G2 0x7824
+#define AR9285_AN_RF2G2_OFFCAL 0x00001000
+#define AR9285_AN_RF2G2_OFFCAL_S 12
+
+#define AR9285_AN_RF2G3 0x7828
+#define AR9285_AN_RF2G3_PDVCCOMP 0x02000000
+#define AR9285_AN_RF2G3_PDVCCOMP_S 25
+#define AR9285_AN_RF2G3_OB_0 0x00E00000
+#define AR9285_AN_RF2G3_OB_0_S 21
+#define AR9285_AN_RF2G3_OB_1 0x001C0000
+#define AR9285_AN_RF2G3_OB_1_S 18
+#define AR9285_AN_RF2G3_OB_2 0x00038000
+#define AR9285_AN_RF2G3_OB_2_S 15
+#define AR9285_AN_RF2G3_OB_3 0x00007000
+#define AR9285_AN_RF2G3_OB_3_S 12
+#define AR9285_AN_RF2G3_OB_4 0x00000E00
+#define AR9285_AN_RF2G3_OB_4_S 9
+
+#define AR9285_AN_RF2G3_DB1_0 0x000001C0
+#define AR9285_AN_RF2G3_DB1_0_S 6
+#define AR9285_AN_RF2G3_DB1_1 0x00000038
+#define AR9285_AN_RF2G3_DB1_1_S 3
+#define AR9285_AN_RF2G3_DB1_2 0x00000007
+#define AR9285_AN_RF2G3_DB1_2_S 0
+#define AR9285_AN_RF2G4 0x782C
+#define AR9285_AN_RF2G4_DB1_3 0xE0000000
+#define AR9285_AN_RF2G4_DB1_3_S 29
+#define AR9285_AN_RF2G4_DB1_4 0x1C000000
+#define AR9285_AN_RF2G4_DB1_4_S 26
+
+#define AR9285_AN_RF2G4_DB2_0 0x03800000
+#define AR9285_AN_RF2G4_DB2_0_S 23
+#define AR9285_AN_RF2G4_DB2_1 0x00700000
+#define AR9285_AN_RF2G4_DB2_1_S 20
+#define AR9285_AN_RF2G4_DB2_2 0x000E0000
+#define AR9285_AN_RF2G4_DB2_2_S 17
+#define AR9285_AN_RF2G4_DB2_3 0x0001C000
+#define AR9285_AN_RF2G4_DB2_3_S 14
+#define AR9285_AN_RF2G4_DB2_4 0x00003800
+#define AR9285_AN_RF2G4_DB2_4_S 11
+
+#define AR9285_AN_RF2G6 0x7834
+#define AR9285_AN_RF2G6_CCOMP 0x00007800
+#define AR9285_AN_RF2G6_CCOMP_S 11
+#define AR9285_AN_RF2G6_OFFS 0x03f00000
+#define AR9285_AN_RF2G6_OFFS_S 20
+
+#define AR9285_AN_RF2G7 0x7838
+#define AR9285_AN_RF2G7_PWDDB 0x00000002
+#define AR9285_AN_RF2G7_PWDDB_S 1
+#define AR9285_AN_RF2G7_PADRVGN2TAB0 0xE0000000
+#define AR9285_AN_RF2G7_PADRVGN2TAB0_S 29
+
+#define AR9285_AN_RF2G8 0x783C
+#define AR9285_AN_RF2G8_PADRVGN2TAB0 0x0001C000
+#define AR9285_AN_RF2G8_PADRVGN2TAB0_S 14
+
+
+#define AR9285_AN_RF2G9 0x7840
+#define AR9285_AN_RXTXBB1 0x7854
+#define AR9285_AN_RXTXBB1_PDRXTXBB1 0x00000020
+#define AR9285_AN_RXTXBB1_PDRXTXBB1_S 5
+#define AR9285_AN_RXTXBB1_PDV2I 0x00000080
+#define AR9285_AN_RXTXBB1_PDV2I_S 7
+#define AR9285_AN_RXTXBB1_PDDACIF 0x00000100
+#define AR9285_AN_RXTXBB1_PDDACIF_S 8
+#define AR9285_AN_RXTXBB1_SPARE9 0x00000001
+#define AR9285_AN_RXTXBB1_SPARE9_S 0
+
+#define AR9285_AN_TOP2 0x7868
+
+#define AR9285_AN_TOP3 0x786c
+#define AR9285_AN_TOP3_XPABIAS_LVL 0x0000000C
+#define AR9285_AN_TOP3_XPABIAS_LVL_S 2
+#define AR9285_AN_TOP3_PWDDAC 0x00800000
+#define AR9285_AN_TOP3_PWDDAC_S 23
+
+#define AR9285_AN_TOP4 0x7870
+#define AR9285_AN_TOP4_DEFAULT 0x10142c00
+
#define AR_STA_ID0 0x8000
#define AR_STA_ID1 0x8004
#define AR_STA_ID1_SADH_MASK 0x0000FFFF
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index 9de27c681b8..f9c309ed3a2 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -286,17 +286,17 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
{
struct ath_buf *bf = NULL;
- spin_lock_bh(&sc->sc_txbuflock);
+ spin_lock_bh(&sc->tx.txbuflock);
- if (unlikely(list_empty(&sc->sc_txbuf))) {
- spin_unlock_bh(&sc->sc_txbuflock);
+ if (unlikely(list_empty(&sc->tx.txbuf))) {
+ spin_unlock_bh(&sc->tx.txbuflock);
return NULL;
}
- bf = list_first_entry(&sc->sc_txbuf, struct ath_buf, list);
+ bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
list_del(&bf->list);
- spin_unlock_bh(&sc->sc_txbuflock);
+ spin_unlock_bh(&sc->tx.txbuflock);
return bf;
}
@@ -310,6 +310,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc,
{
struct sk_buff *skb = bf->bf_mpdu;
struct ath_xmit_status tx_status;
+ unsigned long flags;
/*
* Set retry information.
@@ -340,9 +341,9 @@ static void ath_tx_complete_buf(struct ath_softc *sc,
/*
* Return the list of ath_buf of this mpdu to free queue
*/
- spin_lock_bh(&sc->sc_txbuflock);
- list_splice_tail_init(bf_q, &sc->sc_txbuf);
- spin_unlock_bh(&sc->sc_txbuflock);
+ spin_lock_irqsave(&sc->tx.txbuflock, flags);
+ list_splice_tail_init(bf_q, &sc->tx.txbuf);
+ spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
}
/*
@@ -383,7 +384,7 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
- struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];
+ struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
spin_lock_bh(&txq->axq_lock);
@@ -396,7 +397,7 @@ static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
- struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];
+ struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
ASSERT(tid->paused > 0);
spin_lock_bh(&txq->axq_lock);
@@ -493,7 +494,7 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
int width, int half_gi, bool shortPreamble)
{
- struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode];
+ struct ath_rate_table *rate_table = sc->cur_rate_table;
u32 nbits, nsymbits, duration, nsymbols;
u8 rc;
int streams, pktlen;
@@ -557,7 +558,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
}
/* get the cix for the lowest valid rix */
- rt = sc->hw_rate_table[sc->sc_curmode];
+ rt = sc->cur_rate_table;
for (i = 3; i >= 0; i--) {
if (rates[i].count && (rates[i].idx >= 0)) {
rix = rates[i].idx;
@@ -685,7 +686,7 @@ static int ath_tx_send_normal(struct ath_softc *sc,
static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
- struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];
+ struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
struct ath_buf *bf;
struct list_head bf_head;
INIT_LIST_HEAD(&bf_head);
@@ -860,12 +861,12 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
struct ath_buf *tbf;
/* allocate new descriptor */
- spin_lock_bh(&sc->sc_txbuflock);
- ASSERT(!list_empty((&sc->sc_txbuf)));
- tbf = list_first_entry(&sc->sc_txbuf,
+ spin_lock_bh(&sc->tx.txbuflock);
+ ASSERT(!list_empty((&sc->tx.txbuf)));
+ tbf = list_first_entry(&sc->tx.txbuf,
struct ath_buf, list);
list_del(&tbf->list);
- spin_unlock_bh(&sc->sc_txbuflock);
+ spin_unlock_bh(&sc->tx.txbuflock);
ATH_TXBUF_RESET(tbf);
@@ -1057,9 +1058,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
if (bf_held) {
list_del(&bf_held->list);
- spin_lock_bh(&sc->sc_txbuflock);
- list_add_tail(&bf_held->list, &sc->sc_txbuf);
- spin_unlock_bh(&sc->sc_txbuflock);
+ spin_lock_bh(&sc->tx.txbuflock);
+ list_add_tail(&bf_held->list, &sc->tx.txbuf);
+ spin_unlock_bh(&sc->tx.txbuflock);
}
if (!bf_isampdu(bf)) {
@@ -1128,11 +1129,11 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
if (!(sc->sc_flags & SC_OP_INVALID)) {
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i)) {
- ath_tx_stopdma(sc, &sc->sc_txq[i]);
+ ath_tx_stopdma(sc, &sc->tx.txq[i]);
/* The TxDMA may not really be stopped.
* Double check the hal tx pending count */
npend += ath9k_hw_numtxpending(ah,
- sc->sc_txq[i].axq_qnum);
+ sc->tx.txq[i].axq_qnum);
}
}
}
@@ -1157,7 +1158,7 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i))
- ath_tx_draintxq(sc, &sc->sc_txq[i], retry_tx);
+ ath_tx_draintxq(sc, &sc->tx.txq[i], retry_tx);
}
}
@@ -1240,7 +1241,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
struct ath_buf *bf,
struct ath_atx_tid *tid)
{
- struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode];
+ struct ath_rate_table *rate_table = sc->cur_rate_table;
struct sk_buff *skb;
struct ieee80211_tx_info *tx_info;
struct ieee80211_tx_rate *rates;
@@ -1308,7 +1309,7 @@ static int ath_compute_num_delims(struct ath_softc *sc,
struct ath_buf *bf,
u16 frmlen)
{
- struct ath_rate_table *rt = sc->hw_rate_table[sc->sc_curmode];
+ struct ath_rate_table *rt = sc->cur_rate_table;
struct sk_buff *skb = bf->bf_mpdu;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
u32 nsymbits, nsymbols, mpdudensity;
@@ -1819,9 +1820,9 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
}
spin_unlock_bh(&txq->axq_lock);
- spin_lock_bh(&sc->sc_txbuflock);
- list_add_tail(&bf->list, &sc->sc_txbuf);
- spin_unlock_bh(&sc->sc_txbuflock);
+ spin_lock_bh(&sc->tx.txbuflock);
+ list_add_tail(&bf->list, &sc->tx.txbuf);
+ spin_unlock_bh(&sc->tx.txbuflock);
return r;
}
@@ -1838,10 +1839,10 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
int error = 0;
do {
- spin_lock_init(&sc->sc_txbuflock);
+ spin_lock_init(&sc->tx.txbuflock);
/* Setup tx descriptors */
- error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf,
+ error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
"tx", nbufs, 1);
if (error != 0) {
DPRINTF(sc, ATH_DBG_FATAL,
@@ -1851,7 +1852,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
}
/* XXX allocate beacon state together with vap */
- error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf,
+ error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
"beacon", ATH_BCBUF, 1);
if (error != 0) {
DPRINTF(sc, ATH_DBG_FATAL,
@@ -1873,12 +1874,12 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
int ath_tx_cleanup(struct ath_softc *sc)
{
/* cleanup beacon descriptors */
- if (sc->sc_bdma.dd_desc_len != 0)
- ath_descdma_cleanup(sc, &sc->sc_bdma, &sc->sc_bbuf);
+ if (sc->beacon.bdma.dd_desc_len != 0)
+ ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
/* cleanup tx descriptors */
- if (sc->sc_txdma.dd_desc_len != 0)
- ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf);
+ if (sc->tx.txdma.dd_desc_len != 0)
+ ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
return 0;
}
@@ -1926,15 +1927,15 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
*/
return NULL;
}
- if (qnum >= ARRAY_SIZE(sc->sc_txq)) {
+ if (qnum >= ARRAY_SIZE(sc->tx.txq)) {
DPRINTF(sc, ATH_DBG_FATAL,
"qnum %u out of range, max %u!\n",
- qnum, (unsigned int)ARRAY_SIZE(sc->sc_txq));
+ qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq));
ath9k_hw_releasetxqueue(ah, qnum);
return NULL;
}
if (!ATH_TXQ_SETUP(sc, qnum)) {
- struct ath_txq *txq = &sc->sc_txq[qnum];
+ struct ath_txq *txq = &sc->tx.txq[qnum];
txq->axq_qnum = qnum;
txq->axq_link = NULL;
@@ -1945,9 +1946,9 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
txq->axq_aggr_depth = 0;
txq->axq_totalqueued = 0;
txq->axq_linkbuf = NULL;
- sc->sc_txqsetup |= 1<<qnum;
+ sc->tx.txqsetup |= 1<<qnum;
}
- return &sc->sc_txq[qnum];
+ return &sc->tx.txq[qnum];
}
/* Reclaim resources for a setup queue */
@@ -1955,7 +1956,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
{
ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
- sc->sc_txqsetup &= ~(1<<txq->axq_qnum);
+ sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
}
/*
@@ -1972,15 +1973,15 @@ int ath_tx_setup(struct ath_softc *sc, int haltype)
{
struct ath_txq *txq;
- if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) {
+ if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
DPRINTF(sc, ATH_DBG_FATAL,
"HAL AC %u out of range, max %zu!\n",
- haltype, ARRAY_SIZE(sc->sc_haltype2q));
+ haltype, ARRAY_SIZE(sc->tx.hwq_map));
return 0;
}
txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
if (txq != NULL) {
- sc->sc_haltype2q[haltype] = txq->axq_qnum;
+ sc->tx.hwq_map[haltype] = txq->axq_qnum;
return 1;
} else
return 0;
@@ -1992,19 +1993,19 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
switch (qtype) {
case ATH9K_TX_QUEUE_DATA:
- if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) {
+ if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
DPRINTF(sc, ATH_DBG_FATAL,
"HAL AC %u out of range, max %zu!\n",
- haltype, ARRAY_SIZE(sc->sc_haltype2q));
+ haltype, ARRAY_SIZE(sc->tx.hwq_map));
return -1;
}
- qnum = sc->sc_haltype2q[haltype];
+ qnum = sc->tx.hwq_map[haltype];
break;
case ATH9K_TX_QUEUE_BEACON:
- qnum = sc->sc_bhalq;
+ qnum = sc->beacon.beaconq;
break;
case ATH9K_TX_QUEUE_CAB:
- qnum = sc->sc_cabq->axq_qnum;
+ qnum = sc->beacon.cabq->axq_qnum;
break;
default:
qnum = -1;
@@ -2020,7 +2021,7 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
int qnum;
qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
- txq = &sc->sc_txq[qnum];
+ txq = &sc->tx.txq[qnum];
spin_lock_bh(&txq->axq_lock);
@@ -2049,17 +2050,17 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
int error = 0;
struct ath9k_tx_queue_info qi;
- if (qnum == sc->sc_bhalq) {
+ if (qnum == sc->beacon.beaconq) {
/*
* XXX: for beacon queue, we just save the parameter.
* It will be picked up by ath_beaconq_config when
* it's necessary.
*/
- sc->sc_beacon_qi = *qinfo;
+ sc->beacon.beacon_qi = *qinfo;
return 0;
}
- ASSERT(sc->sc_txq[qnum].axq_qnum == qnum);
+ ASSERT(sc->tx.txq[qnum].axq_qnum == qnum);
ath9k_hw_get_txq_props(ah, qnum, &qi);
qi.tqi_aifs = qinfo->tqi_aifs;
@@ -2082,7 +2083,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
int ath_cabq_update(struct ath_softc *sc)
{
struct ath9k_tx_queue_info qi;
- int qnum = sc->sc_cabq->axq_qnum;
+ int qnum = sc->beacon.cabq->axq_qnum;
struct ath_beacon_config conf;
ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
@@ -2116,7 +2117,7 @@ void ath_tx_tasklet(struct ath_softc *sc)
*/
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
- ath_tx_processq(sc, &sc->sc_txq[i]);
+ ath_tx_processq(sc, &sc->tx.txq[i]);
}
}
@@ -2148,9 +2149,9 @@ void ath_tx_draintxq(struct ath_softc *sc,
list_del(&bf->list);
spin_unlock_bh(&txq->axq_lock);
- spin_lock_bh(&sc->sc_txbuflock);
- list_add_tail(&bf->list, &sc->sc_txbuf);
- spin_unlock_bh(&sc->sc_txbuflock);
+ spin_lock_bh(&sc->tx.txbuflock);
+ list_add_tail(&bf->list, &sc->tx.txbuf);
+ spin_unlock_bh(&sc->tx.txbuflock);
continue;
}
@@ -2188,9 +2189,9 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx)
/* stop beacon queue. The beacon will be freed when
* we go to INIT state */
if (!(sc->sc_flags & SC_OP_INVALID)) {
- (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
+ (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
DPRINTF(sc, ATH_DBG_XMIT, "beacon queue %x\n",
- ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_bhalq));
+ ath9k_hw_gettxbuf(sc->sc_ah, sc->beacon.beaconq));
}
ath_drain_txdataq(sc, retry_tx);
@@ -2198,12 +2199,12 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx)
u32 ath_txq_depth(struct ath_softc *sc, int qnum)
{
- return sc->sc_txq[qnum].axq_depth;
+ return sc->tx.txq[qnum].axq_depth;
}
u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum)
{
- return sc->sc_txq[qnum].axq_aggr_depth;
+ return sc->tx.txq[qnum].axq_aggr_depth;
}
bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
@@ -2284,7 +2285,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid
void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid)
{
struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
- struct ath_txq *txq = &sc->sc_txq[txtid->ac->qnum];
+ struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
struct ath_buf *bf;
struct list_head bf_head;
INIT_LIST_HEAD(&bf_head);
@@ -2405,7 +2406,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
/*
* Init per tid tx state
*/
- for (tidno = 0, tid = &an->an_aggr.tx.tid[tidno];
+ for (tidno = 0, tid = &an->tid[tidno];
tidno < WME_NUM_TID;
tidno++, tid++) {
tid->an = an;
@@ -2419,7 +2420,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
INIT_LIST_HEAD(&tid->buf_q);
acno = TID_TO_WME_AC(tidno);
- tid->ac = &an->an_aggr.tx.ac[acno];
+ tid->ac = &an->ac[acno];
/* ADDBA state */
tid->state &= ~AGGR_ADDBA_COMPLETE;
@@ -2430,7 +2431,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
/*
* Init per ac tx state
*/
- for (acno = 0, ac = &an->an_aggr.tx.ac[acno];
+ for (acno = 0, ac = &an->ac[acno];
acno < WME_NUM_AC; acno++, ac++) {
ac->sched = false;
INIT_LIST_HEAD(&ac->tid_q);
@@ -2466,7 +2467,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
struct ath_txq *txq;
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i)) {
- txq = &sc->sc_txq[i];
+ txq = &sc->tx.txq[i];
spin_lock(&txq->axq_lock);
@@ -2511,9 +2512,9 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
- sc->seq_no += 0x10;
+ sc->tx.seq_no += 0x10;
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
- hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
+ hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
}
/* Add the padding after the header if this is not already done */
@@ -2529,7 +2530,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
memmove(skb->data, skb->data + padsize, hdrlen);
}
- txctl.txq = sc->sc_cabq;
+ txctl.txq = sc->beacon.cabq;
DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
diff --git a/drivers/net/wireless/b43legacy/debugfs.c b/drivers/net/wireless/b43legacy/debugfs.c
index 03ce0821a60..1f85ac569fe 100644
--- a/drivers/net/wireless/b43legacy/debugfs.c
+++ b/drivers/net/wireless/b43legacy/debugfs.c
@@ -211,7 +211,7 @@ static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf,
struct b43legacy_dfs_file *dfile;
ssize_t uninitialized_var(ret);
char *buf;
- const size_t bufsize = 1024 * 128;
+ const size_t bufsize = 1024 * 16; /* 16 KiB buffer */
const size_t buforder = get_order(bufsize);
int err = 0;
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c
index 4c9442b16f3..11319ec2d64 100644
--- a/drivers/net/wireless/b43legacy/phy.c
+++ b/drivers/net/wireless/b43legacy/phy.c
@@ -1296,12 +1296,10 @@ void b43legacy_lo_write(struct b43legacy_wldev *dev,
/* Sanity check. */
if (pair->low < -8 || pair->low > 8 ||
pair->high < -8 || pair->high > 8) {
- struct b43legacy_phy *phy = &dev->phy;
b43legacydbg(dev->wl,
"WARNING: Writing invalid LOpair "
- "(low: %d, high: %d, index: %lu)\n",
- pair->low, pair->high,
- (unsigned long)(pair - phy->_lo_pairs));
+ "(low: %d, high: %d)\n",
+ pair->low, pair->high);
dump_stack();
}
#endif
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 23728eb6110..625f2cf99fa 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -4345,7 +4345,8 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
return;
}
- if (priv->status & STATUS_SCANNING) {
+ if (priv->status & STATUS_SCANNING &&
+ missed_count > IPW_MB_SCAN_CANCEL_THRESHOLD) {
/* Stop scan to keep fw from getting
* stuck (only if we aren't roaming --
* otherwise we'll never scan more than 2 or 3
@@ -6271,6 +6272,20 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
}
}
+static int ipw_passive_dwell_time(struct ipw_priv *priv)
+{
+ /* staying on passive channels longer than the DTIM interval during a
+ * scan, while associated, causes the firmware to cancel the scan
+ * without notification. Hence, don't stay on passive channels longer
+ * than the beacon interval.
+ */
+ if (priv->status & STATUS_ASSOCIATED
+ && priv->assoc_network->beacon_interval > 10)
+ return priv->assoc_network->beacon_interval - 10;
+ else
+ return 120;
+}
+
static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
{
struct ipw_scan_request_ext scan;
@@ -6314,16 +6329,16 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
if (type == IW_SCAN_TYPE_PASSIVE) {
- IPW_DEBUG_WX("use passive scanning\n");
- scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN;
+ IPW_DEBUG_WX("use passive scanning\n");
+ scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN;
scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
- cpu_to_le16(120);
+ cpu_to_le16(ipw_passive_dwell_time(priv));
ipw_add_scan_channels(priv, &scan, scan_type);
goto send_request;
}
/* Use active scan by default. */
- if (priv->config & CFG_SPEED_SCAN)
+ if (priv->config & CFG_SPEED_SCAN)
scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
cpu_to_le16(30);
else
@@ -6333,7 +6348,8 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
cpu_to_le16(20);
- scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
+ scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
+ cpu_to_le16(ipw_passive_dwell_time(priv));
scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
#ifdef CONFIG_IPW2200_MONITOR
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h
index 0a84d52147b..277b274d4be 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.h
+++ b/drivers/net/wireless/ipw2x00/ipw2200.h
@@ -245,6 +245,7 @@ enum connection_manager_assoc_states {
#define HOST_NOTIFICATION_S36_MEASUREMENT_REFUSED 31
#define HOST_NOTIFICATION_STATUS_BEACON_MISSING 1
+#define IPW_MB_SCAN_CANCEL_THRESHOLD 3
#define IPW_MB_ROAMING_THRESHOLD_MIN 1
#define IPW_MB_ROAMING_THRESHOLD_DEFAULT 8
#define IPW_MB_ROAMING_THRESHOLD_MAX 30
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
index daf99ea88e9..c6f4eb54a2b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
@@ -25,7 +25,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-core.h b/drivers/net/wireless/iwlwifi/iwl-3945-core.h
index edac6c6a911..6f463555402 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-core.h
@@ -25,7 +25,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h b/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
index 33016fb5e9b..85eb778f9df 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
@@ -21,7 +21,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 644bd9e0805..94ea0e60c41 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -25,7 +25,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
@@ -103,7 +103,6 @@
* Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG.
*/
#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */
-#define IWL_EEPROM_ACCESS_DELAY 10 /* uSec */
/*
* Regulatory channel usage flags in EEPROM struct iwl_eeprom_channel.flags.
@@ -321,6 +320,7 @@ struct iwl3945_eeprom {
/* RSSR */
#define FH_RSSR_CTRL (FH_RSSR_TABLE+0x000)
#define FH_RSSR_STATUS (FH_RSSR_TABLE+0x004)
+#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000)
/* TCSR */
#define FH_TCSR(_channel) (FH_TCSR_TABLE+(_channel)*0x20)
#define FH_TCSR_CONFIG(_channel) (FH_TCSR(_channel)+0x00)
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-io.h b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
index 7dea1552a90..2440fd664dd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
@@ -21,7 +21,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -93,7 +93,7 @@ static inline int _iwl3945_poll_bit(struct iwl3945_priv *priv, u32 addr,
do {
if ((_iwl3945_read32(priv, addr) & mask) == (bits & mask))
return i;
- mdelay(10);
+ udelay(10);
i += 10;
} while (i < timeout);
@@ -271,16 +271,7 @@ static inline void iwl3945_write_reg_buf(struct iwl3945_priv *priv,
static inline int _iwl3945_poll_direct_bit(struct iwl3945_priv *priv,
u32 addr, u32 mask, int timeout)
{
- int i = 0;
-
- do {
- if ((_iwl3945_read_direct32(priv, addr) & mask) == mask)
- return i;
- mdelay(10);
- i += 10;
- } while (i < timeout);
-
- return -ETIMEDOUT;
+ return _iwl3945_poll_bit(priv, addr, mask, mask, timeout);
}
#ifdef CONFIG_IWL3945_DEBUG
@@ -307,6 +298,7 @@ static inline int __iwl3945_poll_direct_bit(const char *f, u32 l,
static inline u32 _iwl3945_read_prph(struct iwl3945_priv *priv, u32 reg)
{
_iwl3945_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
+ rmb();
return _iwl3945_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
}
#ifdef CONFIG_IWL3945_DEBUG
@@ -328,6 +320,7 @@ static inline void _iwl3945_write_prph(struct iwl3945_priv *priv,
{
_iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
((addr & 0x0000FFFF) | (3 << 24)));
+ wmb();
_iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
}
#ifdef CONFIG_IWL3945_DEBUG
@@ -389,12 +382,14 @@ static inline void iwl3945_clear_bits_prph(struct iwl3945_priv
static inline u32 iwl3945_read_targ_mem(struct iwl3945_priv *priv, u32 addr)
{
iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
+ rmb();
return iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
}
static inline void iwl3945_write_targ_mem(struct iwl3945_priv *priv, u32 addr, u32 val)
{
iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
+ wmb();
iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
}
@@ -402,6 +397,7 @@ static inline void iwl3945_write_targ_mem_buf(struct iwl3945_priv *priv, u32 add
u32 len, u32 *values)
{
iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
+ wmb();
for (; 0 < len; len -= sizeof(u32), values++)
iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index 705c65bed9f..4c638909a7d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -19,7 +19,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
index 2fbd126c134..749ac035fd6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
@@ -19,7 +19,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index b03dd06ceab..9b60a0c5de5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -19,7 +19,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -335,10 +335,11 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
}
-static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband,
+static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta)
{
struct iwl3945_rs_sta *rs_sta = priv_sta;
+ struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
int i;
IWL_DEBUG_RATE("enter\n");
@@ -348,16 +349,21 @@ static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband,
* previous packets? Need to have IEEE 802.1X auth succeed immediately
* after assoc.. */
- for (i = IWL_RATE_COUNT - 1; i >= 0; i--) {
+ for (i = sband->n_bitrates - 1; i >= 0; i--) {
if (sta->supp_rates[sband->band] & (1 << i)) {
rs_sta->last_txrate_idx = i;
break;
}
}
+ priv->sta_supp_rates = sta->supp_rates[sband->band];
/* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */
- if (sband->band == IEEE80211_BAND_5GHZ)
+ if (sband->band == IEEE80211_BAND_5GHZ) {
rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
+ priv->sta_supp_rates = priv->sta_supp_rates <<
+ IWL_FIRST_OFDM_RATE;
+ }
+
IWL_DEBUG_RATE("leave\n");
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
index 98b17ae6ef2..b5a66135ded 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
@@ -19,7 +19,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 4e6b7154c22..d0c9bdcf393 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -19,7 +19,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -277,12 +277,14 @@ int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate)
else if (rate == IWL_RATE_6M_INDEX)
next_rate = IWL_RATE_6M_INDEX;
break;
-/* XXX cannot be invoked in current mac80211 so not a regression
- case MODE_IEEE80211B:
- if (rate == IWL_RATE_11M_INDEX_TABLE)
- next_rate = IWL_RATE_5M_INDEX_TABLE;
+ case IEEE80211_BAND_2GHZ:
+ if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
+ iwl3945_is_associated(priv)) {
+ if (rate == IWL_RATE_11M_INDEX)
+ next_rate = IWL_RATE_5M_INDEX;
+ }
break;
- */
+
default:
break;
}
@@ -1101,9 +1103,8 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- rc = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ rc = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
if (rc < 0) {
spin_unlock_irqrestore(&priv->lock, flags);
IWL_DEBUG_INFO("Failed to init the card\n");
@@ -1284,8 +1285,7 @@ int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv)
IWL_DEBUG_INFO("Card in power save, master is already "
"stopped\n");
else {
- rc = iwl3945_poll_bit(priv, CSR_RESET,
- CSR_RESET_REG_FLAG_MASTER_DISABLED,
+ rc = iwl3945_poll_direct_bit(priv, CSR_RESET,
CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
if (rc < 0) {
spin_unlock_irqrestore(&priv->lock, flags);
@@ -1310,9 +1310,8 @@ int iwl3945_hw_nic_reset(struct iwl3945_priv *priv)
iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
- rc = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
rc = iwl3945_grab_nic_access(priv);
if (!rc) {
@@ -2309,7 +2308,8 @@ int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv)
}
iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0), 0);
- rc = iwl3945_poll_direct_bit(priv, FH_RSSR_STATUS, (1 << 24), 1000);
+ rc = iwl3945_poll_direct_bit(priv, FH_RSSR_STATUS,
+ FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
if (rc < 0)
IWL_ERROR("Can't stop Rx DMA.\n");
@@ -2378,7 +2378,8 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0);
table[index].try_cnt = priv->retry_rate;
prev_index = iwl3945_get_prev_ieee_rate(i);
- table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index;
+ table[index].next_rate_index =
+ iwl3945_rates[prev_index].table_rs_index;
}
switch (priv->band) {
@@ -2386,11 +2387,14 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
IWL_DEBUG_RATE("Select A mode rate scale\n");
/* If one of the following CCK rates is used,
* have it fall back to the 6M OFDM rate */
- for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++)
- table[i].next_rate_index = iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
+ for (i = IWL_RATE_1M_INDEX_TABLE;
+ i <= IWL_RATE_11M_INDEX_TABLE; i++)
+ table[i].next_rate_index =
+ iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
/* Don't fall back to CCK rates */
- table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = IWL_RATE_9M_INDEX_TABLE;
+ table[IWL_RATE_12M_INDEX_TABLE].next_rate_index =
+ IWL_RATE_9M_INDEX_TABLE;
/* Don't drop out of OFDM rates */
table[IWL_RATE_6M_INDEX_TABLE].next_rate_index =
@@ -2401,11 +2405,20 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
IWL_DEBUG_RATE("Select B/G mode rate scale\n");
/* If an OFDM rate is used, have it fall back to the
* 1M CCK rates */
- for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++)
- table[i].next_rate_index = iwl3945_rates[IWL_FIRST_CCK_RATE].table_rs_index;
- /* CCK shouldn't fall back to OFDM... */
- table[IWL_RATE_11M_INDEX_TABLE].next_rate_index = IWL_RATE_5M_INDEX_TABLE;
+ if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
+ iwl3945_is_associated(priv)) {
+
+ index = IWL_FIRST_CCK_RATE;
+ for (i = IWL_RATE_6M_INDEX_TABLE;
+ i <= IWL_RATE_54M_INDEX_TABLE; i++)
+ table[i].next_rate_index =
+ iwl3945_rates[index].table_rs_index;
+
+ index = IWL_RATE_11M_INDEX_TABLE;
+ /* CCK shouldn't fall back to OFDM... */
+ table[index].next_rate_index = IWL_RATE_5M_INDEX_TABLE;
+ }
break;
default:
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 5c2c15e65a6..ec6084c8fd1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -19,7 +19,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -476,7 +476,6 @@ union iwl3945_qos_capabity {
/* QoS structures */
struct iwl3945_qos_info {
- int qos_enable;
int qos_active;
union iwl3945_qos_capabity qos_cap;
struct iwl3945_qosparam_cmd def_qos_parm;
@@ -810,6 +809,8 @@ struct iwl3945_priv {
u16 active_rate;
u16 active_rate_basic;
+ u32 sta_supp_rates;
+
u8 call_post_assoc_from_beacon;
/* Rate scaling data */
s8 data_retry_limit;
@@ -906,9 +907,6 @@ struct iwl3945_priv {
s8 user_txpower_limit;
s8 max_channel_txpower_limit;
-#ifdef CONFIG_PM
- u32 pm_state[16];
-#endif
#ifdef CONFIG_IWL3945_DEBUG
/* debugging info */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index fb0fd773960..6649f7b5565 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -25,7 +25,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
@@ -84,12 +84,6 @@
#define IWL_CMD_FIFO_NUM 4
#define IWL49_FIRST_AMPDU_QUEUE 7
-/* Tx rates */
-#define IWL_CCK_RATES 4
-#define IWL_OFDM_RATES 8
-#define IWL_HT_RATES 16
-#define IWL_MAX_RATES (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES)
-
/* Time constants */
#define SHORT_SLOT_TIME 9
#define LONG_SLOT_TIME 20
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 87c7bb0d504..a7e6e32bd48 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -19,7 +19,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -63,7 +63,6 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv);
static struct iwl_mod_params iwl4965_mod_params = {
.num_of_queues = IWL49_NUM_QUEUES,
.num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
- .enable_qos = 1,
.amsdu_size_8K = 1,
.restart_fw = 1,
/* the rest are 0 by default */
@@ -352,9 +351,8 @@ static int iwl4965_apm_init(struct iwl_priv *priv)
iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
/* wait for clock stabilization */
- ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
if (ret < 0) {
IWL_DEBUG_INFO("Failed to init the card\n");
goto out;
@@ -436,9 +434,8 @@ static int iwl4965_apm_stop_master(struct iwl_priv *priv)
/* set stop master bit */
iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
- ret = iwl_poll_bit(priv, CSR_RESET,
- CSR_RESET_REG_FLAG_MASTER_DISABLED,
- CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
+ ret = iwl_poll_direct_bit(priv, CSR_RESET,
+ CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
if (ret < 0)
goto out;
@@ -482,11 +479,9 @@ static int iwl4965_apm_reset(struct iwl_priv *priv)
iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- ret = iwl_poll_bit(priv, CSR_RESET,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25);
-
- if (ret)
+ ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ if (ret < 0)
goto out;
udelay(10);
@@ -2367,9 +2362,6 @@ MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, 0444);
MODULE_PARM_DESC(queues_num, "number of hw queues.");
-/* QoS */
-module_param_named(qos_enable, iwl4965_mod_params.enable_qos, int, 0444);
-MODULE_PARM_DESC(qos_enable, "enable all QoS functionality");
/* 11n */
module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, 0444);
MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index c6595e8b440..82c3859ce0f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -25,7 +25,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 438e4bd0a9a..2344de94597 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -81,8 +81,7 @@ static int iwl5000_apm_stop_master(struct iwl_priv *priv)
/* set stop master bit */
iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
- ret = iwl_poll_bit(priv, CSR_RESET,
- CSR_RESET_REG_FLAG_MASTER_DISABLED,
+ ret = iwl_poll_direct_bit(priv, CSR_RESET,
CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
if (ret < 0)
goto out;
@@ -120,9 +119,8 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
/* wait for clock stabilization */
- ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
if (ret < 0) {
IWL_DEBUG_INFO("Failed to init the card\n");
return ret;
@@ -189,9 +187,8 @@ static int iwl5000_apm_reset(struct iwl_priv *priv)
iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
/* wait for clock stabilization */
- ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
if (ret < 0) {
IWL_DEBUG_INFO("Failed to init the card\n");
goto out;
@@ -1533,7 +1530,6 @@ static struct iwl_ops iwl5000_ops = {
static struct iwl_mod_params iwl50_mod_params = {
.num_of_queues = IWL50_NUM_QUEUES,
.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
- .enable_qos = 1,
.amsdu_size_8K = 1,
.restart_fw = 1,
/* the rest are 0 by default */
@@ -1631,8 +1627,6 @@ module_param_named(debug50, iwl50_mod_params.debug, int, 0444);
MODULE_PARM_DESC(debug50, "50XX debug output mask");
module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, 0444);
MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series");
-module_param_named(qos_enable50, iwl50_mod_params.enable_qos, int, 0444);
-MODULE_PARM_DESC(qos_enable50, "enable all 50XX QoS functionality");
module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, 0444);
MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality");
module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K, int, 0444);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c
index c50494a74f6..b8137eeae1d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c
@@ -22,7 +22,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 3a2b81291d8..37b892044a1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -19,7 +19,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -38,7 +38,6 @@
#include "iwl-dev.h"
#include "iwl-sta.h"
#include "iwl-core.h"
-#include "iwl-helpers.h"
#define RS_NAME "iwl-agn-rs"
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index adcbf538ed5..78ee83adf74 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -19,7 +19,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index b3c263d2724..2f5e86e1291 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -22,7 +22,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -83,7 +83,7 @@
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERSION);
-MODULE_AUTHOR(DRV_COPYRIGHT);
+MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
MODULE_LICENSE("GPL");
MODULE_ALIAS("iwl4965");
@@ -310,7 +310,7 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
static int iwl_send_bt_config(struct iwl_priv *priv)
{
- struct iwl4965_bt_cmd bt_cmd = {
+ struct iwl_bt_cmd bt_cmd = {
.flags = 3,
.lead_time = 0xAA,
.max_kill = 1,
@@ -319,7 +319,7 @@ static int iwl_send_bt_config(struct iwl_priv *priv)
};
return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
- sizeof(struct iwl4965_bt_cmd), &bt_cmd);
+ sizeof(struct iwl_bt_cmd), &bt_cmd);
}
static void iwl_clear_free_frames(struct iwl_priv *priv)
@@ -546,9 +546,6 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- if (!priv->qos_data.qos_enable)
- return;
-
priv->qos_data.def_qos_parm.qos_flags = 0;
if (priv->qos_data.qos_cap.q_AP.queue_request &&
@@ -860,7 +857,7 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
- struct iwl4965_csa_notification *csa = &(pkt->u.csa_notif);
+ struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
IWL_DEBUG_11H("CSA notif: channel %d, status %d\n",
le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
rxon->channel = csa->channel;
@@ -872,7 +869,7 @@ static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
{
#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- struct iwl4965_sleep_notification *sleep = &(pkt->u.sleep_notif);
+ struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
IWL_DEBUG_RX("sleep mode: %d, src: %d\n",
sleep->pm_sleep_mode, sleep->pm_wakeup_src);
#endif
@@ -942,7 +939,8 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
{
#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status);
+ struct iwl4965_beacon_notif *beacon =
+ (struct iwl4965_beacon_notif *)pkt->u.raw;
u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
IWL_DEBUG_RX("beacon status %x retries %d iss %d "
@@ -1405,8 +1403,11 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
* the driver as well won't allow loading if RFKILL is set
* therefore no need to restart the driver from this handler
*/
- if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status))
+ if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) {
clear_bit(STATUS_RF_KILL_HW, &priv->status);
+ if (priv->is_open && !iwl_is_rfkill(priv))
+ queue_work(priv->workqueue, &priv->up);
+ }
handled |= CSR_INT_BIT_RF_KILL;
}
@@ -2963,12 +2964,6 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len)
goto out_unlock;
}
- if (priv->iw_mode == NL80211_IFTYPE_AP) { /* APs don't scan */
- ret = -EIO;
- IWL_ERROR("ERROR: APs don't scan\n");
- goto out_unlock;
- }
-
/* We don't schedule scan within next_scan_jiffies period.
* Avoid scanning during possible EAPOL exchange, return
* success immediately.
@@ -3112,11 +3107,6 @@ static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
return 0;
}
- if (!priv->qos_data.qos_enable) {
- priv->qos_data.qos_active = 0;
- IWL_DEBUG_MAC80211("leave - qos not enabled\n");
- return 0;
- }
q = AC_NUM - 1 - queue;
spin_lock_irqsave(&priv->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 25f4658f1a7..7956e087361 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -25,7 +25,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h
index 94c8e316382..1abe84bb74a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.h
@@ -25,7 +25,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 528bcab49d1..60e79d9bd72 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -25,7 +25,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
@@ -94,6 +94,7 @@ enum {
REPLY_WEPKEY = 0x20,
/* RX, TX, LEDs */
+ REPLY_3945_RX = 0x1b, /* 3945 only */
REPLY_TX = 0x1c,
REPLY_RATE_SCALE = 0x47, /* 3945 only */
REPLY_LEDS_CMD = 0x48,
@@ -701,7 +702,7 @@ struct iwl_rxon_time_cmd {
/*
* REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
*/
-struct iwl4965_channel_switch_cmd {
+struct iwl_channel_switch_cmd {
u8 band;
u8 expect_beacon;
__le16 channel;
@@ -714,7 +715,7 @@ struct iwl4965_channel_switch_cmd {
/*
* CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command)
*/
-struct iwl4965_csa_notification {
+struct iwl_csa_notification {
__le16 band;
__le16 channel;
__le32 status; /* 0 - OK, 1 - fail */
@@ -1023,25 +1024,6 @@ struct iwl_wep_cmd {
*
*****************************************************************************/
-struct iwl4965_rx_frame_stats {
- u8 phy_count;
- u8 id;
- u8 rssi;
- u8 agc;
- __le16 sig_avg;
- __le16 noise_diff;
- u8 payload[0];
-} __attribute__ ((packed));
-
-struct iwl4965_rx_frame_hdr {
- __le16 channel;
- __le16 phy_flags;
- u8 reserved1;
- u8 rate;
- __le16 len;
- u8 payload[0];
-} __attribute__ ((packed));
-
#define RX_RES_STATUS_NO_CRC32_ERROR cpu_to_le32(1 << 0)
#define RX_RES_STATUS_NO_RXE_OVERFLOW cpu_to_le32(1 << 1)
@@ -1072,26 +1054,6 @@ struct iwl4965_rx_frame_hdr {
#define RX_MPDU_RES_STATUS_TTAK_OK (1 << 7)
#define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800)
-struct iwl4965_rx_frame_end {
- __le32 status;
- __le64 timestamp;
- __le32 beacon_timestamp;
-} __attribute__ ((packed));
-
-/*
- * REPLY_3945_RX = 0x1b (response only, not a command)
- *
- * NOTE: DO NOT dereference from casts to this structure
- * It is provided only for calculating minimum data set size.
- * The actual offsets of the hdr and end are dynamic based on
- * stats.phy_count
- */
-struct iwl4965_rx_frame {
- struct iwl4965_rx_frame_stats stats;
- struct iwl4965_rx_frame_hdr hdr;
- struct iwl4965_rx_frame_end end;
-} __attribute__ ((packed));
-
/* Fixed (non-configurable) rx data from phy */
#define IWL49_RX_RES_PHY_CNT 14
@@ -1276,7 +1238,7 @@ struct iwl4965_rx_mpdu_res_start {
* Used for managing Tx retries when expecting block-acks.
* Driver should set these fields to 0.
*/
-struct iwl4965_dram_scratch {
+struct iwl_dram_scratch {
u8 try_cnt; /* Tx attempts */
u8 bt_kill_cnt; /* Tx attempts blocked by Bluetooth device */
__le16 reserved;
@@ -1307,9 +1269,9 @@ struct iwl_tx_cmd {
__le32 tx_flags; /* TX_CMD_FLG_* */
- /* 4965's uCode may modify this field of the Tx command (in host DRAM!).
+ /* uCode may modify this field of the Tx command (in host DRAM!).
* Driver must also set dram_lsb_ptr and dram_msb_ptr in this cmd. */
- struct iwl4965_dram_scratch scratch;
+ struct iwl_dram_scratch scratch;
/* Rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is cleared. */
__le32 rate_n_flags; /* RATE_MCS_* */
@@ -1917,7 +1879,7 @@ struct iwl_link_quality_cmd {
* same platform. Bluetooth device alerts wireless device when it will Tx;
* wireless device can delay or kill its own Tx to accommodate.
*/
-struct iwl4965_bt_cmd {
+struct iwl_bt_cmd {
u8 flags;
u8 lead_time;
u8 max_kill;
@@ -1943,18 +1905,18 @@ struct iwl4965_bt_cmd {
RXON_FILTER_ASSOC_MSK | \
RXON_FILTER_BCON_AWARE_MSK)
-struct iwl4965_measure_channel {
+struct iwl_measure_channel {
__le32 duration; /* measurement duration in extended beacon
* format */
u8 channel; /* channel to measure */
- u8 type; /* see enum iwl4965_measure_type */
+ u8 type; /* see enum iwl_measure_type */
__le16 reserved;
} __attribute__ ((packed));
/*
* REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command)
*/
-struct iwl4965_spectrum_cmd {
+struct iwl_spectrum_cmd {
__le16 len; /* number of bytes starting from token */
u8 token; /* token id */
u8 id; /* measurement id -- 0 or 1 */
@@ -1967,13 +1929,13 @@ struct iwl4965_spectrum_cmd {
__le32 filter_flags; /* rxon filter flags */
__le16 channel_count; /* minimum 1, maximum 10 */
__le16 reserved3;
- struct iwl4965_measure_channel channels[10];
+ struct iwl_measure_channel channels[10];
} __attribute__ ((packed));
/*
* REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response)
*/
-struct iwl4965_spectrum_resp {
+struct iwl_spectrum_resp {
u8 token;
u8 id; /* id of the prior command replaced, or 0xff */
__le16 status; /* 0 - command will be handled
@@ -1981,12 +1943,12 @@ struct iwl4965_spectrum_resp {
* measurement) */
} __attribute__ ((packed));
-enum iwl4965_measurement_state {
+enum iwl_measurement_state {
IWL_MEASUREMENT_START = 0,
IWL_MEASUREMENT_STOP = 1,
};
-enum iwl4965_measurement_status {
+enum iwl_measurement_status {
IWL_MEASUREMENT_OK = 0,
IWL_MEASUREMENT_CONCURRENT = 1,
IWL_MEASUREMENT_CSA_CONFLICT = 2,
@@ -1999,18 +1961,18 @@ enum iwl4965_measurement_status {
#define NUM_ELEMENTS_IN_HISTOGRAM 8
-struct iwl4965_measurement_histogram {
+struct iwl_measurement_histogram {
__le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */
__le32 cck[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 1usec counts */
} __attribute__ ((packed));
/* clear channel availability counters */
-struct iwl4965_measurement_cca_counters {
+struct iwl_measurement_cca_counters {
__le32 ofdm;
__le32 cck;
} __attribute__ ((packed));
-enum iwl4965_measure_type {
+enum iwl_measure_type {
IWL_MEASURE_BASIC = (1 << 0),
IWL_MEASURE_CHANNEL_LOAD = (1 << 1),
IWL_MEASURE_HISTOGRAM_RPI = (1 << 2),
@@ -2023,7 +1985,7 @@ enum iwl4965_measure_type {
/*
* SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command)
*/
-struct iwl4965_spectrum_notification {
+struct iwl_spectrum_notification {
u8 id; /* measurement id -- 0 or 1 */
u8 token;
u8 channel_index; /* index in measurement channel list */
@@ -2031,7 +1993,7 @@ struct iwl4965_spectrum_notification {
__le32 start_time; /* lower 32-bits of TSF */
u8 band; /* 0 - 5.2GHz, 1 - 2.4GHz */
u8 channel;
- u8 type; /* see enum iwl4965_measurement_type */
+ u8 type; /* see enum iwl_measurement_type */
u8 reserved1;
/* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only only
* valid if applicable for measurement type requested. */
@@ -2041,9 +2003,9 @@ struct iwl4965_spectrum_notification {
u8 basic_type; /* 0 - bss, 1 - ofdm preamble, 2 -
* unidentified */
u8 reserved2[3];
- struct iwl4965_measurement_histogram histogram;
+ struct iwl_measurement_histogram histogram;
__le32 stop_time; /* lower 32-bits of TSF */
- __le32 status; /* see iwl4965_measurement_status */
+ __le32 status; /* see iwl_measurement_status */
} __attribute__ ((packed));
/******************************************************************************
@@ -2101,7 +2063,7 @@ struct iwl_powertable_cmd {
* PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command)
* 3945 and 4965 identical.
*/
-struct iwl4965_sleep_notification {
+struct iwl_sleep_notification {
u8 pm_sleep_mode;
u8 pm_wakeup_src;
__le16 reserved;
@@ -2131,14 +2093,14 @@ enum {
#define CARD_STATE_CMD_DISABLE 0x00 /* Put card to sleep */
#define CARD_STATE_CMD_ENABLE 0x01 /* Wake up card */
#define CARD_STATE_CMD_HALT 0x02 /* Power down permanently */
-struct iwl4965_card_state_cmd {
+struct iwl_card_state_cmd {
__le32 status; /* CARD_STATE_CMD_* request new power state */
} __attribute__ ((packed));
/*
* CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command)
*/
-struct iwl4965_card_state_notif {
+struct iwl_card_state_notif {
__le32 flags;
} __attribute__ ((packed));
@@ -2201,7 +2163,7 @@ struct iwl_scan_channel {
* struct iwl_ssid_ie - directed scan network information element
*
* Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field
- * in struct iwl4965_scan_channel; each channel may select different ssids from
+ * in struct iwl_scan_channel; each channel may select different ssids from
* among the 4 entries. SSID IEs get transmitted in reverse order of entry.
*/
struct iwl_ssid_ie {
@@ -2301,7 +2263,7 @@ struct iwl_scan_cmd {
* Number of channels in list is specified by channel_count.
* Each channel in list is of type:
*
- * struct iwl4965_scan_channel channels[0];
+ * struct iwl_scan_channel channels[0];
*
* NOTE: Only one band of channels can be scanned per pass. You
* must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
@@ -2612,7 +2574,7 @@ struct iwl_notif_statistics {
* then this notification will be sent. */
#define CONSECUTIVE_MISSED_BCONS_TH 20
-struct iwl4965_missed_beacon_notif {
+struct iwl_missed_beacon_notif {
__le32 consequtive_missed_beacons;
__le32 total_missed_becons;
__le32 num_expected_beacons;
@@ -3049,27 +3011,22 @@ struct iwl_rx_packet {
struct iwl_cmd_header hdr;
union {
struct iwl_alive_resp alive_frame;
- struct iwl4965_rx_frame rx_frame;
- struct iwl4965_tx_resp tx_resp;
- struct iwl4965_spectrum_notification spectrum_notif;
- struct iwl4965_csa_notification csa_notif;
+ struct iwl_spectrum_notification spectrum_notif;
+ struct iwl_csa_notification csa_notif;
struct iwl_error_resp err_resp;
- struct iwl4965_card_state_notif card_state_notif;
- struct iwl4965_beacon_notif beacon_status;
+ struct iwl_card_state_notif card_state_notif;
struct iwl_add_sta_resp add_sta;
struct iwl_rem_sta_resp rem_sta;
- struct iwl4965_sleep_notification sleep_notif;
- struct iwl4965_spectrum_resp spectrum;
+ struct iwl_sleep_notification sleep_notif;
+ struct iwl_spectrum_resp spectrum;
struct iwl_notif_statistics stats;
struct iwl_compressed_ba_resp compressed_ba;
- struct iwl4965_missed_beacon_notif missed_beacon;
+ struct iwl_missed_beacon_notif missed_beacon;
__le32 status;
u8 raw[0];
} u;
} __attribute__ ((packed));
-#define IWL_RX_FRAME_SIZE (4 + sizeof(struct iwl4965_rx_frame))
-
int iwl_agn_check_rxon_cmd(struct iwl_rxon_cmd *rxon);
#endif /* __iwl_commands_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index d00dfe4edc3..73d7973707e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -22,7 +22,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
@@ -42,7 +42,7 @@
MODULE_DESCRIPTION("iwl core");
MODULE_VERSION(IWLWIFI_VERSION);
-MODULE_AUTHOR(DRV_COPYRIGHT);
+MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
MODULE_LICENSE("GPL");
#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
@@ -243,24 +243,25 @@ void iwl_reset_qos(struct iwl_priv *priv)
u16 cw_min = 15;
u16 cw_max = 1023;
u8 aifs = 2;
- u8 is_legacy = 0;
+ bool is_legacy = false;
unsigned long flags;
int i;
spin_lock_irqsave(&priv->lock, flags);
- priv->qos_data.qos_active = 0;
+ /* QoS always active in AP and ADHOC mode
+ * In STA mode wait for association
+ */
+ if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
+ priv->iw_mode == NL80211_IFTYPE_AP)
+ priv->qos_data.qos_active = 1;
+ else
+ priv->qos_data.qos_active = 0;
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC) {
- if (priv->qos_data.qos_enable)
- priv->qos_data.qos_active = 1;
- if (!(priv->active_rate & 0xfff0)) {
- cw_min = 31;
- is_legacy = 1;
- }
- } else if (priv->iw_mode == NL80211_IFTYPE_AP) {
- if (priv->qos_data.qos_enable)
- priv->qos_data.qos_active = 1;
- } else if (!(priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK)) {
+ /* check for legacy mode */
+ if ((priv->iw_mode == NL80211_IFTYPE_ADHOC &&
+ (priv->active_rate & IWL_OFDM_RATES_MASK) == 0) ||
+ (priv->iw_mode == NL80211_IFTYPE_STATION &&
+ (priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) {
cw_min = 31;
is_legacy = 1;
}
@@ -890,9 +891,6 @@ int iwl_init_drv(struct iwl_priv *priv)
iwl_set_rxon_chain(priv);
iwl_init_scan_params(priv);
- if (priv->cfg->mod_params->enable_qos)
- priv->qos_data.qos_enable = 1;
-
iwl_reset_qos(priv);
priv->qos_data.qos_active = 0;
@@ -1448,6 +1446,16 @@ int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
return 0;
}
+ /* when driver is up while rfkill is on, it wont receive
+ * any CARD_STATE_NOTIFICATION notifications so we have to
+ * restart it in here
+ */
+ if (priv->is_open && !test_bit(STATUS_ALIVE, &priv->status)) {
+ clear_bit(STATUS_RF_KILL_SW, &priv->status);
+ if (!iwl_is_rfkill(priv))
+ queue_work(priv->workqueue, &priv->up);
+ }
+
/* If the driver is already loaded, it will receive
* CARD_STATE_NOTIFICATION notifications and the handler will
* call restart to reload the driver.
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 81ddca07717..08b842f8576 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -25,7 +25,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
@@ -72,6 +72,7 @@ struct iwl_cmd;
#define IWLWIFI_VERSION "1.3.27k"
#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
+#define DRV_AUTHOR "<ilw@linux.intel.com>"
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
.vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
@@ -157,7 +158,6 @@ struct iwl_mod_params {
int disable_hw_scan; /* def: 0 = use h/w scan */
int num_of_queues; /* def: HW dependent */
int num_of_ampdu_queues;/* def: HW dependent */
- int enable_qos; /* def: 1 = use quality of service */
int disable_11n; /* def: 0 = disable 11n capabilities */
int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
int antenna; /* def: 0 = both antennas (use diversity) */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 84f56a21770..f34ede44ed1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -25,7 +25,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
@@ -216,6 +216,8 @@
/* EEPROM REG */
#define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001)
#define CSR_EEPROM_REG_BIT_CMD (0x00000002)
+#define CSR_EEPROM_REG_MSK_ADDR (0x0000FFFC)
+#define CSR_EEPROM_REG_MSK_DATA (0xFFFF0000)
/* EEPROM GP */
#define CSR_EEPROM_GP_VALID_MSK (0x00000006)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index a115dc64f6a..e4c264b4f7b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -21,7 +21,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 370b66c444b..d5253a179de 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -22,7 +22,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index a19fbb5eaae..eaf0c9cc33a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -19,7 +19,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -186,12 +186,6 @@ struct iwl_channel_info {
u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */
};
-struct iwl4965_clip_group {
- /* maximum power level to prevent clipping for each rate, derived by
- * us from this band's saturation power in EEPROM */
- const s8 clip_powers[IWL_MAX_RATES];
-};
-
#define IWL_TX_FIFO_AC0 0
#define IWL_TX_FIFO_AC1 1
@@ -436,7 +430,6 @@ union iwl_qos_capabity {
/* QoS structures */
struct iwl_qos_info {
- int qos_enable;
int qos_active;
union iwl_qos_capabity qos_cap;
struct iwl_qosparam_cmd def_qos_parm;
@@ -505,6 +498,10 @@ struct iwl_sensitivity_ranges {
#define IWL_FAT_CHANNEL_52 BIT(IEEE80211_BAND_5GHZ)
+#define KELVIN_TO_CELSIUS(x) ((x)-273)
+#define CELSIUS_TO_KELVIN(x) ((x)+273)
+
+
/**
* struct iwl_hw_params
* @max_txq_num: Max # Tx queues supported
@@ -553,15 +550,6 @@ struct iwl_hw_params {
#define HT_SHORT_GI_40MHZ (1 << 1)
-#define IWL_RX_HDR(x) ((struct iwl4965_rx_frame_hdr *)(\
- x->u.rx_frame.stats.payload + \
- x->u.rx_frame.stats.phy_count))
-#define IWL_RX_END(x) ((struct iwl4965_rx_frame_end *)(\
- IWL_RX_HDR(x)->payload + \
- le16_to_cpu(IWL_RX_HDR(x)->len)))
-#define IWL_RX_STATS(x) (&x->u.rx_frame.stats)
-#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload)
-
/******************************************************************************
*
* Functions implemented in core module which are forward declared here
@@ -792,7 +780,7 @@ struct iwl_priv {
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
/* spectrum measurement report caching */
- struct iwl4965_spectrum_notification measure_report;
+ struct iwl_spectrum_notification measure_report;
u8 measurement_status;
#endif
/* ucode beacon time */
@@ -803,10 +791,6 @@ struct iwl_priv {
struct iwl_channel_info *channel_info; /* channel info array */
u8 channel_count; /* # of channels */
- /* each calibration channel group in the EEPROM has a derived
- * clip setting for each rate. */
- const struct iwl4965_clip_group clip_groups[5];
-
/* thermal calibration */
s32 temperature; /* degrees Kelvin */
s32 last_temperature;
@@ -1003,9 +987,6 @@ struct iwl_priv {
s8 tx_power_user_lmt;
s8 tx_power_channel_lmt;
-#ifdef CONFIG_PM
- u32 pm_state[16];
-#endif
#ifdef CONFIG_IWLWIFI_DEBUG
/* debugging info */
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 792a3c15f17..ce2f47306ce 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -25,7 +25,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
@@ -169,10 +169,9 @@ int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
/* See if we got it */
- ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
- EEPROM_SEM_TIMEOUT);
+ ret = iwl_poll_direct_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
+ EEPROM_SEM_TIMEOUT);
if (ret >= 0) {
IWL_DEBUG_IO("Acquired semaphore after %d tries.\n",
count+1);
@@ -210,10 +209,8 @@ int iwl_eeprom_init(struct iwl_priv *priv)
{
u16 *e;
u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
- u32 r;
int sz = priv->cfg->eeprom_size;
int ret;
- int i;
u16 addr;
/* allocate eeprom */
@@ -241,22 +238,19 @@ int iwl_eeprom_init(struct iwl_priv *priv)
/* eeprom is an array of 16bit values */
for (addr = 0; addr < sz; addr += sizeof(u16)) {
- _iwl_write32(priv, CSR_EEPROM_REG, addr << 1);
- _iwl_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
-
- for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT;
- i += IWL_EEPROM_ACCESS_DELAY) {
- r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
- if (r & CSR_EEPROM_REG_READ_VALID_MSK)
- break;
- udelay(IWL_EEPROM_ACCESS_DELAY);
- }
+ u32 r;
+
+ _iwl_write32(priv, CSR_EEPROM_REG,
+ CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
- if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
+ ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
+ CSR_EEPROM_REG_READ_VALID_MSK,
+ IWL_EEPROM_ACCESS_TIMEOUT);
+ if (ret < 0) {
IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
- ret = -ETIMEDOUT;
goto done;
}
+ r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
}
ret = 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 8f6b05fa233..603c84bed63 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -25,7 +25,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
@@ -68,17 +68,14 @@ struct iwl_priv;
/*
* EEPROM access time values:
*
- * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG,
- * then clearing (with subsequent read/modify/write) CSR_EEPROM_REG bit
- * CSR_EEPROM_REG_BIT_CMD (0x2).
+ * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG.
* Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1).
* When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec.
* Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG.
*/
#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */
-#define IWL_EEPROM_ACCESS_DELAY 10 /* uSec */
-#define IWL_EEPROM_SEM_TIMEOUT 10 /* milliseconds */
+#define IWL_EEPROM_SEM_TIMEOUT 10 /* microseconds */
#define IWL_EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index c3dadb03701..d7da1986455 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -25,7 +25,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
@@ -266,11 +266,8 @@
#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000)
#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000)
-#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME (0x00008000)
-
#define FH_RSCSR_FRAME_SIZE_MSK (0x00003FFF) /* bits 0-13 */
-
/**
* Rx Shared Status Registers (RSSR)
*
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 0008a35232b..01a2169cece 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -22,7 +22,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 4f0fa215d32..ca4f638ab9d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -22,7 +22,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -32,8 +32,6 @@
#include <linux/ctype.h>
-#define KELVIN_TO_CELSIUS(x) ((x)-273)
-#define CELSIUS_TO_KELVIN(x) ((x)+273)
#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index bc10435d96e..998ac197169 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -21,7 +21,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -95,7 +95,7 @@ static inline int _iwl_poll_bit(struct iwl_priv *priv, u32 addr,
do {
if ((_iwl_read32(priv, addr) & mask) == (bits & mask))
return i;
- mdelay(10);
+ udelay(10);
i += 10;
} while (i < timeout);
@@ -269,19 +269,10 @@ static inline void iwl_write_reg_buf(struct iwl_priv *priv,
}
}
-static inline int _iwl_poll_direct_bit(struct iwl_priv *priv,
- u32 addr, u32 mask, int timeout)
+static inline int _iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr,
+ u32 mask, int timeout)
{
- int i = 0;
-
- do {
- if ((_iwl_read_direct32(priv, addr) & mask) == mask)
- return i;
- mdelay(10);
- i += 10;
- } while (i < timeout);
-
- return -ETIMEDOUT;
+ return _iwl_poll_bit(priv, addr, mask, mask, timeout);
}
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -308,6 +299,7 @@ static inline int __iwl_poll_direct_bit(const char *f, u32 l,
static inline u32 _iwl_read_prph(struct iwl_priv *priv, u32 reg)
{
_iwl_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
+ rmb();
return _iwl_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
}
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -330,6 +322,7 @@ static inline void _iwl_write_prph(struct iwl_priv *priv,
{
_iwl_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
((addr & 0x0000FFFF) | (3 << 24)));
+ wmb();
_iwl_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
}
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -392,12 +385,14 @@ static inline void iwl_clear_bits_prph(struct iwl_priv
static inline u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
{
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
+ rmb();
return iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
}
static inline void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
{
iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
+ wmb();
iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
}
@@ -405,6 +400,7 @@ static inline void iwl_write_targ_mem_buf(struct iwl_priv *priv, u32 addr,
u32 len, u32 *values)
{
iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
+ wmb();
for (; 0 < len; len -= sizeof(u32), values++)
iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index ffb428a7dd6..dce32ff8dec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -19,7 +19,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -41,7 +41,6 @@
#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-io.h"
-#include "iwl-helpers.h"
#ifdef CONFIG_IWLWIFI_DEBUG
static const char *led_type_str[] = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index 588c9ad20e8..021e00bcd1b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -19,7 +19,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index b429daa5a2b..75ca6a54217 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -22,7 +22,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
@@ -39,7 +39,6 @@
#include "iwl-commands.h"
#include "iwl-debug.h"
#include "iwl-power.h"
-#include "iwl-helpers.h"
/*
* Setting power level allow the card to go to sleep when not busy
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index df484a90ae6..fa098d8975c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -22,7 +22,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
#ifndef __iwl_power_setting_h__
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index b0ffb8919d3..b7a5f23351c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -25,7 +25,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
index 618841a53b9..4b69da30665 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
@@ -22,7 +22,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
#include <linux/kernel.h>
@@ -34,8 +34,6 @@
#include "iwl-eeprom.h"
#include "iwl-dev.h"
#include "iwl-core.h"
-#include "iwl-helpers.h"
-
/* software rf-kill from user */
static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
index 402fd4c781d..86dc055a2e9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
@@ -22,7 +22,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
#ifndef __iwl_rf_kill_h__
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 8d2b73e194d..919a775121e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -22,7 +22,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -439,7 +439,7 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
- FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME |
+ FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK |
rb_size|
(rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
(rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
@@ -467,10 +467,8 @@ int iwl_rxq_stop(struct iwl_priv *priv)
/* stop Rx DMA */
iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
- ret = iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
- (1 << 24), 1000);
- if (ret < 0)
- IWL_ERROR("Can't stop Rx DMA.\n");
+ iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
+ FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -484,7 +482,7 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
{
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- struct iwl4965_missed_beacon_notif *missed_beacon;
+ struct iwl_missed_beacon_notif *missed_beacon;
missed_beacon = &pkt->u.missed_beacon;
if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) {
@@ -622,20 +620,24 @@ static int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm)
return sig_qual;
}
-#ifdef CONFIG_IWLWIFI_DEBUG
+/* Calc max signal level (dBm) among 3 possible receivers */
+static inline int iwl_calc_rssi(struct iwl_priv *priv,
+ struct iwl_rx_phy_res *rx_resp)
+{
+ return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
+}
+#ifdef CONFIG_IWLWIFI_DEBUG
/**
* iwl_dbg_report_frame - dump frame to syslog during debug sessions
*
* You may hack this function to show different aspects of received frames,
* including selective frame dumps.
- * group100 parameter selects whether to show 1 out of 100 good frames.
- *
- * TODO: This was originally written for 3945, need to audit for
- * proper operation with 4965.
+ * group100 parameter selects whether to show 1 out of 100 good data frames.
+ * All beacon and probe response frames are printed.
*/
static void iwl_dbg_report_frame(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt,
+ struct iwl_rx_phy_res *phy_res, u16 length,
struct ieee80211_hdr *header, int group100)
{
u32 to_us;
@@ -647,20 +649,9 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv,
u16 seq_ctl;
u16 channel;
u16 phy_flags;
- int rate_sym;
- u16 length;
- u16 status;
- u16 bcn_tmr;
+ u32 rate_n_flags;
u32 tsf_low;
- u64 tsf;
- u8 rssi;
- u8 agc;
- u16 sig_avg;
- u16 noise_diff;
- struct iwl4965_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
- struct iwl4965_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
- struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt);
- u8 *data = IWL_RX_DATA(pkt);
+ int rssi;
if (likely(!(priv->debug_level & IWL_DL_RX)))
return;
@@ -670,22 +661,13 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv,
seq_ctl = le16_to_cpu(header->seq_ctrl);
/* metadata */
- channel = le16_to_cpu(rx_hdr->channel);
- phy_flags = le16_to_cpu(rx_hdr->phy_flags);
- rate_sym = rx_hdr->rate;
- length = le16_to_cpu(rx_hdr->len);
-
- /* end-of-frame status and timestamp */
- status = le32_to_cpu(rx_end->status);
- bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
- tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
- tsf = le64_to_cpu(rx_end->timestamp);
+ channel = le16_to_cpu(phy_res->channel);
+ phy_flags = le16_to_cpu(phy_res->phy_flags);
+ rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
/* signal statistics */
- rssi = rx_stats->rssi;
- agc = rx_stats->agc;
- sig_avg = le16_to_cpu(rx_stats->sig_avg);
- noise_diff = le16_to_cpu(rx_stats->noise_diff);
+ rssi = iwl_calc_rssi(priv, phy_res);
+ tsf_low = le64_to_cpu(phy_res->timestamp) & 0x0ffffffff;
to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
@@ -739,11 +721,13 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv,
else
title = "Frame";
- rate_idx = iwl_hwrate_to_plcp_idx(rate_sym);
- if (unlikely(rate_idx == -1))
+ rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
+ if (unlikely((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT))) {
bitrate = 0;
- else
+ WARN_ON_ONCE(1);
+ } else {
bitrate = iwl_rates[rate_idx].ieee / 2;
+ }
/* print frame summary.
* MAC addresses show just the last byte (for brevity),
@@ -755,24 +739,17 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv,
length, rssi, channel, bitrate);
else {
/* src/dst addresses assume managed mode */
- IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
- "src=0x%02x, rssi=%u, tim=%lu usec, "
+ IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, src=0x%02x, "
+ "len=%u, rssi=%d, tim=%lu usec, "
"phy=0x%02x, chnl=%d\n",
title, le16_to_cpu(fc), header->addr1[5],
- header->addr3[5], rssi,
+ header->addr3[5], length, rssi,
tsf_low - priv->scan_start_tsf,
phy_flags, channel);
}
}
if (print_dump)
- iwl_print_hex_dump(priv, IWL_DL_RX, data, length);
-}
-#else
-static inline void iwl_dbg_report_frame(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt,
- struct ieee80211_hdr *header,
- int group100)
-{
+ iwl_print_hex_dump(priv, IWL_DL_RX, header, length);
}
#endif
@@ -966,14 +943,6 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
rxb->skb = NULL;
}
-/* Calc max signal level (dBm) among 3 possible receivers */
-static inline int iwl_calc_rssi(struct iwl_priv *priv,
- struct iwl_rx_phy_res *rx_resp)
-{
- return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
-}
-
-
/* This is necessary only for a number of statistics, see the caller. */
static int iwl_is_network_packet(struct iwl_priv *priv,
struct ieee80211_hdr *header)
@@ -1096,9 +1065,10 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
/* Set "1" to report good data frames in groups of 100 */
- /* FIXME: need to optimize the call: */
- iwl_dbg_report_frame(priv, pkt, header, 1);
-
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (unlikely(priv->debug_level & IWL_DL_RX))
+ iwl_dbg_report_frame(priv, rx_start, len, header, 1);
+#endif
IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
rx_status.signal, rx_status.noise, rx_status.signal,
(unsigned long long)rx_status.mactime);
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index c4b90301e9a..3c803f6922e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -22,7 +22,7 @@
* in the file called LICENSE.GPL.
*
* Contact Information:
- * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
#include <linux/types.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.c b/drivers/net/wireless/iwlwifi/iwl-spectrum.c
index ad319a178a9..836c3c80b69 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.c
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.c
@@ -22,7 +22,7 @@
* file called LICENSE.
*
* Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -178,7 +178,7 @@ static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
+ struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
if (!report->state) {
IWL_DEBUG(IWL_DL_11H,
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
index fa990a10251..b7d7943e476 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
@@ -21,7 +21,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 4a2479a1622..412f66bac1a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -22,7 +22,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -33,8 +33,6 @@
#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-sta.h"
-#include "iwl-helpers.h"
-
#define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */
#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 7b98ea4dfbc..9bb7cefc1f3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -22,7 +22,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 18d6cf67d9b..1e7cd8d9039 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -22,7 +22,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -628,7 +628,7 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv)
iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG,
FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
- 200);
+ 1000);
}
iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 1a411c2d83e..352ccac7187 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -22,7 +22,7 @@
* file called LICENSE.
*
* Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
@@ -69,7 +69,6 @@ static int iwl3945_param_debug; /* def: 0 = minimal debug log messages */
static int iwl3945_param_disable; /* def: 0 = enable radio */
static int iwl3945_param_antenna; /* def: 0 = both antennas (use diversity) */
int iwl3945_param_hwcrypto; /* def: 0 = use software encryption */
-static int iwl3945_param_qos_enable = 1; /* def: 1 = use quality of service */
int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */
/*
@@ -94,12 +93,13 @@ int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */
#define IWLWIFI_VERSION "1.2.26k" VD VS
#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
+#define DRV_AUTHOR "<ilw@linux.intel.com>"
#define DRV_VERSION IWLWIFI_VERSION
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERSION);
-MODULE_AUTHOR(DRV_COPYRIGHT);
+MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
MODULE_LICENSE("GPL");
static const struct ieee80211_supported_band *iwl3945_get_band(
@@ -1505,10 +1505,8 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
{
u16 *e = (u16 *)&priv->eeprom;
u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP);
- u32 r;
int sz = sizeof(priv->eeprom);
- int rc;
- int i;
+ int ret;
u16 addr;
/* The EEPROM structure has several padding buffers within it
@@ -1523,29 +1521,28 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
}
/* Make sure driver (instead of uCode) is allowed to read EEPROM */
- rc = iwl3945_eeprom_acquire_semaphore(priv);
- if (rc < 0) {
+ ret = iwl3945_eeprom_acquire_semaphore(priv);
+ if (ret < 0) {
IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
return -ENOENT;
}
/* eeprom is an array of 16bit values */
for (addr = 0; addr < sz; addr += sizeof(u16)) {
- _iwl3945_write32(priv, CSR_EEPROM_REG, addr << 1);
- _iwl3945_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
-
- for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT;
- i += IWL_EEPROM_ACCESS_DELAY) {
- r = _iwl3945_read_direct32(priv, CSR_EEPROM_REG);
- if (r & CSR_EEPROM_REG_READ_VALID_MSK)
- break;
- udelay(IWL_EEPROM_ACCESS_DELAY);
- }
+ u32 r;
- if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
+ _iwl3945_write32(priv, CSR_EEPROM_REG,
+ CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
+ _iwl3945_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
+ ret = iwl3945_poll_direct_bit(priv, CSR_EEPROM_REG,
+ CSR_EEPROM_REG_READ_VALID_MSK,
+ IWL_EEPROM_ACCESS_TIMEOUT);
+ if (ret < 0) {
IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
- return -ETIMEDOUT;
+ return ret;
}
+
+ r = _iwl3945_read_direct32(priv, CSR_EEPROM_REG);
e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
}
@@ -1693,17 +1690,21 @@ static void iwl3945_reset_qos(struct iwl3945_priv *priv)
spin_lock_irqsave(&priv->lock, flags);
priv->qos_data.qos_active = 0;
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC) {
- if (priv->qos_data.qos_enable)
- priv->qos_data.qos_active = 1;
- if (!(priv->active_rate & 0xfff0)) {
- cw_min = 31;
- is_legacy = 1;
- }
- } else if (priv->iw_mode == NL80211_IFTYPE_AP) {
- if (priv->qos_data.qos_enable)
- priv->qos_data.qos_active = 1;
- } else if (!(priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK)) {
+ /* QoS always active in AP and ADHOC mode
+ * In STA mode wait for association
+ */
+ if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
+ priv->iw_mode == NL80211_IFTYPE_AP)
+ priv->qos_data.qos_active = 1;
+ else
+ priv->qos_data.qos_active = 0;
+
+
+ /* check for legacy mode */
+ if ((priv->iw_mode == NL80211_IFTYPE_ADHOC &&
+ (priv->active_rate & IWL_OFDM_RATES_MASK) == 0) ||
+ (priv->iw_mode == NL80211_IFTYPE_STATION &&
+ (priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) {
cw_min = 31;
is_legacy = 1;
}
@@ -1775,9 +1776,6 @@ static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- if (!priv->qos_data.qos_enable)
- return;
-
spin_lock_irqsave(&priv->lock, flags);
priv->qos_data.def_qos_parm.qos_flags = 0;
@@ -2103,11 +2101,6 @@ static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
static int iwl3945_scan_initiate(struct iwl3945_priv *priv)
{
- if (priv->iw_mode == NL80211_IFTYPE_AP) {
- IWL_ERROR("APs don't scan.\n");
- return 0;
- }
-
if (!iwl3945_is_ready_rf(priv)) {
IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
return -EIO;
@@ -6976,12 +6969,6 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
goto out_unlock;
}
- if (priv->iw_mode == NL80211_IFTYPE_AP) { /* APs don't scan */
- rc = -EIO;
- IWL_ERROR("ERROR: APs don't scan\n");
- goto out_unlock;
- }
-
/* we don't schedule scan within next_scan_jiffies period */
if (priv->next_scan_jiffies &&
time_after(priv->next_scan_jiffies, jiffies)) {
@@ -7095,11 +7082,6 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
return 0;
}
- if (!priv->qos_data.qos_enable) {
- priv->qos_data.qos_active = 0;
- IWL_DEBUG_MAC80211("leave - qos not enabled\n");
- return 0;
- }
q = AC_NUM - 1 - queue;
spin_lock_irqsave(&priv->lock, flags);
@@ -7925,9 +7907,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ err = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
if (err < 0) {
IWL_DEBUG_INFO("Failed to init the card\n");
goto out_remove_sysfs;
@@ -7980,9 +7961,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
priv->iw_mode = NL80211_IFTYPE_STATION;
- if (iwl3945_param_qos_enable)
- priv->qos_data.qos_enable = 1;
-
iwl3945_reset_qos(priv);
priv->qos_data.qos_active = 0;
@@ -8373,9 +8351,5 @@ MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
module_param_named(queues_num, iwl3945_param_queues_num, int, 0444);
MODULE_PARM_DESC(queues_num, "number of hw queues.");
-/* QoS */
-module_param_named(qos_enable, iwl3945_param_qos_enable, int, 0444);
-MODULE_PARM_DESC(qos_enable, "enable all QoS functionality");
-
module_exit(iwl3945_exit);
module_init(iwl3945_init);
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index a17b778c172..277ff1975bd 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -245,6 +245,7 @@ enum cmd_mesh_access_opts {
CMD_ACT_MESH_GET_ROUTE_EXP,
CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
CMD_ACT_MESH_GET_AUTOSTART_ENABLED,
+ CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT = 17,
};
/* Define actions and types for CMD_MESH_CONFIG */
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 241af7fe44b..3dba8367944 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -257,6 +257,58 @@ static ssize_t lbs_anycast_set(struct device *dev,
return strlen(buf);
}
+/**
+ * @brief Get function for sysfs attribute prb_rsp_limit
+ */
+static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct cmd_ds_mesh_access mesh_access;
+ int ret;
+ u32 retry_limit;
+
+ memset(&mesh_access, 0, sizeof(mesh_access));
+ mesh_access.data[0] = cpu_to_le32(CMD_ACT_GET);
+
+ ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
+ &mesh_access);
+ if (ret)
+ return ret;
+
+ retry_limit = le32_to_cpu(mesh_access.data[1]);
+ return snprintf(buf, 10, "%d\n", retry_limit);
+}
+
+/**
+ * @brief Set function for sysfs attribute prb_rsp_limit
+ */
+static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct cmd_ds_mesh_access mesh_access;
+ int ret;
+ unsigned long retry_limit;
+
+ memset(&mesh_access, 0, sizeof(mesh_access));
+ mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET);
+
+ if (!strict_strtoul(buf, 10, &retry_limit))
+ return -ENOTSUPP;
+ if (retry_limit > 15)
+ return -ENOTSUPP;
+
+ mesh_access.data[1] = cpu_to_le32(retry_limit);
+
+ ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
+ &mesh_access);
+ if (ret)
+ return ret;
+
+ return strlen(buf);
+}
+
static int lbs_add_rtap(struct lbs_private *priv);
static void lbs_remove_rtap(struct lbs_private *priv);
static int lbs_add_mesh(struct lbs_private *priv);
@@ -375,8 +427,16 @@ static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
*/
static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
+/**
+ * prb_rsp_limit attribute to be exported per mshX interface
+ * through sysfs (/sys/class/net/mshX/prb_rsp_limit)
+ */
+static DEVICE_ATTR(prb_rsp_limit, 0644, lbs_prb_rsp_limit_get,
+ lbs_prb_rsp_limit_set);
+
static struct attribute *lbs_mesh_sysfs_entries[] = {
&dev_attr_anycast_mask.attr,
+ &dev_attr_prb_rsp_limit.attr,
NULL,
};
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 530648b3993..fd5a537ac51 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -522,6 +522,10 @@ static void mac80211_hwsim_sta_notify(struct ieee80211_hw *hw,
case STA_NOTIFY_REMOVE:
hwsim_clear_sta_magic(sta);
break;
+ case STA_NOTIFY_SLEEP:
+ case STA_NOTIFY_AWAKE:
+ /* TODO: make good use of these flags */
+ break;
}
}
diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c
index ce03a2e865f..28f1cae4843 100644
--- a/drivers/net/wireless/orinoco/airport.c
+++ b/drivers/net/wireless/orinoco/airport.c
@@ -279,7 +279,7 @@ init_airport(void)
static void __exit
exit_airport(void)
{
- return macio_unregister_driver(&airport_driver);
+ macio_unregister_driver(&airport_driver);
}
module_init(init_airport);
diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c
index 171bfa03868..bc84e2792f8 100644
--- a/drivers/net/wireless/orinoco/orinoco.c
+++ b/drivers/net/wireless/orinoco/orinoco.c
@@ -1750,7 +1750,7 @@ static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
union iwreq_data wrqu;
int err;
- err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
if (err != 0)
return;
@@ -1773,7 +1773,7 @@ static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
if (!priv->has_wpa)
return;
- err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
sizeof(buf), NULL, &buf);
if (err != 0)
return;
@@ -1803,7 +1803,7 @@ static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
if (!priv->has_wpa)
return;
- err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
sizeof(buf), NULL, &buf);
if (err != 0)
return;
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index bf6a51da3b2..f127602670e 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -178,13 +178,17 @@ static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
/* Note that the CIS values need to be rescaled */
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
- DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
+ DEBUG(2, "%s: Vcc mismatch (vcc = %d, CIS = %d)\n",
+ __func__, vcc,
+ cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
if (!ignore_cis_vcc)
goto next_entry;
}
} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) {
- DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
+ DEBUG(2, "%s: Vcc mismatch (vcc = %d, CIS = %d)\n",
+ __func__, vcc,
+ dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
if (!ignore_cis_vcc)
goto next_entry;
}
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index a2764764c1c..b2ca2e39c2c 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -248,13 +248,17 @@ static int spectrum_cs_config_check(struct pcmcia_device *p_dev,
/* Note that the CIS values need to be rescaled */
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
- DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
+ DEBUG(2, "%s: Vcc mismatch (vcc = %d, CIS = %d)\n",
+ __func__, vcc,
+ cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
if (!ignore_cis_vcc)
goto next_entry;
}
} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) {
- DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
+ DEBUG(2, "%s: Vcc mismatch (vcc = %d, CIS = %d)\n",
+ __func__, vcc,
+ dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
if (!ignore_cis_vcc)
goto next_entry;
}
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 89968a5bff8..a4e99b02af0 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -540,6 +540,14 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
size_t header_len = sizeof(*hdr);
u32 tsf32;
+ /*
+ * If the device is in a unspecified state we have to
+ * ignore all data frames. Else we could end up with a
+ * nasty crash.
+ */
+ if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
+ return 0;
+
if (!(hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_IN_FCS_GOOD))) {
if (priv->filter_flags & FIF_FCSFAIL)
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
@@ -608,6 +616,12 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
if (unlikely(!skb || !dev || !skb_queue_len(&priv->tx_queue)))
return;
+ /*
+ * don't try to free an already unlinked skb
+ */
+ if (unlikely((!skb->next) || (!skb->prev)))
+ return;
+
spin_lock_irqsave(&priv->tx_queue.lock, flags);
info = IEEE80211_SKB_CB(skb);
range = (void *)info->rate_driver_data;
@@ -874,7 +888,27 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
return -EINVAL;
spin_lock_irqsave(&priv->tx_queue.lock, flags);
+
left = skb_queue_len(&priv->tx_queue);
+ if (unlikely(left >= 28)) {
+ /*
+ * The tx_queue is nearly full!
+ * We have throttle normal data traffic, because we must
+ * have a few spare slots for control frames left.
+ */
+ ieee80211_stop_queues(dev);
+
+ if (unlikely(left == 32)) {
+ /*
+ * The tx_queue is now really full.
+ *
+ * TODO: check if the device has crashed and reset it.
+ */
+ spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+ return -ENOSPC;
+ }
+ }
+
while (left--) {
u32 hole_size;
info = IEEE80211_SKB_CB(entry);
@@ -903,7 +937,7 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
if (!target_skb) {
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
ieee80211_stop_queues(dev);
- return -ENOMEM;
+ return -ENOSPC;
}
info = IEEE80211_SKB_CB(skb);
@@ -1051,19 +1085,6 @@ static int p54_sta_unlock(struct ieee80211_hw *dev, u8 *addr)
return 0;
}
-static void p54_sta_notify_ps(struct ieee80211_hw *dev,
- enum sta_notify_ps_cmd notify_cmd,
- struct ieee80211_sta *sta)
-{
- switch (notify_cmd) {
- case STA_NOTIFY_AWAKE:
- p54_sta_unlock(dev, sta->addr);
- break;
- default:
- break;
- }
-}
-
static void p54_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
enum sta_notify_cmd notify_cmd,
struct ieee80211_sta *sta)
@@ -1078,6 +1099,10 @@ static void p54_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
p54_sta_unlock(dev, sta->addr);
break;
+ case STA_NOTIFY_AWAKE:
+ /* update the firmware's filter table */
+ p54_sta_unlock(dev, sta->addr);
+ break;
default:
break;
}
@@ -1684,19 +1709,18 @@ static void p54_stop(struct ieee80211_hw *dev)
struct sk_buff *skb;
mutex_lock(&priv->conf_mutex);
+ priv->mode = NL80211_IFTYPE_UNSPECIFIED;
del_timer(&priv->stats_timer);
p54_free_skb(dev, priv->cached_stats);
priv->cached_stats = NULL;
if (priv->cached_beacon)
p54_tx_cancel(dev, priv->cached_beacon);
+ priv->stop(dev);
while ((skb = skb_dequeue(&priv->tx_queue)))
kfree_skb(skb);
-
priv->cached_beacon = NULL;
- priv->stop(dev);
priv->tsf_high32 = priv->tsf_low32 = 0;
- priv->mode = NL80211_IFTYPE_UNSPECIFIED;
mutex_unlock(&priv->conf_mutex);
}
@@ -2027,7 +2051,6 @@ static const struct ieee80211_ops p54_ops = {
.add_interface = p54_add_interface,
.remove_interface = p54_remove_interface,
.set_tim = p54_set_tim,
- .sta_notify_ps = p54_sta_notify_ps,
.sta_notify = p54_sta_notify,
.set_key = p54_set_key,
.config = p54_config,
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index d21c509325f..c28220e401b 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -332,13 +332,6 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
P54P_READ(dev_int);
-
- /* FIXME: unlikely to happen because the device usually runs out of
- memory before we fill the ring up, but we can make it impossible */
- if (idx - device_idx > ARRAY_SIZE(ring_control->tx_data) - 2) {
- p54_free_skb(dev, skb);
- printk(KERN_INFO "%s: tx overflow.\n", wiphy_name(dev->wiphy));
- }
}
static void p54p_stop(struct ieee80211_hw *dev)
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 2dd3cd41d0f..c2789e53b98 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -86,13 +86,13 @@ static void p54u_rx_cb(struct urb *urb)
struct ieee80211_hw *dev = info->dev;
struct p54u_priv *priv = dev->priv;
+ skb_unlink(skb, &priv->rx_queue);
+
if (unlikely(urb->status)) {
- info->urb = NULL;
- usb_free_urb(urb);
+ dev_kfree_skb_irq(skb);
return;
}
- skb_unlink(skb, &priv->rx_queue);
skb_put(skb, urb->actual_length);
if (priv->hw_type == P54U_NET2280)
@@ -105,7 +105,6 @@ static void p54u_rx_cb(struct urb *urb)
if (p54_rx(dev, skb)) {
skb = dev_alloc_skb(priv->common.rx_mtu + 32);
if (unlikely(!skb)) {
- usb_free_urb(urb);
/* TODO check rx queue length and refill *somewhere* */
return;
}
@@ -115,7 +114,6 @@ static void p54u_rx_cb(struct urb *urb)
info->dev = dev;
urb->transfer_buffer = skb_tail_pointer(skb);
urb->context = skb;
- skb_queue_tail(&priv->rx_queue, skb);
} else {
if (priv->hw_type == P54U_NET2280)
skb_push(skb, priv->common.tx_hdr_len);
@@ -130,11 +128,14 @@ static void p54u_rx_cb(struct urb *urb)
WARN_ON(1);
urb->transfer_buffer = skb_tail_pointer(skb);
}
-
- skb_queue_tail(&priv->rx_queue, skb);
}
-
- usb_submit_urb(urb, GFP_ATOMIC);
+ skb_queue_tail(&priv->rx_queue, skb);
+ usb_anchor_urb(urb, &priv->submitted);
+ if (usb_submit_urb(urb, GFP_ATOMIC)) {
+ skb_unlink(skb, &priv->rx_queue);
+ usb_unanchor_urb(urb);
+ dev_kfree_skb_irq(skb);
+ }
}
static void p54u_tx_reuse_skb_cb(struct urb *urb)
@@ -144,18 +145,6 @@ static void p54u_tx_reuse_skb_cb(struct urb *urb)
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)))->priv;
skb_pull(skb, priv->common.tx_hdr_len);
- usb_free_urb(urb);
-}
-
-static void p54u_tx_cb(struct urb *urb)
-{
- usb_free_urb(urb);
-}
-
-static void p54u_tx_free_cb(struct urb *urb)
-{
- kfree(urb->transfer_buffer);
- usb_free_urb(urb);
}
static void p54u_tx_free_skb_cb(struct urb *urb)
@@ -165,25 +154,36 @@ static void p54u_tx_free_skb_cb(struct urb *urb)
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
p54_free_skb(dev, skb);
- usb_free_urb(urb);
+}
+
+static void p54u_tx_dummy_cb(struct urb *urb) { }
+
+static void p54u_free_urbs(struct ieee80211_hw *dev)
+{
+ struct p54u_priv *priv = dev->priv;
+ usb_kill_anchored_urbs(&priv->submitted);
}
static int p54u_init_urbs(struct ieee80211_hw *dev)
{
struct p54u_priv *priv = dev->priv;
- struct urb *entry;
+ struct urb *entry = NULL;
struct sk_buff *skb;
struct p54u_rx_info *info;
+ int ret = 0;
while (skb_queue_len(&priv->rx_queue) < 32) {
skb = __dev_alloc_skb(priv->common.rx_mtu + 32, GFP_KERNEL);
- if (!skb)
- break;
+ if (!skb) {
+ ret = -ENOMEM;
+ goto err;
+ }
entry = usb_alloc_urb(0, GFP_KERNEL);
if (!entry) {
- kfree_skb(skb);
- break;
+ ret = -ENOMEM;
+ goto err;
}
+
usb_fill_bulk_urb(entry, priv->udev,
usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
skb_tail_pointer(skb),
@@ -192,26 +192,25 @@ static int p54u_init_urbs(struct ieee80211_hw *dev)
info->urb = entry;
info->dev = dev;
skb_queue_tail(&priv->rx_queue, skb);
- usb_submit_urb(entry, GFP_KERNEL);
+
+ usb_anchor_urb(entry, &priv->submitted);
+ ret = usb_submit_urb(entry, GFP_KERNEL);
+ if (ret) {
+ skb_unlink(skb, &priv->rx_queue);
+ usb_unanchor_urb(entry);
+ goto err;
+ }
+ usb_free_urb(entry);
+ entry = NULL;
}
return 0;
-}
-static void p54u_free_urbs(struct ieee80211_hw *dev)
-{
- struct p54u_priv *priv = dev->priv;
- struct p54u_rx_info *info;
- struct sk_buff *skb;
-
- while ((skb = skb_dequeue(&priv->rx_queue))) {
- info = (struct p54u_rx_info *) skb->cb;
- if (!info->urb)
- continue;
-
- usb_kill_urb(info->urb);
- kfree_skb(skb);
- }
+ err:
+ usb_free_urb(entry);
+ kfree_skb(skb);
+ p54u_free_urbs(dev);
+ return ret;
}
static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb,
@@ -219,6 +218,7 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb,
{
struct p54u_priv *priv = dev->priv;
struct urb *addr_urb, *data_urb;
+ int err = 0;
addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!addr_urb)
@@ -233,15 +233,31 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb,
usb_fill_bulk_urb(addr_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
&((struct p54_hdr *)skb->data)->req_id, 4,
- p54u_tx_cb, dev);
+ p54u_tx_dummy_cb, dev);
usb_fill_bulk_urb(data_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
skb->data, skb->len,
free_on_tx ? p54u_tx_free_skb_cb :
p54u_tx_reuse_skb_cb, skb);
- usb_submit_urb(addr_urb, GFP_ATOMIC);
- usb_submit_urb(data_urb, GFP_ATOMIC);
+ usb_anchor_urb(addr_urb, &priv->submitted);
+ err = usb_submit_urb(addr_urb, GFP_ATOMIC);
+ if (err) {
+ usb_unanchor_urb(addr_urb);
+ goto out;
+ }
+
+ usb_anchor_urb(addr_urb, &priv->submitted);
+ err = usb_submit_urb(data_urb, GFP_ATOMIC);
+ if (err)
+ usb_unanchor_urb(data_urb);
+
+ out:
+ usb_free_urb(addr_urb);
+ usb_free_urb(data_urb);
+
+ if (err)
+ p54_free_skb(dev, skb);
}
static __le32 p54u_lm87_chksum(const __le32 *data, size_t length)
@@ -281,7 +297,13 @@ static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb,
free_on_tx ? p54u_tx_free_skb_cb :
p54u_tx_reuse_skb_cb, skb);
- usb_submit_urb(data_urb, GFP_ATOMIC);
+ usb_anchor_urb(data_urb, &priv->submitted);
+ if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
+ usb_unanchor_urb(data_urb);
+ skb_pull(skb, sizeof(*hdr));
+ p54_free_skb(dev, skb);
+ }
+ usb_free_urb(data_urb);
}
static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb,
@@ -291,6 +313,7 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb,
struct urb *int_urb, *data_urb;
struct net2280_tx_hdr *hdr;
struct net2280_reg_write *reg;
+ int err = 0;
reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
if (!reg)
@@ -320,15 +343,42 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb,
usb_fill_bulk_urb(int_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
- p54u_tx_free_cb, dev);
- usb_submit_urb(int_urb, GFP_ATOMIC);
+ p54u_tx_dummy_cb, dev);
+
+ /*
+ * This flag triggers a code path in the USB subsystem that will
+ * free what's inside the transfer_buffer after the callback routine
+ * has completed.
+ */
+ int_urb->transfer_flags |= URB_FREE_BUFFER;
usb_fill_bulk_urb(data_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
skb->data, skb->len,
free_on_tx ? p54u_tx_free_skb_cb :
p54u_tx_reuse_skb_cb, skb);
- usb_submit_urb(data_urb, GFP_ATOMIC);
+
+ usb_anchor_urb(int_urb, &priv->submitted);
+ err = usb_submit_urb(int_urb, GFP_ATOMIC);
+ if (err) {
+ usb_unanchor_urb(int_urb);
+ goto out;
+ }
+
+ usb_anchor_urb(data_urb, &priv->submitted);
+ err = usb_submit_urb(data_urb, GFP_ATOMIC);
+ if (err) {
+ usb_unanchor_urb(data_urb);
+ goto out;
+ }
+ out:
+ usb_free_urb(int_urb);
+ usb_free_urb(data_urb);
+
+ if (err) {
+ skb_pull(skb, sizeof(*hdr));
+ p54_free_skb(dev, skb);
+ }
}
static int p54u_write(struct p54u_priv *priv,
@@ -885,6 +935,7 @@ static int __devinit p54u_probe(struct usb_interface *intf,
goto err_free_dev;
skb_queue_head_init(&priv->rx_queue);
+ init_usb_anchor(&priv->submitted);
p54u_open(dev);
err = p54_read_eeprom(dev);
diff --git a/drivers/net/wireless/p54/p54usb.h b/drivers/net/wireless/p54/p54usb.h
index 5b8fe91379c..54ee738bf2a 100644
--- a/drivers/net/wireless/p54/p54usb.h
+++ b/drivers/net/wireless/p54/p54usb.h
@@ -133,6 +133,7 @@ struct p54u_priv {
spinlock_t lock;
struct sk_buff_head rx_queue;
+ struct usb_anchor submitted;
};
#endif /* P54USB_H */
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h
index c385407a994..3b1e1c2aad2 100644
--- a/drivers/net/wireless/rtl818x/rtl8187.h
+++ b/drivers/net/wireless/rtl818x/rtl8187.h
@@ -99,6 +99,7 @@ struct rtl8187_priv {
struct ieee80211_supported_band band;
struct usb_device *udev;
u32 rx_conf;
+ struct usb_anchor anchored;
u16 txpwr_base;
u8 asic_rev;
u8 is_rtl8187b;
@@ -115,7 +116,6 @@ struct rtl8187_priv {
u8 aifsn[4];
struct {
__le64 buf;
- struct urb *urb;
struct sk_buff_head queue;
} b_tx_status;
};
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index dbf52e8bbd7..74f5449b792 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -99,7 +99,6 @@ static const struct ieee80211_channel rtl818x_channels[] = {
static void rtl8187_iowrite_async_cb(struct urb *urb)
{
kfree(urb->context);
- usb_free_urb(urb);
}
static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr,
@@ -136,11 +135,13 @@ static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr,
usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0),
(unsigned char *)dr, buf, len,
rtl8187_iowrite_async_cb, buf);
+ usb_anchor_urb(urb, &priv->anchored);
rc = usb_submit_urb(urb, GFP_ATOMIC);
if (rc < 0) {
kfree(buf);
- usb_free_urb(urb);
+ usb_unanchor_urb(urb);
}
+ usb_free_urb(urb);
}
static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv,
@@ -172,7 +173,6 @@ static void rtl8187_tx_cb(struct urb *urb)
struct ieee80211_hw *hw = info->rate_driver_data[0];
struct rtl8187_priv *priv = hw->priv;
- usb_free_urb(info->rate_driver_data[1]);
skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) :
sizeof(struct rtl8187_tx_hdr));
ieee80211_tx_info_clear_status(info);
@@ -273,11 +273,13 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep),
buf, skb->len, rtl8187_tx_cb, skb);
+ usb_anchor_urb(urb, &priv->anchored);
rc = usb_submit_urb(urb, GFP_ATOMIC);
if (rc < 0) {
- usb_free_urb(urb);
+ usb_unanchor_urb(urb);
kfree_skb(skb);
}
+ usb_free_urb(urb);
return 0;
}
@@ -301,41 +303,25 @@ static void rtl8187_rx_cb(struct urb *urb)
return;
}
spin_unlock(&priv->rx_queue.lock);
+ skb_put(skb, urb->actual_length);
if (unlikely(urb->status)) {
- usb_free_urb(urb);
dev_kfree_skb_irq(skb);
return;
}
- skb_put(skb, urb->actual_length);
if (!priv->is_rtl8187b) {
struct rtl8187_rx_hdr *hdr =
(typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
flags = le32_to_cpu(hdr->flags);
- signal = hdr->signal & 0x7f;
+ /* As with the RTL8187B below, the AGC is used to calculate
+ * signal strength and quality. In this case, the scaling
+ * constants are derived from the output of p54usb.
+ */
+ quality = 130 - ((41 * hdr->agc) >> 6);
+ signal = -4 - ((27 * hdr->agc) >> 6);
rx_status.antenna = (hdr->signal >> 7) & 1;
- rx_status.noise = hdr->noise;
rx_status.mactime = le64_to_cpu(hdr->mac_time);
- priv->quality = signal;
- rx_status.qual = priv->quality;
- priv->noise = hdr->noise;
- rate = (flags >> 20) & 0xF;
- if (rate > 3) { /* OFDM rate */
- if (signal > 90)
- signal = 90;
- else if (signal < 25)
- signal = 25;
- signal = 90 - signal;
- } else { /* CCK rate */
- if (signal > 95)
- signal = 95;
- else if (signal < 30)
- signal = 30;
- signal = 95 - signal;
- }
- rx_status.signal = signal;
- priv->signal = signal;
} else {
struct rtl8187b_rx_hdr *hdr =
(typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
@@ -353,18 +339,18 @@ static void rtl8187_rx_cb(struct urb *urb)
*/
flags = le32_to_cpu(hdr->flags);
quality = 170 - hdr->agc;
- if (quality > 100)
- quality = 100;
signal = 14 - hdr->agc / 2;
- rx_status.qual = quality;
- priv->quality = quality;
- rx_status.signal = signal;
- priv->signal = signal;
rx_status.antenna = (hdr->rssi >> 7) & 1;
rx_status.mactime = le64_to_cpu(hdr->mac_time);
- rate = (flags >> 20) & 0xF;
}
+ if (quality > 100)
+ quality = 100;
+ rx_status.qual = quality;
+ priv->quality = quality;
+ rx_status.signal = signal;
+ priv->signal = signal;
+ rate = (flags >> 20) & 0xF;
skb_trim(skb, flags & 0x0FFF);
rx_status.rate_idx = rate;
rx_status.freq = dev->conf.channel->center_freq;
@@ -376,7 +362,6 @@ static void rtl8187_rx_cb(struct urb *urb)
skb = dev_alloc_skb(RTL8187_MAX_RX);
if (unlikely(!skb)) {
- usb_free_urb(urb);
/* TODO check rx queue length and refill *somewhere* */
return;
}
@@ -388,24 +373,32 @@ static void rtl8187_rx_cb(struct urb *urb)
urb->context = skb;
skb_queue_tail(&priv->rx_queue, skb);
- usb_submit_urb(urb, GFP_ATOMIC);
+ usb_anchor_urb(urb, &priv->anchored);
+ if (usb_submit_urb(urb, GFP_ATOMIC)) {
+ usb_unanchor_urb(urb);
+ skb_unlink(skb, &priv->rx_queue);
+ dev_kfree_skb_irq(skb);
+ }
}
static int rtl8187_init_urbs(struct ieee80211_hw *dev)
{
struct rtl8187_priv *priv = dev->priv;
- struct urb *entry;
+ struct urb *entry = NULL;
struct sk_buff *skb;
struct rtl8187_rx_info *info;
+ int ret = 0;
while (skb_queue_len(&priv->rx_queue) < 8) {
skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL);
- if (!skb)
- break;
+ if (!skb) {
+ ret = -ENOMEM;
+ goto err;
+ }
entry = usb_alloc_urb(0, GFP_KERNEL);
if (!entry) {
- kfree_skb(skb);
- break;
+ ret = -ENOMEM;
+ goto err;
}
usb_fill_bulk_urb(entry, priv->udev,
usb_rcvbulkpipe(priv->udev,
@@ -416,10 +409,22 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
info->urb = entry;
info->dev = dev;
skb_queue_tail(&priv->rx_queue, skb);
- usb_submit_urb(entry, GFP_KERNEL);
+ usb_anchor_urb(entry, &priv->anchored);
+ ret = usb_submit_urb(entry, GFP_KERNEL);
+ if (ret) {
+ skb_unlink(skb, &priv->rx_queue);
+ usb_unanchor_urb(entry);
+ goto err;
+ }
+ usb_free_urb(entry);
}
+ return ret;
- return 0;
+err:
+ usb_free_urb(entry);
+ kfree_skb(skb);
+ usb_kill_anchored_urbs(&priv->anchored);
+ return ret;
}
static void rtl8187b_status_cb(struct urb *urb)
@@ -429,10 +434,8 @@ static void rtl8187b_status_cb(struct urb *urb)
u64 val;
unsigned int cmd_type;
- if (unlikely(urb->status)) {
- usb_free_urb(urb);
+ if (unlikely(urb->status))
return;
- }
/*
* Read from status buffer:
@@ -503,26 +506,32 @@ static void rtl8187b_status_cb(struct urb *urb)
spin_unlock_irqrestore(&priv->b_tx_status.queue.lock, flags);
}
- usb_submit_urb(urb, GFP_ATOMIC);
+ usb_anchor_urb(urb, &priv->anchored);
+ if (usb_submit_urb(urb, GFP_ATOMIC))
+ usb_unanchor_urb(urb);
}
static int rtl8187b_init_status_urb(struct ieee80211_hw *dev)
{
struct rtl8187_priv *priv = dev->priv;
struct urb *entry;
+ int ret = 0;
entry = usb_alloc_urb(0, GFP_KERNEL);
if (!entry)
return -ENOMEM;
- priv->b_tx_status.urb = entry;
usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, 9),
&priv->b_tx_status.buf, sizeof(priv->b_tx_status.buf),
rtl8187b_status_cb, dev);
- usb_submit_urb(entry, GFP_KERNEL);
+ usb_anchor_urb(entry, &priv->anchored);
+ ret = usb_submit_urb(entry, GFP_KERNEL);
+ if (ret)
+ usb_unanchor_urb(entry);
+ usb_free_urb(entry);
- return 0;
+ return ret;
}
static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
@@ -856,6 +865,9 @@ static int rtl8187_start(struct ieee80211_hw *dev)
return ret;
mutex_lock(&priv->conf_mutex);
+
+ init_usb_anchor(&priv->anchored);
+
if (priv->is_rtl8187b) {
reg = RTL818X_RX_CONF_MGMT |
RTL818X_RX_CONF_DATA |
@@ -951,12 +963,12 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
while ((skb = skb_dequeue(&priv->rx_queue))) {
info = (struct rtl8187_rx_info *)skb->cb;
- usb_kill_urb(info->urb);
kfree_skb(skb);
}
while ((skb = skb_dequeue(&priv->b_tx_status.queue)))
dev_kfree_skb_any(skb);
- usb_kill_urb(priv->b_tx_status.urb);
+
+ usb_kill_anchored_urbs(&priv->anchored);
mutex_unlock(&priv->conf_mutex);
}
@@ -1293,6 +1305,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
priv->mode = NL80211_IFTYPE_MONITOR;
dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+ IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_RX_INCLUDES_FCS;
eeprom.data = dev;
@@ -1408,13 +1421,8 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
(*channel++).hw_value = txpwr >> 8;
}
- if (priv->is_rtl8187b) {
+ if (priv->is_rtl8187b)
printk(KERN_WARNING "rtl8187: 8187B chip detected.\n");
- dev->flags |= IEEE80211_HW_SIGNAL_DBM;
- } else {
- dev->flags |= IEEE80211_HW_SIGNAL_UNSPEC;
- dev->max_signal = 65;
- }
/*
* XXX: Once this driver supports anything that requires
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index a6ec928186a..c4e6ca1a630 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -836,7 +836,7 @@ struct ieee80211_ht_info {
/* Authentication algorithms */
#define WLAN_AUTH_OPEN 0
#define WLAN_AUTH_SHARED_KEY 1
-#define WLAN_AUTH_LEAP 2
+#define WLAN_AUTH_LEAP 128
#define WLAN_AUTH_CHALLENGE_LEN 128
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index f376a93927f..164332cbb77 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -149,11 +149,4 @@ static inline char *rfkill_get_led_name(struct rfkill *rfkill)
#endif
}
-/* rfkill notification chain */
-#define RFKILL_STATE_CHANGED 0x0001 /* state of a normal rfkill
- switch has changed */
-
-int register_rfkill_notifier(struct notifier_block *nb);
-int unregister_rfkill_notifier(struct notifier_block *nb);
-
#endif /* RFKILL_H */
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index 7ab3ed2bbcc..adb7cf31f78 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -385,9 +385,8 @@ struct ieee80211_device;
#define SCM_TEMPORAL_KEY_LENGTH 16
struct ieee80211_security {
- u16 active_key:2,
- enabled:1,
- auth_mode:2, auth_algo:4, unicast_uses_group:1, encrypt:1;
+ u16 active_key:2, enabled:1, unicast_uses_group:1, encrypt:1;
+ u8 auth_mode;
u8 encode_alg[WEP_KEYS];
u8 key_sizes[WEP_KEYS];
u8 keys[WEP_KEYS][SCM_KEY_LEN];
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index e84c922a1b1..046ce692a90 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -773,25 +773,16 @@ struct ieee80211_sta {
* enum sta_notify_cmd - sta notify command
*
* Used with the sta_notify() callback in &struct ieee80211_ops, this
- * indicates addition and removal of a station to station table.
+ * indicates addition and removal of a station to station table,
+ * or if a associated station made a power state transition.
*
* @STA_NOTIFY_ADD: a station was added to the station table
* @STA_NOTIFY_REMOVE: a station being removed from the station table
- */
-enum sta_notify_cmd {
- STA_NOTIFY_ADD, STA_NOTIFY_REMOVE
-};
-
-/**
- * enum sta_notify_ps_cmd - sta power save notify command
- *
- * Used with the sta_notify_ps() callback in &struct ieee80211_ops to
- * notify the driver if a station made a power state transition.
- *
* @STA_NOTIFY_SLEEP: a station is now sleeping
* @STA_NOTIFY_AWAKE: a sleeping station woke up
*/
-enum sta_notify_ps_cmd {
+enum sta_notify_cmd {
+ STA_NOTIFY_ADD, STA_NOTIFY_REMOVE,
STA_NOTIFY_SLEEP, STA_NOTIFY_AWAKE,
};
@@ -1258,15 +1249,9 @@ enum ieee80211_ampdu_mlme_action {
*
* @set_rts_threshold: Configuration of RTS threshold (if device needs it)
*
- * @set_frag_threshold: Configuration of fragmentation threshold. Assign this if
- * the device does fragmentation by itself; if this method is assigned then
- * the stack will not do fragmentation.
- *
- * @sta_notify: Notifies low level driver about addition or removal
- * of associated station or AP.
- *
- * @sta_ps_notify: Notifies low level driver about the power state transition
- * of a associated station. Must be atomic.
+ * @sta_notify: Notifies low level driver about addition, removal or power
+ * state transition of an associated station, AP, IBSS/WDS/mesh peer etc.
+ * Must be atomic.
*
* @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
* bursting) for a hardware TX queue.
@@ -1331,11 +1316,8 @@ struct ieee80211_ops {
void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx,
u32 *iv32, u16 *iv16);
int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value);
- int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value);
void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum sta_notify_cmd, struct ieee80211_sta *sta);
- void (*sta_notify_ps)(struct ieee80211_hw *hw,
- enum sta_notify_ps_cmd, struct ieee80211_sta *sta);
int (*conf_tx)(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
int (*get_tx_stats)(struct ieee80211_hw *hw,
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 31cfd1f89a7..7d4971aa443 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -46,3 +46,5 @@ rc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o
mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y)
mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y)
+
+ccflags-y += -D__CHECK_ENDIAN__
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 7a7a6c176dc..7912eb14eca 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -396,8 +396,10 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
*/
if (params->interval) {
sdata->local->hw.conf.beacon_int = params->interval;
- ieee80211_hw_config(sdata->local,
- IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
+ err = ieee80211_hw_config(sdata->local,
+ IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
+ if (err < 0)
+ return err;
/*
* We updated some parameter so if below bails out
* it's not an error.
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 527205f8c1a..6f59e11d7b3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -187,7 +187,6 @@ struct ieee80211_rx_data {
struct ieee80211_rx_status *status;
struct ieee80211_rate *rate;
- u16 ethertype;
unsigned int flags;
int sent_ps_buffered;
int queue;
@@ -864,8 +863,7 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid);
void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata,
struct ieee80211_if_sta *ifsta);
struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
- struct sk_buff *skb, u8 *bssid,
- u8 *addr, u64 supp_rates);
+ u8 *bssid, u8 *addr, u64 supp_rates);
int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason);
int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason);
u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 29c3ecf7e91..6d8710327d1 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -243,10 +243,20 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
if (changed && local->open_count) {
ret = local->ops->config(local_to_hw(local), changed);
/*
+ * Goal:
* HW reconfiguration should never fail, the driver has told
* us what it can support so it should live up to that promise.
+ *
+ * Current status:
+ * rfkill is not integrated with mac80211 and a
+ * configuration command can thus fail if hardware rfkill
+ * is enabled
+ *
+ * FIXME: integrate rfkill with mac80211 and then add this
+ * WARN_ON() back
+ *
*/
- WARN_ON(ret);
+ /* WARN_ON(ret); */
}
return ret;
@@ -876,12 +886,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
local->mdev->select_queue = ieee80211_select_queue;
- /* add one default STA interface */
- result = ieee80211_if_add(local, "wlan%d", NULL,
- NL80211_IFTYPE_STATION, NULL);
- if (result)
- printk(KERN_WARNING "%s: Failed to add default virtual iface\n",
- wiphy_name(local->hw.wiphy));
+ /* add one default STA interface if supported */
+ if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
+ result = ieee80211_if_add(local, "wlan%d", NULL,
+ NL80211_IFTYPE_STATION, NULL);
+ if (result)
+ printk(KERN_WARNING "%s: Failed to add default virtual iface\n",
+ wiphy_name(local->hw.wiphy));
+ }
rtnl_unlock();
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 87b2ac85d91..290b0017ef2 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1565,8 +1565,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
(unsigned long long) sta->sta.supp_rates[band]);
#endif
} else {
- ieee80211_ibss_add_sta(sdata, NULL, mgmt->bssid,
- mgmt->sa, supp_rates);
+ ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates);
}
rcu_read_unlock();
@@ -1638,9 +1637,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
sdata->dev->name, mgmt->bssid);
#endif
ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss);
- ieee80211_ibss_add_sta(sdata, NULL,
- mgmt->bssid, mgmt->sa,
- supp_rates);
+ ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates);
}
}
@@ -2373,8 +2370,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
* must be callable in atomic context.
*/
struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
- struct sk_buff *skb, u8 *bssid,
- u8 *addr, u64 supp_rates)
+ u8 *bssid,u8 *addr, u64 supp_rates)
{
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 14be095b852..73cf126cef4 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -658,9 +658,9 @@ static void ap_sta_ps_start(struct sta_info *sta)
atomic_inc(&sdata->bss->num_sta_ps);
set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL);
- if (local->ops->sta_notify_ps)
- local->ops->sta_notify_ps(local_to_hw(local), STA_NOTIFY_SLEEP,
- &sta->sta);
+ if (local->ops->sta_notify)
+ local->ops->sta_notify(local_to_hw(local), &sdata->vif,
+ STA_NOTIFY_SLEEP, &sta->sta);
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n",
sdata->dev->name, sta->sta.addr, sta->sta.aid);
@@ -677,9 +677,9 @@ static int ap_sta_ps_end(struct sta_info *sta)
atomic_dec(&sdata->bss->num_sta_ps);
clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL);
- if (local->ops->sta_notify_ps)
- local->ops->sta_notify_ps(local_to_hw(local), STA_NOTIFY_AWAKE,
- &sta->sta);
+ if (local->ops->sta_notify)
+ local->ops->sta_notify(local_to_hw(local), &sdata->vif,
+ STA_NOTIFY_AWAKE, &sta->sta);
if (!skb_queue_empty(&sta->ps_tx_buf))
sta_info_clear_tim_bit(sta);
@@ -1850,9 +1850,8 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
return 0;
rx->flags &= ~IEEE80211_RX_RA_MATCH;
} else if (!rx->sta)
- rx->sta = ieee80211_ibss_add_sta(sdata, rx->skb,
- bssid, hdr->addr2,
- BIT(rx->status->rate_idx));
+ rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2,
+ BIT(rx->status->rate_idx));
break;
case NL80211_IFTYPE_MESH_POINT:
if (!multicast &&
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index d7761e95e4c..b098c58d216 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1001,7 +1001,6 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
if (tx->flags & IEEE80211_TX_FRAGMENTED) {
if ((tx->flags & IEEE80211_TX_UNICAST) &&
skb->len + FCS_LEN > local->fragmentation_threshold &&
- !local->ops->set_frag_threshold &&
!(info->flags & IEEE80211_TX_CTL_AMPDU))
tx->flags |= IEEE80211_TX_FRAGMENTED;
else
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 4e1fdcfacb0..15428048d01 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -418,8 +418,7 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev,
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
sdata->vif.type != NL80211_IFTYPE_ADHOC &&
- sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
- sdata->vif.type != NL80211_IFTYPE_AP)
+ sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
return -EOPNOTSUPP;
/* if SSID was specified explicitly then use that */
@@ -639,14 +638,6 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev,
local->fragmentation_threshold = frag->value & ~0x1;
}
- /* If the wlan card performs fragmentation in hardware/firmware,
- * configure it here */
-
- if (local->ops->set_frag_threshold)
- return local->ops->set_frag_threshold(
- local_to_hw(local),
- local->fragmentation_threshold);
-
return 0;
}
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 051d2c9ea66..3c94f76d552 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -53,51 +53,6 @@ static struct rfkill_gsw_state rfkill_global_states[RFKILL_TYPE_MAX];
static unsigned long rfkill_states_lockdflt[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
static bool rfkill_epo_lock_active;
-static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list);
-
-
-/**
- * register_rfkill_notifier - Add notifier to rfkill notifier chain
- * @nb: pointer to the new entry to add to the chain
- *
- * See blocking_notifier_chain_register() for return value and further
- * observations.
- *
- * Adds a notifier to the rfkill notifier chain. The chain will be
- * called with a pointer to the relevant rfkill structure as a parameter,
- * refer to include/linux/rfkill.h for the possible events.
- *
- * Notifiers added to this chain are to always return NOTIFY_DONE. This
- * chain is a blocking notifier chain: notifiers can sleep.
- *
- * Calls to this chain may have been done through a workqueue. One must
- * assume unordered asynchronous behaviour, there is no way to know if
- * actions related to the event that generated the notification have been
- * carried out already.
- */
-int register_rfkill_notifier(struct notifier_block *nb)
-{
- BUG_ON(!nb);
- return blocking_notifier_chain_register(&rfkill_notifier_list, nb);
-}
-EXPORT_SYMBOL_GPL(register_rfkill_notifier);
-
-/**
- * unregister_rfkill_notifier - remove notifier from rfkill notifier chain
- * @nb: pointer to the entry to remove from the chain
- *
- * See blocking_notifier_chain_unregister() for return value and further
- * observations.
- *
- * Removes a notifier from the rfkill notifier chain.
- */
-int unregister_rfkill_notifier(struct notifier_block *nb)
-{
- BUG_ON(!nb);
- return blocking_notifier_chain_unregister(&rfkill_notifier_list, nb);
-}
-EXPORT_SYMBOL_GPL(unregister_rfkill_notifier);
-
static void rfkill_led_trigger(struct rfkill *rfkill,
enum rfkill_state state)
@@ -124,12 +79,9 @@ static void rfkill_led_trigger_activate(struct led_classdev *led)
}
#endif /* CONFIG_RFKILL_LEDS */
-static void notify_rfkill_state_change(struct rfkill *rfkill)
+static void rfkill_uevent(struct rfkill *rfkill)
{
- rfkill_led_trigger(rfkill, rfkill->state);
- blocking_notifier_call_chain(&rfkill_notifier_list,
- RFKILL_STATE_CHANGED,
- rfkill);
+ kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);
}
static void update_rfkill_state(struct rfkill *rfkill)
@@ -142,7 +94,7 @@ static void update_rfkill_state(struct rfkill *rfkill)
oldstate = rfkill->state;
rfkill->state = newstate;
if (oldstate != newstate)
- notify_rfkill_state_change(rfkill);
+ rfkill_uevent(rfkill);
}
mutex_unlock(&rfkill->mutex);
}
@@ -220,7 +172,7 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
}
if (force || rfkill->state != oldstate)
- notify_rfkill_state_change(rfkill);
+ rfkill_uevent(rfkill);
return retval;
}
@@ -405,7 +357,7 @@ int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
rfkill->state = state;
if (state != oldstate)
- notify_rfkill_state_change(rfkill);
+ rfkill_uevent(rfkill);
mutex_unlock(&rfkill->mutex);
@@ -618,28 +570,6 @@ static int rfkill_resume(struct device *dev)
#define rfkill_resume NULL
#endif
-static int rfkill_blocking_uevent_notifier(struct notifier_block *nb,
- unsigned long eventid,
- void *data)
-{
- struct rfkill *rfkill = (struct rfkill *)data;
-
- switch (eventid) {
- case RFKILL_STATE_CHANGED:
- kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);
- break;
- default:
- break;
- }
-
- return NOTIFY_DONE;
-}
-
-static struct notifier_block rfkill_blocking_uevent_nb = {
- .notifier_call = rfkill_blocking_uevent_notifier,
- .priority = 0,
-};
-
static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct rfkill *rfkill = to_rfkill(dev);
@@ -942,14 +872,11 @@ static int __init rfkill_init(void)
return error;
}
- register_rfkill_notifier(&rfkill_blocking_uevent_nb);
-
return 0;
}
static void __exit rfkill_exit(void)
{
- unregister_rfkill_notifier(&rfkill_blocking_uevent_nb);
class_unregister(&rfkill_class);
}
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index 9bc412c8343..938a334c8db 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -8,3 +8,5 @@ obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o
cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
cfg80211-$(CONFIG_NL80211) += nl80211.o
+
+ccflags-y += -D__CHECK_ENDIAN__
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 9caee6022e3..4335f76be71 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -365,6 +365,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
enum nl80211_sec_chan_offset sec_chan_offset =
NL80211_SEC_CHAN_NO_HT;
struct ieee80211_channel *chan;
+ struct ieee80211_sta_ht_cap *ht_cap;
u32 freq, sec_freq;
if (!rdev->ops->set_channel) {
@@ -372,26 +373,25 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
goto bad_res;
}
+ result = -EINVAL;
+
if (info->attrs[NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]) {
- sec_chan_offset = nla_get_u32(
- info->attrs[
+ sec_chan_offset = nla_get_u32(info->attrs[
NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]);
if (sec_chan_offset != NL80211_SEC_CHAN_NO_HT &&
sec_chan_offset != NL80211_SEC_CHAN_DISABLED &&
sec_chan_offset != NL80211_SEC_CHAN_BELOW &&
- sec_chan_offset != NL80211_SEC_CHAN_ABOVE) {
- result = -EINVAL;
+ sec_chan_offset != NL80211_SEC_CHAN_ABOVE)
goto bad_res;
- }
}
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
chan = ieee80211_get_channel(&rdev->wiphy, freq);
- if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
- /* Primary channel not allowed */
- result = -EINVAL;
+
+ /* Primary channel not allowed */
+ if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
goto bad_res;
- }
+
if (sec_chan_offset == NL80211_SEC_CHAN_BELOW)
sec_freq = freq - 20;
else if (sec_chan_offset == NL80211_SEC_CHAN_ABOVE)
@@ -399,14 +399,26 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
else
sec_freq = 0;
+ ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
+
+ /* no HT capabilities */
+ if (sec_chan_offset != NL80211_SEC_CHAN_NO_HT &&
+ !ht_cap->ht_supported)
+ goto bad_res;
+
if (sec_freq) {
struct ieee80211_channel *schan;
+
+ /* no 40 MHz capabilities */
+ if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
+ (ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT))
+ goto bad_res;
+
schan = ieee80211_get_channel(&rdev->wiphy, sec_freq);
- if (!schan || schan->flags & IEEE80211_CHAN_DISABLED) {
- /* Secondary channel not allowed */
- result = -EINVAL;
+
+ /* Secondary channel not allowed */
+ if (!schan || schan->flags & IEEE80211_CHAN_DISABLED)
goto bad_res;
- }
}
result = rdev->ops->set_channel(&rdev->wiphy, chan,
@@ -416,7 +428,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
}
-bad_res:
+ bad_res:
cfg80211_put_dev(rdev);
return result;
}