提交 56bde885 编写于 作者: D David S. Miller
...@@ -1099,9 +1099,9 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, ...@@ -1099,9 +1099,9 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
if (ah->ah_combined_mic) { if (ah->ah_combined_mic) {
key_v[0] = rxmic[0]; 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[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]; key_v[4] = txmic[1];
} else { } else {
key_v[0] = rxmic[0]; key_v[0] = rxmic[0];
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define AR9160_DEVID_PCI 0x0027 #define AR9160_DEVID_PCI 0x0027
#define AR9280_DEVID_PCI 0x0029 #define AR9280_DEVID_PCI 0x0029
#define AR9280_DEVID_PCIE 0x002a #define AR9280_DEVID_PCIE 0x002a
#define AR9285_DEVID_PCIE 0x002b
#define AR5416_AR9100_DEVID 0x000b #define AR5416_AR9100_DEVID 0x000b
......
...@@ -26,7 +26,7 @@ static int ath_beaconq_config(struct ath_softc *sc) ...@@ -26,7 +26,7 @@ static int ath_beaconq_config(struct ath_softc *sc)
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
struct ath9k_tx_queue_info qi; 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) { if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
/* Always burst out beacon and CAB traffic. */ /* Always burst out beacon and CAB traffic. */
qi.tqi_aifs = 1; qi.tqi_aifs = 1;
...@@ -34,17 +34,17 @@ static int ath_beaconq_config(struct ath_softc *sc) ...@@ -34,17 +34,17 @@ static int ath_beaconq_config(struct ath_softc *sc)
qi.tqi_cwmax = 0; qi.tqi_cwmax = 0;
} else { } else {
/* Adhoc mode; important thing is to use 2x cwmin. */ /* Adhoc mode; important thing is to use 2x cwmin. */
qi.tqi_aifs = sc->sc_beacon_qi.tqi_aifs; qi.tqi_aifs = sc->beacon.beacon_qi.tqi_aifs;
qi.tqi_cwmin = 2*sc->sc_beacon_qi.tqi_cwmin; qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin;
qi.tqi_cwmax = sc->sc_beacon_qi.tqi_cwmax; 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, DPRINTF(sc, ATH_DBG_FATAL,
"unable to update h/w beacon queue parameters\n"); "unable to update h/w beacon queue parameters\n");
return 0; return 0;
} else { } 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; return 1;
} }
} }
...@@ -53,7 +53,7 @@ static void ath_bstuck_process(struct ath_softc *sc) ...@@ -53,7 +53,7 @@ static void ath_bstuck_process(struct ath_softc *sc)
{ {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"stuck beacon; resetting (bmiss count %u)\n", "stuck beacon; resetting (bmiss count %u)\n",
sc->sc_bmisscount); sc->beacon.bmisscnt);
ath_reset(sc, false); ath_reset(sc, false);
} }
...@@ -96,7 +96,7 @@ static void ath_beacon_setup(struct ath_softc *sc, ...@@ -96,7 +96,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
* SWBA's * SWBA's
* XXX assumes two antenna * 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; ds->ds_data = bf->bf_buf_addr;
...@@ -106,7 +106,7 @@ static void ath_beacon_setup(struct ath_softc *sc, ...@@ -106,7 +106,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
* XXX everything at min xmit rate * XXX everything at min xmit rate
*/ */
rix = 0; rix = 0;
rt = sc->hw_rate_table[sc->sc_curmode]; rt = sc->cur_rate_table;
rate = rt->info[rix].ratecode; rate = rt->info[rix].ratecode;
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
rate |= rt->info[rix].short_preamble; rate |= rt->info[rix].short_preamble;
...@@ -153,7 +153,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) ...@@ -153,7 +153,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
ASSERT(vif); ASSERT(vif);
avp = (void *)vif->drv_priv; avp = (void *)vif->drv_priv;
cabq = sc->sc_cabq; cabq = sc->beacon.cabq;
if (avp->av_bcbuf == NULL) { if (avp->av_bcbuf == NULL) {
DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n", 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) ...@@ -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, pci_unmap_single(sc->pdev, bf->bf_dmacontext,
skb->len, skb->len,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
dev_kfree_skb_any(skb);
} }
skb = ieee80211_beacon_get(sc->hw, vif); 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) ...@@ -181,9 +182,9 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
* TX frames) * TX frames)
*/ */
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 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(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 = bf->bf_buf_addr = bf->bf_dmacontext =
...@@ -269,10 +270,10 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) ...@@ -269,10 +270,10 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
ath_beacon_setup(sc, avp, bf); ath_beacon_setup(sc, avp, bf);
/* NB: caller is known to have already stopped tx dma */ /* NB: caller is known to have already stopped tx dma */
ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr); ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
ath9k_hw_txstart(ah, sc->sc_bhalq); ath9k_hw_txstart(ah, sc->beacon.beaconq);
DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n", 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) int ath_beaconq_setup(struct ath_hal *ah)
...@@ -305,7 +306,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -305,7 +306,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
if (!avp->av_bcbuf) { if (!avp->av_bcbuf) {
/* Allocate beacon state for hostap/ibss. We know /* Allocate beacon state for hostap/ibss. We know
* a buffer is available. */ * 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); struct ath_buf, list);
list_del(&avp->av_bcbuf->list); list_del(&avp->av_bcbuf->list);
...@@ -318,13 +319,13 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -318,13 +319,13 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
*/ */
avp->av_bslot = 0; avp->av_bslot = 0;
for (slot = 0; slot < ATH_BCBUF; slot++) 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 * XXX hack, space out slots to better
* deal with misses * deal with misses
*/ */
if (slot+1 < ATH_BCBUF && if (slot+1 < ATH_BCBUF &&
sc->sc_bslot[slot+1] == sc->beacon.bslot[slot+1] ==
ATH_IF_ID_ANY) { ATH_IF_ID_ANY) {
avp->av_bslot = slot+1; avp->av_bslot = slot+1;
break; break;
...@@ -332,8 +333,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -332,8 +333,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
avp->av_bslot = slot; avp->av_bslot = slot;
/* NB: keep looking for a double slot */ /* NB: keep looking for a double slot */
} }
BUG_ON(sc->sc_bslot[avp->av_bslot] != ATH_IF_ID_ANY); BUG_ON(sc->beacon.bslot[avp->av_bslot] != ATH_IF_ID_ANY);
sc->sc_bslot[avp->av_bslot] = if_id; sc->beacon.bslot[avp->av_bslot] = if_id;
sc->sc_nbcnvaps++; sc->sc_nbcnvaps++;
} }
} }
...@@ -361,7 +362,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -361,7 +362,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
} }
tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; 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 * Calculate a TSF adjustment factor required for
...@@ -421,7 +422,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) ...@@ -421,7 +422,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
struct ath_buf *bf; struct ath_buf *bf;
if (avp->av_bslot != -1) { 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--; sc->sc_nbcnvaps--;
} }
...@@ -434,7 +435,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) ...@@ -434,7 +435,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL; bf->bf_mpdu = NULL;
} }
list_add_tail(&bf->list, &sc->sc_bbuf); list_add_tail(&bf->list, &sc->beacon.bbuf);
avp->av_bcbuf = NULL; avp->av_bcbuf = NULL;
} }
...@@ -468,18 +469,18 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -468,18 +469,18 @@ void ath9k_beacon_tasklet(unsigned long data)
* *
* FIXME: Clean up this mess !! * FIXME: Clean up this mess !!
*/ */
if (ath9k_hw_numtxpending(ah, sc->sc_bhalq) != 0) { if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
sc->sc_bmisscount++; sc->beacon.bmisscnt++;
/* XXX: doth needs the chanchange IE countdown decremented. /* XXX: doth needs the chanchange IE countdown decremented.
* We should consider adding a mac80211 call to indicate * We should consider adding a mac80211 call to indicate
* a beacon miss so appropriate action could be taken * a beacon miss so appropriate action could be taken
* (in that layer). * (in that layer).
*/ */
if (sc->sc_bmisscount < BSTUCK_THRESH) { if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
if (sc->sc_flags & SC_OP_NO_RESET) { if (sc->sc_flags & SC_OP_NO_RESET) {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"missed %u consecutive beacons\n", "missed %u consecutive beacons\n",
sc->sc_bmisscount); sc->beacon.bmisscnt);
if (show_cycles) { if (show_cycles) {
/* /*
* Display cycle counter stats from HW * Display cycle counter stats from HW
...@@ -498,11 +499,11 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -498,11 +499,11 @@ void ath9k_beacon_tasklet(unsigned long data)
} else { } else {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"missed %u consecutive beacons\n", "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_flags & SC_OP_NO_RESET) {
if (sc->sc_bmisscount == BSTUCK_THRESH) { if (sc->beacon.bmisscnt == BSTUCK_THRESH) {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"beacon is officially " "beacon is officially "
"stuck\n"); "stuck\n");
...@@ -516,17 +517,17 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -516,17 +517,17 @@ void ath9k_beacon_tasklet(unsigned long data)
return; return;
} }
if (sc->sc_bmisscount != 0) { if (sc->beacon.bmisscnt != 0) {
if (sc->sc_flags & SC_OP_NO_RESET) { if (sc->sc_flags & SC_OP_NO_RESET) {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"resume beacon xmit after %u misses\n", "resume beacon xmit after %u misses\n",
sc->sc_bmisscount); sc->beacon.bmisscnt);
} else { } else {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"resume beacon xmit after %u misses\n", "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) ...@@ -541,7 +542,7 @@ void ath9k_beacon_tasklet(unsigned long data)
tsf = ath9k_hw_gettsf64(ah); tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU(tsf>>32, tsf); tsftu = TSF_TO_TU(tsf>>32, tsf);
slot = ((tsftu % intval) * ATH_BCBUF) / intval; 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, DPRINTF(sc, ATH_DBG_BEACON,
"slot %d [tsf %llu tsftu %u intval %u] if_id %d\n", "slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
...@@ -573,12 +574,12 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -573,12 +574,12 @@ void ath9k_beacon_tasklet(unsigned long data)
* set to ATH_BCBUF so this check is a noop. * set to ATH_BCBUF so this check is a noop.
*/ */
/* XXX locking */ /* XXX locking */
if (sc->sc_updateslot == UPDATE) { if (sc->beacon.updateslot == UPDATE) {
sc->sc_updateslot = COMMIT; /* commit next beacon */ sc->beacon.updateslot = COMMIT; /* commit next beacon */
sc->sc_slotupdate = slot; sc->beacon.slotupdate = slot;
} else if (sc->sc_updateslot == COMMIT && sc->sc_slotupdate == slot) { } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
ath9k_hw_setslottime(sc->sc_ah, sc->sc_slottime); ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime);
sc->sc_updateslot = OK; sc->beacon.updateslot = OK;
} }
if (bfaddr != 0) { if (bfaddr != 0) {
/* /*
...@@ -586,17 +587,17 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -586,17 +587,17 @@ void ath9k_beacon_tasklet(unsigned long data)
* This should never fail since we check above that no frames * This should never fail since we check above that no frames
* are still pending on the queue. * 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, 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: the HAL still stops DMA, so proceed */
} }
/* NB: cabq traffic should already be queued and primed */ /* NB: cabq traffic should already be queued and primed */
ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bfaddr); ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
ath9k_hw_txstart(ah, sc->sc_bhalq); 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) ...@@ -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; conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
/* extract tstamp from last beacon and convert to TU */ /* 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? */ /* XXX conditionalize multi-bss support? */
if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
...@@ -830,7 +831,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -830,7 +831,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
ath_beaconq_config(sc); ath_beaconq_config(sc);
} }
ath9k_hw_beaconinit(ah, nexttbtt, intval); ath9k_hw_beaconinit(ah, nexttbtt, intval);
sc->sc_bmisscount = 0; sc->beacon.bmisscnt = 0;
ath9k_hw_set_interrupts(ah, sc->sc_imask); ath9k_hw_set_interrupts(ah, sc->sc_imask);
/* /*
* When using a self-linked beacon descriptor in * When using a self-linked beacon descriptor in
......
...@@ -818,6 +818,101 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan, ...@@ -818,6 +818,101 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
return true; 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, bool ath9k_hw_init_cal(struct ath_hal *ah,
struct ath9k_channel *chan) struct ath9k_channel *chan)
{ {
...@@ -835,6 +930,9 @@ bool ath9k_hw_init_cal(struct ath_hal *ah, ...@@ -835,6 +930,9 @@ bool ath9k_hw_init_cal(struct ath_hal *ah,
return false; 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_WRITE(ah, AR_PHY_AGC_CONTROL,
REG_READ(ah, AR_PHY_AGC_CONTROL) | REG_READ(ah, AR_PHY_AGC_CONTROL) |
AR_PHY_AGC_CONTROL_NF); AR_PHY_AGC_CONTROL_NF);
......
...@@ -61,7 +61,7 @@ struct ath_node; ...@@ -61,7 +61,7 @@ struct ath_node;
#define TSF_TO_TU(_h,_l) \ #define TSF_TO_TU(_h,_l) \
((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) ((((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}; static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
...@@ -88,16 +88,66 @@ enum ATH_DEBUG { ...@@ -88,16 +88,66 @@ enum ATH_DEBUG {
#ifdef CONFIG_ATH9K_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 { struct ath9k_debug {
int debug_mask; int debug_mask;
struct dentry *debugfs_root; struct dentry *debugfs_root;
struct dentry *debugfs_phy; struct dentry *debugfs_phy;
struct dentry *debugfs_dma; struct dentry *debugfs_dma;
struct dentry *debugfs_interrupt;
struct ath_stats stats;
}; };
void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...); void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
int ath9k_init_debug(struct ath_softc *sc); int ath9k_init_debug(struct ath_softc *sc);
void ath9k_exit_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 #else
...@@ -115,6 +165,11 @@ static inline void ath9k_exit_debug(struct ath_softc *sc) ...@@ -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 */ #endif /* CONFIG_ATH9K_DEBUG */
struct ath_config { struct ath_config {
...@@ -235,18 +290,9 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, ...@@ -235,18 +290,9 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
/* RX / TX */ /* RX / TX */
/***********/ /***********/
#define ATH_MAX_ANTENNA 3 #define ATH_MAX_ANTENNA 3
#define ATH_RXBUF 512 #define ATH_RXBUF 512
#define WME_NUM_TID 16 #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_TXBUF 512 #define ATH_TXBUF 512
#define ATH_TXMAXTRY 13 #define ATH_TXMAXTRY 13
#define ATH_11N_TXMAXTRY 10 #define ATH_11N_TXMAXTRY 10
...@@ -254,19 +300,61 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush); ...@@ -254,19 +300,61 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush);
#define WME_BA_BMP_SIZE 64 #define WME_BA_BMP_SIZE 64
#define WME_MAX_BA WME_BA_BMP_SIZE #define WME_MAX_BA WME_BA_BMP_SIZE
#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
#define TID_TO_WME_AC(_tid) \ #define TID_TO_WME_AC(_tid) \
((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
(((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \ (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
(((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
WME_AC_VO) WME_AC_VO)
#define WME_AC_BE 0 #define WME_AC_BE 0
#define WME_AC_BK 1 #define WME_AC_BK 1
#define WME_AC_VI 2 #define WME_AC_VI 2
#define WME_AC_VO 3 #define WME_AC_VO 3
#define WME_NUM_AC 4 #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 { struct ath_txq {
u32 axq_qnum; /* hardware q number */ u32 axq_qnum; /* hardware q number */
u32 *axq_link; /* link ptr in last TX desc */ u32 *axq_link; /* link ptr in last TX desc */
...@@ -276,7 +364,6 @@ struct ath_txq { ...@@ -276,7 +364,6 @@ struct ath_txq {
u32 axq_depth; /* queue depth */ u32 axq_depth; /* queue depth */
u8 axq_aggr_depth; /* aggregates queued */ u8 axq_aggr_depth; /* aggregates queued */
u32 axq_totalqueued; /* total ever queued */ u32 axq_totalqueued; /* total ever queued */
bool stopped; /* Is mac80211 queue stopped ? */ bool stopped; /* Is mac80211 queue stopped ? */
struct ath_buf *axq_linkbuf; /* virtual addr of last buffer*/ struct ath_buf *axq_linkbuf; /* virtual addr of last buffer*/
...@@ -322,12 +409,6 @@ struct ath_atx_ac { ...@@ -322,12 +409,6 @@ struct ath_atx_ac {
struct list_head tid_q; /* queue of TIDs with buffers */ 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 */ /* per-frame tx control block */
struct ath_tx_control { struct ath_tx_control {
struct ath_txq *txq; struct ath_txq *txq;
...@@ -353,13 +434,54 @@ struct ath_tx_stat { ...@@ -353,13 +434,54 @@ struct ath_tx_stat {
int rateKbps; int rateKbps;
int ratecode; int ratecode;
int flags; 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 */ 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); 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); void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
int ath_tx_setup(struct ath_softc *sc, int haltype); int ath_tx_setup(struct ath_softc *sc, int haltype);
...@@ -382,73 +504,6 @@ void ath_tx_tasklet(struct ath_softc *sc); ...@@ -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_depth(struct ath_softc *sc, int qnum);
u32 ath_txq_aggr_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); 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); 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); 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); void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tidno);
...@@ -489,7 +544,7 @@ struct ath_vap { ...@@ -489,7 +544,7 @@ struct ath_vap {
* number of beacon intervals, the game's up. * number of beacon intervals, the game's up.
*/ */
#define BSTUCK_THRESH (9 * ATH_BCBUF) #define BSTUCK_THRESH (9 * ATH_BCBUF)
#define ATH_BCBUF 4 #define ATH_BCBUF 1
#define ATH_DEFAULT_BINTVAL 100 /* TU */ #define ATH_DEFAULT_BINTVAL 100 /* TU */
#define ATH_DEFAULT_BMISS_LIMIT 10 #define ATH_DEFAULT_BMISS_LIMIT 10
#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
...@@ -507,6 +562,26 @@ struct ath_beacon_config { ...@@ -507,6 +562,26 @@ struct ath_beacon_config {
} u; /* last received beacon/probe response timestamp of this BSS. */ } 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 ath9k_beacon_tasklet(unsigned long data);
void ath_beacon_config(struct ath_softc *sc, int if_id); void ath_beacon_config(struct ath_softc *sc, int if_id);
int ath_beaconq_setup(struct ath_hal *ah); int ath_beaconq_setup(struct ath_hal *ah);
...@@ -577,7 +652,7 @@ struct ath_rfkill { ...@@ -577,7 +652,7 @@ struct ath_rfkill {
#define DEFAULT_CACHELINE 32 #define DEFAULT_CACHELINE 32
#define ATH_DEFAULT_NOISE_FLOOR -95 #define ATH_DEFAULT_NOISE_FLOOR -95
#define ATH_REGCLASSIDS_MAX 10 #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_MAX_SW_RETRIES 10
#define ATH_CHAN_MAX 255 #define ATH_CHAN_MAX 255
#define IEEE80211_WEP_NKID 4 /* number of key ids */ #define IEEE80211_WEP_NKID 4 /* number of key ids */
...@@ -590,7 +665,7 @@ struct ath_rfkill { ...@@ -590,7 +665,7 @@ struct ath_rfkill {
* Different parts have different size key caches. We handle * Different parts have different size key caches. We handle
* up to ATH_KEYMAX entries (could dynamically allocate state). * 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_IF_ID_ANY 0xff
#define ATH_TXPOWER_MAX 100 /* .5 dBm units */ #define ATH_TXPOWER_MAX 100 /* .5 dBm units */
...@@ -623,108 +698,51 @@ struct ath_softc { ...@@ -623,108 +698,51 @@ struct ath_softc {
struct pci_dev *pdev; struct pci_dev *pdev;
struct tasklet_struct intr_tq; struct tasklet_struct intr_tq;
struct tasklet_struct bcon_tasklet; struct tasklet_struct bcon_tasklet;
struct ath_config sc_config;
struct ath_hal *sc_ah; struct ath_hal *sc_ah;
void __iomem *mem; void __iomem *mem;
spinlock_t sc_resetlock;
u8 sc_curbssid[ETH_ALEN]; u8 sc_curbssid[ETH_ALEN];
u8 sc_myaddr[ETH_ALEN]; u8 sc_myaddr[ETH_ALEN];
u8 sc_bssidmask[ETH_ALEN]; u8 sc_bssidmask[ETH_ALEN];
#ifdef CONFIG_ATH9K_DEBUG
struct ath9k_debug sc_debug;
#endif
u32 sc_intrstatus; u32 sc_intrstatus;
u32 sc_flags; /* SC_OP_* */ u32 sc_flags; /* SC_OP_* */
unsigned int rx_filter;
u16 sc_curtxpow; u16 sc_curtxpow;
u16 sc_curaid; u16 sc_curaid;
u16 sc_cachelsz; u16 sc_cachelsz;
int sc_slotupdate; /* slot to next advance fsm */ u8 sc_nbcnvaps;
int sc_slottime; u16 sc_nvaps;
int sc_bslot[ATH_BCBUF];
u8 sc_tx_chainmask; u8 sc_tx_chainmask;
u8 sc_rx_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 ath9k_int sc_imask;
enum wireless_mode sc_curmode;
enum PROT_MODE sc_protmode; 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_extprotspacing sc_ht_extprotspacing;
enum ath9k_ht_macmode tx_chan_width; enum ath9k_ht_macmode tx_chan_width;
#ifdef CONFIG_SLOW_ANT_DIV struct ath_config sc_config;
struct ath_antdiv sc_antdiv; struct ath_rx rx;
#endif struct ath_tx tx;
enum { struct ath_beacon beacon;
OK, /* no change needed */ struct ieee80211_vif *sc_vaps[ATH_BCBUF];
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 ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX]; struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
u8 sc_protrix; struct ath_rate_table *cur_rate_table;
/* Channel, Band */
struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX]; struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX];
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; 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 radio_led;
struct ath_led assoc_led; struct ath_led assoc_led;
struct ath_led tx_led; struct ath_led tx_led;
struct ath_led rx_led; struct ath_led rx_led;
/* Rfkill */
struct ath_rfkill rf_kill; struct ath_rfkill rf_kill;
/* ANI */
struct ath_ani sc_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); int ath_reset(struct ath_softc *sc, bool retry_tx);
......
...@@ -128,6 +128,100 @@ static const struct file_operations fops_dma = { ...@@ -128,6 +128,100 @@ static const struct file_operations fops_dma = {
.owner = THIS_MODULE .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) int ath9k_init_debug(struct ath_softc *sc)
{ {
sc->sc_debug.debug_mask = ath9k_debug; sc->sc_debug.debug_mask = ath9k_debug;
...@@ -146,6 +240,13 @@ int ath9k_init_debug(struct ath_softc *sc) ...@@ -146,6 +240,13 @@ int ath9k_init_debug(struct ath_softc *sc)
if (!sc->sc_debug.debugfs_dma) if (!sc->sc_debug.debugfs_dma)
goto err; 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; return 0;
err: err:
ath9k_exit_debug(sc); ath9k_exit_debug(sc);
...@@ -154,6 +255,7 @@ int ath9k_init_debug(struct ath_softc *sc) ...@@ -154,6 +255,7 @@ int ath9k_init_debug(struct ath_softc *sc)
void ath9k_exit_debug(struct ath_softc *sc) 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_dma);
debugfs_remove(sc->sc_debug.debugfs_phy); debugfs_remove(sc->sc_debug.debugfs_phy);
debugfs_remove(sc->sc_debug.debugfs_root); debugfs_remove(sc->sc_debug.debugfs_root);
......
此差异已折叠。
...@@ -37,7 +37,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type); ...@@ -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, static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode); enum ath9k_ht_macmode macmode);
static u32 ath9k_hw_ini_fixup(struct ath_hal *ah, static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
struct ar5416_eeprom *pEepData, struct ar5416_eeprom_def *pEepData,
u32 reg, u32 value); u32 reg, u32 value);
static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan); 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); 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) ...@@ -392,6 +392,8 @@ static const char *ath9k_hw_devname(u16 devid)
case AR9280_DEVID_PCI: case AR9280_DEVID_PCI:
case AR9280_DEVID_PCIE: case AR9280_DEVID_PCIE:
return "Atheros 9280"; return "Atheros 9280";
case AR9285_DEVID_PCIE:
return "Atheros 9285";
} }
return NULL; return NULL;
...@@ -640,10 +642,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, ...@@ -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_5416 *ahp;
struct ath_hal *ah; struct ath_hal *ah;
int ecode; int ecode;
#ifndef CONFIG_SLOW_ANT_DIV u32 i, j;
u32 i;
u32 j;
#endif
ahp = ath9k_hw_newstate(devid, sc, mem, status); ahp = ath9k_hw_newstate(devid, sc, mem, status);
if (ahp == NULL) if (ahp == NULL)
...@@ -685,7 +684,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, ...@@ -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) && if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
(ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) && (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
(ah->ah_macVersion != AR_SREV_VERSION_9160) && (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, DPRINTF(ah->ah_sc, ATH_DBG_RESET,
"Mac Chip Rev 0x%02x.%x is not supported by " "Mac Chip Rev 0x%02x.%x is not supported by "
"this driver\n", ah->ah_macVersion, ah->ah_macRev); "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, ...@@ -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", "This Mac Chip Rev 0x%02x.%x is \n",
ah->ah_macVersion, ah->ah_macRev); 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, INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
ARRAY_SIZE(ar9280Modes_9280_2), 6); ARRAY_SIZE(ar9280Modes_9280_2), 6);
INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2, 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, ...@@ -846,14 +876,13 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
goto bad; goto bad;
/* rxgain table */ /* rxgain table */
if (AR_SREV_9280_20_OR_LATER(ah)) if (AR_SREV_9280_20(ah))
ath9k_hw_init_rxgain_ini(ah); ath9k_hw_init_rxgain_ini(ah);
/* txgain table */ /* txgain table */
if (AR_SREV_9280_20_OR_LATER(ah)) if (AR_SREV_9280_20(ah))
ath9k_hw_init_txgain_ini(ah); ath9k_hw_init_txgain_ini(ah);
#ifndef CONFIG_SLOW_ANT_DIV
if (ah->ah_devid == AR9280_DEVID_PCI) { if (ah->ah_devid == AR9280_DEVID_PCI) {
for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) { for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
u32 reg = INI_RA(&ahp->ah_iniModes, i, 0); 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, ...@@ -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); u32 val = INI_RA(&ahp->ah_iniModes, i, j);
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); reg, val);
} }
} }
} }
#endif
if (!ath9k_hw_fill_cap_info(ah)) { if (!ath9k_hw_fill_cap_info(ah)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET, DPRINTF(ah->ah_sc, ATH_DBG_RESET,
"failed ath9k_hw_fill_cap_info\n"); "failed ath9k_hw_fill_cap_info\n");
...@@ -1020,8 +1050,6 @@ static void ath9k_hw_init_chain_masks(struct ath_hal *ah) ...@@ -1020,8 +1050,6 @@ static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
} }
case 0x1: case 0x1:
case 0x2: case 0x2:
if (!AR_SREV_9280(ah))
break;
case 0x7: case 0x7:
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
REG_WRITE(ah, AR_PHY_CAL_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, ...@@ -1166,12 +1194,10 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
case AR9160_DEVID_PCI: case AR9160_DEVID_PCI:
case AR9280_DEVID_PCI: case AR9280_DEVID_PCI:
case AR9280_DEVID_PCIE: case AR9280_DEVID_PCIE:
case AR9285_DEVID_PCIE:
ah = ath9k_hw_do_attach(devid, sc, mem, error); ah = ath9k_hw_do_attach(devid, sc, mem, error);
break; break;
default: default:
DPRINTF(ah->ah_sc, ATH_DBG_ANY,
"devid=0x%x not supported.\n", devid);
ah = NULL;
*error = -ENXIO; *error = -ENXIO;
break; break;
} }
...@@ -1186,6 +1212,14 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc, ...@@ -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, static void ath9k_hw_override_ini(struct ath_hal *ah,
struct ath9k_channel *chan) 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) || if (!AR_SREV_5416_V20_OR_LATER(ah) ||
AR_SREV_9280_10_OR_LATER(ah)) AR_SREV_9280_10_OR_LATER(ah))
return; return;
...@@ -1193,8 +1227,8 @@ static void ath9k_hw_override_ini(struct ath_hal *ah, ...@@ -1193,8 +1227,8 @@ static void ath9k_hw_override_ini(struct ath_hal *ah,
REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
} }
static u32 ath9k_hw_ini_fixup(struct ath_hal *ah, static u32 ath9k_hw_def_ini_fixup(struct ath_hal *ah,
struct ar5416_eeprom *pEepData, struct ar5416_eeprom_def *pEepData,
u32 reg, u32 value) u32 reg, u32 value)
{ {
struct base_eep_header *pBase = &(pEepData->baseEepHeader); struct base_eep_header *pBase = &(pEepData->baseEepHeader);
...@@ -1227,6 +1261,18 @@ static u32 ath9k_hw_ini_fixup(struct ath_hal *ah, ...@@ -1227,6 +1261,18 @@ static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
return value; 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, static int ath9k_hw_process_ini(struct ath_hal *ah,
struct ath9k_channel *chan, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode) enum ath9k_ht_macmode macmode)
...@@ -1294,11 +1340,6 @@ static int ath9k_hw_process_ini(struct ath_hal *ah, ...@@ -1294,11 +1340,6 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
u32 reg = INI_RA(&ahp->ah_iniModes, i, 0); u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex); 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); REG_WRITE(ah, reg, val);
if (reg >= 0x7800 && reg < 0x78a0 if (reg >= 0x7800 && reg < 0x78a0
...@@ -1309,10 +1350,10 @@ static int ath9k_hw_process_ini(struct ath_hal *ah, ...@@ -1309,10 +1350,10 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
DO_DELAY(regWrites); DO_DELAY(regWrites);
} }
if (AR_SREV_9280_20_OR_LATER(ah)) if (AR_SREV_9280(ah))
REG_WRITE_ARRAY(&ahp->ah_iniModesRxGain, modesIndex, regWrites); 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); REG_WRITE_ARRAY(&ahp->ah_iniModesTxGain, modesIndex, regWrites);
for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) { 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, ...@@ -1585,10 +1626,15 @@ static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode) enum ath9k_ht_macmode macmode)
{ {
u32 phymode; u32 phymode;
u32 enableDacFifo = 0;
struct ath_hal_5416 *ahp = AH5416(ah); 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 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)) { if (IS_CHAN_HT40(chan)) {
phymode |= AR_PHY_FC_DYN2040_EN; phymode |= AR_PHY_FC_DYN2040_EN;
...@@ -2771,11 +2817,14 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore) ...@@ -2771,11 +2817,14 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
if (ah->ah_config.pcie_waen) { if (ah->ah_config.pcie_waen) {
REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen); REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
} else { } else {
if (AR_SREV_9280(ah)) if (AR_SREV_9285(ah))
REG_WRITE(ah, AR_WA, 0x0040073f); REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
else if (AR_SREV_9280(ah))
REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT);
else 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) ...@@ -3326,7 +3375,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
else else
pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP; 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; pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
else else
pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
...@@ -3346,9 +3395,9 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah) ...@@ -3346,9 +3395,9 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND; pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
pCap->num_antcfg_5ghz = 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 = 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; return true;
} }
......
...@@ -448,6 +448,17 @@ struct ar5416Stats { ...@@ -448,6 +448,17 @@ struct ar5416Stats {
#define AR5416_EEP_TXGAIN_ORIGINAL 0 #define AR5416_EEP_TXGAIN_ORIGINAL 0
#define AR5416_EEP_TXGAIN_HIGH_POWER 1 #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 { enum eeprom_param {
EEP_NFTHRESH_5, EEP_NFTHRESH_5,
...@@ -484,6 +495,11 @@ enum ar5416_rates { ...@@ -484,6 +495,11 @@ enum ar5416_rates {
Ar5416RateSize Ar5416RateSize
}; };
enum ath9k_hal_freq_band {
ATH9K_HAL_FREQ_BAND_5GHZ = 0,
ATH9K_HAL_FREQ_BAND_2GHZ = 1
};
struct base_eep_header { struct base_eep_header {
u16 length; u16 length;
u16 checksum; u16 checksum;
...@@ -507,6 +523,25 @@ struct base_eep_header { ...@@ -507,6 +523,25 @@ struct base_eep_header {
u8 futureBase_3[25]; u8 futureBase_3[25];
} __packed; } __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 { struct spur_chan {
u16 spurChan; u16 spurChan;
u8 spurRangeLow; u8 spurRangeLow;
...@@ -559,11 +594,58 @@ struct modal_eep_header { ...@@ -559,11 +594,58 @@ struct modal_eep_header {
struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
} __packed; } __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 { struct cal_data_per_freq {
u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
} __packed; } __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 { struct cal_target_power_leg {
u8 bChannel; u8 bChannel;
u8 tPow2x[4]; u8 tPow2x[4];
...@@ -574,6 +656,7 @@ struct cal_target_power_ht { ...@@ -574,6 +656,7 @@ struct cal_target_power_ht {
u8 tPow2x[8]; u8 tPow2x[8];
} __packed; } __packed;
#ifdef __BIG_ENDIAN_BITFIELD #ifdef __BIG_ENDIAN_BITFIELD
struct cal_ctl_edges { struct cal_ctl_edges {
u8 bChannel; u8 bChannel;
...@@ -588,10 +671,15 @@ struct cal_ctl_edges { ...@@ -588,10 +671,15 @@ struct cal_ctl_edges {
struct cal_ctl_data { struct cal_ctl_data {
struct cal_ctl_edges 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; } __packed;
struct ar5416_eeprom { struct ar5416_eeprom_def {
struct base_eep_header baseEepHeader; struct base_eep_header baseEepHeader;
u8 custData[64]; u8 custData[64];
struct modal_eep_header modalHeader[2]; struct modal_eep_header modalHeader[2];
...@@ -620,6 +708,26 @@ struct ar5416_eeprom { ...@@ -620,6 +708,26 @@ struct ar5416_eeprom {
u8 padding; u8 padding;
} __packed; } __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 { struct ar5416IniArray {
u32 *ia_array; u32 *ia_array;
u32 ia_rows; u32 ia_rows;
...@@ -687,9 +795,22 @@ struct hal_cal_list { ...@@ -687,9 +795,22 @@ struct hal_cal_list {
struct hal_cal_list *calNext; 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_5416 {
struct ath_hal ah; 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 ar5416Stats ah_stats;
struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES]; struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES];
void __iomem *ah_cal_mem; void __iomem *ah_cal_mem;
...@@ -813,6 +934,8 @@ struct ath_hal_5416 { ...@@ -813,6 +934,8 @@ struct ath_hal_5416 {
struct ar5416IniArray ah_iniModesAdditional; struct ar5416IniArray ah_iniModesAdditional;
struct ar5416IniArray ah_iniModesRxGain; struct ar5416IniArray ah_iniModesRxGain;
struct ar5416IniArray ah_iniModesTxGain; struct ar5416IniArray ah_iniModesTxGain;
/* To indicate EEPROM mapping used */
enum hal_eep_map ah_eep_map;
}; };
#define AH5416(_ah) ((struct ath_hal_5416 *)(_ah)) #define AH5416(_ah) ((struct ath_hal_5416 *)(_ah))
...@@ -854,13 +977,20 @@ struct ath_hal_5416 { ...@@ -854,13 +977,20 @@ struct ath_hal_5416 {
(AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200 (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
#define AR5416_EEPROM_MAX 0xae0 #define AR5416_EEPROM_MAX 0xae0
#define ar5416_get_eep_ver(_ahp) \ #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) \ #define ar5416_get_eep_rev(_ahp) \
(((_ahp)->ah_eeprom.baseEepHeader.version) & 0xFFF) (((_ahp)->ah_eeprom.def.baseEepHeader.version) & 0xFFF)
#define ar5416_get_ntxchains(_txchainmask) \ #define ar5416_get_ntxchains(_txchainmask) \
(((_txchainmask >> 2) & 1) + \ (((_txchainmask >> 2) & 1) + \
((_txchainmask >> 1) & 1) + (_txchainmask & 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 #ifdef __BIG_ENDIAN
#define AR5416_EEPROM_MAGIC 0x5aa5 #define AR5416_EEPROM_MAGIC 0x5aa5
#else #else
......
...@@ -916,12 +916,11 @@ void ath9k_hw_rxena(struct ath_hal *ah) ...@@ -916,12 +916,11 @@ void ath9k_hw_rxena(struct ath_hal *ah)
void ath9k_hw_startpcureceive(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_enable_mib_counters(ah);
ath9k_ani_reset(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) void ath9k_hw_stoppcurecv(struct ath_hal *ah)
......
...@@ -34,6 +34,7 @@ static struct pci_device_id ath_pci_id_table[] __devinitdata = { ...@@ -34,6 +34,7 @@ static struct pci_device_id ath_pci_id_table[] __devinitdata = {
{ PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */ { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */
{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
{ PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
{ 0 } { 0 }
}; };
...@@ -60,7 +61,8 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz) ...@@ -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) 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 * All protection frames are transmited at 2Mb/s for
* 11g, otherwise at 1Mb/s. * 11g, otherwise at 1Mb/s.
...@@ -346,7 +348,7 @@ static void ath_ani_calibrate(unsigned long data) ...@@ -346,7 +348,7 @@ static void ath_ani_calibrate(unsigned long data)
* don't calibrate when we're scanning. * don't calibrate when we're scanning.
* we are most likely not on our home channel. * 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; return;
/* Long calibration runs independently of short calibration. */ /* Long calibration runs independently of short calibration. */
...@@ -485,9 +487,9 @@ static void ath9k_tasklet(unsigned long data) ...@@ -485,9 +487,9 @@ static void ath9k_tasklet(unsigned long data)
if (status & if (status &
(ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) { (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); ath_rx_tasklet(sc, 0);
spin_unlock_bh(&sc->sc_rxflushlock); spin_unlock_bh(&sc->rx.rxflushlock);
} }
/* XXX: optimize this */ /* XXX: optimize this */
if (status & ATH9K_INT_TX) if (status & ATH9K_INT_TX)
...@@ -597,6 +599,8 @@ static irqreturn_t ath_isr(int irq, void *dev) ...@@ -597,6 +599,8 @@ static irqreturn_t ath_isr(int irq, void *dev)
} }
} while (0); } while (0);
ath_debug_stat_interrupt(sc, status);
if (sched) { if (sched) {
/* turn off every interrupt except SWBA */ /* turn off every interrupt except SWBA */
ath9k_hw_set_interrupts(ah, (sc->sc_imask & ATH9K_INT_SWBA)); ath9k_hw_set_interrupts(ah, (sc->sc_imask & ATH9K_INT_SWBA));
...@@ -1302,7 +1306,7 @@ static void ath_detach(struct ath_softc *sc) ...@@ -1302,7 +1306,7 @@ static void ath_detach(struct ath_softc *sc)
/* cleanup tx queues */ /* cleanup tx queues */
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
if (ATH_TXQ_SETUP(sc, 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_hw_detach(sc->sc_ah);
ath9k_exit_debug(sc); ath9k_exit_debug(sc);
...@@ -1393,15 +1397,15 @@ static int ath_init(u16 devid, struct ath_softc *sc) ...@@ -1393,15 +1397,15 @@ static int ath_init(u16 devid, struct ath_softc *sc)
* priority. Note that the hal handles reseting * priority. Note that the hal handles reseting
* these queues at the needed time. * these queues at the needed time.
*/ */
sc->sc_bhalq = ath_beaconq_setup(ah); sc->beacon.beaconq = ath_beaconq_setup(ah);
if (sc->sc_bhalq == -1) { if (sc->beacon.beaconq == -1) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"Unable to setup a beacon xmit queue\n"); "Unable to setup a beacon xmit queue\n");
error = -EIO; error = -EIO;
goto bad2; goto bad2;
} }
sc->sc_cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
if (sc->sc_cabq == NULL) { if (sc->beacon.cabq == NULL) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"Unable to setup CAB xmit queue\n"); "Unable to setup CAB xmit queue\n");
error = -EIO; error = -EIO;
...@@ -1411,8 +1415,8 @@ static int ath_init(u16 devid, struct ath_softc *sc) ...@@ -1411,8 +1415,8 @@ static int ath_init(u16 devid, struct ath_softc *sc)
sc->sc_config.cabqReadytime = ATH_CABQ_READY_TIME; sc->sc_config.cabqReadytime = ATH_CABQ_READY_TIME;
ath_cabq_update(sc); ath_cabq_update(sc);
for (i = 0; i < ARRAY_SIZE(sc->sc_haltype2q); i++) for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
sc->sc_haltype2q[i] = -1; sc->tx.hwq_map[i] = -1;
/* Setup data queues */ /* Setup data queues */
/* NB: ensure BK queue is the lowest priority h/w queue */ /* 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) ...@@ -1492,7 +1496,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask; sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask;
ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); 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); ath9k_hw_getmac(ah, sc->sc_myaddr);
if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) { if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) {
...@@ -1501,20 +1505,15 @@ static int ath_init(u16 devid, struct ath_softc *sc) ...@@ -1501,20 +1505,15 @@ static int ath_init(u16 devid, struct ath_softc *sc)
ath9k_hw_setbssidmask(ah, sc->sc_bssidmask); 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 */ /* initialize beacon slots */
for (i = 0; i < ARRAY_SIZE(sc->sc_bslot); i++) for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
sc->sc_bslot[i] = ATH_IF_ID_ANY; sc->beacon.bslot[i] = ATH_IF_ID_ANY;
/* save MISC configurations */ /* save MISC configurations */
sc->sc_config.swBeaconProcess = 1; 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 */ /* setup channels and rates */
sc->sbands[IEEE80211_BAND_2GHZ].channels = sc->sbands[IEEE80211_BAND_2GHZ].channels =
...@@ -1536,7 +1535,7 @@ static int ath_init(u16 devid, struct ath_softc *sc) ...@@ -1536,7 +1535,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
/* cleanup tx queues */ /* cleanup tx queues */
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
if (ATH_TXQ_SETUP(sc, i)) if (ATH_TXQ_SETUP(sc, i))
ath_tx_cleanupq(sc, &sc->sc_txq[i]); ath_tx_cleanupq(sc, &sc->tx.txq[i]);
bad: bad:
if (ah) if (ah)
ath9k_hw_detach(ah); ath9k_hw_detach(ah);
...@@ -1674,9 +1673,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) ...@@ -1674,9 +1673,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
int i; int i;
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i)) { if (ATH_TXQ_SETUP(sc, i)) {
spin_lock_bh(&sc->sc_txq[i].axq_lock); spin_lock_bh(&sc->tx.txq[i].axq_lock);
ath_txq_schedule(sc, &sc->sc_txq[i]); ath_txq_schedule(sc, &sc->tx.txq[i]);
spin_unlock_bh(&sc->sc_txq[i].axq_lock); spin_unlock_bh(&sc->tx.txq[i].axq_lock);
} }
} }
} }
...@@ -1811,19 +1810,19 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) ...@@ -1811,19 +1810,19 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
switch (queue) { switch (queue) {
case 0: case 0:
qnum = sc->sc_haltype2q[ATH9K_WME_AC_VO]; qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO];
break; break;
case 1: case 1:
qnum = sc->sc_haltype2q[ATH9K_WME_AC_VI]; qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI];
break; break;
case 2: case 2:
qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE]; qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
break; break;
case 3: case 3:
qnum = sc->sc_haltype2q[ATH9K_WME_AC_BK]; qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK];
break; break;
default: default:
qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE]; qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
break; break;
} }
...@@ -1994,9 +1993,9 @@ static int ath9k_tx(struct ieee80211_hw *hw, ...@@ -1994,9 +1993,9 @@ static int ath9k_tx(struct ieee80211_hw *hw,
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) 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(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 */ /* Add the padding after the header if this is not already done */
...@@ -2050,7 +2049,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) ...@@ -2050,7 +2049,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
ath_stoprecv(sc); ath_stoprecv(sc);
ath9k_hw_phy_disable(sc->sc_ah); ath9k_hw_phy_disable(sc->sc_ah);
} else } else
sc->sc_rxlink = NULL; sc->rx.rxlink = NULL;
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 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, ...@@ -2126,16 +2125,13 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n"); DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n");
#ifdef CONFIG_SLOW_ANT_DIV
ath_slow_ant_div_stop(&sc->sc_antdiv);
#endif
/* Stop ANI */ /* Stop ANI */
del_timer_sync(&sc->sc_ani.timer); del_timer_sync(&sc->sc_ani.timer);
/* Reclaim beacon resources */ /* Reclaim beacon resources */
if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP || if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP ||
sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) { 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); ath_beacon_return(sc, avp);
} }
...@@ -2254,7 +2250,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, ...@@ -2254,7 +2250,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
* causes reconfiguration; we may be called * causes reconfiguration; we may be called
* with beacon transmission active. * 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); error = ath_beacon_alloc(sc, 0);
if (error != 0) if (error != 0)
...@@ -2300,7 +2296,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, ...@@ -2300,7 +2296,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
changed_flags &= SUPPORTED_FILTERS; changed_flags &= SUPPORTED_FILTERS;
*total_flags &= SUPPORTED_FILTERS; *total_flags &= SUPPORTED_FILTERS;
sc->rx_filter = *total_flags; sc->rx.rxfilter = *total_flags;
rfilt = ath_calcrxfilter(sc); rfilt = ath_calcrxfilter(sc);
ath9k_hw_setrxfilter(sc->sc_ah, rfilt); ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
...@@ -2309,7 +2305,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, ...@@ -2309,7 +2305,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0); 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, static void ath9k_sta_notify(struct ieee80211_hw *hw,
...@@ -2491,11 +2487,6 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, ...@@ -2491,11 +2487,6 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
return ret; return ret;
} }
static int ath9k_no_fragmentation(struct ieee80211_hw *hw, u32 value)
{
return -EOPNOTSUPP;
}
static struct ieee80211_ops ath9k_ops = { static struct ieee80211_ops ath9k_ops = {
.tx = ath9k_tx, .tx = ath9k_tx,
.start = ath9k_start, .start = ath9k_start,
...@@ -2512,7 +2503,6 @@ static struct ieee80211_ops ath9k_ops = { ...@@ -2512,7 +2503,6 @@ static struct ieee80211_ops ath9k_ops = {
.get_tsf = ath9k_get_tsf, .get_tsf = ath9k_get_tsf,
.reset_tsf = ath9k_reset_tsf, .reset_tsf = ath9k_reset_tsf,
.ampdu_action = ath9k_ampdu_action, .ampdu_action = ath9k_ampdu_action,
.set_frag_threshold = ath9k_no_fragmentation,
}; };
static struct { static struct {
......
...@@ -50,6 +50,9 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, ...@@ -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_SHORT_GI_40 0x00000080
#define AR_PHY_FC_WALSH 0x00000100 #define AR_PHY_FC_WALSH 0x00000100
#define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200 #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_TIMING2 0x9810
#define AR_PHY_TIMING3 0x9814 #define AR_PHY_TIMING3 0x9814
...@@ -100,6 +103,8 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, ...@@ -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 0x000000FF
#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0 #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 0x9844
#define AR_PHY_SETTLING_SWITCH 0x00003F80 #define AR_PHY_SETTLING_SWITCH 0x00003F80
#define AR_PHY_SETTLING_SWITCH_S 7 #define AR_PHY_SETTLING_SWITCH_S 7
......
...@@ -817,7 +817,7 @@ static void ath_rc_ratefind(struct ath_softc *sc, ...@@ -817,7 +817,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
struct ath_rate_table *rate_table; struct ath_rate_table *rate_table;
struct ieee80211_tx_rate *rates = tx_info->control.rates; 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, rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, 1,
is_probe, is_retry); is_probe, is_retry);
nrix = rix; nrix = rix;
...@@ -874,10 +874,9 @@ static void ath_rc_ratefind(struct ath_softc *sc, ...@@ -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 * So, set fourth rate in series to be same as third one for
* above conditions. * above conditions.
*/ */
if ((sc->sc_curmode == ATH9K_MODE_11NG_HT20) || if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
(sc->sc_curmode == ATH9K_MODE_11NG_HT40PLUS) || (sc->hw->conf.ht.enabled)) {
(sc->sc_curmode == ATH9K_MODE_11NG_HT40MINUS)) { u8 dot11rate = rate_table->info[rix].dot11rate;
u8 dot11rate = rate_table->info[rix].dot11rate;
u8 phy = rate_table->info[rix].phy; u8 phy = rate_table->info[rix].phy;
if (i == 4 && if (i == 4 &&
((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) || ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
...@@ -1094,7 +1093,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1094,7 +1093,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
int rate; int rate;
u8 last_per; u8 last_per;
bool state_change = false; 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; int size = ath_rc_priv->rate_table_size;
if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt)) if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
...@@ -1254,7 +1253,7 @@ static void ath_rc_tx_status(struct ath_softc *sc, ...@@ -1254,7 +1253,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
u8 flags; u8 flags;
u32 i = 0, rix; 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 * If the first rate is not the final index, there
...@@ -1354,8 +1353,8 @@ static void ath_rc_init(struct ath_softc *sc, ...@@ -1354,8 +1353,8 @@ static void ath_rc_init(struct ath_softc *sc,
sta->ht_cap.ht_supported, sta->ht_cap.ht_supported,
is_cw_40); is_cw_40);
} else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { } else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
/* sc_curmode would be set on init through config() */ /* cur_rate_table would be set on init through config() */
rate_table = sc->hw_rate_table[sc->sc_curmode]; rate_table = sc->cur_rate_table;
} }
if (!rate_table) { if (!rate_table) {
...@@ -1432,6 +1431,7 @@ static void ath_rc_init(struct ath_softc *sc, ...@@ -1432,6 +1431,7 @@ static void ath_rc_init(struct ath_softc *sc,
ath_rc_priv->max_valid_rate = k; ath_rc_priv->max_valid_rate = k;
ath_rc_sort_validrates(rate_table, ath_rc_priv); ath_rc_sort_validrates(rate_table, ath_rc_priv);
ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
sc->cur_rate_table = rate_table;
} }
/* Rate Control callbacks */ /* Rate Control callbacks */
......
...@@ -41,20 +41,19 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) ...@@ -41,20 +41,19 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
ASSERT(skb != NULL); ASSERT(skb != NULL);
ds->ds_vdata = skb->data; 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 * how much data it can DMA to us and that we are prepared
* to process */ * to process */
ath9k_hw_setuprxdesc(ah, ath9k_hw_setuprxdesc(ah, ds,
ds, sc->rx.bufsize,
sc->sc_rxbufsize,
0); 0);
if (sc->sc_rxlink == NULL) if (sc->rx.rxlink == NULL)
ath9k_hw_putrxbuf(ah, bf->bf_daddr); ath9k_hw_putrxbuf(ah, bf->bf_daddr);
else 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); ath9k_hw_rxena(ah);
} }
...@@ -62,8 +61,8 @@ static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) ...@@ -62,8 +61,8 @@ static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
{ {
/* XXX block beacon interrupts */ /* XXX block beacon interrupts */
ath9k_hw_setantenna(sc->sc_ah, antenna); ath9k_hw_setantenna(sc->sc_ah, antenna);
sc->sc_defant = antenna; sc->rx.defant = antenna;
sc->sc_rxotherant = 0; sc->rx.rxotherant = 0;
} }
/* /*
...@@ -148,7 +147,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, ...@@ -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 ieee80211_rx_status *rx_status, bool *decrypt_error,
struct ath_softc *sc) 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; struct ieee80211_hdr *hdr;
int ratekbps, rix; int ratekbps, rix;
u8 ratecode; u8 ratecode;
...@@ -272,20 +271,20 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) ...@@ -272,20 +271,20 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
int error = 0; int error = 0;
do { do {
spin_lock_init(&sc->sc_rxflushlock); spin_lock_init(&sc->rx.rxflushlock);
sc->sc_flags &= ~SC_OP_RXFLUSH; 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, min(sc->sc_cachelsz,
(u16)64)); (u16)64));
DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", 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 */ /* 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); "rx", nbufs, 1);
if (error != 0) { if (error != 0) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
...@@ -293,8 +292,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) ...@@ -293,8 +292,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
break; break;
} }
list_for_each_entry(bf, &sc->sc_rxbuf, list) { list_for_each_entry(bf, &sc->rx.rxbuf, list) {
skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize); skb = ath_rxbuf_alloc(sc, sc->rx.bufsize);
if (skb == NULL) { if (skb == NULL) {
error = -ENOMEM; error = -ENOMEM;
break; break;
...@@ -302,8 +301,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) ...@@ -302,8 +301,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
bf->bf_mpdu = skb; bf->bf_mpdu = skb;
bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data,
sc->sc_rxbufsize, sc->rx.bufsize,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
if (unlikely(pci_dma_mapping_error(sc->pdev, if (unlikely(pci_dma_mapping_error(sc->pdev,
bf->bf_buf_addr))) { bf->bf_buf_addr))) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
...@@ -315,7 +314,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) ...@@ -315,7 +314,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
} }
bf->bf_dmacontext = bf->bf_buf_addr; bf->bf_dmacontext = bf->bf_buf_addr;
} }
sc->sc_rxlink = NULL; sc->rx.rxlink = NULL;
} while (0); } while (0);
...@@ -330,14 +329,14 @@ void ath_rx_cleanup(struct ath_softc *sc) ...@@ -330,14 +329,14 @@ void ath_rx_cleanup(struct ath_softc *sc)
struct sk_buff *skb; struct sk_buff *skb;
struct ath_buf *bf; 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; skb = bf->bf_mpdu;
if (skb) if (skb)
dev_kfree_skb(skb); dev_kfree_skb(skb);
} }
if (sc->sc_rxdma.dd_desc_len != 0) if (sc->rx.rxdma.dd_desc_len != 0)
ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf); ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
} }
/* /*
...@@ -375,7 +374,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) ...@@ -375,7 +374,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
/* Can't set HOSTAP into promiscous mode */ /* Can't set HOSTAP into promiscous mode */
if (((sc->sc_ah->ah_opmode != NL80211_IFTYPE_AP) && 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)) { (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR)) {
rfilt |= ATH9K_RX_FILTER_PROM; rfilt |= ATH9K_RX_FILTER_PROM;
/* ??? To prevent from sending ACK */ /* ??? To prevent from sending ACK */
...@@ -401,25 +400,25 @@ int ath_startrecv(struct ath_softc *sc) ...@@ -401,25 +400,25 @@ int ath_startrecv(struct ath_softc *sc)
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
struct ath_buf *bf, *tbf; struct ath_buf *bf, *tbf;
spin_lock_bh(&sc->sc_rxbuflock); spin_lock_bh(&sc->rx.rxbuflock);
if (list_empty(&sc->sc_rxbuf)) if (list_empty(&sc->rx.rxbuf))
goto start_recv; goto start_recv;
sc->sc_rxlink = NULL; sc->rx.rxlink = NULL;
list_for_each_entry_safe(bf, tbf, &sc->sc_rxbuf, list) { list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
ath_rx_buf_link(sc, bf); ath_rx_buf_link(sc, bf);
} }
/* We could have deleted elements so the list may be empty now */ /* 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; 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_putrxbuf(ah, bf->bf_daddr);
ath9k_hw_rxena(ah); ath9k_hw_rxena(ah);
start_recv: start_recv:
spin_unlock_bh(&sc->sc_rxbuflock); spin_unlock_bh(&sc->rx.rxbuflock);
ath_opmode_init(sc); ath_opmode_init(sc);
ath9k_hw_startpcureceive(ah); ath9k_hw_startpcureceive(ah);
...@@ -435,25 +434,25 @@ bool ath_stoprecv(struct ath_softc *sc) ...@@ -435,25 +434,25 @@ bool ath_stoprecv(struct ath_softc *sc)
ath9k_hw_setrxfilter(ah, 0); ath9k_hw_setrxfilter(ah, 0);
stopped = ath9k_hw_stopdmarecv(ah); stopped = ath9k_hw_stopdmarecv(ah);
mdelay(3); /* 3ms is long enough for 1 frame */ mdelay(3); /* 3ms is long enough for 1 frame */
sc->sc_rxlink = NULL; sc->rx.rxlink = NULL;
return stopped; return stopped;
} }
void ath_flushrecv(struct ath_softc *sc) 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; sc->sc_flags |= SC_OP_RXFLUSH;
ath_rx_tasklet(sc, 1); ath_rx_tasklet(sc, 1);
sc->sc_flags &= ~SC_OP_RXFLUSH; 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) int ath_rx_tasklet(struct ath_softc *sc, int flush)
{ {
#define PA2DESC(_sc, _pa) \ #define PA2DESC(_sc, _pa) \
((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \ ((struct ath_desc *)((caddr_t)(_sc)->rx.rxdma.dd_desc + \
((_pa) - (_sc)->sc_rxdma.dd_desc_paddr))) ((_pa) - (_sc)->rx.rxdma.dd_desc_paddr)))
struct ath_buf *bf; struct ath_buf *bf;
struct ath_desc *ds; struct ath_desc *ds;
...@@ -465,19 +464,19 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) ...@@ -465,19 +464,19 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
bool decrypt_error = false; bool decrypt_error = false;
u8 keyix; u8 keyix;
spin_lock_bh(&sc->sc_rxbuflock); spin_lock_bh(&sc->rx.rxbuflock);
do { do {
/* If handling rx interrupt and flush is in progress => exit */ /* If handling rx interrupt and flush is in progress => exit */
if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0)) if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
break; break;
if (list_empty(&sc->sc_rxbuf)) { if (list_empty(&sc->rx.rxbuf)) {
sc->sc_rxlink = NULL; sc->rx.rxlink = NULL;
break; 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; ds = bf->bf_desc;
/* /*
...@@ -499,8 +498,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) ...@@ -499,8 +498,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
struct ath_buf *tbf; struct ath_buf *tbf;
struct ath_desc *tds; struct ath_desc *tds;
if (list_is_last(&bf->list, &sc->sc_rxbuf)) { if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
sc->sc_rxlink = NULL; sc->rx.rxlink = NULL;
break; break;
} }
...@@ -540,7 +539,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) ...@@ -540,7 +539,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
goto requeue; goto requeue;
/* The status portion of the descriptor could get corrupted. */ /* 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; goto requeue;
if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc)) 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) ...@@ -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 /* Ensure we always have an skb to requeue once we are done
* processing the current buffer's skb */ * 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, /* If there is no memory we ignore the current RX'd frame,
* tell hardware it can give us a new frame using the old * 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. */ * processing. */
if (!requeue_skb) if (!requeue_skb)
goto requeue; goto requeue;
pci_dma_sync_single_for_cpu(sc->pdev, /* Sync and unmap the frame */
bf->bf_buf_addr, pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr,
sc->sc_rxbufsize, sc->rx.bufsize,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
pci_unmap_single(sc->pdev, bf->bf_buf_addr, pci_unmap_single(sc->pdev, bf->bf_buf_addr,
sc->sc_rxbufsize, sc->rx.bufsize,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
skb_put(skb, ds->ds_rxstat.rs_datalen); skb_put(skb, ds->ds_rxstat.rs_datalen);
...@@ -572,8 +571,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) ...@@ -572,8 +571,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
hdr = (struct ieee80211_hdr *)skb->data; hdr = (struct ieee80211_hdr *)skb->data;
hdrlen = ieee80211_get_hdrlen_from_skb(skb); hdrlen = ieee80211_get_hdrlen_from_skb(skb);
if (hdrlen & 3) { /* The MAC header is padded to have 32-bit boundary if the
padsize = hdrlen % 4; * 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); memmove(skb->data + padsize, skb->data, hdrlen);
skb_pull(skb, padsize); skb_pull(skb, padsize);
} }
...@@ -596,7 +603,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) ...@@ -596,7 +603,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
/* We will now give hardware our shiny new allocated skb */ /* We will now give hardware our shiny new allocated skb */
bf->bf_mpdu = requeue_skb; bf->bf_mpdu = requeue_skb;
bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data, bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data,
sc->sc_rxbufsize, sc->rx.bufsize,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
if (unlikely(pci_dma_mapping_error(sc->pdev, if (unlikely(pci_dma_mapping_error(sc->pdev,
bf->bf_buf_addr))) { bf->bf_buf_addr))) {
...@@ -612,18 +619,18 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) ...@@ -612,18 +619,18 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
* change the default rx antenna if rx diversity chooses the * change the default rx antenna if rx diversity chooses the
* other antenna 3 times in a row. * other antenna 3 times in a row.
*/ */
if (sc->sc_defant != ds->ds_rxstat.rs_antenna) { if (sc->rx.defant != ds->ds_rxstat.rs_antenna) {
if (++sc->sc_rxotherant >= 3) if (++sc->rx.rxotherant >= 3)
ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna); ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna);
} else { } else {
sc->sc_rxotherant = 0; sc->rx.rxotherant = 0;
} }
requeue: requeue:
list_move_tail(&bf->list, &sc->sc_rxbuf); list_move_tail(&bf->list, &sc->rx.rxbuf);
ath_rx_buf_link(sc, bf); ath_rx_buf_link(sc, bf);
} while (1); } while (1);
spin_unlock_bh(&sc->sc_rxbuflock); spin_unlock_bh(&sc->rx.rxbuflock);
return 0; return 0;
#undef PA2DESC #undef PA2DESC
......
...@@ -671,7 +671,11 @@ ...@@ -671,7 +671,11 @@
#define AR_RC_APB 0x00000002 #define AR_RC_APB 0x00000002
#define AR_RC_HOSTIF 0x00000100 #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 0x4008
#define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000 #define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000
...@@ -738,6 +742,8 @@ ...@@ -738,6 +742,8 @@
#define AR_SREV_REVISION_9280_21 2 #define AR_SREV_REVISION_9280_21 2
#define AR_SREV_VERSION_9285 0xC0 #define AR_SREV_VERSION_9285 0xC0
#define AR_SREV_REVISION_9285_10 0 #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) \ #define AR_SREV_9100_OR_LATER(_ah) \
(((_ah)->ah_macVersion >= AR_SREV_VERSION_5416_PCIE)) (((_ah)->ah_macVersion >= AR_SREV_VERSION_5416_PCIE))
...@@ -768,6 +774,16 @@ ...@@ -768,6 +774,16 @@
#define AR_SREV_9285(_ah) (((_ah)->ah_macVersion == AR_SREV_VERSION_9285)) #define AR_SREV_9285(_ah) (((_ah)->ah_macVersion == AR_SREV_VERSION_9285))
#define AR_SREV_9285_10_OR_LATER(_ah) \ #define AR_SREV_9285_10_OR_LATER(_ah) \
(((_ah)->ah_macVersion >= AR_SREV_VERSION_9285)) (((_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_RADIO_SREV_MAJOR 0xf0
#define AR_RAD5133_SREV_MAJOR 0xc0 #define AR_RAD5133_SREV_MAJOR 0xc0
...@@ -1017,6 +1033,97 @@ enum { ...@@ -1017,6 +1033,97 @@ enum {
#define AR_AN_SYNTH9_REFDIVA 0xf8000000 #define AR_AN_SYNTH9_REFDIVA 0xf8000000
#define AR_AN_SYNTH9_REFDIVA_S 27 #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_ID0 0x8000
#define AR_STA_ID1 0x8004 #define AR_STA_ID1 0x8004
#define AR_STA_ID1_SADH_MASK 0x0000FFFF #define AR_STA_ID1_SADH_MASK 0x0000FFFF
......
...@@ -286,17 +286,17 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) ...@@ -286,17 +286,17 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
{ {
struct ath_buf *bf = NULL; struct ath_buf *bf = NULL;
spin_lock_bh(&sc->sc_txbuflock); spin_lock_bh(&sc->tx.txbuflock);
if (unlikely(list_empty(&sc->sc_txbuf))) { if (unlikely(list_empty(&sc->tx.txbuf))) {
spin_unlock_bh(&sc->sc_txbuflock); spin_unlock_bh(&sc->tx.txbuflock);
return NULL; 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); list_del(&bf->list);
spin_unlock_bh(&sc->sc_txbuflock); spin_unlock_bh(&sc->tx.txbuflock);
return bf; return bf;
} }
...@@ -310,6 +310,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, ...@@ -310,6 +310,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc,
{ {
struct sk_buff *skb = bf->bf_mpdu; struct sk_buff *skb = bf->bf_mpdu;
struct ath_xmit_status tx_status; struct ath_xmit_status tx_status;
unsigned long flags;
/* /*
* Set retry information. * Set retry information.
...@@ -340,9 +341,9 @@ static void ath_tx_complete_buf(struct ath_softc *sc, ...@@ -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 * Return the list of ath_buf of this mpdu to free queue
*/ */
spin_lock_bh(&sc->sc_txbuflock); spin_lock_irqsave(&sc->tx.txbuflock, flags);
list_splice_tail_init(bf_q, &sc->sc_txbuf); list_splice_tail_init(bf_q, &sc->tx.txbuf);
spin_unlock_bh(&sc->sc_txbuflock); 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) ...@@ -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) 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); 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) ...@@ -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) 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); ASSERT(tid->paused > 0);
spin_lock_bh(&txq->axq_lock); 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, ...@@ -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, static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
int width, int half_gi, bool shortPreamble) 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; u32 nbits, nsymbits, duration, nsymbols;
u8 rc; u8 rc;
int streams, pktlen; int streams, pktlen;
...@@ -557,7 +558,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) ...@@ -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 */ /* 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--) { for (i = 3; i >= 0; i--) {
if (rates[i].count && (rates[i].idx >= 0)) { if (rates[i].count && (rates[i].idx >= 0)) {
rix = rates[i].idx; rix = rates[i].idx;
...@@ -685,7 +686,7 @@ static int ath_tx_send_normal(struct ath_softc *sc, ...@@ -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) 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 ath_buf *bf;
struct list_head bf_head; struct list_head bf_head;
INIT_LIST_HEAD(&bf_head); INIT_LIST_HEAD(&bf_head);
...@@ -860,12 +861,12 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, ...@@ -860,12 +861,12 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
struct ath_buf *tbf; struct ath_buf *tbf;
/* allocate new descriptor */ /* allocate new descriptor */
spin_lock_bh(&sc->sc_txbuflock); spin_lock_bh(&sc->tx.txbuflock);
ASSERT(!list_empty((&sc->sc_txbuf))); ASSERT(!list_empty((&sc->tx.txbuf)));
tbf = list_first_entry(&sc->sc_txbuf, tbf = list_first_entry(&sc->tx.txbuf,
struct ath_buf, list); struct ath_buf, list);
list_del(&tbf->list); list_del(&tbf->list);
spin_unlock_bh(&sc->sc_txbuflock); spin_unlock_bh(&sc->tx.txbuflock);
ATH_TXBUF_RESET(tbf); ATH_TXBUF_RESET(tbf);
...@@ -1057,9 +1058,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) ...@@ -1057,9 +1058,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
if (bf_held) { if (bf_held) {
list_del(&bf_held->list); list_del(&bf_held->list);
spin_lock_bh(&sc->sc_txbuflock); spin_lock_bh(&sc->tx.txbuflock);
list_add_tail(&bf_held->list, &sc->sc_txbuf); list_add_tail(&bf_held->list, &sc->tx.txbuf);
spin_unlock_bh(&sc->sc_txbuflock); spin_unlock_bh(&sc->tx.txbuflock);
} }
if (!bf_isampdu(bf)) { if (!bf_isampdu(bf)) {
...@@ -1128,11 +1129,11 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) ...@@ -1128,11 +1129,11 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
if (!(sc->sc_flags & SC_OP_INVALID)) { if (!(sc->sc_flags & SC_OP_INVALID)) {
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, 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. /* The TxDMA may not really be stopped.
* Double check the hal tx pending count */ * Double check the hal tx pending count */
npend += ath9k_hw_numtxpending(ah, 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) ...@@ -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++) { for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, 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, ...@@ -1240,7 +1241,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
struct ath_buf *bf, struct ath_buf *bf,
struct ath_atx_tid *tid) 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 sk_buff *skb;
struct ieee80211_tx_info *tx_info; struct ieee80211_tx_info *tx_info;
struct ieee80211_tx_rate *rates; struct ieee80211_tx_rate *rates;
...@@ -1308,7 +1309,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, ...@@ -1308,7 +1309,7 @@ static int ath_compute_num_delims(struct ath_softc *sc,
struct ath_buf *bf, struct ath_buf *bf,
u16 frmlen) 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 sk_buff *skb = bf->bf_mpdu;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
u32 nsymbits, nsymbols, mpdudensity; u32 nsymbits, nsymbols, mpdudensity;
...@@ -1819,9 +1820,9 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb, ...@@ -1819,9 +1820,9 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
} }
spin_unlock_bh(&txq->axq_lock); spin_unlock_bh(&txq->axq_lock);
spin_lock_bh(&sc->sc_txbuflock); spin_lock_bh(&sc->tx.txbuflock);
list_add_tail(&bf->list, &sc->sc_txbuf); list_add_tail(&bf->list, &sc->tx.txbuf);
spin_unlock_bh(&sc->sc_txbuflock); spin_unlock_bh(&sc->tx.txbuflock);
return r; return r;
} }
...@@ -1838,10 +1839,10 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) ...@@ -1838,10 +1839,10 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
int error = 0; int error = 0;
do { do {
spin_lock_init(&sc->sc_txbuflock); spin_lock_init(&sc->tx.txbuflock);
/* Setup tx descriptors */ /* 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); "tx", nbufs, 1);
if (error != 0) { if (error != 0) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
...@@ -1851,7 +1852,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) ...@@ -1851,7 +1852,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
} }
/* XXX allocate beacon state together with vap */ /* 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); "beacon", ATH_BCBUF, 1);
if (error != 0) { if (error != 0) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
...@@ -1873,12 +1874,12 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) ...@@ -1873,12 +1874,12 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
int ath_tx_cleanup(struct ath_softc *sc) int ath_tx_cleanup(struct ath_softc *sc)
{ {
/* cleanup beacon descriptors */ /* cleanup beacon descriptors */
if (sc->sc_bdma.dd_desc_len != 0) if (sc->beacon.bdma.dd_desc_len != 0)
ath_descdma_cleanup(sc, &sc->sc_bdma, &sc->sc_bbuf); ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
/* cleanup tx descriptors */ /* cleanup tx descriptors */
if (sc->sc_txdma.dd_desc_len != 0) if (sc->tx.txdma.dd_desc_len != 0)
ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf); ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
return 0; return 0;
} }
...@@ -1926,15 +1927,15 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) ...@@ -1926,15 +1927,15 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
*/ */
return NULL; return NULL;
} }
if (qnum >= ARRAY_SIZE(sc->sc_txq)) { if (qnum >= ARRAY_SIZE(sc->tx.txq)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"qnum %u out of range, max %u!\n", "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); ath9k_hw_releasetxqueue(ah, qnum);
return NULL; return NULL;
} }
if (!ATH_TXQ_SETUP(sc, qnum)) { 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_qnum = qnum;
txq->axq_link = NULL; txq->axq_link = NULL;
...@@ -1945,9 +1946,9 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) ...@@ -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_aggr_depth = 0;
txq->axq_totalqueued = 0; txq->axq_totalqueued = 0;
txq->axq_linkbuf = NULL; 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 */ /* Reclaim resources for a setup queue */
...@@ -1955,7 +1956,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) ...@@ -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) void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
{ {
ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum); 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) ...@@ -1972,15 +1973,15 @@ int ath_tx_setup(struct ath_softc *sc, int haltype)
{ {
struct ath_txq *txq; struct ath_txq *txq;
if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) { if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"HAL AC %u out of range, max %zu!\n", "HAL AC %u out of range, max %zu!\n",
haltype, ARRAY_SIZE(sc->sc_haltype2q)); haltype, ARRAY_SIZE(sc->tx.hwq_map));
return 0; return 0;
} }
txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype); txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
if (txq != NULL) { if (txq != NULL) {
sc->sc_haltype2q[haltype] = txq->axq_qnum; sc->tx.hwq_map[haltype] = txq->axq_qnum;
return 1; return 1;
} else } else
return 0; return 0;
...@@ -1992,19 +1993,19 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype) ...@@ -1992,19 +1993,19 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
switch (qtype) { switch (qtype) {
case ATH9K_TX_QUEUE_DATA: 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, DPRINTF(sc, ATH_DBG_FATAL,
"HAL AC %u out of range, max %zu!\n", "HAL AC %u out of range, max %zu!\n",
haltype, ARRAY_SIZE(sc->sc_haltype2q)); haltype, ARRAY_SIZE(sc->tx.hwq_map));
return -1; return -1;
} }
qnum = sc->sc_haltype2q[haltype]; qnum = sc->tx.hwq_map[haltype];
break; break;
case ATH9K_TX_QUEUE_BEACON: case ATH9K_TX_QUEUE_BEACON:
qnum = sc->sc_bhalq; qnum = sc->beacon.beaconq;
break; break;
case ATH9K_TX_QUEUE_CAB: case ATH9K_TX_QUEUE_CAB:
qnum = sc->sc_cabq->axq_qnum; qnum = sc->beacon.cabq->axq_qnum;
break; break;
default: default:
qnum = -1; qnum = -1;
...@@ -2020,7 +2021,7 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) ...@@ -2020,7 +2021,7 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
int qnum; int qnum;
qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc); 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); spin_lock_bh(&txq->axq_lock);
...@@ -2049,17 +2050,17 @@ int ath_txq_update(struct ath_softc *sc, int qnum, ...@@ -2049,17 +2050,17 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
int error = 0; int error = 0;
struct ath9k_tx_queue_info qi; 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. * XXX: for beacon queue, we just save the parameter.
* It will be picked up by ath_beaconq_config when * It will be picked up by ath_beaconq_config when
* it's necessary. * it's necessary.
*/ */
sc->sc_beacon_qi = *qinfo; sc->beacon.beacon_qi = *qinfo;
return 0; 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); ath9k_hw_get_txq_props(ah, qnum, &qi);
qi.tqi_aifs = qinfo->tqi_aifs; qi.tqi_aifs = qinfo->tqi_aifs;
...@@ -2082,7 +2083,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum, ...@@ -2082,7 +2083,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
int ath_cabq_update(struct ath_softc *sc) int ath_cabq_update(struct ath_softc *sc)
{ {
struct ath9k_tx_queue_info qi; 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; struct ath_beacon_config conf;
ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi); ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
...@@ -2116,7 +2117,7 @@ void ath_tx_tasklet(struct ath_softc *sc) ...@@ -2116,7 +2117,7 @@ void ath_tx_tasklet(struct ath_softc *sc)
*/ */
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << 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, ...@@ -2148,9 +2149,9 @@ void ath_tx_draintxq(struct ath_softc *sc,
list_del(&bf->list); list_del(&bf->list);
spin_unlock_bh(&txq->axq_lock); spin_unlock_bh(&txq->axq_lock);
spin_lock_bh(&sc->sc_txbuflock); spin_lock_bh(&sc->tx.txbuflock);
list_add_tail(&bf->list, &sc->sc_txbuf); list_add_tail(&bf->list, &sc->tx.txbuf);
spin_unlock_bh(&sc->sc_txbuflock); spin_unlock_bh(&sc->tx.txbuflock);
continue; continue;
} }
...@@ -2188,9 +2189,9 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx) ...@@ -2188,9 +2189,9 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx)
/* stop beacon queue. The beacon will be freed when /* stop beacon queue. The beacon will be freed when
* we go to INIT state */ * we go to INIT state */
if (!(sc->sc_flags & SC_OP_INVALID)) { 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", 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); ath_drain_txdataq(sc, retry_tx);
...@@ -2198,12 +2199,12 @@ void ath_draintxq(struct ath_softc *sc, bool 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) 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) 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) 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 ...@@ -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) 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_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 ath_buf *bf;
struct list_head bf_head; struct list_head bf_head;
INIT_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) ...@@ -2405,7 +2406,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
/* /*
* Init per tid tx state * 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 < WME_NUM_TID;
tidno++, tid++) { tidno++, tid++) {
tid->an = an; tid->an = an;
...@@ -2419,7 +2420,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) ...@@ -2419,7 +2420,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
INIT_LIST_HEAD(&tid->buf_q); INIT_LIST_HEAD(&tid->buf_q);
acno = TID_TO_WME_AC(tidno); acno = TID_TO_WME_AC(tidno);
tid->ac = &an->an_aggr.tx.ac[acno]; tid->ac = &an->ac[acno];
/* ADDBA state */ /* ADDBA state */
tid->state &= ~AGGR_ADDBA_COMPLETE; tid->state &= ~AGGR_ADDBA_COMPLETE;
...@@ -2430,7 +2431,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) ...@@ -2430,7 +2431,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
/* /*
* Init per ac tx state * 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++) { acno < WME_NUM_AC; acno++, ac++) {
ac->sched = false; ac->sched = false;
INIT_LIST_HEAD(&ac->tid_q); INIT_LIST_HEAD(&ac->tid_q);
...@@ -2466,7 +2467,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) ...@@ -2466,7 +2467,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
struct ath_txq *txq; struct ath_txq *txq;
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i)) { if (ATH_TXQ_SETUP(sc, i)) {
txq = &sc->sc_txq[i]; txq = &sc->tx.txq[i];
spin_lock(&txq->axq_lock); spin_lock(&txq->axq_lock);
...@@ -2511,9 +2512,9 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) ...@@ -2511,9 +2512,9 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) 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(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 */ /* 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) ...@@ -2529,7 +2530,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
memmove(skb->data, skb->data + padsize, hdrlen); 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); DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
......
...@@ -211,7 +211,7 @@ static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf, ...@@ -211,7 +211,7 @@ static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf,
struct b43legacy_dfs_file *dfile; struct b43legacy_dfs_file *dfile;
ssize_t uninitialized_var(ret); ssize_t uninitialized_var(ret);
char *buf; char *buf;
const size_t bufsize = 1024 * 128; const size_t bufsize = 1024 * 16; /* 16 KiB buffer */
const size_t buforder = get_order(bufsize); const size_t buforder = get_order(bufsize);
int err = 0; int err = 0;
......
...@@ -245,6 +245,7 @@ enum connection_manager_assoc_states { ...@@ -245,6 +245,7 @@ enum connection_manager_assoc_states {
#define HOST_NOTIFICATION_S36_MEASUREMENT_REFUSED 31 #define HOST_NOTIFICATION_S36_MEASUREMENT_REFUSED 31
#define HOST_NOTIFICATION_STATUS_BEACON_MISSING 1 #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_MIN 1
#define IPW_MB_ROAMING_THRESHOLD_DEFAULT 8 #define IPW_MB_ROAMING_THRESHOLD_DEFAULT 8
#define IPW_MB_ROAMING_THRESHOLD_MAX 30 #define IPW_MB_ROAMING_THRESHOLD_MAX 30
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -46,3 +46,5 @@ rc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o ...@@ -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_PID) += $(rc80211_pid-y)
mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y)
ccflags-y += -D__CHECK_ENDIAN__
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册