提交 143b11c0 编写于 作者: D David S. Miller
...@@ -144,6 +144,7 @@ struct ath_desc { ...@@ -144,6 +144,7 @@ struct ath_desc {
#define ATH9K_TXDESC_EXT_AND_CTL 0x0080 #define ATH9K_TXDESC_EXT_AND_CTL 0x0080
#define ATH9K_TXDESC_VMF 0x0100 #define ATH9K_TXDESC_VMF 0x0100
#define ATH9K_TXDESC_FRAG_IS_ON 0x0200 #define ATH9K_TXDESC_FRAG_IS_ON 0x0200
#define ATH9K_TXDESC_CAB 0x0400
#define ATH9K_RXDESC_INTREQ 0x0020 #define ATH9K_RXDESC_INTREQ 0x0020
...@@ -564,8 +565,6 @@ enum ath9k_cipher { ...@@ -564,8 +565,6 @@ enum ath9k_cipher {
#define CTL_5GHT40 8 #define CTL_5GHT40 8
#define AR_EEPROM_MAC(i) (0x1d+(i)) #define AR_EEPROM_MAC(i) (0x1d+(i))
#define EEP_SCALE 100
#define EEP_DELTA 10
#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c #define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2 #define AR_EEPROM_RFSILENT_GPIO_SEL_S 2
...@@ -606,9 +605,6 @@ struct ath9k_country_entry { ...@@ -606,9 +605,6 @@ struct ath9k_country_entry {
#define REG_CLR_BIT(_a, _r, _f) \ #define REG_CLR_BIT(_a, _r, _f) \
REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f) REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
#define ATH9K_COMP_BUF_MAX_SIZE 9216
#define ATH9K_COMP_BUF_ALIGN_SIZE 512
#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001 #define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
#define INIT_AIFS 2 #define INIT_AIFS 2
...@@ -632,12 +628,6 @@ struct ath9k_country_entry { ...@@ -632,12 +628,6 @@ struct ath9k_country_entry {
(IEEE80211_WEP_IVLEN + \ (IEEE80211_WEP_IVLEN + \
IEEE80211_WEP_KIDLEN + \ IEEE80211_WEP_KIDLEN + \
IEEE80211_WEP_CRCLEN)) IEEE80211_WEP_CRCLEN))
#define IEEE80211_MAX_LEN (2300 + FCS_LEN + \
(IEEE80211_WEP_IVLEN + \
IEEE80211_WEP_KIDLEN + \
IEEE80211_WEP_CRCLEN))
#define MAX_REG_ADD_COUNT 129
#define MAX_RATE_POWER 63 #define MAX_RATE_POWER 63
enum ath9k_power_mode { enum ath9k_power_mode {
...@@ -707,13 +697,6 @@ enum phytype { ...@@ -707,13 +697,6 @@ enum phytype {
}; };
#define PHY_CCK PHY_DS #define PHY_CCK PHY_DS
enum start_adhoc_option {
START_ADHOC_NO_11A,
START_ADHOC_PER_11D,
START_ADHOC_IN_11A,
START_ADHOC_IN_11B,
};
enum ath9k_tp_scale { enum ath9k_tp_scale {
ATH9K_TP_SCALE_MAX = 0, ATH9K_TP_SCALE_MAX = 0,
ATH9K_TP_SCALE_50, ATH9K_TP_SCALE_50,
...@@ -769,14 +752,11 @@ struct ath9k_node_stats { ...@@ -769,14 +752,11 @@ struct ath9k_node_stats {
#define ATH9K_RSSI_EP_MULTIPLIER (1<<7) #define ATH9K_RSSI_EP_MULTIPLIER (1<<7)
enum ath9k_gpio_output_mux_type { #define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT, #define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
ATH9K_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED, #define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2
ATH9K_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED, #define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5
ATH9K_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED, #define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6
ATH9K_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
ATH9K_GPIO_OUTPUT_MUX_NUM_ENTRIES
};
enum { enum {
ATH9K_RESET_POWER_ON, ATH9K_RESET_POWER_ON,
...@@ -790,19 +770,20 @@ struct ath_hal { ...@@ -790,19 +770,20 @@ struct ath_hal {
u32 ah_magic; u32 ah_magic;
u16 ah_devid; u16 ah_devid;
u16 ah_subvendorid; u16 ah_subvendorid;
struct ath_softc *ah_sc;
void __iomem *ah_sh;
u16 ah_countryCode;
u32 ah_macVersion; u32 ah_macVersion;
u16 ah_macRev; u16 ah_macRev;
u16 ah_phyRev; u16 ah_phyRev;
u16 ah_analog5GhzRev; u16 ah_analog5GhzRev;
u16 ah_analog2GhzRev; u16 ah_analog2GhzRev;
u8 ah_decompMask[ATH9K_DECOMP_MASK_SIZE];
u32 ah_flags; void __iomem *ah_sh;
struct ath_softc *ah_sc;
enum ath9k_opmode ah_opmode; enum ath9k_opmode ah_opmode;
struct ath9k_ops_config ah_config; struct ath9k_ops_config ah_config;
struct ath9k_hw_capabilities ah_caps; struct ath9k_hw_capabilities ah_caps;
u16 ah_countryCode;
u32 ah_flags;
int16_t ah_powerLimit; int16_t ah_powerLimit;
u16 ah_maxPowerLevel; u16 ah_maxPowerLevel;
u32 ah_tpScale; u32 ah_tpScale;
...@@ -812,15 +793,16 @@ struct ath_hal { ...@@ -812,15 +793,16 @@ struct ath_hal {
u16 ah_currentRD5G; u16 ah_currentRD5G;
u16 ah_currentRD2G; u16 ah_currentRD2G;
char ah_iso[4]; char ah_iso[4];
enum start_adhoc_option ah_adHocMode;
bool ah_commonMode;
struct ath9k_channel ah_channels[150]; struct ath9k_channel ah_channels[150];
u32 ah_nchan;
struct ath9k_channel *ah_curchan; struct ath9k_channel *ah_curchan;
u32 ah_nchan;
u16 ah_rfsilent; u16 ah_rfsilent;
bool ah_rfkillEnabled; bool ah_rfkillEnabled;
bool ah_isPciExpress; bool ah_isPciExpress;
u16 ah_txTrigLevel; u16 ah_txTrigLevel;
#ifndef ATH_NF_PER_CHAN #ifndef ATH_NF_PER_CHAN
struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
#endif #endif
...@@ -853,7 +835,7 @@ bool ath9k_regd_init_channels(struct ath_hal *ah, ...@@ -853,7 +835,7 @@ bool ath9k_regd_init_channels(struct ath_hal *ah,
u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags); u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags);
enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah,
enum ath9k_int ints); enum ath9k_int ints);
bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode, bool ath9k_hw_reset(struct ath_hal *ah,
struct ath9k_channel *chan, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode, enum ath9k_ht_macmode macmode,
u8 txchainmask, u8 rxchainmask, u8 txchainmask, u8 rxchainmask,
...@@ -1018,4 +1000,7 @@ void ath9k_hw_get_channel_centers(struct ath_hal *ah, ...@@ -1018,4 +1000,7 @@ void ath9k_hw_get_channel_centers(struct ath_hal *ah,
bool ath9k_get_channel_edges(struct ath_hal *ah, bool ath9k_get_channel_edges(struct ath_hal *ah,
u16 flags, u16 *low, u16 flags, u16 *low,
u16 *high); u16 *high);
void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
u32 ah_signal_type);
void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 value);
#endif #endif
...@@ -33,7 +33,7 @@ static int ath_beaconq_config(struct ath_softc *sc) ...@@ -33,7 +33,7 @@ static int ath_beaconq_config(struct ath_softc *sc)
struct ath9k_tx_queue_info qi; struct ath9k_tx_queue_info qi;
ath9k_hw_get_txq_props(ah, sc->sc_bhalq, &qi); ath9k_hw_get_txq_props(ah, sc->sc_bhalq, &qi);
if (sc->sc_opmode == ATH9K_M_HOSTAP) { if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
/* Always burst out beacon and CAB traffic. */ /* Always burst out beacon and CAB traffic. */
qi.tqi_aifs = 1; qi.tqi_aifs = 1;
qi.tqi_cwmin = 0; qi.tqi_cwmin = 0;
...@@ -85,7 +85,7 @@ static void ath_beacon_setup(struct ath_softc *sc, ...@@ -85,7 +85,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
flags = ATH9K_TXDESC_NOACK; flags = ATH9K_TXDESC_NOACK;
if (sc->sc_opmode == ATH9K_M_IBSS && if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS &&
(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) { (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
ds->ds_link = bf->bf_daddr; /* self-linked */ ds->ds_link = bf->bf_daddr; /* self-linked */
flags |= ATH9K_TXDESC_VEOL; flags |= ATH9K_TXDESC_VEOL;
...@@ -111,24 +111,24 @@ static void ath_beacon_setup(struct ath_softc *sc, ...@@ -111,24 +111,24 @@ static void ath_beacon_setup(struct ath_softc *sc,
rix = 0; rix = 0;
rt = sc->sc_currates; rt = sc->sc_currates;
rate = rt->info[rix].rateCode; rate = rt->info[rix].rateCode;
if (sc->sc_flags & ATH_PREAMBLE_SHORT) if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
rate |= rt->info[rix].shortPreamble; rate |= rt->info[rix].shortPreamble;
ath9k_hw_set11n_txdesc(ah, ds ath9k_hw_set11n_txdesc(ah, ds,
, skb->len + FCS_LEN /* frame length */ skb->len + FCS_LEN, /* frame length */
, ATH9K_PKT_TYPE_BEACON /* Atheros packet type */ ATH9K_PKT_TYPE_BEACON, /* Atheros packet type */
, avp->av_btxctl.txpower /* txpower XXX */ avp->av_btxctl.txpower, /* txpower XXX */
, ATH9K_TXKEYIX_INVALID /* no encryption */ ATH9K_TXKEYIX_INVALID, /* no encryption */
, ATH9K_KEY_TYPE_CLEAR /* no encryption */ ATH9K_KEY_TYPE_CLEAR, /* no encryption */
, flags /* no ack, veol for beacons */ flags /* no ack, veol for beacons */
); );
/* NB: beacon's BufLen must be a multiple of 4 bytes */ /* NB: beacon's BufLen must be a multiple of 4 bytes */
ath9k_hw_filltxdesc(ah, ds ath9k_hw_filltxdesc(ah, ds,
, roundup(skb->len, 4) /* buffer length */ roundup(skb->len, 4), /* buffer length */
, true /* first segment */ true, /* first segment */
, true /* last segment */ true, /* last segment */
, ds /* first descriptor */ ds /* first descriptor */
); );
memzero(series, sizeof(struct ath9k_11n_rate_series) * 4); memzero(series, sizeof(struct ath9k_11n_rate_series) * 4);
...@@ -140,55 +140,6 @@ static void ath_beacon_setup(struct ath_softc *sc, ...@@ -140,55 +140,6 @@ static void ath_beacon_setup(struct ath_softc *sc,
ctsrate, ctsduration, series, 4, 0); ctsrate, ctsduration, series, 4, 0);
} }
/* Move everything from the vap's mcast queue to the hardware cab queue.
* Caller must hold mcasq lock and cabq lock
* XXX MORE_DATA bit?
*/
static void empty_mcastq_into_cabq(struct ath_hal *ah,
struct ath_txq *mcastq, struct ath_txq *cabq)
{
struct ath_buf *bfmcast;
BUG_ON(list_empty(&mcastq->axq_q));
bfmcast = list_first_entry(&mcastq->axq_q, struct ath_buf, list);
/* link the descriptors */
if (!cabq->axq_link)
ath9k_hw_puttxbuf(ah, cabq->axq_qnum, bfmcast->bf_daddr);
else
*cabq->axq_link = bfmcast->bf_daddr;
/* append the private vap mcast list to the cabq */
cabq->axq_depth += mcastq->axq_depth;
cabq->axq_totalqueued += mcastq->axq_totalqueued;
cabq->axq_linkbuf = mcastq->axq_linkbuf;
cabq->axq_link = mcastq->axq_link;
list_splice_tail_init(&mcastq->axq_q, &cabq->axq_q);
mcastq->axq_depth = 0;
mcastq->axq_totalqueued = 0;
mcastq->axq_linkbuf = NULL;
mcastq->axq_link = NULL;
}
/* This is only run at DTIM. We move everything from the vap's mcast queue
* to the hardware cab queue. Caller must hold the mcastq lock. */
static void trigger_mcastq(struct ath_hal *ah,
struct ath_txq *mcastq, struct ath_txq *cabq)
{
spin_lock_bh(&cabq->axq_lock);
if (!list_empty(&mcastq->axq_q))
empty_mcastq_into_cabq(ah, mcastq, cabq);
/* cabq is gated by beacon so it is safe to start here */
if (!list_empty(&cabq->axq_q))
ath9k_hw_txstart(ah, cabq->axq_qnum);
spin_unlock_bh(&cabq->axq_lock);
}
/* /*
* Generate beacon frame and queue cab data for a vap. * Generate beacon frame and queue cab data for a vap.
* *
...@@ -199,19 +150,14 @@ static void trigger_mcastq(struct ath_hal *ah, ...@@ -199,19 +150,14 @@ static void trigger_mcastq(struct ath_hal *ah,
*/ */
static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
{ {
struct ath_hal *ah = sc->sc_ah;
struct ath_buf *bf; struct ath_buf *bf;
struct ath_vap *avp; struct ath_vap *avp;
struct sk_buff *skb; struct sk_buff *skb;
int cabq_depth; int cabq_depth;
int mcastq_depth;
int is_beacon_dtim = 0;
unsigned int curlen;
struct ath_txq *cabq; struct ath_txq *cabq;
struct ath_txq *mcastq; struct ieee80211_tx_info *info;
avp = sc->sc_vaps[if_id]; avp = sc->sc_vaps[if_id];
mcastq = &avp->av_mcastq;
cabq = sc->sc_cabq; cabq = sc->sc_cabq;
ASSERT(avp); ASSERT(avp);
...@@ -223,32 +169,33 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) ...@@ -223,32 +169,33 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
} }
bf = avp->av_bcbuf; bf = avp->av_bcbuf;
skb = (struct sk_buff *) bf->bf_mpdu; skb = (struct sk_buff *) bf->bf_mpdu;
if (skb) {
pci_unmap_single(sc->pdev, bf->bf_dmacontext,
skb_end_pointer(skb) - skb->head,
PCI_DMA_TODEVICE);
}
/* skb = ieee80211_beacon_get(sc->hw, avp->av_if_data);
* Update dynamic beacon contents. If this returns bf->bf_mpdu = skb;
* non-zero then we need to remap the memory because if (skb == NULL)
* the beacon frame changed size (probably because return NULL;
* of the TIM bitmap). info = IEEE80211_SKB_CB(skb);
*/ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
curlen = skb->len; /*
* TODO: make sure the seq# gets assigned properly (vs. other
/* XXX: spin_lock_bh should not be used here, but sparse bitches * TX frames)
* otherwise. We should fix sparse :) */ */
spin_lock_bh(&mcastq->axq_lock); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
mcastq_depth = avp->av_mcastq.axq_depth; sc->seq_no += 0x10;
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
if (ath_update_beacon(sc, if_id, &avp->av_boff, skb, mcastq_depth) == hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
1) {
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
get_dma_mem_context(bf, bf_dmacontext));
bf->bf_buf_addr = ath_skb_map_single(sc, skb, PCI_DMA_TODEVICE,
get_dma_mem_context(bf, bf_dmacontext));
} else {
pci_dma_sync_single_for_cpu(sc->pdev,
bf->bf_buf_addr,
skb_tailroom(skb),
PCI_DMA_TODEVICE);
} }
bf->bf_buf_addr = bf->bf_dmacontext =
pci_map_single(sc->pdev, skb->data,
skb_end_pointer(skb) - skb->head,
PCI_DMA_TODEVICE);
skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data);
/* /*
* if the CABQ traffic from previous DTIM is pending and the current * if the CABQ traffic from previous DTIM is pending and the current
...@@ -262,9 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) ...@@ -262,9 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
cabq_depth = cabq->axq_depth; cabq_depth = cabq->axq_depth;
spin_unlock_bh(&cabq->axq_lock); spin_unlock_bh(&cabq->axq_lock);
is_beacon_dtim = avp->av_boff.bo_tim[4] & 1; if (skb && cabq_depth) {
if (mcastq_depth && is_beacon_dtim && cabq_depth) {
/* /*
* Unlock the cabq lock as ath_tx_draintxq acquires * Unlock the cabq lock as ath_tx_draintxq acquires
* the lock again which is a common function and that * the lock again which is a common function and that
...@@ -284,10 +229,11 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) ...@@ -284,10 +229,11 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
* Enable the CAB queue before the beacon queue to * Enable the CAB queue before the beacon queue to
* insure cab frames are triggered by this beacon. * insure cab frames are triggered by this beacon.
*/ */
if (is_beacon_dtim) while (skb) {
trigger_mcastq(ah, mcastq, cabq); ath_tx_cabq(sc, skb);
skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data);
}
spin_unlock_bh(&mcastq->axq_lock);
return bf; return bf;
} }
...@@ -375,7 +321,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -375,7 +321,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
struct ath_buf, list); struct ath_buf, list);
list_del(&avp->av_bcbuf->list); list_del(&avp->av_bcbuf->list);
if (sc->sc_opmode == ATH9K_M_HOSTAP || if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP ||
!(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) { !(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
int slot; int slot;
/* /*
...@@ -408,8 +354,9 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -408,8 +354,9 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
bf = avp->av_bcbuf; bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) { if (bf->bf_mpdu != NULL) {
skb = (struct sk_buff *)bf->bf_mpdu; skb = (struct sk_buff *)bf->bf_mpdu;
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE, pci_unmap_single(sc->pdev, bf->bf_dmacontext,
get_dma_mem_context(bf, bf_dmacontext)); skb_end_pointer(skb) - skb->head,
PCI_DMA_TODEVICE);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL; bf->bf_mpdu = NULL;
} }
...@@ -418,7 +365,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -418,7 +365,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
* NB: the beacon data buffer must be 32-bit aligned; * NB: the beacon data buffer must be 32-bit aligned;
* we assume the wbuf routines will return us something * we assume the wbuf routines will return us something
* with this alignment (perhaps should assert). * with this alignment (perhaps should assert).
* FIXME: Fill avp->av_boff.bo_tim,avp->av_btxctl.txpower and * FIXME: Fill avp->av_btxctl.txpower and
* avp->av_btxctl.shortPreamble * avp->av_btxctl.shortPreamble
*/ */
skb = ieee80211_beacon_get(sc->hw, avp->av_if_data); skb = ieee80211_beacon_get(sc->hw, avp->av_if_data);
...@@ -439,9 +386,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -439,9 +386,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
__le64 val; __le64 val;
int intval; int intval;
/* FIXME: Use default value for now: Sujith */ intval = sc->hw->conf.beacon_int ?
sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
intval = ATH_DEFAULT_BINTVAL;
/* /*
* The beacon interval is in TU's; the TSF in usecs. * The beacon interval is in TU's; the TSF in usecs.
...@@ -466,8 +412,10 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -466,8 +412,10 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
memcpy(&wh[1], &val, sizeof(val)); memcpy(&wh[1], &val, sizeof(val));
} }
bf->bf_buf_addr = ath_skb_map_single(sc, skb, PCI_DMA_TODEVICE, bf->bf_buf_addr = bf->bf_dmacontext =
get_dma_mem_context(bf, bf_dmacontext)); pci_map_single(sc->pdev, skb->data,
skb_end_pointer(skb) - skb->head,
PCI_DMA_TODEVICE);
bf->bf_mpdu = skb; bf->bf_mpdu = skb;
return 0; return 0;
...@@ -493,8 +441,9 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) ...@@ -493,8 +441,9 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
bf = avp->av_bcbuf; bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) { if (bf->bf_mpdu != NULL) {
struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE, pci_unmap_single(sc->pdev, bf->bf_dmacontext,
get_dma_mem_context(bf, bf_dmacontext)); skb_end_pointer(skb) - skb->head,
PCI_DMA_TODEVICE);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL; bf->bf_mpdu = NULL;
} }
...@@ -504,30 +453,6 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) ...@@ -504,30 +453,6 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
} }
} }
/*
* Reclaim beacon resources and return buffer to the pool.
*
* This function will free any wbuf frames that are still attached to the
* beacon buffers in the ATH object. Note that this does not de-allocate
* any wbuf objects that are in the transmit queue and have not yet returned
* to the ATH object.
*/
void ath_beacon_free(struct ath_softc *sc)
{
struct ath_buf *bf;
list_for_each_entry(bf, &sc->sc_bbuf, list) {
if (bf->bf_mpdu != NULL) {
struct sk_buff *skb = (struct sk_buff *) bf->bf_mpdu;
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
get_dma_mem_context(bf, bf_dmacontext));
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
}
}
}
/* /*
* Tasklet for Sending Beacons * Tasklet for Sending Beacons
* *
...@@ -540,9 +465,6 @@ void ath_beacon_free(struct ath_softc *sc) ...@@ -540,9 +465,6 @@ void ath_beacon_free(struct ath_softc *sc)
void ath9k_beacon_tasklet(unsigned long data) void ath9k_beacon_tasklet(unsigned long data)
{ {
#define TSF_TO_TU(_h,_l) \
((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
struct ath_softc *sc = (struct ath_softc *)data; struct ath_softc *sc = (struct ath_softc *)data;
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
struct ath_buf *bf = NULL; struct ath_buf *bf = NULL;
...@@ -555,7 +477,7 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -555,7 +477,7 @@ void ath9k_beacon_tasklet(unsigned long data)
u32 tsftu; u32 tsftu;
u16 intval; u16 intval;
if (sc->sc_noreset) { if (sc->sc_flags & SC_OP_NO_RESET) {
show_cycles = ath9k_hw_GetMibCycleCountsPct(ah, show_cycles = ath9k_hw_GetMibCycleCountsPct(ah,
&rx_clear, &rx_clear,
&rx_frame, &rx_frame,
...@@ -577,7 +499,7 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -577,7 +499,7 @@ void ath9k_beacon_tasklet(unsigned long data)
* (in that layer). * (in that layer).
*/ */
if (sc->sc_bmisscount < BSTUCK_THRESH) { if (sc->sc_bmisscount < BSTUCK_THRESH) {
if (sc->sc_noreset) { if (sc->sc_flags & SC_OP_NO_RESET) {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: missed %u consecutive beacons\n", "%s: missed %u consecutive beacons\n",
__func__, sc->sc_bmisscount); __func__, sc->sc_bmisscount);
...@@ -605,7 +527,7 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -605,7 +527,7 @@ void ath9k_beacon_tasklet(unsigned long data)
__func__, sc->sc_bmisscount); __func__, sc->sc_bmisscount);
} }
} else if (sc->sc_bmisscount >= BSTUCK_THRESH) { } else if (sc->sc_bmisscount >= BSTUCK_THRESH) {
if (sc->sc_noreset) { if (sc->sc_flags & SC_OP_NO_RESET) {
if (sc->sc_bmisscount == BSTUCK_THRESH) { if (sc->sc_bmisscount == BSTUCK_THRESH) {
DPRINTF(sc, DPRINTF(sc,
ATH_DBG_BEACON, ATH_DBG_BEACON,
...@@ -624,7 +546,7 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -624,7 +546,7 @@ void ath9k_beacon_tasklet(unsigned long data)
return; return;
} }
if (sc->sc_bmisscount != 0) { if (sc->sc_bmisscount != 0) {
if (sc->sc_noreset) { if (sc->sc_flags & SC_OP_NO_RESET) {
DPRINTF(sc, DPRINTF(sc,
ATH_DBG_BEACON, ATH_DBG_BEACON,
"%s: resume beacon xmit after %u misses\n", "%s: resume beacon xmit after %u misses\n",
...@@ -643,8 +565,8 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -643,8 +565,8 @@ void ath9k_beacon_tasklet(unsigned long data)
* on the tsf to safeguard against missing an swba. * on the tsf to safeguard against missing an swba.
*/ */
/* FIXME: Use default value for now - Sujith */ intval = sc->hw->conf.beacon_int ?
intval = ATH_DEFAULT_BINTVAL; sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
tsf = ath9k_hw_gettsf64(ah); tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU(tsf>>32, tsf); tsftu = TSF_TO_TU(tsf>>32, tsf);
...@@ -704,7 +626,6 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -704,7 +626,6 @@ void ath9k_beacon_tasklet(unsigned long data)
sc->ast_be_xmit += bc; /* XXX per-vap? */ sc->ast_be_xmit += bc; /* XXX per-vap? */
} }
#undef TSF_TO_TU
} }
/* /*
...@@ -719,7 +640,7 @@ void ath_bstuck_process(struct ath_softc *sc) ...@@ -719,7 +640,7 @@ void ath_bstuck_process(struct ath_softc *sc)
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: stuck beacon; resetting (bmiss count %u)\n", "%s: stuck beacon; resetting (bmiss count %u)\n",
__func__, sc->sc_bmisscount); __func__, sc->sc_bmisscount);
ath_internal_reset(sc); ath_reset(sc, false);
} }
/* /*
...@@ -740,8 +661,6 @@ void ath_bstuck_process(struct ath_softc *sc) ...@@ -740,8 +661,6 @@ void ath_bstuck_process(struct ath_softc *sc)
void ath_beacon_config(struct ath_softc *sc, int if_id) void ath_beacon_config(struct ath_softc *sc, int if_id)
{ {
#define TSF_TO_TU(_h,_l) \
((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
u32 nexttbtt, intval; u32 nexttbtt, intval;
struct ath_beacon_config conf; struct ath_beacon_config conf;
...@@ -750,7 +669,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -750,7 +669,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
if (if_id != ATH_IF_ID_ANY) if (if_id != ATH_IF_ID_ANY)
av_opmode = sc->sc_vaps[if_id]->av_opmode; av_opmode = sc->sc_vaps[if_id]->av_opmode;
else else
av_opmode = sc->sc_opmode; av_opmode = sc->sc_ah->ah_opmode;
memzero(&conf, sizeof(struct ath_beacon_config)); memzero(&conf, sizeof(struct ath_beacon_config));
...@@ -760,7 +679,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -760,7 +679,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
* Protocol stack doesn't support dynamic beacon configuration, * Protocol stack doesn't support dynamic beacon configuration,
* use default configurations. * use default configurations.
*/ */
conf.beacon_interval = ATH_DEFAULT_BINTVAL; conf.beacon_interval = sc->hw->conf.beacon_int ?
sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
conf.listen_interval = 1; conf.listen_interval = 1;
conf.dtim_period = conf.beacon_interval; conf.dtim_period = conf.beacon_interval;
conf.dtim_count = 1; conf.dtim_count = 1;
...@@ -770,7 +690,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -770,7 +690,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
nexttbtt = TSF_TO_TU(get_unaligned_le32(conf.u.last_tstamp + 4), nexttbtt = TSF_TO_TU(get_unaligned_le32(conf.u.last_tstamp + 4),
get_unaligned_le32(conf.u.last_tstamp)); get_unaligned_le32(conf.u.last_tstamp));
/* XXX conditionalize multi-bss support? */ /* XXX conditionalize multi-bss support? */
if (sc->sc_opmode == ATH9K_M_HOSTAP) { if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
/* /*
* For multi-bss ap support beacons are either staggered * For multi-bss ap support beacons are either staggered
* evenly over N slots or burst together. For the former * evenly over N slots or burst together. For the former
...@@ -791,7 +711,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -791,7 +711,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n", DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
__func__, nexttbtt, intval, conf.beacon_interval); __func__, nexttbtt, intval, conf.beacon_interval);
/* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */ /* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */
if (sc->sc_opmode == ATH9K_M_STA) { if (sc->sc_ah->ah_opmode == ATH9K_M_STA) {
struct ath9k_beacon_state bs; struct ath9k_beacon_state bs;
u64 tsf; u64 tsf;
u32 tsftu; u32 tsftu;
...@@ -886,19 +806,19 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -886,19 +806,19 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
"cfp:period %u " "cfp:period %u "
"maxdur %u " "maxdur %u "
"next %u " "next %u "
"timoffset %u\n" "timoffset %u\n",
, __func__ __func__,
, (unsigned long long)tsf, tsftu (unsigned long long)tsf, tsftu,
, bs.bs_intval bs.bs_intval,
, bs.bs_nexttbtt bs.bs_nexttbtt,
, bs.bs_dtimperiod bs.bs_dtimperiod,
, bs.bs_nextdtim bs.bs_nextdtim,
, bs.bs_bmissthreshold bs.bs_bmissthreshold,
, bs.bs_sleepduration bs.bs_sleepduration,
, bs.bs_cfpperiod bs.bs_cfpperiod,
, bs.bs_cfpmaxduration bs.bs_cfpmaxduration,
, bs.bs_cfpnext bs.bs_cfpnext,
, bs.bs_timoffset bs.bs_timoffset
); );
ath9k_hw_set_interrupts(ah, 0); ath9k_hw_set_interrupts(ah, 0);
...@@ -911,7 +831,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -911,7 +831,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
ath9k_hw_set_interrupts(ah, 0); ath9k_hw_set_interrupts(ah, 0);
if (nexttbtt == intval) if (nexttbtt == intval)
intval |= ATH9K_BEACON_RESET_TSF; intval |= ATH9K_BEACON_RESET_TSF;
if (sc->sc_opmode == ATH9K_M_IBSS) { if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS) {
/* /*
* Pull nexttbtt forward to reflect the current * Pull nexttbtt forward to reflect the current
* TSF . * TSF .
...@@ -943,7 +863,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -943,7 +863,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
sc->sc_imask |= ATH9K_INT_SWBA; sc->sc_imask |= ATH9K_INT_SWBA;
ath_beaconq_config(sc); ath_beaconq_config(sc);
} else if (sc->sc_opmode == ATH9K_M_HOSTAP) { } else if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
/* /*
* In AP mode we enable the beacon timers and * In AP mode we enable the beacon timers and
* SWBA interrupts to prepare beacon frames. * SWBA interrupts to prepare beacon frames.
...@@ -959,11 +879,10 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -959,11 +879,10 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
* When using a self-linked beacon descriptor in * When using a self-linked beacon descriptor in
* ibss mode load it once here. * ibss mode load it once here.
*/ */
if (sc->sc_opmode == ATH9K_M_IBSS && if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS &&
(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
ath_beacon_start_adhoc(sc, 0); ath_beacon_start_adhoc(sc, 0);
} }
#undef TSF_TO_TU
} }
/* Function to collect beacon rssi data and resync beacon if necessary */ /* Function to collect beacon rssi data and resync beacon if necessary */
...@@ -975,5 +894,5 @@ void ath_beacon_sync(struct ath_softc *sc, int if_id) ...@@ -975,5 +894,5 @@ void ath_beacon_sync(struct ath_softc *sc, int if_id)
* beacon frame we just received. * beacon frame we just received.
*/ */
ath_beacon_config(sc, if_id); ath_beacon_config(sc, if_id);
sc->sc_beacons = 1; sc->sc_flags |= SC_OP_BEACONS;
} }
...@@ -21,9 +21,6 @@ ...@@ -21,9 +21,6 @@
static int ath_outdoor; /* enable outdoor use */ static int ath_outdoor; /* enable outdoor use */
static const u8 ath_bcast_mac[ETH_ALEN] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
static u32 ath_chainmask_sel_up_rssi_thres = static u32 ath_chainmask_sel_up_rssi_thres =
ATH_CHAINMASK_SEL_UP_RSSI_THRES; ATH_CHAINMASK_SEL_UP_RSSI_THRES;
static u32 ath_chainmask_sel_down_rssi_thres = static u32 ath_chainmask_sel_down_rssi_thres =
...@@ -54,10 +51,8 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz) ...@@ -54,10 +51,8 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz)
* Set current operating mode * Set current operating mode
* *
* This function initializes and fills the rate table in the ATH object based * This function initializes and fills the rate table in the ATH object based
* on the operating mode. The blink rates are also set up here, although * on the operating mode.
* they have been superceeded by the ath_led module.
*/ */
static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
{ {
const struct ath9k_rate_table *rt; const struct ath9k_rate_table *rt;
...@@ -235,7 +230,7 @@ static int ath_setup_channels(struct ath_softc *sc) ...@@ -235,7 +230,7 @@ static int ath_setup_channels(struct ath_softc *sc)
* Determine mode from channel flags * Determine mode from channel flags
* *
* This routine will provide the enumerated WIRELESSS_MODE value based * This routine will provide the enumerated WIRELESSS_MODE value based
* on the settings of the channel flags. If ho valid set of flags * on the settings of the channel flags. If no valid set of flags
* exist, the lowest mode (11b) is selected. * exist, the lowest mode (11b) is selected.
*/ */
...@@ -260,7 +255,8 @@ static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan) ...@@ -260,7 +255,8 @@ static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan)
else if (chan->chanmode == CHANNEL_G_HT40MINUS) else if (chan->chanmode == CHANNEL_G_HT40MINUS)
return ATH9K_MODE_11NG_HT40MINUS; return ATH9K_MODE_11NG_HT40MINUS;
/* NB: should not get here */ WARN_ON(1); /* should not get here */
return ATH9K_MODE_11B; return ATH9K_MODE_11B;
} }
...@@ -275,14 +271,12 @@ static int ath_stop(struct ath_softc *sc) ...@@ -275,14 +271,12 @@ static int ath_stop(struct ath_softc *sc)
{ {
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
DPRINTF(sc, ATH_DBG_CONFIG, "%s: invalid %u\n", DPRINTF(sc, ATH_DBG_CONFIG, "%s: invalid %ld\n",
__func__, sc->sc_invalid); __func__, sc->sc_flags & SC_OP_INVALID);
/* /*
* Shutdown the hardware and driver: * Shutdown the hardware and driver:
* stop output from above * stop output from above
* reset 802.11 state machine
* (sends station deassoc/deauth frames)
* turn off timers * turn off timers
* disable interrupts * disable interrupts
* clear transmit machinery * clear transmit machinery
...@@ -294,10 +288,10 @@ static int ath_stop(struct ath_softc *sc) ...@@ -294,10 +288,10 @@ static int ath_stop(struct ath_softc *sc)
* hardware is gone (invalid). * hardware is gone (invalid).
*/ */
if (!sc->sc_invalid) if (!(sc->sc_flags & SC_OP_INVALID))
ath9k_hw_set_interrupts(ah, 0); ath9k_hw_set_interrupts(ah, 0);
ath_draintxq(sc, false); ath_draintxq(sc, false);
if (!sc->sc_invalid) { if (!(sc->sc_flags & SC_OP_INVALID)) {
ath_stoprecv(sc); ath_stoprecv(sc);
ath9k_hw_phy_disable(ah); ath9k_hw_phy_disable(ah);
} else } else
...@@ -306,56 +300,6 @@ static int ath_stop(struct ath_softc *sc) ...@@ -306,56 +300,6 @@ static int ath_stop(struct ath_softc *sc)
return 0; return 0;
} }
/*
* Start Scan
*
* This function is called when starting a channel scan. It will perform
* power save wakeup processing, set the filter for the scan, and get the
* chip ready to send broadcast packets out during the scan.
*/
void ath_scan_start(struct ath_softc *sc)
{
struct ath_hal *ah = sc->sc_ah;
u32 rfilt;
u32 now = (u32) jiffies_to_msecs(get_timestamp());
sc->sc_scanning = 1;
rfilt = ath_calcrxfilter(sc);
ath9k_hw_setrxfilter(ah, rfilt);
ath9k_hw_write_associd(ah, ath_bcast_mac, 0);
/* Restore previous power management state. */
DPRINTF(sc, ATH_DBG_CONFIG, "%d.%03d | %s: RX filter 0x%x aid 0\n",
now / 1000, now % 1000, __func__, rfilt);
}
/*
* Scan End
*
* This routine is called by the upper layer when the scan is completed. This
* will set the filters back to normal operating mode, set the BSSID to the
* correct value, and restore the power save state.
*/
void ath_scan_end(struct ath_softc *sc)
{
struct ath_hal *ah = sc->sc_ah;
u32 rfilt;
u32 now = (u32) jiffies_to_msecs(get_timestamp());
sc->sc_scanning = 0;
/* Request for a full reset due to rx packet filter changes */
sc->sc_full_reset = 1;
rfilt = ath_calcrxfilter(sc);
ath9k_hw_setrxfilter(ah, rfilt);
ath9k_hw_write_associd(ah, sc->sc_curbssid, sc->sc_curaid);
DPRINTF(sc, ATH_DBG_CONFIG, "%d.%03d | %s: RX filter 0x%x aid 0x%x\n",
now / 1000, now % 1000, __func__, rfilt, sc->sc_curaid);
}
/* /*
* Set the current channel * Set the current channel
* *
...@@ -367,25 +311,23 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) ...@@ -367,25 +311,23 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
{ {
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
bool fastcc = true, stopped; bool fastcc = true, stopped;
enum ath9k_ht_macmode ht_macmode;
if (sc->sc_invalid) /* if the device is invalid or removed */ if (sc->sc_flags & SC_OP_INVALID) /* the device is invalid or removed */
return -EIO; return -EIO;
DPRINTF(sc, ATH_DBG_CONFIG, DPRINTF(sc, ATH_DBG_CONFIG,
"%s: %u (%u MHz) -> %u (%u MHz), cflags:%x\n", "%s: %u (%u MHz) -> %u (%u MHz), cflags:%x\n",
__func__, __func__,
ath9k_hw_mhz2ieee(ah, sc->sc_curchan.channel, ath9k_hw_mhz2ieee(ah, sc->sc_ah->ah_curchan->channel,
sc->sc_curchan.channelFlags), sc->sc_ah->ah_curchan->channelFlags),
sc->sc_curchan.channel, sc->sc_ah->ah_curchan->channel,
ath9k_hw_mhz2ieee(ah, hchan->channel, hchan->channelFlags), ath9k_hw_mhz2ieee(ah, hchan->channel, hchan->channelFlags),
hchan->channel, hchan->channelFlags); hchan->channel, hchan->channelFlags);
ht_macmode = ath_cwm_macmode(sc); if (hchan->channel != sc->sc_ah->ah_curchan->channel ||
hchan->channelFlags != sc->sc_ah->ah_curchan->channelFlags ||
if (hchan->channel != sc->sc_curchan.channel || (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) ||
hchan->channelFlags != sc->sc_curchan.channelFlags || (sc->sc_flags & SC_OP_FULL_RESET)) {
sc->sc_update_chainmask || sc->sc_full_reset) {
int status; int status;
/* /*
* This is only performed if the channel settings have * This is only performed if the channel settings have
...@@ -404,15 +346,16 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) ...@@ -404,15 +346,16 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
* to flush data frames already in queue because of * to flush data frames already in queue because of
* changing channel. */ * changing channel. */
if (!stopped || sc->sc_full_reset) if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
fastcc = false; fastcc = false;
spin_lock_bh(&sc->sc_resetlock); spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(ah, sc->sc_opmode, hchan, if (!ath9k_hw_reset(ah, hchan,
ht_macmode, sc->sc_tx_chainmask, sc->sc_ht_info.tx_chan_width,
sc->sc_rx_chainmask, sc->sc_tx_chainmask,
sc->sc_ht_extprotspacing, sc->sc_rx_chainmask,
fastcc, &status)) { sc->sc_ht_extprotspacing,
fastcc, &status)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: unable to reset channel %u (%uMhz) " "%s: unable to reset channel %u (%uMhz) "
"flags 0x%x hal status %u\n", __func__, "flags 0x%x hal status %u\n", __func__,
...@@ -424,9 +367,8 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) ...@@ -424,9 +367,8 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
} }
spin_unlock_bh(&sc->sc_resetlock); spin_unlock_bh(&sc->sc_resetlock);
sc->sc_curchan = *hchan; sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE;
sc->sc_update_chainmask = 0; sc->sc_flags &= ~SC_OP_FULL_RESET;
sc->sc_full_reset = 0;
/* Re-enable rx framework */ /* Re-enable rx framework */
if (ath_startrecv(sc) != 0) { if (ath_startrecv(sc) != 0) {
...@@ -537,7 +479,7 @@ int ath_chainmask_sel_logic(struct ath_softc *sc, struct ath_node *an) ...@@ -537,7 +479,7 @@ int ath_chainmask_sel_logic(struct ath_softc *sc, struct ath_node *an)
void ath_update_chainmask(struct ath_softc *sc, int is_ht) void ath_update_chainmask(struct ath_softc *sc, int is_ht)
{ {
sc->sc_update_chainmask = 1; sc->sc_flags |= SC_OP_CHAINMASK_UPDATE;
if (is_ht) { if (is_ht) {
sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask; sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask;
sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask; sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask;
...@@ -554,62 +496,6 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht) ...@@ -554,62 +496,6 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht)
/* VAP management */ /* VAP management */
/******************/ /******************/
/*
* VAP in Listen mode
*
* This routine brings the VAP out of the down state into a "listen" state
* where it waits for association requests. This is used in AP and AdHoc
* modes.
*/
int ath_vap_listen(struct ath_softc *sc, int if_id)
{
struct ath_hal *ah = sc->sc_ah;
struct ath_vap *avp;
u32 rfilt = 0;
DECLARE_MAC_BUF(mac);
avp = sc->sc_vaps[if_id];
if (avp == NULL) {
DPRINTF(sc, ATH_DBG_FATAL, "%s: invalid interface id %u\n",
__func__, if_id);
return -EINVAL;
}
#ifdef CONFIG_SLOW_ANT_DIV
ath_slow_ant_div_stop(&sc->sc_antdiv);
#endif
/* update ratectrl about the new state */
ath_rate_newstate(sc, avp);
rfilt = ath_calcrxfilter(sc);
ath9k_hw_setrxfilter(ah, rfilt);
if (sc->sc_opmode == ATH9K_M_STA || sc->sc_opmode == ATH9K_M_IBSS) {
memcpy(sc->sc_curbssid, ath_bcast_mac, ETH_ALEN);
ath9k_hw_write_associd(ah, sc->sc_curbssid, sc->sc_curaid);
} else
sc->sc_curaid = 0;
DPRINTF(sc, ATH_DBG_CONFIG,
"%s: RX filter 0x%x bssid %s aid 0x%x\n",
__func__, rfilt, print_mac(mac,
sc->sc_curbssid), sc->sc_curaid);
/*
* XXXX
* Disable BMISS interrupt when we're not associated
*/
ath9k_hw_set_interrupts(ah,
sc->sc_imask & ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS));
sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
/* need to reconfigure the beacons when it moves to RUN */
sc->sc_beacons = 0;
return 0;
}
int ath_vap_attach(struct ath_softc *sc, int ath_vap_attach(struct ath_softc *sc,
int if_id, int if_id,
struct ieee80211_vif *if_data, struct ieee80211_vif *if_data,
...@@ -647,16 +533,13 @@ int ath_vap_attach(struct ath_softc *sc, ...@@ -647,16 +533,13 @@ int ath_vap_attach(struct ath_softc *sc,
/* Set the VAP opmode */ /* Set the VAP opmode */
avp->av_opmode = opmode; avp->av_opmode = opmode;
avp->av_bslot = -1; avp->av_bslot = -1;
INIT_LIST_HEAD(&avp->av_mcastq.axq_q);
INIT_LIST_HEAD(&avp->av_mcastq.axq_acq);
spin_lock_init(&avp->av_mcastq.axq_lock);
ath9k_hw_set_tsfadjust(sc->sc_ah, 1); ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
sc->sc_vaps[if_id] = avp; sc->sc_vaps[if_id] = avp;
sc->sc_nvaps++; sc->sc_nvaps++;
/* Set the device opmode */ /* Set the device opmode */
sc->sc_opmode = opmode; sc->sc_ah->ah_opmode = opmode;
/* default VAP configuration */ /* default VAP configuration */
avp->av_config.av_fixed_rateset = IEEE80211_FIXED_RATE_NONE; avp->av_config.av_fixed_rateset = IEEE80211_FIXED_RATE_NONE;
...@@ -689,9 +572,6 @@ int ath_vap_detach(struct ath_softc *sc, int if_id) ...@@ -689,9 +572,6 @@ int ath_vap_detach(struct ath_softc *sc, int if_id)
ath_stoprecv(sc); /* stop recv side */ ath_stoprecv(sc); /* stop recv side */
ath_flushrecv(sc); /* flush recv queue */ ath_flushrecv(sc); /* flush recv queue */
/* Reclaim any pending mcast bufs on the vap. */
ath_tx_draintxq(sc, &avp->av_mcastq, false);
kfree(avp); kfree(avp);
sc->sc_vaps[if_id] = NULL; sc->sc_vaps[if_id] = NULL;
sc->sc_nvaps--; sc->sc_nvaps--;
...@@ -728,9 +608,9 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) ...@@ -728,9 +608,9 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
int status; int status;
int error = 0; int error = 0;
enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc);
DPRINTF(sc, ATH_DBG_CONFIG, "%s: mode %d\n", __func__, sc->sc_opmode); DPRINTF(sc, ATH_DBG_CONFIG, "%s: mode %d\n",
__func__, sc->sc_ah->ah_opmode);
/* /*
* Stop anything previously setup. This is safe * Stop anything previously setup. This is safe
...@@ -752,16 +632,16 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) ...@@ -752,16 +632,16 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
* be followed by initialization of the appropriate bits * be followed by initialization of the appropriate bits
* and then setup of the interrupt mask. * and then setup of the interrupt mask.
*/ */
sc->sc_curchan = *initial_chan;
spin_lock_bh(&sc->sc_resetlock); spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(ah, sc->sc_opmode, &sc->sc_curchan, ht_macmode, if (!ath9k_hw_reset(ah, initial_chan,
sc->sc_tx_chainmask, sc->sc_rx_chainmask, sc->sc_ht_info.tx_chan_width,
sc->sc_ht_extprotspacing, false, &status)) { sc->sc_tx_chainmask, sc->sc_rx_chainmask,
sc->sc_ht_extprotspacing, false, &status)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: unable to reset hardware; hal status %u " "%s: unable to reset hardware; hal status %u "
"(freq %u flags 0x%x)\n", __func__, status, "(freq %u flags 0x%x)\n", __func__, status,
sc->sc_curchan.channel, sc->sc_curchan.channelFlags); initial_chan->channel, initial_chan->channelFlags);
error = -EIO; error = -EIO;
spin_unlock_bh(&sc->sc_resetlock); spin_unlock_bh(&sc->sc_resetlock);
goto done; goto done;
...@@ -802,7 +682,8 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) ...@@ -802,7 +682,8 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
* Note we only do this (at the moment) for station mode. * Note we only do this (at the moment) for station mode.
*/ */
if (ath9k_hw_phycounters(ah) && if (ath9k_hw_phycounters(ah) &&
((sc->sc_opmode == ATH9K_M_STA) || (sc->sc_opmode == ATH9K_M_IBSS))) ((sc->sc_ah->ah_opmode == ATH9K_M_STA) ||
(sc->sc_ah->ah_opmode == ATH9K_M_IBSS)))
sc->sc_imask |= ATH9K_INT_MIB; sc->sc_imask |= ATH9K_INT_MIB;
/* /*
* Some hardware processes the TIM IE and fires an * Some hardware processes the TIM IE and fires an
...@@ -811,7 +692,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) ...@@ -811,7 +692,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
* enable the TIM interrupt when operating as station. * enable the TIM interrupt when operating as station.
*/ */
if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) && if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) &&
(sc->sc_opmode == ATH9K_M_STA) && (sc->sc_ah->ah_opmode == ATH9K_M_STA) &&
!sc->sc_config.swBeaconProcess) !sc->sc_config.swBeaconProcess)
sc->sc_imask |= ATH9K_INT_TIM; sc->sc_imask |= ATH9K_INT_TIM;
/* /*
...@@ -823,34 +704,34 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) ...@@ -823,34 +704,34 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
/* XXX: we must make sure h/w is ready and clear invalid flag /* XXX: we must make sure h/w is ready and clear invalid flag
* before turning on interrupt. */ * before turning on interrupt. */
sc->sc_invalid = 0; sc->sc_flags &= ~SC_OP_INVALID;
done: done:
return error; return error;
} }
/* int ath_reset(struct ath_softc *sc, bool retry_tx)
* Reset the hardware w/o losing operational state. This is
* basically a more efficient way of doing ath_stop, ath_init,
* followed by state transitions to the current 802.11
* operational state. Used to recover from errors rx overrun
* and to reset the hardware when rf gain settings must be reset.
*/
static int ath_reset_start(struct ath_softc *sc, u32 flag)
{ {
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
int status;
int error = 0;
ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */ ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */
ath_draintxq(sc, flag & RESET_RETRY_TXQ); /* stop xmit side */ ath_draintxq(sc, retry_tx); /* stop xmit */
ath_stoprecv(sc); /* stop recv side */ ath_stoprecv(sc); /* stop recv */
ath_flushrecv(sc); /* flush recv queue */ ath_flushrecv(sc); /* flush recv queue */
return 0; /* Reset chip */
} spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan,
static int ath_reset_end(struct ath_softc *sc, u32 flag) sc->sc_ht_info.tx_chan_width,
{ sc->sc_tx_chainmask, sc->sc_rx_chainmask,
struct ath_hal *ah = sc->sc_ah; sc->sc_ht_extprotspacing, false, &status)) {
DPRINTF(sc, ATH_DBG_FATAL,
"%s: unable to reset hardware; hal status %u\n",
__func__, status);
error = -EIO;
}
spin_unlock_bh(&sc->sc_resetlock);
if (ath_startrecv(sc) != 0) /* restart recv */ if (ath_startrecv(sc) != 0) /* restart recv */
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
...@@ -861,16 +742,17 @@ static int ath_reset_end(struct ath_softc *sc, u32 flag) ...@@ -861,16 +742,17 @@ static int ath_reset_end(struct ath_softc *sc, u32 flag)
* that changes the channel so update any state that * that changes the channel so update any state that
* might change as a result. * might change as a result.
*/ */
ath_setcurmode(sc, ath_chan2mode(&sc->sc_curchan)); ath_setcurmode(sc, ath_chan2mode(sc->sc_ah->ah_curchan));
ath_update_txpow(sc); /* update tx power state */ ath_update_txpow(sc);
if (sc->sc_beacons) if (sc->sc_flags & SC_OP_BEACONS)
ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */ ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */
ath9k_hw_set_interrupts(ah, sc->sc_imask); ath9k_hw_set_interrupts(ah, sc->sc_imask);
/* Restart the txq */ /* Restart the txq */
if (flag & RESET_RETRY_TXQ) { if (retry_tx) {
int i; int i;
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i)) { if (ATH_TXQ_SETUP(sc, i)) {
...@@ -880,28 +762,6 @@ static int ath_reset_end(struct ath_softc *sc, u32 flag) ...@@ -880,28 +762,6 @@ static int ath_reset_end(struct ath_softc *sc, u32 flag)
} }
} }
} }
return 0;
}
int ath_reset(struct ath_softc *sc)
{
struct ath_hal *ah = sc->sc_ah;
int status;
int error = 0;
enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc);
/* NB: indicate channel change so we do a full reset */
spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(ah, sc->sc_opmode, &sc->sc_curchan,
ht_macmode,
sc->sc_tx_chainmask, sc->sc_rx_chainmask,
sc->sc_ht_extprotspacing, false, &status)) {
DPRINTF(sc, ATH_DBG_FATAL,
"%s: unable to reset hardware; hal status %u\n",
__func__, status);
error = -EIO;
}
spin_unlock_bh(&sc->sc_resetlock);
return error; return error;
} }
...@@ -911,7 +771,7 @@ int ath_suspend(struct ath_softc *sc) ...@@ -911,7 +771,7 @@ int ath_suspend(struct ath_softc *sc)
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
/* No I/O if device has been surprise removed */ /* No I/O if device has been surprise removed */
if (sc->sc_invalid) if (sc->sc_flags & SC_OP_INVALID)
return -EIO; return -EIO;
/* Shut off the interrupt before setting sc->sc_invalid to '1' */ /* Shut off the interrupt before setting sc->sc_invalid to '1' */
...@@ -919,7 +779,7 @@ int ath_suspend(struct ath_softc *sc) ...@@ -919,7 +779,7 @@ int ath_suspend(struct ath_softc *sc)
/* XXX: we must make sure h/w will not generate any interrupt /* XXX: we must make sure h/w will not generate any interrupt
* before setting the invalid flag. */ * before setting the invalid flag. */
sc->sc_invalid = 1; sc->sc_flags |= SC_OP_INVALID;
/* disable HAL and put h/w to sleep */ /* disable HAL and put h/w to sleep */
ath9k_hw_disable(sc->sc_ah); ath9k_hw_disable(sc->sc_ah);
...@@ -940,7 +800,7 @@ irqreturn_t ath_isr(int irq, void *dev) ...@@ -940,7 +800,7 @@ irqreturn_t ath_isr(int irq, void *dev)
bool sched = false; bool sched = false;
do { do {
if (sc->sc_invalid) { if (sc->sc_flags & SC_OP_INVALID) {
/* /*
* The hardware is not ready/present, don't * The hardware is not ready/present, don't
* touch anything. Note this can happen early * touch anything. Note this can happen early
...@@ -1050,7 +910,7 @@ static void ath9k_tasklet(unsigned long data) ...@@ -1050,7 +910,7 @@ static void ath9k_tasklet(unsigned long data)
if (status & ATH9K_INT_FATAL) { if (status & ATH9K_INT_FATAL) {
/* need a chip reset */ /* need a chip reset */
ath_internal_reset(sc); ath_reset(sc, false);
return; return;
} else { } else {
...@@ -1093,10 +953,9 @@ int ath_init(u16 devid, struct ath_softc *sc) ...@@ -1093,10 +953,9 @@ int ath_init(u16 devid, struct ath_softc *sc)
int status; int status;
int error = 0, i; int error = 0, i;
int csz = 0; int csz = 0;
u32 rd;
/* XXX: hardware will not be ready until ath_open() being called */ /* XXX: hardware will not be ready until ath_open() being called */
sc->sc_invalid = 1; sc->sc_flags |= SC_OP_INVALID;
sc->sc_debug = DBG_DEFAULT; sc->sc_debug = DBG_DEFAULT;
DPRINTF(sc, ATH_DBG_CONFIG, "%s: devid 0x%x\n", __func__, devid); DPRINTF(sc, ATH_DBG_CONFIG, "%s: devid 0x%x\n", __func__, devid);
...@@ -1126,9 +985,6 @@ int ath_init(u16 devid, struct ath_softc *sc) ...@@ -1126,9 +985,6 @@ int ath_init(u16 devid, struct ath_softc *sc)
} }
sc->sc_ah = ah; sc->sc_ah = ah;
/* Get the chipset-specific aggr limit. */
sc->sc_rtsaggrlimit = ah->ah_caps.rts_aggr_limit;
/* Get the hardware key cache size. */ /* Get the hardware key cache size. */
sc->sc_keymax = ah->ah_caps.keycache_size; sc->sc_keymax = ah->ah_caps.keycache_size;
if (sc->sc_keymax > ATH_KEYMAX) { if (sc->sc_keymax > ATH_KEYMAX) {
...@@ -1162,14 +1018,12 @@ int ath_init(u16 devid, struct ath_softc *sc) ...@@ -1162,14 +1018,12 @@ int ath_init(u16 devid, struct ath_softc *sc)
* is resposible for filtering this list based on settings * is resposible for filtering this list based on settings
* like the phy mode. * like the phy mode.
*/ */
rd = ah->ah_currentRD;
error = ath_setup_channels(sc); error = ath_setup_channels(sc);
if (error) if (error)
goto bad; goto bad;
/* default to STA mode */ /* default to STA mode */
sc->sc_opmode = ATH9K_M_MONITOR; sc->sc_ah->ah_opmode = ATH9K_M_MONITOR;
/* Setup rate tables */ /* Setup rate tables */
...@@ -1240,7 +1094,7 @@ int ath_init(u16 devid, struct ath_softc *sc) ...@@ -1240,7 +1094,7 @@ int ath_init(u16 devid, struct ath_softc *sc)
sc->sc_rc = ath_rate_attach(ah); sc->sc_rc = ath_rate_attach(ah);
if (sc->sc_rc == NULL) { if (sc->sc_rc == NULL) {
error = EIO; error = -EIO;
goto bad2; goto bad2;
} }
...@@ -1280,20 +1134,13 @@ int ath_init(u16 devid, struct ath_softc *sc) ...@@ -1280,20 +1134,13 @@ int ath_init(u16 devid, struct ath_softc *sc)
/* 11n Capabilities */ /* 11n Capabilities */
if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) { if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
sc->sc_txaggr = 1; sc->sc_flags |= SC_OP_TXAGGR;
sc->sc_rxaggr = 1; sc->sc_flags |= SC_OP_RXAGGR;
} }
sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask; sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask;
sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask; sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask;
/* Configuration for rx chain detection */
sc->sc_rxchaindetect_ref = 0;
sc->sc_rxchaindetect_thresh5GHz = 35;
sc->sc_rxchaindetect_thresh2GHz = 35;
sc->sc_rxchaindetect_delta5GHz = 30;
sc->sc_rxchaindetect_delta2GHz = 30;
ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
sc->sc_defant = ath9k_hw_getdefantenna(ah); sc->sc_defant = ath9k_hw_getdefantenna(ah);
...@@ -1337,7 +1184,7 @@ void ath_deinit(struct ath_softc *sc) ...@@ -1337,7 +1184,7 @@ void ath_deinit(struct ath_softc *sc)
DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__); DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__);
ath_stop(sc); ath_stop(sc);
if (!sc->sc_invalid) if (!(sc->sc_flags & SC_OP_INVALID))
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
ath_rate_detach(sc->sc_rc); ath_rate_detach(sc->sc_rc);
/* cleanup tx queues */ /* cleanup tx queues */
...@@ -1464,9 +1311,9 @@ void ath_newassoc(struct ath_softc *sc, ...@@ -1464,9 +1311,9 @@ void ath_newassoc(struct ath_softc *sc,
/* if station reassociates, tear down the aggregation state. */ /* if station reassociates, tear down the aggregation state. */
if (!isnew) { if (!isnew) {
for (tidno = 0; tidno < WME_NUM_TID; tidno++) { for (tidno = 0; tidno < WME_NUM_TID; tidno++) {
if (sc->sc_txaggr) if (sc->sc_flags & SC_OP_TXAGGR)
ath_tx_aggr_teardown(sc, an, tidno); ath_tx_aggr_teardown(sc, an, tidno);
if (sc->sc_rxaggr) if (sc->sc_flags & SC_OP_RXAGGR)
ath_rx_aggr_teardown(sc, an, tidno); ath_rx_aggr_teardown(sc, an, tidno);
} }
} }
...@@ -1815,13 +1662,6 @@ void ath_descdma_cleanup(struct ath_softc *sc, ...@@ -1815,13 +1662,6 @@ void ath_descdma_cleanup(struct ath_softc *sc,
/* Utilities */ /* Utilities */
/*************/ /*************/
void ath_internal_reset(struct ath_softc *sc)
{
ath_reset_start(sc, 0);
ath_reset(sc);
ath_reset_end(sc, 0);
}
int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
{ {
int qnum; int qnum;
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <asm/page.h> #include <asm/page.h>
#include <net/mac80211.h> #include <net/mac80211.h>
#include <linux/leds.h>
#include "ath9k.h" #include "ath9k.h"
#include "rc.h" #include "rc.h"
...@@ -79,12 +80,12 @@ struct ath_node; ...@@ -79,12 +80,12 @@ struct ath_node;
} \ } \
} while (0) } while (0)
#define TSF_TO_TU(_h,_l) \
((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
/* XXX: remove */ /* XXX: remove */
#define memzero(_buf, _len) memset(_buf, 0, _len) #define memzero(_buf, _len) memset(_buf, 0, _len)
#define get_dma_mem_context(var, field) (&((var)->field))
#define copy_dma_mem_context(dst, src) (*dst = *src)
#define ATH9K_BH_STATUS_INTACT 0 #define ATH9K_BH_STATUS_INTACT 0
#define ATH9K_BH_STATUS_CHANGE 1 #define ATH9K_BH_STATUS_CHANGE 1
...@@ -95,6 +96,8 @@ static inline unsigned long get_timestamp(void) ...@@ -95,6 +96,8 @@ static inline unsigned long get_timestamp(void)
return ((jiffies / HZ) * 1000) + (jiffies % HZ) * (1000 / HZ); return ((jiffies / HZ) * 1000) + (jiffies % HZ) * (1000 / HZ);
} }
static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
/*************/ /*************/
/* Debugging */ /* Debugging */
/*************/ /*************/
...@@ -175,11 +178,6 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht); ...@@ -175,11 +178,6 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht);
/* Descriptor Management */ /* Descriptor Management */
/*************************/ /*************************/
/* Number of descriptors per buffer. The only case where we see skbuff
chains is due to FF aggregation in the driver. */
#define ATH_TXDESC 1
/* if there's more fragment for this MSDU */
#define ATH_BF_MORE_MPDU 1
#define ATH_TXBUF_RESET(_bf) do { \ #define ATH_TXBUF_RESET(_bf) do { \
(_bf)->bf_status = 0; \ (_bf)->bf_status = 0; \
(_bf)->bf_lastbf = NULL; \ (_bf)->bf_lastbf = NULL; \
...@@ -189,28 +187,29 @@ chains is due to FF aggregation in the driver. */ ...@@ -189,28 +187,29 @@ chains is due to FF aggregation in the driver. */
sizeof(struct ath_buf_state)); \ sizeof(struct ath_buf_state)); \
} while (0) } while (0)
enum buffer_type {
BUF_DATA = BIT(0),
BUF_AGGR = BIT(1),
BUF_AMPDU = BIT(2),
BUF_HT = BIT(3),
BUF_RETRY = BIT(4),
BUF_XRETRY = BIT(5),
BUF_SHORT_PREAMBLE = BIT(6),
BUF_BAR = BIT(7),
BUF_PSPOLL = BIT(8),
BUF_AGGR_BURST = BIT(9),
BUF_CALC_AIRTIME = BIT(10),
};
struct ath_buf_state { struct ath_buf_state {
int bfs_nframes; /* # frames in aggregate */ int bfs_nframes; /* # frames in aggregate */
u16 bfs_al; /* length of aggregate */ u16 bfs_al; /* length of aggregate */
u16 bfs_frmlen; /* length of frame */ u16 bfs_frmlen; /* length of frame */
int bfs_seqno; /* sequence number */ int bfs_seqno; /* sequence number */
int bfs_tidno; /* tid of this frame */ int bfs_tidno; /* tid of this frame */
int bfs_retries; /* current retries */ int bfs_retries; /* current retries */
struct ath_rc_series bfs_rcs[4]; /* rate series */ struct ath_rc_series bfs_rcs[4]; /* rate series */
u8 bfs_isdata:1; /* is a data frame/aggregate */ u32 bf_type; /* BUF_* (enum buffer_type) */
u8 bfs_isaggr:1; /* is an aggregate */
u8 bfs_isampdu:1; /* is an a-mpdu, aggregate or not */
u8 bfs_ht:1; /* is an HT frame */
u8 bfs_isretried:1; /* is retried */
u8 bfs_isxretried:1; /* is excessive retried */
u8 bfs_shpreamble:1; /* is short preamble */
u8 bfs_isbar:1; /* is a BAR */
u8 bfs_ispspoll:1; /* is a PS-Poll */
u8 bfs_aggrburst:1; /* is a aggr burst */
u8 bfs_calcairtime:1; /* requests airtime be calculated
when set for tx frame */
int bfs_rifsburst_elem; /* RIFS burst/bar */
int bfs_nrifsubframes; /* # of elements in burst */
/* key type use to encrypt this frame */ /* key type use to encrypt this frame */
enum ath9k_key_type bfs_keytype; enum ath9k_key_type bfs_keytype;
}; };
...@@ -222,26 +221,22 @@ struct ath_buf_state { ...@@ -222,26 +221,22 @@ struct ath_buf_state {
#define bf_seqno bf_state.bfs_seqno #define bf_seqno bf_state.bfs_seqno
#define bf_tidno bf_state.bfs_tidno #define bf_tidno bf_state.bfs_tidno
#define bf_rcs bf_state.bfs_rcs #define bf_rcs bf_state.bfs_rcs
#define bf_isdata bf_state.bfs_isdata
#define bf_isaggr bf_state.bfs_isaggr
#define bf_isampdu bf_state.bfs_isampdu
#define bf_ht bf_state.bfs_ht
#define bf_isretried bf_state.bfs_isretried
#define bf_isxretried bf_state.bfs_isxretried
#define bf_shpreamble bf_state.bfs_shpreamble
#define bf_rifsburst_elem bf_state.bfs_rifsburst_elem
#define bf_nrifsubframes bf_state.bfs_nrifsubframes
#define bf_keytype bf_state.bfs_keytype #define bf_keytype bf_state.bfs_keytype
#define bf_isbar bf_state.bfs_isbar #define bf_isdata(bf) (bf->bf_state.bf_type & BUF_DATA)
#define bf_ispspoll bf_state.bfs_ispspoll #define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
#define bf_aggrburst bf_state.bfs_aggrburst #define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
#define bf_calcairtime bf_state.bfs_calcairtime #define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT)
#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
#define bf_isshpreamble(bf) (bf->bf_state.bf_type & BUF_SHORT_PREAMBLE)
#define bf_isbar(bf) (bf->bf_state.bf_type & BUF_BAR)
#define bf_ispspoll(bf) (bf->bf_state.bf_type & BUF_PSPOLL)
#define bf_isaggrburst(bf) (bf->bf_state.bf_type & BUF_AGGR_BURST)
/* /*
* Abstraction of a contiguous buffer to transmit/receive. There is only * Abstraction of a contiguous buffer to transmit/receive. There is only
* a single hw descriptor encapsulated here. * a single hw descriptor encapsulated here.
*/ */
struct ath_buf { struct ath_buf {
struct list_head list; struct list_head list;
struct list_head *last; struct list_head *last;
...@@ -391,10 +386,10 @@ int ath_rx_input(struct ath_softc *sc, ...@@ -391,10 +386,10 @@ int ath_rx_input(struct ath_softc *sc,
struct sk_buff *skb, struct sk_buff *skb,
struct ath_recv_status *rx_status, struct ath_recv_status *rx_status,
enum ATH_RX_TYPE *status); enum ATH_RX_TYPE *status);
int ath__rx_indicate(struct ath_softc *sc, int _ath_rx_indicate(struct ath_softc *sc,
struct sk_buff *skb, struct sk_buff *skb,
struct ath_recv_status *status, struct ath_recv_status *status,
u16 keyix); u16 keyix);
int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb, int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb,
struct ath_recv_status *status); struct ath_recv_status *status);
...@@ -402,8 +397,7 @@ int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb, ...@@ -402,8 +397,7 @@ int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb,
/* TX */ /* TX */
/******/ /******/
#define ATH_FRAG_PER_MSDU 1 #define ATH_TXBUF 512
#define ATH_TXBUF (512/ATH_FRAG_PER_MSDU)
/* max number of transmit attempts (tries) */ /* max number of transmit attempts (tries) */
#define ATH_TXMAXTRY 13 #define ATH_TXMAXTRY 13
/* max number of 11n transmit attempts (tries) */ /* max number of 11n transmit attempts (tries) */
...@@ -522,7 +516,6 @@ struct ath_tx_control { ...@@ -522,7 +516,6 @@ struct ath_tx_control {
u32 keyix; u32 keyix;
int min_rate; int min_rate;
int mcast_rate; int mcast_rate;
u16 nextfraglen;
struct ath_softc *dev; struct ath_softc *dev;
dma_addr_t dmacontext; dma_addr_t dmacontext;
}; };
...@@ -557,10 +550,10 @@ void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); ...@@ -557,10 +550,10 @@ void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
int ath_tx_setup(struct ath_softc *sc, int haltype); int ath_tx_setup(struct ath_softc *sc, int haltype);
void ath_draintxq(struct ath_softc *sc, bool retry_tx); void ath_draintxq(struct ath_softc *sc, bool retry_tx);
void ath_tx_draintxq(struct ath_softc *sc, void ath_tx_draintxq(struct ath_softc *sc,
struct ath_txq *txq, bool retry_tx); struct ath_txq *txq, bool retry_tx);
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
void ath_tx_node_cleanup(struct ath_softc *sc, void ath_tx_node_cleanup(struct ath_softc *sc,
struct ath_node *an, bool bh_flag); struct ath_node *an, bool bh_flag);
void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an); void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an);
void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
int ath_tx_init(struct ath_softc *sc, int nbufs); int ath_tx_init(struct ath_softc *sc, int nbufs);
...@@ -575,6 +568,7 @@ u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum); ...@@ -575,6 +568,7 @@ u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum);
void ath_notify_txq_status(struct ath_softc *sc, u16 queue_depth); void ath_notify_txq_status(struct ath_softc *sc, u16 queue_depth);
void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
struct ath_xmit_status *tx_status, struct ath_node *an); struct ath_xmit_status *tx_status, struct ath_node *an);
void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
/**********************/ /**********************/
/* Node / Aggregation */ /* Node / Aggregation */
...@@ -585,7 +579,6 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, ...@@ -585,7 +579,6 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
/* indicates the node is 80211 power save */ /* indicates the node is 80211 power save */
#define ATH_NODE_PWRSAVE 0x2 #define ATH_NODE_PWRSAVE 0x2
#define ADDBA_TIMEOUT 200 /* 200 milliseconds */
#define ADDBA_EXCHANGE_ATTEMPTS 10 #define ADDBA_EXCHANGE_ATTEMPTS 10
#define ATH_AGGR_DELIM_SZ 4 /* delimiter size */ #define ATH_AGGR_DELIM_SZ 4 /* delimiter size */
#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
...@@ -705,9 +698,6 @@ struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr); ...@@ -705,9 +698,6 @@ struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr);
#define ATH_BCBUF 4 /* number of beacon buffers */ #define ATH_BCBUF 4 /* number of beacon buffers */
#define ATH_DEFAULT_BINTVAL 100 /* default beacon interval in TU */ #define ATH_DEFAULT_BINTVAL 100 /* default beacon interval in TU */
#define ATH_DEFAULT_BMISS_LIMIT 10 #define ATH_DEFAULT_BMISS_LIMIT 10
#define ATH_BEACON_AIFS_DEFAULT 0 /* Default aifs for ap beacon q */
#define ATH_BEACON_CWMIN_DEFAULT 0 /* Default cwmin for ap beacon q */
#define ATH_BEACON_CWMAX_DEFAULT 0 /* Default cwmax for ap beacon q */
#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
/* beacon configuration */ /* beacon configuration */
...@@ -724,30 +714,16 @@ struct ath_beacon_config { ...@@ -724,30 +714,16 @@ struct ath_beacon_config {
} u; /* last received beacon/probe response timestamp of this BSS. */ } u; /* last received beacon/probe response timestamp of this BSS. */
}; };
/* offsets in a beacon frame for
* quick acess of beacon content by low-level driver */
struct ath_beacon_offset {
u8 *bo_tim; /* start of atim/dtim */
};
void ath9k_beacon_tasklet(unsigned long data); void ath9k_beacon_tasklet(unsigned long data);
void ath_beacon_config(struct ath_softc *sc, int if_id); void ath_beacon_config(struct ath_softc *sc, int if_id);
int ath_beaconq_setup(struct ath_hal *ah); int ath_beaconq_setup(struct ath_hal *ah);
int ath_beacon_alloc(struct ath_softc *sc, int if_id); int ath_beacon_alloc(struct ath_softc *sc, int if_id);
void ath_bstuck_process(struct ath_softc *sc); void ath_bstuck_process(struct ath_softc *sc);
void ath_beacon_tasklet(struct ath_softc *sc, int *needmark);
void ath_beacon_free(struct ath_softc *sc);
void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp); void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp);
void ath_beacon_sync(struct ath_softc *sc, int if_id); void ath_beacon_sync(struct ath_softc *sc, int if_id);
void ath_update_beacon_info(struct ath_softc *sc, int avgbrssi);
void ath_get_beaconconfig(struct ath_softc *sc, void ath_get_beaconconfig(struct ath_softc *sc,
int if_id, int if_id,
struct ath_beacon_config *conf); struct ath_beacon_config *conf);
int ath_update_beacon(struct ath_softc *sc,
int if_id,
struct ath_beacon_offset *bo,
struct sk_buff *skb,
int mcast);
/********/ /********/
/* VAPs */ /* VAPs */
/********/ /********/
...@@ -774,10 +750,8 @@ struct ath_vap { ...@@ -774,10 +750,8 @@ struct ath_vap {
struct ieee80211_vif *av_if_data; struct ieee80211_vif *av_if_data;
enum ath9k_opmode av_opmode; /* VAP operational mode */ enum ath9k_opmode av_opmode; /* VAP operational mode */
struct ath_buf *av_bcbuf; /* beacon buffer */ struct ath_buf *av_bcbuf; /* beacon buffer */
struct ath_beacon_offset av_boff; /* dynamic update state */
struct ath_tx_control av_btxctl; /* txctl information for beacon */ struct ath_tx_control av_btxctl; /* txctl information for beacon */
int av_bslot; /* beacon slot index */ int av_bslot; /* beacon slot index */
struct ath_txq av_mcastq; /* multicast transmit queue */
struct ath_vap_config av_config;/* vap configuration parameters*/ struct ath_vap_config av_config;/* vap configuration parameters*/
struct ath_rate_node *rc_node; struct ath_rate_node *rc_node;
}; };
...@@ -788,8 +762,7 @@ int ath_vap_attach(struct ath_softc *sc, ...@@ -788,8 +762,7 @@ int ath_vap_attach(struct ath_softc *sc,
enum ath9k_opmode opmode); enum ath9k_opmode opmode);
int ath_vap_detach(struct ath_softc *sc, int if_id); int ath_vap_detach(struct ath_softc *sc, int if_id);
int ath_vap_config(struct ath_softc *sc, int ath_vap_config(struct ath_softc *sc,
int if_id, struct ath_vap_config *if_config); int if_id, struct ath_vap_config *if_config);
int ath_vap_listen(struct ath_softc *sc, int if_id);
/*********************/ /*********************/
/* Antenna diversity */ /* Antenna diversity */
...@@ -829,6 +802,27 @@ void ath_slow_ant_div(struct ath_antdiv *antdiv, ...@@ -829,6 +802,27 @@ void ath_slow_ant_div(struct ath_antdiv *antdiv,
struct ath_rx_status *rx_stats); struct ath_rx_status *rx_stats);
void ath_setdefantenna(void *sc, u32 antenna); void ath_setdefantenna(void *sc, u32 antenna);
/********************/
/* LED Control */
/********************/
#define ATH_LED_PIN 1
enum ath_led_type {
ATH_LED_RADIO,
ATH_LED_ASSOC,
ATH_LED_TX,
ATH_LED_RX
};
struct ath_led {
struct ath_softc *sc;
struct led_classdev led_cdev;
enum ath_led_type led_type;
char name[32];
bool registered;
};
/********************/ /********************/
/* Main driver core */ /* Main driver core */
/********************/ /********************/
...@@ -841,11 +835,7 @@ void ath_setdefantenna(void *sc, u32 antenna); ...@@ -841,11 +835,7 @@ void ath_setdefantenna(void *sc, u32 antenna);
#define ATH_DEFAULT_NOISE_FLOOR -95 #define ATH_DEFAULT_NOISE_FLOOR -95
#define ATH_REGCLASSIDS_MAX 10 #define ATH_REGCLASSIDS_MAX 10
#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */ #define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
#define ATH_PREAMBLE_SHORT (1<<0)
#define ATH_PROTECT_ENABLE (1<<1)
#define ATH_MAX_SW_RETRIES 10 #define ATH_MAX_SW_RETRIES 10
/* Num farmes difference in tx to flip default recv */
#define ATH_ANTENNA_DIFF 2
#define ATH_CHAN_MAX 255 #define ATH_CHAN_MAX 255
#define IEEE80211_WEP_NKID 4 /* number of key ids */ #define IEEE80211_WEP_NKID 4 /* number of key ids */
#define IEEE80211_RATE_VAL 0x7f #define IEEE80211_RATE_VAL 0x7f
...@@ -859,9 +849,7 @@ void ath_setdefantenna(void *sc, u32 antenna); ...@@ -859,9 +849,7 @@ void ath_setdefantenna(void *sc, u32 antenna);
*/ */
#define ATH_KEYMAX 128 /* max key cache size we handle */ #define ATH_KEYMAX 128 /* max key cache size we handle */
#define RESET_RETRY_TXQ 0x00000001
#define ATH_IF_ID_ANY 0xff #define ATH_IF_ID_ANY 0xff
#define ATH_TXPOWER_MAX 100 /* .5 dBm units */ #define ATH_TXPOWER_MAX 100 /* .5 dBm units */
#define RSSI_LPF_THRESHOLD -20 #define RSSI_LPF_THRESHOLD -20
...@@ -907,60 +895,61 @@ struct ath_ht_info { ...@@ -907,60 +895,61 @@ struct ath_ht_info {
u8 ext_chan_offset; u8 ext_chan_offset;
}; };
#define SC_OP_INVALID BIT(0)
#define SC_OP_BEACONS BIT(1)
#define SC_OP_RXAGGR BIT(2)
#define SC_OP_TXAGGR BIT(3)
#define SC_OP_CHAINMASK_UPDATE BIT(4)
#define SC_OP_FULL_RESET BIT(5)
#define SC_OP_NO_RESET BIT(6)
#define SC_OP_PREAMBLE_SHORT BIT(7)
#define SC_OP_PROTECT_ENABLE BIT(8)
#define SC_OP_RXFLUSH BIT(9)
#define SC_OP_LED_ASSOCIATED BIT(10)
struct ath_softc { struct ath_softc {
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
struct pci_dev *pdev; struct pci_dev *pdev;
void __iomem *mem;
struct tasklet_struct intr_tq; struct tasklet_struct intr_tq;
struct tasklet_struct bcon_tasklet; struct tasklet_struct bcon_tasklet;
struct ath_config sc_config; /* load-time parameters */ struct ath_config sc_config;
int sc_debug;
struct ath_hal *sc_ah; struct ath_hal *sc_ah;
struct ath_rate_softc *sc_rc; /* tx rate control support */ struct ath_rate_softc *sc_rc;
void __iomem *mem;
u8 sc_curbssid[ETH_ALEN];
u8 sc_myaddr[ETH_ALEN];
u8 sc_bssidmask[ETH_ALEN];
int sc_debug;
u32 sc_intrstatus; u32 sc_intrstatus;
enum ath9k_opmode sc_opmode; /* current operating mode */ u32 sc_flags; /* SC_OP_* */
unsigned int rx_filter;
u8 sc_invalid; /* being detached */
u8 sc_beacons; /* beacons running */
u8 sc_scanning; /* scanning active */
u8 sc_txaggr; /* enable 11n tx aggregation */
u8 sc_rxaggr; /* enable 11n rx aggregation */
u8 sc_update_chainmask; /* change chain mask */
u8 sc_full_reset; /* force full reset */
enum wireless_mode sc_curmode; /* current phy mode */
u16 sc_curtxpow; u16 sc_curtxpow;
u16 sc_curaid; u16 sc_curaid;
u8 sc_curbssid[ETH_ALEN]; u16 sc_cachelsz;
u8 sc_myaddr[ETH_ALEN]; 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; /* current phy mode */
enum PROT_MODE sc_protmode; enum PROT_MODE sc_protmode;
u8 sc_mcastantenna;
u8 sc_txantenna; /* data tx antenna (fixed or auto) */
u8 sc_nbcnvaps; /* # of vaps sending beacons */ u8 sc_nbcnvaps; /* # of vaps sending beacons */
u16 sc_nvaps; /* # of active virtual ap's */ u16 sc_nvaps; /* # of active virtual ap's */
struct ath_vap *sc_vaps[ATH_BCBUF]; struct ath_vap *sc_vaps[ATH_BCBUF];
enum ath9k_int sc_imask;
u8 sc_bssidmask[ETH_ALEN]; u8 sc_mcastantenna;
u8 sc_defant; /* current default antenna */ u8 sc_defant; /* current default antenna */
u8 sc_rxotherant; /* rx's on non-default antenna */ u8 sc_rxotherant; /* rx's on non-default antenna */
u16 sc_cachelsz;
int sc_slotupdate; /* slot to next advance fsm */
int sc_slottime;
u8 sc_noreset;
int sc_bslot[ATH_BCBUF];
struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */ struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */
struct list_head node_list; struct list_head node_list;
struct ath_ht_info sc_ht_info; struct ath_ht_info sc_ht_info;
int16_t sc_noise_floor; /* signal noise floor in dBm */
enum ath9k_ht_extprotspacing sc_ht_extprotspacing; enum ath9k_ht_extprotspacing sc_ht_extprotspacing;
u8 sc_tx_chainmask;
u8 sc_rx_chainmask;
u8 sc_rxchaindetect_ref;
u8 sc_rxchaindetect_thresh5GHz;
u8 sc_rxchaindetect_thresh2GHz;
u8 sc_rxchaindetect_delta5GHz;
u8 sc_rxchaindetect_delta2GHz;
u32 sc_rtsaggrlimit; /* Chipset specific aggr limit */
u32 sc_flags;
#ifdef CONFIG_SLOW_ANT_DIV #ifdef CONFIG_SLOW_ANT_DIV
struct ath_antdiv sc_antdiv; struct ath_antdiv sc_antdiv;
#endif #endif
...@@ -981,8 +970,6 @@ struct ath_softc { ...@@ -981,8 +970,6 @@ struct ath_softc {
struct ath_descdma sc_rxdma; struct ath_descdma sc_rxdma;
int sc_rxbufsize; /* rx size based on mtu */ int sc_rxbufsize; /* rx size based on mtu */
u32 *sc_rxlink; /* link ptr in last RX desc */ u32 *sc_rxlink; /* link ptr in last RX desc */
u32 sc_rxflush; /* rx flush in progress */
u64 sc_lastrx; /* tsf of last rx'd frame */
/* TX */ /* TX */
struct list_head sc_txbuf; struct list_head sc_txbuf;
...@@ -991,7 +978,7 @@ struct ath_softc { ...@@ -991,7 +978,7 @@ struct ath_softc {
u32 sc_txqsetup; u32 sc_txqsetup;
u32 sc_txintrperiod; /* tx interrupt batching */ u32 sc_txintrperiod; /* tx interrupt batching */
int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */ int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */
u32 sc_ant_tx[8]; /* recent tx frames/antenna */ u16 seq_no; /* TX sequence number */
/* Beacon */ /* Beacon */
struct ath9k_tx_queue_info sc_beacon_qi; struct ath9k_tx_queue_info sc_beacon_qi;
...@@ -1015,7 +1002,6 @@ struct ath_softc { ...@@ -1015,7 +1002,6 @@ struct ath_softc {
/* Channel, Band */ /* Channel, Band */
struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX]; struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX];
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
struct ath9k_channel sc_curchan;
/* Locks */ /* Locks */
spinlock_t sc_rxflushlock; spinlock_t sc_rxflushlock;
...@@ -1023,6 +1009,12 @@ struct ath_softc { ...@@ -1023,6 +1009,12 @@ struct ath_softc {
spinlock_t sc_txbuflock; spinlock_t sc_txbuflock;
spinlock_t sc_resetlock; spinlock_t sc_resetlock;
spinlock_t node_lock; spinlock_t node_lock;
/* LEDs */
struct ath_led radio_led;
struct ath_led assoc_led;
struct ath_led tx_led;
struct ath_led rx_led;
}; };
int ath_init(u16 devid, struct ath_softc *sc); int ath_init(u16 devid, struct ath_softc *sc);
...@@ -1030,14 +1022,8 @@ void ath_deinit(struct ath_softc *sc); ...@@ -1030,14 +1022,8 @@ void ath_deinit(struct ath_softc *sc);
int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan); int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan);
int ath_suspend(struct ath_softc *sc); int ath_suspend(struct ath_softc *sc);
irqreturn_t ath_isr(int irq, void *dev); irqreturn_t ath_isr(int irq, void *dev);
int ath_reset(struct ath_softc *sc); int ath_reset(struct ath_softc *sc, bool retry_tx);
void ath_scan_start(struct ath_softc *sc);
void ath_scan_end(struct ath_softc *sc);
int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan); int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan);
void ath_setup_rate(struct ath_softc *sc,
enum wireless_mode wMode,
enum RATE_TYPE type,
const struct ath9k_rate_table *rt);
/*********************/ /*********************/
/* Utility Functions */ /* Utility Functions */
...@@ -1056,17 +1042,5 @@ int ath_cabq_update(struct ath_softc *); ...@@ -1056,17 +1042,5 @@ int ath_cabq_update(struct ath_softc *);
void ath_get_currentCountry(struct ath_softc *sc, void ath_get_currentCountry(struct ath_softc *sc,
struct ath9k_country_entry *ctry); struct ath9k_country_entry *ctry);
u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp); u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp);
void ath_internal_reset(struct ath_softc *sc);
u32 ath_chan2flags(struct ieee80211_channel *chan, struct ath_softc *sc);
dma_addr_t ath_skb_map_single(struct ath_softc *sc,
struct sk_buff *skb,
int direction,
dma_addr_t *pa);
void ath_skb_unmap_single(struct ath_softc *sc,
struct sk_buff *skb,
int direction,
dma_addr_t *pa);
void ath_mcast_merge(struct ath_softc *sc, u32 mfilt[2]);
enum ath9k_ht_macmode ath_cwm_macmode(struct ath_softc *sc);
#endif /* CORE_H */ #endif /* CORE_H */
...@@ -85,29 +85,6 @@ static const struct hal_percal_data adc_init_dc_cal = { ...@@ -85,29 +85,6 @@ static const struct hal_percal_data adc_init_dc_cal = {
ath9k_hw_adc_dccal_calibrate ath9k_hw_adc_dccal_calibrate
}; };
static const struct ath_hal ar5416hal = {
AR5416_MAGIC,
0,
0,
NULL,
NULL,
CTRY_DEFAULT,
0,
0,
0,
0,
0,
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
},
};
static struct ath9k_rate_table ar5416_11a_table = { static struct ath9k_rate_table ar5416_11a_table = {
8, 8,
{0}, {0},
...@@ -371,7 +348,7 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah) ...@@ -371,7 +348,7 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah)
ah->ah_config.intr_mitigation = 0; ah->ah_config.intr_mitigation = 0;
} }
static inline void ath9k_hw_override_ini(struct ath_hal *ah, static void ath9k_hw_override_ini(struct ath_hal *ah,
struct ath9k_channel *chan) struct ath9k_channel *chan)
{ {
if (!AR_SREV_5416_V20_OR_LATER(ah) if (!AR_SREV_5416_V20_OR_LATER(ah)
...@@ -381,8 +358,8 @@ static inline void ath9k_hw_override_ini(struct ath_hal *ah, ...@@ -381,8 +358,8 @@ static inline void ath9k_hw_override_ini(struct ath_hal *ah,
REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
} }
static inline void ath9k_hw_init_bb(struct ath_hal *ah, static void ath9k_hw_init_bb(struct ath_hal *ah,
struct ath9k_channel *chan) struct ath9k_channel *chan)
{ {
u32 synthDelay; u32 synthDelay;
...@@ -397,8 +374,8 @@ static inline void ath9k_hw_init_bb(struct ath_hal *ah, ...@@ -397,8 +374,8 @@ static inline void ath9k_hw_init_bb(struct ath_hal *ah,
udelay(synthDelay + BASE_ACTIVATE_DELAY); udelay(synthDelay + BASE_ACTIVATE_DELAY);
} }
static inline void ath9k_hw_init_interrupt_masks(struct ath_hal *ah, static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
enum ath9k_opmode opmode) enum ath9k_opmode opmode)
{ {
struct ath_hal_5416 *ahp = AH5416(ah); struct ath_hal_5416 *ahp = AH5416(ah);
...@@ -428,7 +405,7 @@ static inline void ath9k_hw_init_interrupt_masks(struct ath_hal *ah, ...@@ -428,7 +405,7 @@ static inline void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
} }
} }
static inline void ath9k_hw_init_qos(struct ath_hal *ah) static void ath9k_hw_init_qos(struct ath_hal *ah)
{ {
REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa); REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210); REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
...@@ -523,7 +500,7 @@ static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, ...@@ -523,7 +500,7 @@ static inline bool ath9k_hw_nvram_read(struct ath_hal *ah,
return ath9k_hw_eeprom_read(ah, off, data); return ath9k_hw_eeprom_read(ah, off, data);
} }
static inline bool ath9k_hw_fill_eeprom(struct ath_hal *ah) static bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
{ {
struct ath_hal_5416 *ahp = AH5416(ah); struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416_eeprom *eep = &ahp->ah_eeprom; struct ar5416_eeprom *eep = &ahp->ah_eeprom;
...@@ -790,7 +767,7 @@ ath9k_hw_eeprom_set_board_values(struct ath_hal *ah, ...@@ -790,7 +767,7 @@ ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
return true; return true;
} }
static inline int ath9k_hw_check_eeprom(struct ath_hal *ah) static int ath9k_hw_check_eeprom(struct ath_hal *ah)
{ {
u32 sum = 0, el; u32 sum = 0, el;
u16 *eepdata; u16 *eepdata;
...@@ -1196,11 +1173,12 @@ static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid, ...@@ -1196,11 +1173,12 @@ static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
ah = &ahp->ah; ah = &ahp->ah;
memcpy(&ahp->ah, &ar5416hal, sizeof(struct ath_hal));
ah->ah_sc = sc; ah->ah_sc = sc;
ah->ah_sh = mem; ah->ah_sh = mem;
ah->ah_magic = AR5416_MAGIC;
ah->ah_countryCode = CTRY_DEFAULT;
ah->ah_devid = devid; ah->ah_devid = devid;
ah->ah_subvendorid = 0; ah->ah_subvendorid = 0;
...@@ -1294,7 +1272,7 @@ u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp, ...@@ -1294,7 +1272,7 @@ u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
} }
} }
static inline int ath9k_hw_get_radiorev(struct ath_hal *ah) static int ath9k_hw_get_radiorev(struct ath_hal *ah)
{ {
u32 val; u32 val;
int i; int i;
...@@ -1307,7 +1285,7 @@ static inline int ath9k_hw_get_radiorev(struct ath_hal *ah) ...@@ -1307,7 +1285,7 @@ static inline int ath9k_hw_get_radiorev(struct ath_hal *ah)
return ath9k_hw_reverse_bits(val, 8); return ath9k_hw_reverse_bits(val, 8);
} }
static inline int ath9k_hw_init_macaddr(struct ath_hal *ah) static int ath9k_hw_init_macaddr(struct ath_hal *ah)
{ {
u32 sum; u32 sum;
int i; int i;
...@@ -1389,7 +1367,7 @@ static u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, ...@@ -1389,7 +1367,7 @@ static u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah,
return spur_val; return spur_val;
} }
static inline int ath9k_hw_rfattach(struct ath_hal *ah) static int ath9k_hw_rfattach(struct ath_hal *ah)
{ {
bool rfStatus = false; bool rfStatus = false;
int ecode = 0; int ecode = 0;
...@@ -1434,8 +1412,8 @@ static int ath9k_hw_rf_claim(struct ath_hal *ah) ...@@ -1434,8 +1412,8 @@ static int ath9k_hw_rf_claim(struct ath_hal *ah)
return 0; return 0;
} }
static inline void ath9k_hw_init_pll(struct ath_hal *ah, static void ath9k_hw_init_pll(struct ath_hal *ah,
struct ath9k_channel *chan) struct ath9k_channel *chan)
{ {
u32 pll; u32 pll;
...@@ -1553,7 +1531,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode) ...@@ -1553,7 +1531,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
} }
} }
static inline void static void
ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan) ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
{ {
u32 rfMode = 0; u32 rfMode = 0;
...@@ -1623,7 +1601,7 @@ static bool ath9k_hw_set_reset(struct ath_hal *ah, int type) ...@@ -1623,7 +1601,7 @@ static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
return true; return true;
} }
static inline bool ath9k_hw_set_reset_power_on(struct ath_hal *ah) static bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
{ {
REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
AR_RTC_FORCE_WAKE_ON_INT); AR_RTC_FORCE_WAKE_ON_INT);
...@@ -1664,7 +1642,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, ...@@ -1664,7 +1642,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hal *ah,
} }
} }
static inline static
struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah, struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah,
struct ath9k_channel *chan) struct ath9k_channel *chan)
{ {
...@@ -2098,7 +2076,7 @@ static void ath9k_hw_ani_attach(struct ath_hal *ah) ...@@ -2098,7 +2076,7 @@ static void ath9k_hw_ani_attach(struct ath_hal *ah)
ahp->ah_procPhyErr |= HAL_PROCESS_ANI; ahp->ah_procPhyErr |= HAL_PROCESS_ANI;
} }
static inline void ath9k_hw_ani_setup(struct ath_hal *ah) static void ath9k_hw_ani_setup(struct ath_hal *ah)
{ {
struct ath_hal_5416 *ahp = AH5416(ah); struct ath_hal_5416 *ahp = AH5416(ah);
int i; int i;
...@@ -2822,32 +2800,11 @@ static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah, ...@@ -2822,32 +2800,11 @@ static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
} }
} }
static bool ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio, void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
enum ath9k_gpio_output_mux_type u32 ah_signal_type)
halSignalType)
{ {
u32 ah_signal_type;
u32 gpio_shift; u32 gpio_shift;
static u32 MuxSignalConversionTable[] = {
AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
};
if ((halSignalType >= 0)
&& (halSignalType < ARRAY_SIZE(MuxSignalConversionTable)))
ah_signal_type = MuxSignalConversionTable[halSignalType];
else
return false;
ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type); ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
gpio_shift = 2 * gpio; gpio_shift = 2 * gpio;
...@@ -2856,16 +2813,12 @@ static bool ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio, ...@@ -2856,16 +2813,12 @@ static bool ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
AR_GPIO_OE_OUT, AR_GPIO_OE_OUT,
(AR_GPIO_OE_OUT_DRV_ALL << gpio_shift), (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
(AR_GPIO_OE_OUT_DRV << gpio_shift)); (AR_GPIO_OE_OUT_DRV << gpio_shift));
return true;
} }
static bool ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val)
u32 val)
{ {
REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
AR_GPIO_BIT(gpio)); AR_GPIO_BIT(gpio));
return true;
} }
static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio) static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
...@@ -2883,7 +2836,7 @@ static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio) ...@@ -2883,7 +2836,7 @@ static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
} }
} }
static inline int ath9k_hw_post_attach(struct ath_hal *ah) static int ath9k_hw_post_attach(struct ath_hal *ah)
{ {
int ecode; int ecode;
...@@ -3595,7 +3548,7 @@ static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, ...@@ -3595,7 +3548,7 @@ static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin,
return true; return true;
} }
static inline void static void
ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah, ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
struct ath9k_channel *chan, struct ath9k_channel *chan,
struct cal_data_per_freq *pRawDataSet, struct cal_data_per_freq *pRawDataSet,
...@@ -3777,7 +3730,7 @@ ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah, ...@@ -3777,7 +3730,7 @@ ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
return; return;
} }
static inline bool static bool
ath9k_hw_set_power_cal_table(struct ath_hal *ah, ath9k_hw_set_power_cal_table(struct ath_hal *ah,
struct ar5416_eeprom *pEepData, struct ar5416_eeprom *pEepData,
struct ath9k_channel *chan, struct ath9k_channel *chan,
...@@ -3980,7 +3933,7 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore) ...@@ -3980,7 +3933,7 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
} }
} }
static inline void static void
ath9k_hw_get_legacy_target_powers(struct ath_hal *ah, ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
struct ath9k_channel *chan, struct ath9k_channel *chan,
struct cal_target_power_leg *powInfo, struct cal_target_power_leg *powInfo,
...@@ -4046,7 +3999,7 @@ ath9k_hw_get_legacy_target_powers(struct ath_hal *ah, ...@@ -4046,7 +3999,7 @@ ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
} }
} }
static inline void static void
ath9k_hw_get_target_powers(struct ath_hal *ah, ath9k_hw_get_target_powers(struct ath_hal *ah,
struct ath9k_channel *chan, struct ath9k_channel *chan,
struct cal_target_power_ht *powInfo, struct cal_target_power_ht *powInfo,
...@@ -4113,7 +4066,7 @@ ath9k_hw_get_target_powers(struct ath_hal *ah, ...@@ -4113,7 +4066,7 @@ ath9k_hw_get_target_powers(struct ath_hal *ah,
} }
} }
static inline u16 static u16
ath9k_hw_get_max_edge_power(u16 freq, ath9k_hw_get_max_edge_power(u16 freq,
struct cal_ctl_edges *pRdEdgesPower, struct cal_ctl_edges *pRdEdgesPower,
bool is2GHz) bool is2GHz)
...@@ -4143,7 +4096,7 @@ ath9k_hw_get_max_edge_power(u16 freq, ...@@ -4143,7 +4096,7 @@ ath9k_hw_get_max_edge_power(u16 freq,
return twiceMaxEdgePower; return twiceMaxEdgePower;
} }
static inline bool static bool
ath9k_hw_set_power_per_rate_table(struct ath_hal *ah, ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
struct ar5416_eeprom *pEepData, struct ar5416_eeprom *pEepData,
struct ath9k_channel *chan, struct ath9k_channel *chan,
...@@ -5122,7 +5075,7 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, ...@@ -5122,7 +5075,7 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
} }
static inline void ath9k_hw_init_chain_masks(struct ath_hal *ah) static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
{ {
struct ath_hal_5416 *ahp = AH5416(ah); struct ath_hal_5416 *ahp = AH5416(ah);
int rx_chainmask, tx_chainmask; int rx_chainmask, tx_chainmask;
...@@ -5326,7 +5279,7 @@ bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us) ...@@ -5326,7 +5279,7 @@ bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
} }
} }
static inline void ath9k_hw_init_user_settings(struct ath_hal *ah) static void ath9k_hw_init_user_settings(struct ath_hal *ah)
{ {
struct ath_hal_5416 *ahp = AH5416(ah); struct ath_hal_5416 *ahp = AH5416(ah);
...@@ -5345,7 +5298,7 @@ static inline void ath9k_hw_init_user_settings(struct ath_hal *ah) ...@@ -5345,7 +5298,7 @@ static inline void ath9k_hw_init_user_settings(struct ath_hal *ah)
ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout); ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
} }
static inline int static int
ath9k_hw_process_ini(struct ath_hal *ah, ath9k_hw_process_ini(struct ath_hal *ah,
struct ath9k_channel *chan, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode) enum ath9k_ht_macmode macmode)
...@@ -5476,7 +5429,7 @@ ath9k_hw_process_ini(struct ath_hal *ah, ...@@ -5476,7 +5429,7 @@ ath9k_hw_process_ini(struct ath_hal *ah,
return 0; return 0;
} }
static inline void ath9k_hw_setup_calibration(struct ath_hal *ah, static void ath9k_hw_setup_calibration(struct ath_hal *ah,
struct hal_cal_list *currCal) struct hal_cal_list *currCal)
{ {
REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0), REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
...@@ -5512,8 +5465,8 @@ static inline void ath9k_hw_setup_calibration(struct ath_hal *ah, ...@@ -5512,8 +5465,8 @@ static inline void ath9k_hw_setup_calibration(struct ath_hal *ah,
AR_PHY_TIMING_CTRL4_DO_CAL); AR_PHY_TIMING_CTRL4_DO_CAL);
} }
static inline void ath9k_hw_reset_calibration(struct ath_hal *ah, static void ath9k_hw_reset_calibration(struct ath_hal *ah,
struct hal_cal_list *currCal) struct hal_cal_list *currCal)
{ {
struct ath_hal_5416 *ahp = AH5416(ah); struct ath_hal_5416 *ahp = AH5416(ah);
int i; int i;
...@@ -5532,7 +5485,7 @@ static inline void ath9k_hw_reset_calibration(struct ath_hal *ah, ...@@ -5532,7 +5485,7 @@ static inline void ath9k_hw_reset_calibration(struct ath_hal *ah,
ahp->ah_CalSamples = 0; ahp->ah_CalSamples = 0;
} }
static inline void static void
ath9k_hw_per_calibration(struct ath_hal *ah, ath9k_hw_per_calibration(struct ath_hal *ah,
struct ath9k_channel *ichan, struct ath9k_channel *ichan,
u8 rxchainmask, u8 rxchainmask,
...@@ -5622,7 +5575,7 @@ static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah, ...@@ -5622,7 +5575,7 @@ static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
return true; return true;
} }
static inline bool static bool
ath9k_hw_channel_change(struct ath_hal *ah, ath9k_hw_channel_change(struct ath_hal *ah,
struct ath9k_channel *chan, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode) enum ath9k_ht_macmode macmode)
...@@ -5799,8 +5752,8 @@ static bool ath9k_hw_iscal_supported(struct ath_hal *ah, ...@@ -5799,8 +5752,8 @@ static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
return retval; return retval;
} }
static inline bool ath9k_hw_init_cal(struct ath_hal *ah, static bool ath9k_hw_init_cal(struct ath_hal *ah,
struct ath9k_channel *chan) struct ath9k_channel *chan)
{ {
struct ath_hal_5416 *ahp = AH5416(ah); struct ath_hal_5416 *ahp = AH5416(ah);
struct ath9k_channel *ichan = struct ath9k_channel *ichan =
...@@ -5861,7 +5814,7 @@ static inline bool ath9k_hw_init_cal(struct ath_hal *ah, ...@@ -5861,7 +5814,7 @@ static inline bool ath9k_hw_init_cal(struct ath_hal *ah,
} }
bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode, bool ath9k_hw_reset(struct ath_hal *ah,
struct ath9k_channel *chan, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode, enum ath9k_ht_macmode macmode,
u8 txchainmask, u8 rxchainmask, u8 txchainmask, u8 rxchainmask,
...@@ -5945,7 +5898,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode, ...@@ -5945,7 +5898,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
else else
ath9k_hw_set_gpio(ah, 9, 1); ath9k_hw_set_gpio(ah, 9, 1);
} }
ath9k_hw_cfg_output(ah, 9, ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT); ath9k_hw_cfg_output(ah, 9, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
} }
ecode = ath9k_hw_process_ini(ah, chan, macmode); ecode = ath9k_hw_process_ini(ah, chan, macmode);
...@@ -5975,7 +5928,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode, ...@@ -5975,7 +5928,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
| (ah->ah_config. | (ah->ah_config.
ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
| ahp->ah_staId1Defaults); | ahp->ah_staId1Defaults);
ath9k_hw_set_operating_mode(ah, opmode); ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask)); REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4)); REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
...@@ -6005,13 +5958,11 @@ bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode, ...@@ -6005,13 +5958,11 @@ bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
for (i = 0; i < ah->ah_caps.total_queues; i++) for (i = 0; i < ah->ah_caps.total_queues; i++)
ath9k_hw_resettxqueue(ah, i); ath9k_hw_resettxqueue(ah, i);
ath9k_hw_init_interrupt_masks(ah, opmode); ath9k_hw_init_interrupt_masks(ah, ah->ah_opmode);
ath9k_hw_init_qos(ah); ath9k_hw_init_qos(ah);
ath9k_hw_init_user_settings(ah); ath9k_hw_init_user_settings(ah);
ah->ah_opmode = opmode;
REG_WRITE(ah, AR_STA_ID1, REG_WRITE(ah, AR_STA_ID1,
REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
...@@ -7678,8 +7629,7 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q) ...@@ -7678,8 +7629,7 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
REG_WRITE(ah, AR_DRETRY_LIMIT(q), REG_WRITE(ah, AR_DRETRY_LIMIT(q),
SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
| SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
| SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH) | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
);
REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ); REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
REG_WRITE(ah, AR_DMISC(q), REG_WRITE(ah, AR_DMISC(q),
...@@ -8324,15 +8274,7 @@ struct ath_hal *ath9k_hw_attach(u16 devid, ...@@ -8324,15 +8274,7 @@ struct ath_hal *ath9k_hw_attach(u16 devid,
*error = -ENXIO; *error = -ENXIO;
break; break;
} }
if (ah != NULL) {
ah->ah_devid = ah->ah_devid;
ah->ah_subvendorid = ah->ah_subvendorid;
ah->ah_macVersion = ah->ah_macVersion;
ah->ah_macRev = ah->ah_macRev;
ah->ah_phyRev = ah->ah_phyRev;
ah->ah_analog5GhzRev = ah->ah_analog5GhzRev;
ah->ah_analog2GhzRev = ah->ah_analog2GhzRev;
}
return ah; return ah;
} }
......
...@@ -314,14 +314,11 @@ struct ar5416_desc { ...@@ -314,14 +314,11 @@ struct ar5416_desc {
#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \ #define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
MS(ads->ds_rxstatus0, AR_RxRate) : \ MS(ads->ds_rxstatus0, AR_RxRate) : \
(ads->ds_rxstatus3 >> 2) & 0xFF) (ads->ds_rxstatus3 >> 2) & 0xFF)
#define RXSTATUS_DUPLICATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
MS(ads->ds_rxstatus3, AR_Parallel40) : \
(ads->ds_rxstatus3 >> 10) & 0x1)
#define set11nTries(_series, _index) \ #define set11nTries(_series, _index) \
(SM((_series)[_index].Tries, AR_XmitDataTries##_index)) (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
#define set11nRate(_series, _index) \ #define set11nRate(_series, _index) \
(SM((_series)[_index].Rate, AR_XmitRate##_index)) (SM((_series)[_index].Rate, AR_XmitRate##_index))
#define set11nPktDurRTSCTS(_series, _index) \ #define set11nPktDurRTSCTS(_series, _index) \
...@@ -330,11 +327,11 @@ struct ar5416_desc { ...@@ -330,11 +327,11 @@ struct ar5416_desc {
AR_RTSCTSQual##_index : 0)) AR_RTSCTSQual##_index : 0))
#define set11nRateFlags(_series, _index) \ #define set11nRateFlags(_series, _index) \
(((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \ (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \
AR_2040_##_index : 0) \ AR_2040_##_index : 0) \
|((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \ |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \
AR_GI##_index : 0) \ AR_GI##_index : 0) \
|SM((_series)[_index].ChSel, AR_ChainSel##_index)) |SM((_series)[_index].ChSel, AR_ChainSel##_index))
#define AR_SREV_9100(ah) ((ah->ah_macVersion) == AR_SREV_VERSION_9100) #define AR_SREV_9100(ah) ((ah->ah_macVersion) == AR_SREV_VERSION_9100)
...@@ -346,9 +343,6 @@ struct ar5416_desc { ...@@ -346,9 +343,6 @@ struct ar5416_desc {
#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1) #define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1)
#define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD #define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD
#define NUM_CORNER_FIX_BITS_2133 7
#define CCK_OFDM_GAIN_DELTA 15
struct ar5416AniState { struct ar5416AniState {
struct ath9k_channel c; struct ath9k_channel c;
u8 noiseImmunityLevel; u8 noiseImmunityLevel;
...@@ -377,11 +371,8 @@ struct ar5416AniState { ...@@ -377,11 +371,8 @@ struct ar5416AniState {
}; };
#define HAL_PROCESS_ANI 0x00000001 #define HAL_PROCESS_ANI 0x00000001
#define HAL_RADAR_EN 0x80000000
#define HAL_AR_EN 0x40000000
#define DO_ANI(ah) \ #define DO_ANI(ah) \
((AH5416(ah)->ah_procPhyErr & HAL_PROCESS_ANI)) ((AH5416(ah)->ah_procPhyErr & HAL_PROCESS_ANI))
struct ar5416Stats { struct ar5416Stats {
u32 ast_ani_niup; u32 ast_ani_niup;
...@@ -425,7 +416,6 @@ struct ar5416Stats { ...@@ -425,7 +416,6 @@ struct ar5416Stats {
#define AR5416_EEP_MINOR_VER_7 0x7 #define AR5416_EEP_MINOR_VER_7 0x7
#define AR5416_EEP_MINOR_VER_9 0x9 #define AR5416_EEP_MINOR_VER_9 0x9
#define AR5416_EEP_START_LOC 256
#define AR5416_NUM_5G_CAL_PIERS 8 #define AR5416_NUM_5G_CAL_PIERS 8
#define AR5416_NUM_2G_CAL_PIERS 4 #define AR5416_NUM_2G_CAL_PIERS 4
#define AR5416_NUM_5G_20_TARGET_POWERS 8 #define AR5416_NUM_5G_20_TARGET_POWERS 8
...@@ -441,25 +431,10 @@ struct ar5416Stats { ...@@ -441,25 +431,10 @@ struct ar5416Stats {
#define AR5416_EEPROM_MODAL_SPURS 5 #define AR5416_EEPROM_MODAL_SPURS 5
#define AR5416_MAX_RATE_POWER 63 #define AR5416_MAX_RATE_POWER 63
#define AR5416_NUM_PDADC_VALUES 128 #define AR5416_NUM_PDADC_VALUES 128
#define AR5416_NUM_RATES 16
#define AR5416_BCHAN_UNUSED 0xFF #define AR5416_BCHAN_UNUSED 0xFF
#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64 #define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
#define AR5416_EEPMISC_BIG_ENDIAN 0x01
#define AR5416_MAX_CHAINS 3 #define AR5416_MAX_CHAINS 3
#define AR5416_ANT_16S 25
#define AR5416_NUM_ANT_CHAIN_FIELDS 7
#define AR5416_NUM_ANT_COMMON_FIELDS 4
#define AR5416_SIZE_ANT_CHAIN_FIELD 3
#define AR5416_SIZE_ANT_COMMON_FIELD 4
#define AR5416_ANT_CHAIN_MASK 0x7
#define AR5416_ANT_COMMON_MASK 0xf
#define AR5416_CHAIN_0_IDX 0
#define AR5416_CHAIN_1_IDX 1
#define AR5416_CHAIN_2_IDX 2
#define AR5416_PWR_TABLE_OFFSET -5 #define AR5416_PWR_TABLE_OFFSET -5
#define AR5416_LEGACY_CHAINMASK 1
enum eeprom_param { enum eeprom_param {
EEP_NFTHRESH_5, EEP_NFTHRESH_5,
...@@ -633,7 +608,7 @@ struct ar5416IniArray { ...@@ -633,7 +608,7 @@ struct ar5416IniArray {
}; };
#define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \ #define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \
(iniarray)->ia_array = (u32 *)(array); \ (iniarray)->ia_array = (u32 *)(array); \
(iniarray)->ia_rows = (rows); \ (iniarray)->ia_rows = (rows); \
(iniarray)->ia_columns = (columns); \ (iniarray)->ia_columns = (columns); \
} while (0) } while (0)
...@@ -641,16 +616,16 @@ struct ar5416IniArray { ...@@ -641,16 +616,16 @@ struct ar5416IniArray {
#define INI_RA(iniarray, row, column) \ #define INI_RA(iniarray, row, column) \
(((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)]) (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)])
#define INIT_CAL(_perCal) do { \ #define INIT_CAL(_perCal) do { \
(_perCal)->calState = CAL_WAITING; \ (_perCal)->calState = CAL_WAITING; \
(_perCal)->calNext = NULL; \ (_perCal)->calNext = NULL; \
} while (0) } while (0)
#define INSERT_CAL(_ahp, _perCal) \ #define INSERT_CAL(_ahp, _perCal) \
do { \ do { \
if ((_ahp)->ah_cal_list_last == NULL) { \ if ((_ahp)->ah_cal_list_last == NULL) { \
(_ahp)->ah_cal_list = \ (_ahp)->ah_cal_list = \
(_ahp)->ah_cal_list_last = (_perCal); \ (_ahp)->ah_cal_list_last = (_perCal); \
((_ahp)->ah_cal_list_last)->calNext = (_perCal); \ ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
} else { \ } else { \
((_ahp)->ah_cal_list_last)->calNext = (_perCal); \ ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
...@@ -696,25 +671,29 @@ struct hal_cal_list { ...@@ -696,25 +671,29 @@ struct hal_cal_list {
struct ath_hal_5416 { struct ath_hal_5416 {
struct ath_hal ah; struct ath_hal ah;
struct ar5416_eeprom ah_eeprom; struct ar5416_eeprom ah_eeprom;
struct ar5416Stats ah_stats;
struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES];
void __iomem *ah_cal_mem;
u8 ah_macaddr[ETH_ALEN]; u8 ah_macaddr[ETH_ALEN];
u8 ah_bssid[ETH_ALEN]; u8 ah_bssid[ETH_ALEN];
u8 ah_bssidmask[ETH_ALEN]; u8 ah_bssidmask[ETH_ALEN];
u16 ah_assocId; u16 ah_assocId;
int16_t ah_curchanRadIndex; int16_t ah_curchanRadIndex;
u32 ah_maskReg; u32 ah_maskReg;
struct ar5416Stats ah_stats;
u32 ah_txDescMask;
u32 ah_txOkInterruptMask; u32 ah_txOkInterruptMask;
u32 ah_txErrInterruptMask; u32 ah_txErrInterruptMask;
u32 ah_txDescInterruptMask; u32 ah_txDescInterruptMask;
u32 ah_txEolInterruptMask; u32 ah_txEolInterruptMask;
u32 ah_txUrnInterruptMask; u32 ah_txUrnInterruptMask;
struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES];
enum ath9k_power_mode ah_powerMode;
bool ah_chipFullSleep; bool ah_chipFullSleep;
u32 ah_atimWindow; u32 ah_atimWindow;
enum ath9k_ant_setting ah_diversityControl;
u16 ah_antennaSwitchSwap; u16 ah_antennaSwitchSwap;
enum ath9k_power_mode ah_powerMode;
enum ath9k_ant_setting ah_diversityControl;
/* Calibration */
enum hal_cal_types ah_suppCals; enum hal_cal_types ah_suppCals;
struct hal_cal_list ah_iqCalData; struct hal_cal_list ah_iqCalData;
struct hal_cal_list ah_adcGainCalData; struct hal_cal_list ah_adcGainCalData;
...@@ -751,16 +730,16 @@ struct ath_hal_5416 { ...@@ -751,16 +730,16 @@ struct ath_hal_5416 {
int32_t sign[AR5416_MAX_CHAINS]; int32_t sign[AR5416_MAX_CHAINS];
} ah_Meas3; } ah_Meas3;
u16 ah_CalSamples; u16 ah_CalSamples;
u32 ah_tx6PowerInHalfDbm;
u32 ah_staId1Defaults; u32 ah_staId1Defaults;
u32 ah_miscMode; u32 ah_miscMode;
bool ah_tpcEnabled;
u32 ah_beaconInterval;
enum { enum {
AUTO_32KHZ, AUTO_32KHZ,
USE_32KHZ, USE_32KHZ,
DONT_USE_32KHZ, DONT_USE_32KHZ,
} ah_enable32kHzClock; } ah_enable32kHzClock;
/* RF */
u32 *ah_analogBank0Data; u32 *ah_analogBank0Data;
u32 *ah_analogBank1Data; u32 *ah_analogBank1Data;
u32 *ah_analogBank2Data; u32 *ah_analogBank2Data;
...@@ -770,8 +749,9 @@ struct ath_hal_5416 { ...@@ -770,8 +749,9 @@ struct ath_hal_5416 {
u32 *ah_analogBank7Data; u32 *ah_analogBank7Data;
u32 *ah_addac5416_21; u32 *ah_addac5416_21;
u32 *ah_bank6Temp; u32 *ah_bank6Temp;
u32 ah_ofdmTxPower;
int16_t ah_txPowerIndexOffset; int16_t ah_txPowerIndexOffset;
u32 ah_beaconInterval;
u32 ah_slottime; u32 ah_slottime;
u32 ah_acktimeout; u32 ah_acktimeout;
u32 ah_ctstimeout; u32 ah_ctstimeout;
...@@ -780,7 +760,8 @@ struct ath_hal_5416 { ...@@ -780,7 +760,8 @@ struct ath_hal_5416 {
u32 ah_gpioSelect; u32 ah_gpioSelect;
u32 ah_polarity; u32 ah_polarity;
u32 ah_gpioBit; u32 ah_gpioBit;
bool ah_eepEnabled;
/* ANI */
u32 ah_procPhyErr; u32 ah_procPhyErr;
bool ah_hasHwPhyCounters; bool ah_hasHwPhyCounters;
u32 ah_aniPeriod; u32 ah_aniPeriod;
...@@ -790,18 +771,14 @@ struct ath_hal_5416 { ...@@ -790,18 +771,14 @@ struct ath_hal_5416 {
int ah_coarseHigh[5]; int ah_coarseHigh[5];
int ah_coarseLow[5]; int ah_coarseLow[5];
int ah_firpwr[5]; int ah_firpwr[5];
u16 ah_ratesArray[16]; enum ath9k_ani_cmd ah_ani_function;
u32 ah_intrTxqs; u32 ah_intrTxqs;
bool ah_intrMitigation; bool ah_intrMitigation;
u32 ah_cycleCount;
u32 ah_ctlBusy;
u32 ah_extBusy;
enum ath9k_ht_extprotspacing ah_extprotspacing; enum ath9k_ht_extprotspacing ah_extprotspacing;
u8 ah_txchainmask; u8 ah_txchainmask;
u8 ah_rxchainmask; u8 ah_rxchainmask;
int ah_hwp;
void __iomem *ah_cal_mem;
enum ath9k_ani_cmd ah_ani_function;
struct ar5416IniArray ah_iniModes; struct ar5416IniArray ah_iniModes;
struct ar5416IniArray ah_iniCommon; struct ar5416IniArray ah_iniCommon;
struct ar5416IniArray ah_iniBank0; struct ar5416IniArray ah_iniBank0;
...@@ -820,10 +797,6 @@ struct ath_hal_5416 { ...@@ -820,10 +797,6 @@ struct ath_hal_5416 {
#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5)) #define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
#define IS_5416_EMU(ah) \
((ah->ah_devid == AR5416_DEVID_EMU) || \
(ah->ah_devid == AR5416_DEVID_EMU_PCIE))
#define ar5416RfDetach(ah) do { \ #define ar5416RfDetach(ah) do { \
if (AH5416(ah)->ah_rfHal.rfDetach != NULL) \ if (AH5416(ah)->ah_rfHal.rfDetach != NULL) \
AH5416(ah)->ah_rfHal.rfDetach(ah); \ AH5416(ah)->ah_rfHal.rfDetach(ah); \
...@@ -841,8 +814,8 @@ struct ath_hal_5416 { ...@@ -841,8 +814,8 @@ struct ath_hal_5416 {
#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \ #define REG_WRITE_ARRAY(iniarray, column, regWr) do { \
int r; \ int r; \
for (r = 0; r < ((iniarray)->ia_rows); r++) { \ for (r = 0; r < ((iniarray)->ia_rows); r++) { \
REG_WRITE(ah, INI_RA((iniarray), (r), 0), \ REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
INI_RA((iniarray), r, (column))); \ INI_RA((iniarray), r, (column))); \
DO_DELAY(regWr); \ DO_DELAY(regWr); \
} \ } \
} while (0) } while (0)
...@@ -852,30 +825,21 @@ struct ath_hal_5416 { ...@@ -852,30 +825,21 @@ struct ath_hal_5416 {
#define COEF_SCALE_S 24 #define COEF_SCALE_S 24
#define HT40_CHANNEL_CENTER_SHIFT 10 #define HT40_CHANNEL_CENTER_SHIFT 10
#define ar5416CheckOpMode(_opmode) \
((_opmode == ATH9K_M_STA) || (_opmode == ATH9K_M_IBSS) || \
(_opmode == ATH9K_M_HOSTAP) || (_opmode == ATH9K_M_MONITOR))
#define AR5416_EEPROM_MAGIC_OFFSET 0x0 #define AR5416_EEPROM_MAGIC_OFFSET 0x0
#define AR5416_EEPROM_S 2 #define AR5416_EEPROM_S 2
#define AR5416_EEPROM_OFFSET 0x2000 #define AR5416_EEPROM_OFFSET 0x2000
#define AR5416_EEPROM_START_ADDR \ #define AR5416_EEPROM_START_ADDR \
(AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200 (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
#define AR5416_EEPROM_MAX 0xae0 #define AR5416_EEPROM_MAX 0xae0
#define ar5416_get_eep_ver(_ahp) \ #define ar5416_get_eep_ver(_ahp) \
(((_ahp)->ah_eeprom.baseEepHeader.version >> 12) & 0xF) (((_ahp)->ah_eeprom.baseEepHeader.version >> 12) & 0xF)
#define ar5416_get_eep_rev(_ahp) \ #define ar5416_get_eep_rev(_ahp) \
(((_ahp)->ah_eeprom.baseEepHeader.version) & 0xFFF) (((_ahp)->ah_eeprom.baseEepHeader.version) & 0xFFF)
#define ar5416_get_ntxchains(_txchainmask) \ #define ar5416_get_ntxchains(_txchainmask) \
(((_txchainmask >> 2) & 1) + \ (((_txchainmask >> 2) & 1) + \
((_txchainmask >> 1) & 1) + (_txchainmask & 1)) ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
#define IS_EEP_MINOR_V3(_ahp) \
(ath9k_hw_get_eeprom((_ahp), EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_3)
#define FIXED_CCA_THRESHOLD 15
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
#define AR5416_EEPROM_MAGIC 0x5aa5 #define AR5416_EEPROM_MAGIC 0x5aa5
#else #else
...@@ -910,8 +874,6 @@ struct ath_hal_5416 { ...@@ -910,8 +874,6 @@ struct ath_hal_5416 {
#define AR_GPIOD_MASK 0x00001FFF #define AR_GPIOD_MASK 0x00001FFF
#define AR_GPIO_BIT(_gpio) (1 << (_gpio)) #define AR_GPIO_BIT(_gpio) (1 << (_gpio))
#define MAX_ANALOG_START 319
#define HAL_EP_RND(x, mul) \ #define HAL_EP_RND(x, mul) \
((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
#define BEACON_RSSI(ahp) \ #define BEACON_RSSI(ahp) \
...@@ -923,8 +885,6 @@ struct ath_hal_5416 { ...@@ -923,8 +885,6 @@ struct ath_hal_5416 {
#define AH_TIMEOUT 100000 #define AH_TIMEOUT 100000
#define AH_TIME_QUANTUM 10 #define AH_TIME_QUANTUM 10
#define IS(_c, _f) (((_c)->channelFlags & _f) || 0)
#define AR_KEYTABLE_SIZE 128 #define AR_KEYTABLE_SIZE 128
#define POWER_UP_TIME 200000 #define POWER_UP_TIME 200000
...@@ -964,6 +924,6 @@ struct ath_hal_5416 { ...@@ -964,6 +924,6 @@ struct ath_hal_5416 {
#define OFDM_SYMBOL_TIME_QUARTER 16 #define OFDM_SYMBOL_TIME_QUARTER 16
u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp, u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
enum eeprom_param param); enum eeprom_param param);
#endif #endif
...@@ -22,8 +22,6 @@ ...@@ -22,8 +22,6 @@
#define ATH_PCI_VERSION "0.1" #define ATH_PCI_VERSION "0.1"
#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13 #define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
#define IEEE80211_ACTION_CAT_HT 7
#define IEEE80211_ACTION_HT_TXCHWIDTH 0
static char *dev_info = "ath9k"; static char *dev_info = "ath9k";
...@@ -212,21 +210,16 @@ static int ath_key_config(struct ath_softc *sc, ...@@ -212,21 +210,16 @@ static int ath_key_config(struct ath_softc *sc,
static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key) static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
{ {
#define ATH_MAX_NUM_KEYS 4
int freeslot; int freeslot;
freeslot = (key->keyidx >= ATH_MAX_NUM_KEYS) ? 1 : 0; freeslot = (key->keyidx >= 4) ? 1 : 0;
ath_key_reset(sc, key->keyidx, freeslot); ath_key_reset(sc, key->keyidx, freeslot);
#undef ATH_MAX_NUM_KEYS
} }
static void setup_ht_cap(struct ieee80211_ht_info *ht_info) static void setup_ht_cap(struct ieee80211_ht_info *ht_info)
{ {
/* Until mac80211 includes these fields */ #define ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */
#define ATH9K_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */
#define IEEE80211_HT_CAP_DSSSCCK40 0x1000
#define IEEE80211_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */
#define IEEE80211_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */
ht_info->ht_supported = 1; ht_info->ht_supported = 1;
ht_info->cap = (u16)IEEE80211_HT_CAP_SUP_WIDTH ht_info->cap = (u16)IEEE80211_HT_CAP_SUP_WIDTH
...@@ -234,8 +227,8 @@ static void setup_ht_cap(struct ieee80211_ht_info *ht_info) ...@@ -234,8 +227,8 @@ static void setup_ht_cap(struct ieee80211_ht_info *ht_info)
|(u16)IEEE80211_HT_CAP_SGI_40 |(u16)IEEE80211_HT_CAP_SGI_40
|(u16)IEEE80211_HT_CAP_DSSSCCK40; |(u16)IEEE80211_HT_CAP_DSSSCCK40;
ht_info->ampdu_factor = IEEE80211_HT_CAP_MAXRXAMPDU_65536; ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536;
ht_info->ampdu_density = IEEE80211_HT_CAP_MPDUDENSITY_8; ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8;
/* setup supported mcs set */ /* setup supported mcs set */
memset(ht_info->supp_mcs_set, 0, 16); memset(ht_info->supp_mcs_set, 0, 16);
ht_info->supp_mcs_set[0] = 0xff; ht_info->supp_mcs_set[0] = 0xff;
...@@ -368,6 +361,20 @@ static int ath9k_tx(struct ieee80211_hw *hw, ...@@ -368,6 +361,20 @@ static int ath9k_tx(struct ieee80211_hw *hw,
{ {
struct ath_softc *sc = hw->priv; struct ath_softc *sc = hw->priv;
int hdrlen, padsize; int hdrlen, padsize;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
/*
* As a temporary workaround, assign seq# here; this will likely need
* to be cleaned up to work better with Beacon transmission and virtual
* BSSes.
*/
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;
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
}
/* Add the padding after the header if this is not already done */ /* Add the padding after the header if this is not already done */
hdrlen = ieee80211_get_hdrlen_from_skb(skb); hdrlen = ieee80211_get_hdrlen_from_skb(skb);
...@@ -426,10 +433,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, ...@@ -426,10 +433,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
case IEEE80211_IF_TYPE_IBSS: case IEEE80211_IF_TYPE_IBSS:
ic_opmode = ATH9K_M_IBSS; ic_opmode = ATH9K_M_IBSS;
break; break;
case IEEE80211_IF_TYPE_AP:
ic_opmode = ATH9K_M_HOSTAP;
break;
default: default:
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: Only STA and IBSS are supported currently\n", "%s: Interface type %d not yet supported\n",
__func__); __func__, conf->type);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -472,7 +482,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, ...@@ -472,7 +482,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
ath_rate_newstate(sc, avp); ath_rate_newstate(sc, avp);
/* Reclaim beacon resources */ /* Reclaim beacon resources */
if (sc->sc_opmode == ATH9K_M_HOSTAP || sc->sc_opmode == ATH9K_M_IBSS) { if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP ||
sc->sc_ah->ah_opmode == ATH9K_M_IBSS) {
ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
ath_beacon_return(sc, avp); ath_beacon_return(sc, avp);
} }
...@@ -480,7 +491,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, ...@@ -480,7 +491,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
/* Set interrupt mask */ /* Set interrupt mask */
sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask & ~ATH9K_INT_GLOBAL); ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask & ~ATH9K_INT_GLOBAL);
sc->sc_beacons = 0; sc->sc_flags &= ~SC_OP_BEACONS;
error = ath_vap_detach(sc, 0); error = ath_vap_detach(sc, 0);
if (error) if (error)
...@@ -529,6 +540,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, ...@@ -529,6 +540,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
struct ieee80211_if_conf *conf) struct ieee80211_if_conf *conf)
{ {
struct ath_softc *sc = hw->priv; struct ath_softc *sc = hw->priv;
struct ath_hal *ah = sc->sc_ah;
struct ath_vap *avp; struct ath_vap *avp;
u32 rfilt = 0; u32 rfilt = 0;
int error, i; int error, i;
...@@ -541,6 +553,17 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, ...@@ -541,6 +553,17 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
return -EINVAL; return -EINVAL;
} }
/* TODO: Need to decide which hw opmode to use for multi-interface
* cases */
if (vif->type == IEEE80211_IF_TYPE_AP &&
ah->ah_opmode != ATH9K_M_HOSTAP) {
ah->ah_opmode = ATH9K_M_HOSTAP;
ath9k_hw_setopmode(ah);
ath9k_hw_write_associd(ah, sc->sc_myaddr, 0);
/* Request full reset to get hw opmode changed properly */
sc->sc_flags |= SC_OP_FULL_RESET;
}
if ((conf->changed & IEEE80211_IFCC_BSSID) && if ((conf->changed & IEEE80211_IFCC_BSSID) &&
!is_zero_ether_addr(conf->bssid)) { !is_zero_ether_addr(conf->bssid)) {
switch (vif->type) { switch (vif->type) {
...@@ -549,10 +572,6 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, ...@@ -549,10 +572,6 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
/* Update ratectrl about the new state */ /* Update ratectrl about the new state */
ath_rate_newstate(sc, avp); ath_rate_newstate(sc, avp);
/* Set rx filter */
rfilt = ath_calcrxfilter(sc);
ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
/* Set BSSID */ /* Set BSSID */
memcpy(sc->sc_curbssid, conf->bssid, ETH_ALEN); memcpy(sc->sc_curbssid, conf->bssid, ETH_ALEN);
sc->sc_curaid = 0; sc->sc_curaid = 0;
...@@ -585,7 +604,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, ...@@ -585,7 +604,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
print_mac(mac, sc->sc_curbssid), sc->sc_curaid); print_mac(mac, sc->sc_curbssid), sc->sc_curaid);
/* need to reconfigure the beacon */ /* need to reconfigure the beacon */
sc->sc_beacons = 0; sc->sc_flags &= ~SC_OP_BEACONS ;
break; break;
default: default:
...@@ -594,7 +613,8 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, ...@@ -594,7 +613,8 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
} }
if ((conf->changed & IEEE80211_IFCC_BEACON) && if ((conf->changed & IEEE80211_IFCC_BEACON) &&
(vif->type == IEEE80211_IF_TYPE_IBSS)) { ((vif->type == IEEE80211_IF_TYPE_IBSS) ||
(vif->type == IEEE80211_IF_TYPE_AP))) {
/* /*
* Allocate and setup the beacon frame. * Allocate and setup the beacon frame.
* *
...@@ -636,8 +656,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, ...@@ -636,8 +656,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
FIF_BCN_PRBRESP_PROMISC | \ FIF_BCN_PRBRESP_PROMISC | \
FIF_FCSFAIL) FIF_FCSFAIL)
/* Accept unicast, bcast and mcast frames */ /* FIXME: sc->sc_full_reset ? */
static void ath9k_configure_filter(struct ieee80211_hw *hw, static void ath9k_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags, unsigned int changed_flags,
unsigned int *total_flags, unsigned int *total_flags,
...@@ -645,16 +664,22 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, ...@@ -645,16 +664,22 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
struct dev_mc_list *mclist) struct dev_mc_list *mclist)
{ {
struct ath_softc *sc = hw->priv; struct ath_softc *sc = hw->priv;
u32 rfilt;
changed_flags &= SUPPORTED_FILTERS; changed_flags &= SUPPORTED_FILTERS;
*total_flags &= SUPPORTED_FILTERS; *total_flags &= SUPPORTED_FILTERS;
sc->rx_filter = *total_flags;
rfilt = ath_calcrxfilter(sc);
ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
if (*total_flags & FIF_BCN_PRBRESP_PROMISC) if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
ath_scan_start(sc); ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0);
else
ath_scan_end(sc);
} }
DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set HW RX filter: 0x%x\n",
__func__, sc->rx_filter);
} }
static void ath9k_sta_notify(struct ieee80211_hw *hw, static void ath9k_sta_notify(struct ieee80211_hw *hw,
...@@ -831,7 +856,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, ...@@ -831,7 +856,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
/* Configure the beacon */ /* Configure the beacon */
ath_beacon_config(sc, 0); ath_beacon_config(sc, 0);
sc->sc_beacons = 1; sc->sc_flags |= SC_OP_BEACONS;
/* Reset rssi stats */ /* Reset rssi stats */
sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER; sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
...@@ -894,9 +919,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ...@@ -894,9 +919,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
__func__, __func__,
bss_conf->use_short_preamble); bss_conf->use_short_preamble);
if (bss_conf->use_short_preamble) if (bss_conf->use_short_preamble)
sc->sc_flags |= ATH_PREAMBLE_SHORT; sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
else else
sc->sc_flags &= ~ATH_PREAMBLE_SHORT; sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
} }
if (changed & BSS_CHANGED_ERP_CTS_PROT) { if (changed & BSS_CHANGED_ERP_CTS_PROT) {
...@@ -905,9 +930,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ...@@ -905,9 +930,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
bss_conf->use_cts_prot); bss_conf->use_cts_prot);
if (bss_conf->use_cts_prot && if (bss_conf->use_cts_prot &&
hw->conf.channel->band != IEEE80211_BAND_5GHZ) hw->conf.channel->band != IEEE80211_BAND_5GHZ)
sc->sc_flags |= ATH_PROTECT_ENABLE; sc->sc_flags |= SC_OP_PROTECT_ENABLE;
else else
sc->sc_flags &= ~ATH_PROTECT_ENABLE; sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
} }
if (changed & BSS_CHANGED_HT) { if (changed & BSS_CHANGED_HT) {
...@@ -1035,15 +1060,6 @@ void ath_get_beaconconfig(struct ath_softc *sc, ...@@ -1035,15 +1060,6 @@ void ath_get_beaconconfig(struct ath_softc *sc,
conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval; conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
} }
int ath_update_beacon(struct ath_softc *sc,
int if_id,
struct ath_beacon_offset *bo,
struct sk_buff *skb,
int mcast)
{
return 0;
}
void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
struct ath_xmit_status *tx_status, struct ath_node *an) struct ath_xmit_status *tx_status, struct ath_node *an)
{ {
...@@ -1065,8 +1081,16 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, ...@@ -1065,8 +1081,16 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
tx_status->flags &= ~ATH_TX_BAR; tx_status->flags &= ~ATH_TX_BAR;
} }
if (tx_status->flags)
tx_info->status.excessive_retries = 1; if (tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY)) {
if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
/* Frame was not ACKed, but an ACK was expected */
tx_info->status.excessive_retries = 1;
}
} else {
/* Frame was ACKed */
tx_info->flags |= IEEE80211_TX_STAT_ACK;
}
tx_info->status.retry_count = tx_status->retries; tx_info->status.retry_count = tx_status->retries;
...@@ -1075,7 +1099,7 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, ...@@ -1075,7 +1099,7 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
ath_node_put(sc, an, ATH9K_BH_STATUS_CHANGE); ath_node_put(sc, an, ATH9K_BH_STATUS_CHANGE);
} }
int ath__rx_indicate(struct ath_softc *sc, int _ath_rx_indicate(struct ath_softc *sc,
struct sk_buff *skb, struct sk_buff *skb,
struct ath_recv_status *status, struct ath_recv_status *status,
u16 keyix) u16 keyix)
...@@ -1095,9 +1119,6 @@ int ath__rx_indicate(struct ath_softc *sc, ...@@ -1095,9 +1119,6 @@ int ath__rx_indicate(struct ath_softc *sc,
skb_pull(skb, padsize); skb_pull(skb, padsize);
} }
/* remove FCS before passing up to protocol stack */
skb_trim(skb, (skb->len - FCS_LEN));
/* Prepare rx status */ /* Prepare rx status */
ath9k_rx_prepare(sc, skb, status, &rx_status); ath9k_rx_prepare(sc, skb, status, &rx_status);
...@@ -1146,9 +1167,119 @@ int ath_rx_subframe(struct ath_node *an, ...@@ -1146,9 +1167,119 @@ int ath_rx_subframe(struct ath_node *an,
return 0; return 0;
} }
enum ath9k_ht_macmode ath_cwm_macmode(struct ath_softc *sc) /********************************/
/* LED functions */
/********************************/
static void ath_led_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness)
{ {
return sc->sc_ht_info.tx_chan_width; struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
struct ath_softc *sc = led->sc;
switch (brightness) {
case LED_OFF:
if (led->led_type == ATH_LED_ASSOC ||
led->led_type == ATH_LED_RADIO)
sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
(led->led_type == ATH_LED_RADIO) ? 1 :
!!(sc->sc_flags & SC_OP_LED_ASSOCIATED));
break;
case LED_FULL:
if (led->led_type == ATH_LED_ASSOC)
sc->sc_flags |= SC_OP_LED_ASSOCIATED;
ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
break;
default:
break;
}
}
static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
char *trigger)
{
int ret;
led->sc = sc;
led->led_cdev.name = led->name;
led->led_cdev.default_trigger = trigger;
led->led_cdev.brightness_set = ath_led_brightness;
ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
if (ret)
DPRINTF(sc, ATH_DBG_FATAL,
"Failed to register led:%s", led->name);
else
led->registered = 1;
return ret;
}
static void ath_unregister_led(struct ath_led *led)
{
if (led->registered) {
led_classdev_unregister(&led->led_cdev);
led->registered = 0;
}
}
static void ath_deinit_leds(struct ath_softc *sc)
{
ath_unregister_led(&sc->assoc_led);
sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
ath_unregister_led(&sc->tx_led);
ath_unregister_led(&sc->rx_led);
ath_unregister_led(&sc->radio_led);
ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
}
static void ath_init_leds(struct ath_softc *sc)
{
char *trigger;
int ret;
/* Configure gpio 1 for output */
ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
/* LED off, active low */
ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
trigger = ieee80211_get_radio_led_name(sc->hw);
snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
"ath9k-%s:radio", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->radio_led, trigger);
sc->radio_led.led_type = ATH_LED_RADIO;
if (ret)
goto fail;
trigger = ieee80211_get_assoc_led_name(sc->hw);
snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
"ath9k-%s:assoc", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->assoc_led, trigger);
sc->assoc_led.led_type = ATH_LED_ASSOC;
if (ret)
goto fail;
trigger = ieee80211_get_tx_led_name(sc->hw);
snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
"ath9k-%s:tx", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->tx_led, trigger);
sc->tx_led.led_type = ATH_LED_TX;
if (ret)
goto fail;
trigger = ieee80211_get_rx_led_name(sc->hw);
snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
"ath9k-%s:rx", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->rx_led, trigger);
sc->rx_led.led_type = ATH_LED_RX;
if (ret)
goto fail;
return;
fail:
ath_deinit_leds(sc);
} }
static int ath_detach(struct ath_softc *sc) static int ath_detach(struct ath_softc *sc)
...@@ -1157,6 +1288,9 @@ static int ath_detach(struct ath_softc *sc) ...@@ -1157,6 +1288,9 @@ static int ath_detach(struct ath_softc *sc)
DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__); DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__);
/* Deinit LED control */
ath_deinit_leds(sc);
/* Unregister hw */ /* Unregister hw */
ieee80211_unregister_hw(hw); ieee80211_unregister_hw(hw);
...@@ -1250,18 +1384,21 @@ static int ath_attach(u16 devid, ...@@ -1250,18 +1384,21 @@ static int ath_attach(u16 devid,
goto bad; goto bad;
} }
/* Initialize LED control */
ath_init_leds(sc);
/* initialize tx/rx engine */ /* initialize tx/rx engine */
error = ath_tx_init(sc, ATH_TXBUF); error = ath_tx_init(sc, ATH_TXBUF);
if (error != 0) if (error != 0)
goto bad1; goto detach;
error = ath_rx_init(sc, ATH_RXBUF); error = ath_rx_init(sc, ATH_RXBUF);
if (error != 0) if (error != 0)
goto bad1; goto detach;
return 0; return 0;
bad1: detach:
ath_detach(sc); ath_detach(sc);
bad: bad:
return error; return error;
...@@ -1340,7 +1477,9 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1340,7 +1477,9 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto bad2; goto bad2;
} }
hw->flags = IEEE80211_HW_SIGNAL_DBM | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM; IEEE80211_HW_NOISE_DBM;
SET_IEEE80211_DEV(hw, &pdev->dev); SET_IEEE80211_DEV(hw, &pdev->dev);
...@@ -1404,6 +1543,10 @@ static void ath_pci_remove(struct pci_dev *pdev) ...@@ -1404,6 +1543,10 @@ static void ath_pci_remove(struct pci_dev *pdev)
static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state) static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{ {
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath_softc *sc = hw->priv;
ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
pci_save_state(pdev); pci_save_state(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_power_state(pdev, 3); pci_set_power_state(pdev, 3);
...@@ -1413,6 +1556,8 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -1413,6 +1556,8 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
static int ath_pci_resume(struct pci_dev *pdev) static int ath_pci_resume(struct pci_dev *pdev)
{ {
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath_softc *sc = hw->priv;
u32 val; u32 val;
int err; int err;
...@@ -1429,6 +1574,11 @@ static int ath_pci_resume(struct pci_dev *pdev) ...@@ -1429,6 +1574,11 @@ static int ath_pci_resume(struct pci_dev *pdev)
if ((val & 0x0000ff00) != 0) if ((val & 0x0000ff00) != 0)
pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
/* Enable LED */
ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
return 0; return 0;
} }
......
...@@ -18,19 +18,19 @@ ...@@ -18,19 +18,19 @@
#define PHY_H #define PHY_H
bool ath9k_hw_ar9280_set_channel(struct ath_hal *ah, bool ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
struct ath9k_channel struct ath9k_channel
*chan); *chan);
bool ath9k_hw_set_channel(struct ath_hal *ah, bool ath9k_hw_set_channel(struct ath_hal *ah,
struct ath9k_channel *chan); struct ath9k_channel *chan);
void ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex, void ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex,
u32 freqIndex, int regWrites); u32 freqIndex, int regWrites);
bool ath9k_hw_set_rf_regs(struct ath_hal *ah, bool ath9k_hw_set_rf_regs(struct ath_hal *ah,
struct ath9k_channel *chan, struct ath9k_channel *chan,
u16 modesIndex); u16 modesIndex);
void ath9k_hw_decrease_chain_power(struct ath_hal *ah, void ath9k_hw_decrease_chain_power(struct ath_hal *ah,
struct ath9k_channel *chan); struct ath9k_channel *chan);
bool ath9k_hw_init_rf(struct ath_hal *ah, bool ath9k_hw_init_rf(struct ath_hal *ah,
int *status); int *status);
#define AR_PHY_BASE 0x9800 #define AR_PHY_BASE 0x9800
#define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2)) #define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2))
......
...@@ -653,8 +653,8 @@ ath_rc_sib_init_validrates(struct ath_rate_node *ath_rc_priv, ...@@ -653,8 +653,8 @@ ath_rc_sib_init_validrates(struct ath_rate_node *ath_rc_priv,
rate_ctrl = (struct ath_tx_ratectrl *)(ath_rc_priv); rate_ctrl = (struct ath_tx_ratectrl *)(ath_rc_priv);
for (i = 0; i < rate_table->rate_cnt; i++) { for (i = 0; i < rate_table->rate_cnt; i++) {
valid = (ath_rc_priv->single_stream ? valid = (ath_rc_priv->single_stream ?
rate_table->info[i].valid_single_stream : rate_table->info[i].valid_single_stream :
rate_table->info[i].valid); rate_table->info[i].valid);
if (valid == TRUE) { if (valid == TRUE) {
u32 phy = rate_table->info[i].phy; u32 phy = rate_table->info[i].phy;
u8 valid_rate_count = 0; u8 valid_rate_count = 0;
...@@ -740,14 +740,14 @@ ath_rc_sib_setvalid_htrates(struct ath_rate_node *ath_rc_priv, ...@@ -740,14 +740,14 @@ ath_rc_sib_setvalid_htrates(struct ath_rate_node *ath_rc_priv,
for (j = 0; j < rate_table->rate_cnt; j++) { for (j = 0; j < rate_table->rate_cnt; j++) {
u32 phy = rate_table->info[j].phy; u32 phy = rate_table->info[j].phy;
u32 valid = (ath_rc_priv->single_stream ? u32 valid = (ath_rc_priv->single_stream ?
rate_table->info[j].valid_single_stream : rate_table->info[j].valid_single_stream :
rate_table->info[j].valid); rate_table->info[j].valid);
if (((((struct ath_rateset *) if (((((struct ath_rateset *)
mcs_set)->rs_rates[i] & 0x7F) != mcs_set)->rs_rates[i] & 0x7F) !=
(rate_table->info[j].dot11rate & 0x7F)) || (rate_table->info[j].dot11rate & 0x7F)) ||
!WLAN_RC_PHY_HT(phy) || !WLAN_RC_PHY_HT(phy) ||
!WLAN_RC_PHY_HT_VALID(valid, capflag)) !WLAN_RC_PHY_HT_VALID(valid, capflag))
continue; continue;
if (!ath_rc_valid_phyrate(phy, capflag, FALSE)) if (!ath_rc_valid_phyrate(phy, capflag, FALSE))
...@@ -847,9 +847,9 @@ void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp) ...@@ -847,9 +847,9 @@ void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp)
/* For half and quarter rate channles use different /* For half and quarter rate channles use different
* rate tables * rate tables
*/ */
if (sc->sc_curchan.channelFlags & CHANNEL_HALF) if (sc->sc_ah->ah_curchan->channelFlags & CHANNEL_HALF)
ar5416_sethalf_ratetable(asc); ar5416_sethalf_ratetable(asc);
else if (sc->sc_curchan.channelFlags & CHANNEL_QUARTER) else if (sc->sc_ah->ah_curchan->channelFlags & CHANNEL_QUARTER)
ar5416_setquarter_ratetable(asc); ar5416_setquarter_ratetable(asc);
else /* full rate */ else /* full rate */
ar5416_setfull_ratetable(asc); ar5416_setfull_ratetable(asc);
...@@ -866,10 +866,10 @@ void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp) ...@@ -866,10 +866,10 @@ void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp)
} }
static u8 ath_rc_ratefind_ht(struct ath_softc *sc, static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
struct ath_rate_node *ath_rc_priv, struct ath_rate_node *ath_rc_priv,
const struct ath_rate_table *rate_table, const struct ath_rate_table *rate_table,
int probe_allowed, int *is_probing, int probe_allowed, int *is_probing,
int is_retry) int is_retry)
{ {
u32 dt, best_thruput, this_thruput, now_msec; u32 dt, best_thruput, this_thruput, now_msec;
u8 rate, next_rate, best_rate, maxindex, minindex; u8 rate, next_rate, best_rate, maxindex, minindex;
...@@ -997,8 +997,8 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc, ...@@ -997,8 +997,8 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
rate = rate_ctrl->rate_table_size - 1; rate = rate_ctrl->rate_table_size - 1;
ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) || ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) ||
(rate_table->info[rate].valid_single_stream && (rate_table->info[rate].valid_single_stream &&
ath_rc_priv->single_stream)); ath_rc_priv->single_stream));
return rate; return rate;
} }
...@@ -1023,10 +1023,10 @@ static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table , ...@@ -1023,10 +1023,10 @@ static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table ,
} }
static u8 ath_rc_rate_getidx(struct ath_softc *sc, static u8 ath_rc_rate_getidx(struct ath_softc *sc,
struct ath_rate_node *ath_rc_priv, struct ath_rate_node *ath_rc_priv,
const struct ath_rate_table *rate_table, const struct ath_rate_table *rate_table,
u8 rix, u16 stepdown, u8 rix, u16 stepdown,
u16 min_rate) u16 min_rate)
{ {
u32 j; u32 j;
u8 nextindex; u8 nextindex;
...@@ -1066,8 +1066,8 @@ static void ath_rc_ratefind(struct ath_softc *sc, ...@@ -1066,8 +1066,8 @@ static void ath_rc_ratefind(struct ath_softc *sc,
rate_table = rate_table =
(struct ath_rate_table *)asc->hw_rate_table[sc->sc_curmode]; (struct ath_rate_table *)asc->hw_rate_table[sc->sc_curmode];
rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table,
(rcflag & ATH_RC_PROBE_ALLOWED) ? 1 : 0, (rcflag & ATH_RC_PROBE_ALLOWED) ? 1 : 0,
is_probe, is_retry); is_probe, is_retry);
nrix = rix; nrix = rix;
if ((rcflag & ATH_RC_PROBE_ALLOWED) && (*is_probe)) { if ((rcflag & ATH_RC_PROBE_ALLOWED) && (*is_probe)) {
...@@ -1099,13 +1099,13 @@ static void ath_rc_ratefind(struct ath_softc *sc, ...@@ -1099,13 +1099,13 @@ static void ath_rc_ratefind(struct ath_softc *sc,
try_num = ((i + 1) == num_rates) ? try_num = ((i + 1) == num_rates) ?
num_tries - (try_per_rate * i) : try_per_rate ; num_tries - (try_per_rate * i) : try_per_rate ;
min_rate = (((i + 1) == num_rates) && min_rate = (((i + 1) == num_rates) &&
(rcflag & ATH_RC_MINRATE_LASTRATE)) ? 1 : 0; (rcflag & ATH_RC_MINRATE_LASTRATE)) ? 1 : 0;
nrix = ath_rc_rate_getidx(sc, ath_rc_priv, nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
rate_table, nrix, 1, min_rate); rate_table, nrix, 1, min_rate);
/* All other rates in the series have RTS enabled */ /* All other rates in the series have RTS enabled */
ath_rc_rate_set_series(rate_table, ath_rc_rate_set_series(rate_table,
&series[i], try_num, nrix, TRUE); &series[i], try_num, nrix, TRUE);
} }
/* /*
...@@ -1124,13 +1124,13 @@ static void ath_rc_ratefind(struct ath_softc *sc, ...@@ -1124,13 +1124,13 @@ static void ath_rc_ratefind(struct ath_softc *sc,
* above conditions. * above conditions.
*/ */
if ((sc->sc_curmode == ATH9K_MODE_11NG_HT20) || if ((sc->sc_curmode == ATH9K_MODE_11NG_HT20) ||
(sc->sc_curmode == ATH9K_MODE_11NG_HT40PLUS) || (sc->sc_curmode == ATH9K_MODE_11NG_HT40PLUS) ||
(sc->sc_curmode == ATH9K_MODE_11NG_HT40MINUS)) { (sc->sc_curmode == ATH9K_MODE_11NG_HT40MINUS)) {
u8 dot11rate = rate_table->info[rix].dot11rate; u8 dot11rate = rate_table->info[rix].dot11rate;
u8 phy = rate_table->info[rix].phy; u8 phy = rate_table->info[rix].phy;
if (i == 4 && if (i == 4 &&
((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) || ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
(dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) { (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) {
series[3].rix = series[2].rix; series[3].rix = series[2].rix;
series[3].flags = series[2].flags; series[3].flags = series[2].flags;
series[3].max_4ms_framelen = series[2].max_4ms_framelen; series[3].max_4ms_framelen = series[2].max_4ms_framelen;
...@@ -1141,18 +1141,19 @@ static void ath_rc_ratefind(struct ath_softc *sc, ...@@ -1141,18 +1141,19 @@ static void ath_rc_ratefind(struct ath_softc *sc,
/* /*
* Return the Tx rate series. * Return the Tx rate series.
*/ */
void ath_rate_findrate(struct ath_softc *sc, static void ath_rate_findrate(struct ath_softc *sc,
struct ath_rate_node *ath_rc_priv, struct ath_rate_node *ath_rc_priv,
int num_tries, int num_tries,
int num_rates, int num_rates,
unsigned int rcflag, unsigned int rcflag,
struct ath_rc_series series[], struct ath_rc_series series[],
int *is_probe, int *is_probe,
int is_retry) int is_retry)
{ {
struct ath_vap *avp = ath_rc_priv->avp; struct ath_vap *avp = ath_rc_priv->avp;
DPRINTF(sc, ATH_DBG_RATE, "%s", __func__); DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
if (!num_rates || !num_tries) if (!num_rates || !num_tries)
return; return;
...@@ -1174,9 +1175,8 @@ void ath_rate_findrate(struct ath_softc *sc, ...@@ -1174,9 +1175,8 @@ void ath_rate_findrate(struct ath_softc *sc,
unsigned int mcs; unsigned int mcs;
u8 series_rix = 0; u8 series_rix = 0;
series[idx].tries = series[idx].tries = IEEE80211_RATE_IDX_ENTRY(
IEEE80211_RATE_IDX_ENTRY( avp->av_config.av_fixed_retryset, idx);
avp->av_config.av_fixed_retryset, idx);
mcs = IEEE80211_RATE_IDX_ENTRY( mcs = IEEE80211_RATE_IDX_ENTRY(
avp->av_config.av_fixed_rateset, idx); avp->av_config.av_fixed_rateset, idx);
...@@ -1228,7 +1228,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1228,7 +1228,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
u32 now_msec = jiffies_to_msecs(jiffies); u32 now_msec = jiffies_to_msecs(jiffies);
int state_change = FALSE, rate, count; int state_change = FALSE, rate, count;
u8 last_per; u8 last_per;
struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc; struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc;
struct ath_rate_table *rate_table = struct ath_rate_table *rate_table =
(struct ath_rate_table *)asc->hw_rate_table[sc->sc_curmode]; (struct ath_rate_table *)asc->hw_rate_table[sc->sc_curmode];
...@@ -1272,14 +1272,14 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1272,14 +1272,14 @@ static void ath_rc_update_ht(struct ath_softc *sc,
} else { } else {
/* xretries == 2 */ /* xretries == 2 */
count = sizeof(nretry_to_per_lookup) / count = sizeof(nretry_to_per_lookup) /
sizeof(nretry_to_per_lookup[0]); sizeof(nretry_to_per_lookup[0]);
if (retries >= count) if (retries >= count)
retries = count - 1; retries = count - 1;
/* new_PER = 7/8*old_PER + 1/8*(currentPER) */ /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
rate_ctrl->state[tx_rate].per = rate_ctrl->state[tx_rate].per =
(u8)(rate_ctrl->state[tx_rate].per - (u8)(rate_ctrl->state[tx_rate].per -
(rate_ctrl->state[tx_rate].per >> 3) + (rate_ctrl->state[tx_rate].per >> 3) +
((100) >> 3)); ((100) >> 3));
} }
/* xretries == 1 or 2 */ /* xretries == 1 or 2 */
...@@ -1295,8 +1295,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1295,8 +1295,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
if (retries >= count) if (retries >= count)
retries = count - 1; retries = count - 1;
if (info_priv->n_bad_frames) { if (info_priv->n_bad_frames) {
/* new_PER = 7/8*old_PER + 1/8*(currentPER) */ /* new_PER = 7/8*old_PER + 1/8*(currentPER)
/*
* Assuming that n_frames is not 0. The current PER * Assuming that n_frames is not 0. The current PER
* from the retries is 100 * retries / (retries+1), * from the retries is 100 * retries / (retries+1),
* since the first retries attempts failed, and the * since the first retries attempts failed, and the
...@@ -1386,7 +1385,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1386,7 +1385,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
* rssi_ack values. * rssi_ack values.
*/ */
if (tx_rate == rate_ctrl->rate_max_phy && if (tx_rate == rate_ctrl->rate_max_phy &&
rate_ctrl->hw_maxretry_pktcnt < 255) { rate_ctrl->hw_maxretry_pktcnt < 255) {
rate_ctrl->hw_maxretry_pktcnt++; rate_ctrl->hw_maxretry_pktcnt++;
} }
...@@ -1418,7 +1417,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1418,7 +1417,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
/* Now reduce the current /* Now reduce the current
* rssi threshold. */ * rssi threshold. */
if ((rssi_ackAvg < rssi_thres + 2) && if ((rssi_ackAvg < rssi_thres + 2) &&
(rssi_thres > rssi_ack_vmin)) { (rssi_thres > rssi_ack_vmin)) {
rate_ctrl->state[tx_rate]. rate_ctrl->state[tx_rate].
rssi_thres--; rssi_thres--;
} }
...@@ -1436,10 +1435,10 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1436,10 +1435,10 @@ static void ath_rc_update_ht(struct ath_softc *sc,
* a while (except if we are probing). * a while (except if we are probing).
*/ */
if (rate_ctrl->state[tx_rate].per >= 55 && tx_rate > 0 && if (rate_ctrl->state[tx_rate].per >= 55 && tx_rate > 0 &&
rate_table->info[tx_rate].ratekbps <= rate_table->info[tx_rate].ratekbps <=
rate_table->info[rate_ctrl->rate_max_phy].ratekbps) { rate_table->info[rate_ctrl->rate_max_phy].ratekbps) {
ath_rc_get_nextlowervalid_txrate(rate_table, rate_ctrl, ath_rc_get_nextlowervalid_txrate(rate_table, rate_ctrl,
(u8) tx_rate, &rate_ctrl->rate_max_phy); (u8) tx_rate, &rate_ctrl->rate_max_phy);
/* Don't probe for a little while. */ /* Don't probe for a little while. */
rate_ctrl->probe_time = now_msec; rate_ctrl->probe_time = now_msec;
...@@ -1460,43 +1459,43 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1460,43 +1459,43 @@ static void ath_rc_update_ht(struct ath_softc *sc,
break; break;
if (rate_ctrl->state[rate].rssi_thres + if (rate_ctrl->state[rate].rssi_thres +
rate_table->info[rate].rssi_ack_deltamin > rate_table->info[rate].rssi_ack_deltamin >
rate_ctrl->state[rate+1].rssi_thres) { rate_ctrl->state[rate+1].rssi_thres) {
rate_ctrl->state[rate+1].rssi_thres = rate_ctrl->state[rate+1].rssi_thres =
rate_ctrl->state[rate]. rate_ctrl->state[rate].
rssi_thres + rssi_thres +
rate_table->info[rate]. rate_table->info[rate].
rssi_ack_deltamin; rssi_ack_deltamin;
} }
} }
/* Make sure the rates below this have lower rssi thresholds. */ /* Make sure the rates below this have lower rssi thresholds. */
for (rate = tx_rate - 1; rate >= 0; rate--) { for (rate = tx_rate - 1; rate >= 0; rate--) {
if (rate_table->info[rate].phy != if (rate_table->info[rate].phy !=
rate_table->info[tx_rate].phy) rate_table->info[tx_rate].phy)
break; break;
if (rate_ctrl->state[rate].rssi_thres + if (rate_ctrl->state[rate].rssi_thres +
rate_table->info[rate].rssi_ack_deltamin > rate_table->info[rate].rssi_ack_deltamin >
rate_ctrl->state[rate+1].rssi_thres) { rate_ctrl->state[rate+1].rssi_thres) {
if (rate_ctrl->state[rate+1].rssi_thres < if (rate_ctrl->state[rate+1].rssi_thres <
rate_table->info[rate]. rate_table->info[rate].
rssi_ack_deltamin) rssi_ack_deltamin)
rate_ctrl->state[rate].rssi_thres = 0; rate_ctrl->state[rate].rssi_thres = 0;
else { else {
rate_ctrl->state[rate].rssi_thres = rate_ctrl->state[rate].rssi_thres =
rate_ctrl->state[rate+1]. rate_ctrl->state[rate+1].
rssi_thres - rssi_thres -
rate_table->info[rate]. rate_table->info[rate].
rssi_ack_deltamin; rssi_ack_deltamin;
} }
if (rate_ctrl->state[rate].rssi_thres < if (rate_ctrl->state[rate].rssi_thres <
rate_table->info[rate]. rate_table->info[rate].
rssi_ack_validmin) { rssi_ack_validmin) {
rate_ctrl->state[rate].rssi_thres = rate_ctrl->state[rate].rssi_thres =
rate_table->info[rate]. rate_table->info[rate].
rssi_ack_validmin; rssi_ack_validmin;
} }
} }
} }
...@@ -1507,11 +1506,11 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1507,11 +1506,11 @@ static void ath_rc_update_ht(struct ath_softc *sc,
if (rate_ctrl->state[tx_rate].per < last_per) { if (rate_ctrl->state[tx_rate].per < last_per) {
for (rate = tx_rate - 1; rate >= 0; rate--) { for (rate = tx_rate - 1; rate >= 0; rate--) {
if (rate_table->info[rate].phy != if (rate_table->info[rate].phy !=
rate_table->info[tx_rate].phy) rate_table->info[tx_rate].phy)
break; break;
if (rate_ctrl->state[rate].per > if (rate_ctrl->state[rate].per >
rate_ctrl->state[rate+1].per) { rate_ctrl->state[rate+1].per) {
rate_ctrl->state[rate].per = rate_ctrl->state[rate].per =
rate_ctrl->state[rate+1].per; rate_ctrl->state[rate+1].per;
} }
...@@ -1528,11 +1527,11 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1528,11 +1527,11 @@ static void ath_rc_update_ht(struct ath_softc *sc,
/* Every so often, we reduce the thresholds and /* Every so often, we reduce the thresholds and
* PER (different for CCK and OFDM). */ * PER (different for CCK and OFDM). */
if (now_msec - rate_ctrl->rssi_down_time >= if (now_msec - rate_ctrl->rssi_down_time >=
rate_table->rssi_reduce_interval) { rate_table->rssi_reduce_interval) {
for (rate = 0; rate < rate_ctrl->rate_table_size; rate++) { for (rate = 0; rate < rate_ctrl->rate_table_size; rate++) {
if (rate_ctrl->state[rate].rssi_thres > if (rate_ctrl->state[rate].rssi_thres >
rate_table->info[rate].rssi_ack_validmin) rate_table->info[rate].rssi_ack_validmin)
rate_ctrl->state[rate].rssi_thres -= 1; rate_ctrl->state[rate].rssi_thres -= 1;
} }
rate_ctrl->rssi_down_time = now_msec; rate_ctrl->rssi_down_time = now_msec;
...@@ -1541,7 +1540,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1541,7 +1540,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
/* Every so often, we reduce the thresholds /* Every so often, we reduce the thresholds
* and PER (different for CCK and OFDM). */ * and PER (different for CCK and OFDM). */
if (now_msec - rate_ctrl->per_down_time >= if (now_msec - rate_ctrl->per_down_time >=
rate_table->rssi_reduce_interval) { rate_table->rssi_reduce_interval) {
for (rate = 0; rate < rate_ctrl->rate_table_size; rate++) { for (rate = 0; rate < rate_ctrl->rate_table_size; rate++) {
rate_ctrl->state[rate].per = rate_ctrl->state[rate].per =
7 * rate_ctrl->state[rate].per / 8; 7 * rate_ctrl->state[rate].per / 8;
...@@ -1560,7 +1559,7 @@ static void ath_rc_update(struct ath_softc *sc, ...@@ -1560,7 +1559,7 @@ static void ath_rc_update(struct ath_softc *sc,
struct ath_tx_info_priv *info_priv, int final_ts_idx, struct ath_tx_info_priv *info_priv, int final_ts_idx,
int xretries, int long_retry) int xretries, int long_retry)
{ {
struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc; struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc;
struct ath_rate_table *rate_table; struct ath_rate_table *rate_table;
struct ath_tx_ratectrl *rate_ctrl; struct ath_tx_ratectrl *rate_ctrl;
struct ath_rc_series rcs[4]; struct ath_rc_series rcs[4];
...@@ -1637,7 +1636,6 @@ static void ath_rc_update(struct ath_softc *sc, ...@@ -1637,7 +1636,6 @@ static void ath_rc_update(struct ath_softc *sc,
xretries, long_retry); xretries, long_retry);
} }
/* /*
* Process a tx descriptor for a completed transmit (success or failure). * Process a tx descriptor for a completed transmit (success or failure).
*/ */
...@@ -1651,13 +1649,13 @@ static void ath_rate_tx_complete(struct ath_softc *sc, ...@@ -1651,13 +1649,13 @@ static void ath_rate_tx_complete(struct ath_softc *sc,
struct ath_vap *avp; struct ath_vap *avp;
avp = rc_priv->avp; avp = rc_priv->avp;
if ((avp->av_config.av_fixed_rateset != IEEE80211_FIXED_RATE_NONE) if ((avp->av_config.av_fixed_rateset != IEEE80211_FIXED_RATE_NONE) ||
|| info_priv->tx.ts_status & ATH9K_TXERR_FILT) (info_priv->tx.ts_status & ATH9K_TXERR_FILT))
return; return;
if (info_priv->tx.ts_rssi > 0) { if (info_priv->tx.ts_rssi > 0) {
ATH_RSSI_LPF(an->an_chainmask_sel.tx_avgrssi, ATH_RSSI_LPF(an->an_chainmask_sel.tx_avgrssi,
info_priv->tx.ts_rssi); info_priv->tx.ts_rssi);
} }
/* /*
...@@ -1682,7 +1680,6 @@ static void ath_rate_tx_complete(struct ath_softc *sc, ...@@ -1682,7 +1680,6 @@ static void ath_rate_tx_complete(struct ath_softc *sc,
info_priv->tx.ts_longretry); info_priv->tx.ts_longretry);
} }
/* /*
* Update the SIB's rate control information * Update the SIB's rate control information
* *
...@@ -1701,8 +1698,8 @@ static void ath_rc_sib_update(struct ath_softc *sc, ...@@ -1701,8 +1698,8 @@ static void ath_rc_sib_update(struct ath_softc *sc,
struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc; struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc;
struct ath_rateset *rateset = negotiated_rates; struct ath_rateset *rateset = negotiated_rates;
u8 *ht_mcs = (u8 *)negotiated_htrates; u8 *ht_mcs = (u8 *)negotiated_htrates;
struct ath_tx_ratectrl *rate_ctrl = (struct ath_tx_ratectrl *) struct ath_tx_ratectrl *rate_ctrl =
(ath_rc_priv); (struct ath_tx_ratectrl *)ath_rc_priv;
u8 i, j, k, hi = 0, hthi = 0; u8 i, j, k, hi = 0, hthi = 0;
rate_table = (struct ath_rate_table *) rate_table = (struct ath_rate_table *)
...@@ -1824,7 +1821,8 @@ static void ath_setup_rates(struct ieee80211_local *local, struct sta_info *sta) ...@@ -1824,7 +1821,8 @@ static void ath_setup_rates(struct ieee80211_local *local, struct sta_info *sta)
struct ath_rate_node *rc_priv = sta->rate_ctrl_priv; struct ath_rate_node *rc_priv = sta->rate_ctrl_priv;
int i, j = 0; int i, j = 0;
DPRINTF(sc, ATH_DBG_RATE, "%s", __func__); DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
for (i = 0; i < sband->n_bitrates; i++) { for (i = 0; i < sband->n_bitrates; i++) {
if (sta->supp_rates[local->hw.conf.channel->band] & BIT(i)) { if (sta->supp_rates[local->hw.conf.channel->band] & BIT(i)) {
...@@ -1903,7 +1901,7 @@ static void ath_tx_aggr_resp(struct ath_softc *sc, ...@@ -1903,7 +1901,7 @@ static void ath_tx_aggr_resp(struct ath_softc *sc,
int state; int state;
DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac);
if (!sc->sc_txaggr) if (!(sc->sc_flags & SC_OP_TXAGGR))
return; return;
txtid = ATH_AN_2_TID(an, tidno); txtid = ATH_AN_2_TID(an, tidno);
...@@ -1944,7 +1942,7 @@ static void ath_get_rate(void *priv, struct net_device *dev, ...@@ -1944,7 +1942,7 @@ static void ath_get_rate(void *priv, struct net_device *dev,
struct ath_rate_node *ath_rc_priv; struct ath_rate_node *ath_rc_priv;
struct ath_node *an; struct ath_node *an;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
int is_probe, chk, ret; int is_probe = FALSE, chk, ret;
s8 lowest_idx; s8 lowest_idx;
__le16 fc = hdr->frame_control; __le16 fc = hdr->frame_control;
u8 *qc, tid; u8 *qc, tid;
...@@ -1962,7 +1960,7 @@ static void ath_get_rate(void *priv, struct net_device *dev, ...@@ -1962,7 +1960,7 @@ static void ath_get_rate(void *priv, struct net_device *dev,
tx_info_priv->min_rate = (sband->bitrates[lowest_idx].bitrate * 2) / 10; tx_info_priv->min_rate = (sband->bitrates[lowest_idx].bitrate * 2) / 10;
/* lowest rate for management and multicast/broadcast frames */ /* lowest rate for management and multicast/broadcast frames */
if (!ieee80211_is_data(fc) || if (!ieee80211_is_data(fc) ||
is_multicast_ether_addr(hdr->addr1) || !sta) { is_multicast_ether_addr(hdr->addr1) || !sta) {
sel->rate_idx = lowest_idx; sel->rate_idx = lowest_idx;
return; return;
} }
...@@ -1978,7 +1976,7 @@ static void ath_get_rate(void *priv, struct net_device *dev, ...@@ -1978,7 +1976,7 @@ static void ath_get_rate(void *priv, struct net_device *dev,
false); false);
if (is_probe) if (is_probe)
sel->probe_idx = ((struct ath_tx_ratectrl *) sel->probe_idx = ((struct ath_tx_ratectrl *)
sta->rate_ctrl_priv)->probe_rate; sta->rate_ctrl_priv)->probe_rate;
/* Ratecontrol sometimes returns invalid rate index */ /* Ratecontrol sometimes returns invalid rate index */
if (tx_info_priv->rcs[0].rix != 0xff) if (tx_info_priv->rcs[0].rix != 0xff)
...@@ -2035,6 +2033,7 @@ static void ath_rate_init(void *priv, void *priv_sta, ...@@ -2035,6 +2033,7 @@ static void ath_rate_init(void *priv, void *priv_sta,
struct ieee80211_hw *hw = local_to_hw(local); struct ieee80211_hw *hw = local_to_hw(local);
struct ieee80211_conf *conf = &local->hw.conf; struct ieee80211_conf *conf = &local->hw.conf;
struct ath_softc *sc = hw->priv; struct ath_softc *sc = hw->priv;
struct ath_rate_node *ath_rc_priv = priv_sta;
int i, j = 0; int i, j = 0;
DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
...@@ -2046,12 +2045,11 @@ static void ath_rate_init(void *priv, void *priv_sta, ...@@ -2046,12 +2045,11 @@ static void ath_rate_init(void *priv, void *priv_sta,
if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
for (i = 0; i < MCS_SET_SIZE; i++) { for (i = 0; i < MCS_SET_SIZE; i++) {
if (conf->ht_conf.supp_mcs_set[i/8] & (1<<(i%8))) if (conf->ht_conf.supp_mcs_set[i/8] & (1<<(i%8)))
((struct ath_rate_node *) ath_rc_priv->neg_ht_rates.rs_rates[j++] = i;
priv_sta)->neg_ht_rates.rs_rates[j++] = i;
if (j == ATH_RATE_MAX) if (j == ATH_RATE_MAX)
break; break;
} }
((struct ath_rate_node *)priv_sta)->neg_ht_rates.rs_nrates = j; ath_rc_priv->neg_ht_rates.rs_nrates = j;
} }
ath_rc_node_update(hw, priv_sta); ath_rc_node_update(hw, priv_sta);
} }
...@@ -2066,7 +2064,7 @@ static void *ath_rate_alloc(struct ieee80211_local *local) ...@@ -2066,7 +2064,7 @@ static void *ath_rate_alloc(struct ieee80211_local *local)
struct ieee80211_hw *hw = local_to_hw(local); struct ieee80211_hw *hw = local_to_hw(local);
struct ath_softc *sc = hw->priv; struct ath_softc *sc = hw->priv;
DPRINTF(sc, ATH_DBG_RATE, "%s", __func__); DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
return local->hw.priv; return local->hw.priv;
} }
...@@ -2081,14 +2079,17 @@ static void *ath_rate_alloc_sta(void *priv, gfp_t gfp) ...@@ -2081,14 +2079,17 @@ static void *ath_rate_alloc_sta(void *priv, gfp_t gfp)
struct ath_vap *avp = sc->sc_vaps[0]; struct ath_vap *avp = sc->sc_vaps[0];
struct ath_rate_node *rate_priv; struct ath_rate_node *rate_priv;
DPRINTF(sc, ATH_DBG_RATE, "%s", __func__); DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
rate_priv = ath_rate_node_alloc(avp, sc->sc_rc, gfp); rate_priv = ath_rate_node_alloc(avp, sc->sc_rc, gfp);
if (!rate_priv) { if (!rate_priv) {
DPRINTF(sc, ATH_DBG_FATAL, "%s:Unable to allocate" DPRINTF(sc, ATH_DBG_FATAL,
"private rate control structure", __func__); "%s: Unable to allocate private rc structure\n",
__func__);
return NULL; return NULL;
} }
ath_rc_sib_init(rate_priv); ath_rc_sib_init(rate_priv);
return rate_priv; return rate_priv;
} }
......
...@@ -71,9 +71,6 @@ enum ieee80211_fixed_rate_mode { ...@@ -71,9 +71,6 @@ enum ieee80211_fixed_rate_mode {
*/ */
#define IEEE80211_RATE_IDX_ENTRY(val, idx) (((val&(0xff<<(idx*8)))>>(idx*8))) #define IEEE80211_RATE_IDX_ENTRY(val, idx) (((val&(0xff<<(idx*8)))>>(idx*8)))
#define SHORT_PRE 1
#define LONG_PRE 0
#define WLAN_PHY_HT_20_SS WLAN_RC_PHY_HT_20_SS #define WLAN_PHY_HT_20_SS WLAN_RC_PHY_HT_20_SS
#define WLAN_PHY_HT_20_DS WLAN_RC_PHY_HT_20_DS #define WLAN_PHY_HT_20_DS WLAN_RC_PHY_HT_20_DS
#define WLAN_PHY_HT_20_DS_HGI WLAN_RC_PHY_HT_20_DS_HGI #define WLAN_PHY_HT_20_DS_HGI WLAN_RC_PHY_HT_20_DS_HGI
...@@ -102,18 +99,18 @@ enum { ...@@ -102,18 +99,18 @@ enum {
WLAN_RC_PHY_MAX WLAN_RC_PHY_MAX
}; };
#define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \ #define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \
|| (_phy == WLAN_RC_PHY_HT_40_DS) \ || (_phy == WLAN_RC_PHY_HT_40_DS) \
|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
#define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \ #define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \
|| (_phy == WLAN_RC_PHY_HT_40_DS) \ || (_phy == WLAN_RC_PHY_HT_40_DS) \
|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
#define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \ #define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
#define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS) #define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS)
...@@ -135,56 +132,59 @@ enum { ...@@ -135,56 +132,59 @@ enum {
#define WLAN_RC_SGI_FLAG (0x04) #define WLAN_RC_SGI_FLAG (0x04)
#define WLAN_RC_HT_FLAG (0x08) #define WLAN_RC_HT_FLAG (0x08)
/* Index into the rate table */
#define INIT_RATE_MAX_20 23
#define INIT_RATE_MAX_40 40
#define RATE_TABLE_SIZE 64 #define RATE_TABLE_SIZE 64
/* XXX: Convert to kdoc */ /**
* struct ath_rate_table - Rate Control table
* @valid: valid for use in rate control
* @valid_single_stream: valid for use in rate control for
* single stream operation
* @phy: CCK/OFDM
* @ratekbps: rate in Kbits per second
* @user_ratekbps: user rate in Kbits per second
* @ratecode: rate that goes into HW descriptors
* @short_preamble: Mask for enabling short preamble in ratecode for CCK
* @dot11rate: value that goes into supported
* rates info element of MLME
* @ctrl_rate: Index of next lower basic rate, used for duration computation
* @max_4ms_framelen: maximum frame length(bytes) for tx duration
* @probe_interval: interval for rate control to probe for other rates
* @rssi_reduce_interval: interval for rate control to reduce rssi
* @initial_ratemax: initial ratemax value used in ath_rc_sib_update()
*/
struct ath_rate_table { struct ath_rate_table {
int rate_cnt; int rate_cnt;
struct { struct {
int valid; /* Valid for use in rate control */ int valid;
int valid_single_stream;/* Valid for use in rate control int valid_single_stream;
for single stream operation */ u8 phy;
u8 phy; /* CCK/OFDM/TURBO/XR */ u32 ratekbps;
u32 ratekbps; /* Rate in Kbits per second */ u32 user_ratekbps;
u32 user_ratekbps; /* User rate in KBits per second */ u8 ratecode;
u8 ratecode; /* rate that goes into u8 short_preamble;
hw descriptors */ u8 dot11rate;
u8 short_preamble; /* Mask for enabling short preamble u8 ctrl_rate;
in rate code for CCK */ int8_t rssi_ack_validmin;
u8 dot11rate; /* Value that goes into supported int8_t rssi_ack_deltamin;
rates info element of MLME */ u8 base_index;
u8 ctrl_rate; /* Index of next lower basic rate, u8 cw40index;
used for duration computation */ u8 sgi_index;
int8_t rssi_ack_validmin; /* Rate control related */ u8 ht_index;
int8_t rssi_ack_deltamin; /* Rate control related */ u32 max_4ms_framelen;
u8 base_index; /* base rate index */
u8 cw40index; /* 40cap rate index */
u8 sgi_index; /* shortgi rate index */
u8 ht_index; /* shortgi rate index */
u32 max_4ms_framelen; /* Maximum frame length(bytes)
for 4ms tx duration */
} info[RATE_TABLE_SIZE]; } info[RATE_TABLE_SIZE];
u32 probe_interval; /* interval for ratectrl to u32 probe_interval;
probe for other rates */ u32 rssi_reduce_interval;
u32 rssi_reduce_interval; /* interval for ratectrl u8 initial_ratemax;
to reduce RSSI */
u8 initial_ratemax; /* the initial ratemax value used
in ath_rc_sib_update() */
}; };
#define ATH_RC_PROBE_ALLOWED 0x00000001 #define ATH_RC_PROBE_ALLOWED 0x00000001
#define ATH_RC_MINRATE_LASTRATE 0x00000002 #define ATH_RC_MINRATE_LASTRATE 0x00000002
#define ATH_RC_SHORT_PREAMBLE 0x00000004
struct ath_rc_series { struct ath_rc_series {
u8 rix; u8 rix;
u8 tries; u8 tries;
u8 flags; u8 flags;
u32 max_4ms_framelen; u32 max_4ms_framelen;
}; };
/* rcs_flags definition */ /* rcs_flags definition */
...@@ -201,42 +201,56 @@ struct ath_rc_series { ...@@ -201,42 +201,56 @@ struct ath_rc_series {
#define MAX_TX_RATE_PHY 48 #define MAX_TX_RATE_PHY 48
struct ath_tx_ratectrl_state { struct ath_tx_ratectrl_state {
int8_t rssi_thres; /* required rssi for this rate (dB) */ int8_t rssi_thres; /* required rssi for this rate (dB) */
u8 per; /* recent estimate of packet error rate (%) */ u8 per; /* recent estimate of packet error rate (%) */
}; };
/**
* struct ath_tx_ratectrl - TX Rate control Information
* @state: RC state
* @rssi_last: last ACK rssi
* @rssi_last_lookup: last ACK rssi used for lookup
* @rssi_last_prev: previous last ACK rssi
* @rssi_last_prev2: 2nd previous last ACK rssi
* @rssi_sum_cnt: count of rssi_sum for averaging
* @rssi_sum_rate: rate that we are averaging
* @rssi_sum: running sum of rssi for averaging
* @probe_rate: rate we are probing at
* @rssi_time: msec timestamp for last ack rssi
* @rssi_down_time: msec timestamp for last down step
* @probe_time: msec timestamp for last probe
* @hw_maxretry_pktcnt: num of packets since we got HW max retry error
* @max_valid_rate: maximum number of valid rate
* @per_down_time: msec timestamp for last PER down step
* @valid_phy_ratecnt: valid rate count
* @rate_max_phy: phy index for the max rate
* @probe_interval: interval for ratectrl to probe for other rates
*/
struct ath_tx_ratectrl { struct ath_tx_ratectrl {
struct ath_tx_ratectrl_state state[MAX_TX_RATE_TBL]; /* state */ struct ath_tx_ratectrl_state state[MAX_TX_RATE_TBL];
int8_t rssi_last; /* last ack rssi */ int8_t rssi_last;
int8_t rssi_last_lookup; /* last ack rssi used for lookup */ int8_t rssi_last_lookup;
int8_t rssi_last_prev; /* previous last ack rssi */ int8_t rssi_last_prev;
int8_t rssi_last_prev2; /* 2nd previous last ack rssi */ int8_t rssi_last_prev2;
int32_t rssi_sum_cnt; /* count of rssi_sum for averaging */ int32_t rssi_sum_cnt;
int32_t rssi_sum_rate; /* rate that we are averaging */ int32_t rssi_sum_rate;
int32_t rssi_sum; /* running sum of rssi for averaging */ int32_t rssi_sum;
u32 valid_txrate_mask; /* mask of valid rates */ u8 rate_table_size;
u8 rate_table_size; /* rate table size */ u8 probe_rate;
u8 rate_max; /* max rate that has recently worked */ u32 rssi_time;
u8 probe_rate; /* rate we are probing at */ u32 rssi_down_time;
u32 rssi_time; /* msec timestamp for last ack rssi */ u32 probe_time;
u32 rssi_down_time; /* msec timestamp for last down step */ u8 hw_maxretry_pktcnt;
u32 probe_time; /* msec timestamp for last probe */ u8 max_valid_rate;
u8 hw_maxretry_pktcnt; /* num packets since we got u8 valid_rate_index[MAX_TX_RATE_TBL];
HW max retry error */ u32 per_down_time;
u8 max_valid_rate; /* maximum number of valid rate */
u8 valid_rate_index[MAX_TX_RATE_TBL]; /* valid rate index */
u32 per_down_time; /* msec timstamp for last
PER down step */
/* 11n state */ /* 11n state */
u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX]; /* valid rate count */ u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX];
u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][MAX_TX_RATE_TBL]; u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][MAX_TX_RATE_TBL];
u8 rc_phy_mode; u8 rc_phy_mode;
u8 rate_max_phy; /* Phy index for the max rate */ u8 rate_max_phy;
u32 rate_max_lastused; /* msec timstamp of when we u32 probe_interval;
last used rateMaxPhy */
u32 probe_interval; /* interval for ratectrl to probe
for other rates */
}; };
struct ath_rateset { struct ath_rateset {
...@@ -248,29 +262,32 @@ struct ath_rateset { ...@@ -248,29 +262,32 @@ struct ath_rateset {
struct ath_rate_softc { struct ath_rate_softc {
/* phy tables that contain rate control data */ /* phy tables that contain rate control data */
const void *hw_rate_table[ATH9K_MODE_MAX]; const void *hw_rate_table[ATH9K_MODE_MAX];
int fixedrix; /* -1 or index of fixed rate */
/* -1 or index of fixed rate */
int fixedrix;
}; };
/* per-node state */ /* per-node state */
struct ath_rate_node { struct ath_rate_node {
struct ath_tx_ratectrl tx_ratectrl; /* rate control state proper */ struct ath_tx_ratectrl tx_ratectrl;
u32 prev_data_rix; /* rate idx of last data frame */
/* map of rate ix -> negotiated rate set ix */ /* rate idx of last data frame */
u8 rixmap[MAX_TX_RATE_TBL]; u32 prev_data_rix;
/* map of ht rate ix -> negotiated rate set ix */ /* ht capabilities */
u8 ht_rixmap[MAX_TX_RATE_TBL]; u8 ht_cap;
u8 ht_cap; /* ht capabilities */ /* When TRUE, only single stream Tx possible */
u8 ant_tx; /* current transmit antenna */ u8 single_stream;
u8 single_stream; /* When TRUE, only single /* Negotiated rates */
stream Tx possible */ struct ath_rateset neg_rates;
struct ath_rateset neg_rates; /* Negotiated rates */
struct ath_rateset neg_ht_rates; /* Negotiated HT rates */ /* Negotiated HT rates */
struct ath_rate_softc *asc; /* back pointer to atheros softc */ struct ath_rateset neg_ht_rates;
struct ath_vap *avp; /* back pointer to vap */
struct ath_rate_softc *asc;
struct ath_vap *avp;
}; };
/* Driver data of ieee80211_tx_info */ /* Driver data of ieee80211_tx_info */
...@@ -296,18 +313,11 @@ void ath_rate_detach(struct ath_rate_softc *asc); ...@@ -296,18 +313,11 @@ void ath_rate_detach(struct ath_rate_softc *asc);
void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv); void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv);
void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp); void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp);
/*
* Return the tx rate series.
*/
void ath_rate_findrate(struct ath_softc *sc, struct ath_rate_node *ath_rc_priv,
int num_tries, int num_rates,
unsigned int rcflag, struct ath_rc_series[],
int *is_probe, int isretry);
/* /*
* Return rate index for given Dot11 Rate. * Return rate index for given Dot11 Rate.
*/ */
u8 ath_rate_findrateix(struct ath_softc *sc, u8 ath_rate_findrateix(struct ath_softc *sc,
u8 dot11_rate); u8 dot11_rate);
/* Routines to register/unregister rate control algorithm */ /* Routines to register/unregister rate control algorithm */
int ath_rate_control_register(void); int ath_rate_control_register(void);
......
...@@ -184,7 +184,7 @@ static int ath_ampdu_input(struct ath_softc *sc, ...@@ -184,7 +184,7 @@ static int ath_ampdu_input(struct ath_softc *sc,
tid = qc[0] & 0xf; tid = qc[0] & 0xf;
} }
if (sc->sc_opmode == ATH9K_M_STA) { if (sc->sc_ah->ah_opmode == ATH9K_M_STA) {
/* Drop the frame not belonging to me. */ /* Drop the frame not belonging to me. */
if (memcmp(hdr->addr1, sc->sc_myaddr, ETH_ALEN)) { if (memcmp(hdr->addr1, sc->sc_myaddr, ETH_ALEN)) {
dev_kfree_skb(skb); dev_kfree_skb(skb);
...@@ -448,17 +448,16 @@ static int ath_rx_indicate(struct ath_softc *sc, ...@@ -448,17 +448,16 @@ static int ath_rx_indicate(struct ath_softc *sc,
int type; int type;
/* indicate frame to the stack, which will free the old skb. */ /* indicate frame to the stack, which will free the old skb. */
type = ath__rx_indicate(sc, skb, status, keyix); type = _ath_rx_indicate(sc, skb, status, keyix);
/* allocate a new skb and queue it to for H/W processing */ /* allocate a new skb and queue it to for H/W processing */
nskb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize); nskb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize);
if (nskb != NULL) { if (nskb != NULL) {
bf->bf_mpdu = nskb; bf->bf_mpdu = nskb;
bf->bf_buf_addr = ath_skb_map_single(sc, bf->bf_buf_addr = pci_map_single(sc->pdev, nskb->data,
nskb, skb_end_pointer(nskb) - nskb->head,
PCI_DMA_FROMDEVICE, PCI_DMA_FROMDEVICE);
/* XXX: Remove get_dma_mem_context() */ bf->bf_dmacontext = bf->bf_buf_addr;
get_dma_mem_context(bf, bf_dmacontext));
ATH_RX_CONTEXT(nskb)->ctx_rxbuf = bf; ATH_RX_CONTEXT(nskb)->ctx_rxbuf = bf;
/* queue the new wbuf to H/W */ /* queue the new wbuf to H/W */
...@@ -504,7 +503,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) ...@@ -504,7 +503,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
do { do {
spin_lock_init(&sc->sc_rxflushlock); spin_lock_init(&sc->sc_rxflushlock);
sc->sc_rxflush = 0; sc->sc_flags &= ~SC_OP_RXFLUSH;
spin_lock_init(&sc->sc_rxbuflock); spin_lock_init(&sc->sc_rxbuflock);
/* /*
...@@ -541,9 +540,10 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) ...@@ -541,9 +540,10 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
} }
bf->bf_mpdu = skb; bf->bf_mpdu = skb;
bf->bf_buf_addr = bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data,
ath_skb_map_single(sc, skb, PCI_DMA_FROMDEVICE, skb_end_pointer(skb) - skb->head,
get_dma_mem_context(bf, bf_dmacontext)); PCI_DMA_FROMDEVICE);
bf->bf_dmacontext = bf->bf_buf_addr;
ATH_RX_CONTEXT(skb)->ctx_rxbuf = bf; ATH_RX_CONTEXT(skb)->ctx_rxbuf = bf;
} }
sc->sc_rxlink = NULL; sc->sc_rxlink = NULL;
...@@ -597,6 +597,7 @@ void ath_rx_cleanup(struct ath_softc *sc) ...@@ -597,6 +597,7 @@ void ath_rx_cleanup(struct ath_softc *sc)
u32 ath_calcrxfilter(struct ath_softc *sc) u32 ath_calcrxfilter(struct ath_softc *sc)
{ {
#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR) #define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
u32 rfilt; u32 rfilt;
rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE) rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE)
...@@ -604,25 +605,29 @@ u32 ath_calcrxfilter(struct ath_softc *sc) ...@@ -604,25 +605,29 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
| ATH9K_RX_FILTER_MCAST; | ATH9K_RX_FILTER_MCAST;
/* If not a STA, enable processing of Probe Requests */ /* If not a STA, enable processing of Probe Requests */
if (sc->sc_opmode != ATH9K_M_STA) if (sc->sc_ah->ah_opmode != ATH9K_M_STA)
rfilt |= ATH9K_RX_FILTER_PROBEREQ; rfilt |= ATH9K_RX_FILTER_PROBEREQ;
/* Can't set HOSTAP into promiscous mode */ /* Can't set HOSTAP into promiscous mode */
if (sc->sc_opmode == ATH9K_M_MONITOR) { if (((sc->sc_ah->ah_opmode != ATH9K_M_HOSTAP) &&
(sc->rx_filter & FIF_PROMISC_IN_BSS)) ||
(sc->sc_ah->ah_opmode == ATH9K_M_MONITOR)) {
rfilt |= ATH9K_RX_FILTER_PROM; rfilt |= ATH9K_RX_FILTER_PROM;
/* ??? To prevent from sending ACK */ /* ??? To prevent from sending ACK */
rfilt &= ~ATH9K_RX_FILTER_UCAST; rfilt &= ~ATH9K_RX_FILTER_UCAST;
} }
if (sc->sc_opmode == ATH9K_M_STA || sc->sc_opmode == ATH9K_M_IBSS || if (((sc->sc_ah->ah_opmode == ATH9K_M_STA) &&
sc->sc_scanning) (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC)) ||
(sc->sc_ah->ah_opmode == ATH9K_M_IBSS))
rfilt |= ATH9K_RX_FILTER_BEACON; rfilt |= ATH9K_RX_FILTER_BEACON;
/* If in HOSTAP mode, want to enable reception of PSPOLL frames /* If in HOSTAP mode, want to enable reception of PSPOLL frames
& beacon frames */ & beacon frames */
if (sc->sc_opmode == ATH9K_M_HOSTAP) if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP)
rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL); rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL);
return rfilt; return rfilt;
#undef RX_FILTER_PRESERVE #undef RX_FILTER_PRESERVE
} }
...@@ -702,11 +707,11 @@ void ath_flushrecv(struct ath_softc *sc) ...@@ -702,11 +707,11 @@ void ath_flushrecv(struct ath_softc *sc)
* progress (see references to sc_rxflush) * progress (see references to sc_rxflush)
*/ */
spin_lock_bh(&sc->sc_rxflushlock); spin_lock_bh(&sc->sc_rxflushlock);
sc->sc_rxflush = 1; sc->sc_flags |= SC_OP_RXFLUSH;
ath_rx_tasklet(sc, 1); ath_rx_tasklet(sc, 1);
sc->sc_rxflush = 0; sc->sc_flags &= ~SC_OP_RXFLUSH;
spin_unlock_bh(&sc->sc_rxflushlock); spin_unlock_bh(&sc->sc_rxflushlock);
} }
...@@ -719,7 +724,7 @@ int ath_rx_input(struct ath_softc *sc, ...@@ -719,7 +724,7 @@ int ath_rx_input(struct ath_softc *sc,
struct ath_recv_status *rx_status, struct ath_recv_status *rx_status,
enum ATH_RX_TYPE *status) enum ATH_RX_TYPE *status)
{ {
if (is_ampdu && sc->sc_rxaggr) { if (is_ampdu && (sc->sc_flags & SC_OP_RXAGGR)) {
*status = ATH_RX_CONSUMED; *status = ATH_RX_CONSUMED;
return ath_ampdu_input(sc, an, skb, rx_status); return ath_ampdu_input(sc, an, skb, rx_status);
} else { } else {
...@@ -750,7 +755,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) ...@@ -750,7 +755,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
do { do {
/* If handling rx interrupt and flush is in progress => exit */ /* If handling rx interrupt and flush is in progress => exit */
if (sc->sc_rxflush && (flush == 0)) if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
break; break;
spin_lock_bh(&sc->sc_rxbuflock); spin_lock_bh(&sc->sc_rxbuflock);
...@@ -900,7 +905,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) ...@@ -900,7 +905,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
* Enable this if you want to see * Enable this if you want to see
* error frames in Monitor mode. * error frames in Monitor mode.
*/ */
if (sc->sc_opmode != ATH9K_M_MONITOR) if (sc->sc_ah->ah_opmode != ATH9K_M_MONITOR)
goto rx_next; goto rx_next;
#endif #endif
/* fall thru for monitor mode handling... */ /* fall thru for monitor mode handling... */
...@@ -945,7 +950,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) ...@@ -945,7 +950,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
* decryption and MIC failures. For monitor mode, * decryption and MIC failures. For monitor mode,
* we also ignore the CRC error. * we also ignore the CRC error.
*/ */
if (sc->sc_opmode == ATH9K_M_MONITOR) { if (sc->sc_ah->ah_opmode == ATH9K_M_MONITOR) {
if (ds->ds_rxstat.rs_status & if (ds->ds_rxstat.rs_status &
~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
ATH9K_RXERR_CRC)) ATH9K_RXERR_CRC))
...@@ -1089,7 +1094,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) ...@@ -1089,7 +1094,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
"%s: Reset rx chain mask. " "%s: Reset rx chain mask. "
"Do internal reset\n", __func__); "Do internal reset\n", __func__);
ASSERT(flush == 0); ASSERT(flush == 0);
ath_internal_reset(sc); ath_reset(sc, false);
} }
return 0; return 0;
...@@ -1127,7 +1132,7 @@ int ath_rx_aggr_start(struct ath_softc *sc, ...@@ -1127,7 +1132,7 @@ int ath_rx_aggr_start(struct ath_softc *sc,
rxtid = &an->an_aggr.rx.tid[tid]; rxtid = &an->an_aggr.rx.tid[tid];
spin_lock_bh(&rxtid->tidlock); spin_lock_bh(&rxtid->tidlock);
if (sc->sc_rxaggr) { if (sc->sc_flags & SC_OP_RXAGGR) {
/* Allow aggregation reception /* Allow aggregation reception
* Adjust rx BA window size. Peer might indicate a * Adjust rx BA window size. Peer might indicate a
* zero buffer size for a _dont_care_ condition. * zero buffer size for a _dont_care_ condition.
...@@ -1227,7 +1232,7 @@ void ath_rx_aggr_teardown(struct ath_softc *sc, ...@@ -1227,7 +1232,7 @@ void ath_rx_aggr_teardown(struct ath_softc *sc,
void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an) void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an)
{ {
if (sc->sc_rxaggr) { if (sc->sc_flags & SC_OP_RXAGGR) {
struct ath_arx_tid *rxtid; struct ath_arx_tid *rxtid;
int tidno; int tidno;
...@@ -1259,7 +1264,7 @@ void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an) ...@@ -1259,7 +1264,7 @@ void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an)
void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an) void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
{ {
if (sc->sc_rxaggr) { if (sc->sc_flags & SC_OP_RXAGGR) {
struct ath_arx_tid *rxtid; struct ath_arx_tid *rxtid;
int tidno, i; int tidno, i;
...@@ -1292,27 +1297,3 @@ void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an) ...@@ -1292,27 +1297,3 @@ void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an)
{ {
ath_rx_node_cleanup(sc, an); ath_rx_node_cleanup(sc, an);
} }
dma_addr_t ath_skb_map_single(struct ath_softc *sc,
struct sk_buff *skb,
int direction,
dma_addr_t *pa)
{
/*
* NB: do NOT use skb->len, which is 0 on initialization.
* Use skb's entire data area instead.
*/
*pa = pci_map_single(sc->pdev, skb->data,
skb_end_pointer(skb) - skb->head, direction);
return *pa;
}
void ath_skb_unmap_single(struct ath_softc *sc,
struct sk_buff *skb,
int direction,
dma_addr_t *pa)
{
/* Unmap skb's entire data area */
pci_unmap_single(sc->pdev, *pa,
skb_end_pointer(skb) - skb->head, direction);
}
...@@ -899,12 +899,6 @@ enum { ...@@ -899,12 +899,6 @@ enum {
#define AR_GPIO_OUTPUT_MUX2 0x4064 #define AR_GPIO_OUTPUT_MUX2 0x4064
#define AR_GPIO_OUTPUT_MUX3 0x4068 #define AR_GPIO_OUTPUT_MUX3 0x4068
#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2
#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5
#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6
#define AR_INPUT_STATE 0x406c #define AR_INPUT_STATE 0x406c
#define AR_EEPROM_STATUS_DATA 0x407c #define AR_EEPROM_STATUS_DATA 0x407c
......
此差异已折叠。
b43-y += main.o b43-y += main.o
b43-y += tables.o b43-y += tables.o
b43-$(CONFIG_B43_NPHY) += tables_nphy.o b43-$(CONFIG_B43_NPHY) += tables_nphy.o
b43-y += phy.o b43-y += phy_common.o
b43-y += phy_g.o
b43-y += phy_a.o
b43-$(CONFIG_B43_NPHY) += nphy.o b43-$(CONFIG_B43_NPHY) += nphy.o
b43-y += sysfs.o b43-y += sysfs.o
b43-y += xmit.o b43-y += xmit.o
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include "leds.h" #include "leds.h"
#include "rfkill.h" #include "rfkill.h"
#include "lo.h" #include "lo.h"
#include "phy.h" #include "phy_common.h"
/* The unique identifier of the firmware that's officially supported by /* The unique identifier of the firmware that's officially supported by
...@@ -173,6 +173,11 @@ enum { ...@@ -173,6 +173,11 @@ enum {
#define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */ #define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */
#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5Ghz channel */ #define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5Ghz channel */
#define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */ #define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */
/* TSSI information */
#define B43_SHM_SH_TSSI_CCK 0x0058 /* TSSI for last 4 CCK frames (32bit) */
#define B43_SHM_SH_TSSI_OFDM_A 0x0068 /* TSSI for last 4 OFDM frames (32bit) */
#define B43_SHM_SH_TSSI_OFDM_G 0x0070 /* TSSI for last 4 OFDM frames (32bit) */
#define B43_TSSI_MAX 0x7F /* Max value for one TSSI value */
/* SHM_SHARED TX FIFO variables */ /* SHM_SHARED TX FIFO variables */
#define B43_SHM_SH_SIZE01 0x0098 /* TX FIFO size for FIFO 0 (low) and 1 (high) */ #define B43_SHM_SH_SIZE01 0x0098 /* TX FIFO size for FIFO 0 (low) and 1 (high) */
#define B43_SHM_SH_SIZE23 0x009A /* TX FIFO size for FIFO 2 and 3 */ #define B43_SHM_SH_SIZE23 0x009A /* TX FIFO size for FIFO 2 and 3 */
...@@ -508,122 +513,6 @@ struct b43_iv { ...@@ -508,122 +513,6 @@ struct b43_iv {
} __attribute__((__packed__)); } __attribute__((__packed__));
struct b43_phy {
/* Band support flags. */
bool supports_2ghz;
bool supports_5ghz;
/* GMODE bit enabled? */
bool gmode;
/* Analog Type */
u8 analog;
/* B43_PHYTYPE_ */
u8 type;
/* PHY revision number. */
u8 rev;
/* Radio versioning */
u16 radio_manuf; /* Radio manufacturer */
u16 radio_ver; /* Radio version */
u8 radio_rev; /* Radio revision */
bool dyn_tssi_tbl; /* tssi2dbm is kmalloc()ed. */
/* ACI (adjacent channel interference) flags. */
bool aci_enable;
bool aci_wlan_automatic;
bool aci_hw_rssi;
/* Radio switched on/off */
bool radio_on;
struct {
/* Values saved when turning the radio off.
* They are needed when turning it on again. */
bool valid;
u16 rfover;
u16 rfoverval;
} radio_off_context;
u16 minlowsig[2];
u16 minlowsigpos[2];
/* TSSI to dBm table in use */
const s8 *tssi2dbm;
/* Target idle TSSI */
int tgt_idle_tssi;
/* Current idle TSSI */
int cur_idle_tssi;
/* LocalOscillator control values. */
struct b43_txpower_lo_control *lo_control;
/* Values from b43_calc_loopback_gain() */
s16 max_lb_gain; /* Maximum Loopback gain in hdB */
s16 trsw_rx_gain; /* TRSW RX gain in hdB */
s16 lna_lod_gain; /* LNA lod */
s16 lna_gain; /* LNA */
s16 pga_gain; /* PGA */
/* Desired TX power level (in dBm).
* This is set by the user and adjusted in b43_phy_xmitpower(). */
u8 power_level;
/* A-PHY TX Power control value. */
u16 txpwr_offset;
/* Current TX power level attenuation control values */
struct b43_bbatt bbatt;
struct b43_rfatt rfatt;
u8 tx_control; /* B43_TXCTL_XXX */
/* Hardware Power Control enabled? */
bool hardware_power_control;
/* Current Interference Mitigation mode */
int interfmode;
/* Stack of saved values from the Interference Mitigation code.
* Each value in the stack is layed out as follows:
* bit 0-11: offset
* bit 12-15: register ID
* bit 16-32: value
* register ID is: 0x1 PHY, 0x2 Radio, 0x3 ILT
*/
#define B43_INTERFSTACK_SIZE 26
u32 interfstack[B43_INTERFSTACK_SIZE]; //FIXME: use a data structure
/* Saved values from the NRSSI Slope calculation */
s16 nrssi[2];
s32 nrssislope;
/* In memory nrssi lookup table. */
s8 nrssi_lt[64];
/* current channel */
u8 channel;
u16 lofcal;
u16 initval; //FIXME rename?
/* PHY TX errors counter. */
atomic_t txerr_cnt;
/* The device does address auto increment for the OFDM tables.
* We cache the previously used address here and omit the address
* write on the next table access, if possible. */
u16 ofdmtab_addr; /* The address currently set in hardware. */
enum { /* The last data flow direction. */
B43_OFDMTAB_DIRECTION_UNKNOWN = 0,
B43_OFDMTAB_DIRECTION_READ,
B43_OFDMTAB_DIRECTION_WRITE,
} ofdmtab_addr_direction;
#if B43_DEBUG
/* Manual TX-power control enabled? */
bool manual_txpower_control;
/* PHY registers locked by b43_phy_lock()? */
bool phy_locked;
#endif /* B43_DEBUG */
};
/* Data structures for DMA transmission, per 80211 core. */ /* Data structures for DMA transmission, per 80211 core. */
struct b43_dma { struct b43_dma {
struct b43_dmaring *tx_ring_AC_BK; /* Background */ struct b43_dmaring *tx_ring_AC_BK; /* Background */
...@@ -764,6 +653,11 @@ struct b43_wl { ...@@ -764,6 +653,11 @@ struct b43_wl {
struct b43_qos_params qos_params[4]; struct b43_qos_params qos_params[4];
/* Workqueue for updating QOS parameters in hardware. */ /* Workqueue for updating QOS parameters in hardware. */
struct work_struct qos_update_work; struct work_struct qos_update_work;
/* Work for adjustment of the transmission power.
* This is scheduled when we determine that the actual TX output
* power doesn't match what we want. */
struct work_struct txpower_adjust_work;
}; };
/* In-memory representation of a cached microcode file. */ /* In-memory representation of a cached microcode file. */
...@@ -908,6 +802,15 @@ static inline int b43_is_mode(struct b43_wl *wl, int type) ...@@ -908,6 +802,15 @@ static inline int b43_is_mode(struct b43_wl *wl, int type)
return (wl->operating && wl->if_type == type); return (wl->operating && wl->if_type == type);
} }
/**
* b43_current_band - Returns the currently used band.
* Returns one of IEEE80211_BAND_2GHZ and IEEE80211_BAND_5GHZ.
*/
static inline enum ieee80211_band b43_current_band(struct b43_wl *wl)
{
return wl->hw->conf.channel->band;
}
static inline u16 b43_read16(struct b43_wldev *dev, u16 offset) static inline u16 b43_read16(struct b43_wldev *dev, u16 offset)
{ {
return ssb_read16(dev->dev, offset); return ssb_read16(dev->dev, offset);
......
...@@ -443,76 +443,6 @@ static ssize_t txstat_read_file(struct b43_wldev *dev, ...@@ -443,76 +443,6 @@ static ssize_t txstat_read_file(struct b43_wldev *dev,
return count; return count;
} }
static ssize_t txpower_g_read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{
ssize_t count = 0;
if (dev->phy.type != B43_PHYTYPE_G) {
fappend("Device is not a G-PHY\n");
goto out;
}
fappend("Control: %s\n", dev->phy.manual_txpower_control ?
"MANUAL" : "AUTOMATIC");
fappend("Baseband attenuation: %u\n", dev->phy.bbatt.att);
fappend("Radio attenuation: %u\n", dev->phy.rfatt.att);
fappend("TX Mixer Gain: %s\n",
(dev->phy.tx_control & B43_TXCTL_TXMIX) ? "ON" : "OFF");
fappend("PA Gain 2dB: %s\n",
(dev->phy.tx_control & B43_TXCTL_PA2DB) ? "ON" : "OFF");
fappend("PA Gain 3dB: %s\n",
(dev->phy.tx_control & B43_TXCTL_PA3DB) ? "ON" : "OFF");
fappend("\n\n");
fappend("You can write to this file:\n");
fappend("Writing \"auto\" enables automatic txpower control.\n");
fappend
("Writing the attenuation values as \"bbatt rfatt txmix pa2db pa3db\" "
"enables manual txpower control.\n");
fappend("Example: 5 4 0 0 1\n");
fappend("Enables manual control with Baseband attenuation 5, "
"Radio attenuation 4, No TX Mixer Gain, "
"No PA Gain 2dB, With PA Gain 3dB.\n");
out:
return count;
}
static int txpower_g_write_file(struct b43_wldev *dev,
const char *buf, size_t count)
{
if (dev->phy.type != B43_PHYTYPE_G)
return -ENODEV;
if ((count >= 4) && (memcmp(buf, "auto", 4) == 0)) {
/* Automatic control */
dev->phy.manual_txpower_control = 0;
b43_phy_xmitpower(dev);
} else {
int bbatt = 0, rfatt = 0, txmix = 0, pa2db = 0, pa3db = 0;
/* Manual control */
if (sscanf(buf, "%d %d %d %d %d", &bbatt, &rfatt,
&txmix, &pa2db, &pa3db) != 5)
return -EINVAL;
b43_put_attenuation_into_ranges(dev, &bbatt, &rfatt);
dev->phy.manual_txpower_control = 1;
dev->phy.bbatt.att = bbatt;
dev->phy.rfatt.att = rfatt;
dev->phy.tx_control = 0;
if (txmix)
dev->phy.tx_control |= B43_TXCTL_TXMIX;
if (pa2db)
dev->phy.tx_control |= B43_TXCTL_PA2DB;
if (pa3db)
dev->phy.tx_control |= B43_TXCTL_PA3DB;
b43_phy_lock(dev);
b43_radio_lock(dev);
b43_set_txpower_g(dev, &dev->phy.bbatt,
&dev->phy.rfatt, dev->phy.tx_control);
b43_radio_unlock(dev);
b43_phy_unlock(dev);
}
return 0;
}
/* wl->irq_lock is locked */ /* wl->irq_lock is locked */
static int restart_write_file(struct b43_wldev *dev, static int restart_write_file(struct b43_wldev *dev,
const char *buf, size_t count) const char *buf, size_t count)
...@@ -560,7 +490,7 @@ static ssize_t loctls_read_file(struct b43_wldev *dev, ...@@ -560,7 +490,7 @@ static ssize_t loctls_read_file(struct b43_wldev *dev,
err = -ENODEV; err = -ENODEV;
goto out; goto out;
} }
lo = phy->lo_control; lo = phy->g->lo_control;
fappend("-- Local Oscillator calibration data --\n\n"); fappend("-- Local Oscillator calibration data --\n\n");
fappend("HW-power-control enabled: %d\n", fappend("HW-power-control enabled: %d\n",
dev->phy.hardware_power_control); dev->phy.hardware_power_control);
...@@ -578,8 +508,8 @@ static ssize_t loctls_read_file(struct b43_wldev *dev, ...@@ -578,8 +508,8 @@ static ssize_t loctls_read_file(struct b43_wldev *dev,
list_for_each_entry(cal, &lo->calib_list, list) { list_for_each_entry(cal, &lo->calib_list, list) {
bool active; bool active;
active = (b43_compare_bbatt(&cal->bbatt, &phy->bbatt) && active = (b43_compare_bbatt(&cal->bbatt, &phy->g->bbatt) &&
b43_compare_rfatt(&cal->rfatt, &phy->rfatt)); b43_compare_rfatt(&cal->rfatt, &phy->g->rfatt));
fappend("BB(%d), RF(%d,%d) -> I=%d, Q=%d " fappend("BB(%d), RF(%d,%d) -> I=%d, Q=%d "
"(expires in %lu sec)%s\n", "(expires in %lu sec)%s\n",
cal->bbatt.att, cal->bbatt.att,
...@@ -763,7 +693,6 @@ B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1); ...@@ -763,7 +693,6 @@ B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1); B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1);
B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1); B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1);
B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0); B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0);
B43_DEBUGFS_FOPS(txpower_g, txpower_g_read_file, txpower_g_write_file, 0);
B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1); B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1);
B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL, 0); B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL, 0);
...@@ -877,7 +806,6 @@ void b43_debugfs_add_device(struct b43_wldev *dev) ...@@ -877,7 +806,6 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
ADD_FILE(mmio32write, 0200); ADD_FILE(mmio32write, 0200);
ADD_FILE(tsf, 0600); ADD_FILE(tsf, 0600);
ADD_FILE(txstat, 0400); ADD_FILE(txstat, 0400);
ADD_FILE(txpower_g, 0600);
ADD_FILE(restart, 0200); ADD_FILE(restart, 0200);
ADD_FILE(loctls, 0400); ADD_FILE(loctls, 0400);
...@@ -907,7 +835,6 @@ void b43_debugfs_remove_device(struct b43_wldev *dev) ...@@ -907,7 +835,6 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
debugfs_remove(e->file_mmio32write.dentry); debugfs_remove(e->file_mmio32write.dentry);
debugfs_remove(e->file_tsf.dentry); debugfs_remove(e->file_tsf.dentry);
debugfs_remove(e->file_txstat.dentry); debugfs_remove(e->file_txstat.dentry);
debugfs_remove(e->file_txpower_g.dentry);
debugfs_remove(e->file_restart.dentry); debugfs_remove(e->file_restart.dentry);
debugfs_remove(e->file_loctls.dentry); debugfs_remove(e->file_loctls.dentry);
......
此差异已折叠。
#ifndef B43_LO_H_ #ifndef B43_LO_H_
#define B43_LO_H_ #define B43_LO_H_
#include "phy.h" /* G-PHY Local Oscillator */
#include "phy_g.h"
struct b43_wldev; struct b43_wldev;
......
此差异已折叠。
此差异已折叠。
#ifndef B43_NPHY_H_ #ifndef B43_NPHY_H_
#define B43_NPHY_H_ #define B43_NPHY_H_
#include "phy.h" #include "phy_common.h"
/* N-PHY registers. */ /* N-PHY registers. */
...@@ -919,54 +919,14 @@ ...@@ -919,54 +919,14 @@
struct b43_wldev; struct b43_wldev;
struct b43_phy_n {
bool initialised;
#ifdef CONFIG_B43_NPHY //TODO lots of missing stuff
/* N-PHY support enabled */ };
int b43_phy_initn(struct b43_wldev *dev);
void b43_nphy_radio_turn_on(struct b43_wldev *dev); struct b43_phy_operations;
void b43_nphy_radio_turn_off(struct b43_wldev *dev); extern const struct b43_phy_operations b43_phyops_n;
int b43_nphy_selectchannel(struct b43_wldev *dev, u8 channel);
void b43_nphy_xmitpower(struct b43_wldev *dev);
void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna);
#else /* CONFIG_B43_NPHY */
/* N-PHY support disabled */
static inline
int b43_phy_initn(struct b43_wldev *dev)
{
return -EOPNOTSUPP;
}
static inline
void b43_nphy_radio_turn_on(struct b43_wldev *dev)
{
}
static inline
void b43_nphy_radio_turn_off(struct b43_wldev *dev)
{
}
static inline
int b43_nphy_selectchannel(struct b43_wldev *dev, u8 channel)
{
return -ENOSYS;
}
static inline
void b43_nphy_xmitpower(struct b43_wldev *dev)
{
}
static inline
void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
{
}
#endif /* CONFIG_B43_NPHY */
#endif /* B43_NPHY_H_ */ #endif /* B43_NPHY_H_ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "rfkill.h" #include "rfkill.h"
#include "b43.h" #include "b43.h"
#include "phy_common.h"
#include <linux/kmod.h> #include <linux/kmod.h>
...@@ -114,11 +115,11 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) ...@@ -114,11 +115,11 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
goto out_unlock; goto out_unlock;
} }
if (!dev->phy.radio_on) if (!dev->phy.radio_on)
b43_radio_turn_on(dev); b43_software_rfkill(dev, state);
break; break;
case RFKILL_STATE_SOFT_BLOCKED: case RFKILL_STATE_SOFT_BLOCKED:
if (dev->phy.radio_on) if (dev->phy.radio_on)
b43_radio_turn_off(dev, 0); b43_software_rfkill(dev, state);
break; break;
default: default:
b43warn(wl, "Received unexpected rfkill state %d.\n", state); b43warn(wl, "Received unexpected rfkill state %d.\n", state);
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "b43.h" #include "b43.h"
#include "sysfs.h" #include "sysfs.h"
#include "main.h" #include "main.h"
#include "phy.h" #include "phy_common.h"
#define GENERIC_FILESIZE 64 #define GENERIC_FILESIZE 64
...@@ -59,7 +59,12 @@ static ssize_t b43_attr_interfmode_show(struct device *dev, ...@@ -59,7 +59,12 @@ static ssize_t b43_attr_interfmode_show(struct device *dev,
mutex_lock(&wldev->wl->mutex); mutex_lock(&wldev->wl->mutex);
switch (wldev->phy.interfmode) { if (wldev->phy.type != B43_PHYTYPE_G) {
mutex_unlock(&wldev->wl->mutex);
return -ENOSYS;
}
switch (wldev->phy.g->interfmode) {
case B43_INTERFMODE_NONE: case B43_INTERFMODE_NONE:
count = count =
snprintf(buf, PAGE_SIZE, snprintf(buf, PAGE_SIZE,
...@@ -117,11 +122,15 @@ static ssize_t b43_attr_interfmode_store(struct device *dev, ...@@ -117,11 +122,15 @@ static ssize_t b43_attr_interfmode_store(struct device *dev,
mutex_lock(&wldev->wl->mutex); mutex_lock(&wldev->wl->mutex);
spin_lock_irqsave(&wldev->wl->irq_lock, flags); spin_lock_irqsave(&wldev->wl->irq_lock, flags);
err = b43_radio_set_interference_mitigation(wldev, mode); if (wldev->phy.ops->interf_mitigation) {
if (err) { err = wldev->phy.ops->interf_mitigation(wldev, mode);
b43err(wldev->wl, "Interference Mitigation not " if (err) {
"supported by device\n"); b43err(wldev->wl, "Interference Mitigation not "
} "supported by device\n");
}
} else
err = -ENOSYS;
mmiowb(); mmiowb();
spin_unlock_irqrestore(&wldev->wl->irq_lock, flags); spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
mutex_unlock(&wldev->wl->mutex); mutex_unlock(&wldev->wl->mutex);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册