forked from Minki/linux
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
This commit is contained in:
commit
56bde88590
@ -1099,9 +1099,9 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
|
||||
|
||||
if (ah->ah_combined_mic) {
|
||||
key_v[0] = rxmic[0];
|
||||
key_v[1] = (txmic[0] >> 16) & 0xffff;
|
||||
key_v[1] = cpu_to_le32(le32_to_cpu(txmic[0]) >> 16);
|
||||
key_v[2] = rxmic[1];
|
||||
key_v[3] = txmic[0] & 0xffff;
|
||||
key_v[3] = cpu_to_le32(le32_to_cpu(txmic[0]) & 0xffff);
|
||||
key_v[4] = txmic[1];
|
||||
} else {
|
||||
key_v[0] = rxmic[0];
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define AR9160_DEVID_PCI 0x0027
|
||||
#define AR9280_DEVID_PCI 0x0029
|
||||
#define AR9280_DEVID_PCIE 0x002a
|
||||
#define AR9285_DEVID_PCIE 0x002b
|
||||
|
||||
#define AR5416_AR9100_DEVID 0x000b
|
||||
|
||||
|
@ -26,7 +26,7 @@ static int ath_beaconq_config(struct ath_softc *sc)
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
struct ath9k_tx_queue_info qi;
|
||||
|
||||
ath9k_hw_get_txq_props(ah, sc->sc_bhalq, &qi);
|
||||
ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
|
||||
if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
|
||||
/* Always burst out beacon and CAB traffic. */
|
||||
qi.tqi_aifs = 1;
|
||||
@ -34,17 +34,17 @@ static int ath_beaconq_config(struct ath_softc *sc)
|
||||
qi.tqi_cwmax = 0;
|
||||
} else {
|
||||
/* Adhoc mode; important thing is to use 2x cwmin. */
|
||||
qi.tqi_aifs = sc->sc_beacon_qi.tqi_aifs;
|
||||
qi.tqi_cwmin = 2*sc->sc_beacon_qi.tqi_cwmin;
|
||||
qi.tqi_cwmax = sc->sc_beacon_qi.tqi_cwmax;
|
||||
qi.tqi_aifs = sc->beacon.beacon_qi.tqi_aifs;
|
||||
qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin;
|
||||
qi.tqi_cwmax = sc->beacon.beacon_qi.tqi_cwmax;
|
||||
}
|
||||
|
||||
if (!ath9k_hw_set_txq_props(ah, sc->sc_bhalq, &qi)) {
|
||||
if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
|
||||
DPRINTF(sc, ATH_DBG_FATAL,
|
||||
"unable to update h/w beacon queue parameters\n");
|
||||
return 0;
|
||||
} else {
|
||||
ath9k_hw_resettxqueue(ah, sc->sc_bhalq); /* push to h/w */
|
||||
ath9k_hw_resettxqueue(ah, sc->beacon.beaconq); /* push to h/w */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -53,7 +53,7 @@ static void ath_bstuck_process(struct ath_softc *sc)
|
||||
{
|
||||
DPRINTF(sc, ATH_DBG_BEACON,
|
||||
"stuck beacon; resetting (bmiss count %u)\n",
|
||||
sc->sc_bmisscount);
|
||||
sc->beacon.bmisscnt);
|
||||
ath_reset(sc, false);
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
|
||||
* SWBA's
|
||||
* XXX assumes two antenna
|
||||
*/
|
||||
antenna = ((sc->ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1);
|
||||
antenna = ((sc->beacon.ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1);
|
||||
}
|
||||
|
||||
ds->ds_data = bf->bf_buf_addr;
|
||||
@ -106,7 +106,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
|
||||
* XXX everything at min xmit rate
|
||||
*/
|
||||
rix = 0;
|
||||
rt = sc->hw_rate_table[sc->sc_curmode];
|
||||
rt = sc->cur_rate_table;
|
||||
rate = rt->info[rix].ratecode;
|
||||
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
|
||||
rate |= rt->info[rix].short_preamble;
|
||||
@ -153,7 +153,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
|
||||
ASSERT(vif);
|
||||
|
||||
avp = (void *)vif->drv_priv;
|
||||
cabq = sc->sc_cabq;
|
||||
cabq = sc->beacon.cabq;
|
||||
|
||||
if (avp->av_bcbuf == NULL) {
|
||||
DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n",
|
||||
@ -167,6 +167,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
|
||||
pci_unmap_single(sc->pdev, bf->bf_dmacontext,
|
||||
skb->len,
|
||||
PCI_DMA_TODEVICE);
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
|
||||
skb = ieee80211_beacon_get(sc->hw, vif);
|
||||
@ -181,9 +182,9 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
|
||||
* TX frames)
|
||||
*/
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
sc->seq_no += 0x10;
|
||||
sc->tx.seq_no += 0x10;
|
||||
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
|
||||
hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
|
||||
hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
|
||||
}
|
||||
|
||||
bf->bf_buf_addr = bf->bf_dmacontext =
|
||||
@ -269,10 +270,10 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
|
||||
ath_beacon_setup(sc, avp, bf);
|
||||
|
||||
/* NB: caller is known to have already stopped tx dma */
|
||||
ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr);
|
||||
ath9k_hw_txstart(ah, sc->sc_bhalq);
|
||||
ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
|
||||
ath9k_hw_txstart(ah, sc->beacon.beaconq);
|
||||
DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
|
||||
sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc);
|
||||
sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
|
||||
}
|
||||
|
||||
int ath_beaconq_setup(struct ath_hal *ah)
|
||||
@ -305,7 +306,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
|
||||
if (!avp->av_bcbuf) {
|
||||
/* Allocate beacon state for hostap/ibss. We know
|
||||
* a buffer is available. */
|
||||
avp->av_bcbuf = list_first_entry(&sc->sc_bbuf,
|
||||
avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf,
|
||||
struct ath_buf, list);
|
||||
list_del(&avp->av_bcbuf->list);
|
||||
|
||||
@ -318,13 +319,13 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
|
||||
*/
|
||||
avp->av_bslot = 0;
|
||||
for (slot = 0; slot < ATH_BCBUF; slot++)
|
||||
if (sc->sc_bslot[slot] == ATH_IF_ID_ANY) {
|
||||
if (sc->beacon.bslot[slot] == ATH_IF_ID_ANY) {
|
||||
/*
|
||||
* XXX hack, space out slots to better
|
||||
* deal with misses
|
||||
*/
|
||||
if (slot+1 < ATH_BCBUF &&
|
||||
sc->sc_bslot[slot+1] ==
|
||||
sc->beacon.bslot[slot+1] ==
|
||||
ATH_IF_ID_ANY) {
|
||||
avp->av_bslot = slot+1;
|
||||
break;
|
||||
@ -332,8 +333,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
|
||||
avp->av_bslot = slot;
|
||||
/* NB: keep looking for a double slot */
|
||||
}
|
||||
BUG_ON(sc->sc_bslot[avp->av_bslot] != ATH_IF_ID_ANY);
|
||||
sc->sc_bslot[avp->av_bslot] = if_id;
|
||||
BUG_ON(sc->beacon.bslot[avp->av_bslot] != ATH_IF_ID_ANY);
|
||||
sc->beacon.bslot[avp->av_bslot] = if_id;
|
||||
sc->sc_nbcnvaps++;
|
||||
}
|
||||
}
|
||||
@ -361,7 +362,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
|
||||
}
|
||||
|
||||
tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
|
||||
sc->bc_tstamp = le64_to_cpu(tstamp);
|
||||
sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
|
||||
|
||||
/*
|
||||
* Calculate a TSF adjustment factor required for
|
||||
@ -421,7 +422,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
|
||||
struct ath_buf *bf;
|
||||
|
||||
if (avp->av_bslot != -1) {
|
||||
sc->sc_bslot[avp->av_bslot] = ATH_IF_ID_ANY;
|
||||
sc->beacon.bslot[avp->av_bslot] = ATH_IF_ID_ANY;
|
||||
sc->sc_nbcnvaps--;
|
||||
}
|
||||
|
||||
@ -434,7 +435,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
|
||||
dev_kfree_skb_any(skb);
|
||||
bf->bf_mpdu = NULL;
|
||||
}
|
||||
list_add_tail(&bf->list, &sc->sc_bbuf);
|
||||
list_add_tail(&bf->list, &sc->beacon.bbuf);
|
||||
|
||||
avp->av_bcbuf = NULL;
|
||||
}
|
||||
@ -468,18 +469,18 @@ void ath9k_beacon_tasklet(unsigned long data)
|
||||
*
|
||||
* FIXME: Clean up this mess !!
|
||||
*/
|
||||
if (ath9k_hw_numtxpending(ah, sc->sc_bhalq) != 0) {
|
||||
sc->sc_bmisscount++;
|
||||
if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
|
||||
sc->beacon.bmisscnt++;
|
||||
/* XXX: doth needs the chanchange IE countdown decremented.
|
||||
* We should consider adding a mac80211 call to indicate
|
||||
* a beacon miss so appropriate action could be taken
|
||||
* (in that layer).
|
||||
*/
|
||||
if (sc->sc_bmisscount < BSTUCK_THRESH) {
|
||||
if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
|
||||
if (sc->sc_flags & SC_OP_NO_RESET) {
|
||||
DPRINTF(sc, ATH_DBG_BEACON,
|
||||
"missed %u consecutive beacons\n",
|
||||
sc->sc_bmisscount);
|
||||
sc->beacon.bmisscnt);
|
||||
if (show_cycles) {
|
||||
/*
|
||||
* Display cycle counter stats from HW
|
||||
@ -498,11 +499,11 @@ void ath9k_beacon_tasklet(unsigned long data)
|
||||
} else {
|
||||
DPRINTF(sc, ATH_DBG_BEACON,
|
||||
"missed %u consecutive beacons\n",
|
||||
sc->sc_bmisscount);
|
||||
sc->beacon.bmisscnt);
|
||||
}
|
||||
} else if (sc->sc_bmisscount >= BSTUCK_THRESH) {
|
||||
} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
|
||||
if (sc->sc_flags & SC_OP_NO_RESET) {
|
||||
if (sc->sc_bmisscount == BSTUCK_THRESH) {
|
||||
if (sc->beacon.bmisscnt == BSTUCK_THRESH) {
|
||||
DPRINTF(sc, ATH_DBG_BEACON,
|
||||
"beacon is officially "
|
||||
"stuck\n");
|
||||
@ -516,17 +517,17 @@ void ath9k_beacon_tasklet(unsigned long data)
|
||||
return;
|
||||
}
|
||||
|
||||
if (sc->sc_bmisscount != 0) {
|
||||
if (sc->beacon.bmisscnt != 0) {
|
||||
if (sc->sc_flags & SC_OP_NO_RESET) {
|
||||
DPRINTF(sc, ATH_DBG_BEACON,
|
||||
"resume beacon xmit after %u misses\n",
|
||||
sc->sc_bmisscount);
|
||||
sc->beacon.bmisscnt);
|
||||
} else {
|
||||
DPRINTF(sc, ATH_DBG_BEACON,
|
||||
"resume beacon xmit after %u misses\n",
|
||||
sc->sc_bmisscount);
|
||||
sc->beacon.bmisscnt);
|
||||
}
|
||||
sc->sc_bmisscount = 0;
|
||||
sc->beacon.bmisscnt = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -541,7 +542,7 @@ void ath9k_beacon_tasklet(unsigned long data)
|
||||
tsf = ath9k_hw_gettsf64(ah);
|
||||
tsftu = TSF_TO_TU(tsf>>32, tsf);
|
||||
slot = ((tsftu % intval) * ATH_BCBUF) / intval;
|
||||
if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF];
|
||||
if_id = sc->beacon.bslot[(slot + 1) % ATH_BCBUF];
|
||||
|
||||
DPRINTF(sc, ATH_DBG_BEACON,
|
||||
"slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
|
||||
@ -573,12 +574,12 @@ void ath9k_beacon_tasklet(unsigned long data)
|
||||
* set to ATH_BCBUF so this check is a noop.
|
||||
*/
|
||||
/* XXX locking */
|
||||
if (sc->sc_updateslot == UPDATE) {
|
||||
sc->sc_updateslot = COMMIT; /* commit next beacon */
|
||||
sc->sc_slotupdate = slot;
|
||||
} else if (sc->sc_updateslot == COMMIT && sc->sc_slotupdate == slot) {
|
||||
ath9k_hw_setslottime(sc->sc_ah, sc->sc_slottime);
|
||||
sc->sc_updateslot = OK;
|
||||
if (sc->beacon.updateslot == UPDATE) {
|
||||
sc->beacon.updateslot = COMMIT; /* commit next beacon */
|
||||
sc->beacon.slotupdate = slot;
|
||||
} else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
|
||||
ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime);
|
||||
sc->beacon.updateslot = OK;
|
||||
}
|
||||
if (bfaddr != 0) {
|
||||
/*
|
||||
@ -586,17 +587,17 @@ void ath9k_beacon_tasklet(unsigned long data)
|
||||
* This should never fail since we check above that no frames
|
||||
* are still pending on the queue.
|
||||
*/
|
||||
if (!ath9k_hw_stoptxdma(ah, sc->sc_bhalq)) {
|
||||
if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
|
||||
DPRINTF(sc, ATH_DBG_FATAL,
|
||||
"beacon queue %u did not stop?\n", sc->sc_bhalq);
|
||||
"beacon queue %u did not stop?\n", sc->beacon.beaconq);
|
||||
/* NB: the HAL still stops DMA, so proceed */
|
||||
}
|
||||
|
||||
/* NB: cabq traffic should already be queued and primed */
|
||||
ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bfaddr);
|
||||
ath9k_hw_txstart(ah, sc->sc_bhalq);
|
||||
ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
|
||||
ath9k_hw_txstart(ah, sc->beacon.beaconq);
|
||||
|
||||
sc->ast_be_xmit += bc; /* XXX per-vap? */
|
||||
sc->beacon.ast_be_xmit += bc; /* XXX per-vap? */
|
||||
}
|
||||
}
|
||||
|
||||
@ -643,7 +644,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
|
||||
conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
|
||||
|
||||
/* extract tstamp from last beacon and convert to TU */
|
||||
nexttbtt = TSF_TO_TU(sc->bc_tstamp >> 32, sc->bc_tstamp);
|
||||
nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
|
||||
|
||||
/* XXX conditionalize multi-bss support? */
|
||||
if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
|
||||
@ -830,7 +831,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
|
||||
ath_beaconq_config(sc);
|
||||
}
|
||||
ath9k_hw_beaconinit(ah, nexttbtt, intval);
|
||||
sc->sc_bmisscount = 0;
|
||||
sc->beacon.bmisscnt = 0;
|
||||
ath9k_hw_set_interrupts(ah, sc->sc_imask);
|
||||
/*
|
||||
* When using a self-linked beacon descriptor in
|
||||
|
@ -818,6 +818,101 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_9285_pa_cal(struct ath_hal *ah)
|
||||
{
|
||||
|
||||
u32 regVal;
|
||||
int i, offset, offs_6_1, offs_0;
|
||||
u32 ccomp_org, reg_field;
|
||||
u32 regList[][2] = {
|
||||
{ 0x786c, 0 },
|
||||
{ 0x7854, 0 },
|
||||
{ 0x7820, 0 },
|
||||
{ 0x7824, 0 },
|
||||
{ 0x7868, 0 },
|
||||
{ 0x783c, 0 },
|
||||
{ 0x7838, 0 },
|
||||
};
|
||||
|
||||
if (AR_SREV_9285_11(ah)) {
|
||||
REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regList); i++)
|
||||
regList[i][1] = REG_READ(ah, regList[i][0]);
|
||||
|
||||
regVal = REG_READ(ah, 0x7834);
|
||||
regVal &= (~(0x1));
|
||||
REG_WRITE(ah, 0x7834, regVal);
|
||||
regVal = REG_READ(ah, 0x9808);
|
||||
regVal |= (0x1 << 27);
|
||||
REG_WRITE(ah, 0x9808, regVal);
|
||||
|
||||
REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 1);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
|
||||
ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 7);
|
||||
|
||||
REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
|
||||
udelay(30);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
|
||||
|
||||
for (i = 6; i > 0; i--) {
|
||||
regVal = REG_READ(ah, 0x7834);
|
||||
regVal |= (1 << (19 + i));
|
||||
REG_WRITE(ah, 0x7834, regVal);
|
||||
udelay(1);
|
||||
regVal = REG_READ(ah, 0x7834);
|
||||
regVal &= (~(0x1 << (19 + i)));
|
||||
reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
|
||||
regVal |= (reg_field << (19 + i));
|
||||
REG_WRITE(ah, 0x7834, regVal);
|
||||
}
|
||||
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
|
||||
udelay(1);
|
||||
reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
|
||||
offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
|
||||
offs_0 = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
|
||||
|
||||
offset = (offs_6_1<<1) | offs_0;
|
||||
offset = offset - 0;
|
||||
offs_6_1 = offset>>1;
|
||||
offs_0 = offset & 1;
|
||||
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
|
||||
|
||||
regVal = REG_READ(ah, 0x7834);
|
||||
regVal |= 0x1;
|
||||
REG_WRITE(ah, 0x7834, regVal);
|
||||
regVal = REG_READ(ah, 0x9808);
|
||||
regVal &= (~(0x1 << 27));
|
||||
REG_WRITE(ah, 0x9808, regVal);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regList); i++)
|
||||
REG_WRITE(ah, regList[i][0], regList[i][1]);
|
||||
|
||||
REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
|
||||
|
||||
if (AR_SREV_9285_11(ah))
|
||||
REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
|
||||
|
||||
}
|
||||
|
||||
bool ath9k_hw_init_cal(struct ath_hal *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
@ -835,6 +930,9 @@ bool ath9k_hw_init_cal(struct ath_hal *ah,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
|
||||
ath9k_hw_9285_pa_cal(ah);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
|
||||
REG_READ(ah, AR_PHY_AGC_CONTROL) |
|
||||
AR_PHY_AGC_CONTROL_NF);
|
||||
|
@ -61,7 +61,7 @@ struct ath_node;
|
||||
#define TSF_TO_TU(_h,_l) \
|
||||
((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
|
||||
|
||||
#define ATH_TXQ_SETUP(sc, i) ((sc)->sc_txqsetup & (1<<i))
|
||||
#define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i))
|
||||
|
||||
static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
|
||||
@ -88,16 +88,66 @@ enum ATH_DEBUG {
|
||||
|
||||
#ifdef CONFIG_ATH9K_DEBUG
|
||||
|
||||
/**
|
||||
* struct ath_interrupt_stats - Contains statistics about interrupts
|
||||
* @total: Total no. of interrupts generated so far
|
||||
* @rxok: RX with no errors
|
||||
* @rxeol: RX with no more RXDESC available
|
||||
* @rxorn: RX FIFO overrun
|
||||
* @txok: TX completed at the requested rate
|
||||
* @txurn: TX FIFO underrun
|
||||
* @mib: MIB regs reaching its threshold
|
||||
* @rxphyerr: RX with phy errors
|
||||
* @rx_keycache_miss: RX with key cache misses
|
||||
* @swba: Software Beacon Alert
|
||||
* @bmiss: Beacon Miss
|
||||
* @bnr: Beacon Not Ready
|
||||
* @cst: Carrier Sense TImeout
|
||||
* @gtt: Global TX Timeout
|
||||
* @tim: RX beacon TIM occurrence
|
||||
* @cabend: RX End of CAB traffic
|
||||
* @dtimsync: DTIM sync lossage
|
||||
* @dtim: RX Beacon with DTIM
|
||||
*/
|
||||
struct ath_interrupt_stats {
|
||||
u32 total;
|
||||
u32 rxok;
|
||||
u32 rxeol;
|
||||
u32 rxorn;
|
||||
u32 txok;
|
||||
u32 txeol;
|
||||
u32 txurn;
|
||||
u32 mib;
|
||||
u32 rxphyerr;
|
||||
u32 rx_keycache_miss;
|
||||
u32 swba;
|
||||
u32 bmiss;
|
||||
u32 bnr;
|
||||
u32 cst;
|
||||
u32 gtt;
|
||||
u32 tim;
|
||||
u32 cabend;
|
||||
u32 dtimsync;
|
||||
u32 dtim;
|
||||
};
|
||||
|
||||
struct ath_stats {
|
||||
struct ath_interrupt_stats istats;
|
||||
};
|
||||
|
||||
struct ath9k_debug {
|
||||
int debug_mask;
|
||||
struct dentry *debugfs_root;
|
||||
struct dentry *debugfs_phy;
|
||||
struct dentry *debugfs_dma;
|
||||
struct dentry *debugfs_interrupt;
|
||||
struct ath_stats stats;
|
||||
};
|
||||
|
||||
void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
|
||||
int ath9k_init_debug(struct ath_softc *sc);
|
||||
void ath9k_exit_debug(struct ath_softc *sc);
|
||||
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
|
||||
|
||||
#else
|
||||
|
||||
@ -115,6 +165,11 @@ static inline void ath9k_exit_debug(struct ath_softc *sc)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
|
||||
enum ath9k_int status)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ATH9K_DEBUG */
|
||||
|
||||
struct ath_config {
|
||||
@ -235,18 +290,9 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
|
||||
/* RX / TX */
|
||||
/***********/
|
||||
|
||||
#define ATH_MAX_ANTENNA 3
|
||||
#define ATH_RXBUF 512
|
||||
#define WME_NUM_TID 16
|
||||
|
||||
int ath_startrecv(struct ath_softc *sc);
|
||||
bool ath_stoprecv(struct ath_softc *sc);
|
||||
void ath_flushrecv(struct ath_softc *sc);
|
||||
u32 ath_calcrxfilter(struct ath_softc *sc);
|
||||
int ath_rx_init(struct ath_softc *sc, int nbufs);
|
||||
void ath_rx_cleanup(struct ath_softc *sc);
|
||||
int ath_rx_tasklet(struct ath_softc *sc, int flush);
|
||||
|
||||
#define ATH_MAX_ANTENNA 3
|
||||
#define ATH_RXBUF 512
|
||||
#define WME_NUM_TID 16
|
||||
#define ATH_TXBUF 512
|
||||
#define ATH_TXMAXTRY 13
|
||||
#define ATH_11N_TXMAXTRY 10
|
||||
@ -254,19 +300,61 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush);
|
||||
#define WME_BA_BMP_SIZE 64
|
||||
#define WME_MAX_BA WME_BA_BMP_SIZE
|
||||
#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
|
||||
|
||||
#define TID_TO_WME_AC(_tid) \
|
||||
((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
|
||||
(((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
|
||||
(((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
|
||||
WME_AC_VO)
|
||||
|
||||
|
||||
#define WME_AC_BE 0
|
||||
#define WME_AC_BK 1
|
||||
#define WME_AC_VI 2
|
||||
#define WME_AC_VO 3
|
||||
#define WME_NUM_AC 4
|
||||
|
||||
#define ADDBA_EXCHANGE_ATTEMPTS 10
|
||||
#define ATH_AGGR_DELIM_SZ 4
|
||||
#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
|
||||
/* number of delimiters for encryption padding */
|
||||
#define ATH_AGGR_ENCRYPTDELIM 10
|
||||
/* minimum h/w qdepth to be sustained to maximize aggregation */
|
||||
#define ATH_AGGR_MIN_QDEPTH 2
|
||||
#define ATH_AMPDU_SUBFRAME_DEFAULT 32
|
||||
#define IEEE80211_SEQ_SEQ_SHIFT 4
|
||||
#define IEEE80211_SEQ_MAX 4096
|
||||
#define IEEE80211_MIN_AMPDU_BUF 0x8
|
||||
#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
|
||||
|
||||
/* return whether a bit at index _n in bitmap _bm is set
|
||||
* _sz is the size of the bitmap */
|
||||
#define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \
|
||||
((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
|
||||
|
||||
/* return block-ack bitmap index given sequence and starting sequence */
|
||||
#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
|
||||
|
||||
/* returns delimiter padding required given the packet length */
|
||||
#define ATH_AGGR_GET_NDELIM(_len) \
|
||||
(((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \
|
||||
(ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
|
||||
|
||||
#define BAW_WITHIN(_start, _bawsz, _seqno) \
|
||||
((((_seqno) - (_start)) & 4095) < (_bawsz))
|
||||
|
||||
#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
|
||||
#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
|
||||
#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
|
||||
#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
|
||||
|
||||
enum ATH_AGGR_STATUS {
|
||||
ATH_AGGR_DONE,
|
||||
ATH_AGGR_BAW_CLOSED,
|
||||
ATH_AGGR_LIMITED,
|
||||
ATH_AGGR_SHORTPKT,
|
||||
ATH_AGGR_8K_LIMITED,
|
||||
};
|
||||
|
||||
struct ath_txq {
|
||||
u32 axq_qnum; /* hardware q number */
|
||||
u32 *axq_link; /* link ptr in last TX desc */
|
||||
@ -276,7 +364,6 @@ struct ath_txq {
|
||||
u32 axq_depth; /* queue depth */
|
||||
u8 axq_aggr_depth; /* aggregates queued */
|
||||
u32 axq_totalqueued; /* total ever queued */
|
||||
|
||||
bool stopped; /* Is mac80211 queue stopped ? */
|
||||
struct ath_buf *axq_linkbuf; /* virtual addr of last buffer*/
|
||||
|
||||
@ -322,12 +409,6 @@ struct ath_atx_ac {
|
||||
struct list_head tid_q; /* queue of TIDs with buffers */
|
||||
};
|
||||
|
||||
/* per dest tx state */
|
||||
struct ath_atx {
|
||||
struct ath_atx_tid tid[WME_NUM_TID];
|
||||
struct ath_atx_ac ac[WME_NUM_AC];
|
||||
};
|
||||
|
||||
/* per-frame tx control block */
|
||||
struct ath_tx_control {
|
||||
struct ath_txq *txq;
|
||||
@ -353,13 +434,54 @@ struct ath_tx_stat {
|
||||
int rateKbps;
|
||||
int ratecode;
|
||||
int flags;
|
||||
/* if any of ctl,extn chain rssis are valid */
|
||||
#define ATH_TX_CHAIN_RSSI_VALID 0x01
|
||||
/* if extn chain rssis are valid */
|
||||
#define ATH_TX_RSSI_EXTN_VALID 0x02
|
||||
u32 airtime; /* time on air per final tx rate */
|
||||
};
|
||||
|
||||
struct aggr_rifs_param {
|
||||
int param_max_frames;
|
||||
int param_max_len;
|
||||
int param_rl;
|
||||
int param_al;
|
||||
struct ath_rc_series *param_rcs;
|
||||
};
|
||||
|
||||
struct ath_node {
|
||||
struct ath_softc *an_sc;
|
||||
struct ath_atx_tid tid[WME_NUM_TID];
|
||||
struct ath_atx_ac ac[WME_NUM_AC];
|
||||
u16 maxampdu;
|
||||
u8 mpdudensity;
|
||||
};
|
||||
|
||||
struct ath_tx {
|
||||
u16 seq_no;
|
||||
u32 txqsetup;
|
||||
int hwq_map[ATH9K_WME_AC_VO+1];
|
||||
spinlock_t txbuflock;
|
||||
struct list_head txbuf;
|
||||
struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
|
||||
struct ath_descdma txdma;
|
||||
};
|
||||
|
||||
struct ath_rx {
|
||||
u8 defant;
|
||||
u8 rxotherant;
|
||||
u32 *rxlink;
|
||||
int bufsize;
|
||||
unsigned int rxfilter;
|
||||
spinlock_t rxflushlock;
|
||||
spinlock_t rxbuflock;
|
||||
struct list_head rxbuf;
|
||||
struct ath_descdma rxdma;
|
||||
};
|
||||
|
||||
int ath_startrecv(struct ath_softc *sc);
|
||||
bool ath_stoprecv(struct ath_softc *sc);
|
||||
void ath_flushrecv(struct ath_softc *sc);
|
||||
u32 ath_calcrxfilter(struct ath_softc *sc);
|
||||
int ath_rx_init(struct ath_softc *sc, int nbufs);
|
||||
void ath_rx_cleanup(struct ath_softc *sc);
|
||||
int ath_rx_tasklet(struct ath_softc *sc, int flush);
|
||||
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
|
||||
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
|
||||
int ath_tx_setup(struct ath_softc *sc, int haltype);
|
||||
@ -382,73 +504,6 @@ void ath_tx_tasklet(struct ath_softc *sc);
|
||||
u32 ath_txq_depth(struct ath_softc *sc, int qnum);
|
||||
u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum);
|
||||
void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
|
||||
|
||||
/**********************/
|
||||
/* Node / Aggregation */
|
||||
/**********************/
|
||||
|
||||
#define ADDBA_EXCHANGE_ATTEMPTS 10
|
||||
#define ATH_AGGR_DELIM_SZ 4
|
||||
#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
|
||||
/* number of delimiters for encryption padding */
|
||||
#define ATH_AGGR_ENCRYPTDELIM 10
|
||||
/* minimum h/w qdepth to be sustained to maximize aggregation */
|
||||
#define ATH_AGGR_MIN_QDEPTH 2
|
||||
#define ATH_AMPDU_SUBFRAME_DEFAULT 32
|
||||
#define IEEE80211_SEQ_SEQ_SHIFT 4
|
||||
#define IEEE80211_SEQ_MAX 4096
|
||||
#define IEEE80211_MIN_AMPDU_BUF 0x8
|
||||
#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
|
||||
|
||||
/* return whether a bit at index _n in bitmap _bm is set
|
||||
* _sz is the size of the bitmap */
|
||||
#define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \
|
||||
((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
|
||||
|
||||
/* return block-ack bitmap index given sequence and starting sequence */
|
||||
#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
|
||||
|
||||
/* returns delimiter padding required given the packet length */
|
||||
#define ATH_AGGR_GET_NDELIM(_len) \
|
||||
(((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \
|
||||
(ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
|
||||
|
||||
#define BAW_WITHIN(_start, _bawsz, _seqno) \
|
||||
((((_seqno) - (_start)) & 4095) < (_bawsz))
|
||||
|
||||
#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
|
||||
#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
|
||||
#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
|
||||
#define ATH_AN_2_TID(_an, _tidno) (&(_an)->an_aggr.tx.tid[(_tidno)])
|
||||
|
||||
enum ATH_AGGR_STATUS {
|
||||
ATH_AGGR_DONE,
|
||||
ATH_AGGR_BAW_CLOSED,
|
||||
ATH_AGGR_LIMITED,
|
||||
ATH_AGGR_SHORTPKT,
|
||||
ATH_AGGR_8K_LIMITED,
|
||||
};
|
||||
|
||||
struct aggr_rifs_param {
|
||||
int param_max_frames;
|
||||
int param_max_len;
|
||||
int param_rl;
|
||||
int param_al;
|
||||
struct ath_rc_series *param_rcs;
|
||||
};
|
||||
|
||||
/* Per-node aggregation state */
|
||||
struct ath_node_aggr {
|
||||
struct ath_atx tx;
|
||||
};
|
||||
|
||||
struct ath_node {
|
||||
struct ath_softc *an_sc;
|
||||
struct ath_node_aggr an_aggr;
|
||||
u16 maxampdu;
|
||||
u8 mpdudensity;
|
||||
};
|
||||
|
||||
void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid);
|
||||
bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
|
||||
void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tidno);
|
||||
@ -489,7 +544,7 @@ struct ath_vap {
|
||||
* number of beacon intervals, the game's up.
|
||||
*/
|
||||
#define BSTUCK_THRESH (9 * ATH_BCBUF)
|
||||
#define ATH_BCBUF 4
|
||||
#define ATH_BCBUF 1
|
||||
#define ATH_DEFAULT_BINTVAL 100 /* TU */
|
||||
#define ATH_DEFAULT_BMISS_LIMIT 10
|
||||
#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
|
||||
@ -507,6 +562,26 @@ struct ath_beacon_config {
|
||||
} u; /* last received beacon/probe response timestamp of this BSS. */
|
||||
};
|
||||
|
||||
struct ath_beacon {
|
||||
enum {
|
||||
OK, /* no change needed */
|
||||
UPDATE, /* update pending */
|
||||
COMMIT /* beacon sent, commit change */
|
||||
} updateslot; /* slot time update fsm */
|
||||
|
||||
u32 beaconq;
|
||||
u32 bmisscnt;
|
||||
u32 ast_be_xmit;
|
||||
u64 bc_tstamp;
|
||||
int bslot[ATH_BCBUF];
|
||||
int slottime;
|
||||
int slotupdate;
|
||||
struct ath9k_tx_queue_info beacon_qi;
|
||||
struct ath_descdma bdma;
|
||||
struct ath_txq *cabq;
|
||||
struct list_head bbuf;
|
||||
};
|
||||
|
||||
void ath9k_beacon_tasklet(unsigned long data);
|
||||
void ath_beacon_config(struct ath_softc *sc, int if_id);
|
||||
int ath_beaconq_setup(struct ath_hal *ah);
|
||||
@ -577,7 +652,7 @@ struct ath_rfkill {
|
||||
#define DEFAULT_CACHELINE 32
|
||||
#define ATH_DEFAULT_NOISE_FLOOR -95
|
||||
#define ATH_REGCLASSIDS_MAX 10
|
||||
#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
|
||||
#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
|
||||
#define ATH_MAX_SW_RETRIES 10
|
||||
#define ATH_CHAN_MAX 255
|
||||
#define IEEE80211_WEP_NKID 4 /* number of key ids */
|
||||
@ -590,7 +665,7 @@ struct ath_rfkill {
|
||||
* Different parts have different size key caches. We handle
|
||||
* up to ATH_KEYMAX entries (could dynamically allocate state).
|
||||
*/
|
||||
#define ATH_KEYMAX 128 /* max key cache size we handle */
|
||||
#define ATH_KEYMAX 128 /* max key cache size we handle */
|
||||
|
||||
#define ATH_IF_ID_ANY 0xff
|
||||
#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
|
||||
@ -623,108 +698,51 @@ struct ath_softc {
|
||||
struct pci_dev *pdev;
|
||||
struct tasklet_struct intr_tq;
|
||||
struct tasklet_struct bcon_tasklet;
|
||||
struct ath_config sc_config;
|
||||
struct ath_hal *sc_ah;
|
||||
void __iomem *mem;
|
||||
spinlock_t sc_resetlock;
|
||||
|
||||
u8 sc_curbssid[ETH_ALEN];
|
||||
u8 sc_myaddr[ETH_ALEN];
|
||||
u8 sc_bssidmask[ETH_ALEN];
|
||||
|
||||
#ifdef CONFIG_ATH9K_DEBUG
|
||||
struct ath9k_debug sc_debug;
|
||||
#endif
|
||||
u32 sc_intrstatus;
|
||||
u32 sc_flags; /* SC_OP_* */
|
||||
unsigned int rx_filter;
|
||||
u16 sc_curtxpow;
|
||||
u16 sc_curaid;
|
||||
u16 sc_cachelsz;
|
||||
int sc_slotupdate; /* slot to next advance fsm */
|
||||
int sc_slottime;
|
||||
int sc_bslot[ATH_BCBUF];
|
||||
u8 sc_tx_chainmask;
|
||||
u8 sc_rx_chainmask;
|
||||
enum ath9k_int sc_imask;
|
||||
enum wireless_mode sc_curmode;
|
||||
enum PROT_MODE sc_protmode;
|
||||
|
||||
u8 sc_nbcnvaps;
|
||||
u16 sc_nvaps;
|
||||
struct ieee80211_vif *sc_vaps[ATH_BCBUF];
|
||||
|
||||
u8 sc_mcastantenna;
|
||||
u8 sc_defant;
|
||||
u8 sc_rxotherant;
|
||||
|
||||
struct ath9k_node_stats sc_halstats;
|
||||
u8 sc_tx_chainmask;
|
||||
u8 sc_rx_chainmask;
|
||||
u32 sc_keymax;
|
||||
DECLARE_BITMAP(sc_keymap, ATH_KEYMAX);
|
||||
u8 sc_splitmic;
|
||||
u8 sc_protrix;
|
||||
enum ath9k_int sc_imask;
|
||||
enum PROT_MODE sc_protmode;
|
||||
enum ath9k_ht_extprotspacing sc_ht_extprotspacing;
|
||||
enum ath9k_ht_macmode tx_chan_width;
|
||||
|
||||
#ifdef CONFIG_SLOW_ANT_DIV
|
||||
struct ath_antdiv sc_antdiv;
|
||||
#endif
|
||||
enum {
|
||||
OK, /* no change needed */
|
||||
UPDATE, /* update pending */
|
||||
COMMIT /* beacon sent, commit change */
|
||||
} sc_updateslot; /* slot time update fsm */
|
||||
|
||||
/* Crypto */
|
||||
u32 sc_keymax;
|
||||
DECLARE_BITMAP(sc_keymap, ATH_KEYMAX);
|
||||
u8 sc_splitmic; /* split TKIP MIC keys */
|
||||
|
||||
/* RX */
|
||||
struct list_head sc_rxbuf;
|
||||
struct ath_descdma sc_rxdma;
|
||||
int sc_rxbufsize;
|
||||
u32 *sc_rxlink;
|
||||
|
||||
/* TX */
|
||||
struct list_head sc_txbuf;
|
||||
struct ath_txq sc_txq[ATH9K_NUM_TX_QUEUES];
|
||||
struct ath_descdma sc_txdma;
|
||||
u32 sc_txqsetup;
|
||||
int sc_haltype2q[ATH9K_WME_AC_VO+1];
|
||||
u16 seq_no; /* TX sequence number */
|
||||
|
||||
/* Beacon */
|
||||
struct ath9k_tx_queue_info sc_beacon_qi;
|
||||
struct ath_descdma sc_bdma;
|
||||
struct ath_txq *sc_cabq;
|
||||
struct list_head sc_bbuf;
|
||||
u32 sc_bhalq;
|
||||
u32 sc_bmisscount;
|
||||
u32 ast_be_xmit;
|
||||
u64 bc_tstamp;
|
||||
|
||||
/* Rate */
|
||||
struct ath_config sc_config;
|
||||
struct ath_rx rx;
|
||||
struct ath_tx tx;
|
||||
struct ath_beacon beacon;
|
||||
struct ieee80211_vif *sc_vaps[ATH_BCBUF];
|
||||
struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
|
||||
struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
|
||||
u8 sc_protrix;
|
||||
|
||||
/* Channel, Band */
|
||||
struct ath_rate_table *cur_rate_table;
|
||||
struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX];
|
||||
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
|
||||
|
||||
/* Locks */
|
||||
spinlock_t sc_rxflushlock;
|
||||
spinlock_t sc_rxbuflock;
|
||||
spinlock_t sc_txbuflock;
|
||||
spinlock_t sc_resetlock;
|
||||
|
||||
/* LEDs */
|
||||
struct ath_led radio_led;
|
||||
struct ath_led assoc_led;
|
||||
struct ath_led tx_led;
|
||||
struct ath_led rx_led;
|
||||
|
||||
/* Rfkill */
|
||||
struct ath_rfkill rf_kill;
|
||||
|
||||
/* ANI */
|
||||
struct ath_ani sc_ani;
|
||||
struct ath9k_node_stats sc_halstats;
|
||||
#ifdef CONFIG_ATH9K_DEBUG
|
||||
struct ath9k_debug sc_debug;
|
||||
#endif
|
||||
};
|
||||
|
||||
int ath_reset(struct ath_softc *sc, bool retry_tx);
|
||||
|
@ -128,6 +128,100 @@ static const struct file_operations fops_dma = {
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
||||
|
||||
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
|
||||
{
|
||||
if (status)
|
||||
sc->sc_debug.stats.istats.total++;
|
||||
if (status & ATH9K_INT_RX)
|
||||
sc->sc_debug.stats.istats.rxok++;
|
||||
if (status & ATH9K_INT_RXEOL)
|
||||
sc->sc_debug.stats.istats.rxeol++;
|
||||
if (status & ATH9K_INT_RXORN)
|
||||
sc->sc_debug.stats.istats.rxorn++;
|
||||
if (status & ATH9K_INT_TX)
|
||||
sc->sc_debug.stats.istats.txok++;
|
||||
if (status & ATH9K_INT_TXURN)
|
||||
sc->sc_debug.stats.istats.txurn++;
|
||||
if (status & ATH9K_INT_MIB)
|
||||
sc->sc_debug.stats.istats.mib++;
|
||||
if (status & ATH9K_INT_RXPHY)
|
||||
sc->sc_debug.stats.istats.rxphyerr++;
|
||||
if (status & ATH9K_INT_RXKCM)
|
||||
sc->sc_debug.stats.istats.rx_keycache_miss++;
|
||||
if (status & ATH9K_INT_SWBA)
|
||||
sc->sc_debug.stats.istats.swba++;
|
||||
if (status & ATH9K_INT_BMISS)
|
||||
sc->sc_debug.stats.istats.bmiss++;
|
||||
if (status & ATH9K_INT_BNR)
|
||||
sc->sc_debug.stats.istats.bnr++;
|
||||
if (status & ATH9K_INT_CST)
|
||||
sc->sc_debug.stats.istats.cst++;
|
||||
if (status & ATH9K_INT_GTT)
|
||||
sc->sc_debug.stats.istats.gtt++;
|
||||
if (status & ATH9K_INT_TIM)
|
||||
sc->sc_debug.stats.istats.tim++;
|
||||
if (status & ATH9K_INT_CABEND)
|
||||
sc->sc_debug.stats.istats.cabend++;
|
||||
if (status & ATH9K_INT_DTIMSYNC)
|
||||
sc->sc_debug.stats.istats.dtimsync++;
|
||||
if (status & ATH9K_INT_DTIM)
|
||||
sc->sc_debug.stats.istats.dtim++;
|
||||
}
|
||||
|
||||
static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
char buf[512];
|
||||
unsigned int len = 0;
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "RX", sc->sc_debug.stats.istats.rxok);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "RXEOL", sc->sc_debug.stats.istats.rxeol);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "RXORN", sc->sc_debug.stats.istats.rxorn);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "TX", sc->sc_debug.stats.istats.txok);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "TXURN", sc->sc_debug.stats.istats.txurn);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "MIB", sc->sc_debug.stats.istats.mib);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "RXPHY", sc->sc_debug.stats.istats.rxphyerr);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "RXKCM", sc->sc_debug.stats.istats.rx_keycache_miss);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "SWBA", sc->sc_debug.stats.istats.swba);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "BMISS", sc->sc_debug.stats.istats.bmiss);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "BNR", sc->sc_debug.stats.istats.bnr);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "CST", sc->sc_debug.stats.istats.cst);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "GTT", sc->sc_debug.stats.istats.gtt);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "TIM", sc->sc_debug.stats.istats.tim);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "CABEND", sc->sc_debug.stats.istats.cabend);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "DTIMSYNC", sc->sc_debug.stats.istats.dtimsync);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "DTIM", sc->sc_debug.stats.istats.dtim);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "TOTAL", sc->sc_debug.stats.istats.total);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_interrupt = {
|
||||
.read = read_file_interrupt,
|
||||
.open = ath9k_debugfs_open,
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
||||
int ath9k_init_debug(struct ath_softc *sc)
|
||||
{
|
||||
sc->sc_debug.debug_mask = ath9k_debug;
|
||||
@ -146,6 +240,13 @@ int ath9k_init_debug(struct ath_softc *sc)
|
||||
if (!sc->sc_debug.debugfs_dma)
|
||||
goto err;
|
||||
|
||||
sc->sc_debug.debugfs_interrupt = debugfs_create_file("interrupt",
|
||||
S_IRUGO,
|
||||
sc->sc_debug.debugfs_phy,
|
||||
sc, &fops_interrupt);
|
||||
if (!sc->sc_debug.debugfs_interrupt)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
ath9k_exit_debug(sc);
|
||||
@ -154,6 +255,7 @@ err:
|
||||
|
||||
void ath9k_exit_debug(struct ath_softc *sc)
|
||||
{
|
||||
debugfs_remove(sc->sc_debug.debugfs_interrupt);
|
||||
debugfs_remove(sc->sc_debug.debugfs_dma);
|
||||
debugfs_remove(sc->sc_debug.debugfs_phy);
|
||||
debugfs_remove(sc->sc_debug.debugfs_root);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type);
|
||||
static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
|
||||
enum ath9k_ht_macmode macmode);
|
||||
static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
|
||||
struct ar5416_eeprom *pEepData,
|
||||
struct ar5416_eeprom_def *pEepData,
|
||||
u32 reg, u32 value);
|
||||
static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan);
|
||||
static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan);
|
||||
@ -392,6 +392,8 @@ static const char *ath9k_hw_devname(u16 devid)
|
||||
case AR9280_DEVID_PCI:
|
||||
case AR9280_DEVID_PCIE:
|
||||
return "Atheros 9280";
|
||||
case AR9285_DEVID_PCIE:
|
||||
return "Atheros 9285";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -640,10 +642,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
|
||||
struct ath_hal_5416 *ahp;
|
||||
struct ath_hal *ah;
|
||||
int ecode;
|
||||
#ifndef CONFIG_SLOW_ANT_DIV
|
||||
u32 i;
|
||||
u32 j;
|
||||
#endif
|
||||
u32 i, j;
|
||||
|
||||
ahp = ath9k_hw_newstate(devid, sc, mem, status);
|
||||
if (ahp == NULL)
|
||||
@ -685,7 +684,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
|
||||
if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
|
||||
(ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
|
||||
(ah->ah_macVersion != AR_SREV_VERSION_9160) &&
|
||||
(!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) {
|
||||
(!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) {
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_RESET,
|
||||
"Mac Chip Rev 0x%02x.%x is not supported by "
|
||||
"this driver\n", ah->ah_macVersion, ah->ah_macRev);
|
||||
@ -736,7 +735,38 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
|
||||
"This Mac Chip Rev 0x%02x.%x is \n",
|
||||
ah->ah_macVersion, ah->ah_macRev);
|
||||
|
||||
if (AR_SREV_9280_20_OR_LATER(ah)) {
|
||||
if (AR_SREV_9285_12_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285_1_2,
|
||||
ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
|
||||
INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285_1_2,
|
||||
ARRAY_SIZE(ar9285Common_9285_1_2), 2);
|
||||
|
||||
if (ah->ah_config.pcie_clock_req) {
|
||||
INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
|
||||
ar9285PciePhy_clkreq_off_L1_9285_1_2,
|
||||
ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
|
||||
ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
|
||||
ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
|
||||
2);
|
||||
}
|
||||
} else if (AR_SREV_9285_10_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285,
|
||||
ARRAY_SIZE(ar9285Modes_9285), 6);
|
||||
INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285,
|
||||
ARRAY_SIZE(ar9285Common_9285), 2);
|
||||
|
||||
if (ah->ah_config.pcie_clock_req) {
|
||||
INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
|
||||
ar9285PciePhy_clkreq_off_L1_9285,
|
||||
ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
|
||||
ar9285PciePhy_clkreq_always_on_L1_9285,
|
||||
ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
|
||||
}
|
||||
} else if (AR_SREV_9280_20_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_9280_2), 6);
|
||||
INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
|
||||
@ -846,14 +876,13 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
|
||||
goto bad;
|
||||
|
||||
/* rxgain table */
|
||||
if (AR_SREV_9280_20_OR_LATER(ah))
|
||||
if (AR_SREV_9280_20(ah))
|
||||
ath9k_hw_init_rxgain_ini(ah);
|
||||
|
||||
/* txgain table */
|
||||
if (AR_SREV_9280_20_OR_LATER(ah))
|
||||
if (AR_SREV_9280_20(ah))
|
||||
ath9k_hw_init_txgain_ini(ah);
|
||||
|
||||
#ifndef CONFIG_SLOW_ANT_DIV
|
||||
if (ah->ah_devid == AR9280_DEVID_PCI) {
|
||||
for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
|
||||
u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
|
||||
@ -862,12 +891,13 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
|
||||
u32 val = INI_RA(&ahp->ah_iniModes, i, j);
|
||||
|
||||
INI_RA(&ahp->ah_iniModes, i, j) =
|
||||
ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom,
|
||||
ath9k_hw_ini_fixup(ah,
|
||||
&ahp->ah_eeprom.def,
|
||||
reg, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ath9k_hw_fill_cap_info(ah)) {
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_RESET,
|
||||
"failed ath9k_hw_fill_cap_info\n");
|
||||
@ -1020,8 +1050,6 @@ static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
|
||||
}
|
||||
case 0x1:
|
||||
case 0x2:
|
||||
if (!AR_SREV_9280(ah))
|
||||
break;
|
||||
case 0x7:
|
||||
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
|
||||
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
|
||||
@ -1166,12 +1194,10 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
|
||||
case AR9160_DEVID_PCI:
|
||||
case AR9280_DEVID_PCI:
|
||||
case AR9280_DEVID_PCIE:
|
||||
case AR9285_DEVID_PCIE:
|
||||
ah = ath9k_hw_do_attach(devid, sc, mem, error);
|
||||
break;
|
||||
default:
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_ANY,
|
||||
"devid=0x%x not supported.\n", devid);
|
||||
ah = NULL;
|
||||
*error = -ENXIO;
|
||||
break;
|
||||
}
|
||||
@ -1186,6 +1212,14 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
|
||||
static void ath9k_hw_override_ini(struct ath_hal *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
/*
|
||||
* Set the RX_ABORT and RX_DIS and clear if off only after
|
||||
* RXE is set for MAC. This prevents frames with corrupted
|
||||
* descriptor status.
|
||||
*/
|
||||
REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
|
||||
|
||||
|
||||
if (!AR_SREV_5416_V20_OR_LATER(ah) ||
|
||||
AR_SREV_9280_10_OR_LATER(ah))
|
||||
return;
|
||||
@ -1193,8 +1227,8 @@ static void ath9k_hw_override_ini(struct ath_hal *ah,
|
||||
REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
|
||||
}
|
||||
|
||||
static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
|
||||
struct ar5416_eeprom *pEepData,
|
||||
static u32 ath9k_hw_def_ini_fixup(struct ath_hal *ah,
|
||||
struct ar5416_eeprom_def *pEepData,
|
||||
u32 reg, u32 value)
|
||||
{
|
||||
struct base_eep_header *pBase = &(pEepData->baseEepHeader);
|
||||
@ -1227,6 +1261,18 @@ static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
|
||||
return value;
|
||||
}
|
||||
|
||||
static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
|
||||
struct ar5416_eeprom_def *pEepData,
|
||||
u32 reg, u32 value)
|
||||
{
|
||||
struct ath_hal_5416 *ahp = AH5416(ah);
|
||||
|
||||
if (ahp->ah_eep_map == EEP_MAP_4KBITS)
|
||||
return value;
|
||||
else
|
||||
return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value);
|
||||
}
|
||||
|
||||
static int ath9k_hw_process_ini(struct ath_hal *ah,
|
||||
struct ath9k_channel *chan,
|
||||
enum ath9k_ht_macmode macmode)
|
||||
@ -1294,11 +1340,6 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
|
||||
u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
|
||||
u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
|
||||
|
||||
#ifdef CONFIG_SLOW_ANT_DIV
|
||||
if (ah->ah_devid == AR9280_DEVID_PCI)
|
||||
val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg, val);
|
||||
#endif
|
||||
|
||||
REG_WRITE(ah, reg, val);
|
||||
|
||||
if (reg >= 0x7800 && reg < 0x78a0
|
||||
@ -1309,10 +1350,10 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
|
||||
DO_DELAY(regWrites);
|
||||
}
|
||||
|
||||
if (AR_SREV_9280_20_OR_LATER(ah))
|
||||
if (AR_SREV_9280(ah))
|
||||
REG_WRITE_ARRAY(&ahp->ah_iniModesRxGain, modesIndex, regWrites);
|
||||
|
||||
if (AR_SREV_9280_20_OR_LATER(ah))
|
||||
if (AR_SREV_9280(ah))
|
||||
REG_WRITE_ARRAY(&ahp->ah_iniModesTxGain, modesIndex, regWrites);
|
||||
|
||||
for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
|
||||
@ -1585,10 +1626,15 @@ static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
|
||||
enum ath9k_ht_macmode macmode)
|
||||
{
|
||||
u32 phymode;
|
||||
u32 enableDacFifo = 0;
|
||||
struct ath_hal_5416 *ahp = AH5416(ah);
|
||||
|
||||
if (AR_SREV_9285_10_OR_LATER(ah))
|
||||
enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
|
||||
AR_PHY_FC_ENABLE_DAC_FIFO);
|
||||
|
||||
phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
|
||||
| AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH;
|
||||
| AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo;
|
||||
|
||||
if (IS_CHAN_HT40(chan)) {
|
||||
phymode |= AR_PHY_FC_DYN2040_EN;
|
||||
@ -2771,11 +2817,14 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
|
||||
if (ah->ah_config.pcie_waen) {
|
||||
REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
|
||||
} else {
|
||||
if (AR_SREV_9280(ah))
|
||||
REG_WRITE(ah, AR_WA, 0x0040073f);
|
||||
if (AR_SREV_9285(ah))
|
||||
REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
|
||||
else if (AR_SREV_9280(ah))
|
||||
REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT);
|
||||
else
|
||||
REG_WRITE(ah, AR_WA, 0x0000073f);
|
||||
REG_WRITE(ah, AR_WA, AR_WA_DEFAULT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**********************/
|
||||
@ -3326,7 +3375,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
|
||||
else
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
|
||||
|
||||
if (AR_SREV_9280(ah))
|
||||
if (AR_SREV_9280(ah) || AR_SREV_9285(ah))
|
||||
pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
|
||||
else
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
|
||||
@ -3346,9 +3395,9 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
|
||||
pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
|
||||
|
||||
pCap->num_antcfg_5ghz =
|
||||
ath9k_hw_get_num_ant_config(ah, IEEE80211_BAND_5GHZ);
|
||||
ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
|
||||
pCap->num_antcfg_2ghz =
|
||||
ath9k_hw_get_num_ant_config(ah, IEEE80211_BAND_2GHZ);
|
||||
ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -448,6 +448,17 @@ struct ar5416Stats {
|
||||
#define AR5416_EEP_TXGAIN_ORIGINAL 0
|
||||
#define AR5416_EEP_TXGAIN_HIGH_POWER 1
|
||||
|
||||
#define AR5416_EEP4K_START_LOC 64
|
||||
#define AR5416_EEP4K_NUM_2G_CAL_PIERS 3
|
||||
#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
|
||||
#define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS 3
|
||||
#define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS 3
|
||||
#define AR5416_EEP4K_NUM_CTLS 12
|
||||
#define AR5416_EEP4K_NUM_BAND_EDGES 4
|
||||
#define AR5416_EEP4K_NUM_PD_GAINS 2
|
||||
#define AR5416_EEP4K_PD_GAINS_IN_MASK 4
|
||||
#define AR5416_EEP4K_PD_GAIN_ICEPTS 5
|
||||
#define AR5416_EEP4K_MAX_CHAINS 1
|
||||
|
||||
enum eeprom_param {
|
||||
EEP_NFTHRESH_5,
|
||||
@ -484,6 +495,11 @@ enum ar5416_rates {
|
||||
Ar5416RateSize
|
||||
};
|
||||
|
||||
enum ath9k_hal_freq_band {
|
||||
ATH9K_HAL_FREQ_BAND_5GHZ = 0,
|
||||
ATH9K_HAL_FREQ_BAND_2GHZ = 1
|
||||
};
|
||||
|
||||
struct base_eep_header {
|
||||
u16 length;
|
||||
u16 checksum;
|
||||
@ -507,6 +523,25 @@ struct base_eep_header {
|
||||
u8 futureBase_3[25];
|
||||
} __packed;
|
||||
|
||||
struct base_eep_header_4k {
|
||||
u16 length;
|
||||
u16 checksum;
|
||||
u16 version;
|
||||
u8 opCapFlags;
|
||||
u8 eepMisc;
|
||||
u16 regDmn[2];
|
||||
u8 macAddr[6];
|
||||
u8 rxMask;
|
||||
u8 txMask;
|
||||
u16 rfSilent;
|
||||
u16 blueToothOptions;
|
||||
u16 deviceCap;
|
||||
u32 binBuildNumber;
|
||||
u8 deviceType;
|
||||
u8 futureBase[1];
|
||||
} __packed;
|
||||
|
||||
|
||||
struct spur_chan {
|
||||
u16 spurChan;
|
||||
u8 spurRangeLow;
|
||||
@ -559,11 +594,58 @@ struct modal_eep_header {
|
||||
struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
|
||||
} __packed;
|
||||
|
||||
struct modal_eep_4k_header {
|
||||
u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
|
||||
u32 antCtrlCommon;
|
||||
u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
|
||||
u8 switchSettling;
|
||||
u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
|
||||
u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
|
||||
u8 adcDesiredSize;
|
||||
u8 pgaDesiredSize;
|
||||
u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
|
||||
u8 txEndToXpaOff;
|
||||
u8 txEndToRxOn;
|
||||
u8 txFrameToXpaOn;
|
||||
u8 thresh62;
|
||||
u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
|
||||
u8 xpdGain;
|
||||
u8 xpd;
|
||||
u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS];
|
||||
u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
|
||||
u8 pdGainOverlap;
|
||||
u8 ob_01;
|
||||
u8 db1_01;
|
||||
u8 xpaBiasLvl;
|
||||
u8 txFrameToDataStart;
|
||||
u8 txFrameToPaOn;
|
||||
u8 ht40PowerIncForPdadc;
|
||||
u8 bswAtten[AR5416_EEP4K_MAX_CHAINS];
|
||||
u8 bswMargin[AR5416_EEP4K_MAX_CHAINS];
|
||||
u8 swSettleHt40;
|
||||
u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS];
|
||||
u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
|
||||
u8 db2_01;
|
||||
u8 version;
|
||||
u16 ob_234;
|
||||
u16 db1_234;
|
||||
u16 db2_234;
|
||||
u8 futureModal[4];
|
||||
|
||||
struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
|
||||
} __packed;
|
||||
|
||||
|
||||
struct cal_data_per_freq {
|
||||
u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
|
||||
u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
|
||||
} __packed;
|
||||
|
||||
struct cal_data_per_freq_4k {
|
||||
u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
|
||||
u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
|
||||
} __packed;
|
||||
|
||||
struct cal_target_power_leg {
|
||||
u8 bChannel;
|
||||
u8 tPow2x[4];
|
||||
@ -574,6 +656,7 @@ struct cal_target_power_ht {
|
||||
u8 tPow2x[8];
|
||||
} __packed;
|
||||
|
||||
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
struct cal_ctl_edges {
|
||||
u8 bChannel;
|
||||
@ -588,10 +671,15 @@ struct cal_ctl_edges {
|
||||
|
||||
struct cal_ctl_data {
|
||||
struct cal_ctl_edges
|
||||
ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
|
||||
ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
|
||||
} __packed;
|
||||
|
||||
struct ar5416_eeprom {
|
||||
struct cal_ctl_data_4k {
|
||||
struct cal_ctl_edges
|
||||
ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
|
||||
} __packed;
|
||||
|
||||
struct ar5416_eeprom_def {
|
||||
struct base_eep_header baseEepHeader;
|
||||
u8 custData[64];
|
||||
struct modal_eep_header modalHeader[2];
|
||||
@ -620,6 +708,26 @@ struct ar5416_eeprom {
|
||||
u8 padding;
|
||||
} __packed;
|
||||
|
||||
struct ar5416_eeprom_4k {
|
||||
struct base_eep_header_4k baseEepHeader;
|
||||
u8 custData[20];
|
||||
struct modal_eep_4k_header modalHeader;
|
||||
u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
|
||||
struct cal_data_per_freq_4k
|
||||
calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
|
||||
struct cal_target_power_leg
|
||||
calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
|
||||
struct cal_target_power_leg
|
||||
calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
|
||||
struct cal_target_power_ht
|
||||
calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
|
||||
struct cal_target_power_ht
|
||||
calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
|
||||
u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
|
||||
struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
|
||||
u8 padding;
|
||||
} __packed;
|
||||
|
||||
struct ar5416IniArray {
|
||||
u32 *ia_array;
|
||||
u32 ia_rows;
|
||||
@ -687,9 +795,22 @@ struct hal_cal_list {
|
||||
struct hal_cal_list *calNext;
|
||||
};
|
||||
|
||||
/*
|
||||
* Enum to indentify the eeprom mappings
|
||||
*/
|
||||
enum hal_eep_map {
|
||||
EEP_MAP_DEFAULT = 0x0,
|
||||
EEP_MAP_4KBITS,
|
||||
EEP_MAP_MAX
|
||||
};
|
||||
|
||||
|
||||
struct ath_hal_5416 {
|
||||
struct ath_hal ah;
|
||||
struct ar5416_eeprom ah_eeprom;
|
||||
union {
|
||||
struct ar5416_eeprom_def def;
|
||||
struct ar5416_eeprom_4k map4k;
|
||||
} ah_eeprom;
|
||||
struct ar5416Stats ah_stats;
|
||||
struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES];
|
||||
void __iomem *ah_cal_mem;
|
||||
@ -813,6 +934,8 @@ struct ath_hal_5416 {
|
||||
struct ar5416IniArray ah_iniModesAdditional;
|
||||
struct ar5416IniArray ah_iniModesRxGain;
|
||||
struct ar5416IniArray ah_iniModesTxGain;
|
||||
/* To indicate EEPROM mapping used */
|
||||
enum hal_eep_map ah_eep_map;
|
||||
};
|
||||
#define AH5416(_ah) ((struct ath_hal_5416 *)(_ah))
|
||||
|
||||
@ -854,13 +977,20 @@ struct ath_hal_5416 {
|
||||
(AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
|
||||
#define AR5416_EEPROM_MAX 0xae0
|
||||
#define ar5416_get_eep_ver(_ahp) \
|
||||
(((_ahp)->ah_eeprom.baseEepHeader.version >> 12) & 0xF)
|
||||
(((_ahp)->ah_eeprom.def.baseEepHeader.version >> 12) & 0xF)
|
||||
#define ar5416_get_eep_rev(_ahp) \
|
||||
(((_ahp)->ah_eeprom.baseEepHeader.version) & 0xFFF)
|
||||
(((_ahp)->ah_eeprom.def.baseEepHeader.version) & 0xFFF)
|
||||
#define ar5416_get_ntxchains(_txchainmask) \
|
||||
(((_txchainmask >> 2) & 1) + \
|
||||
((_txchainmask >> 1) & 1) + (_txchainmask & 1))
|
||||
|
||||
/* EEPROM 4K bit map definations */
|
||||
#define ar5416_get_eep4k_ver(_ahp) \
|
||||
(((_ahp)->ah_eeprom.map4k.baseEepHeader.version >> 12) & 0xF)
|
||||
#define ar5416_get_eep4k_rev(_ahp) \
|
||||
(((_ahp)->ah_eeprom.map4k.baseEepHeader.version) & 0xFFF)
|
||||
|
||||
|
||||
#ifdef __BIG_ENDIAN
|
||||
#define AR5416_EEPROM_MAGIC 0x5aa5
|
||||
#else
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -916,12 +916,11 @@ void ath9k_hw_rxena(struct ath_hal *ah)
|
||||
|
||||
void ath9k_hw_startpcureceive(struct ath_hal *ah)
|
||||
{
|
||||
REG_CLR_BIT(ah, AR_DIAG_SW,
|
||||
(AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
|
||||
|
||||
ath9k_enable_mib_counters(ah);
|
||||
|
||||
ath9k_ani_reset(ah);
|
||||
|
||||
REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
|
||||
}
|
||||
|
||||
void ath9k_hw_stoppcurecv(struct ath_hal *ah)
|
||||
|
@ -34,6 +34,7 @@ static struct pci_device_id ath_pci_id_table[] __devinitdata = {
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@ -60,7 +61,8 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz)
|
||||
|
||||
static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
|
||||
{
|
||||
sc->sc_curmode = mode;
|
||||
if (!sc->sc_curaid)
|
||||
sc->cur_rate_table = sc->hw_rate_table[mode];
|
||||
/*
|
||||
* All protection frames are transmited at 2Mb/s for
|
||||
* 11g, otherwise at 1Mb/s.
|
||||
@ -346,7 +348,7 @@ static void ath_ani_calibrate(unsigned long data)
|
||||
* don't calibrate when we're scanning.
|
||||
* we are most likely not on our home channel.
|
||||
*/
|
||||
if (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC)
|
||||
if (sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC)
|
||||
return;
|
||||
|
||||
/* Long calibration runs independently of short calibration. */
|
||||
@ -485,9 +487,9 @@ static void ath9k_tasklet(unsigned long data)
|
||||
|
||||
if (status &
|
||||
(ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
|
||||
spin_lock_bh(&sc->sc_rxflushlock);
|
||||
spin_lock_bh(&sc->rx.rxflushlock);
|
||||
ath_rx_tasklet(sc, 0);
|
||||
spin_unlock_bh(&sc->sc_rxflushlock);
|
||||
spin_unlock_bh(&sc->rx.rxflushlock);
|
||||
}
|
||||
/* XXX: optimize this */
|
||||
if (status & ATH9K_INT_TX)
|
||||
@ -597,6 +599,8 @@ static irqreturn_t ath_isr(int irq, void *dev)
|
||||
}
|
||||
} while (0);
|
||||
|
||||
ath_debug_stat_interrupt(sc, status);
|
||||
|
||||
if (sched) {
|
||||
/* turn off every interrupt except SWBA */
|
||||
ath9k_hw_set_interrupts(ah, (sc->sc_imask & ATH9K_INT_SWBA));
|
||||
@ -1302,7 +1306,7 @@ static void ath_detach(struct ath_softc *sc)
|
||||
/* cleanup tx queues */
|
||||
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
|
||||
if (ATH_TXQ_SETUP(sc, i))
|
||||
ath_tx_cleanupq(sc, &sc->sc_txq[i]);
|
||||
ath_tx_cleanupq(sc, &sc->tx.txq[i]);
|
||||
|
||||
ath9k_hw_detach(sc->sc_ah);
|
||||
ath9k_exit_debug(sc);
|
||||
@ -1393,15 +1397,15 @@ static int ath_init(u16 devid, struct ath_softc *sc)
|
||||
* priority. Note that the hal handles reseting
|
||||
* these queues at the needed time.
|
||||
*/
|
||||
sc->sc_bhalq = ath_beaconq_setup(ah);
|
||||
if (sc->sc_bhalq == -1) {
|
||||
sc->beacon.beaconq = ath_beaconq_setup(ah);
|
||||
if (sc->beacon.beaconq == -1) {
|
||||
DPRINTF(sc, ATH_DBG_FATAL,
|
||||
"Unable to setup a beacon xmit queue\n");
|
||||
error = -EIO;
|
||||
goto bad2;
|
||||
}
|
||||
sc->sc_cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
|
||||
if (sc->sc_cabq == NULL) {
|
||||
sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
|
||||
if (sc->beacon.cabq == NULL) {
|
||||
DPRINTF(sc, ATH_DBG_FATAL,
|
||||
"Unable to setup CAB xmit queue\n");
|
||||
error = -EIO;
|
||||
@ -1411,8 +1415,8 @@ static int ath_init(u16 devid, struct ath_softc *sc)
|
||||
sc->sc_config.cabqReadytime = ATH_CABQ_READY_TIME;
|
||||
ath_cabq_update(sc);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sc->sc_haltype2q); i++)
|
||||
sc->sc_haltype2q[i] = -1;
|
||||
for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
|
||||
sc->tx.hwq_map[i] = -1;
|
||||
|
||||
/* Setup data queues */
|
||||
/* NB: ensure BK queue is the lowest priority h/w queue */
|
||||
@ -1492,7 +1496,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
|
||||
sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask;
|
||||
|
||||
ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
|
||||
sc->sc_defant = ath9k_hw_getdefantenna(ah);
|
||||
sc->rx.defant = ath9k_hw_getdefantenna(ah);
|
||||
|
||||
ath9k_hw_getmac(ah, sc->sc_myaddr);
|
||||
if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) {
|
||||
@ -1501,20 +1505,15 @@ static int ath_init(u16 devid, struct ath_softc *sc)
|
||||
ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
|
||||
}
|
||||
|
||||
sc->sc_slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */
|
||||
sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */
|
||||
|
||||
/* initialize beacon slots */
|
||||
for (i = 0; i < ARRAY_SIZE(sc->sc_bslot); i++)
|
||||
sc->sc_bslot[i] = ATH_IF_ID_ANY;
|
||||
for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
|
||||
sc->beacon.bslot[i] = ATH_IF_ID_ANY;
|
||||
|
||||
/* save MISC configurations */
|
||||
sc->sc_config.swBeaconProcess = 1;
|
||||
|
||||
#ifdef CONFIG_SLOW_ANT_DIV
|
||||
/* range is 40 - 255, we use something in the middle */
|
||||
ath_slow_ant_div_init(&sc->sc_antdiv, sc, 0x127);
|
||||
#endif
|
||||
|
||||
/* setup channels and rates */
|
||||
|
||||
sc->sbands[IEEE80211_BAND_2GHZ].channels =
|
||||
@ -1536,7 +1535,7 @@ bad2:
|
||||
/* cleanup tx queues */
|
||||
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
|
||||
if (ATH_TXQ_SETUP(sc, i))
|
||||
ath_tx_cleanupq(sc, &sc->sc_txq[i]);
|
||||
ath_tx_cleanupq(sc, &sc->tx.txq[i]);
|
||||
bad:
|
||||
if (ah)
|
||||
ath9k_hw_detach(ah);
|
||||
@ -1674,9 +1673,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
|
||||
int i;
|
||||
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
|
||||
if (ATH_TXQ_SETUP(sc, i)) {
|
||||
spin_lock_bh(&sc->sc_txq[i].axq_lock);
|
||||
ath_txq_schedule(sc, &sc->sc_txq[i]);
|
||||
spin_unlock_bh(&sc->sc_txq[i].axq_lock);
|
||||
spin_lock_bh(&sc->tx.txq[i].axq_lock);
|
||||
ath_txq_schedule(sc, &sc->tx.txq[i]);
|
||||
spin_unlock_bh(&sc->tx.txq[i].axq_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1811,19 +1810,19 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
|
||||
|
||||
switch (queue) {
|
||||
case 0:
|
||||
qnum = sc->sc_haltype2q[ATH9K_WME_AC_VO];
|
||||
qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO];
|
||||
break;
|
||||
case 1:
|
||||
qnum = sc->sc_haltype2q[ATH9K_WME_AC_VI];
|
||||
qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI];
|
||||
break;
|
||||
case 2:
|
||||
qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE];
|
||||
qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
|
||||
break;
|
||||
case 3:
|
||||
qnum = sc->sc_haltype2q[ATH9K_WME_AC_BK];
|
||||
qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK];
|
||||
break;
|
||||
default:
|
||||
qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE];
|
||||
qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1994,9 +1993,9 @@ static int ath9k_tx(struct ieee80211_hw *hw,
|
||||
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
|
||||
sc->seq_no += 0x10;
|
||||
sc->tx.seq_no += 0x10;
|
||||
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
|
||||
hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
|
||||
hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
|
||||
}
|
||||
|
||||
/* Add the padding after the header if this is not already done */
|
||||
@ -2050,7 +2049,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
|
||||
ath_stoprecv(sc);
|
||||
ath9k_hw_phy_disable(sc->sc_ah);
|
||||
} else
|
||||
sc->sc_rxlink = NULL;
|
||||
sc->rx.rxlink = NULL;
|
||||
|
||||
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
|
||||
if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
|
||||
@ -2126,16 +2125,13 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
|
||||
|
||||
DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n");
|
||||
|
||||
#ifdef CONFIG_SLOW_ANT_DIV
|
||||
ath_slow_ant_div_stop(&sc->sc_antdiv);
|
||||
#endif
|
||||
/* Stop ANI */
|
||||
del_timer_sync(&sc->sc_ani.timer);
|
||||
|
||||
/* Reclaim beacon resources */
|
||||
if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP ||
|
||||
sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) {
|
||||
ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
|
||||
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
|
||||
ath_beacon_return(sc, avp);
|
||||
}
|
||||
|
||||
@ -2254,7 +2250,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
|
||||
* causes reconfiguration; we may be called
|
||||
* with beacon transmission active.
|
||||
*/
|
||||
ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
|
||||
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
|
||||
|
||||
error = ath_beacon_alloc(sc, 0);
|
||||
if (error != 0)
|
||||
@ -2300,7 +2296,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
|
||||
changed_flags &= SUPPORTED_FILTERS;
|
||||
*total_flags &= SUPPORTED_FILTERS;
|
||||
|
||||
sc->rx_filter = *total_flags;
|
||||
sc->rx.rxfilter = *total_flags;
|
||||
rfilt = ath_calcrxfilter(sc);
|
||||
ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
|
||||
|
||||
@ -2309,7 +2305,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
|
||||
ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0);
|
||||
}
|
||||
|
||||
DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx_filter);
|
||||
DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter);
|
||||
}
|
||||
|
||||
static void ath9k_sta_notify(struct ieee80211_hw *hw,
|
||||
@ -2491,11 +2487,6 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath9k_no_fragmentation(struct ieee80211_hw *hw, u32 value)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static struct ieee80211_ops ath9k_ops = {
|
||||
.tx = ath9k_tx,
|
||||
.start = ath9k_start,
|
||||
@ -2512,7 +2503,6 @@ static struct ieee80211_ops ath9k_ops = {
|
||||
.get_tsf = ath9k_get_tsf,
|
||||
.reset_tsf = ath9k_reset_tsf,
|
||||
.ampdu_action = ath9k_ampdu_action,
|
||||
.set_frag_threshold = ath9k_no_fragmentation,
|
||||
};
|
||||
|
||||
static struct {
|
||||
|
@ -50,6 +50,9 @@ bool ath9k_hw_init_rf(struct ath_hal *ah,
|
||||
#define AR_PHY_FC_SHORT_GI_40 0x00000080
|
||||
#define AR_PHY_FC_WALSH 0x00000100
|
||||
#define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200
|
||||
#define AR_PHY_FC_ENABLE_DAC_FIFO 0x00000800
|
||||
|
||||
#define AR_PHY_TEST2 0x9808
|
||||
|
||||
#define AR_PHY_TIMING2 0x9810
|
||||
#define AR_PHY_TIMING3 0x9814
|
||||
@ -100,6 +103,8 @@ bool ath9k_hw_init_rf(struct ath_hal *ah,
|
||||
#define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF
|
||||
#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0
|
||||
|
||||
#define AR_PHY_TSTDAC_CONST 0x983c
|
||||
|
||||
#define AR_PHY_SETTLING 0x9844
|
||||
#define AR_PHY_SETTLING_SWITCH 0x00003F80
|
||||
#define AR_PHY_SETTLING_SWITCH_S 7
|
||||
|
@ -817,7 +817,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
|
||||
struct ath_rate_table *rate_table;
|
||||
struct ieee80211_tx_rate *rates = tx_info->control.rates;
|
||||
|
||||
rate_table = sc->hw_rate_table[sc->sc_curmode];
|
||||
rate_table = sc->cur_rate_table;
|
||||
rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, 1,
|
||||
is_probe, is_retry);
|
||||
nrix = rix;
|
||||
@ -874,10 +874,9 @@ static void ath_rc_ratefind(struct ath_softc *sc,
|
||||
* So, set fourth rate in series to be same as third one for
|
||||
* above conditions.
|
||||
*/
|
||||
if ((sc->sc_curmode == ATH9K_MODE_11NG_HT20) ||
|
||||
(sc->sc_curmode == ATH9K_MODE_11NG_HT40PLUS) ||
|
||||
(sc->sc_curmode == ATH9K_MODE_11NG_HT40MINUS)) {
|
||||
u8 dot11rate = rate_table->info[rix].dot11rate;
|
||||
if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
|
||||
(sc->hw->conf.ht.enabled)) {
|
||||
u8 dot11rate = rate_table->info[rix].dot11rate;
|
||||
u8 phy = rate_table->info[rix].phy;
|
||||
if (i == 4 &&
|
||||
((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
|
||||
@ -1094,7 +1093,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
|
||||
int rate;
|
||||
u8 last_per;
|
||||
bool state_change = false;
|
||||
struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode];
|
||||
struct ath_rate_table *rate_table = sc->cur_rate_table;
|
||||
int size = ath_rc_priv->rate_table_size;
|
||||
|
||||
if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
|
||||
@ -1254,7 +1253,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
|
||||
u8 flags;
|
||||
u32 i = 0, rix;
|
||||
|
||||
rate_table = sc->hw_rate_table[sc->sc_curmode];
|
||||
rate_table = sc->cur_rate_table;
|
||||
|
||||
/*
|
||||
* If the first rate is not the final index, there
|
||||
@ -1354,8 +1353,8 @@ static void ath_rc_init(struct ath_softc *sc,
|
||||
sta->ht_cap.ht_supported,
|
||||
is_cw_40);
|
||||
} else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
|
||||
/* sc_curmode would be set on init through config() */
|
||||
rate_table = sc->hw_rate_table[sc->sc_curmode];
|
||||
/* cur_rate_table would be set on init through config() */
|
||||
rate_table = sc->cur_rate_table;
|
||||
}
|
||||
|
||||
if (!rate_table) {
|
||||
@ -1432,6 +1431,7 @@ static void ath_rc_init(struct ath_softc *sc,
|
||||
ath_rc_priv->max_valid_rate = k;
|
||||
ath_rc_sort_validrates(rate_table, ath_rc_priv);
|
||||
ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
|
||||
sc->cur_rate_table = rate_table;
|
||||
}
|
||||
|
||||
/* Rate Control callbacks */
|
||||
|
@ -41,20 +41,19 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
|
||||
ASSERT(skb != NULL);
|
||||
ds->ds_vdata = skb->data;
|
||||
|
||||
/* setup rx descriptors. The sc_rxbufsize here tells the harware
|
||||
/* setup rx descriptors. The rx.bufsize here tells the harware
|
||||
* how much data it can DMA to us and that we are prepared
|
||||
* to process */
|
||||
ath9k_hw_setuprxdesc(ah,
|
||||
ds,
|
||||
sc->sc_rxbufsize,
|
||||
ath9k_hw_setuprxdesc(ah, ds,
|
||||
sc->rx.bufsize,
|
||||
0);
|
||||
|
||||
if (sc->sc_rxlink == NULL)
|
||||
if (sc->rx.rxlink == NULL)
|
||||
ath9k_hw_putrxbuf(ah, bf->bf_daddr);
|
||||
else
|
||||
*sc->sc_rxlink = bf->bf_daddr;
|
||||
*sc->rx.rxlink = bf->bf_daddr;
|
||||
|
||||
sc->sc_rxlink = &ds->ds_link;
|
||||
sc->rx.rxlink = &ds->ds_link;
|
||||
ath9k_hw_rxena(ah);
|
||||
}
|
||||
|
||||
@ -62,8 +61,8 @@ static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
|
||||
{
|
||||
/* XXX block beacon interrupts */
|
||||
ath9k_hw_setantenna(sc->sc_ah, antenna);
|
||||
sc->sc_defant = antenna;
|
||||
sc->sc_rxotherant = 0;
|
||||
sc->rx.defant = antenna;
|
||||
sc->rx.rxotherant = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -148,7 +147,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
|
||||
struct ieee80211_rx_status *rx_status, bool *decrypt_error,
|
||||
struct ath_softc *sc)
|
||||
{
|
||||
struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode];
|
||||
struct ath_rate_table *rate_table = sc->cur_rate_table;
|
||||
struct ieee80211_hdr *hdr;
|
||||
int ratekbps, rix;
|
||||
u8 ratecode;
|
||||
@ -272,20 +271,20 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
|
||||
int error = 0;
|
||||
|
||||
do {
|
||||
spin_lock_init(&sc->sc_rxflushlock);
|
||||
spin_lock_init(&sc->rx.rxflushlock);
|
||||
sc->sc_flags &= ~SC_OP_RXFLUSH;
|
||||
spin_lock_init(&sc->sc_rxbuflock);
|
||||
spin_lock_init(&sc->rx.rxbuflock);
|
||||
|
||||
sc->sc_rxbufsize = roundup(IEEE80211_MAX_MPDU_LEN,
|
||||
sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
|
||||
min(sc->sc_cachelsz,
|
||||
(u16)64));
|
||||
|
||||
DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
|
||||
sc->sc_cachelsz, sc->sc_rxbufsize);
|
||||
sc->sc_cachelsz, sc->rx.bufsize);
|
||||
|
||||
/* Initialize rx descriptors */
|
||||
|
||||
error = ath_descdma_setup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
|
||||
error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
|
||||
"rx", nbufs, 1);
|
||||
if (error != 0) {
|
||||
DPRINTF(sc, ATH_DBG_FATAL,
|
||||
@ -293,8 +292,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
|
||||
break;
|
||||
}
|
||||
|
||||
list_for_each_entry(bf, &sc->sc_rxbuf, list) {
|
||||
skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize);
|
||||
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
|
||||
skb = ath_rxbuf_alloc(sc, sc->rx.bufsize);
|
||||
if (skb == NULL) {
|
||||
error = -ENOMEM;
|
||||
break;
|
||||
@ -302,8 +301,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
|
||||
|
||||
bf->bf_mpdu = skb;
|
||||
bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data,
|
||||
sc->sc_rxbufsize,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
sc->rx.bufsize,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
if (unlikely(pci_dma_mapping_error(sc->pdev,
|
||||
bf->bf_buf_addr))) {
|
||||
dev_kfree_skb_any(skb);
|
||||
@ -315,7 +314,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
|
||||
}
|
||||
bf->bf_dmacontext = bf->bf_buf_addr;
|
||||
}
|
||||
sc->sc_rxlink = NULL;
|
||||
sc->rx.rxlink = NULL;
|
||||
|
||||
} while (0);
|
||||
|
||||
@ -330,14 +329,14 @@ void ath_rx_cleanup(struct ath_softc *sc)
|
||||
struct sk_buff *skb;
|
||||
struct ath_buf *bf;
|
||||
|
||||
list_for_each_entry(bf, &sc->sc_rxbuf, list) {
|
||||
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
|
||||
skb = bf->bf_mpdu;
|
||||
if (skb)
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
if (sc->sc_rxdma.dd_desc_len != 0)
|
||||
ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf);
|
||||
if (sc->rx.rxdma.dd_desc_len != 0)
|
||||
ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -375,7 +374,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
|
||||
|
||||
/* Can't set HOSTAP into promiscous mode */
|
||||
if (((sc->sc_ah->ah_opmode != NL80211_IFTYPE_AP) &&
|
||||
(sc->rx_filter & FIF_PROMISC_IN_BSS)) ||
|
||||
(sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
|
||||
(sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR)) {
|
||||
rfilt |= ATH9K_RX_FILTER_PROM;
|
||||
/* ??? To prevent from sending ACK */
|
||||
@ -401,25 +400,25 @@ int ath_startrecv(struct ath_softc *sc)
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
struct ath_buf *bf, *tbf;
|
||||
|
||||
spin_lock_bh(&sc->sc_rxbuflock);
|
||||
if (list_empty(&sc->sc_rxbuf))
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
if (list_empty(&sc->rx.rxbuf))
|
||||
goto start_recv;
|
||||
|
||||
sc->sc_rxlink = NULL;
|
||||
list_for_each_entry_safe(bf, tbf, &sc->sc_rxbuf, list) {
|
||||
sc->rx.rxlink = NULL;
|
||||
list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
|
||||
ath_rx_buf_link(sc, bf);
|
||||
}
|
||||
|
||||
/* We could have deleted elements so the list may be empty now */
|
||||
if (list_empty(&sc->sc_rxbuf))
|
||||
if (list_empty(&sc->rx.rxbuf))
|
||||
goto start_recv;
|
||||
|
||||
bf = list_first_entry(&sc->sc_rxbuf, struct ath_buf, list);
|
||||
bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
|
||||
ath9k_hw_putrxbuf(ah, bf->bf_daddr);
|
||||
ath9k_hw_rxena(ah);
|
||||
|
||||
start_recv:
|
||||
spin_unlock_bh(&sc->sc_rxbuflock);
|
||||
spin_unlock_bh(&sc->rx.rxbuflock);
|
||||
ath_opmode_init(sc);
|
||||
ath9k_hw_startpcureceive(ah);
|
||||
|
||||
@ -435,25 +434,25 @@ bool ath_stoprecv(struct ath_softc *sc)
|
||||
ath9k_hw_setrxfilter(ah, 0);
|
||||
stopped = ath9k_hw_stopdmarecv(ah);
|
||||
mdelay(3); /* 3ms is long enough for 1 frame */
|
||||
sc->sc_rxlink = NULL;
|
||||
sc->rx.rxlink = NULL;
|
||||
|
||||
return stopped;
|
||||
}
|
||||
|
||||
void ath_flushrecv(struct ath_softc *sc)
|
||||
{
|
||||
spin_lock_bh(&sc->sc_rxflushlock);
|
||||
spin_lock_bh(&sc->rx.rxflushlock);
|
||||
sc->sc_flags |= SC_OP_RXFLUSH;
|
||||
ath_rx_tasklet(sc, 1);
|
||||
sc->sc_flags &= ~SC_OP_RXFLUSH;
|
||||
spin_unlock_bh(&sc->sc_rxflushlock);
|
||||
spin_unlock_bh(&sc->rx.rxflushlock);
|
||||
}
|
||||
|
||||
int ath_rx_tasklet(struct ath_softc *sc, int flush)
|
||||
{
|
||||
#define PA2DESC(_sc, _pa) \
|
||||
((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
|
||||
((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
|
||||
((struct ath_desc *)((caddr_t)(_sc)->rx.rxdma.dd_desc + \
|
||||
((_pa) - (_sc)->rx.rxdma.dd_desc_paddr)))
|
||||
|
||||
struct ath_buf *bf;
|
||||
struct ath_desc *ds;
|
||||
@ -465,19 +464,19 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
|
||||
bool decrypt_error = false;
|
||||
u8 keyix;
|
||||
|
||||
spin_lock_bh(&sc->sc_rxbuflock);
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
do {
|
||||
/* If handling rx interrupt and flush is in progress => exit */
|
||||
if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
|
||||
break;
|
||||
|
||||
if (list_empty(&sc->sc_rxbuf)) {
|
||||
sc->sc_rxlink = NULL;
|
||||
if (list_empty(&sc->rx.rxbuf)) {
|
||||
sc->rx.rxlink = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
bf = list_first_entry(&sc->sc_rxbuf, struct ath_buf, list);
|
||||
bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
|
||||
ds = bf->bf_desc;
|
||||
|
||||
/*
|
||||
@ -499,8 +498,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
|
||||
struct ath_buf *tbf;
|
||||
struct ath_desc *tds;
|
||||
|
||||
if (list_is_last(&bf->list, &sc->sc_rxbuf)) {
|
||||
sc->sc_rxlink = NULL;
|
||||
if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
|
||||
sc->rx.rxlink = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -540,7 +539,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
|
||||
goto requeue;
|
||||
|
||||
/* The status portion of the descriptor could get corrupted. */
|
||||
if (sc->sc_rxbufsize < ds->ds_rxstat.rs_datalen)
|
||||
if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen)
|
||||
goto requeue;
|
||||
|
||||
if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc))
|
||||
@ -548,21 +547,21 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
|
||||
|
||||
/* Ensure we always have an skb to requeue once we are done
|
||||
* processing the current buffer's skb */
|
||||
requeue_skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize);
|
||||
requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize);
|
||||
|
||||
/* If there is no memory we ignore the current RX'd frame,
|
||||
* tell hardware it can give us a new frame using the old
|
||||
* skb and put it at the tail of the sc->sc_rxbuf list for
|
||||
* skb and put it at the tail of the sc->rx.rxbuf list for
|
||||
* processing. */
|
||||
if (!requeue_skb)
|
||||
goto requeue;
|
||||
|
||||
pci_dma_sync_single_for_cpu(sc->pdev,
|
||||
bf->bf_buf_addr,
|
||||
sc->sc_rxbufsize,
|
||||
/* Sync and unmap the frame */
|
||||
pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr,
|
||||
sc->rx.bufsize,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
pci_unmap_single(sc->pdev, bf->bf_buf_addr,
|
||||
sc->sc_rxbufsize,
|
||||
sc->rx.bufsize,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
|
||||
skb_put(skb, ds->ds_rxstat.rs_datalen);
|
||||
@ -572,8 +571,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
|
||||
|
||||
if (hdrlen & 3) {
|
||||
padsize = hdrlen % 4;
|
||||
/* The MAC header is padded to have 32-bit boundary if the
|
||||
* packet payload is non-zero. The general calculation for
|
||||
* padsize would take into account odd header lengths:
|
||||
* padsize = (4 - hdrlen % 4) % 4; However, since only
|
||||
* even-length headers are used, padding can only be 0 or 2
|
||||
* bytes and we can optimize this a bit. In addition, we must
|
||||
* not try to remove padding from short control frames that do
|
||||
* not have payload. */
|
||||
padsize = hdrlen & 3;
|
||||
if (padsize && hdrlen >= 24) {
|
||||
memmove(skb->data + padsize, skb->data, hdrlen);
|
||||
skb_pull(skb, padsize);
|
||||
}
|
||||
@ -596,7 +603,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
|
||||
/* We will now give hardware our shiny new allocated skb */
|
||||
bf->bf_mpdu = requeue_skb;
|
||||
bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data,
|
||||
sc->sc_rxbufsize,
|
||||
sc->rx.bufsize,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
if (unlikely(pci_dma_mapping_error(sc->pdev,
|
||||
bf->bf_buf_addr))) {
|
||||
@ -612,18 +619,18 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
|
||||
* change the default rx antenna if rx diversity chooses the
|
||||
* other antenna 3 times in a row.
|
||||
*/
|
||||
if (sc->sc_defant != ds->ds_rxstat.rs_antenna) {
|
||||
if (++sc->sc_rxotherant >= 3)
|
||||
if (sc->rx.defant != ds->ds_rxstat.rs_antenna) {
|
||||
if (++sc->rx.rxotherant >= 3)
|
||||
ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna);
|
||||
} else {
|
||||
sc->sc_rxotherant = 0;
|
||||
sc->rx.rxotherant = 0;
|
||||
}
|
||||
requeue:
|
||||
list_move_tail(&bf->list, &sc->sc_rxbuf);
|
||||
list_move_tail(&bf->list, &sc->rx.rxbuf);
|
||||
ath_rx_buf_link(sc, bf);
|
||||
} while (1);
|
||||
|
||||
spin_unlock_bh(&sc->sc_rxbuflock);
|
||||
spin_unlock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
return 0;
|
||||
#undef PA2DESC
|
||||
|
@ -671,7 +671,11 @@
|
||||
#define AR_RC_APB 0x00000002
|
||||
#define AR_RC_HOSTIF 0x00000100
|
||||
|
||||
#define AR_WA 0x4004
|
||||
#define AR_WA 0x4004
|
||||
#define AR9285_WA_DEFAULT 0x004a05cb
|
||||
#define AR9280_WA_DEFAULT 0x0040073f
|
||||
#define AR_WA_DEFAULT 0x0000073f
|
||||
|
||||
|
||||
#define AR_PM_STATE 0x4008
|
||||
#define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000
|
||||
@ -738,6 +742,8 @@
|
||||
#define AR_SREV_REVISION_9280_21 2
|
||||
#define AR_SREV_VERSION_9285 0xC0
|
||||
#define AR_SREV_REVISION_9285_10 0
|
||||
#define AR_SREV_REVISION_9285_11 1
|
||||
#define AR_SREV_REVISION_9285_12 2
|
||||
|
||||
#define AR_SREV_9100_OR_LATER(_ah) \
|
||||
(((_ah)->ah_macVersion >= AR_SREV_VERSION_5416_PCIE))
|
||||
@ -768,6 +774,16 @@
|
||||
#define AR_SREV_9285(_ah) (((_ah)->ah_macVersion == AR_SREV_VERSION_9285))
|
||||
#define AR_SREV_9285_10_OR_LATER(_ah) \
|
||||
(((_ah)->ah_macVersion >= AR_SREV_VERSION_9285))
|
||||
#define AR_SREV_9285_11(_ah) \
|
||||
(AR_SREV_9280(ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9285_11))
|
||||
#define AR_SREV_9285_11_OR_LATER(_ah) \
|
||||
(((_ah)->ah_macVersion > AR_SREV_VERSION_9285) || \
|
||||
(AR_SREV_9285(ah) && ((_ah)->ah_macRev >= AR_SREV_REVISION_9285_11)))
|
||||
#define AR_SREV_9285_12(_ah) \
|
||||
(AR_SREV_9280(ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9285_12))
|
||||
#define AR_SREV_9285_12_OR_LATER(_ah) \
|
||||
(((_ah)->ah_macVersion > AR_SREV_VERSION_9285) || \
|
||||
(AR_SREV_9285(ah) && ((_ah)->ah_macRev >= AR_SREV_REVISION_9285_12)))
|
||||
|
||||
#define AR_RADIO_SREV_MAJOR 0xf0
|
||||
#define AR_RAD5133_SREV_MAJOR 0xc0
|
||||
@ -1017,6 +1033,97 @@ enum {
|
||||
#define AR_AN_SYNTH9_REFDIVA 0xf8000000
|
||||
#define AR_AN_SYNTH9_REFDIVA_S 27
|
||||
|
||||
#define AR9285_AN_RF2G1 0x7820
|
||||
#define AR9285_AN_RF2G1_ENPACAL 0x00000800
|
||||
#define AR9285_AN_RF2G1_ENPACAL_S 11
|
||||
#define AR9285_AN_RF2G1_PDPADRV1 0x02000000
|
||||
#define AR9285_AN_RF2G1_PDPADRV1_S 25
|
||||
#define AR9285_AN_RF2G1_PDPADRV2 0x01000000
|
||||
#define AR9285_AN_RF2G1_PDPADRV2_S 24
|
||||
#define AR9285_AN_RF2G1_PDPAOUT 0x00800000
|
||||
#define AR9285_AN_RF2G1_PDPAOUT_S 23
|
||||
|
||||
|
||||
#define AR9285_AN_RF2G2 0x7824
|
||||
#define AR9285_AN_RF2G2_OFFCAL 0x00001000
|
||||
#define AR9285_AN_RF2G2_OFFCAL_S 12
|
||||
|
||||
#define AR9285_AN_RF2G3 0x7828
|
||||
#define AR9285_AN_RF2G3_PDVCCOMP 0x02000000
|
||||
#define AR9285_AN_RF2G3_PDVCCOMP_S 25
|
||||
#define AR9285_AN_RF2G3_OB_0 0x00E00000
|
||||
#define AR9285_AN_RF2G3_OB_0_S 21
|
||||
#define AR9285_AN_RF2G3_OB_1 0x001C0000
|
||||
#define AR9285_AN_RF2G3_OB_1_S 18
|
||||
#define AR9285_AN_RF2G3_OB_2 0x00038000
|
||||
#define AR9285_AN_RF2G3_OB_2_S 15
|
||||
#define AR9285_AN_RF2G3_OB_3 0x00007000
|
||||
#define AR9285_AN_RF2G3_OB_3_S 12
|
||||
#define AR9285_AN_RF2G3_OB_4 0x00000E00
|
||||
#define AR9285_AN_RF2G3_OB_4_S 9
|
||||
|
||||
#define AR9285_AN_RF2G3_DB1_0 0x000001C0
|
||||
#define AR9285_AN_RF2G3_DB1_0_S 6
|
||||
#define AR9285_AN_RF2G3_DB1_1 0x00000038
|
||||
#define AR9285_AN_RF2G3_DB1_1_S 3
|
||||
#define AR9285_AN_RF2G3_DB1_2 0x00000007
|
||||
#define AR9285_AN_RF2G3_DB1_2_S 0
|
||||
#define AR9285_AN_RF2G4 0x782C
|
||||
#define AR9285_AN_RF2G4_DB1_3 0xE0000000
|
||||
#define AR9285_AN_RF2G4_DB1_3_S 29
|
||||
#define AR9285_AN_RF2G4_DB1_4 0x1C000000
|
||||
#define AR9285_AN_RF2G4_DB1_4_S 26
|
||||
|
||||
#define AR9285_AN_RF2G4_DB2_0 0x03800000
|
||||
#define AR9285_AN_RF2G4_DB2_0_S 23
|
||||
#define AR9285_AN_RF2G4_DB2_1 0x00700000
|
||||
#define AR9285_AN_RF2G4_DB2_1_S 20
|
||||
#define AR9285_AN_RF2G4_DB2_2 0x000E0000
|
||||
#define AR9285_AN_RF2G4_DB2_2_S 17
|
||||
#define AR9285_AN_RF2G4_DB2_3 0x0001C000
|
||||
#define AR9285_AN_RF2G4_DB2_3_S 14
|
||||
#define AR9285_AN_RF2G4_DB2_4 0x00003800
|
||||
#define AR9285_AN_RF2G4_DB2_4_S 11
|
||||
|
||||
#define AR9285_AN_RF2G6 0x7834
|
||||
#define AR9285_AN_RF2G6_CCOMP 0x00007800
|
||||
#define AR9285_AN_RF2G6_CCOMP_S 11
|
||||
#define AR9285_AN_RF2G6_OFFS 0x03f00000
|
||||
#define AR9285_AN_RF2G6_OFFS_S 20
|
||||
|
||||
#define AR9285_AN_RF2G7 0x7838
|
||||
#define AR9285_AN_RF2G7_PWDDB 0x00000002
|
||||
#define AR9285_AN_RF2G7_PWDDB_S 1
|
||||
#define AR9285_AN_RF2G7_PADRVGN2TAB0 0xE0000000
|
||||
#define AR9285_AN_RF2G7_PADRVGN2TAB0_S 29
|
||||
|
||||
#define AR9285_AN_RF2G8 0x783C
|
||||
#define AR9285_AN_RF2G8_PADRVGN2TAB0 0x0001C000
|
||||
#define AR9285_AN_RF2G8_PADRVGN2TAB0_S 14
|
||||
|
||||
|
||||
#define AR9285_AN_RF2G9 0x7840
|
||||
#define AR9285_AN_RXTXBB1 0x7854
|
||||
#define AR9285_AN_RXTXBB1_PDRXTXBB1 0x00000020
|
||||
#define AR9285_AN_RXTXBB1_PDRXTXBB1_S 5
|
||||
#define AR9285_AN_RXTXBB1_PDV2I 0x00000080
|
||||
#define AR9285_AN_RXTXBB1_PDV2I_S 7
|
||||
#define AR9285_AN_RXTXBB1_PDDACIF 0x00000100
|
||||
#define AR9285_AN_RXTXBB1_PDDACIF_S 8
|
||||
#define AR9285_AN_RXTXBB1_SPARE9 0x00000001
|
||||
#define AR9285_AN_RXTXBB1_SPARE9_S 0
|
||||
|
||||
#define AR9285_AN_TOP2 0x7868
|
||||
|
||||
#define AR9285_AN_TOP3 0x786c
|
||||
#define AR9285_AN_TOP3_XPABIAS_LVL 0x0000000C
|
||||
#define AR9285_AN_TOP3_XPABIAS_LVL_S 2
|
||||
#define AR9285_AN_TOP3_PWDDAC 0x00800000
|
||||
#define AR9285_AN_TOP3_PWDDAC_S 23
|
||||
|
||||
#define AR9285_AN_TOP4 0x7870
|
||||
#define AR9285_AN_TOP4_DEFAULT 0x10142c00
|
||||
|
||||
#define AR_STA_ID0 0x8000
|
||||
#define AR_STA_ID1 0x8004
|
||||
#define AR_STA_ID1_SADH_MASK 0x0000FFFF
|
||||
|
@ -286,17 +286,17 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_buf *bf = NULL;
|
||||
|
||||
spin_lock_bh(&sc->sc_txbuflock);
|
||||
spin_lock_bh(&sc->tx.txbuflock);
|
||||
|
||||
if (unlikely(list_empty(&sc->sc_txbuf))) {
|
||||
spin_unlock_bh(&sc->sc_txbuflock);
|
||||
if (unlikely(list_empty(&sc->tx.txbuf))) {
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bf = list_first_entry(&sc->sc_txbuf, struct ath_buf, list);
|
||||
bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
|
||||
list_del(&bf->list);
|
||||
|
||||
spin_unlock_bh(&sc->sc_txbuflock);
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
|
||||
return bf;
|
||||
}
|
||||
@ -310,6 +310,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc,
|
||||
{
|
||||
struct sk_buff *skb = bf->bf_mpdu;
|
||||
struct ath_xmit_status tx_status;
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Set retry information.
|
||||
@ -340,9 +341,9 @@ static void ath_tx_complete_buf(struct ath_softc *sc,
|
||||
/*
|
||||
* Return the list of ath_buf of this mpdu to free queue
|
||||
*/
|
||||
spin_lock_bh(&sc->sc_txbuflock);
|
||||
list_splice_tail_init(bf_q, &sc->sc_txbuf);
|
||||
spin_unlock_bh(&sc->sc_txbuflock);
|
||||
spin_lock_irqsave(&sc->tx.txbuflock, flags);
|
||||
list_splice_tail_init(bf_q, &sc->tx.txbuf);
|
||||
spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -383,7 +384,7 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
|
||||
|
||||
static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
|
||||
{
|
||||
struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];
|
||||
struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
|
||||
@ -396,7 +397,7 @@ static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
|
||||
|
||||
void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
|
||||
{
|
||||
struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];
|
||||
struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
|
||||
|
||||
ASSERT(tid->paused > 0);
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
@ -493,7 +494,7 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
|
||||
static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
|
||||
int width, int half_gi, bool shortPreamble)
|
||||
{
|
||||
struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode];
|
||||
struct ath_rate_table *rate_table = sc->cur_rate_table;
|
||||
u32 nbits, nsymbits, duration, nsymbols;
|
||||
u8 rc;
|
||||
int streams, pktlen;
|
||||
@ -557,7 +558,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
|
||||
}
|
||||
|
||||
/* get the cix for the lowest valid rix */
|
||||
rt = sc->hw_rate_table[sc->sc_curmode];
|
||||
rt = sc->cur_rate_table;
|
||||
for (i = 3; i >= 0; i--) {
|
||||
if (rates[i].count && (rates[i].idx >= 0)) {
|
||||
rix = rates[i].idx;
|
||||
@ -685,7 +686,7 @@ static int ath_tx_send_normal(struct ath_softc *sc,
|
||||
|
||||
static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
|
||||
{
|
||||
struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];
|
||||
struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
|
||||
struct ath_buf *bf;
|
||||
struct list_head bf_head;
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
@ -860,12 +861,12 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
|
||||
struct ath_buf *tbf;
|
||||
|
||||
/* allocate new descriptor */
|
||||
spin_lock_bh(&sc->sc_txbuflock);
|
||||
ASSERT(!list_empty((&sc->sc_txbuf)));
|
||||
tbf = list_first_entry(&sc->sc_txbuf,
|
||||
spin_lock_bh(&sc->tx.txbuflock);
|
||||
ASSERT(!list_empty((&sc->tx.txbuf)));
|
||||
tbf = list_first_entry(&sc->tx.txbuf,
|
||||
struct ath_buf, list);
|
||||
list_del(&tbf->list);
|
||||
spin_unlock_bh(&sc->sc_txbuflock);
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
|
||||
ATH_TXBUF_RESET(tbf);
|
||||
|
||||
@ -1057,9 +1058,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||
|
||||
if (bf_held) {
|
||||
list_del(&bf_held->list);
|
||||
spin_lock_bh(&sc->sc_txbuflock);
|
||||
list_add_tail(&bf_held->list, &sc->sc_txbuf);
|
||||
spin_unlock_bh(&sc->sc_txbuflock);
|
||||
spin_lock_bh(&sc->tx.txbuflock);
|
||||
list_add_tail(&bf_held->list, &sc->tx.txbuf);
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
}
|
||||
|
||||
if (!bf_isampdu(bf)) {
|
||||
@ -1128,11 +1129,11 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
|
||||
if (!(sc->sc_flags & SC_OP_INVALID)) {
|
||||
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
|
||||
if (ATH_TXQ_SETUP(sc, i)) {
|
||||
ath_tx_stopdma(sc, &sc->sc_txq[i]);
|
||||
ath_tx_stopdma(sc, &sc->tx.txq[i]);
|
||||
/* The TxDMA may not really be stopped.
|
||||
* Double check the hal tx pending count */
|
||||
npend += ath9k_hw_numtxpending(ah,
|
||||
sc->sc_txq[i].axq_qnum);
|
||||
sc->tx.txq[i].axq_qnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1157,7 +1158,7 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
|
||||
|
||||
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
|
||||
if (ATH_TXQ_SETUP(sc, i))
|
||||
ath_tx_draintxq(sc, &sc->sc_txq[i], retry_tx);
|
||||
ath_tx_draintxq(sc, &sc->tx.txq[i], retry_tx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1240,7 +1241,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
|
||||
struct ath_buf *bf,
|
||||
struct ath_atx_tid *tid)
|
||||
{
|
||||
struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode];
|
||||
struct ath_rate_table *rate_table = sc->cur_rate_table;
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_tx_info *tx_info;
|
||||
struct ieee80211_tx_rate *rates;
|
||||
@ -1308,7 +1309,7 @@ static int ath_compute_num_delims(struct ath_softc *sc,
|
||||
struct ath_buf *bf,
|
||||
u16 frmlen)
|
||||
{
|
||||
struct ath_rate_table *rt = sc->hw_rate_table[sc->sc_curmode];
|
||||
struct ath_rate_table *rt = sc->cur_rate_table;
|
||||
struct sk_buff *skb = bf->bf_mpdu;
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
u32 nsymbits, nsymbols, mpdudensity;
|
||||
@ -1819,9 +1820,9 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
|
||||
}
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
spin_lock_bh(&sc->sc_txbuflock);
|
||||
list_add_tail(&bf->list, &sc->sc_txbuf);
|
||||
spin_unlock_bh(&sc->sc_txbuflock);
|
||||
spin_lock_bh(&sc->tx.txbuflock);
|
||||
list_add_tail(&bf->list, &sc->tx.txbuf);
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -1838,10 +1839,10 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
|
||||
int error = 0;
|
||||
|
||||
do {
|
||||
spin_lock_init(&sc->sc_txbuflock);
|
||||
spin_lock_init(&sc->tx.txbuflock);
|
||||
|
||||
/* Setup tx descriptors */
|
||||
error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf,
|
||||
error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
|
||||
"tx", nbufs, 1);
|
||||
if (error != 0) {
|
||||
DPRINTF(sc, ATH_DBG_FATAL,
|
||||
@ -1851,7 +1852,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
|
||||
}
|
||||
|
||||
/* XXX allocate beacon state together with vap */
|
||||
error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf,
|
||||
error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
|
||||
"beacon", ATH_BCBUF, 1);
|
||||
if (error != 0) {
|
||||
DPRINTF(sc, ATH_DBG_FATAL,
|
||||
@ -1873,12 +1874,12 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
|
||||
int ath_tx_cleanup(struct ath_softc *sc)
|
||||
{
|
||||
/* cleanup beacon descriptors */
|
||||
if (sc->sc_bdma.dd_desc_len != 0)
|
||||
ath_descdma_cleanup(sc, &sc->sc_bdma, &sc->sc_bbuf);
|
||||
if (sc->beacon.bdma.dd_desc_len != 0)
|
||||
ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
|
||||
|
||||
/* cleanup tx descriptors */
|
||||
if (sc->sc_txdma.dd_desc_len != 0)
|
||||
ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf);
|
||||
if (sc->tx.txdma.dd_desc_len != 0)
|
||||
ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1926,15 +1927,15 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
if (qnum >= ARRAY_SIZE(sc->sc_txq)) {
|
||||
if (qnum >= ARRAY_SIZE(sc->tx.txq)) {
|
||||
DPRINTF(sc, ATH_DBG_FATAL,
|
||||
"qnum %u out of range, max %u!\n",
|
||||
qnum, (unsigned int)ARRAY_SIZE(sc->sc_txq));
|
||||
qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq));
|
||||
ath9k_hw_releasetxqueue(ah, qnum);
|
||||
return NULL;
|
||||
}
|
||||
if (!ATH_TXQ_SETUP(sc, qnum)) {
|
||||
struct ath_txq *txq = &sc->sc_txq[qnum];
|
||||
struct ath_txq *txq = &sc->tx.txq[qnum];
|
||||
|
||||
txq->axq_qnum = qnum;
|
||||
txq->axq_link = NULL;
|
||||
@ -1945,9 +1946,9 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
|
||||
txq->axq_aggr_depth = 0;
|
||||
txq->axq_totalqueued = 0;
|
||||
txq->axq_linkbuf = NULL;
|
||||
sc->sc_txqsetup |= 1<<qnum;
|
||||
sc->tx.txqsetup |= 1<<qnum;
|
||||
}
|
||||
return &sc->sc_txq[qnum];
|
||||
return &sc->tx.txq[qnum];
|
||||
}
|
||||
|
||||
/* Reclaim resources for a setup queue */
|
||||
@ -1955,7 +1956,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
|
||||
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
|
||||
{
|
||||
ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
|
||||
sc->sc_txqsetup &= ~(1<<txq->axq_qnum);
|
||||
sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1972,15 +1973,15 @@ int ath_tx_setup(struct ath_softc *sc, int haltype)
|
||||
{
|
||||
struct ath_txq *txq;
|
||||
|
||||
if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) {
|
||||
if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
|
||||
DPRINTF(sc, ATH_DBG_FATAL,
|
||||
"HAL AC %u out of range, max %zu!\n",
|
||||
haltype, ARRAY_SIZE(sc->sc_haltype2q));
|
||||
haltype, ARRAY_SIZE(sc->tx.hwq_map));
|
||||
return 0;
|
||||
}
|
||||
txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
|
||||
if (txq != NULL) {
|
||||
sc->sc_haltype2q[haltype] = txq->axq_qnum;
|
||||
sc->tx.hwq_map[haltype] = txq->axq_qnum;
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
@ -1992,19 +1993,19 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
|
||||
|
||||
switch (qtype) {
|
||||
case ATH9K_TX_QUEUE_DATA:
|
||||
if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) {
|
||||
if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
|
||||
DPRINTF(sc, ATH_DBG_FATAL,
|
||||
"HAL AC %u out of range, max %zu!\n",
|
||||
haltype, ARRAY_SIZE(sc->sc_haltype2q));
|
||||
haltype, ARRAY_SIZE(sc->tx.hwq_map));
|
||||
return -1;
|
||||
}
|
||||
qnum = sc->sc_haltype2q[haltype];
|
||||
qnum = sc->tx.hwq_map[haltype];
|
||||
break;
|
||||
case ATH9K_TX_QUEUE_BEACON:
|
||||
qnum = sc->sc_bhalq;
|
||||
qnum = sc->beacon.beaconq;
|
||||
break;
|
||||
case ATH9K_TX_QUEUE_CAB:
|
||||
qnum = sc->sc_cabq->axq_qnum;
|
||||
qnum = sc->beacon.cabq->axq_qnum;
|
||||
break;
|
||||
default:
|
||||
qnum = -1;
|
||||
@ -2020,7 +2021,7 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
|
||||
int qnum;
|
||||
|
||||
qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
|
||||
txq = &sc->sc_txq[qnum];
|
||||
txq = &sc->tx.txq[qnum];
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
|
||||
@ -2049,17 +2050,17 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
|
||||
int error = 0;
|
||||
struct ath9k_tx_queue_info qi;
|
||||
|
||||
if (qnum == sc->sc_bhalq) {
|
||||
if (qnum == sc->beacon.beaconq) {
|
||||
/*
|
||||
* XXX: for beacon queue, we just save the parameter.
|
||||
* It will be picked up by ath_beaconq_config when
|
||||
* it's necessary.
|
||||
*/
|
||||
sc->sc_beacon_qi = *qinfo;
|
||||
sc->beacon.beacon_qi = *qinfo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ASSERT(sc->sc_txq[qnum].axq_qnum == qnum);
|
||||
ASSERT(sc->tx.txq[qnum].axq_qnum == qnum);
|
||||
|
||||
ath9k_hw_get_txq_props(ah, qnum, &qi);
|
||||
qi.tqi_aifs = qinfo->tqi_aifs;
|
||||
@ -2082,7 +2083,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
|
||||
int ath_cabq_update(struct ath_softc *sc)
|
||||
{
|
||||
struct ath9k_tx_queue_info qi;
|
||||
int qnum = sc->sc_cabq->axq_qnum;
|
||||
int qnum = sc->beacon.cabq->axq_qnum;
|
||||
struct ath_beacon_config conf;
|
||||
|
||||
ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
|
||||
@ -2116,7 +2117,7 @@ void ath_tx_tasklet(struct ath_softc *sc)
|
||||
*/
|
||||
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
|
||||
if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
|
||||
ath_tx_processq(sc, &sc->sc_txq[i]);
|
||||
ath_tx_processq(sc, &sc->tx.txq[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2148,9 +2149,9 @@ void ath_tx_draintxq(struct ath_softc *sc,
|
||||
list_del(&bf->list);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
spin_lock_bh(&sc->sc_txbuflock);
|
||||
list_add_tail(&bf->list, &sc->sc_txbuf);
|
||||
spin_unlock_bh(&sc->sc_txbuflock);
|
||||
spin_lock_bh(&sc->tx.txbuflock);
|
||||
list_add_tail(&bf->list, &sc->tx.txbuf);
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2188,9 +2189,9 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx)
|
||||
/* stop beacon queue. The beacon will be freed when
|
||||
* we go to INIT state */
|
||||
if (!(sc->sc_flags & SC_OP_INVALID)) {
|
||||
(void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
|
||||
(void) ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
|
||||
DPRINTF(sc, ATH_DBG_XMIT, "beacon queue %x\n",
|
||||
ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_bhalq));
|
||||
ath9k_hw_gettxbuf(sc->sc_ah, sc->beacon.beaconq));
|
||||
}
|
||||
|
||||
ath_drain_txdataq(sc, retry_tx);
|
||||
@ -2198,12 +2199,12 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx)
|
||||
|
||||
u32 ath_txq_depth(struct ath_softc *sc, int qnum)
|
||||
{
|
||||
return sc->sc_txq[qnum].axq_depth;
|
||||
return sc->tx.txq[qnum].axq_depth;
|
||||
}
|
||||
|
||||
u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum)
|
||||
{
|
||||
return sc->sc_txq[qnum].axq_aggr_depth;
|
||||
return sc->tx.txq[qnum].axq_aggr_depth;
|
||||
}
|
||||
|
||||
bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
|
||||
@ -2284,7 +2285,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid
|
||||
void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid)
|
||||
{
|
||||
struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
|
||||
struct ath_txq *txq = &sc->sc_txq[txtid->ac->qnum];
|
||||
struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
|
||||
struct ath_buf *bf;
|
||||
struct list_head bf_head;
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
@ -2405,7 +2406,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
|
||||
/*
|
||||
* Init per tid tx state
|
||||
*/
|
||||
for (tidno = 0, tid = &an->an_aggr.tx.tid[tidno];
|
||||
for (tidno = 0, tid = &an->tid[tidno];
|
||||
tidno < WME_NUM_TID;
|
||||
tidno++, tid++) {
|
||||
tid->an = an;
|
||||
@ -2419,7 +2420,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
|
||||
INIT_LIST_HEAD(&tid->buf_q);
|
||||
|
||||
acno = TID_TO_WME_AC(tidno);
|
||||
tid->ac = &an->an_aggr.tx.ac[acno];
|
||||
tid->ac = &an->ac[acno];
|
||||
|
||||
/* ADDBA state */
|
||||
tid->state &= ~AGGR_ADDBA_COMPLETE;
|
||||
@ -2430,7 +2431,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
|
||||
/*
|
||||
* Init per ac tx state
|
||||
*/
|
||||
for (acno = 0, ac = &an->an_aggr.tx.ac[acno];
|
||||
for (acno = 0, ac = &an->ac[acno];
|
||||
acno < WME_NUM_AC; acno++, ac++) {
|
||||
ac->sched = false;
|
||||
INIT_LIST_HEAD(&ac->tid_q);
|
||||
@ -2466,7 +2467,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
|
||||
struct ath_txq *txq;
|
||||
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
|
||||
if (ATH_TXQ_SETUP(sc, i)) {
|
||||
txq = &sc->sc_txq[i];
|
||||
txq = &sc->tx.txq[i];
|
||||
|
||||
spin_lock(&txq->axq_lock);
|
||||
|
||||
@ -2511,9 +2512,9 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
|
||||
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
|
||||
sc->seq_no += 0x10;
|
||||
sc->tx.seq_no += 0x10;
|
||||
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
|
||||
hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
|
||||
hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
|
||||
}
|
||||
|
||||
/* Add the padding after the header if this is not already done */
|
||||
@ -2529,7 +2530,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
|
||||
memmove(skb->data, skb->data + padsize, hdrlen);
|
||||
}
|
||||
|
||||
txctl.txq = sc->sc_cabq;
|
||||
txctl.txq = sc->beacon.cabq;
|
||||
|
||||
DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
|
||||
|
||||
|
@ -211,7 +211,7 @@ static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf,
|
||||
struct b43legacy_dfs_file *dfile;
|
||||
ssize_t uninitialized_var(ret);
|
||||
char *buf;
|
||||
const size_t bufsize = 1024 * 128;
|
||||
const size_t bufsize = 1024 * 16; /* 16 KiB buffer */
|
||||
const size_t buforder = get_order(bufsize);
|
||||
int err = 0;
|
||||
|
||||
|
@ -1296,12 +1296,10 @@ void b43legacy_lo_write(struct b43legacy_wldev *dev,
|
||||
/* Sanity check. */
|
||||
if (pair->low < -8 || pair->low > 8 ||
|
||||
pair->high < -8 || pair->high > 8) {
|
||||
struct b43legacy_phy *phy = &dev->phy;
|
||||
b43legacydbg(dev->wl,
|
||||
"WARNING: Writing invalid LOpair "
|
||||
"(low: %d, high: %d, index: %lu)\n",
|
||||
pair->low, pair->high,
|
||||
(unsigned long)(pair - phy->_lo_pairs));
|
||||
"(low: %d, high: %d)\n",
|
||||
pair->low, pair->high);
|
||||
dump_stack();
|
||||
}
|
||||
#endif
|
||||
|
@ -4345,7 +4345,8 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->status & STATUS_SCANNING) {
|
||||
if (priv->status & STATUS_SCANNING &&
|
||||
missed_count > IPW_MB_SCAN_CANCEL_THRESHOLD) {
|
||||
/* Stop scan to keep fw from getting
|
||||
* stuck (only if we aren't roaming --
|
||||
* otherwise we'll never scan more than 2 or 3
|
||||
@ -6271,6 +6272,20 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
|
||||
}
|
||||
}
|
||||
|
||||
static int ipw_passive_dwell_time(struct ipw_priv *priv)
|
||||
{
|
||||
/* staying on passive channels longer than the DTIM interval during a
|
||||
* scan, while associated, causes the firmware to cancel the scan
|
||||
* without notification. Hence, don't stay on passive channels longer
|
||||
* than the beacon interval.
|
||||
*/
|
||||
if (priv->status & STATUS_ASSOCIATED
|
||||
&& priv->assoc_network->beacon_interval > 10)
|
||||
return priv->assoc_network->beacon_interval - 10;
|
||||
else
|
||||
return 120;
|
||||
}
|
||||
|
||||
static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
|
||||
{
|
||||
struct ipw_scan_request_ext scan;
|
||||
@ -6314,16 +6329,16 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
|
||||
scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
|
||||
|
||||
if (type == IW_SCAN_TYPE_PASSIVE) {
|
||||
IPW_DEBUG_WX("use passive scanning\n");
|
||||
scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN;
|
||||
IPW_DEBUG_WX("use passive scanning\n");
|
||||
scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN;
|
||||
scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
|
||||
cpu_to_le16(120);
|
||||
cpu_to_le16(ipw_passive_dwell_time(priv));
|
||||
ipw_add_scan_channels(priv, &scan, scan_type);
|
||||
goto send_request;
|
||||
}
|
||||
|
||||
/* Use active scan by default. */
|
||||
if (priv->config & CFG_SPEED_SCAN)
|
||||
if (priv->config & CFG_SPEED_SCAN)
|
||||
scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
|
||||
cpu_to_le16(30);
|
||||
else
|
||||
@ -6333,7 +6348,8 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
|
||||
scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
|
||||
cpu_to_le16(20);
|
||||
|
||||
scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
|
||||
scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
|
||||
cpu_to_le16(ipw_passive_dwell_time(priv));
|
||||
scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
|
||||
|
||||
#ifdef CONFIG_IPW2200_MONITOR
|
||||
|
@ -245,6 +245,7 @@ enum connection_manager_assoc_states {
|
||||
#define HOST_NOTIFICATION_S36_MEASUREMENT_REFUSED 31
|
||||
|
||||
#define HOST_NOTIFICATION_STATUS_BEACON_MISSING 1
|
||||
#define IPW_MB_SCAN_CANCEL_THRESHOLD 3
|
||||
#define IPW_MB_ROAMING_THRESHOLD_MIN 1
|
||||
#define IPW_MB_ROAMING_THRESHOLD_DEFAULT 8
|
||||
#define IPW_MB_ROAMING_THRESHOLD_MAX 30
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* Tomas Winkler <tomas.winkler@intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -21,7 +21,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -103,7 +103,6 @@
|
||||
* Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG.
|
||||
*/
|
||||
#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */
|
||||
#define IWL_EEPROM_ACCESS_DELAY 10 /* uSec */
|
||||
|
||||
/*
|
||||
* Regulatory channel usage flags in EEPROM struct iwl_eeprom_channel.flags.
|
||||
@ -321,6 +320,7 @@ struct iwl3945_eeprom {
|
||||
/* RSSR */
|
||||
#define FH_RSSR_CTRL (FH_RSSR_TABLE+0x000)
|
||||
#define FH_RSSR_STATUS (FH_RSSR_TABLE+0x004)
|
||||
#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000)
|
||||
/* TCSR */
|
||||
#define FH_TCSR(_channel) (FH_TCSR_TABLE+(_channel)*0x20)
|
||||
#define FH_TCSR_CONFIG(_channel) (FH_TCSR(_channel)+0x00)
|
||||
|
@ -21,7 +21,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -93,7 +93,7 @@ static inline int _iwl3945_poll_bit(struct iwl3945_priv *priv, u32 addr,
|
||||
do {
|
||||
if ((_iwl3945_read32(priv, addr) & mask) == (bits & mask))
|
||||
return i;
|
||||
mdelay(10);
|
||||
udelay(10);
|
||||
i += 10;
|
||||
} while (i < timeout);
|
||||
|
||||
@ -271,16 +271,7 @@ static inline void iwl3945_write_reg_buf(struct iwl3945_priv *priv,
|
||||
static inline int _iwl3945_poll_direct_bit(struct iwl3945_priv *priv,
|
||||
u32 addr, u32 mask, int timeout)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
if ((_iwl3945_read_direct32(priv, addr) & mask) == mask)
|
||||
return i;
|
||||
mdelay(10);
|
||||
i += 10;
|
||||
} while (i < timeout);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
return _iwl3945_poll_bit(priv, addr, mask, mask, timeout);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWL3945_DEBUG
|
||||
@ -307,6 +298,7 @@ static inline int __iwl3945_poll_direct_bit(const char *f, u32 l,
|
||||
static inline u32 _iwl3945_read_prph(struct iwl3945_priv *priv, u32 reg)
|
||||
{
|
||||
_iwl3945_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
|
||||
rmb();
|
||||
return _iwl3945_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
|
||||
}
|
||||
#ifdef CONFIG_IWL3945_DEBUG
|
||||
@ -328,6 +320,7 @@ static inline void _iwl3945_write_prph(struct iwl3945_priv *priv,
|
||||
{
|
||||
_iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
|
||||
((addr & 0x0000FFFF) | (3 << 24)));
|
||||
wmb();
|
||||
_iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
|
||||
}
|
||||
#ifdef CONFIG_IWL3945_DEBUG
|
||||
@ -389,12 +382,14 @@ static inline void iwl3945_clear_bits_prph(struct iwl3945_priv
|
||||
static inline u32 iwl3945_read_targ_mem(struct iwl3945_priv *priv, u32 addr)
|
||||
{
|
||||
iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
|
||||
rmb();
|
||||
return iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
|
||||
}
|
||||
|
||||
static inline void iwl3945_write_targ_mem(struct iwl3945_priv *priv, u32 addr, u32 val)
|
||||
{
|
||||
iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
|
||||
wmb();
|
||||
iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
|
||||
}
|
||||
|
||||
@ -402,6 +397,7 @@ static inline void iwl3945_write_targ_mem_buf(struct iwl3945_priv *priv, u32 add
|
||||
u32 len, u32 *values)
|
||||
{
|
||||
iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
|
||||
wmb();
|
||||
for (; 0 < len; len -= sizeof(u32), values++)
|
||||
iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -335,10 +335,11 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
|
||||
|
||||
}
|
||||
|
||||
static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband,
|
||||
static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
|
||||
struct ieee80211_sta *sta, void *priv_sta)
|
||||
{
|
||||
struct iwl3945_rs_sta *rs_sta = priv_sta;
|
||||
struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
|
||||
int i;
|
||||
|
||||
IWL_DEBUG_RATE("enter\n");
|
||||
@ -348,16 +349,21 @@ static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband,
|
||||
* previous packets? Need to have IEEE 802.1X auth succeed immediately
|
||||
* after assoc.. */
|
||||
|
||||
for (i = IWL_RATE_COUNT - 1; i >= 0; i--) {
|
||||
for (i = sband->n_bitrates - 1; i >= 0; i--) {
|
||||
if (sta->supp_rates[sband->band] & (1 << i)) {
|
||||
rs_sta->last_txrate_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
priv->sta_supp_rates = sta->supp_rates[sband->band];
|
||||
/* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */
|
||||
if (sband->band == IEEE80211_BAND_5GHZ)
|
||||
if (sband->band == IEEE80211_BAND_5GHZ) {
|
||||
rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
|
||||
priv->sta_supp_rates = priv->sta_supp_rates <<
|
||||
IWL_FIRST_OFDM_RATE;
|
||||
}
|
||||
|
||||
|
||||
IWL_DEBUG_RATE("leave\n");
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -277,12 +277,14 @@ int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate)
|
||||
else if (rate == IWL_RATE_6M_INDEX)
|
||||
next_rate = IWL_RATE_6M_INDEX;
|
||||
break;
|
||||
/* XXX cannot be invoked in current mac80211 so not a regression
|
||||
case MODE_IEEE80211B:
|
||||
if (rate == IWL_RATE_11M_INDEX_TABLE)
|
||||
next_rate = IWL_RATE_5M_INDEX_TABLE;
|
||||
case IEEE80211_BAND_2GHZ:
|
||||
if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
|
||||
iwl3945_is_associated(priv)) {
|
||||
if (rate == IWL_RATE_11M_INDEX)
|
||||
next_rate = IWL_RATE_5M_INDEX;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1101,9 +1103,8 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
|
||||
CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
|
||||
|
||||
iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
|
||||
rc = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
rc = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
if (rc < 0) {
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
IWL_DEBUG_INFO("Failed to init the card\n");
|
||||
@ -1284,8 +1285,7 @@ int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv)
|
||||
IWL_DEBUG_INFO("Card in power save, master is already "
|
||||
"stopped\n");
|
||||
else {
|
||||
rc = iwl3945_poll_bit(priv, CSR_RESET,
|
||||
CSR_RESET_REG_FLAG_MASTER_DISABLED,
|
||||
rc = iwl3945_poll_direct_bit(priv, CSR_RESET,
|
||||
CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
|
||||
if (rc < 0) {
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
@ -1310,9 +1310,8 @@ int iwl3945_hw_nic_reset(struct iwl3945_priv *priv)
|
||||
|
||||
iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
|
||||
|
||||
rc = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
|
||||
rc = iwl3945_grab_nic_access(priv);
|
||||
if (!rc) {
|
||||
@ -2309,7 +2308,8 @@ int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv)
|
||||
}
|
||||
|
||||
iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0), 0);
|
||||
rc = iwl3945_poll_direct_bit(priv, FH_RSSR_STATUS, (1 << 24), 1000);
|
||||
rc = iwl3945_poll_direct_bit(priv, FH_RSSR_STATUS,
|
||||
FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
|
||||
if (rc < 0)
|
||||
IWL_ERROR("Can't stop Rx DMA.\n");
|
||||
|
||||
@ -2378,7 +2378,8 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
|
||||
iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0);
|
||||
table[index].try_cnt = priv->retry_rate;
|
||||
prev_index = iwl3945_get_prev_ieee_rate(i);
|
||||
table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index;
|
||||
table[index].next_rate_index =
|
||||
iwl3945_rates[prev_index].table_rs_index;
|
||||
}
|
||||
|
||||
switch (priv->band) {
|
||||
@ -2386,11 +2387,14 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
|
||||
IWL_DEBUG_RATE("Select A mode rate scale\n");
|
||||
/* If one of the following CCK rates is used,
|
||||
* have it fall back to the 6M OFDM rate */
|
||||
for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++)
|
||||
table[i].next_rate_index = iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
|
||||
for (i = IWL_RATE_1M_INDEX_TABLE;
|
||||
i <= IWL_RATE_11M_INDEX_TABLE; i++)
|
||||
table[i].next_rate_index =
|
||||
iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
|
||||
|
||||
/* Don't fall back to CCK rates */
|
||||
table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = IWL_RATE_9M_INDEX_TABLE;
|
||||
table[IWL_RATE_12M_INDEX_TABLE].next_rate_index =
|
||||
IWL_RATE_9M_INDEX_TABLE;
|
||||
|
||||
/* Don't drop out of OFDM rates */
|
||||
table[IWL_RATE_6M_INDEX_TABLE].next_rate_index =
|
||||
@ -2401,11 +2405,20 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
|
||||
IWL_DEBUG_RATE("Select B/G mode rate scale\n");
|
||||
/* If an OFDM rate is used, have it fall back to the
|
||||
* 1M CCK rates */
|
||||
for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++)
|
||||
table[i].next_rate_index = iwl3945_rates[IWL_FIRST_CCK_RATE].table_rs_index;
|
||||
|
||||
/* CCK shouldn't fall back to OFDM... */
|
||||
table[IWL_RATE_11M_INDEX_TABLE].next_rate_index = IWL_RATE_5M_INDEX_TABLE;
|
||||
if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
|
||||
iwl3945_is_associated(priv)) {
|
||||
|
||||
index = IWL_FIRST_CCK_RATE;
|
||||
for (i = IWL_RATE_6M_INDEX_TABLE;
|
||||
i <= IWL_RATE_54M_INDEX_TABLE; i++)
|
||||
table[i].next_rate_index =
|
||||
iwl3945_rates[index].table_rs_index;
|
||||
|
||||
index = IWL_RATE_11M_INDEX_TABLE;
|
||||
/* CCK shouldn't fall back to OFDM... */
|
||||
table[index].next_rate_index = IWL_RATE_5M_INDEX_TABLE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -476,7 +476,6 @@ union iwl3945_qos_capabity {
|
||||
|
||||
/* QoS structures */
|
||||
struct iwl3945_qos_info {
|
||||
int qos_enable;
|
||||
int qos_active;
|
||||
union iwl3945_qos_capabity qos_cap;
|
||||
struct iwl3945_qosparam_cmd def_qos_parm;
|
||||
@ -810,6 +809,8 @@ struct iwl3945_priv {
|
||||
u16 active_rate;
|
||||
u16 active_rate_basic;
|
||||
|
||||
u32 sta_supp_rates;
|
||||
|
||||
u8 call_post_assoc_from_beacon;
|
||||
/* Rate scaling data */
|
||||
s8 data_retry_limit;
|
||||
@ -906,9 +907,6 @@ struct iwl3945_priv {
|
||||
s8 user_txpower_limit;
|
||||
s8 max_channel_txpower_limit;
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
u32 pm_state[16];
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IWL3945_DEBUG
|
||||
/* debugging info */
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -84,12 +84,6 @@
|
||||
#define IWL_CMD_FIFO_NUM 4
|
||||
#define IWL49_FIRST_AMPDU_QUEUE 7
|
||||
|
||||
/* Tx rates */
|
||||
#define IWL_CCK_RATES 4
|
||||
#define IWL_OFDM_RATES 8
|
||||
#define IWL_HT_RATES 16
|
||||
#define IWL_MAX_RATES (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES)
|
||||
|
||||
/* Time constants */
|
||||
#define SHORT_SLOT_TIME 9
|
||||
#define LONG_SLOT_TIME 20
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -63,7 +63,6 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv);
|
||||
static struct iwl_mod_params iwl4965_mod_params = {
|
||||
.num_of_queues = IWL49_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
|
||||
.enable_qos = 1,
|
||||
.amsdu_size_8K = 1,
|
||||
.restart_fw = 1,
|
||||
/* the rest are 0 by default */
|
||||
@ -352,9 +351,8 @@ static int iwl4965_apm_init(struct iwl_priv *priv)
|
||||
iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
|
||||
|
||||
/* wait for clock stabilization */
|
||||
ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
if (ret < 0) {
|
||||
IWL_DEBUG_INFO("Failed to init the card\n");
|
||||
goto out;
|
||||
@ -436,9 +434,8 @@ static int iwl4965_apm_stop_master(struct iwl_priv *priv)
|
||||
/* set stop master bit */
|
||||
iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
|
||||
|
||||
ret = iwl_poll_bit(priv, CSR_RESET,
|
||||
CSR_RESET_REG_FLAG_MASTER_DISABLED,
|
||||
CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
|
||||
ret = iwl_poll_direct_bit(priv, CSR_RESET,
|
||||
CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
@ -482,11 +479,9 @@ static int iwl4965_apm_reset(struct iwl_priv *priv)
|
||||
|
||||
iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
|
||||
|
||||
ret = iwl_poll_bit(priv, CSR_RESET,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25);
|
||||
|
||||
if (ret)
|
||||
ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
udelay(10);
|
||||
@ -2367,9 +2362,6 @@ MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
|
||||
|
||||
module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, 0444);
|
||||
MODULE_PARM_DESC(queues_num, "number of hw queues.");
|
||||
/* QoS */
|
||||
module_param_named(qos_enable, iwl4965_mod_params.enable_qos, int, 0444);
|
||||
MODULE_PARM_DESC(qos_enable, "enable all QoS functionality");
|
||||
/* 11n */
|
||||
module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, 0444);
|
||||
MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -81,8 +81,7 @@ static int iwl5000_apm_stop_master(struct iwl_priv *priv)
|
||||
/* set stop master bit */
|
||||
iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
|
||||
|
||||
ret = iwl_poll_bit(priv, CSR_RESET,
|
||||
CSR_RESET_REG_FLAG_MASTER_DISABLED,
|
||||
ret = iwl_poll_direct_bit(priv, CSR_RESET,
|
||||
CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@ -120,9 +119,8 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
|
||||
iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
|
||||
|
||||
/* wait for clock stabilization */
|
||||
ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
if (ret < 0) {
|
||||
IWL_DEBUG_INFO("Failed to init the card\n");
|
||||
return ret;
|
||||
@ -189,9 +187,8 @@ static int iwl5000_apm_reset(struct iwl_priv *priv)
|
||||
iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
|
||||
|
||||
/* wait for clock stabilization */
|
||||
ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
if (ret < 0) {
|
||||
IWL_DEBUG_INFO("Failed to init the card\n");
|
||||
goto out;
|
||||
@ -1533,7 +1530,6 @@ static struct iwl_ops iwl5000_ops = {
|
||||
static struct iwl_mod_params iwl50_mod_params = {
|
||||
.num_of_queues = IWL50_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
|
||||
.enable_qos = 1,
|
||||
.amsdu_size_8K = 1,
|
||||
.restart_fw = 1,
|
||||
/* the rest are 0 by default */
|
||||
@ -1631,8 +1627,6 @@ module_param_named(debug50, iwl50_mod_params.debug, int, 0444);
|
||||
MODULE_PARM_DESC(debug50, "50XX debug output mask");
|
||||
module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, 0444);
|
||||
MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series");
|
||||
module_param_named(qos_enable50, iwl50_mod_params.enable_qos, int, 0444);
|
||||
MODULE_PARM_DESC(qos_enable50, "enable all 50XX QoS functionality");
|
||||
module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, 0444);
|
||||
MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality");
|
||||
module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K, int, 0444);
|
||||
|
@ -22,7 +22,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* Tomas Winkler <tomas.winkler@intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -38,7 +38,6 @@
|
||||
#include "iwl-dev.h"
|
||||
#include "iwl-sta.h"
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-helpers.h"
|
||||
|
||||
#define RS_NAME "iwl-agn-rs"
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -83,7 +83,7 @@
|
||||
|
||||
MODULE_DESCRIPTION(DRV_DESCRIPTION);
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_AUTHOR(DRV_COPYRIGHT);
|
||||
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("iwl4965");
|
||||
|
||||
@ -310,7 +310,7 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
|
||||
|
||||
static int iwl_send_bt_config(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl4965_bt_cmd bt_cmd = {
|
||||
struct iwl_bt_cmd bt_cmd = {
|
||||
.flags = 3,
|
||||
.lead_time = 0xAA,
|
||||
.max_kill = 1,
|
||||
@ -319,7 +319,7 @@ static int iwl_send_bt_config(struct iwl_priv *priv)
|
||||
};
|
||||
|
||||
return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
|
||||
sizeof(struct iwl4965_bt_cmd), &bt_cmd);
|
||||
sizeof(struct iwl_bt_cmd), &bt_cmd);
|
||||
}
|
||||
|
||||
static void iwl_clear_free_frames(struct iwl_priv *priv)
|
||||
@ -546,9 +546,6 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
if (!priv->qos_data.qos_enable)
|
||||
return;
|
||||
|
||||
priv->qos_data.def_qos_parm.qos_flags = 0;
|
||||
|
||||
if (priv->qos_data.qos_cap.q_AP.queue_request &&
|
||||
@ -860,7 +857,7 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
|
||||
struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
|
||||
struct iwl4965_csa_notification *csa = &(pkt->u.csa_notif);
|
||||
struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
|
||||
IWL_DEBUG_11H("CSA notif: channel %d, status %d\n",
|
||||
le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
|
||||
rxon->channel = csa->channel;
|
||||
@ -872,7 +869,7 @@ static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
|
||||
{
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
|
||||
struct iwl4965_sleep_notification *sleep = &(pkt->u.sleep_notif);
|
||||
struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
|
||||
IWL_DEBUG_RX("sleep mode: %d, src: %d\n",
|
||||
sleep->pm_sleep_mode, sleep->pm_wakeup_src);
|
||||
#endif
|
||||
@ -942,7 +939,8 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
|
||||
{
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
|
||||
struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status);
|
||||
struct iwl4965_beacon_notif *beacon =
|
||||
(struct iwl4965_beacon_notif *)pkt->u.raw;
|
||||
u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
|
||||
|
||||
IWL_DEBUG_RX("beacon status %x retries %d iss %d "
|
||||
@ -1405,8 +1403,11 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
|
||||
* the driver as well won't allow loading if RFKILL is set
|
||||
* therefore no need to restart the driver from this handler
|
||||
*/
|
||||
if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status))
|
||||
if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) {
|
||||
clear_bit(STATUS_RF_KILL_HW, &priv->status);
|
||||
if (priv->is_open && !iwl_is_rfkill(priv))
|
||||
queue_work(priv->workqueue, &priv->up);
|
||||
}
|
||||
|
||||
handled |= CSR_INT_BIT_RF_KILL;
|
||||
}
|
||||
@ -2963,12 +2964,6 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (priv->iw_mode == NL80211_IFTYPE_AP) { /* APs don't scan */
|
||||
ret = -EIO;
|
||||
IWL_ERROR("ERROR: APs don't scan\n");
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* We don't schedule scan within next_scan_jiffies period.
|
||||
* Avoid scanning during possible EAPOL exchange, return
|
||||
* success immediately.
|
||||
@ -3112,11 +3107,6 @@ static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!priv->qos_data.qos_enable) {
|
||||
priv->qos_data.qos_active = 0;
|
||||
IWL_DEBUG_MAC80211("leave - qos not enabled\n");
|
||||
return 0;
|
||||
}
|
||||
q = AC_NUM - 1 - queue;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* Tomas Winkler <tomas.winkler@intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* Tomas Winkler <tomas.winkler@intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -94,6 +94,7 @@ enum {
|
||||
REPLY_WEPKEY = 0x20,
|
||||
|
||||
/* RX, TX, LEDs */
|
||||
REPLY_3945_RX = 0x1b, /* 3945 only */
|
||||
REPLY_TX = 0x1c,
|
||||
REPLY_RATE_SCALE = 0x47, /* 3945 only */
|
||||
REPLY_LEDS_CMD = 0x48,
|
||||
@ -701,7 +702,7 @@ struct iwl_rxon_time_cmd {
|
||||
/*
|
||||
* REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
|
||||
*/
|
||||
struct iwl4965_channel_switch_cmd {
|
||||
struct iwl_channel_switch_cmd {
|
||||
u8 band;
|
||||
u8 expect_beacon;
|
||||
__le16 channel;
|
||||
@ -714,7 +715,7 @@ struct iwl4965_channel_switch_cmd {
|
||||
/*
|
||||
* CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command)
|
||||
*/
|
||||
struct iwl4965_csa_notification {
|
||||
struct iwl_csa_notification {
|
||||
__le16 band;
|
||||
__le16 channel;
|
||||
__le32 status; /* 0 - OK, 1 - fail */
|
||||
@ -1023,25 +1024,6 @@ struct iwl_wep_cmd {
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
struct iwl4965_rx_frame_stats {
|
||||
u8 phy_count;
|
||||
u8 id;
|
||||
u8 rssi;
|
||||
u8 agc;
|
||||
__le16 sig_avg;
|
||||
__le16 noise_diff;
|
||||
u8 payload[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct iwl4965_rx_frame_hdr {
|
||||
__le16 channel;
|
||||
__le16 phy_flags;
|
||||
u8 reserved1;
|
||||
u8 rate;
|
||||
__le16 len;
|
||||
u8 payload[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define RX_RES_STATUS_NO_CRC32_ERROR cpu_to_le32(1 << 0)
|
||||
#define RX_RES_STATUS_NO_RXE_OVERFLOW cpu_to_le32(1 << 1)
|
||||
|
||||
@ -1072,26 +1054,6 @@ struct iwl4965_rx_frame_hdr {
|
||||
#define RX_MPDU_RES_STATUS_TTAK_OK (1 << 7)
|
||||
#define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800)
|
||||
|
||||
struct iwl4965_rx_frame_end {
|
||||
__le32 status;
|
||||
__le64 timestamp;
|
||||
__le32 beacon_timestamp;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* REPLY_3945_RX = 0x1b (response only, not a command)
|
||||
*
|
||||
* NOTE: DO NOT dereference from casts to this structure
|
||||
* It is provided only for calculating minimum data set size.
|
||||
* The actual offsets of the hdr and end are dynamic based on
|
||||
* stats.phy_count
|
||||
*/
|
||||
struct iwl4965_rx_frame {
|
||||
struct iwl4965_rx_frame_stats stats;
|
||||
struct iwl4965_rx_frame_hdr hdr;
|
||||
struct iwl4965_rx_frame_end end;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Fixed (non-configurable) rx data from phy */
|
||||
|
||||
#define IWL49_RX_RES_PHY_CNT 14
|
||||
@ -1276,7 +1238,7 @@ struct iwl4965_rx_mpdu_res_start {
|
||||
* Used for managing Tx retries when expecting block-acks.
|
||||
* Driver should set these fields to 0.
|
||||
*/
|
||||
struct iwl4965_dram_scratch {
|
||||
struct iwl_dram_scratch {
|
||||
u8 try_cnt; /* Tx attempts */
|
||||
u8 bt_kill_cnt; /* Tx attempts blocked by Bluetooth device */
|
||||
__le16 reserved;
|
||||
@ -1307,9 +1269,9 @@ struct iwl_tx_cmd {
|
||||
|
||||
__le32 tx_flags; /* TX_CMD_FLG_* */
|
||||
|
||||
/* 4965's uCode may modify this field of the Tx command (in host DRAM!).
|
||||
/* uCode may modify this field of the Tx command (in host DRAM!).
|
||||
* Driver must also set dram_lsb_ptr and dram_msb_ptr in this cmd. */
|
||||
struct iwl4965_dram_scratch scratch;
|
||||
struct iwl_dram_scratch scratch;
|
||||
|
||||
/* Rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is cleared. */
|
||||
__le32 rate_n_flags; /* RATE_MCS_* */
|
||||
@ -1917,7 +1879,7 @@ struct iwl_link_quality_cmd {
|
||||
* same platform. Bluetooth device alerts wireless device when it will Tx;
|
||||
* wireless device can delay or kill its own Tx to accommodate.
|
||||
*/
|
||||
struct iwl4965_bt_cmd {
|
||||
struct iwl_bt_cmd {
|
||||
u8 flags;
|
||||
u8 lead_time;
|
||||
u8 max_kill;
|
||||
@ -1943,18 +1905,18 @@ struct iwl4965_bt_cmd {
|
||||
RXON_FILTER_ASSOC_MSK | \
|
||||
RXON_FILTER_BCON_AWARE_MSK)
|
||||
|
||||
struct iwl4965_measure_channel {
|
||||
struct iwl_measure_channel {
|
||||
__le32 duration; /* measurement duration in extended beacon
|
||||
* format */
|
||||
u8 channel; /* channel to measure */
|
||||
u8 type; /* see enum iwl4965_measure_type */
|
||||
u8 type; /* see enum iwl_measure_type */
|
||||
__le16 reserved;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command)
|
||||
*/
|
||||
struct iwl4965_spectrum_cmd {
|
||||
struct iwl_spectrum_cmd {
|
||||
__le16 len; /* number of bytes starting from token */
|
||||
u8 token; /* token id */
|
||||
u8 id; /* measurement id -- 0 or 1 */
|
||||
@ -1967,13 +1929,13 @@ struct iwl4965_spectrum_cmd {
|
||||
__le32 filter_flags; /* rxon filter flags */
|
||||
__le16 channel_count; /* minimum 1, maximum 10 */
|
||||
__le16 reserved3;
|
||||
struct iwl4965_measure_channel channels[10];
|
||||
struct iwl_measure_channel channels[10];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response)
|
||||
*/
|
||||
struct iwl4965_spectrum_resp {
|
||||
struct iwl_spectrum_resp {
|
||||
u8 token;
|
||||
u8 id; /* id of the prior command replaced, or 0xff */
|
||||
__le16 status; /* 0 - command will be handled
|
||||
@ -1981,12 +1943,12 @@ struct iwl4965_spectrum_resp {
|
||||
* measurement) */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum iwl4965_measurement_state {
|
||||
enum iwl_measurement_state {
|
||||
IWL_MEASUREMENT_START = 0,
|
||||
IWL_MEASUREMENT_STOP = 1,
|
||||
};
|
||||
|
||||
enum iwl4965_measurement_status {
|
||||
enum iwl_measurement_status {
|
||||
IWL_MEASUREMENT_OK = 0,
|
||||
IWL_MEASUREMENT_CONCURRENT = 1,
|
||||
IWL_MEASUREMENT_CSA_CONFLICT = 2,
|
||||
@ -1999,18 +1961,18 @@ enum iwl4965_measurement_status {
|
||||
|
||||
#define NUM_ELEMENTS_IN_HISTOGRAM 8
|
||||
|
||||
struct iwl4965_measurement_histogram {
|
||||
struct iwl_measurement_histogram {
|
||||
__le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */
|
||||
__le32 cck[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 1usec counts */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* clear channel availability counters */
|
||||
struct iwl4965_measurement_cca_counters {
|
||||
struct iwl_measurement_cca_counters {
|
||||
__le32 ofdm;
|
||||
__le32 cck;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum iwl4965_measure_type {
|
||||
enum iwl_measure_type {
|
||||
IWL_MEASURE_BASIC = (1 << 0),
|
||||
IWL_MEASURE_CHANNEL_LOAD = (1 << 1),
|
||||
IWL_MEASURE_HISTOGRAM_RPI = (1 << 2),
|
||||
@ -2023,7 +1985,7 @@ enum iwl4965_measure_type {
|
||||
/*
|
||||
* SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command)
|
||||
*/
|
||||
struct iwl4965_spectrum_notification {
|
||||
struct iwl_spectrum_notification {
|
||||
u8 id; /* measurement id -- 0 or 1 */
|
||||
u8 token;
|
||||
u8 channel_index; /* index in measurement channel list */
|
||||
@ -2031,7 +1993,7 @@ struct iwl4965_spectrum_notification {
|
||||
__le32 start_time; /* lower 32-bits of TSF */
|
||||
u8 band; /* 0 - 5.2GHz, 1 - 2.4GHz */
|
||||
u8 channel;
|
||||
u8 type; /* see enum iwl4965_measurement_type */
|
||||
u8 type; /* see enum iwl_measurement_type */
|
||||
u8 reserved1;
|
||||
/* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only only
|
||||
* valid if applicable for measurement type requested. */
|
||||
@ -2041,9 +2003,9 @@ struct iwl4965_spectrum_notification {
|
||||
u8 basic_type; /* 0 - bss, 1 - ofdm preamble, 2 -
|
||||
* unidentified */
|
||||
u8 reserved2[3];
|
||||
struct iwl4965_measurement_histogram histogram;
|
||||
struct iwl_measurement_histogram histogram;
|
||||
__le32 stop_time; /* lower 32-bits of TSF */
|
||||
__le32 status; /* see iwl4965_measurement_status */
|
||||
__le32 status; /* see iwl_measurement_status */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/******************************************************************************
|
||||
@ -2101,7 +2063,7 @@ struct iwl_powertable_cmd {
|
||||
* PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command)
|
||||
* 3945 and 4965 identical.
|
||||
*/
|
||||
struct iwl4965_sleep_notification {
|
||||
struct iwl_sleep_notification {
|
||||
u8 pm_sleep_mode;
|
||||
u8 pm_wakeup_src;
|
||||
__le16 reserved;
|
||||
@ -2131,14 +2093,14 @@ enum {
|
||||
#define CARD_STATE_CMD_DISABLE 0x00 /* Put card to sleep */
|
||||
#define CARD_STATE_CMD_ENABLE 0x01 /* Wake up card */
|
||||
#define CARD_STATE_CMD_HALT 0x02 /* Power down permanently */
|
||||
struct iwl4965_card_state_cmd {
|
||||
struct iwl_card_state_cmd {
|
||||
__le32 status; /* CARD_STATE_CMD_* request new power state */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command)
|
||||
*/
|
||||
struct iwl4965_card_state_notif {
|
||||
struct iwl_card_state_notif {
|
||||
__le32 flags;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
@ -2201,7 +2163,7 @@ struct iwl_scan_channel {
|
||||
* struct iwl_ssid_ie - directed scan network information element
|
||||
*
|
||||
* Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field
|
||||
* in struct iwl4965_scan_channel; each channel may select different ssids from
|
||||
* in struct iwl_scan_channel; each channel may select different ssids from
|
||||
* among the 4 entries. SSID IEs get transmitted in reverse order of entry.
|
||||
*/
|
||||
struct iwl_ssid_ie {
|
||||
@ -2301,7 +2263,7 @@ struct iwl_scan_cmd {
|
||||
* Number of channels in list is specified by channel_count.
|
||||
* Each channel in list is of type:
|
||||
*
|
||||
* struct iwl4965_scan_channel channels[0];
|
||||
* struct iwl_scan_channel channels[0];
|
||||
*
|
||||
* NOTE: Only one band of channels can be scanned per pass. You
|
||||
* must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
|
||||
@ -2612,7 +2574,7 @@ struct iwl_notif_statistics {
|
||||
* then this notification will be sent. */
|
||||
#define CONSECUTIVE_MISSED_BCONS_TH 20
|
||||
|
||||
struct iwl4965_missed_beacon_notif {
|
||||
struct iwl_missed_beacon_notif {
|
||||
__le32 consequtive_missed_beacons;
|
||||
__le32 total_missed_becons;
|
||||
__le32 num_expected_beacons;
|
||||
@ -3049,27 +3011,22 @@ struct iwl_rx_packet {
|
||||
struct iwl_cmd_header hdr;
|
||||
union {
|
||||
struct iwl_alive_resp alive_frame;
|
||||
struct iwl4965_rx_frame rx_frame;
|
||||
struct iwl4965_tx_resp tx_resp;
|
||||
struct iwl4965_spectrum_notification spectrum_notif;
|
||||
struct iwl4965_csa_notification csa_notif;
|
||||
struct iwl_spectrum_notification spectrum_notif;
|
||||
struct iwl_csa_notification csa_notif;
|
||||
struct iwl_error_resp err_resp;
|
||||
struct iwl4965_card_state_notif card_state_notif;
|
||||
struct iwl4965_beacon_notif beacon_status;
|
||||
struct iwl_card_state_notif card_state_notif;
|
||||
struct iwl_add_sta_resp add_sta;
|
||||
struct iwl_rem_sta_resp rem_sta;
|
||||
struct iwl4965_sleep_notification sleep_notif;
|
||||
struct iwl4965_spectrum_resp spectrum;
|
||||
struct iwl_sleep_notification sleep_notif;
|
||||
struct iwl_spectrum_resp spectrum;
|
||||
struct iwl_notif_statistics stats;
|
||||
struct iwl_compressed_ba_resp compressed_ba;
|
||||
struct iwl4965_missed_beacon_notif missed_beacon;
|
||||
struct iwl_missed_beacon_notif missed_beacon;
|
||||
__le32 status;
|
||||
u8 raw[0];
|
||||
} u;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define IWL_RX_FRAME_SIZE (4 + sizeof(struct iwl4965_rx_frame))
|
||||
|
||||
int iwl_agn_check_rxon_cmd(struct iwl_rxon_cmd *rxon);
|
||||
|
||||
#endif /* __iwl_commands_h__ */
|
||||
|
@ -22,7 +22,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* Tomas Winkler <tomas.winkler@intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
|
||||
@ -42,7 +42,7 @@
|
||||
|
||||
MODULE_DESCRIPTION("iwl core");
|
||||
MODULE_VERSION(IWLWIFI_VERSION);
|
||||
MODULE_AUTHOR(DRV_COPYRIGHT);
|
||||
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
|
||||
@ -243,24 +243,25 @@ void iwl_reset_qos(struct iwl_priv *priv)
|
||||
u16 cw_min = 15;
|
||||
u16 cw_max = 1023;
|
||||
u8 aifs = 2;
|
||||
u8 is_legacy = 0;
|
||||
bool is_legacy = false;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
priv->qos_data.qos_active = 0;
|
||||
/* QoS always active in AP and ADHOC mode
|
||||
* In STA mode wait for association
|
||||
*/
|
||||
if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
|
||||
priv->iw_mode == NL80211_IFTYPE_AP)
|
||||
priv->qos_data.qos_active = 1;
|
||||
else
|
||||
priv->qos_data.qos_active = 0;
|
||||
|
||||
if (priv->iw_mode == NL80211_IFTYPE_ADHOC) {
|
||||
if (priv->qos_data.qos_enable)
|
||||
priv->qos_data.qos_active = 1;
|
||||
if (!(priv->active_rate & 0xfff0)) {
|
||||
cw_min = 31;
|
||||
is_legacy = 1;
|
||||
}
|
||||
} else if (priv->iw_mode == NL80211_IFTYPE_AP) {
|
||||
if (priv->qos_data.qos_enable)
|
||||
priv->qos_data.qos_active = 1;
|
||||
} else if (!(priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK)) {
|
||||
/* check for legacy mode */
|
||||
if ((priv->iw_mode == NL80211_IFTYPE_ADHOC &&
|
||||
(priv->active_rate & IWL_OFDM_RATES_MASK) == 0) ||
|
||||
(priv->iw_mode == NL80211_IFTYPE_STATION &&
|
||||
(priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) {
|
||||
cw_min = 31;
|
||||
is_legacy = 1;
|
||||
}
|
||||
@ -890,9 +891,6 @@ int iwl_init_drv(struct iwl_priv *priv)
|
||||
iwl_set_rxon_chain(priv);
|
||||
iwl_init_scan_params(priv);
|
||||
|
||||
if (priv->cfg->mod_params->enable_qos)
|
||||
priv->qos_data.qos_enable = 1;
|
||||
|
||||
iwl_reset_qos(priv);
|
||||
|
||||
priv->qos_data.qos_active = 0;
|
||||
@ -1448,6 +1446,16 @@ int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* when driver is up while rfkill is on, it wont receive
|
||||
* any CARD_STATE_NOTIFICATION notifications so we have to
|
||||
* restart it in here
|
||||
*/
|
||||
if (priv->is_open && !test_bit(STATUS_ALIVE, &priv->status)) {
|
||||
clear_bit(STATUS_RF_KILL_SW, &priv->status);
|
||||
if (!iwl_is_rfkill(priv))
|
||||
queue_work(priv->workqueue, &priv->up);
|
||||
}
|
||||
|
||||
/* If the driver is already loaded, it will receive
|
||||
* CARD_STATE_NOTIFICATION notifications and the handler will
|
||||
* call restart to reload the driver.
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* Tomas Winkler <tomas.winkler@intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -72,6 +72,7 @@ struct iwl_cmd;
|
||||
|
||||
#define IWLWIFI_VERSION "1.3.27k"
|
||||
#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
|
||||
#define DRV_AUTHOR "<ilw@linux.intel.com>"
|
||||
|
||||
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
|
||||
.vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
|
||||
@ -157,7 +158,6 @@ struct iwl_mod_params {
|
||||
int disable_hw_scan; /* def: 0 = use h/w scan */
|
||||
int num_of_queues; /* def: HW dependent */
|
||||
int num_of_ampdu_queues;/* def: HW dependent */
|
||||
int enable_qos; /* def: 1 = use quality of service */
|
||||
int disable_11n; /* def: 0 = disable 11n capabilities */
|
||||
int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
|
||||
int antenna; /* def: 0 = both antennas (use diversity) */
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -216,6 +216,8 @@
|
||||
/* EEPROM REG */
|
||||
#define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001)
|
||||
#define CSR_EEPROM_REG_BIT_CMD (0x00000002)
|
||||
#define CSR_EEPROM_REG_MSK_ADDR (0x0000FFFC)
|
||||
#define CSR_EEPROM_REG_MSK_DATA (0xFFFF0000)
|
||||
|
||||
/* EEPROM GP */
|
||||
#define CSR_EEPROM_GP_VALID_MSK (0x00000006)
|
||||
|
@ -21,7 +21,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -22,7 +22,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* Tomas Winkler <tomas.winkler@intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -186,12 +186,6 @@ struct iwl_channel_info {
|
||||
u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */
|
||||
};
|
||||
|
||||
struct iwl4965_clip_group {
|
||||
/* maximum power level to prevent clipping for each rate, derived by
|
||||
* us from this band's saturation power in EEPROM */
|
||||
const s8 clip_powers[IWL_MAX_RATES];
|
||||
};
|
||||
|
||||
|
||||
#define IWL_TX_FIFO_AC0 0
|
||||
#define IWL_TX_FIFO_AC1 1
|
||||
@ -436,7 +430,6 @@ union iwl_qos_capabity {
|
||||
|
||||
/* QoS structures */
|
||||
struct iwl_qos_info {
|
||||
int qos_enable;
|
||||
int qos_active;
|
||||
union iwl_qos_capabity qos_cap;
|
||||
struct iwl_qosparam_cmd def_qos_parm;
|
||||
@ -505,6 +498,10 @@ struct iwl_sensitivity_ranges {
|
||||
|
||||
#define IWL_FAT_CHANNEL_52 BIT(IEEE80211_BAND_5GHZ)
|
||||
|
||||
#define KELVIN_TO_CELSIUS(x) ((x)-273)
|
||||
#define CELSIUS_TO_KELVIN(x) ((x)+273)
|
||||
|
||||
|
||||
/**
|
||||
* struct iwl_hw_params
|
||||
* @max_txq_num: Max # Tx queues supported
|
||||
@ -553,15 +550,6 @@ struct iwl_hw_params {
|
||||
#define HT_SHORT_GI_40MHZ (1 << 1)
|
||||
|
||||
|
||||
#define IWL_RX_HDR(x) ((struct iwl4965_rx_frame_hdr *)(\
|
||||
x->u.rx_frame.stats.payload + \
|
||||
x->u.rx_frame.stats.phy_count))
|
||||
#define IWL_RX_END(x) ((struct iwl4965_rx_frame_end *)(\
|
||||
IWL_RX_HDR(x)->payload + \
|
||||
le16_to_cpu(IWL_RX_HDR(x)->len)))
|
||||
#define IWL_RX_STATS(x) (&x->u.rx_frame.stats)
|
||||
#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload)
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Functions implemented in core module which are forward declared here
|
||||
@ -792,7 +780,7 @@ struct iwl_priv {
|
||||
|
||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
||||
/* spectrum measurement report caching */
|
||||
struct iwl4965_spectrum_notification measure_report;
|
||||
struct iwl_spectrum_notification measure_report;
|
||||
u8 measurement_status;
|
||||
#endif
|
||||
/* ucode beacon time */
|
||||
@ -803,10 +791,6 @@ struct iwl_priv {
|
||||
struct iwl_channel_info *channel_info; /* channel info array */
|
||||
u8 channel_count; /* # of channels */
|
||||
|
||||
/* each calibration channel group in the EEPROM has a derived
|
||||
* clip setting for each rate. */
|
||||
const struct iwl4965_clip_group clip_groups[5];
|
||||
|
||||
/* thermal calibration */
|
||||
s32 temperature; /* degrees Kelvin */
|
||||
s32 last_temperature;
|
||||
@ -1003,9 +987,6 @@ struct iwl_priv {
|
||||
s8 tx_power_user_lmt;
|
||||
s8 tx_power_channel_lmt;
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
u32 pm_state[16];
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
/* debugging info */
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* Tomas Winkler <tomas.winkler@intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -169,10 +169,9 @@ int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
|
||||
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
|
||||
|
||||
/* See if we got it */
|
||||
ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
|
||||
EEPROM_SEM_TIMEOUT);
|
||||
ret = iwl_poll_direct_bit(priv, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
|
||||
EEPROM_SEM_TIMEOUT);
|
||||
if (ret >= 0) {
|
||||
IWL_DEBUG_IO("Acquired semaphore after %d tries.\n",
|
||||
count+1);
|
||||
@ -210,10 +209,8 @@ int iwl_eeprom_init(struct iwl_priv *priv)
|
||||
{
|
||||
u16 *e;
|
||||
u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
|
||||
u32 r;
|
||||
int sz = priv->cfg->eeprom_size;
|
||||
int ret;
|
||||
int i;
|
||||
u16 addr;
|
||||
|
||||
/* allocate eeprom */
|
||||
@ -241,22 +238,19 @@ int iwl_eeprom_init(struct iwl_priv *priv)
|
||||
|
||||
/* eeprom is an array of 16bit values */
|
||||
for (addr = 0; addr < sz; addr += sizeof(u16)) {
|
||||
_iwl_write32(priv, CSR_EEPROM_REG, addr << 1);
|
||||
_iwl_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
|
||||
u32 r;
|
||||
|
||||
for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT;
|
||||
i += IWL_EEPROM_ACCESS_DELAY) {
|
||||
r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
|
||||
if (r & CSR_EEPROM_REG_READ_VALID_MSK)
|
||||
break;
|
||||
udelay(IWL_EEPROM_ACCESS_DELAY);
|
||||
}
|
||||
_iwl_write32(priv, CSR_EEPROM_REG,
|
||||
CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
|
||||
|
||||
if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
|
||||
ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
|
||||
CSR_EEPROM_REG_READ_VALID_MSK,
|
||||
IWL_EEPROM_ACCESS_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
|
||||
ret = -ETIMEDOUT;
|
||||
goto done;
|
||||
}
|
||||
r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
|
||||
e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
|
||||
}
|
||||
ret = 0;
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* Tomas Winkler <tomas.winkler@intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -68,17 +68,14 @@ struct iwl_priv;
|
||||
/*
|
||||
* EEPROM access time values:
|
||||
*
|
||||
* Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG,
|
||||
* then clearing (with subsequent read/modify/write) CSR_EEPROM_REG bit
|
||||
* CSR_EEPROM_REG_BIT_CMD (0x2).
|
||||
* Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG.
|
||||
* Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1).
|
||||
* When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec.
|
||||
* Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG.
|
||||
*/
|
||||
#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */
|
||||
#define IWL_EEPROM_ACCESS_DELAY 10 /* uSec */
|
||||
|
||||
#define IWL_EEPROM_SEM_TIMEOUT 10 /* milliseconds */
|
||||
#define IWL_EEPROM_SEM_TIMEOUT 10 /* microseconds */
|
||||
#define IWL_EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */
|
||||
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -266,11 +266,8 @@
|
||||
#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000)
|
||||
#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000)
|
||||
|
||||
#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME (0x00008000)
|
||||
|
||||
#define FH_RSCSR_FRAME_SIZE_MSK (0x00003FFF) /* bits 0-13 */
|
||||
|
||||
|
||||
/**
|
||||
* Rx Shared Status Registers (RSSR)
|
||||
*
|
||||
|
@ -22,7 +22,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* Tomas Winkler <tomas.winkler@intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -32,8 +32,6 @@
|
||||
|
||||
#include <linux/ctype.h>
|
||||
|
||||
#define KELVIN_TO_CELSIUS(x) ((x)-273)
|
||||
#define CELSIUS_TO_KELVIN(x) ((x)+273)
|
||||
#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -95,7 +95,7 @@ static inline int _iwl_poll_bit(struct iwl_priv *priv, u32 addr,
|
||||
do {
|
||||
if ((_iwl_read32(priv, addr) & mask) == (bits & mask))
|
||||
return i;
|
||||
mdelay(10);
|
||||
udelay(10);
|
||||
i += 10;
|
||||
} while (i < timeout);
|
||||
|
||||
@ -269,19 +269,10 @@ static inline void iwl_write_reg_buf(struct iwl_priv *priv,
|
||||
}
|
||||
}
|
||||
|
||||
static inline int _iwl_poll_direct_bit(struct iwl_priv *priv,
|
||||
u32 addr, u32 mask, int timeout)
|
||||
static inline int _iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr,
|
||||
u32 mask, int timeout)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
if ((_iwl_read_direct32(priv, addr) & mask) == mask)
|
||||
return i;
|
||||
mdelay(10);
|
||||
i += 10;
|
||||
} while (i < timeout);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
return _iwl_poll_bit(priv, addr, mask, mask, timeout);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
@ -308,6 +299,7 @@ static inline int __iwl_poll_direct_bit(const char *f, u32 l,
|
||||
static inline u32 _iwl_read_prph(struct iwl_priv *priv, u32 reg)
|
||||
{
|
||||
_iwl_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
|
||||
rmb();
|
||||
return _iwl_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
|
||||
}
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
@ -330,6 +322,7 @@ static inline void _iwl_write_prph(struct iwl_priv *priv,
|
||||
{
|
||||
_iwl_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
|
||||
((addr & 0x0000FFFF) | (3 << 24)));
|
||||
wmb();
|
||||
_iwl_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
|
||||
}
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
@ -392,12 +385,14 @@ static inline void iwl_clear_bits_prph(struct iwl_priv
|
||||
static inline u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
|
||||
{
|
||||
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
|
||||
rmb();
|
||||
return iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
|
||||
}
|
||||
|
||||
static inline void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
|
||||
{
|
||||
iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
|
||||
wmb();
|
||||
iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
|
||||
}
|
||||
|
||||
@ -405,6 +400,7 @@ static inline void iwl_write_targ_mem_buf(struct iwl_priv *priv, u32 addr,
|
||||
u32 len, u32 *values)
|
||||
{
|
||||
iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
|
||||
wmb();
|
||||
for (; 0 < len; len -= sizeof(u32), values++)
|
||||
iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -41,7 +41,6 @@
|
||||
#include "iwl-dev.h"
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-io.h"
|
||||
#include "iwl-helpers.h"
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
static const char *led_type_str[] = {
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
|
||||
@ -39,7 +39,6 @@
|
||||
#include "iwl-commands.h"
|
||||
#include "iwl-debug.h"
|
||||
#include "iwl-power.h"
|
||||
#include "iwl-helpers.h"
|
||||
|
||||
/*
|
||||
* Setting power level allow the card to go to sleep when not busy
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
#ifndef __iwl_power_setting_h__
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
#include <linux/kernel.h>
|
||||
@ -34,8 +34,6 @@
|
||||
#include "iwl-eeprom.h"
|
||||
#include "iwl-dev.h"
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-helpers.h"
|
||||
|
||||
|
||||
/* software rf-kill from user */
|
||||
static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
#ifndef __iwl_rf_kill_h__
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -439,7 +439,7 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
|
||||
FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
|
||||
FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
|
||||
FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
|
||||
FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME |
|
||||
FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK |
|
||||
rb_size|
|
||||
(rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
|
||||
(rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
|
||||
@ -467,10 +467,8 @@ int iwl_rxq_stop(struct iwl_priv *priv)
|
||||
|
||||
/* stop Rx DMA */
|
||||
iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
|
||||
ret = iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
|
||||
(1 << 24), 1000);
|
||||
if (ret < 0)
|
||||
IWL_ERROR("Can't stop Rx DMA.\n");
|
||||
iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
|
||||
FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
|
||||
|
||||
iwl_release_nic_access(priv);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
@ -484,7 +482,7 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
|
||||
|
||||
{
|
||||
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
|
||||
struct iwl4965_missed_beacon_notif *missed_beacon;
|
||||
struct iwl_missed_beacon_notif *missed_beacon;
|
||||
|
||||
missed_beacon = &pkt->u.missed_beacon;
|
||||
if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) {
|
||||
@ -622,20 +620,24 @@ static int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm)
|
||||
return sig_qual;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
/* Calc max signal level (dBm) among 3 possible receivers */
|
||||
static inline int iwl_calc_rssi(struct iwl_priv *priv,
|
||||
struct iwl_rx_phy_res *rx_resp)
|
||||
{
|
||||
return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
/**
|
||||
* iwl_dbg_report_frame - dump frame to syslog during debug sessions
|
||||
*
|
||||
* You may hack this function to show different aspects of received frames,
|
||||
* including selective frame dumps.
|
||||
* group100 parameter selects whether to show 1 out of 100 good frames.
|
||||
*
|
||||
* TODO: This was originally written for 3945, need to audit for
|
||||
* proper operation with 4965.
|
||||
* group100 parameter selects whether to show 1 out of 100 good data frames.
|
||||
* All beacon and probe response frames are printed.
|
||||
*/
|
||||
static void iwl_dbg_report_frame(struct iwl_priv *priv,
|
||||
struct iwl_rx_packet *pkt,
|
||||
struct iwl_rx_phy_res *phy_res, u16 length,
|
||||
struct ieee80211_hdr *header, int group100)
|
||||
{
|
||||
u32 to_us;
|
||||
@ -647,20 +649,9 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv,
|
||||
u16 seq_ctl;
|
||||
u16 channel;
|
||||
u16 phy_flags;
|
||||
int rate_sym;
|
||||
u16 length;
|
||||
u16 status;
|
||||
u16 bcn_tmr;
|
||||
u32 rate_n_flags;
|
||||
u32 tsf_low;
|
||||
u64 tsf;
|
||||
u8 rssi;
|
||||
u8 agc;
|
||||
u16 sig_avg;
|
||||
u16 noise_diff;
|
||||
struct iwl4965_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
|
||||
struct iwl4965_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
|
||||
struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt);
|
||||
u8 *data = IWL_RX_DATA(pkt);
|
||||
int rssi;
|
||||
|
||||
if (likely(!(priv->debug_level & IWL_DL_RX)))
|
||||
return;
|
||||
@ -670,22 +661,13 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv,
|
||||
seq_ctl = le16_to_cpu(header->seq_ctrl);
|
||||
|
||||
/* metadata */
|
||||
channel = le16_to_cpu(rx_hdr->channel);
|
||||
phy_flags = le16_to_cpu(rx_hdr->phy_flags);
|
||||
rate_sym = rx_hdr->rate;
|
||||
length = le16_to_cpu(rx_hdr->len);
|
||||
|
||||
/* end-of-frame status and timestamp */
|
||||
status = le32_to_cpu(rx_end->status);
|
||||
bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
|
||||
tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
|
||||
tsf = le64_to_cpu(rx_end->timestamp);
|
||||
channel = le16_to_cpu(phy_res->channel);
|
||||
phy_flags = le16_to_cpu(phy_res->phy_flags);
|
||||
rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
|
||||
|
||||
/* signal statistics */
|
||||
rssi = rx_stats->rssi;
|
||||
agc = rx_stats->agc;
|
||||
sig_avg = le16_to_cpu(rx_stats->sig_avg);
|
||||
noise_diff = le16_to_cpu(rx_stats->noise_diff);
|
||||
rssi = iwl_calc_rssi(priv, phy_res);
|
||||
tsf_low = le64_to_cpu(phy_res->timestamp) & 0x0ffffffff;
|
||||
|
||||
to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
|
||||
|
||||
@ -739,11 +721,13 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv,
|
||||
else
|
||||
title = "Frame";
|
||||
|
||||
rate_idx = iwl_hwrate_to_plcp_idx(rate_sym);
|
||||
if (unlikely(rate_idx == -1))
|
||||
rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
|
||||
if (unlikely((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT))) {
|
||||
bitrate = 0;
|
||||
else
|
||||
WARN_ON_ONCE(1);
|
||||
} else {
|
||||
bitrate = iwl_rates[rate_idx].ieee / 2;
|
||||
}
|
||||
|
||||
/* print frame summary.
|
||||
* MAC addresses show just the last byte (for brevity),
|
||||
@ -755,24 +739,17 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv,
|
||||
length, rssi, channel, bitrate);
|
||||
else {
|
||||
/* src/dst addresses assume managed mode */
|
||||
IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
|
||||
"src=0x%02x, rssi=%u, tim=%lu usec, "
|
||||
IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, src=0x%02x, "
|
||||
"len=%u, rssi=%d, tim=%lu usec, "
|
||||
"phy=0x%02x, chnl=%d\n",
|
||||
title, le16_to_cpu(fc), header->addr1[5],
|
||||
header->addr3[5], rssi,
|
||||
header->addr3[5], length, rssi,
|
||||
tsf_low - priv->scan_start_tsf,
|
||||
phy_flags, channel);
|
||||
}
|
||||
}
|
||||
if (print_dump)
|
||||
iwl_print_hex_dump(priv, IWL_DL_RX, data, length);
|
||||
}
|
||||
#else
|
||||
static inline void iwl_dbg_report_frame(struct iwl_priv *priv,
|
||||
struct iwl_rx_packet *pkt,
|
||||
struct ieee80211_hdr *header,
|
||||
int group100)
|
||||
{
|
||||
iwl_print_hex_dump(priv, IWL_DL_RX, header, length);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -966,14 +943,6 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
|
||||
rxb->skb = NULL;
|
||||
}
|
||||
|
||||
/* Calc max signal level (dBm) among 3 possible receivers */
|
||||
static inline int iwl_calc_rssi(struct iwl_priv *priv,
|
||||
struct iwl_rx_phy_res *rx_resp)
|
||||
{
|
||||
return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
|
||||
}
|
||||
|
||||
|
||||
/* This is necessary only for a number of statistics, see the caller. */
|
||||
static int iwl_is_network_packet(struct iwl_priv *priv,
|
||||
struct ieee80211_hdr *header)
|
||||
@ -1096,9 +1065,10 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
|
||||
priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
|
||||
|
||||
/* Set "1" to report good data frames in groups of 100 */
|
||||
/* FIXME: need to optimize the call: */
|
||||
iwl_dbg_report_frame(priv, pkt, header, 1);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
if (unlikely(priv->debug_level & IWL_DL_RX))
|
||||
iwl_dbg_report_frame(priv, rx_start, len, header, 1);
|
||||
#endif
|
||||
IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
|
||||
rx_status.signal, rx_status.noise, rx_status.signal,
|
||||
(unsigned long long)rx_status.mactime);
|
||||
|
@ -22,7 +22,7 @@
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* Tomas Winkler <tomas.winkler@intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
#include <linux/types.h>
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -178,7 +178,7 @@ static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
|
||||
struct iwl_rx_mem_buffer *rxb)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
|
||||
struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
|
||||
struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
|
||||
|
||||
if (!report->state) {
|
||||
IWL_DEBUG(IWL_DL_11H,
|
||||
|
@ -21,7 +21,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -33,8 +33,6 @@
|
||||
#include "iwl-dev.h"
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-sta.h"
|
||||
#include "iwl-helpers.h"
|
||||
|
||||
|
||||
#define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */
|
||||
#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -628,7 +628,7 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv)
|
||||
iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
|
||||
iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG,
|
||||
FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
|
||||
200);
|
||||
1000);
|
||||
}
|
||||
iwl_release_nic_access(priv);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -69,7 +69,6 @@ static int iwl3945_param_debug; /* def: 0 = minimal debug log messages */
|
||||
static int iwl3945_param_disable; /* def: 0 = enable radio */
|
||||
static int iwl3945_param_antenna; /* def: 0 = both antennas (use diversity) */
|
||||
int iwl3945_param_hwcrypto; /* def: 0 = use software encryption */
|
||||
static int iwl3945_param_qos_enable = 1; /* def: 1 = use quality of service */
|
||||
int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */
|
||||
|
||||
/*
|
||||
@ -94,12 +93,13 @@ int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */
|
||||
|
||||
#define IWLWIFI_VERSION "1.2.26k" VD VS
|
||||
#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
|
||||
#define DRV_AUTHOR "<ilw@linux.intel.com>"
|
||||
#define DRV_VERSION IWLWIFI_VERSION
|
||||
|
||||
|
||||
MODULE_DESCRIPTION(DRV_DESCRIPTION);
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_AUTHOR(DRV_COPYRIGHT);
|
||||
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static const struct ieee80211_supported_band *iwl3945_get_band(
|
||||
@ -1505,10 +1505,8 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
|
||||
{
|
||||
u16 *e = (u16 *)&priv->eeprom;
|
||||
u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP);
|
||||
u32 r;
|
||||
int sz = sizeof(priv->eeprom);
|
||||
int rc;
|
||||
int i;
|
||||
int ret;
|
||||
u16 addr;
|
||||
|
||||
/* The EEPROM structure has several padding buffers within it
|
||||
@ -1523,29 +1521,28 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
|
||||
}
|
||||
|
||||
/* Make sure driver (instead of uCode) is allowed to read EEPROM */
|
||||
rc = iwl3945_eeprom_acquire_semaphore(priv);
|
||||
if (rc < 0) {
|
||||
ret = iwl3945_eeprom_acquire_semaphore(priv);
|
||||
if (ret < 0) {
|
||||
IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* eeprom is an array of 16bit values */
|
||||
for (addr = 0; addr < sz; addr += sizeof(u16)) {
|
||||
_iwl3945_write32(priv, CSR_EEPROM_REG, addr << 1);
|
||||
u32 r;
|
||||
|
||||
_iwl3945_write32(priv, CSR_EEPROM_REG,
|
||||
CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
|
||||
_iwl3945_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
|
||||
|
||||
for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT;
|
||||
i += IWL_EEPROM_ACCESS_DELAY) {
|
||||
r = _iwl3945_read_direct32(priv, CSR_EEPROM_REG);
|
||||
if (r & CSR_EEPROM_REG_READ_VALID_MSK)
|
||||
break;
|
||||
udelay(IWL_EEPROM_ACCESS_DELAY);
|
||||
}
|
||||
|
||||
if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
|
||||
ret = iwl3945_poll_direct_bit(priv, CSR_EEPROM_REG,
|
||||
CSR_EEPROM_REG_READ_VALID_MSK,
|
||||
IWL_EEPROM_ACCESS_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
|
||||
return -ETIMEDOUT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
r = _iwl3945_read_direct32(priv, CSR_EEPROM_REG);
|
||||
e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
|
||||
}
|
||||
|
||||
@ -1693,17 +1690,21 @@ static void iwl3945_reset_qos(struct iwl3945_priv *priv)
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
priv->qos_data.qos_active = 0;
|
||||
|
||||
if (priv->iw_mode == NL80211_IFTYPE_ADHOC) {
|
||||
if (priv->qos_data.qos_enable)
|
||||
priv->qos_data.qos_active = 1;
|
||||
if (!(priv->active_rate & 0xfff0)) {
|
||||
cw_min = 31;
|
||||
is_legacy = 1;
|
||||
}
|
||||
} else if (priv->iw_mode == NL80211_IFTYPE_AP) {
|
||||
if (priv->qos_data.qos_enable)
|
||||
priv->qos_data.qos_active = 1;
|
||||
} else if (!(priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK)) {
|
||||
/* QoS always active in AP and ADHOC mode
|
||||
* In STA mode wait for association
|
||||
*/
|
||||
if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
|
||||
priv->iw_mode == NL80211_IFTYPE_AP)
|
||||
priv->qos_data.qos_active = 1;
|
||||
else
|
||||
priv->qos_data.qos_active = 0;
|
||||
|
||||
|
||||
/* check for legacy mode */
|
||||
if ((priv->iw_mode == NL80211_IFTYPE_ADHOC &&
|
||||
(priv->active_rate & IWL_OFDM_RATES_MASK) == 0) ||
|
||||
(priv->iw_mode == NL80211_IFTYPE_STATION &&
|
||||
(priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) {
|
||||
cw_min = 31;
|
||||
is_legacy = 1;
|
||||
}
|
||||
@ -1775,9 +1776,6 @@ static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
if (!priv->qos_data.qos_enable)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
priv->qos_data.def_qos_parm.qos_flags = 0;
|
||||
|
||||
@ -2103,11 +2101,6 @@ static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
|
||||
|
||||
static int iwl3945_scan_initiate(struct iwl3945_priv *priv)
|
||||
{
|
||||
if (priv->iw_mode == NL80211_IFTYPE_AP) {
|
||||
IWL_ERROR("APs don't scan.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!iwl3945_is_ready_rf(priv)) {
|
||||
IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
|
||||
return -EIO;
|
||||
@ -6976,12 +6969,6 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (priv->iw_mode == NL80211_IFTYPE_AP) { /* APs don't scan */
|
||||
rc = -EIO;
|
||||
IWL_ERROR("ERROR: APs don't scan\n");
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* we don't schedule scan within next_scan_jiffies period */
|
||||
if (priv->next_scan_jiffies &&
|
||||
time_after(priv->next_scan_jiffies, jiffies)) {
|
||||
@ -7095,11 +7082,6 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!priv->qos_data.qos_enable) {
|
||||
priv->qos_data.qos_active = 0;
|
||||
IWL_DEBUG_MAC80211("leave - qos not enabled\n");
|
||||
return 0;
|
||||
}
|
||||
q = AC_NUM - 1 - queue;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
@ -7925,9 +7907,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
|
||||
CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
|
||||
|
||||
iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
|
||||
err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
err = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
if (err < 0) {
|
||||
IWL_DEBUG_INFO("Failed to init the card\n");
|
||||
goto out_remove_sysfs;
|
||||
@ -7980,9 +7961,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
|
||||
|
||||
priv->iw_mode = NL80211_IFTYPE_STATION;
|
||||
|
||||
if (iwl3945_param_qos_enable)
|
||||
priv->qos_data.qos_enable = 1;
|
||||
|
||||
iwl3945_reset_qos(priv);
|
||||
|
||||
priv->qos_data.qos_active = 0;
|
||||
@ -8373,9 +8351,5 @@ MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
|
||||
module_param_named(queues_num, iwl3945_param_queues_num, int, 0444);
|
||||
MODULE_PARM_DESC(queues_num, "number of hw queues.");
|
||||
|
||||
/* QoS */
|
||||
module_param_named(qos_enable, iwl3945_param_qos_enable, int, 0444);
|
||||
MODULE_PARM_DESC(qos_enable, "enable all QoS functionality");
|
||||
|
||||
module_exit(iwl3945_exit);
|
||||
module_init(iwl3945_init);
|
||||
|
@ -245,6 +245,7 @@ enum cmd_mesh_access_opts {
|
||||
CMD_ACT_MESH_GET_ROUTE_EXP,
|
||||
CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
|
||||
CMD_ACT_MESH_GET_AUTOSTART_ENABLED,
|
||||
CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT = 17,
|
||||
};
|
||||
|
||||
/* Define actions and types for CMD_MESH_CONFIG */
|
||||
|
@ -257,6 +257,58 @@ static ssize_t lbs_anycast_set(struct device *dev,
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get function for sysfs attribute prb_rsp_limit
|
||||
*/
|
||||
static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct lbs_private *priv = netdev_priv(to_net_dev(dev));
|
||||
struct cmd_ds_mesh_access mesh_access;
|
||||
int ret;
|
||||
u32 retry_limit;
|
||||
|
||||
memset(&mesh_access, 0, sizeof(mesh_access));
|
||||
mesh_access.data[0] = cpu_to_le32(CMD_ACT_GET);
|
||||
|
||||
ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
|
||||
&mesh_access);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
retry_limit = le32_to_cpu(mesh_access.data[1]);
|
||||
return snprintf(buf, 10, "%d\n", retry_limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set function for sysfs attribute prb_rsp_limit
|
||||
*/
|
||||
static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct lbs_private *priv = netdev_priv(to_net_dev(dev));
|
||||
struct cmd_ds_mesh_access mesh_access;
|
||||
int ret;
|
||||
unsigned long retry_limit;
|
||||
|
||||
memset(&mesh_access, 0, sizeof(mesh_access));
|
||||
mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET);
|
||||
|
||||
if (!strict_strtoul(buf, 10, &retry_limit))
|
||||
return -ENOTSUPP;
|
||||
if (retry_limit > 15)
|
||||
return -ENOTSUPP;
|
||||
|
||||
mesh_access.data[1] = cpu_to_le32(retry_limit);
|
||||
|
||||
ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
|
||||
&mesh_access);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static int lbs_add_rtap(struct lbs_private *priv);
|
||||
static void lbs_remove_rtap(struct lbs_private *priv);
|
||||
static int lbs_add_mesh(struct lbs_private *priv);
|
||||
@ -375,8 +427,16 @@ static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
|
||||
*/
|
||||
static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
|
||||
|
||||
/**
|
||||
* prb_rsp_limit attribute to be exported per mshX interface
|
||||
* through sysfs (/sys/class/net/mshX/prb_rsp_limit)
|
||||
*/
|
||||
static DEVICE_ATTR(prb_rsp_limit, 0644, lbs_prb_rsp_limit_get,
|
||||
lbs_prb_rsp_limit_set);
|
||||
|
||||
static struct attribute *lbs_mesh_sysfs_entries[] = {
|
||||
&dev_attr_anycast_mask.attr,
|
||||
&dev_attr_prb_rsp_limit.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -522,6 +522,10 @@ static void mac80211_hwsim_sta_notify(struct ieee80211_hw *hw,
|
||||
case STA_NOTIFY_REMOVE:
|
||||
hwsim_clear_sta_magic(sta);
|
||||
break;
|
||||
case STA_NOTIFY_SLEEP:
|
||||
case STA_NOTIFY_AWAKE:
|
||||
/* TODO: make good use of these flags */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,7 @@ init_airport(void)
|
||||
static void __exit
|
||||
exit_airport(void)
|
||||
{
|
||||
return macio_unregister_driver(&airport_driver);
|
||||
macio_unregister_driver(&airport_driver);
|
||||
}
|
||||
|
||||
module_init(init_airport);
|
||||
|
@ -1750,7 +1750,7 @@ static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
|
||||
union iwreq_data wrqu;
|
||||
int err;
|
||||
|
||||
err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
|
||||
err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
|
||||
ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
|
||||
if (err != 0)
|
||||
return;
|
||||
@ -1773,7 +1773,7 @@ static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
|
||||
if (!priv->has_wpa)
|
||||
return;
|
||||
|
||||
err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
|
||||
err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
|
||||
sizeof(buf), NULL, &buf);
|
||||
if (err != 0)
|
||||
return;
|
||||
@ -1803,7 +1803,7 @@ static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
|
||||
if (!priv->has_wpa)
|
||||
return;
|
||||
|
||||
err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
|
||||
err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
|
||||
sizeof(buf), NULL, &buf);
|
||||
if (err != 0)
|
||||
return;
|
||||
|
@ -178,13 +178,17 @@ static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
|
||||
/* Note that the CIS values need to be rescaled */
|
||||
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
|
||||
DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
|
||||
DEBUG(2, "%s: Vcc mismatch (vcc = %d, CIS = %d)\n",
|
||||
__func__, vcc,
|
||||
cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
|
||||
if (!ignore_cis_vcc)
|
||||
goto next_entry;
|
||||
}
|
||||
} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) {
|
||||
DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
|
||||
DEBUG(2, "%s: Vcc mismatch (vcc = %d, CIS = %d)\n",
|
||||
__func__, vcc,
|
||||
dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
|
||||
if (!ignore_cis_vcc)
|
||||
goto next_entry;
|
||||
}
|
||||
|
@ -248,13 +248,17 @@ static int spectrum_cs_config_check(struct pcmcia_device *p_dev,
|
||||
/* Note that the CIS values need to be rescaled */
|
||||
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
|
||||
DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
|
||||
DEBUG(2, "%s: Vcc mismatch (vcc = %d, CIS = %d)\n",
|
||||
__func__, vcc,
|
||||
cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
|
||||
if (!ignore_cis_vcc)
|
||||
goto next_entry;
|
||||
}
|
||||
} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) {
|
||||
DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
|
||||
DEBUG(2, "%s: Vcc mismatch (vcc = %d, CIS = %d)\n",
|
||||
__func__, vcc,
|
||||
dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
|
||||
if (!ignore_cis_vcc)
|
||||
goto next_entry;
|
||||
}
|
||||
|
@ -540,6 +540,14 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
|
||||
size_t header_len = sizeof(*hdr);
|
||||
u32 tsf32;
|
||||
|
||||
/*
|
||||
* If the device is in a unspecified state we have to
|
||||
* ignore all data frames. Else we could end up with a
|
||||
* nasty crash.
|
||||
*/
|
||||
if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
|
||||
return 0;
|
||||
|
||||
if (!(hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_IN_FCS_GOOD))) {
|
||||
if (priv->filter_flags & FIF_FCSFAIL)
|
||||
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
@ -608,6 +616,12 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
|
||||
if (unlikely(!skb || !dev || !skb_queue_len(&priv->tx_queue)))
|
||||
return;
|
||||
|
||||
/*
|
||||
* don't try to free an already unlinked skb
|
||||
*/
|
||||
if (unlikely((!skb->next) || (!skb->prev)))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&priv->tx_queue.lock, flags);
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
range = (void *)info->rate_driver_data;
|
||||
@ -874,7 +888,27 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&priv->tx_queue.lock, flags);
|
||||
|
||||
left = skb_queue_len(&priv->tx_queue);
|
||||
if (unlikely(left >= 28)) {
|
||||
/*
|
||||
* The tx_queue is nearly full!
|
||||
* We have throttle normal data traffic, because we must
|
||||
* have a few spare slots for control frames left.
|
||||
*/
|
||||
ieee80211_stop_queues(dev);
|
||||
|
||||
if (unlikely(left == 32)) {
|
||||
/*
|
||||
* The tx_queue is now really full.
|
||||
*
|
||||
* TODO: check if the device has crashed and reset it.
|
||||
*/
|
||||
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
|
||||
return -ENOSPC;
|
||||
}
|
||||
}
|
||||
|
||||
while (left--) {
|
||||
u32 hole_size;
|
||||
info = IEEE80211_SKB_CB(entry);
|
||||
@ -903,7 +937,7 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
|
||||
if (!target_skb) {
|
||||
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
|
||||
ieee80211_stop_queues(dev);
|
||||
return -ENOMEM;
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
@ -1051,19 +1085,6 @@ static int p54_sta_unlock(struct ieee80211_hw *dev, u8 *addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void p54_sta_notify_ps(struct ieee80211_hw *dev,
|
||||
enum sta_notify_ps_cmd notify_cmd,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
switch (notify_cmd) {
|
||||
case STA_NOTIFY_AWAKE:
|
||||
p54_sta_unlock(dev, sta->addr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void p54_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
|
||||
enum sta_notify_cmd notify_cmd,
|
||||
struct ieee80211_sta *sta)
|
||||
@ -1076,6 +1097,10 @@ static void p54_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
|
||||
* need to buffer frames for this station anymore.
|
||||
*/
|
||||
|
||||
p54_sta_unlock(dev, sta->addr);
|
||||
break;
|
||||
case STA_NOTIFY_AWAKE:
|
||||
/* update the firmware's filter table */
|
||||
p54_sta_unlock(dev, sta->addr);
|
||||
break;
|
||||
default:
|
||||
@ -1684,19 +1709,18 @@ static void p54_stop(struct ieee80211_hw *dev)
|
||||
struct sk_buff *skb;
|
||||
|
||||
mutex_lock(&priv->conf_mutex);
|
||||
priv->mode = NL80211_IFTYPE_UNSPECIFIED;
|
||||
del_timer(&priv->stats_timer);
|
||||
p54_free_skb(dev, priv->cached_stats);
|
||||
priv->cached_stats = NULL;
|
||||
if (priv->cached_beacon)
|
||||
p54_tx_cancel(dev, priv->cached_beacon);
|
||||
|
||||
priv->stop(dev);
|
||||
while ((skb = skb_dequeue(&priv->tx_queue)))
|
||||
kfree_skb(skb);
|
||||
|
||||
priv->cached_beacon = NULL;
|
||||
priv->stop(dev);
|
||||
priv->tsf_high32 = priv->tsf_low32 = 0;
|
||||
priv->mode = NL80211_IFTYPE_UNSPECIFIED;
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
}
|
||||
|
||||
@ -2027,7 +2051,6 @@ static const struct ieee80211_ops p54_ops = {
|
||||
.add_interface = p54_add_interface,
|
||||
.remove_interface = p54_remove_interface,
|
||||
.set_tim = p54_set_tim,
|
||||
.sta_notify_ps = p54_sta_notify_ps,
|
||||
.sta_notify = p54_sta_notify,
|
||||
.set_key = p54_set_key,
|
||||
.config = p54_config,
|
||||
|
@ -332,13 +332,6 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
|
||||
|
||||
P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
|
||||
P54P_READ(dev_int);
|
||||
|
||||
/* FIXME: unlikely to happen because the device usually runs out of
|
||||
memory before we fill the ring up, but we can make it impossible */
|
||||
if (idx - device_idx > ARRAY_SIZE(ring_control->tx_data) - 2) {
|
||||
p54_free_skb(dev, skb);
|
||||
printk(KERN_INFO "%s: tx overflow.\n", wiphy_name(dev->wiphy));
|
||||
}
|
||||
}
|
||||
|
||||
static void p54p_stop(struct ieee80211_hw *dev)
|
||||
|
@ -86,13 +86,13 @@ static void p54u_rx_cb(struct urb *urb)
|
||||
struct ieee80211_hw *dev = info->dev;
|
||||
struct p54u_priv *priv = dev->priv;
|
||||
|
||||
skb_unlink(skb, &priv->rx_queue);
|
||||
|
||||
if (unlikely(urb->status)) {
|
||||
info->urb = NULL;
|
||||
usb_free_urb(urb);
|
||||
dev_kfree_skb_irq(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
skb_unlink(skb, &priv->rx_queue);
|
||||
skb_put(skb, urb->actual_length);
|
||||
|
||||
if (priv->hw_type == P54U_NET2280)
|
||||
@ -105,7 +105,6 @@ static void p54u_rx_cb(struct urb *urb)
|
||||
if (p54_rx(dev, skb)) {
|
||||
skb = dev_alloc_skb(priv->common.rx_mtu + 32);
|
||||
if (unlikely(!skb)) {
|
||||
usb_free_urb(urb);
|
||||
/* TODO check rx queue length and refill *somewhere* */
|
||||
return;
|
||||
}
|
||||
@ -115,7 +114,6 @@ static void p54u_rx_cb(struct urb *urb)
|
||||
info->dev = dev;
|
||||
urb->transfer_buffer = skb_tail_pointer(skb);
|
||||
urb->context = skb;
|
||||
skb_queue_tail(&priv->rx_queue, skb);
|
||||
} else {
|
||||
if (priv->hw_type == P54U_NET2280)
|
||||
skb_push(skb, priv->common.tx_hdr_len);
|
||||
@ -130,11 +128,14 @@ static void p54u_rx_cb(struct urb *urb)
|
||||
WARN_ON(1);
|
||||
urb->transfer_buffer = skb_tail_pointer(skb);
|
||||
}
|
||||
|
||||
skb_queue_tail(&priv->rx_queue, skb);
|
||||
}
|
||||
|
||||
usb_submit_urb(urb, GFP_ATOMIC);
|
||||
skb_queue_tail(&priv->rx_queue, skb);
|
||||
usb_anchor_urb(urb, &priv->submitted);
|
||||
if (usb_submit_urb(urb, GFP_ATOMIC)) {
|
||||
skb_unlink(skb, &priv->rx_queue);
|
||||
usb_unanchor_urb(urb);
|
||||
dev_kfree_skb_irq(skb);
|
||||
}
|
||||
}
|
||||
|
||||
static void p54u_tx_reuse_skb_cb(struct urb *urb)
|
||||
@ -144,18 +145,6 @@ static void p54u_tx_reuse_skb_cb(struct urb *urb)
|
||||
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)))->priv;
|
||||
|
||||
skb_pull(skb, priv->common.tx_hdr_len);
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
|
||||
static void p54u_tx_cb(struct urb *urb)
|
||||
{
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
|
||||
static void p54u_tx_free_cb(struct urb *urb)
|
||||
{
|
||||
kfree(urb->transfer_buffer);
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
|
||||
static void p54u_tx_free_skb_cb(struct urb *urb)
|
||||
@ -165,25 +154,36 @@ static void p54u_tx_free_skb_cb(struct urb *urb)
|
||||
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
|
||||
|
||||
p54_free_skb(dev, skb);
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
|
||||
static void p54u_tx_dummy_cb(struct urb *urb) { }
|
||||
|
||||
static void p54u_free_urbs(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct p54u_priv *priv = dev->priv;
|
||||
usb_kill_anchored_urbs(&priv->submitted);
|
||||
}
|
||||
|
||||
static int p54u_init_urbs(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct p54u_priv *priv = dev->priv;
|
||||
struct urb *entry;
|
||||
struct urb *entry = NULL;
|
||||
struct sk_buff *skb;
|
||||
struct p54u_rx_info *info;
|
||||
int ret = 0;
|
||||
|
||||
while (skb_queue_len(&priv->rx_queue) < 32) {
|
||||
skb = __dev_alloc_skb(priv->common.rx_mtu + 32, GFP_KERNEL);
|
||||
if (!skb)
|
||||
break;
|
||||
if (!skb) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
entry = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!entry) {
|
||||
kfree_skb(skb);
|
||||
break;
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
usb_fill_bulk_urb(entry, priv->udev,
|
||||
usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
|
||||
skb_tail_pointer(skb),
|
||||
@ -192,26 +192,25 @@ static int p54u_init_urbs(struct ieee80211_hw *dev)
|
||||
info->urb = entry;
|
||||
info->dev = dev;
|
||||
skb_queue_tail(&priv->rx_queue, skb);
|
||||
usb_submit_urb(entry, GFP_KERNEL);
|
||||
|
||||
usb_anchor_urb(entry, &priv->submitted);
|
||||
ret = usb_submit_urb(entry, GFP_KERNEL);
|
||||
if (ret) {
|
||||
skb_unlink(skb, &priv->rx_queue);
|
||||
usb_unanchor_urb(entry);
|
||||
goto err;
|
||||
}
|
||||
usb_free_urb(entry);
|
||||
entry = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void p54u_free_urbs(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct p54u_priv *priv = dev->priv;
|
||||
struct p54u_rx_info *info;
|
||||
struct sk_buff *skb;
|
||||
|
||||
while ((skb = skb_dequeue(&priv->rx_queue))) {
|
||||
info = (struct p54u_rx_info *) skb->cb;
|
||||
if (!info->urb)
|
||||
continue;
|
||||
|
||||
usb_kill_urb(info->urb);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
err:
|
||||
usb_free_urb(entry);
|
||||
kfree_skb(skb);
|
||||
p54u_free_urbs(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb,
|
||||
@ -219,6 +218,7 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb,
|
||||
{
|
||||
struct p54u_priv *priv = dev->priv;
|
||||
struct urb *addr_urb, *data_urb;
|
||||
int err = 0;
|
||||
|
||||
addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
|
||||
if (!addr_urb)
|
||||
@ -233,15 +233,31 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb,
|
||||
usb_fill_bulk_urb(addr_urb, priv->udev,
|
||||
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
|
||||
&((struct p54_hdr *)skb->data)->req_id, 4,
|
||||
p54u_tx_cb, dev);
|
||||
p54u_tx_dummy_cb, dev);
|
||||
usb_fill_bulk_urb(data_urb, priv->udev,
|
||||
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
|
||||
skb->data, skb->len,
|
||||
free_on_tx ? p54u_tx_free_skb_cb :
|
||||
p54u_tx_reuse_skb_cb, skb);
|
||||
|
||||
usb_submit_urb(addr_urb, GFP_ATOMIC);
|
||||
usb_submit_urb(data_urb, GFP_ATOMIC);
|
||||
usb_anchor_urb(addr_urb, &priv->submitted);
|
||||
err = usb_submit_urb(addr_urb, GFP_ATOMIC);
|
||||
if (err) {
|
||||
usb_unanchor_urb(addr_urb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
usb_anchor_urb(addr_urb, &priv->submitted);
|
||||
err = usb_submit_urb(data_urb, GFP_ATOMIC);
|
||||
if (err)
|
||||
usb_unanchor_urb(data_urb);
|
||||
|
||||
out:
|
||||
usb_free_urb(addr_urb);
|
||||
usb_free_urb(data_urb);
|
||||
|
||||
if (err)
|
||||
p54_free_skb(dev, skb);
|
||||
}
|
||||
|
||||
static __le32 p54u_lm87_chksum(const __le32 *data, size_t length)
|
||||
@ -281,7 +297,13 @@ static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb,
|
||||
free_on_tx ? p54u_tx_free_skb_cb :
|
||||
p54u_tx_reuse_skb_cb, skb);
|
||||
|
||||
usb_submit_urb(data_urb, GFP_ATOMIC);
|
||||
usb_anchor_urb(data_urb, &priv->submitted);
|
||||
if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
|
||||
usb_unanchor_urb(data_urb);
|
||||
skb_pull(skb, sizeof(*hdr));
|
||||
p54_free_skb(dev, skb);
|
||||
}
|
||||
usb_free_urb(data_urb);
|
||||
}
|
||||
|
||||
static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb,
|
||||
@ -291,6 +313,7 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb,
|
||||
struct urb *int_urb, *data_urb;
|
||||
struct net2280_tx_hdr *hdr;
|
||||
struct net2280_reg_write *reg;
|
||||
int err = 0;
|
||||
|
||||
reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
|
||||
if (!reg)
|
||||
@ -320,15 +343,42 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb,
|
||||
|
||||
usb_fill_bulk_urb(int_urb, priv->udev,
|
||||
usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
|
||||
p54u_tx_free_cb, dev);
|
||||
usb_submit_urb(int_urb, GFP_ATOMIC);
|
||||
p54u_tx_dummy_cb, dev);
|
||||
|
||||
/*
|
||||
* This flag triggers a code path in the USB subsystem that will
|
||||
* free what's inside the transfer_buffer after the callback routine
|
||||
* has completed.
|
||||
*/
|
||||
int_urb->transfer_flags |= URB_FREE_BUFFER;
|
||||
|
||||
usb_fill_bulk_urb(data_urb, priv->udev,
|
||||
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
|
||||
skb->data, skb->len,
|
||||
free_on_tx ? p54u_tx_free_skb_cb :
|
||||
p54u_tx_reuse_skb_cb, skb);
|
||||
usb_submit_urb(data_urb, GFP_ATOMIC);
|
||||
|
||||
usb_anchor_urb(int_urb, &priv->submitted);
|
||||
err = usb_submit_urb(int_urb, GFP_ATOMIC);
|
||||
if (err) {
|
||||
usb_unanchor_urb(int_urb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
usb_anchor_urb(data_urb, &priv->submitted);
|
||||
err = usb_submit_urb(data_urb, GFP_ATOMIC);
|
||||
if (err) {
|
||||
usb_unanchor_urb(data_urb);
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
usb_free_urb(int_urb);
|
||||
usb_free_urb(data_urb);
|
||||
|
||||
if (err) {
|
||||
skb_pull(skb, sizeof(*hdr));
|
||||
p54_free_skb(dev, skb);
|
||||
}
|
||||
}
|
||||
|
||||
static int p54u_write(struct p54u_priv *priv,
|
||||
@ -885,6 +935,7 @@ static int __devinit p54u_probe(struct usb_interface *intf,
|
||||
goto err_free_dev;
|
||||
|
||||
skb_queue_head_init(&priv->rx_queue);
|
||||
init_usb_anchor(&priv->submitted);
|
||||
|
||||
p54u_open(dev);
|
||||
err = p54_read_eeprom(dev);
|
||||
|
@ -133,6 +133,7 @@ struct p54u_priv {
|
||||
|
||||
spinlock_t lock;
|
||||
struct sk_buff_head rx_queue;
|
||||
struct usb_anchor submitted;
|
||||
};
|
||||
|
||||
#endif /* P54USB_H */
|
||||
|
@ -99,6 +99,7 @@ struct rtl8187_priv {
|
||||
struct ieee80211_supported_band band;
|
||||
struct usb_device *udev;
|
||||
u32 rx_conf;
|
||||
struct usb_anchor anchored;
|
||||
u16 txpwr_base;
|
||||
u8 asic_rev;
|
||||
u8 is_rtl8187b;
|
||||
@ -115,7 +116,6 @@ struct rtl8187_priv {
|
||||
u8 aifsn[4];
|
||||
struct {
|
||||
__le64 buf;
|
||||
struct urb *urb;
|
||||
struct sk_buff_head queue;
|
||||
} b_tx_status;
|
||||
};
|
||||
|
@ -99,7 +99,6 @@ static const struct ieee80211_channel rtl818x_channels[] = {
|
||||
static void rtl8187_iowrite_async_cb(struct urb *urb)
|
||||
{
|
||||
kfree(urb->context);
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
|
||||
static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr,
|
||||
@ -136,11 +135,13 @@ static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr,
|
||||
usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0),
|
||||
(unsigned char *)dr, buf, len,
|
||||
rtl8187_iowrite_async_cb, buf);
|
||||
usb_anchor_urb(urb, &priv->anchored);
|
||||
rc = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (rc < 0) {
|
||||
kfree(buf);
|
||||
usb_free_urb(urb);
|
||||
usb_unanchor_urb(urb);
|
||||
}
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
|
||||
static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv,
|
||||
@ -172,7 +173,6 @@ static void rtl8187_tx_cb(struct urb *urb)
|
||||
struct ieee80211_hw *hw = info->rate_driver_data[0];
|
||||
struct rtl8187_priv *priv = hw->priv;
|
||||
|
||||
usb_free_urb(info->rate_driver_data[1]);
|
||||
skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) :
|
||||
sizeof(struct rtl8187_tx_hdr));
|
||||
ieee80211_tx_info_clear_status(info);
|
||||
@ -273,11 +273,13 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
|
||||
|
||||
usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep),
|
||||
buf, skb->len, rtl8187_tx_cb, skb);
|
||||
usb_anchor_urb(urb, &priv->anchored);
|
||||
rc = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (rc < 0) {
|
||||
usb_free_urb(urb);
|
||||
usb_unanchor_urb(urb);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
usb_free_urb(urb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -301,41 +303,25 @@ static void rtl8187_rx_cb(struct urb *urb)
|
||||
return;
|
||||
}
|
||||
spin_unlock(&priv->rx_queue.lock);
|
||||
skb_put(skb, urb->actual_length);
|
||||
|
||||
if (unlikely(urb->status)) {
|
||||
usb_free_urb(urb);
|
||||
dev_kfree_skb_irq(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
skb_put(skb, urb->actual_length);
|
||||
if (!priv->is_rtl8187b) {
|
||||
struct rtl8187_rx_hdr *hdr =
|
||||
(typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
|
||||
flags = le32_to_cpu(hdr->flags);
|
||||
signal = hdr->signal & 0x7f;
|
||||
/* As with the RTL8187B below, the AGC is used to calculate
|
||||
* signal strength and quality. In this case, the scaling
|
||||
* constants are derived from the output of p54usb.
|
||||
*/
|
||||
quality = 130 - ((41 * hdr->agc) >> 6);
|
||||
signal = -4 - ((27 * hdr->agc) >> 6);
|
||||
rx_status.antenna = (hdr->signal >> 7) & 1;
|
||||
rx_status.noise = hdr->noise;
|
||||
rx_status.mactime = le64_to_cpu(hdr->mac_time);
|
||||
priv->quality = signal;
|
||||
rx_status.qual = priv->quality;
|
||||
priv->noise = hdr->noise;
|
||||
rate = (flags >> 20) & 0xF;
|
||||
if (rate > 3) { /* OFDM rate */
|
||||
if (signal > 90)
|
||||
signal = 90;
|
||||
else if (signal < 25)
|
||||
signal = 25;
|
||||
signal = 90 - signal;
|
||||
} else { /* CCK rate */
|
||||
if (signal > 95)
|
||||
signal = 95;
|
||||
else if (signal < 30)
|
||||
signal = 30;
|
||||
signal = 95 - signal;
|
||||
}
|
||||
rx_status.signal = signal;
|
||||
priv->signal = signal;
|
||||
} else {
|
||||
struct rtl8187b_rx_hdr *hdr =
|
||||
(typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
|
||||
@ -353,18 +339,18 @@ static void rtl8187_rx_cb(struct urb *urb)
|
||||
*/
|
||||
flags = le32_to_cpu(hdr->flags);
|
||||
quality = 170 - hdr->agc;
|
||||
if (quality > 100)
|
||||
quality = 100;
|
||||
signal = 14 - hdr->agc / 2;
|
||||
rx_status.qual = quality;
|
||||
priv->quality = quality;
|
||||
rx_status.signal = signal;
|
||||
priv->signal = signal;
|
||||
rx_status.antenna = (hdr->rssi >> 7) & 1;
|
||||
rx_status.mactime = le64_to_cpu(hdr->mac_time);
|
||||
rate = (flags >> 20) & 0xF;
|
||||
}
|
||||
|
||||
if (quality > 100)
|
||||
quality = 100;
|
||||
rx_status.qual = quality;
|
||||
priv->quality = quality;
|
||||
rx_status.signal = signal;
|
||||
priv->signal = signal;
|
||||
rate = (flags >> 20) & 0xF;
|
||||
skb_trim(skb, flags & 0x0FFF);
|
||||
rx_status.rate_idx = rate;
|
||||
rx_status.freq = dev->conf.channel->center_freq;
|
||||
@ -376,7 +362,6 @@ static void rtl8187_rx_cb(struct urb *urb)
|
||||
|
||||
skb = dev_alloc_skb(RTL8187_MAX_RX);
|
||||
if (unlikely(!skb)) {
|
||||
usb_free_urb(urb);
|
||||
/* TODO check rx queue length and refill *somewhere* */
|
||||
return;
|
||||
}
|
||||
@ -388,24 +373,32 @@ static void rtl8187_rx_cb(struct urb *urb)
|
||||
urb->context = skb;
|
||||
skb_queue_tail(&priv->rx_queue, skb);
|
||||
|
||||
usb_submit_urb(urb, GFP_ATOMIC);
|
||||
usb_anchor_urb(urb, &priv->anchored);
|
||||
if (usb_submit_urb(urb, GFP_ATOMIC)) {
|
||||
usb_unanchor_urb(urb);
|
||||
skb_unlink(skb, &priv->rx_queue);
|
||||
dev_kfree_skb_irq(skb);
|
||||
}
|
||||
}
|
||||
|
||||
static int rtl8187_init_urbs(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
struct urb *entry;
|
||||
struct urb *entry = NULL;
|
||||
struct sk_buff *skb;
|
||||
struct rtl8187_rx_info *info;
|
||||
int ret = 0;
|
||||
|
||||
while (skb_queue_len(&priv->rx_queue) < 8) {
|
||||
skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL);
|
||||
if (!skb)
|
||||
break;
|
||||
if (!skb) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
entry = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!entry) {
|
||||
kfree_skb(skb);
|
||||
break;
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
usb_fill_bulk_urb(entry, priv->udev,
|
||||
usb_rcvbulkpipe(priv->udev,
|
||||
@ -416,10 +409,22 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
|
||||
info->urb = entry;
|
||||
info->dev = dev;
|
||||
skb_queue_tail(&priv->rx_queue, skb);
|
||||
usb_submit_urb(entry, GFP_KERNEL);
|
||||
usb_anchor_urb(entry, &priv->anchored);
|
||||
ret = usb_submit_urb(entry, GFP_KERNEL);
|
||||
if (ret) {
|
||||
skb_unlink(skb, &priv->rx_queue);
|
||||
usb_unanchor_urb(entry);
|
||||
goto err;
|
||||
}
|
||||
usb_free_urb(entry);
|
||||
}
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
usb_free_urb(entry);
|
||||
kfree_skb(skb);
|
||||
usb_kill_anchored_urbs(&priv->anchored);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rtl8187b_status_cb(struct urb *urb)
|
||||
@ -429,10 +434,8 @@ static void rtl8187b_status_cb(struct urb *urb)
|
||||
u64 val;
|
||||
unsigned int cmd_type;
|
||||
|
||||
if (unlikely(urb->status)) {
|
||||
usb_free_urb(urb);
|
||||
if (unlikely(urb->status))
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from status buffer:
|
||||
@ -503,26 +506,32 @@ static void rtl8187b_status_cb(struct urb *urb)
|
||||
spin_unlock_irqrestore(&priv->b_tx_status.queue.lock, flags);
|
||||
}
|
||||
|
||||
usb_submit_urb(urb, GFP_ATOMIC);
|
||||
usb_anchor_urb(urb, &priv->anchored);
|
||||
if (usb_submit_urb(urb, GFP_ATOMIC))
|
||||
usb_unanchor_urb(urb);
|
||||
}
|
||||
|
||||
static int rtl8187b_init_status_urb(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
struct urb *entry;
|
||||
int ret = 0;
|
||||
|
||||
entry = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
priv->b_tx_status.urb = entry;
|
||||
|
||||
usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, 9),
|
||||
&priv->b_tx_status.buf, sizeof(priv->b_tx_status.buf),
|
||||
rtl8187b_status_cb, dev);
|
||||
|
||||
usb_submit_urb(entry, GFP_KERNEL);
|
||||
usb_anchor_urb(entry, &priv->anchored);
|
||||
ret = usb_submit_urb(entry, GFP_KERNEL);
|
||||
if (ret)
|
||||
usb_unanchor_urb(entry);
|
||||
usb_free_urb(entry);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
|
||||
@ -856,6 +865,9 @@ static int rtl8187_start(struct ieee80211_hw *dev)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&priv->conf_mutex);
|
||||
|
||||
init_usb_anchor(&priv->anchored);
|
||||
|
||||
if (priv->is_rtl8187b) {
|
||||
reg = RTL818X_RX_CONF_MGMT |
|
||||
RTL818X_RX_CONF_DATA |
|
||||
@ -951,12 +963,12 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
|
||||
|
||||
while ((skb = skb_dequeue(&priv->rx_queue))) {
|
||||
info = (struct rtl8187_rx_info *)skb->cb;
|
||||
usb_kill_urb(info->urb);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
while ((skb = skb_dequeue(&priv->b_tx_status.queue)))
|
||||
dev_kfree_skb_any(skb);
|
||||
usb_kill_urb(priv->b_tx_status.urb);
|
||||
|
||||
usb_kill_anchored_urbs(&priv->anchored);
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
}
|
||||
|
||||
@ -1293,6 +1305,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
|
||||
|
||||
priv->mode = NL80211_IFTYPE_MONITOR;
|
||||
dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
|
||||
IEEE80211_HW_SIGNAL_DBM |
|
||||
IEEE80211_HW_RX_INCLUDES_FCS;
|
||||
|
||||
eeprom.data = dev;
|
||||
@ -1408,13 +1421,8 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
|
||||
(*channel++).hw_value = txpwr >> 8;
|
||||
}
|
||||
|
||||
if (priv->is_rtl8187b) {
|
||||
if (priv->is_rtl8187b)
|
||||
printk(KERN_WARNING "rtl8187: 8187B chip detected.\n");
|
||||
dev->flags |= IEEE80211_HW_SIGNAL_DBM;
|
||||
} else {
|
||||
dev->flags |= IEEE80211_HW_SIGNAL_UNSPEC;
|
||||
dev->max_signal = 65;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: Once this driver supports anything that requires
|
||||
|
@ -836,7 +836,7 @@ struct ieee80211_ht_info {
|
||||
/* Authentication algorithms */
|
||||
#define WLAN_AUTH_OPEN 0
|
||||
#define WLAN_AUTH_SHARED_KEY 1
|
||||
#define WLAN_AUTH_LEAP 2
|
||||
#define WLAN_AUTH_LEAP 128
|
||||
|
||||
#define WLAN_AUTH_CHALLENGE_LEN 128
|
||||
|
||||
|
@ -149,11 +149,4 @@ static inline char *rfkill_get_led_name(struct rfkill *rfkill)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* rfkill notification chain */
|
||||
#define RFKILL_STATE_CHANGED 0x0001 /* state of a normal rfkill
|
||||
switch has changed */
|
||||
|
||||
int register_rfkill_notifier(struct notifier_block *nb);
|
||||
int unregister_rfkill_notifier(struct notifier_block *nb);
|
||||
|
||||
#endif /* RFKILL_H */
|
||||
|
@ -385,9 +385,8 @@ struct ieee80211_device;
|
||||
#define SCM_TEMPORAL_KEY_LENGTH 16
|
||||
|
||||
struct ieee80211_security {
|
||||
u16 active_key:2,
|
||||
enabled:1,
|
||||
auth_mode:2, auth_algo:4, unicast_uses_group:1, encrypt:1;
|
||||
u16 active_key:2, enabled:1, unicast_uses_group:1, encrypt:1;
|
||||
u8 auth_mode;
|
||||
u8 encode_alg[WEP_KEYS];
|
||||
u8 key_sizes[WEP_KEYS];
|
||||
u8 keys[WEP_KEYS][SCM_KEY_LEN];
|
||||
|
@ -773,25 +773,16 @@ struct ieee80211_sta {
|
||||
* enum sta_notify_cmd - sta notify command
|
||||
*
|
||||
* Used with the sta_notify() callback in &struct ieee80211_ops, this
|
||||
* indicates addition and removal of a station to station table.
|
||||
* indicates addition and removal of a station to station table,
|
||||
* or if a associated station made a power state transition.
|
||||
*
|
||||
* @STA_NOTIFY_ADD: a station was added to the station table
|
||||
* @STA_NOTIFY_REMOVE: a station being removed from the station table
|
||||
*/
|
||||
enum sta_notify_cmd {
|
||||
STA_NOTIFY_ADD, STA_NOTIFY_REMOVE
|
||||
};
|
||||
|
||||
/**
|
||||
* enum sta_notify_ps_cmd - sta power save notify command
|
||||
*
|
||||
* Used with the sta_notify_ps() callback in &struct ieee80211_ops to
|
||||
* notify the driver if a station made a power state transition.
|
||||
*
|
||||
* @STA_NOTIFY_SLEEP: a station is now sleeping
|
||||
* @STA_NOTIFY_AWAKE: a sleeping station woke up
|
||||
*/
|
||||
enum sta_notify_ps_cmd {
|
||||
enum sta_notify_cmd {
|
||||
STA_NOTIFY_ADD, STA_NOTIFY_REMOVE,
|
||||
STA_NOTIFY_SLEEP, STA_NOTIFY_AWAKE,
|
||||
};
|
||||
|
||||
@ -1258,15 +1249,9 @@ enum ieee80211_ampdu_mlme_action {
|
||||
*
|
||||
* @set_rts_threshold: Configuration of RTS threshold (if device needs it)
|
||||
*
|
||||
* @set_frag_threshold: Configuration of fragmentation threshold. Assign this if
|
||||
* the device does fragmentation by itself; if this method is assigned then
|
||||
* the stack will not do fragmentation.
|
||||
*
|
||||
* @sta_notify: Notifies low level driver about addition or removal
|
||||
* of associated station or AP.
|
||||
*
|
||||
* @sta_ps_notify: Notifies low level driver about the power state transition
|
||||
* of a associated station. Must be atomic.
|
||||
* @sta_notify: Notifies low level driver about addition, removal or power
|
||||
* state transition of an associated station, AP, IBSS/WDS/mesh peer etc.
|
||||
* Must be atomic.
|
||||
*
|
||||
* @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
|
||||
* bursting) for a hardware TX queue.
|
||||
@ -1331,11 +1316,8 @@ struct ieee80211_ops {
|
||||
void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx,
|
||||
u32 *iv32, u16 *iv16);
|
||||
int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value);
|
||||
int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value);
|
||||
void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
enum sta_notify_cmd, struct ieee80211_sta *sta);
|
||||
void (*sta_notify_ps)(struct ieee80211_hw *hw,
|
||||
enum sta_notify_ps_cmd, struct ieee80211_sta *sta);
|
||||
int (*conf_tx)(struct ieee80211_hw *hw, u16 queue,
|
||||
const struct ieee80211_tx_queue_params *params);
|
||||
int (*get_tx_stats)(struct ieee80211_hw *hw,
|
||||
|
@ -46,3 +46,5 @@ rc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o
|
||||
|
||||
mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y)
|
||||
mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y)
|
||||
|
||||
ccflags-y += -D__CHECK_ENDIAN__
|
||||
|
@ -396,8 +396,10 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
*/
|
||||
if (params->interval) {
|
||||
sdata->local->hw.conf.beacon_int = params->interval;
|
||||
ieee80211_hw_config(sdata->local,
|
||||
IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
|
||||
err = ieee80211_hw_config(sdata->local,
|
||||
IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
/*
|
||||
* We updated some parameter so if below bails out
|
||||
* it's not an error.
|
||||
|
@ -187,7 +187,6 @@ struct ieee80211_rx_data {
|
||||
struct ieee80211_rx_status *status;
|
||||
struct ieee80211_rate *rate;
|
||||
|
||||
u16 ethertype;
|
||||
unsigned int flags;
|
||||
int sent_ps_buffered;
|
||||
int queue;
|
||||
@ -864,8 +863,7 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid);
|
||||
void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_if_sta *ifsta);
|
||||
struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb, u8 *bssid,
|
||||
u8 *addr, u64 supp_rates);
|
||||
u8 *bssid, u8 *addr, u64 supp_rates);
|
||||
int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason);
|
||||
int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason);
|
||||
u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);
|
||||
|
@ -243,10 +243,20 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
|
||||
if (changed && local->open_count) {
|
||||
ret = local->ops->config(local_to_hw(local), changed);
|
||||
/*
|
||||
* Goal:
|
||||
* HW reconfiguration should never fail, the driver has told
|
||||
* us what it can support so it should live up to that promise.
|
||||
*
|
||||
* Current status:
|
||||
* rfkill is not integrated with mac80211 and a
|
||||
* configuration command can thus fail if hardware rfkill
|
||||
* is enabled
|
||||
*
|
||||
* FIXME: integrate rfkill with mac80211 and then add this
|
||||
* WARN_ON() back
|
||||
*
|
||||
*/
|
||||
WARN_ON(ret);
|
||||
/* WARN_ON(ret); */
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -876,12 +886,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
|
||||
|
||||
local->mdev->select_queue = ieee80211_select_queue;
|
||||
|
||||
/* add one default STA interface */
|
||||
result = ieee80211_if_add(local, "wlan%d", NULL,
|
||||
NL80211_IFTYPE_STATION, NULL);
|
||||
if (result)
|
||||
printk(KERN_WARNING "%s: Failed to add default virtual iface\n",
|
||||
wiphy_name(local->hw.wiphy));
|
||||
/* add one default STA interface if supported */
|
||||
if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
|
||||
result = ieee80211_if_add(local, "wlan%d", NULL,
|
||||
NL80211_IFTYPE_STATION, NULL);
|
||||
if (result)
|
||||
printk(KERN_WARNING "%s: Failed to add default virtual iface\n",
|
||||
wiphy_name(local->hw.wiphy));
|
||||
}
|
||||
|
||||
rtnl_unlock();
|
||||
|
||||
|
@ -1565,8 +1565,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
||||
(unsigned long long) sta->sta.supp_rates[band]);
|
||||
#endif
|
||||
} else {
|
||||
ieee80211_ibss_add_sta(sdata, NULL, mgmt->bssid,
|
||||
mgmt->sa, supp_rates);
|
||||
ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates);
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
@ -1638,9 +1637,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
||||
sdata->dev->name, mgmt->bssid);
|
||||
#endif
|
||||
ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss);
|
||||
ieee80211_ibss_add_sta(sdata, NULL,
|
||||
mgmt->bssid, mgmt->sa,
|
||||
supp_rates);
|
||||
ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2373,8 +2370,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
|
||||
* must be callable in atomic context.
|
||||
*/
|
||||
struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb, u8 *bssid,
|
||||
u8 *addr, u64 supp_rates)
|
||||
u8 *bssid,u8 *addr, u64 supp_rates)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct sta_info *sta;
|
||||
|
@ -658,9 +658,9 @@ static void ap_sta_ps_start(struct sta_info *sta)
|
||||
|
||||
atomic_inc(&sdata->bss->num_sta_ps);
|
||||
set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL);
|
||||
if (local->ops->sta_notify_ps)
|
||||
local->ops->sta_notify_ps(local_to_hw(local), STA_NOTIFY_SLEEP,
|
||||
&sta->sta);
|
||||
if (local->ops->sta_notify)
|
||||
local->ops->sta_notify(local_to_hw(local), &sdata->vif,
|
||||
STA_NOTIFY_SLEEP, &sta->sta);
|
||||
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
|
||||
printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n",
|
||||
sdata->dev->name, sta->sta.addr, sta->sta.aid);
|
||||
@ -677,9 +677,9 @@ static int ap_sta_ps_end(struct sta_info *sta)
|
||||
atomic_dec(&sdata->bss->num_sta_ps);
|
||||
|
||||
clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL);
|
||||
if (local->ops->sta_notify_ps)
|
||||
local->ops->sta_notify_ps(local_to_hw(local), STA_NOTIFY_AWAKE,
|
||||
&sta->sta);
|
||||
if (local->ops->sta_notify)
|
||||
local->ops->sta_notify(local_to_hw(local), &sdata->vif,
|
||||
STA_NOTIFY_AWAKE, &sta->sta);
|
||||
|
||||
if (!skb_queue_empty(&sta->ps_tx_buf))
|
||||
sta_info_clear_tim_bit(sta);
|
||||
@ -1850,9 +1850,8 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
|
||||
return 0;
|
||||
rx->flags &= ~IEEE80211_RX_RA_MATCH;
|
||||
} else if (!rx->sta)
|
||||
rx->sta = ieee80211_ibss_add_sta(sdata, rx->skb,
|
||||
bssid, hdr->addr2,
|
||||
BIT(rx->status->rate_idx));
|
||||
rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2,
|
||||
BIT(rx->status->rate_idx));
|
||||
break;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
if (!multicast &&
|
||||
|
@ -1001,7 +1001,6 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
|
||||
if (tx->flags & IEEE80211_TX_FRAGMENTED) {
|
||||
if ((tx->flags & IEEE80211_TX_UNICAST) &&
|
||||
skb->len + FCS_LEN > local->fragmentation_threshold &&
|
||||
!local->ops->set_frag_threshold &&
|
||||
!(info->flags & IEEE80211_TX_CTL_AMPDU))
|
||||
tx->flags |= IEEE80211_TX_FRAGMENTED;
|
||||
else
|
||||
|
@ -418,8 +418,7 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev,
|
||||
|
||||
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
|
||||
sdata->vif.type != NL80211_IFTYPE_ADHOC &&
|
||||
sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
|
||||
sdata->vif.type != NL80211_IFTYPE_AP)
|
||||
sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* if SSID was specified explicitly then use that */
|
||||
@ -639,14 +638,6 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev,
|
||||
local->fragmentation_threshold = frag->value & ~0x1;
|
||||
}
|
||||
|
||||
/* If the wlan card performs fragmentation in hardware/firmware,
|
||||
* configure it here */
|
||||
|
||||
if (local->ops->set_frag_threshold)
|
||||
return local->ops->set_frag_threshold(
|
||||
local_to_hw(local),
|
||||
local->fragmentation_threshold);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -53,51 +53,6 @@ static struct rfkill_gsw_state rfkill_global_states[RFKILL_TYPE_MAX];
|
||||
static unsigned long rfkill_states_lockdflt[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
|
||||
static bool rfkill_epo_lock_active;
|
||||
|
||||
static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list);
|
||||
|
||||
|
||||
/**
|
||||
* register_rfkill_notifier - Add notifier to rfkill notifier chain
|
||||
* @nb: pointer to the new entry to add to the chain
|
||||
*
|
||||
* See blocking_notifier_chain_register() for return value and further
|
||||
* observations.
|
||||
*
|
||||
* Adds a notifier to the rfkill notifier chain. The chain will be
|
||||
* called with a pointer to the relevant rfkill structure as a parameter,
|
||||
* refer to include/linux/rfkill.h for the possible events.
|
||||
*
|
||||
* Notifiers added to this chain are to always return NOTIFY_DONE. This
|
||||
* chain is a blocking notifier chain: notifiers can sleep.
|
||||
*
|
||||
* Calls to this chain may have been done through a workqueue. One must
|
||||
* assume unordered asynchronous behaviour, there is no way to know if
|
||||
* actions related to the event that generated the notification have been
|
||||
* carried out already.
|
||||
*/
|
||||
int register_rfkill_notifier(struct notifier_block *nb)
|
||||
{
|
||||
BUG_ON(!nb);
|
||||
return blocking_notifier_chain_register(&rfkill_notifier_list, nb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(register_rfkill_notifier);
|
||||
|
||||
/**
|
||||
* unregister_rfkill_notifier - remove notifier from rfkill notifier chain
|
||||
* @nb: pointer to the entry to remove from the chain
|
||||
*
|
||||
* See blocking_notifier_chain_unregister() for return value and further
|
||||
* observations.
|
||||
*
|
||||
* Removes a notifier from the rfkill notifier chain.
|
||||
*/
|
||||
int unregister_rfkill_notifier(struct notifier_block *nb)
|
||||
{
|
||||
BUG_ON(!nb);
|
||||
return blocking_notifier_chain_unregister(&rfkill_notifier_list, nb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(unregister_rfkill_notifier);
|
||||
|
||||
|
||||
static void rfkill_led_trigger(struct rfkill *rfkill,
|
||||
enum rfkill_state state)
|
||||
@ -124,12 +79,9 @@ static void rfkill_led_trigger_activate(struct led_classdev *led)
|
||||
}
|
||||
#endif /* CONFIG_RFKILL_LEDS */
|
||||
|
||||
static void notify_rfkill_state_change(struct rfkill *rfkill)
|
||||
static void rfkill_uevent(struct rfkill *rfkill)
|
||||
{
|
||||
rfkill_led_trigger(rfkill, rfkill->state);
|
||||
blocking_notifier_call_chain(&rfkill_notifier_list,
|
||||
RFKILL_STATE_CHANGED,
|
||||
rfkill);
|
||||
kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);
|
||||
}
|
||||
|
||||
static void update_rfkill_state(struct rfkill *rfkill)
|
||||
@ -142,7 +94,7 @@ static void update_rfkill_state(struct rfkill *rfkill)
|
||||
oldstate = rfkill->state;
|
||||
rfkill->state = newstate;
|
||||
if (oldstate != newstate)
|
||||
notify_rfkill_state_change(rfkill);
|
||||
rfkill_uevent(rfkill);
|
||||
}
|
||||
mutex_unlock(&rfkill->mutex);
|
||||
}
|
||||
@ -220,7 +172,7 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
|
||||
}
|
||||
|
||||
if (force || rfkill->state != oldstate)
|
||||
notify_rfkill_state_change(rfkill);
|
||||
rfkill_uevent(rfkill);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -405,7 +357,7 @@ int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
|
||||
rfkill->state = state;
|
||||
|
||||
if (state != oldstate)
|
||||
notify_rfkill_state_change(rfkill);
|
||||
rfkill_uevent(rfkill);
|
||||
|
||||
mutex_unlock(&rfkill->mutex);
|
||||
|
||||
@ -618,28 +570,6 @@ static int rfkill_resume(struct device *dev)
|
||||
#define rfkill_resume NULL
|
||||
#endif
|
||||
|
||||
static int rfkill_blocking_uevent_notifier(struct notifier_block *nb,
|
||||
unsigned long eventid,
|
||||
void *data)
|
||||
{
|
||||
struct rfkill *rfkill = (struct rfkill *)data;
|
||||
|
||||
switch (eventid) {
|
||||
case RFKILL_STATE_CHANGED:
|
||||
kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block rfkill_blocking_uevent_nb = {
|
||||
.notifier_call = rfkill_blocking_uevent_notifier,
|
||||
.priority = 0,
|
||||
};
|
||||
|
||||
static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct rfkill *rfkill = to_rfkill(dev);
|
||||
@ -942,14 +872,11 @@ static int __init rfkill_init(void)
|
||||
return error;
|
||||
}
|
||||
|
||||
register_rfkill_notifier(&rfkill_blocking_uevent_nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit rfkill_exit(void)
|
||||
{
|
||||
unregister_rfkill_notifier(&rfkill_blocking_uevent_nb);
|
||||
class_unregister(&rfkill_class);
|
||||
}
|
||||
|
||||
|
@ -8,3 +8,5 @@ obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
|
||||
cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o
|
||||
cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
|
||||
cfg80211-$(CONFIG_NL80211) += nl80211.o
|
||||
|
||||
ccflags-y += -D__CHECK_ENDIAN__
|
||||
|
@ -365,6 +365,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
|
||||
enum nl80211_sec_chan_offset sec_chan_offset =
|
||||
NL80211_SEC_CHAN_NO_HT;
|
||||
struct ieee80211_channel *chan;
|
||||
struct ieee80211_sta_ht_cap *ht_cap;
|
||||
u32 freq, sec_freq;
|
||||
|
||||
if (!rdev->ops->set_channel) {
|
||||
@ -372,26 +373,25 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
|
||||
goto bad_res;
|
||||
}
|
||||
|
||||
result = -EINVAL;
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]) {
|
||||
sec_chan_offset = nla_get_u32(
|
||||
info->attrs[
|
||||
sec_chan_offset = nla_get_u32(info->attrs[
|
||||
NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]);
|
||||
if (sec_chan_offset != NL80211_SEC_CHAN_NO_HT &&
|
||||
sec_chan_offset != NL80211_SEC_CHAN_DISABLED &&
|
||||
sec_chan_offset != NL80211_SEC_CHAN_BELOW &&
|
||||
sec_chan_offset != NL80211_SEC_CHAN_ABOVE) {
|
||||
result = -EINVAL;
|
||||
sec_chan_offset != NL80211_SEC_CHAN_ABOVE)
|
||||
goto bad_res;
|
||||
}
|
||||
}
|
||||
|
||||
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
|
||||
chan = ieee80211_get_channel(&rdev->wiphy, freq);
|
||||
if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
|
||||
/* Primary channel not allowed */
|
||||
result = -EINVAL;
|
||||
|
||||
/* Primary channel not allowed */
|
||||
if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
|
||||
goto bad_res;
|
||||
}
|
||||
|
||||
if (sec_chan_offset == NL80211_SEC_CHAN_BELOW)
|
||||
sec_freq = freq - 20;
|
||||
else if (sec_chan_offset == NL80211_SEC_CHAN_ABOVE)
|
||||
@ -399,14 +399,26 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
|
||||
else
|
||||
sec_freq = 0;
|
||||
|
||||
ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
|
||||
|
||||
/* no HT capabilities */
|
||||
if (sec_chan_offset != NL80211_SEC_CHAN_NO_HT &&
|
||||
!ht_cap->ht_supported)
|
||||
goto bad_res;
|
||||
|
||||
if (sec_freq) {
|
||||
struct ieee80211_channel *schan;
|
||||
schan = ieee80211_get_channel(&rdev->wiphy, sec_freq);
|
||||
if (!schan || schan->flags & IEEE80211_CHAN_DISABLED) {
|
||||
/* Secondary channel not allowed */
|
||||
result = -EINVAL;
|
||||
|
||||
/* no 40 MHz capabilities */
|
||||
if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
|
||||
(ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT))
|
||||
goto bad_res;
|
||||
|
||||
schan = ieee80211_get_channel(&rdev->wiphy, sec_freq);
|
||||
|
||||
/* Secondary channel not allowed */
|
||||
if (!schan || schan->flags & IEEE80211_CHAN_DISABLED)
|
||||
goto bad_res;
|
||||
}
|
||||
}
|
||||
|
||||
result = rdev->ops->set_channel(&rdev->wiphy, chan,
|
||||
@ -416,7 +428,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
|
||||
}
|
||||
|
||||
|
||||
bad_res:
|
||||
bad_res:
|
||||
cfg80211_put_dev(rdev);
|
||||
return result;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user