From f45144ef412422edf8018825328768e3db3ea45b Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 11 Aug 2008 14:02:53 +0530 Subject: ath9k: Merge reset functions Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/beacon.c | 2 +- drivers/net/wireless/ath9k/core.c | 73 ++++++++++++------------------------- drivers/net/wireless/ath9k/core.h | 3 +- drivers/net/wireless/ath9k/recv.c | 2 +- drivers/net/wireless/ath9k/xmit.c | 2 +- 5 files changed, 27 insertions(+), 55 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index caf569401a34..67a804626757 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -719,7 +719,7 @@ void ath_bstuck_process(struct ath_softc *sc) DPRINTF(sc, ATH_DBG_BEACON, "%s: stuck beacon; resetting (bmiss count %u)\n", __func__, sc->sc_bmisscount); - ath_internal_reset(sc); + ath_reset(sc, false); } /* diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index f6c45288d0e7..10f2729a8c4b 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -828,29 +828,30 @@ done: return error; } -/* - * 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) +int ath_reset(struct ath_softc *sc, bool retry_tx) { struct ath_hal *ah = sc->sc_ah; + int status; + int error = 0; + enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc); ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */ - ath_draintxq(sc, flag & RESET_RETRY_TXQ); /* stop xmit side */ - ath_stoprecv(sc); /* stop recv side */ - ath_flushrecv(sc); /* flush recv queue */ - - return 0; -} + ath_draintxq(sc, retry_tx); /* stop xmit */ + ath_stoprecv(sc); /* stop recv */ + ath_flushrecv(sc); /* flush recv queue */ -static int ath_reset_end(struct ath_softc *sc, u32 flag) -{ - struct ath_hal *ah = sc->sc_ah; + /* Reset chip */ + 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); if (ath_startrecv(sc) != 0) /* restart recv */ DPRINTF(sc, ATH_DBG_FATAL, @@ -863,14 +864,15 @@ static int ath_reset_end(struct ath_softc *sc, u32 flag) */ ath_setcurmode(sc, ath_chan2mode(&sc->sc_curchan)); - ath_update_txpow(sc); /* update tx power state */ + ath_update_txpow(sc); if (sc->sc_beacons) ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */ + ath9k_hw_set_interrupts(ah, sc->sc_imask); /* Restart the txq */ - if (flag & RESET_RETRY_TXQ) { + if (retry_tx) { int i; for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i)) { @@ -880,28 +882,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; } @@ -1050,7 +1030,7 @@ static void ath9k_tasklet(unsigned long data) if (status & ATH9K_INT_FATAL) { /* need a chip reset */ - ath_internal_reset(sc); + ath_reset(sc, false); return; } else { @@ -1815,13 +1795,6 @@ void ath_descdma_cleanup(struct ath_softc *sc, /* 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 qnum; diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 673b3d81133a..ef8f63766d43 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -1030,7 +1030,7 @@ void ath_deinit(struct ath_softc *sc); int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan); int ath_suspend(struct ath_softc *sc); 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); @@ -1056,7 +1056,6 @@ int ath_cabq_update(struct ath_softc *); void ath_get_currentCountry(struct ath_softc *sc, struct ath9k_country_entry *ctry); 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, diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 2fe806175c01..838b656b9da4 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -1089,7 +1089,7 @@ rx_next: "%s: Reset rx chain mask. " "Do internal reset\n", __func__); ASSERT(flush == 0); - ath_internal_reset(sc); + ath_reset(sc, false); } return 0; diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 157f830ee6b8..93064cc4cba8 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -1242,7 +1242,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, } if (needreset) - ath_internal_reset(sc); + ath_reset(sc, false); return; } -- cgit v1.2.1 From 7dcfdcd908a4540512aaf06b2b35e8c8a084fb69 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 11 Aug 2008 14:03:13 +0530 Subject: ath9k: RX Filter cleanup Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.c | 53 --------------------------------------- drivers/net/wireless/ath9k/core.h | 5 ++-- drivers/net/wireless/ath9k/main.c | 19 +++++++------- drivers/net/wireless/ath9k/recv.c | 11 +++++--- 4 files changed, 21 insertions(+), 67 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 10f2729a8c4b..7f92d469ad02 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -21,9 +21,6 @@ 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 = ATH_CHAINMASK_SEL_UP_RSSI_THRES; static u32 ath_chainmask_sel_down_rssi_thres = @@ -306,56 +303,6 @@ static int ath_stop(struct ath_softc *sc) 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 * diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index ef8f63766d43..07c958802b79 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -95,6 +95,8 @@ static inline unsigned long get_timestamp(void) return ((jiffies / HZ) * 1000) + (jiffies % HZ) * (1000 / HZ); } +static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + /*************/ /* Debugging */ /*************/ @@ -919,10 +921,9 @@ struct ath_softc { struct ath_rate_softc *sc_rc; /* tx rate control support */ u32 sc_intrstatus; enum ath9k_opmode sc_opmode; /* current operating mode */ - + 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 */ diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 2888778040e4..262fd7a8cd9a 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -549,10 +549,6 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, /* Update ratectrl about the new state */ ath_rate_newstate(sc, avp); - /* Set rx filter */ - rfilt = ath_calcrxfilter(sc); - ath9k_hw_setrxfilter(sc->sc_ah, rfilt); - /* Set BSSID */ memcpy(sc->sc_curbssid, conf->bssid, ETH_ALEN); sc->sc_curaid = 0; @@ -636,8 +632,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, FIF_BCN_PRBRESP_PROMISC | \ FIF_FCSFAIL) -/* Accept unicast, bcast and mcast frames */ - +/* FIXME: sc->sc_full_reset ? */ static void ath9k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, @@ -645,16 +640,22 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, struct dev_mc_list *mclist) { struct ath_softc *sc = hw->priv; + u32 rfilt; changed_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 (*total_flags & FIF_BCN_PRBRESP_PROMISC) - ath_scan_start(sc); - else - ath_scan_end(sc); + ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0); } + + 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, diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 838b656b9da4..a12584961d69 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -597,6 +597,7 @@ void ath_rx_cleanup(struct ath_softc *sc) u32 ath_calcrxfilter(struct ath_softc *sc) { #define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR) + u32 rfilt; rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE) @@ -608,14 +609,17 @@ u32 ath_calcrxfilter(struct ath_softc *sc) rfilt |= ATH9K_RX_FILTER_PROBEREQ; /* Can't set HOSTAP into promiscous mode */ - if (sc->sc_opmode == ATH9K_M_MONITOR) { + if (((sc->sc_opmode != ATH9K_M_HOSTAP) && + (sc->rx_filter & FIF_PROMISC_IN_BSS)) || + (sc->sc_opmode == ATH9K_M_MONITOR)) { rfilt |= ATH9K_RX_FILTER_PROM; /* ??? To prevent from sending ACK */ rfilt &= ~ATH9K_RX_FILTER_UCAST; } - if (sc->sc_opmode == ATH9K_M_STA || sc->sc_opmode == ATH9K_M_IBSS || - sc->sc_scanning) + if (((sc->sc_opmode == ATH9K_M_STA) && + (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC)) || + (sc->sc_opmode == ATH9K_M_IBSS)) rfilt |= ATH9K_RX_FILTER_BEACON; /* If in HOSTAP mode, want to enable reception of PSPOLL frames @@ -623,6 +627,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) if (sc->sc_opmode == ATH9K_M_HOSTAP) rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL); return rfilt; + #undef RX_FILTER_PRESERVE } -- cgit v1.2.1 From cd3d39a6875507f4f4d585391fe3d344f0b64b5c Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 11 Aug 2008 14:03:34 +0530 Subject: ath9k: Use bitfields for buffer type Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.h | 70 +++++++++++++---------------- drivers/net/wireless/ath9k/xmit.c | 92 ++++++++++++++++++++++----------------- 2 files changed, 83 insertions(+), 79 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 07c958802b79..9e16c6c28a39 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -177,11 +177,6 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht); /* 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 { \ (_bf)->bf_status = 0; \ (_bf)->bf_lastbf = NULL; \ @@ -191,28 +186,29 @@ chains is due to FF aggregation in the driver. */ sizeof(struct ath_buf_state)); \ } 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 { - int bfs_nframes; /* # frames in aggregate */ - u16 bfs_al; /* length of aggregate */ - u16 bfs_frmlen; /* length of frame */ - int bfs_seqno; /* sequence number */ - int bfs_tidno; /* tid of this frame */ - int bfs_retries; /* current retries */ + int bfs_nframes; /* # frames in aggregate */ + u16 bfs_al; /* length of aggregate */ + u16 bfs_frmlen; /* length of frame */ + int bfs_seqno; /* sequence number */ + int bfs_tidno; /* tid of this frame */ + int bfs_retries; /* current retries */ struct ath_rc_series bfs_rcs[4]; /* rate series */ - u8 bfs_isdata:1; /* is a data frame/aggregate */ - 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 */ + u32 bf_type; /* BUF_* (enum buffer_type) */ /* key type use to encrypt this frame */ enum ath9k_key_type bfs_keytype; }; @@ -224,26 +220,22 @@ struct ath_buf_state { #define bf_seqno bf_state.bfs_seqno #define bf_tidno bf_state.bfs_tidno #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_isbar bf_state.bfs_isbar -#define bf_ispspoll bf_state.bfs_ispspoll -#define bf_aggrburst bf_state.bfs_aggrburst -#define bf_calcairtime bf_state.bfs_calcairtime +#define bf_isdata(bf) (bf->bf_state.bf_type & BUF_DATA) +#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR) +#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) +#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 * a single hw descriptor encapsulated here. */ - struct ath_buf { struct list_head list; struct list_head *last; diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 93064cc4cba8..47cf9f3555ae 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -518,7 +518,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, if (!txok) { tx_status.flags |= ATH_TX_ERROR; - if (bf->bf_isxretried) + if (bf_isxretried(bf)) tx_status.flags |= ATH_TX_XRETRY; } /* Unmap this frame */ @@ -629,7 +629,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, if (isnodegone || ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED) return 0; - isaggr = bf->bf_isaggr; + isaggr = bf_isaggr(bf); if (isaggr) { seq_st = ATH_DS_BA_SEQ(ds); memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3); @@ -651,7 +651,7 @@ static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf) struct sk_buff *skb; struct ieee80211_hdr *hdr; - bf->bf_isretried = 1; + bf->bf_state.bf_type |= BUF_RETRY; bf->bf_retries++; skb = bf->bf_mpdu; @@ -698,7 +698,7 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rc; int streams, pktlen; - pktlen = bf->bf_isaggr ? bf->bf_al : bf->bf_frmlen; + pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen; rc = rt->info[rix].rateCode; /* @@ -781,7 +781,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) * let rate series flags determine which rates will actually * use RTS. */ - if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf->bf_isdata) { + if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf_isdata(bf)) { BUG_ON(!an); /* * 802.11g protection not needed, use our default behavior @@ -793,7 +793,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) * and the second aggregate should have any protection at all. */ if (an->an_smmode == ATH_SM_PWRSAV_DYNAMIC) { - if (!bf->bf_aggrburst) { + if (!bf_isaggrburst(bf)) { flags = ATH9K_TXDESC_RTSENA; dynamic_mimops = 1; } else { @@ -806,7 +806,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) * Set protection if aggregate protection on */ if (sc->sc_config.ath_aggr_prot && - (!bf->bf_isaggr || (bf->bf_isaggr && bf->bf_al < 8192))) { + (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) { flags = ATH9K_TXDESC_RTSENA; cix = rt->info[sc->sc_protrix].controlRate; rtsctsena = 1; @@ -815,7 +815,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) /* * For AR5416 - RTS cannot be followed by a frame larger than 8K. */ - if (bf->bf_isaggr && (bf->bf_al > aggr_limit_with_rts)) { + if (bf_isaggr(bf) && (bf->bf_al > aggr_limit_with_rts)) { /* * Ensure that in the case of SM Dynamic power save * while we are bursting the second aggregate the @@ -832,7 +832,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) /* NB: cix is set above where RTS/CTS is enabled */ BUG_ON(cix == 0xff); ctsrate = rt->info[cix].rateCode | - (bf->bf_shpreamble ? rt->info[cix].shortPreamble : 0); + (bf_isshpreamble(bf) ? rt->info[cix].shortPreamble : 0); /* * Setup HAL rate series @@ -846,7 +846,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) rix = bf->bf_rcs[i].rix; series[i].Rate = rt->info[rix].rateCode | - (bf->bf_shpreamble ? rt->info[rix].shortPreamble : 0); + (bf_isshpreamble(bf) ? rt->info[rix].shortPreamble : 0); series[i].Tries = bf->bf_rcs[i].tries; @@ -862,7 +862,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) sc, rix, bf, (bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) != 0, (bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG), - bf->bf_shpreamble); + bf_isshpreamble(bf)); if ((an->an_smmode == ATH_SM_PWRSAV_STATIC) && (bf->bf_rcs[i].flags & ATH_RC_DS_FLAG) == 0) { @@ -875,7 +875,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) */ series[i].ChSel = sc->sc_tx_chainmask; } else { - if (bf->bf_ht) + if (bf_isht(bf)) series[i].ChSel = ath_chainmask_sel_logic(sc, an); else @@ -908,7 +908,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) * use the precalculated ACK durations. */ if (flags & ATH9K_TXDESC_RTSENA) { /* SIFS + CTS */ - ctsduration += bf->bf_shpreamble ? + ctsduration += bf_isshpreamble(bf) ? rt->info[cix].spAckDuration : rt->info[cix].lpAckDuration; } @@ -916,7 +916,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) ctsduration += series[0].PktDuration; if ((bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) { /* SIFS + ACK */ - ctsduration += bf->bf_shpreamble ? + ctsduration += bf_isshpreamble(bf) ? rt->info[rix].spAckDuration : rt->info[rix].lpAckDuration; } @@ -932,10 +932,10 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) * set dur_update_en for l-sig computation except for PS-Poll frames */ ath9k_hw_set11n_ratescenario(ah, ds, lastds, - !bf->bf_ispspoll, - ctsrate, - ctsduration, - series, 4, flags); + !bf_ispspoll(bf), + ctsrate, + ctsduration, + series, 4, flags); if (sc->sc_config.ath_aggr_prot && flags) ath9k_hw_set11n_burstduration(ah, ds, 8192); } @@ -958,7 +958,7 @@ static int ath_tx_send_normal(struct ath_softc *sc, BUG_ON(list_empty(bf_head)); bf = list_first_entry(bf_head, struct ath_buf, list); - bf->bf_isampdu = 0; /* regular HT frame */ + bf->bf_state.bf_type &= ~BUF_AMPDU; /* regular HT frame */ skb = (struct sk_buff *)bf->bf_mpdu; tx_info = IEEE80211_SKB_CB(skb); @@ -998,7 +998,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) while (!list_empty(&tid->buf_q)) { bf = list_first_entry(&tid->buf_q, struct ath_buf, list); - ASSERT(!bf->bf_isretried); + ASSERT(!bf_isretried(bf)); list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list); ath_tx_send_normal(sc, txq, tid, &bf_head); } @@ -1025,7 +1025,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, int isaggr, txfail, txpending, sendbar = 0, needreset = 0; int isnodegone = (an->an_flags & ATH_NODE_CLEAN); - isaggr = bf->bf_isaggr; + isaggr = bf_isaggr(bf); if (isaggr) { if (txok) { if (ATH_DS_TX_BA(ds)) { @@ -1075,7 +1075,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, ath_tx_set_retry(sc, bf); txpending = 1; } else { - bf->bf_isxretried = 1; + bf->bf_state.bf_type |= BUF_XRETRY; txfail = 1; sendbar = 1; } @@ -1331,7 +1331,7 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) txq->axq_depth--; - if (bf->bf_isaggr) + if (bf_isaggr(bf)) txq->axq_aggr_depth--; txok = (ds->ds_txstat.ts_status == 0); @@ -1345,14 +1345,14 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) spin_unlock_bh(&sc->sc_txbuflock); } - if (!bf->bf_isampdu) { + if (!bf_isampdu(bf)) { /* * This frame is sent out as a single frame. * Use hardware retry status for this frame. */ bf->bf_retries = ds->ds_txstat.ts_longretry; if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) - bf->bf_isxretried = 1; + bf->bf_state.bf_type |= BUF_XRETRY; nbad = 0; } else { nbad = ath_tx_num_badfrms(sc, bf, txok); @@ -1368,7 +1368,7 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) if (ds->ds_txstat.ts_status == 0) nacked++; - if (bf->bf_isdata) { + if (bf_isdata(bf)) { if (isrifs) tmp_ds = bf->bf_rifslast->bf_desc; else @@ -1384,7 +1384,7 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) /* * Complete this transmit unit */ - if (bf->bf_isampdu) + if (bf_isampdu(bf)) ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, txok); else ath_tx_complete_buf(sc, bf, &bf_head, txok, 0); @@ -1481,7 +1481,7 @@ static void ath_tx_addto_baw(struct ath_softc *sc, { int index, cindex; - if (bf->bf_isretried) + if (bf_isretried(bf)) return; index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno); @@ -1516,7 +1516,7 @@ static int ath_tx_send_ampdu(struct ath_softc *sc, BUG_ON(list_empty(bf_head)); bf = list_first_entry(bf_head, struct ath_buf, list); - bf->bf_isampdu = 1; + bf->bf_state.bf_type |= BUF_AMPDU; bf->bf_seqno = txctl->seqno; /* save seqno and tidno in buffer */ bf->bf_tidno = txctl->tidno; @@ -1860,7 +1860,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, if (bf->bf_nframes == 1) { ASSERT(bf->bf_lastfrm == bf_last); - bf->bf_isaggr = 0; + bf->bf_state.bf_type &= ~BUF_AGGR; /* * clear aggr bits for every descriptor * XXX TODO: is there a way to optimize it? @@ -1877,7 +1877,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, /* * setup first desc with rate and aggr info */ - bf->bf_isaggr = 1; + bf->bf_state.bf_type |= BUF_AGGR; ath_buf_set_rate(sc, bf); ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al); @@ -1925,7 +1925,7 @@ static void ath_tid_drain(struct ath_softc *sc, list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list); /* update baw for software retried frame */ - if (bf->bf_isretried) + if (bf_isretried(bf)) ath_tx_update_baw(sc, tid, bf->bf_seqno); /* @@ -2014,11 +2014,21 @@ static int ath_tx_start_dma(struct ath_softc *sc, /* set up this buffer */ ATH_TXBUF_RESET(bf); bf->bf_frmlen = txctl->frmlen; - bf->bf_isdata = ieee80211_is_data(fc); - bf->bf_isbar = ieee80211_is_back_req(fc); - bf->bf_ispspoll = ieee80211_is_pspoll(fc); + + ieee80211_is_data(fc) ? + (bf->bf_state.bf_type |= BUF_DATA) : + (bf->bf_state.bf_type &= ~BUF_DATA); + ieee80211_is_back_req(fc) ? + (bf->bf_state.bf_type |= BUF_BAR) : + (bf->bf_state.bf_type &= ~BUF_BAR); + ieee80211_is_pspoll(fc) ? + (bf->bf_state.bf_type |= BUF_PSPOLL) : + (bf->bf_state.bf_type &= ~BUF_PSPOLL); + (sc->sc_flags & ATH_PREAMBLE_SHORT) ? + (bf->bf_state.bf_type |= BUF_SHORT_PREAMBLE) : + (bf->bf_state.bf_type &= ~BUF_SHORT_PREAMBLE); + bf->bf_flags = txctl->flags; - bf->bf_shpreamble = sc->sc_flags & ATH_PREAMBLE_SHORT; bf->bf_keytype = txctl->keytype; tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0]; rcs = tx_info_priv->rcs; @@ -2060,7 +2070,9 @@ static int ath_tx_start_dma(struct ath_softc *sc, ds); /* first descriptor */ bf->bf_lastfrm = bf; - bf->bf_ht = txctl->ht; + (txctl->ht) ? + (bf->bf_state.bf_type |= BUF_HT) : + (bf->bf_state.bf_type &= ~BUF_HT); spin_lock_bh(&txq->axq_lock); @@ -2162,7 +2174,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) /* Setup tx descriptors */ error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf, - "tx", nbufs * ATH_FRAG_PER_MSDU, ATH_TXDESC); + "tx", nbufs * ATH_FRAG_PER_MSDU, 1); if (error != 0) { DPRINTF(sc, ATH_DBG_FATAL, "%s: failed to allocate tx descriptors: %d\n", @@ -2486,7 +2498,7 @@ void ath_tx_draintxq(struct ath_softc *sc, spin_unlock_bh(&txq->axq_lock); - if (bf->bf_isampdu) + if (bf_isampdu(bf)) ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, 0); else ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); @@ -2647,7 +2659,7 @@ void ath_tx_aggr_teardown(struct ath_softc *sc, spin_lock_bh(&txq->axq_lock); while (!list_empty(&txtid->buf_q)) { bf = list_first_entry(&txtid->buf_q, struct ath_buf, list); - if (!bf->bf_isretried) { + if (!bf_isretried(bf)) { /* * NB: it's based on the assumption that * software retried frame will always stay -- cgit v1.2.1 From 556bb8f141d702a84281064751a3242359a9f257 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 11 Aug 2008 14:03:53 +0530 Subject: ath9k: Remove a few unnecessary macros Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.h | 15 +++------------ drivers/net/wireless/ath9k/xmit.c | 2 +- 2 files changed, 4 insertions(+), 13 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 9e16c6c28a39..19399da8d47e 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -396,8 +396,7 @@ int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb, /* TX */ /******/ -#define ATH_FRAG_PER_MSDU 1 -#define ATH_TXBUF (512/ATH_FRAG_PER_MSDU) +#define ATH_TXBUF 512 /* max number of transmit attempts (tries) */ #define ATH_TXMAXTRY 13 /* max number of 11n transmit attempts (tries) */ @@ -551,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); void ath_draintxq(struct ath_softc *sc, bool retry_tx); 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_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_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); int ath_tx_init(struct ath_softc *sc, int nbufs); @@ -579,7 +578,6 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, /* indicates the node is 80211 power save */ #define ATH_NODE_PWRSAVE 0x2 -#define ADDBA_TIMEOUT 200 /* 200 milliseconds */ #define ADDBA_EXCHANGE_ATTEMPTS 10 #define ATH_AGGR_DELIM_SZ 4 /* delimiter size */ #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ @@ -699,9 +697,6 @@ struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr); #define ATH_BCBUF 4 /* number of beacon buffers */ #define ATH_DEFAULT_BINTVAL 100 /* default beacon interval in TU */ #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) /* beacon configuration */ @@ -838,8 +833,6 @@ void ath_setdefantenna(void *sc, u32 antenna); #define ATH_PREAMBLE_SHORT (1<<0) #define ATH_PROTECT_ENABLE (1<<1) #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 IEEE80211_WEP_NKID 4 /* number of key ids */ #define IEEE80211_RATE_VAL 0x7f @@ -853,9 +846,7 @@ void ath_setdefantenna(void *sc, u32 antenna); */ #define ATH_KEYMAX 128 /* max key cache size we handle */ -#define RESET_RETRY_TXQ 0x00000001 #define ATH_IF_ID_ANY 0xff - #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ #define RSSI_LPF_THRESHOLD -20 diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 47cf9f3555ae..a24a3a5b0e62 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -2174,7 +2174,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) /* Setup tx descriptors */ error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf, - "tx", nbufs * ATH_FRAG_PER_MSDU, 1); + "tx", nbufs, 1); if (error != 0) { DPRINTF(sc, ATH_DBG_FATAL, "%s: failed to allocate tx descriptors: %d\n", -- cgit v1.2.1 From d2d80ee9c6ae3d60bcbffb200959db645f5a558f Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 11 Aug 2008 14:04:13 +0530 Subject: ath9k: Remove ar5416hal and assign default values directly Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/hw.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index a17eb130f574..3d879e7a8ea6 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -85,29 +85,6 @@ static const struct hal_percal_data adc_init_dc_cal = { 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 = { 8, {0}, @@ -1196,11 +1173,12 @@ static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid, ah = &ahp->ah; - memcpy(&ahp->ah, &ar5416hal, sizeof(struct ath_hal)); - ah->ah_sc = sc; ah->ah_sh = mem; + ah->ah_magic = AR5416_MAGIC; + ah->ah_countryCode = CTRY_DEFAULT; + ah->ah_devid = devid; ah->ah_subvendorid = 0; -- cgit v1.2.1 From 6a2b9e8c8f4be9954933051719b312adcfb7263d Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 11 Aug 2008 14:04:32 +0530 Subject: ath9k: Unused macros, variables Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 18 +++--- drivers/net/wireless/ath9k/hw.h | 116 +++++++++++++------------------------ 2 files changed, 50 insertions(+), 84 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index d1b0fbae5a32..3e7072dcb439 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -790,19 +790,20 @@ struct ath_hal { u32 ah_magic; u16 ah_devid; u16 ah_subvendorid; - struct ath_softc *ah_sc; - void __iomem *ah_sh; - u16 ah_countryCode; u32 ah_macVersion; u16 ah_macRev; u16 ah_phyRev; u16 ah_analog5GhzRev; 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; struct ath9k_ops_config ah_config; struct ath9k_hw_capabilities ah_caps; + + u16 ah_countryCode; + u32 ah_flags; int16_t ah_powerLimit; u16 ah_maxPowerLevel; u32 ah_tpScale; @@ -812,15 +813,16 @@ struct ath_hal { u16 ah_currentRD5G; u16 ah_currentRD2G; char ah_iso[4]; - enum start_adhoc_option ah_adHocMode; - bool ah_commonMode; + struct ath9k_channel ah_channels[150]; - u32 ah_nchan; struct ath9k_channel *ah_curchan; + u32 ah_nchan; + u16 ah_rfsilent; bool ah_rfkillEnabled; bool ah_isPciExpress; u16 ah_txTrigLevel; + #ifndef ATH_NF_PER_CHAN struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; #endif diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h index ae680f21ba7e..5cb3912ad392 100644 --- a/drivers/net/wireless/ath9k/hw.h +++ b/drivers/net/wireless/ath9k/hw.h @@ -314,14 +314,11 @@ struct ar5416_desc { #define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \ MS(ads->ds_rxstatus0, AR_RxRate) : \ (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)) -#define set11nRate(_series, _index) \ +#define set11nRate(_series, _index) \ (SM((_series)[_index].Rate, AR_XmitRate##_index)) #define set11nPktDurRTSCTS(_series, _index) \ @@ -330,11 +327,11 @@ struct ar5416_desc { AR_RTSCTSQual##_index : 0)) #define set11nRateFlags(_series, _index) \ - (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \ - AR_2040_##_index : 0) \ - |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \ - AR_GI##_index : 0) \ - |SM((_series)[_index].ChSel, AR_ChainSel##_index)) + (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \ + AR_2040_##_index : 0) \ + |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \ + AR_GI##_index : 0) \ + |SM((_series)[_index].ChSel, AR_ChainSel##_index)) #define AR_SREV_9100(ah) ((ah->ah_macVersion) == AR_SREV_VERSION_9100) @@ -346,9 +343,6 @@ struct ar5416_desc { #define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1) #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 ath9k_channel c; u8 noiseImmunityLevel; @@ -377,11 +371,8 @@ struct ar5416AniState { }; #define HAL_PROCESS_ANI 0x00000001 -#define HAL_RADAR_EN 0x80000000 -#define HAL_AR_EN 0x40000000 - #define DO_ANI(ah) \ - ((AH5416(ah)->ah_procPhyErr & HAL_PROCESS_ANI)) + ((AH5416(ah)->ah_procPhyErr & HAL_PROCESS_ANI)) struct ar5416Stats { u32 ast_ani_niup; @@ -425,7 +416,6 @@ struct ar5416Stats { #define AR5416_EEP_MINOR_VER_7 0x7 #define AR5416_EEP_MINOR_VER_9 0x9 -#define AR5416_EEP_START_LOC 256 #define AR5416_NUM_5G_CAL_PIERS 8 #define AR5416_NUM_2G_CAL_PIERS 4 #define AR5416_NUM_5G_20_TARGET_POWERS 8 @@ -441,25 +431,10 @@ struct ar5416Stats { #define AR5416_EEPROM_MODAL_SPURS 5 #define AR5416_MAX_RATE_POWER 63 #define AR5416_NUM_PDADC_VALUES 128 -#define AR5416_NUM_RATES 16 #define AR5416_BCHAN_UNUSED 0xFF #define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64 -#define AR5416_EEPMISC_BIG_ENDIAN 0x01 #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_LEGACY_CHAINMASK 1 enum eeprom_param { EEP_NFTHRESH_5, @@ -633,7 +608,7 @@ struct ar5416IniArray { }; #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_columns = (columns); \ } while (0) @@ -641,16 +616,16 @@ struct ar5416IniArray { #define INI_RA(iniarray, row, column) \ (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)]) -#define INIT_CAL(_perCal) do { \ - (_perCal)->calState = CAL_WAITING; \ - (_perCal)->calNext = NULL; \ +#define INIT_CAL(_perCal) do { \ + (_perCal)->calState = CAL_WAITING; \ + (_perCal)->calNext = NULL; \ } while (0) #define INSERT_CAL(_ahp, _perCal) \ do { \ if ((_ahp)->ah_cal_list_last == NULL) { \ - (_ahp)->ah_cal_list = \ - (_ahp)->ah_cal_list_last = (_perCal); \ + (_ahp)->ah_cal_list = \ + (_ahp)->ah_cal_list_last = (_perCal); \ ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \ } else { \ ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \ @@ -696,25 +671,29 @@ struct hal_cal_list { struct ath_hal_5416 { struct ath_hal ah; 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_bssid[ETH_ALEN]; u8 ah_bssidmask[ETH_ALEN]; u16 ah_assocId; + int16_t ah_curchanRadIndex; u32 ah_maskReg; - struct ar5416Stats ah_stats; - u32 ah_txDescMask; u32 ah_txOkInterruptMask; u32 ah_txErrInterruptMask; u32 ah_txDescInterruptMask; u32 ah_txEolInterruptMask; u32 ah_txUrnInterruptMask; - struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES]; - enum ath9k_power_mode ah_powerMode; bool ah_chipFullSleep; u32 ah_atimWindow; - enum ath9k_ant_setting ah_diversityControl; u16 ah_antennaSwitchSwap; + enum ath9k_power_mode ah_powerMode; + enum ath9k_ant_setting ah_diversityControl; + + /* Calibration */ enum hal_cal_types ah_suppCals; struct hal_cal_list ah_iqCalData; struct hal_cal_list ah_adcGainCalData; @@ -751,16 +730,16 @@ struct ath_hal_5416 { int32_t sign[AR5416_MAX_CHAINS]; } ah_Meas3; u16 ah_CalSamples; - u32 ah_tx6PowerInHalfDbm; + u32 ah_staId1Defaults; u32 ah_miscMode; - bool ah_tpcEnabled; - u32 ah_beaconInterval; enum { AUTO_32KHZ, USE_32KHZ, DONT_USE_32KHZ, } ah_enable32kHzClock; + + /* RF */ u32 *ah_analogBank0Data; u32 *ah_analogBank1Data; u32 *ah_analogBank2Data; @@ -770,8 +749,9 @@ struct ath_hal_5416 { u32 *ah_analogBank7Data; u32 *ah_addac5416_21; u32 *ah_bank6Temp; - u32 ah_ofdmTxPower; + int16_t ah_txPowerIndexOffset; + u32 ah_beaconInterval; u32 ah_slottime; u32 ah_acktimeout; u32 ah_ctstimeout; @@ -780,7 +760,8 @@ struct ath_hal_5416 { u32 ah_gpioSelect; u32 ah_polarity; u32 ah_gpioBit; - bool ah_eepEnabled; + + /* ANI */ u32 ah_procPhyErr; bool ah_hasHwPhyCounters; u32 ah_aniPeriod; @@ -790,18 +771,14 @@ struct ath_hal_5416 { int ah_coarseHigh[5]; int ah_coarseLow[5]; int ah_firpwr[5]; - u16 ah_ratesArray[16]; + enum ath9k_ani_cmd ah_ani_function; + u32 ah_intrTxqs; bool ah_intrMitigation; - u32 ah_cycleCount; - u32 ah_ctlBusy; - u32 ah_extBusy; enum ath9k_ht_extprotspacing ah_extprotspacing; u8 ah_txchainmask; 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_iniCommon; struct ar5416IniArray ah_iniBank0; @@ -820,10 +797,6 @@ struct ath_hal_5416 { #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 { \ if (AH5416(ah)->ah_rfHal.rfDetach != NULL) \ AH5416(ah)->ah_rfHal.rfDetach(ah); \ @@ -841,8 +814,8 @@ struct ath_hal_5416 { #define REG_WRITE_ARRAY(iniarray, column, regWr) do { \ int r; \ for (r = 0; r < ((iniarray)->ia_rows); r++) { \ - REG_WRITE(ah, INI_RA((iniarray), (r), 0), \ - INI_RA((iniarray), r, (column))); \ + REG_WRITE(ah, INI_RA((iniarray), (r), 0), \ + INI_RA((iniarray), r, (column))); \ DO_DELAY(regWr); \ } \ } while (0) @@ -860,22 +833,17 @@ struct ath_hal_5416 { #define AR5416_EEPROM_S 2 #define AR5416_EEPROM_OFFSET 0x2000 -#define AR5416_EEPROM_START_ADDR \ +#define AR5416_EEPROM_START_ADDR \ (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200 #define AR5416_EEPROM_MAX 0xae0 -#define ar5416_get_eep_ver(_ahp) \ +#define ar5416_get_eep_ver(_ahp) \ (((_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) -#define ar5416_get_ntxchains(_txchainmask) \ +#define ar5416_get_ntxchains(_txchainmask) \ (((_txchainmask >> 2) & 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 #define AR5416_EEPROM_MAGIC 0x5aa5 #else @@ -910,8 +878,6 @@ struct ath_hal_5416 { #define AR_GPIOD_MASK 0x00001FFF #define AR_GPIO_BIT(_gpio) (1 << (_gpio)) -#define MAX_ANALOG_START 319 - #define HAL_EP_RND(x, mul) \ ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) #define BEACON_RSSI(ahp) \ @@ -923,8 +889,6 @@ struct ath_hal_5416 { #define AH_TIMEOUT 100000 #define AH_TIME_QUANTUM 10 -#define IS(_c, _f) (((_c)->channelFlags & _f) || 0) - #define AR_KEYTABLE_SIZE 128 #define POWER_UP_TIME 200000 @@ -964,6 +928,6 @@ struct ath_hal_5416 { #define OFDM_SYMBOL_TIME_QUARTER 16 u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp, - enum eeprom_param param); + enum eeprom_param param); #endif -- cgit v1.2.1 From b4696c8b9233bea812b972a5e79c5db7ecf13867 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 11 Aug 2008 14:04:52 +0530 Subject: ath9k: Use a single opmode variable ah_opmode and sc_opmode are redundant. This patch removes sc_opmode. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath9k/beacon.c | 18 +++++++++--------- drivers/net/wireless/ath9k/core.c | 21 ++++++++++++--------- drivers/net/wireless/ath9k/core.h | 6 +++--- drivers/net/wireless/ath9k/hw.c | 8 +++----- drivers/net/wireless/ath9k/main.c | 3 ++- drivers/net/wireless/ath9k/recv.c | 18 +++++++++--------- drivers/net/wireless/ath9k/xmit.c | 4 ++-- 8 files changed, 41 insertions(+), 39 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 3e7072dcb439..682d3bb4d494 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -855,7 +855,7 @@ bool ath9k_regd_init_channels(struct ath_hal *ah, 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 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, enum ath9k_ht_macmode macmode, u8 txchainmask, u8 rxchainmask, diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index 67a804626757..2736a4b4e4a1 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -33,7 +33,7 @@ static int ath_beaconq_config(struct ath_softc *sc) struct ath9k_tx_queue_info 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. */ qi.tqi_aifs = 1; qi.tqi_cwmin = 0; @@ -85,7 +85,7 @@ static void ath_beacon_setup(struct ath_softc *sc, 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)) { ds->ds_link = bf->bf_daddr; /* self-linked */ flags |= ATH9K_TXDESC_VEOL; @@ -375,7 +375,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) struct ath_buf, 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)) { int slot; /* @@ -750,7 +750,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) if (if_id != ATH_IF_ID_ANY) av_opmode = sc->sc_vaps[if_id]->av_opmode; else - av_opmode = sc->sc_opmode; + av_opmode = sc->sc_ah->ah_opmode; memzero(&conf, sizeof(struct ath_beacon_config)); @@ -770,7 +770,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) nexttbtt = TSF_TO_TU(get_unaligned_le32(conf.u.last_tstamp + 4), get_unaligned_le32(conf.u.last_tstamp)); /* 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 * evenly over N slots or burst together. For the former @@ -791,7 +791,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n", __func__, nexttbtt, intval, conf.beacon_interval); /* 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; u64 tsf; u32 tsftu; @@ -911,7 +911,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ath9k_hw_set_interrupts(ah, 0); if (nexttbtt == intval) 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 * TSF . @@ -943,7 +943,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) sc->sc_imask |= ATH9K_INT_SWBA; 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 * SWBA interrupts to prepare beacon frames. @@ -959,7 +959,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) * When using a self-linked beacon descriptor in * 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)) ath_beacon_start_adhoc(sc, 0); } diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 7f92d469ad02..8359356ac02e 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -355,7 +355,7 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) fastcc = false; 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_rx_chainmask, sc->sc_ht_extprotspacing, @@ -533,7 +533,8 @@ int ath_vap_listen(struct ath_softc *sc, int if_id) rfilt = ath_calcrxfilter(sc); ath9k_hw_setrxfilter(ah, rfilt); - if (sc->sc_opmode == ATH9K_M_STA || sc->sc_opmode == ATH9K_M_IBSS) { + if (sc->sc_ah->ah_opmode == ATH9K_M_STA || + sc->sc_ah->ah_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 @@ -603,7 +604,7 @@ int ath_vap_attach(struct ath_softc *sc, sc->sc_vaps[if_id] = avp; sc->sc_nvaps++; /* Set the device opmode */ - sc->sc_opmode = opmode; + sc->sc_ah->ah_opmode = opmode; /* default VAP configuration */ avp->av_config.av_fixed_rateset = IEEE80211_FIXED_RATE_NONE; @@ -677,7 +678,8 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) 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 @@ -702,7 +704,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) sc->sc_curchan = *initial_chan; spin_lock_bh(&sc->sc_resetlock); - if (!ath9k_hw_reset(ah, sc->sc_opmode, &sc->sc_curchan, ht_macmode, + if (!ath9k_hw_reset(ah, &sc->sc_curchan, ht_macmode, sc->sc_tx_chainmask, sc->sc_rx_chainmask, sc->sc_ht_extprotspacing, false, &status)) { DPRINTF(sc, ATH_DBG_FATAL, @@ -749,7 +751,8 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) * Note we only do this (at the moment) for station mode. */ 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; /* * Some hardware processes the TIM IE and fires an @@ -758,7 +761,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) * enable the TIM interrupt when operating as station. */ 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_imask |= ATH9K_INT_TIM; /* @@ -789,7 +792,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) /* Reset chip */ spin_lock_bh(&sc->sc_resetlock); - if (!ath9k_hw_reset(ah, sc->sc_opmode, &sc->sc_curchan, + if (!ath9k_hw_reset(ah, &sc->sc_curchan, ht_macmode, sc->sc_tx_chainmask, sc->sc_rx_chainmask, sc->sc_ht_extprotspacing, false, &status)) { @@ -1096,7 +1099,7 @@ int ath_init(u16 devid, struct ath_softc *sc) goto bad; /* default to STA mode */ - sc->sc_opmode = ATH9K_M_MONITOR; + sc->sc_ah->ah_opmode = ATH9K_M_MONITOR; /* Setup rate tables */ diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 19399da8d47e..bfe16230b5e7 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -895,15 +895,15 @@ struct ath_ht_info { struct ath_softc { struct ieee80211_hw *hw; struct pci_dev *pdev; - void __iomem *mem; struct tasklet_struct intr_tq; struct tasklet_struct bcon_tasklet; struct ath_config sc_config; /* load-time parameters */ - int sc_debug; struct ath_hal *sc_ah; struct ath_rate_softc *sc_rc; /* tx rate control support */ + void __iomem *mem; + + int sc_debug; u32 sc_intrstatus; - enum ath9k_opmode sc_opmode; /* current operating mode */ unsigned int rx_filter; u8 sc_invalid; /* being detached */ u8 sc_beacons; /* beacons running */ diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 3d879e7a8ea6..24b78c2eb44b 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -5839,7 +5839,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, enum ath9k_ht_macmode macmode, u8 txchainmask, u8 rxchainmask, @@ -5953,7 +5953,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode, | (ah->ah_config. ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) | 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_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4)); @@ -5983,13 +5983,11 @@ bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode, for (i = 0; i < ah->ah_caps.total_queues; 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_user_settings(ah); - ah->ah_opmode = opmode; - REG_WRITE(ah, AR_STA_ID1, REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 262fd7a8cd9a..7504b64020c9 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -472,7 +472,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, ath_rate_newstate(sc, avp); /* 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); ath_beacon_return(sc, avp); } diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index a12584961d69..6d1d5035f159 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -184,7 +184,7 @@ static int ath_ampdu_input(struct ath_softc *sc, 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. */ if (memcmp(hdr->addr1, sc->sc_myaddr, ETH_ALEN)) { dev_kfree_skb(skb); @@ -605,26 +605,26 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | ATH9K_RX_FILTER_MCAST; /* 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; /* Can't set HOSTAP into promiscous mode */ - if (((sc->sc_opmode != ATH9K_M_HOSTAP) && + if (((sc->sc_ah->ah_opmode != ATH9K_M_HOSTAP) && (sc->rx_filter & FIF_PROMISC_IN_BSS)) || - (sc->sc_opmode == ATH9K_M_MONITOR)) { + (sc->sc_ah->ah_opmode == ATH9K_M_MONITOR)) { rfilt |= ATH9K_RX_FILTER_PROM; /* ??? To prevent from sending ACK */ rfilt &= ~ATH9K_RX_FILTER_UCAST; } - if (((sc->sc_opmode == ATH9K_M_STA) && + if (((sc->sc_ah->ah_opmode == ATH9K_M_STA) && (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC)) || - (sc->sc_opmode == ATH9K_M_IBSS)) + (sc->sc_ah->ah_opmode == ATH9K_M_IBSS)) rfilt |= ATH9K_RX_FILTER_BEACON; /* If in HOSTAP mode, want to enable reception of PSPOLL 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); return rfilt; @@ -905,7 +905,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) * Enable this if you want to see * error frames in Monitor mode. */ - if (sc->sc_opmode != ATH9K_M_MONITOR) + if (sc->sc_ah->ah_opmode != ATH9K_M_MONITOR) goto rx_next; #endif /* fall thru for monitor mode handling... */ @@ -950,7 +950,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) * decryption and MIC failures. For monitor mode, * 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 & ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | ATH9K_RXERR_CRC)) diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index a24a3a5b0e62..0b5b2dd92562 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -1047,7 +1047,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, * when perform internal reset in this routine. * Only enable reset in STA mode for now. */ - if (sc->sc_opmode == ATH9K_M_STA) + if (sc->sc_ah->ah_opmode == ATH9K_M_STA) needreset = 1; } } else { @@ -1454,7 +1454,7 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) "%s: Unable to stop TxDMA. Reset HAL!\n", __func__); spin_lock_bh(&sc->sc_resetlock); - if (!ath9k_hw_reset(ah, sc->sc_opmode, + if (!ath9k_hw_reset(ah, &sc->sc_curchan, ht_macmode, sc->sc_tx_chainmask, sc->sc_rx_chainmask, sc->sc_ht_extprotspacing, true, &status)) { -- cgit v1.2.1 From 672840ac04f79f499b60b9f0eb41799c837db4eb Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 11 Aug 2008 14:05:08 +0530 Subject: ath9k: Use bitfields for sc operations Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/beacon.c | 4 ++-- drivers/net/wireless/ath9k/core.c | 45 +++++++++++++++++++------------------ drivers/net/wireless/ath9k/core.h | 24 +++++++++++--------- drivers/net/wireless/ath9k/main.c | 14 ++++++------ drivers/net/wireless/ath9k/rc.c | 2 +- drivers/net/wireless/ath9k/recv.c | 8 +++---- drivers/net/wireless/ath9k/xmit.c | 31 ++++++++++++------------- 7 files changed, 66 insertions(+), 62 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index 2736a4b4e4a1..f1c420141714 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -111,7 +111,7 @@ static void ath_beacon_setup(struct ath_softc *sc, rix = 0; rt = sc->sc_currates; 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; ath9k_hw_set11n_txdesc(ah, ds @@ -975,5 +975,5 @@ void ath_beacon_sync(struct ath_softc *sc, int if_id) * beacon frame we just received. */ ath_beacon_config(sc, if_id); - sc->sc_beacons = 1; + sc->sc_flags |= SC_OP_BEACONS; } diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 8359356ac02e..9b8258d9efd3 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -272,8 +272,8 @@ static int ath_stop(struct ath_softc *sc) { struct ath_hal *ah = sc->sc_ah; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: invalid %u\n", - __func__, sc->sc_invalid); + DPRINTF(sc, ATH_DBG_CONFIG, "%s: invalid %ld\n", + __func__, sc->sc_flags & SC_OP_INVALID); /* * Shutdown the hardware and driver: @@ -291,10 +291,10 @@ static int ath_stop(struct ath_softc *sc) * hardware is gone (invalid). */ - if (!sc->sc_invalid) + if (!(sc->sc_flags & SC_OP_INVALID)) ath9k_hw_set_interrupts(ah, 0); ath_draintxq(sc, false); - if (!sc->sc_invalid) { + if (!(sc->sc_flags & SC_OP_INVALID)) { ath_stoprecv(sc); ath9k_hw_phy_disable(ah); } else @@ -316,7 +316,7 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) 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; DPRINTF(sc, ATH_DBG_CONFIG, @@ -332,7 +332,8 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) if (hchan->channel != sc->sc_curchan.channel || hchan->channelFlags != sc->sc_curchan.channelFlags || - sc->sc_update_chainmask || sc->sc_full_reset) { + (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) || + (sc->sc_flags & SC_OP_FULL_RESET)) { int status; /* * This is only performed if the channel settings have @@ -351,7 +352,7 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) * to flush data frames already in queue because of * changing channel. */ - if (!stopped || sc->sc_full_reset) + if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET)) fastcc = false; spin_lock_bh(&sc->sc_resetlock); @@ -372,8 +373,8 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) spin_unlock_bh(&sc->sc_resetlock); sc->sc_curchan = *hchan; - sc->sc_update_chainmask = 0; - sc->sc_full_reset = 0; + sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE; + sc->sc_flags &= ~SC_OP_FULL_RESET; /* Re-enable rx framework */ if (ath_startrecv(sc) != 0) { @@ -484,7 +485,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) { - sc->sc_update_chainmask = 1; + sc->sc_flags |= SC_OP_CHAINMASK_UPDATE; if (is_ht) { sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask; sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask; @@ -553,7 +554,7 @@ int ath_vap_listen(struct ath_softc *sc, int if_id) 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; + sc->sc_flags &= ~SC_OP_BEACONS; return 0; } @@ -773,7 +774,7 @@ 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 * before turning on interrupt. */ - sc->sc_invalid = 0; + sc->sc_flags &= ~SC_OP_INVALID; done: return error; } @@ -816,7 +817,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) 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 */ ath9k_hw_set_interrupts(ah, sc->sc_imask); @@ -841,7 +842,7 @@ int ath_suspend(struct ath_softc *sc) struct ath_hal *ah = sc->sc_ah; /* No I/O if device has been surprise removed */ - if (sc->sc_invalid) + if (sc->sc_flags & SC_OP_INVALID) return -EIO; /* Shut off the interrupt before setting sc->sc_invalid to '1' */ @@ -849,7 +850,7 @@ int ath_suspend(struct ath_softc *sc) /* XXX: we must make sure h/w will not generate any interrupt * before setting the invalid flag. */ - sc->sc_invalid = 1; + sc->sc_flags |= SC_OP_INVALID; /* disable HAL and put h/w to sleep */ ath9k_hw_disable(sc->sc_ah); @@ -870,7 +871,7 @@ irqreturn_t ath_isr(int irq, void *dev) bool sched = false; do { - if (sc->sc_invalid) { + if (sc->sc_flags & SC_OP_INVALID) { /* * The hardware is not ready/present, don't * touch anything. Note this can happen early @@ -1026,7 +1027,7 @@ int ath_init(u16 devid, struct ath_softc *sc) u32 rd; /* 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; DPRINTF(sc, ATH_DBG_CONFIG, "%s: devid 0x%x\n", __func__, devid); @@ -1210,8 +1211,8 @@ int ath_init(u16 devid, struct ath_softc *sc) /* 11n Capabilities */ if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) { - sc->sc_txaggr = 1; - sc->sc_rxaggr = 1; + sc->sc_flags |= SC_OP_TXAGGR; + sc->sc_flags |= SC_OP_RXAGGR; } sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask; @@ -1267,7 +1268,7 @@ void ath_deinit(struct ath_softc *sc) DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__); ath_stop(sc); - if (!sc->sc_invalid) + if (!(sc->sc_flags & SC_OP_INVALID)) ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); ath_rate_detach(sc->sc_rc); /* cleanup tx queues */ @@ -1394,9 +1395,9 @@ void ath_newassoc(struct ath_softc *sc, /* if station reassociates, tear down the aggregation state. */ if (!isnew) { 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); - if (sc->sc_rxaggr) + if (sc->sc_flags & SC_OP_RXAGGR) ath_rx_aggr_teardown(sc, an, tidno); } } diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index bfe16230b5e7..702f7b8eba59 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -830,8 +830,6 @@ void ath_setdefantenna(void *sc, u32 antenna); #define ATH_DEFAULT_NOISE_FLOOR -95 #define ATH_REGCLASSIDS_MAX 10 #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_CHAN_MAX 255 #define IEEE80211_WEP_NKID 4 /* number of key ids */ @@ -892,25 +890,30 @@ struct ath_ht_info { 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_PREAMBLE_SHORT BIT(6) +#define SC_OP_PROTECT_ENABLE BIT(7) + struct ath_softc { struct ieee80211_hw *hw; struct pci_dev *pdev; struct tasklet_struct intr_tq; struct tasklet_struct bcon_tasklet; - struct ath_config sc_config; /* load-time parameters */ + struct ath_config sc_config; struct ath_hal *sc_ah; - struct ath_rate_softc *sc_rc; /* tx rate control support */ + struct ath_rate_softc *sc_rc; void __iomem *mem; int sc_debug; u32 sc_intrstatus; + u32 sc_flags; /* SC_OP_* */ unsigned int rx_filter; - u8 sc_invalid; /* being detached */ - u8 sc_beacons; /* beacons running */ - 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_curaid; @@ -944,7 +947,6 @@ struct ath_softc { u8 sc_rxchaindetect_delta5GHz; u8 sc_rxchaindetect_delta2GHz; u32 sc_rtsaggrlimit; /* Chipset specific aggr limit */ - u32 sc_flags; #ifdef CONFIG_SLOW_ANT_DIV struct ath_antdiv sc_antdiv; #endif diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 7504b64020c9..7fb57ee4c436 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -481,7 +481,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, /* Set interrupt mask */ sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); 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); if (error) @@ -582,7 +582,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, print_mac(mac, sc->sc_curbssid), sc->sc_curaid); /* need to reconfigure the beacon */ - sc->sc_beacons = 0; + sc->sc_flags &= ~SC_OP_BEACONS ; break; default: @@ -833,7 +833,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, /* Configure the beacon */ ath_beacon_config(sc, 0); - sc->sc_beacons = 1; + sc->sc_flags |= SC_OP_BEACONS; /* Reset rssi stats */ sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER; @@ -896,9 +896,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, __func__, 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 - sc->sc_flags &= ~ATH_PREAMBLE_SHORT; + sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT; } if (changed & BSS_CHANGED_ERP_CTS_PROT) { @@ -907,9 +907,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, bss_conf->use_cts_prot); if (bss_conf->use_cts_prot && hw->conf.channel->band != IEEE80211_BAND_5GHZ) - sc->sc_flags |= ATH_PROTECT_ENABLE; + sc->sc_flags |= SC_OP_PROTECT_ENABLE; else - sc->sc_flags &= ~ATH_PROTECT_ENABLE; + sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; } if (changed & BSS_CHANGED_HT) { diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 73c460ad355f..20e10849e934 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -1903,7 +1903,7 @@ static void ath_tx_aggr_resp(struct ath_softc *sc, int state; DECLARE_MAC_BUF(mac); - if (!sc->sc_txaggr) + if (!(sc->sc_flags & SC_OP_TXAGGR)) return; txtid = ATH_AN_2_TID(an, tidno); diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 6d1d5035f159..9c7583210e36 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -724,7 +724,7 @@ int ath_rx_input(struct ath_softc *sc, struct ath_recv_status *rx_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; return ath_ampdu_input(sc, an, skb, rx_status); } else { @@ -1132,7 +1132,7 @@ int ath_rx_aggr_start(struct ath_softc *sc, rxtid = &an->an_aggr.rx.tid[tid]; spin_lock_bh(&rxtid->tidlock); - if (sc->sc_rxaggr) { + if (sc->sc_flags & SC_OP_RXAGGR) { /* Allow aggregation reception * Adjust rx BA window size. Peer might indicate a * zero buffer size for a _dont_care_ condition. @@ -1232,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) { - if (sc->sc_rxaggr) { + if (sc->sc_flags & SC_OP_RXAGGR) { struct ath_arx_tid *rxtid; int tidno; @@ -1264,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) { - if (sc->sc_rxaggr) { + if (sc->sc_flags & SC_OP_RXAGGR) { struct ath_arx_tid *rxtid; int tidno, i; diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 0b5b2dd92562..75a84924b4dc 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -392,7 +392,7 @@ static int ath_tx_prepare(struct ath_softc *sc, * incremented by the fragmentation routine. */ if (likely(!(txctl->flags & ATH9K_TXDESC_FRAG_IS_ON)) && - txctl->ht && sc->sc_txaggr) { + txctl->ht && (sc->sc_flags & SC_OP_TXAGGR)) { struct ath_atx_tid *tid; tid = ATH_AN_2_TID(txctl->an, txctl->tidno); @@ -422,7 +422,7 @@ static int ath_tx_prepare(struct ath_softc *sc, /* * XXX not right with fragmentation. */ - if (sc->sc_flags & ATH_PREAMBLE_SHORT) + if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) dur = rt->info[rix].spAckDuration; else dur = rt->info[rix].lpAckDuration; @@ -438,8 +438,9 @@ static int ath_tx_prepare(struct ath_softc *sc, ** Add time for next fragment. */ dur += ath9k_hw_computetxtime(sc->sc_ah, rt, - txctl->nextfraglen, - rix, sc->sc_flags & ATH_PREAMBLE_SHORT); + txctl->nextfraglen, + rix, + (sc->sc_flags & SC_OP_PREAMBLE_SHORT)); } if (ieee80211_has_morefrags(fc) || @@ -1406,7 +1407,7 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) /* * schedule any pending packets if aggregation is enabled */ - if (sc->sc_txaggr) + if (sc->sc_flags & SC_OP_TXAGGR) ath_txq_schedule(sc, txq); spin_unlock_bh(&txq->axq_lock); } @@ -1433,7 +1434,7 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc); /* XXX return value */ - if (!sc->sc_invalid) { + if (!(sc->sc_flags & SC_OP_INVALID)) { for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i)) { ath_tx_stopdma(sc, &sc->sc_txq[i]); @@ -2024,7 +2025,7 @@ static int ath_tx_start_dma(struct ath_softc *sc, ieee80211_is_pspoll(fc) ? (bf->bf_state.bf_type |= BUF_PSPOLL) : (bf->bf_state.bf_type &= ~BUF_PSPOLL); - (sc->sc_flags & ATH_PREAMBLE_SHORT) ? + (sc->sc_flags & SC_OP_PREAMBLE_SHORT) ? (bf->bf_state.bf_type |= BUF_SHORT_PREAMBLE) : (bf->bf_state.bf_type &= ~BUF_SHORT_PREAMBLE); @@ -2076,7 +2077,7 @@ static int ath_tx_start_dma(struct ath_softc *sc, spin_lock_bh(&txq->axq_lock); - if (txctl->ht && sc->sc_txaggr) { + if (txctl->ht && (sc->sc_flags & SC_OP_TXAGGR)) { struct ath_atx_tid *tid = ATH_AN_2_TID(an, txctl->tidno); if (ath_aggr_query(sc, an, txctl->tidno)) { /* @@ -2153,7 +2154,7 @@ static void xmit_map_sg(struct ath_softc *sc, tx_status.retries = 0; tx_status.flags = ATH_TX_ERROR; - if (txctl->ht && sc->sc_txaggr) { + if (txctl->ht && (sc->sc_flags & SC_OP_TXAGGR)) { /* Reclaim the seqno. */ tid = ATH_AN_2_TID((struct ath_node *) txctl->an, txctl->tidno); @@ -2505,7 +2506,7 @@ void ath_tx_draintxq(struct ath_softc *sc, } /* flush any pending frames if aggregation is enabled */ - if (sc->sc_txaggr) { + if (sc->sc_flags & SC_OP_TXAGGR) { if (!retry_tx) { spin_lock_bh(&txq->axq_lock); ath_txq_drain_pending_buffers(sc, txq, @@ -2521,7 +2522,7 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx) { /* stop beacon queue. The beacon will be freed when * we go to INIT state */ - if (!sc->sc_invalid) { + if (!(sc->sc_flags & SC_OP_INVALID)) { (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); DPRINTF(sc, ATH_DBG_XMIT, "%s: beacon queue %x\n", __func__, ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_bhalq)); @@ -2548,7 +2549,7 @@ enum ATH_AGGR_CHECK ath_tx_aggr_check(struct ath_softc *sc, struct ath_atx_tid *txtid; DECLARE_MAC_BUF(mac); - if (!sc->sc_txaggr) + if (!(sc->sc_flags & SC_OP_TXAGGR)) return AGGR_NOT_REQUIRED; /* ADDBA exchange must be completed before sending aggregates */ @@ -2595,7 +2596,7 @@ int ath_tx_aggr_start(struct ath_softc *sc, return -1; } - if (sc->sc_txaggr) { + if (sc->sc_flags & SC_OP_TXAGGR) { txtid = ATH_AN_2_TID(an, tid); txtid->addba_exchangeinprogress = 1; ath_tx_pause_tid(sc, txtid); @@ -2755,7 +2756,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) { - if (sc->sc_txaggr) { + if (sc->sc_flags & SC_OP_TXAGGR) { struct ath_atx_tid *tid; struct ath_atx_ac *ac; int tidno, acno; @@ -2867,7 +2868,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an) { - if (sc->sc_txaggr) { + if (sc->sc_flags & SC_OP_TXAGGR) { struct ath_atx_tid *tid; int tidno, i; -- cgit v1.2.1 From 7c56d24bc80112daadc7ef54247a5fc8397dbc5c Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 11 Aug 2008 14:05:26 +0530 Subject: ath9k: Use ah_curchan and remove sc_curchan which is redundant Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.c | 20 +++++++++----------- drivers/net/wireless/ath9k/core.h | 1 - drivers/net/wireless/ath9k/rc.c | 4 ++-- drivers/net/wireless/ath9k/xmit.c | 2 +- 4 files changed, 12 insertions(+), 15 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 9b8258d9efd3..87b4ca525d25 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -322,16 +322,16 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) DPRINTF(sc, ATH_DBG_CONFIG, "%s: %u (%u MHz) -> %u (%u MHz), cflags:%x\n", __func__, - ath9k_hw_mhz2ieee(ah, sc->sc_curchan.channel, - sc->sc_curchan.channelFlags), - sc->sc_curchan.channel, + ath9k_hw_mhz2ieee(ah, sc->sc_ah->ah_curchan->channel, + sc->sc_ah->ah_curchan->channelFlags), + sc->sc_ah->ah_curchan->channel, ath9k_hw_mhz2ieee(ah, hchan->channel, hchan->channelFlags), hchan->channel, hchan->channelFlags); ht_macmode = ath_cwm_macmode(sc); - if (hchan->channel != sc->sc_curchan.channel || - hchan->channelFlags != sc->sc_curchan.channelFlags || + if (hchan->channel != sc->sc_ah->ah_curchan->channel || + hchan->channelFlags != sc->sc_ah->ah_curchan->channelFlags || (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) || (sc->sc_flags & SC_OP_FULL_RESET)) { int status; @@ -372,7 +372,6 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) } spin_unlock_bh(&sc->sc_resetlock); - sc->sc_curchan = *hchan; sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE; sc->sc_flags &= ~SC_OP_FULL_RESET; @@ -702,16 +701,15 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) * be followed by initialization of the appropriate bits * and then setup of the interrupt mask. */ - sc->sc_curchan = *initial_chan; spin_lock_bh(&sc->sc_resetlock); - if (!ath9k_hw_reset(ah, &sc->sc_curchan, ht_macmode, + if (!ath9k_hw_reset(ah, initial_chan, 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 " "(freq %u flags 0x%x)\n", __func__, status, - sc->sc_curchan.channel, sc->sc_curchan.channelFlags); + initial_chan->channel, initial_chan->channelFlags); error = -EIO; spin_unlock_bh(&sc->sc_resetlock); goto done; @@ -793,7 +791,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) /* Reset chip */ spin_lock_bh(&sc->sc_resetlock); - if (!ath9k_hw_reset(ah, &sc->sc_curchan, + if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, ht_macmode, sc->sc_tx_chainmask, sc->sc_rx_chainmask, sc->sc_ht_extprotspacing, false, &status)) { @@ -813,7 +811,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) * that changes the channel so update any state that * 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); diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 702f7b8eba59..7f4bd15fa7ef 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -1001,7 +1001,6 @@ struct ath_softc { /* Channel, Band */ struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX]; struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; - struct ath9k_channel sc_curchan; /* Locks */ spinlock_t sc_rxflushlock; diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 20e10849e934..1392361ef9a6 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -847,9 +847,9 @@ void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp) /* For half and quarter rate channles use different * rate tables */ - if (sc->sc_curchan.channelFlags & CHANNEL_HALF) + if (sc->sc_ah->ah_curchan->channelFlags & CHANNEL_HALF) 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); else /* full rate */ ar5416_setfull_ratetable(asc); diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 75a84924b4dc..9ea5d9333305 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -1456,7 +1456,7 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) spin_lock_bh(&sc->sc_resetlock); if (!ath9k_hw_reset(ah, - &sc->sc_curchan, ht_macmode, + sc->sc_ah->ah_curchan, ht_macmode, sc->sc_tx_chainmask, sc->sc_rx_chainmask, sc->sc_ht_extprotspacing, true, &status)) { -- cgit v1.2.1 From 98deeea0b3464955ec416c30cbd0c3d21cacfa9a Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 11 Aug 2008 14:05:46 +0530 Subject: ath9k: Trim struct ath_softc Add sc_rxflush and sc_noreset as bitfields to sc_flags. Remove a few variables and function prototypes that are unused. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/beacon.c | 8 ++--- drivers/net/wireless/ath9k/core.c | 10 ------- drivers/net/wireless/ath9k/core.h | 58 ++++++++++++++----------------------- drivers/net/wireless/ath9k/recv.c | 8 ++--- drivers/net/wireless/ath9k/xmit.c | 8 ++--- 5 files changed, 31 insertions(+), 61 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index f1c420141714..e0ca0172f8be 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -555,7 +555,7 @@ void ath9k_beacon_tasklet(unsigned long data) u32 tsftu; u16 intval; - if (sc->sc_noreset) { + if (sc->sc_flags & SC_OP_NO_RESET) { show_cycles = ath9k_hw_GetMibCycleCountsPct(ah, &rx_clear, &rx_frame, @@ -577,7 +577,7 @@ void ath9k_beacon_tasklet(unsigned long data) * (in that layer). */ if (sc->sc_bmisscount < BSTUCK_THRESH) { - if (sc->sc_noreset) { + if (sc->sc_flags & SC_OP_NO_RESET) { DPRINTF(sc, ATH_DBG_BEACON, "%s: missed %u consecutive beacons\n", __func__, sc->sc_bmisscount); @@ -605,7 +605,7 @@ void ath9k_beacon_tasklet(unsigned long data) __func__, sc->sc_bmisscount); } } 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) { DPRINTF(sc, ATH_DBG_BEACON, @@ -624,7 +624,7 @@ void ath9k_beacon_tasklet(unsigned long data) return; } if (sc->sc_bmisscount != 0) { - if (sc->sc_noreset) { + if (sc->sc_flags & SC_OP_NO_RESET) { DPRINTF(sc, ATH_DBG_BEACON, "%s: resume beacon xmit after %u misses\n", diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 87b4ca525d25..0d953f9fdeeb 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -1055,9 +1055,6 @@ int ath_init(u16 devid, struct ath_softc *sc) } 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. */ sc->sc_keymax = ah->ah_caps.keycache_size; if (sc->sc_keymax > ATH_KEYMAX) { @@ -1216,13 +1213,6 @@ int ath_init(u16 devid, struct ath_softc *sc) sc->sc_tx_chainmask = ah->ah_caps.tx_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); sc->sc_defant = ath9k_hw_getdefantenna(ah); diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 7f4bd15fa7ef..8243ff049b60 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -724,11 +724,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id); int ath_beaconq_setup(struct ath_hal *ah); int ath_beacon_alloc(struct ath_softc *sc, int if_id); 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_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, int if_id, struct ath_beacon_config *conf); @@ -896,8 +893,10 @@ struct ath_ht_info { #define SC_OP_TXAGGR BIT(3) #define SC_OP_CHAINMASK_UPDATE BIT(4) #define SC_OP_FULL_RESET BIT(5) -#define SC_OP_PREAMBLE_SHORT BIT(6) -#define SC_OP_PROTECT_ENABLE BIT(7) +#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) struct ath_softc { struct ieee80211_hw *hw; @@ -909,44 +908,39 @@ struct ath_softc { 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_flags; /* SC_OP_* */ unsigned int rx_filter; - - enum wireless_mode sc_curmode; /* current phy mode */ u16 sc_curtxpow; u16 sc_curaid; - u8 sc_curbssid[ETH_ALEN]; - u8 sc_myaddr[ETH_ALEN]; + u16 sc_cachelsz; + int sc_slotupdate; /* slot to next advance fsm */ + int sc_slottime; + int sc_bslot[ATH_BCBUF]; + u8 sc_tx_chainmask; + u8 sc_rx_chainmask; + enum ath9k_int sc_imask; + enum wireless_mode sc_curmode; /* current phy mode */ enum PROT_MODE sc_protmode; - u8 sc_mcastantenna; - u8 sc_txantenna; /* data tx antenna (fixed or auto) */ + u8 sc_nbcnvaps; /* # of vaps sending beacons */ u16 sc_nvaps; /* # of active virtual ap's */ 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_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 list_head node_list; struct ath_ht_info sc_ht_info; - int16_t sc_noise_floor; /* signal noise floor in dBm */ 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 */ + #ifdef CONFIG_SLOW_ANT_DIV struct ath_antdiv sc_antdiv; #endif @@ -967,7 +961,6 @@ struct ath_softc { struct ath_descdma sc_rxdma; int sc_rxbufsize; /* rx size based on mtu */ 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 */ @@ -977,7 +970,6 @@ struct ath_softc { u32 sc_txqsetup; u32 sc_txintrperiod; /* tx interrupt batching */ int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */ - u32 sc_ant_tx[8]; /* recent tx frames/antenna */ /* Beacon */ struct ath9k_tx_queue_info sc_beacon_qi; @@ -1016,13 +1008,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan); int ath_suspend(struct ath_softc *sc); irqreturn_t ath_isr(int irq, void *dev); 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); -void ath_setup_rate(struct ath_softc *sc, - enum wireless_mode wMode, - enum RATE_TYPE type, - const struct ath9k_rate_table *rt); /*********************/ /* Utility Functions */ @@ -1041,7 +1027,6 @@ int ath_cabq_update(struct ath_softc *); void ath_get_currentCountry(struct ath_softc *sc, struct ath9k_country_entry *ctry); u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp); -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, @@ -1050,7 +1035,6 @@ 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 */ diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 9c7583210e36..af2011fb05a0 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -504,7 +504,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) do { spin_lock_init(&sc->sc_rxflushlock); - sc->sc_rxflush = 0; + sc->sc_flags &= ~SC_OP_RXFLUSH; spin_lock_init(&sc->sc_rxbuflock); /* @@ -707,11 +707,11 @@ void ath_flushrecv(struct ath_softc *sc) * progress (see references to sc_rxflush) */ spin_lock_bh(&sc->sc_rxflushlock); - sc->sc_rxflush = 1; + sc->sc_flags |= SC_OP_RXFLUSH; ath_rx_tasklet(sc, 1); - sc->sc_rxflush = 0; + sc->sc_flags &= ~SC_OP_RXFLUSH; spin_unlock_bh(&sc->sc_rxflushlock); } @@ -755,7 +755,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) do { /* 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; spin_lock_bh(&sc->sc_rxbuflock); diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 9ea5d9333305..e2ffa1cdb5e1 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -485,12 +485,8 @@ static int ath_tx_prepare(struct ath_softc *sc, if (is_multicast_ether_addr(hdr->addr1)) { antenna = sc->sc_mcastantenna + 1; sc->sc_mcastantenna = (sc->sc_mcastantenna + 1) & 0x1; - } else - antenna = sc->sc_txantenna; + } -#ifdef USE_LEGACY_HAL - txctl->antenna = antenna; -#endif return 0; } @@ -743,7 +739,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) int i, flags, rtsctsena = 0, dynamic_mimops = 0; u32 ctsduration = 0; u8 rix = 0, cix, ctsrate = 0; - u32 aggr_limit_with_rts = sc->sc_rtsaggrlimit; + u32 aggr_limit_with_rts = ah->ah_caps.rts_aggr_limit; struct ath_node *an = (struct ath_node *) bf->bf_node; /* -- cgit v1.2.1 From 2ad67de3c8a21354b8b2721d5d2baabb7c5013c9 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 11 Aug 2008 14:01:47 +0300 Subject: ath9k: Allow AP mode to be enabled Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.c | 12 +++++++++--- drivers/net/wireless/ath9k/main.c | 19 +++++++++++++++++-- 2 files changed, 26 insertions(+), 5 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 0d953f9fdeeb..9737775aad3c 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -549,9 +549,15 @@ int ath_vap_listen(struct ath_softc *sc, int if_id) * 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); + if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { + ath9k_hw_set_interrupts(ah, sc->sc_imask & ~ATH9K_INT_BMISS); + sc->sc_imask &= ~ATH9K_INT_BMISS; + } else { + 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_flags &= ~SC_OP_BEACONS; diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 7fb57ee4c436..183c76e1187d 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -426,10 +426,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, case IEEE80211_IF_TYPE_IBSS: ic_opmode = ATH9K_M_IBSS; break; + case IEEE80211_IF_TYPE_AP: + ic_opmode = ATH9K_M_HOSTAP; + break; default: DPRINTF(sc, ATH_DBG_FATAL, - "%s: Only STA and IBSS are supported currently\n", - __func__); + "%s: Interface type %d not yet supported\n", + __func__, conf->type); return -EOPNOTSUPP; } @@ -530,6 +533,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, struct ieee80211_if_conf *conf) { struct ath_softc *sc = hw->priv; + struct ath_hal *ah = sc->sc_ah; struct ath_vap *avp; u32 rfilt = 0; int error, i; @@ -542,6 +546,17 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, 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) && !is_zero_ether_addr(conf->bssid)) { switch (vif->type) { -- cgit v1.2.1 From a8fff50e4d6aad520b261b3c32e2c67a7dfb7228 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 11 Aug 2008 14:01:48 +0300 Subject: ath9k: Updated Beacon generation to use mac80211-style This change moves ath9k to use mac80211-generated Beacon frames instead of trying to allocate a single Beacon frame and then update it. In addition, the remaining ath_skb_{map,unmap}_single() wrapper calls are replaced with direct pci_{map,unmap}_single() calls in beacon.c. Power save buffering for multicast/broadcast frames is not yet converted to use mac80211-style (frames to be buffered inside mac80211, not in driver). Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/beacon.c | 72 ++++++++++++++++++------------------- drivers/net/wireless/ath9k/core.h | 5 --- drivers/net/wireless/ath9k/main.c | 21 ++++++----- 3 files changed, 48 insertions(+), 50 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index e0ca0172f8be..8abcd3e8a301 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -172,6 +172,7 @@ static void empty_mcastq_into_cabq(struct ath_hal *ah, mcastq->axq_link = NULL; } +/* TODO: use ieee80211_get_buffered_bc() to fetch power saved mcast frames */ /* 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, @@ -206,7 +207,6 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) int cabq_depth; int mcastq_depth; int is_beacon_dtim = 0; - unsigned int curlen; struct ath_txq *cabq; struct ath_txq *mcastq; avp = sc->sc_vaps[if_id]; @@ -223,33 +223,27 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) } bf = avp->av_bcbuf; 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); + } - /* - * Update dynamic beacon contents. If this returns - * non-zero then we need to remap the memory because - * the beacon frame changed size (probably because - * of the TIM bitmap). - */ - curlen = skb->len; + skb = ieee80211_beacon_get(sc->hw, avp->av_if_data); + bf->bf_mpdu = skb; + if (skb == NULL) + return NULL; + bf->bf_buf_addr = bf->bf_dmacontext = + pci_map_single(sc->pdev, skb->data, + skb_end_pointer(skb) - skb->head, + PCI_DMA_TODEVICE); + /* TODO: convert to use ieee80211_get_buffered_bc() */ /* XXX: spin_lock_bh should not be used here, but sparse bitches * otherwise. We should fix sparse :) */ spin_lock_bh(&mcastq->axq_lock); mcastq_depth = avp->av_mcastq.axq_depth; - if (ath_update_beacon(sc, if_id, &avp->av_boff, skb, mcastq_depth) == - 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); - } - /* * if the CABQ traffic from previous DTIM is pending and the current * beacon is also a DTIM. @@ -262,7 +256,8 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) cabq_depth = cabq->axq_depth; spin_unlock_bh(&cabq->axq_lock); - is_beacon_dtim = avp->av_boff.bo_tim[4] & 1; + if (avp->av_boff.bo_tim) + is_beacon_dtim = avp->av_boff.bo_tim[4] & 1; if (mcastq_depth && is_beacon_dtim && cabq_depth) { /* @@ -408,8 +403,9 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) bf = avp->av_bcbuf; if (bf->bf_mpdu != NULL) { skb = (struct sk_buff *)bf->bf_mpdu; - ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE, - get_dma_mem_context(bf, bf_dmacontext)); + pci_unmap_single(sc->pdev, bf->bf_dmacontext, + skb_end_pointer(skb) - skb->head, + PCI_DMA_TODEVICE); dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; } @@ -439,9 +435,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) __le64 val; int intval; - /* FIXME: Use default value for now: Sujith */ - - intval = ATH_DEFAULT_BINTVAL; + intval = sc->hw->conf.beacon_int ? + sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL; /* * The beacon interval is in TU's; the TSF in usecs. @@ -466,8 +461,10 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) memcpy(&wh[1], &val, sizeof(val)); } - bf->bf_buf_addr = ath_skb_map_single(sc, skb, PCI_DMA_TODEVICE, - get_dma_mem_context(bf, bf_dmacontext)); + bf->bf_buf_addr = bf->bf_dmacontext = + pci_map_single(sc->pdev, skb->data, + skb_end_pointer(skb) - skb->head, + PCI_DMA_TODEVICE); bf->bf_mpdu = skb; return 0; @@ -493,8 +490,9 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) bf = avp->av_bcbuf; 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)); + pci_unmap_single(sc->pdev, bf->bf_dmacontext, + skb_end_pointer(skb) - skb->head, + PCI_DMA_TODEVICE); dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; } @@ -520,8 +518,9 @@ void ath_beacon_free(struct ath_softc *sc) 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)); + pci_unmap_single(sc->pdev, bf->bf_dmacontext, + skb_end_pointer(skb) - skb->head, + PCI_DMA_TODEVICE); dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; } @@ -643,8 +642,8 @@ void ath9k_beacon_tasklet(unsigned long data) * on the tsf to safeguard against missing an swba. */ - /* FIXME: Use default value for now - Sujith */ - intval = ATH_DEFAULT_BINTVAL; + intval = sc->hw->conf.beacon_int ? + sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL; tsf = ath9k_hw_gettsf64(ah); tsftu = TSF_TO_TU(tsf>>32, tsf); @@ -760,7 +759,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) * Protocol stack doesn't support dynamic beacon configuration, * 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.dtim_period = conf.beacon_interval; conf.dtim_count = 1; diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 8243ff049b60..bf7319401889 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -729,11 +729,6 @@ void ath_beacon_sync(struct ath_softc *sc, int if_id); void ath_get_beaconconfig(struct ath_softc *sc, int if_id, 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 */ /********/ diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 183c76e1187d..f904cf67dba8 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -624,6 +624,18 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, ath_beacon_sync(sc, 0); } + if ((conf->changed & IEEE80211_IFCC_BEACON) && + (vif->type == IEEE80211_IF_TYPE_AP)) { + ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); + + error = ath_beacon_alloc(sc, 0); + if (error != 0) + return error; + + ath_beacon_config(sc, 0); + sc->sc_flags |= SC_OP_BEACONS; + } + /* Check for WLAN_CAPABILITY_PRIVACY ? */ if ((avp->av_opmode != IEEE80211_IF_TYPE_STA)) { for (i = 0; i < IEEE80211_WEP_NKID; i++) @@ -1052,15 +1064,6 @@ void ath_get_beaconconfig(struct ath_softc *sc, 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, struct ath_xmit_status *tx_status, struct ath_node *an) { -- cgit v1.2.1 From 580f0b8a6dc1cb4d32c351a507d1c1d319bdc1eb Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 11 Aug 2008 14:01:49 +0300 Subject: ath9k: Fix TX status reporting Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index f904cf67dba8..4b61666261e3 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1085,8 +1085,16 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 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; -- cgit v1.2.1 From 147583c057c43095925b5f331fe304f2d5b997ba Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 11 Aug 2008 14:01:50 +0300 Subject: ath9k: Assign seq# when mac80211 requests this Use TX control flag IEEE80211_TX_CTL_ASSIGN_SEQ as a request to update the seq# for the frames. This will likely require some further cleanup to get seq# correctly for Beacons vs. other frames and also potentially for multiple BSSes. Anyway, this is better than ending up sending out most frames with seq# 0. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/beacon.c | 12 ++++++++++++ drivers/net/wireless/ath9k/core.h | 1 + drivers/net/wireless/ath9k/main.c | 14 ++++++++++++++ 3 files changed, 27 insertions(+) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index 8abcd3e8a301..a020f9a21544 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -209,6 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) int is_beacon_dtim = 0; struct ath_txq *cabq; struct ath_txq *mcastq; + struct ieee80211_tx_info *info; avp = sc->sc_vaps[if_id]; mcastq = &avp->av_mcastq; @@ -233,6 +234,17 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) bf->bf_mpdu = skb; if (skb == NULL) return NULL; + info = IEEE80211_SKB_CB(skb); + if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { + /* + * TODO: make sure the seq# gets assigned properly (vs. other + * TX frames) + */ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + sc->seq_no += 0x10; + hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); + hdr->seq_ctrl |= cpu_to_le16(sc->seq_no); + } bf->bf_buf_addr = bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data, skb_end_pointer(skb) - skb->head, diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index bf7319401889..c242942bbc18 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -965,6 +965,7 @@ struct ath_softc { u32 sc_txqsetup; u32 sc_txintrperiod; /* tx interrupt batching */ int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */ + u16 seq_no; /* TX sequence number */ /* Beacon */ struct ath9k_tx_queue_info sc_beacon_qi; diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 4b61666261e3..8fbde897406e 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -368,6 +368,20 @@ static int ath9k_tx(struct ieee80211_hw *hw, { struct ath_softc *sc = hw->priv; 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 */ hdrlen = ieee80211_get_hdrlen_from_skb(skb); -- cgit v1.2.1 From b14ecdd0afa4f616fcd1fcff4b902e15334256c7 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 11 Aug 2008 14:01:51 +0300 Subject: ath9k: Fix TX control flag use for no ACK and RTS/CTS Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/xmit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index e2ffa1cdb5e1..55f3c8e5bbbc 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -357,9 +357,9 @@ static int ath_tx_prepare(struct ath_softc *sc, txctl->flags = ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) - tx_info->flags |= ATH9K_TXDESC_NOACK; + txctl->flags |= ATH9K_TXDESC_NOACK; if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) - tx_info->flags |= ATH9K_TXDESC_RTSENA; + txctl->flags |= ATH9K_TXDESC_RTSENA; /* * Setup for rate calculations. -- cgit v1.2.1 From 927e70e9244e6ecdc7c28bc5424b0b8c11dee314 Mon Sep 17 00:00:00 2001 From: Sujith Date: Thu, 14 Aug 2008 13:26:34 +0530 Subject: ath9k: Remove remaining occurences of ath_skb_map functions Use direct pci functions instead. Also, use sc_ht_info.tx_chan_width directly and remove ath_cwm_macmode. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.c | 27 ++++++++++++-------------- drivers/net/wireless/ath9k/core.h | 9 --------- drivers/net/wireless/ath9k/recv.c | 40 ++++++++------------------------------- drivers/net/wireless/ath9k/xmit.c | 8 ++++---- 4 files changed, 24 insertions(+), 60 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 9737775aad3c..a9e8ad053a30 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -314,7 +314,6 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) { struct ath_hal *ah = sc->sc_ah; bool fastcc = true, stopped; - enum ath9k_ht_macmode ht_macmode; if (sc->sc_flags & SC_OP_INVALID) /* the device is invalid or removed */ return -EIO; @@ -328,8 +327,6 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) ath9k_hw_mhz2ieee(ah, 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 || (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) || @@ -357,10 +354,11 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) spin_lock_bh(&sc->sc_resetlock); if (!ath9k_hw_reset(ah, hchan, - ht_macmode, sc->sc_tx_chainmask, - sc->sc_rx_chainmask, - sc->sc_ht_extprotspacing, - fastcc, &status)) { + sc->sc_ht_info.tx_chan_width, + sc->sc_tx_chainmask, + sc->sc_rx_chainmask, + sc->sc_ht_extprotspacing, + fastcc, &status)) { DPRINTF(sc, ATH_DBG_FATAL, "%s: unable to reset channel %u (%uMhz) " "flags 0x%x hal status %u\n", __func__, @@ -682,7 +680,6 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) struct ath_hal *ah = sc->sc_ah; int status; 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_ah->ah_opmode); @@ -709,9 +706,10 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) */ spin_lock_bh(&sc->sc_resetlock); - if (!ath9k_hw_reset(ah, initial_chan, ht_macmode, - sc->sc_tx_chainmask, sc->sc_rx_chainmask, - sc->sc_ht_extprotspacing, false, &status)) { + if (!ath9k_hw_reset(ah, initial_chan, + sc->sc_ht_info.tx_chan_width, + 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 " "(freq %u flags 0x%x)\n", __func__, status, @@ -788,7 +786,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) struct ath_hal *ah = sc->sc_ah; int status; int error = 0; - enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc); ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */ ath_draintxq(sc, retry_tx); /* stop xmit */ @@ -798,9 +795,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) /* Reset chip */ spin_lock_bh(&sc->sc_resetlock); if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, - ht_macmode, - sc->sc_tx_chainmask, sc->sc_rx_chainmask, - sc->sc_ht_extprotspacing, false, &status)) { + sc->sc_ht_info.tx_chan_width, + 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); diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index c242942bbc18..51bf528e4c15 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -1023,14 +1023,5 @@ int ath_cabq_update(struct ath_softc *); void ath_get_currentCountry(struct ath_softc *sc, struct ath9k_country_entry *ctry); u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp); -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); -enum ath9k_ht_macmode ath_cwm_macmode(struct ath_softc *sc); #endif /* CORE_H */ diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index af2011fb05a0..91f635411ab5 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -454,11 +454,10 @@ static int ath_rx_indicate(struct ath_softc *sc, nskb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize); if (nskb != NULL) { bf->bf_mpdu = nskb; - bf->bf_buf_addr = ath_skb_map_single(sc, - nskb, - PCI_DMA_FROMDEVICE, - /* XXX: Remove get_dma_mem_context() */ - get_dma_mem_context(bf, bf_dmacontext)); + bf->bf_buf_addr = pci_map_single(sc->pdev, nskb->data, + skb_end_pointer(nskb) - nskb->head, + PCI_DMA_FROMDEVICE); + bf->bf_dmacontext = bf->bf_buf_addr; ATH_RX_CONTEXT(nskb)->ctx_rxbuf = bf; /* queue the new wbuf to H/W */ @@ -541,9 +540,10 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) } bf->bf_mpdu = skb; - bf->bf_buf_addr = - ath_skb_map_single(sc, skb, PCI_DMA_FROMDEVICE, - get_dma_mem_context(bf, bf_dmacontext)); + bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, + skb_end_pointer(skb) - skb->head, + PCI_DMA_FROMDEVICE); + bf->bf_dmacontext = bf->bf_buf_addr; ATH_RX_CONTEXT(skb)->ctx_rxbuf = bf; } sc->sc_rxlink = NULL; @@ -1297,27 +1297,3 @@ void ath_rx_node_free(struct ath_softc *sc, struct ath_node *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); -} diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 55f3c8e5bbbc..8d31ad7952be 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -1427,7 +1427,6 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) struct ath_hal *ah = sc->sc_ah; int i; int npend = 0; - enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc); /* XXX return value */ if (!(sc->sc_flags & SC_OP_INVALID)) { @@ -1452,9 +1451,10 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) spin_lock_bh(&sc->sc_resetlock); if (!ath9k_hw_reset(ah, - sc->sc_ah->ah_curchan, ht_macmode, - sc->sc_tx_chainmask, sc->sc_rx_chainmask, - sc->sc_ht_extprotspacing, true, &status)) { + sc->sc_ah->ah_curchan, + sc->sc_ht_info.tx_chan_width, + sc->sc_tx_chainmask, sc->sc_rx_chainmask, + sc->sc_ht_extprotspacing, true, &status)) { DPRINTF(sc, ATH_DBG_FATAL, "%s: unable to reset hardware; hal status %u\n", -- cgit v1.2.1 From dc2222a85fd63103b9aad0d4b77c4d87b78c58a2 Mon Sep 17 00:00:00 2001 From: Sujith Date: Thu, 14 Aug 2008 13:26:55 +0530 Subject: ath9k: Random cleanup Remove dead code, add newlines, fix indentation. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.c | 5 +- drivers/net/wireless/ath9k/hw.c | 13 +--- drivers/net/wireless/ath9k/rc.c | 159 +++++++++++++++++++------------------- 3 files changed, 83 insertions(+), 94 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index a9e8ad053a30..e3682b6ccfb2 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -1025,7 +1025,6 @@ int ath_init(u16 devid, struct ath_softc *sc) int status; int error = 0, i; int csz = 0; - u32 rd; /* XXX: hardware will not be ready until ath_open() being called */ sc->sc_flags |= SC_OP_INVALID; @@ -1091,8 +1090,6 @@ int ath_init(u16 devid, struct ath_softc *sc) * is resposible for filtering this list based on settings * like the phy mode. */ - rd = ah->ah_currentRD; - error = ath_setup_channels(sc); if (error) goto bad; @@ -1169,7 +1166,7 @@ int ath_init(u16 devid, struct ath_softc *sc) sc->sc_rc = ath_rate_attach(ah); if (sc->sc_rc == NULL) { - error = EIO; + error = -EIO; goto bad2; } diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 24b78c2eb44b..7d8c908d69d5 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -7654,8 +7654,7 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q) REG_WRITE(ah, AR_DRETRY_LIMIT(q), SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) | 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_DMISC(q), @@ -8300,15 +8299,7 @@ struct ath_hal *ath9k_hw_attach(u16 devid, *error = -ENXIO; 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; } diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 1392361ef9a6..1dd7c71daf0a 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -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); for (i = 0; i < rate_table->rate_cnt; i++) { valid = (ath_rc_priv->single_stream ? - rate_table->info[i].valid_single_stream : - rate_table->info[i].valid); + rate_table->info[i].valid_single_stream : + rate_table->info[i].valid); if (valid == TRUE) { u32 phy = rate_table->info[i].phy; u8 valid_rate_count = 0; @@ -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++) { u32 phy = rate_table->info[j].phy; u32 valid = (ath_rc_priv->single_stream ? - rate_table->info[j].valid_single_stream : - rate_table->info[j].valid); + rate_table->info[j].valid_single_stream : + rate_table->info[j].valid); if (((((struct ath_rateset *) - mcs_set)->rs_rates[i] & 0x7F) != - (rate_table->info[j].dot11rate & 0x7F)) || - !WLAN_RC_PHY_HT(phy) || - !WLAN_RC_PHY_HT_VALID(valid, capflag)) + mcs_set)->rs_rates[i] & 0x7F) != + (rate_table->info[j].dot11rate & 0x7F)) || + !WLAN_RC_PHY_HT(phy) || + !WLAN_RC_PHY_HT_VALID(valid, capflag)) continue; if (!ath_rc_valid_phyrate(phy, capflag, FALSE)) @@ -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, - struct ath_rate_node *ath_rc_priv, - const struct ath_rate_table *rate_table, - int probe_allowed, int *is_probing, - int is_retry) + struct ath_rate_node *ath_rc_priv, + const struct ath_rate_table *rate_table, + int probe_allowed, int *is_probing, + int is_retry) { u32 dt, best_thruput, this_thruput, now_msec; u8 rate, next_rate, best_rate, maxindex, minindex; @@ -997,8 +997,8 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc, rate = rate_ctrl->rate_table_size - 1; ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) || - (rate_table->info[rate].valid_single_stream && - ath_rc_priv->single_stream)); + (rate_table->info[rate].valid_single_stream && + ath_rc_priv->single_stream)); return rate; } @@ -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, - struct ath_rate_node *ath_rc_priv, - const struct ath_rate_table *rate_table, - u8 rix, u16 stepdown, - u16 min_rate) + struct ath_rate_node *ath_rc_priv, + const struct ath_rate_table *rate_table, + u8 rix, u16 stepdown, + u16 min_rate) { u32 j; u8 nextindex; @@ -1066,8 +1066,8 @@ static void ath_rc_ratefind(struct ath_softc *sc, rate_table = (struct ath_rate_table *)asc->hw_rate_table[sc->sc_curmode]; rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, - (rcflag & ATH_RC_PROBE_ALLOWED) ? 1 : 0, - is_probe, is_retry); + (rcflag & ATH_RC_PROBE_ALLOWED) ? 1 : 0, + is_probe, is_retry); nrix = rix; if ((rcflag & ATH_RC_PROBE_ALLOWED) && (*is_probe)) { @@ -1099,13 +1099,13 @@ static void ath_rc_ratefind(struct ath_softc *sc, try_num = ((i + 1) == num_rates) ? num_tries - (try_per_rate * i) : try_per_rate ; 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, - rate_table, nrix, 1, min_rate); + rate_table, nrix, 1, min_rate); /* All other rates in the series have RTS enabled */ 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, * above conditions. */ if ((sc->sc_curmode == ATH9K_MODE_11NG_HT20) || - (sc->sc_curmode == ATH9K_MODE_11NG_HT40PLUS) || - (sc->sc_curmode == ATH9K_MODE_11NG_HT40MINUS)) { + (sc->sc_curmode == ATH9K_MODE_11NG_HT40PLUS) || + (sc->sc_curmode == ATH9K_MODE_11NG_HT40MINUS)) { u8 dot11rate = rate_table->info[rix].dot11rate; u8 phy = rate_table->info[rix].phy; if (i == 4 && ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) || - (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].flags = series[2].flags; series[3].max_4ms_framelen = series[2].max_4ms_framelen; @@ -1152,7 +1152,8 @@ void ath_rate_findrate(struct ath_softc *sc, { 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) return; @@ -1174,9 +1175,8 @@ void ath_rate_findrate(struct ath_softc *sc, unsigned int mcs; u8 series_rix = 0; - series[idx].tries = - IEEE80211_RATE_IDX_ENTRY( - avp->av_config.av_fixed_retryset, idx); + series[idx].tries = IEEE80211_RATE_IDX_ENTRY( + avp->av_config.av_fixed_retryset, idx); mcs = IEEE80211_RATE_IDX_ENTRY( avp->av_config.av_fixed_rateset, idx); @@ -1228,7 +1228,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, u32 now_msec = jiffies_to_msecs(jiffies); int state_change = FALSE, rate, count; 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 *)asc->hw_rate_table[sc->sc_curmode]; @@ -1272,14 +1272,14 @@ static void ath_rc_update_ht(struct ath_softc *sc, } else { /* xretries == 2 */ count = sizeof(nretry_to_per_lookup) / - sizeof(nretry_to_per_lookup[0]); + sizeof(nretry_to_per_lookup[0]); if (retries >= count) retries = count - 1; /* new_PER = 7/8*old_PER + 1/8*(currentPER) */ rate_ctrl->state[tx_rate].per = (u8)(rate_ctrl->state[tx_rate].per - - (rate_ctrl->state[tx_rate].per >> 3) + - ((100) >> 3)); + (rate_ctrl->state[tx_rate].per >> 3) + + ((100) >> 3)); } /* xretries == 1 or 2 */ @@ -1295,8 +1295,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, if (retries >= count) retries = count - 1; 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 * from the retries is 100 * retries / (retries+1), * since the first retries attempts failed, and the @@ -1386,7 +1385,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, * rssi_ack values. */ 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++; } @@ -1418,7 +1417,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, /* Now reduce the current * rssi threshold. */ if ((rssi_ackAvg < rssi_thres + 2) && - (rssi_thres > rssi_ack_vmin)) { + (rssi_thres > rssi_ack_vmin)) { rate_ctrl->state[tx_rate]. rssi_thres--; } @@ -1436,10 +1435,10 @@ static void ath_rc_update_ht(struct ath_softc *sc, * a while (except if we are probing). */ if (rate_ctrl->state[tx_rate].per >= 55 && tx_rate > 0 && - rate_table->info[tx_rate].ratekbps <= - rate_table->info[rate_ctrl->rate_max_phy].ratekbps) { + rate_table->info[tx_rate].ratekbps <= + rate_table->info[rate_ctrl->rate_max_phy].ratekbps) { 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. */ rate_ctrl->probe_time = now_msec; @@ -1460,43 +1459,43 @@ static void ath_rc_update_ht(struct ath_softc *sc, break; if (rate_ctrl->state[rate].rssi_thres + - rate_table->info[rate].rssi_ack_deltamin > - rate_ctrl->state[rate+1].rssi_thres) { + 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]. - rssi_thres + + rssi_thres + rate_table->info[rate]. - rssi_ack_deltamin; + rssi_ack_deltamin; } } /* Make sure the rates below this have lower rssi thresholds. */ for (rate = tx_rate - 1; rate >= 0; rate--) { if (rate_table->info[rate].phy != - rate_table->info[tx_rate].phy) + rate_table->info[tx_rate].phy) break; if (rate_ctrl->state[rate].rssi_thres + - rate_table->info[rate].rssi_ack_deltamin > - rate_ctrl->state[rate+1].rssi_thres) { + rate_table->info[rate].rssi_ack_deltamin > + rate_ctrl->state[rate+1].rssi_thres) { if (rate_ctrl->state[rate+1].rssi_thres < - rate_table->info[rate]. - rssi_ack_deltamin) + rate_table->info[rate]. + rssi_ack_deltamin) rate_ctrl->state[rate].rssi_thres = 0; else { rate_ctrl->state[rate].rssi_thres = rate_ctrl->state[rate+1]. - rssi_thres - - rate_table->info[rate]. - rssi_ack_deltamin; + rssi_thres - + rate_table->info[rate]. + rssi_ack_deltamin; } 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 = rate_table->info[rate]. - rssi_ack_validmin; + rssi_ack_validmin; } } } @@ -1507,11 +1506,11 @@ static void ath_rc_update_ht(struct ath_softc *sc, if (rate_ctrl->state[tx_rate].per < last_per) { for (rate = tx_rate - 1; rate >= 0; rate--) { if (rate_table->info[rate].phy != - rate_table->info[tx_rate].phy) + rate_table->info[tx_rate].phy) break; 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+1].per; } @@ -1528,11 +1527,11 @@ static void ath_rc_update_ht(struct ath_softc *sc, /* Every so often, we reduce the thresholds and * PER (different for CCK and OFDM). */ 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++) { 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->rssi_down_time = now_msec; @@ -1541,7 +1540,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, /* Every so often, we reduce the thresholds * and PER (different for CCK and OFDM). */ 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++) { rate_ctrl->state[rate].per = 7 * rate_ctrl->state[rate].per / 8; @@ -1560,7 +1559,7 @@ static void ath_rc_update(struct ath_softc *sc, struct ath_tx_info_priv *info_priv, int final_ts_idx, 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_tx_ratectrl *rate_ctrl; struct ath_rc_series rcs[4]; @@ -1637,7 +1636,6 @@ static void ath_rc_update(struct ath_softc *sc, xretries, long_retry); } - /* * 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, struct ath_vap *avp; avp = rc_priv->avp; - if ((avp->av_config.av_fixed_rateset != IEEE80211_FIXED_RATE_NONE) - || info_priv->tx.ts_status & ATH9K_TXERR_FILT) + if ((avp->av_config.av_fixed_rateset != IEEE80211_FIXED_RATE_NONE) || + (info_priv->tx.ts_status & ATH9K_TXERR_FILT)) return; if (info_priv->tx.ts_rssi > 0) { 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, info_priv->tx.ts_longretry); } - /* * Update the SIB's rate control information * @@ -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_rateset *rateset = negotiated_rates; u8 *ht_mcs = (u8 *)negotiated_htrates; - struct ath_tx_ratectrl *rate_ctrl = (struct ath_tx_ratectrl *) - (ath_rc_priv); + struct ath_tx_ratectrl *rate_ctrl = + (struct ath_tx_ratectrl *)ath_rc_priv; u8 i, j, k, hi = 0, hthi = 0; rate_table = (struct ath_rate_table *) @@ -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; 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]; for (i = 0; i < sband->n_bitrates; i++) { if (sta->supp_rates[local->hw.conf.channel->band] & BIT(i)) { @@ -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; /* lowest rate for management and multicast/broadcast frames */ if (!ieee80211_is_data(fc) || - is_multicast_ether_addr(hdr->addr1) || !sta) { + is_multicast_ether_addr(hdr->addr1) || !sta) { sel->rate_idx = lowest_idx; return; } @@ -1978,7 +1976,7 @@ static void ath_get_rate(void *priv, struct net_device *dev, false); if (is_probe) 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 */ if (tx_info_priv->rcs[0].rix != 0xff) @@ -2035,6 +2033,7 @@ static void ath_rate_init(void *priv, void *priv_sta, struct ieee80211_hw *hw = local_to_hw(local); struct ieee80211_conf *conf = &local->hw.conf; struct ath_softc *sc = hw->priv; + struct ath_rate_node *ath_rc_priv = priv_sta; int i, j = 0; DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); @@ -2046,12 +2045,11 @@ static void ath_rate_init(void *priv, void *priv_sta, if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { for (i = 0; i < MCS_SET_SIZE; i++) { if (conf->ht_conf.supp_mcs_set[i/8] & (1<<(i%8))) - ((struct ath_rate_node *) - priv_sta)->neg_ht_rates.rs_rates[j++] = i; + ath_rc_priv->neg_ht_rates.rs_rates[j++] = i; if (j == ATH_RATE_MAX) 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); } @@ -2066,7 +2064,7 @@ static void *ath_rate_alloc(struct ieee80211_local *local) struct ieee80211_hw *hw = local_to_hw(local); 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; } @@ -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_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); if (!rate_priv) { - DPRINTF(sc, ATH_DBG_FATAL, "%s:Unable to allocate" - "private rate control structure", __func__); + DPRINTF(sc, ATH_DBG_FATAL, + "%s: Unable to allocate private rc structure\n", + __func__); return NULL; } ath_rc_sib_init(rate_priv); + return rate_priv; } -- cgit v1.2.1 From ff9b662dab1fcd885fb728de3a8c13ebb5455117 Mon Sep 17 00:00:00 2001 From: Sujith Date: Thu, 14 Aug 2008 13:27:16 +0530 Subject: ath9k: Miscellaneous fixes This patch removes ath_vap_listen() and dma wrapper macros. Also, Inline abuse is cleaned up and a few typos are fixed. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/beacon.c | 52 +++++++++++++------------- drivers/net/wireless/ath9k/core.c | 74 ++----------------------------------- drivers/net/wireless/ath9k/core.h | 6 +-- drivers/net/wireless/ath9k/hw.c | 68 +++++++++++++++++----------------- drivers/net/wireless/ath9k/main.c | 19 ++-------- drivers/net/wireless/ath9k/xmit.c | 29 ++++++--------- 6 files changed, 79 insertions(+), 169 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index a020f9a21544..89e5c65accd0 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -114,21 +114,21 @@ static void ath_beacon_setup(struct ath_softc *sc, if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) rate |= rt->info[rix].shortPreamble; - ath9k_hw_set11n_txdesc(ah, ds - , skb->len + FCS_LEN /* frame length */ - , ATH9K_PKT_TYPE_BEACON /* Atheros packet type */ - , avp->av_btxctl.txpower /* txpower XXX */ - , ATH9K_TXKEYIX_INVALID /* no encryption */ - , ATH9K_KEY_TYPE_CLEAR /* no encryption */ - , flags /* no ack, veol for beacons */ + ath9k_hw_set11n_txdesc(ah, ds, + skb->len + FCS_LEN, /* frame length */ + ATH9K_PKT_TYPE_BEACON, /* Atheros packet type */ + avp->av_btxctl.txpower, /* txpower XXX */ + ATH9K_TXKEYIX_INVALID, /* no encryption */ + ATH9K_KEY_TYPE_CLEAR, /* no encryption */ + flags /* no ack, veol for beacons */ ); /* NB: beacon's BufLen must be a multiple of 4 bytes */ - ath9k_hw_filltxdesc(ah, ds - , roundup(skb->len, 4) /* buffer length */ - , true /* first segment */ - , true /* last segment */ - , ds /* first descriptor */ + ath9k_hw_filltxdesc(ah, ds, + roundup(skb->len, 4), /* buffer length */ + true, /* first segment */ + true, /* last segment */ + ds /* first descriptor */ ); memzero(series, sizeof(struct ath9k_11n_rate_series) * 4); @@ -551,7 +551,7 @@ void ath_beacon_free(struct ath_softc *sc) void ath9k_beacon_tasklet(unsigned long data) { -#define TSF_TO_TU(_h,_l) \ +#define TSF_TO_TU(_h,_l) \ ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) struct ath_softc *sc = (struct ath_softc *)data; @@ -898,19 +898,19 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) "cfp:period %u " "maxdur %u " "next %u " - "timoffset %u\n" - , __func__ - , (unsigned long long)tsf, tsftu - , bs.bs_intval - , bs.bs_nexttbtt - , bs.bs_dtimperiod - , bs.bs_nextdtim - , bs.bs_bmissthreshold - , bs.bs_sleepduration - , bs.bs_cfpperiod - , bs.bs_cfpmaxduration - , bs.bs_cfpnext - , bs.bs_timoffset + "timoffset %u\n", + __func__, + (unsigned long long)tsf, tsftu, + bs.bs_intval, + bs.bs_nexttbtt, + bs.bs_dtimperiod, + bs.bs_nextdtim, + bs.bs_bmissthreshold, + bs.bs_sleepduration, + bs.bs_cfpperiod, + bs.bs_cfpmaxduration, + bs.bs_cfpnext, + bs.bs_timoffset ); ath9k_hw_set_interrupts(ah, 0); diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index e3682b6ccfb2..57645ee83efb 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -51,10 +51,8 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz) * Set current operating mode * * 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 - * they have been superceeded by the ath_led module. + * on the operating mode. */ - static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) { const struct ath9k_rate_table *rt; @@ -232,7 +230,7 @@ static int ath_setup_channels(struct ath_softc *sc) * Determine mode from channel flags * * 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. */ @@ -257,7 +255,8 @@ static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan) else if (chan->chanmode == CHANNEL_G_HT40MINUS) return ATH9K_MODE_11NG_HT40MINUS; - /* NB: should not get here */ + WARN_ON(1); /* should not get here */ + return ATH9K_MODE_11B; } @@ -278,8 +277,6 @@ static int ath_stop(struct ath_softc *sc) /* * Shutdown the hardware and driver: * stop output from above - * reset 802.11 state machine - * (sends station deassoc/deauth frames) * turn off timers * disable interrupts * clear transmit machinery @@ -499,69 +496,6 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht) /* 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_ah->ah_opmode == ATH9K_M_STA || - sc->sc_ah->ah_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 - */ - if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { - ath9k_hw_set_interrupts(ah, sc->sc_imask & ~ATH9K_INT_BMISS); - sc->sc_imask &= ~ATH9K_INT_BMISS; - } else { - 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_flags &= ~SC_OP_BEACONS; - - return 0; -} - int ath_vap_attach(struct ath_softc *sc, int if_id, struct ieee80211_vif *if_data, diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 51bf528e4c15..406225ba4521 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -82,9 +82,6 @@ struct ath_node; /* XXX: remove */ #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_CHANGE 1 @@ -769,8 +766,7 @@ int ath_vap_attach(struct ath_softc *sc, enum ath9k_opmode opmode); int ath_vap_detach(struct ath_softc *sc, int if_id); int ath_vap_config(struct ath_softc *sc, - int if_id, struct ath_vap_config *if_config); -int ath_vap_listen(struct ath_softc *sc, int if_id); + int if_id, struct ath_vap_config *if_config); /*********************/ /* Antenna diversity */ diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 7d8c908d69d5..47c60acac41f 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -348,7 +348,7 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah) 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) { if (!AR_SREV_5416_V20_OR_LATER(ah) @@ -358,8 +358,8 @@ static inline void ath9k_hw_override_ini(struct ath_hal *ah, REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); } -static inline void ath9k_hw_init_bb(struct ath_hal *ah, - struct ath9k_channel *chan) +static void ath9k_hw_init_bb(struct ath_hal *ah, + struct ath9k_channel *chan) { u32 synthDelay; @@ -374,8 +374,8 @@ static inline void ath9k_hw_init_bb(struct ath_hal *ah, udelay(synthDelay + BASE_ACTIVATE_DELAY); } -static inline void ath9k_hw_init_interrupt_masks(struct ath_hal *ah, - enum ath9k_opmode opmode) +static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah, + enum ath9k_opmode opmode) { struct ath_hal_5416 *ahp = AH5416(ah); @@ -405,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_SELECT, 0x3210); @@ -500,7 +500,7 @@ static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, 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 ar5416_eeprom *eep = &ahp->ah_eeprom; @@ -767,7 +767,7 @@ ath9k_hw_eeprom_set_board_values(struct ath_hal *ah, 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; u16 *eepdata; @@ -1272,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; int i; @@ -1285,7 +1285,7 @@ static inline int ath9k_hw_get_radiorev(struct ath_hal *ah) 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; int i; @@ -1367,7 +1367,7 @@ static u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, 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; int ecode = 0; @@ -1412,8 +1412,8 @@ static int ath9k_hw_rf_claim(struct ath_hal *ah) return 0; } -static inline void ath9k_hw_init_pll(struct ath_hal *ah, - struct ath9k_channel *chan) +static void ath9k_hw_init_pll(struct ath_hal *ah, + struct ath9k_channel *chan) { u32 pll; @@ -1531,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) { u32 rfMode = 0; @@ -1601,7 +1601,7 @@ static bool ath9k_hw_set_reset(struct ath_hal *ah, int type) 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 | AR_RTC_FORCE_WAKE_ON_INT); @@ -1642,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 *chan) { @@ -2076,7 +2076,7 @@ static void ath9k_hw_ani_attach(struct ath_hal *ah) 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); int i; @@ -2861,7 +2861,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; @@ -3573,7 +3573,7 @@ static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, return true; } -static inline void +static void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah, struct ath9k_channel *chan, struct cal_data_per_freq *pRawDataSet, @@ -3755,7 +3755,7 @@ ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah, return; } -static inline bool +static bool ath9k_hw_set_power_cal_table(struct ath_hal *ah, struct ar5416_eeprom *pEepData, struct ath9k_channel *chan, @@ -3958,7 +3958,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, struct ath9k_channel *chan, struct cal_target_power_leg *powInfo, @@ -4024,7 +4024,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, struct ath9k_channel *chan, struct cal_target_power_ht *powInfo, @@ -4091,7 +4091,7 @@ ath9k_hw_get_target_powers(struct ath_hal *ah, } } -static inline u16 +static u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, bool is2GHz) @@ -4121,7 +4121,7 @@ ath9k_hw_get_max_edge_power(u16 freq, return twiceMaxEdgePower; } -static inline bool +static bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah, struct ar5416_eeprom *pEepData, struct ath9k_channel *chan, @@ -5100,7 +5100,7 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, 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); int rx_chainmask, tx_chainmask; @@ -5304,7 +5304,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); @@ -5323,7 +5323,7 @@ static inline void ath9k_hw_init_user_settings(struct ath_hal *ah) ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout); } -static inline int +static int ath9k_hw_process_ini(struct ath_hal *ah, struct ath9k_channel *chan, enum ath9k_ht_macmode macmode) @@ -5454,7 +5454,7 @@ ath9k_hw_process_ini(struct ath_hal *ah, 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) { REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0), @@ -5490,8 +5490,8 @@ static inline void ath9k_hw_setup_calibration(struct ath_hal *ah, AR_PHY_TIMING_CTRL4_DO_CAL); } -static inline void ath9k_hw_reset_calibration(struct ath_hal *ah, - struct hal_cal_list *currCal) +static void ath9k_hw_reset_calibration(struct ath_hal *ah, + struct hal_cal_list *currCal) { struct ath_hal_5416 *ahp = AH5416(ah); int i; @@ -5510,7 +5510,7 @@ static inline void ath9k_hw_reset_calibration(struct ath_hal *ah, ahp->ah_CalSamples = 0; } -static inline void +static void ath9k_hw_per_calibration(struct ath_hal *ah, struct ath9k_channel *ichan, u8 rxchainmask, @@ -5600,7 +5600,7 @@ static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah, return true; } -static inline bool +static bool ath9k_hw_channel_change(struct ath_hal *ah, struct ath9k_channel *chan, enum ath9k_ht_macmode macmode) @@ -5777,8 +5777,8 @@ static bool ath9k_hw_iscal_supported(struct ath_hal *ah, return retval; } -static inline bool ath9k_hw_init_cal(struct ath_hal *ah, - struct ath9k_channel *chan) +static bool ath9k_hw_init_cal(struct ath_hal *ah, + struct ath9k_channel *chan) { struct ath_hal_5416 *ahp = AH5416(ah); struct ath9k_channel *ichan = diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 8fbde897406e..605599eb6d3f 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -212,12 +212,10 @@ static int ath_key_config(struct ath_softc *sc, static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key) { -#define ATH_MAX_NUM_KEYS 4 int freeslot; - freeslot = (key->keyidx >= ATH_MAX_NUM_KEYS) ? 1 : 0; + freeslot = (key->keyidx >= 4) ? 1 : 0; ath_key_reset(sc, key->keyidx, freeslot); -#undef ATH_MAX_NUM_KEYS } static void setup_ht_cap(struct ieee80211_ht_info *ht_info) @@ -620,7 +618,8 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, } 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. * @@ -638,18 +637,6 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, ath_beacon_sync(sc, 0); } - if ((conf->changed & IEEE80211_IFCC_BEACON) && - (vif->type == IEEE80211_IF_TYPE_AP)) { - ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); - - error = ath_beacon_alloc(sc, 0); - if (error != 0) - return error; - - ath_beacon_config(sc, 0); - sc->sc_flags |= SC_OP_BEACONS; - } - /* Check for WLAN_CAPABILITY_PRIVACY ? */ if ((avp->av_opmode != IEEE80211_IF_TYPE_STA)) { for (i = 0; i < IEEE80211_WEP_NKID; i++) diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 8d31ad7952be..04f94d2c8010 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -499,7 +499,6 @@ static void ath_tx_complete_buf(struct ath_softc *sc, { struct sk_buff *skb = bf->bf_mpdu; struct ath_xmit_status tx_status; - dma_addr_t *pa; /* * Set retry information. @@ -519,9 +518,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, tx_status.flags |= ATH_TX_XRETRY; } /* Unmap this frame */ - pa = get_dma_mem_context(bf, bf_dmacontext); pci_unmap_single(sc->pdev, - *pa, + bf->bf_dmacontext, skb->len, PCI_DMA_TODEVICE); /* complete this frame */ @@ -1172,11 +1170,8 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, tbf->bf_lastfrm->bf_desc); /* copy the DMA context */ - copy_dma_mem_context( - get_dma_mem_context(tbf, - bf_dmacontext), - get_dma_mem_context(bf_last, - bf_dmacontext)); + tbf->bf_dmacontext = + bf_last->bf_dmacontext; } list_add_tail(&tbf->list, &bf_head); } else { @@ -1185,7 +1180,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, * software retry */ ath9k_hw_cleartxdesc(sc->sc_ah, - bf->bf_lastfrm->bf_desc); + bf->bf_lastfrm->bf_desc); } /* @@ -2045,8 +2040,7 @@ static int ath_tx_start_dma(struct ath_softc *sc, /* * Save the DMA context in the first ath_buf */ - copy_dma_mem_context(get_dma_mem_context(bf, bf_dmacontext), - get_dma_mem_context(txctl, dmacontext)); + bf->bf_dmacontext = txctl->dmacontext; /* * Formulate first tx descriptor with tx controls. @@ -2127,25 +2121,26 @@ static int ath_tx_start_dma(struct ath_softc *sc, static void xmit_map_sg(struct ath_softc *sc, struct sk_buff *skb, - dma_addr_t *pa, struct ath_tx_control *txctl) { struct ath_xmit_status tx_status; struct ath_atx_tid *tid; struct scatterlist sg; - *pa = pci_map_single(sc->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); + txctl->dmacontext = pci_map_single(sc->pdev, skb->data, + skb->len, PCI_DMA_TODEVICE); /* setup S/G list */ memset(&sg, 0, sizeof(struct scatterlist)); - sg_dma_address(&sg) = *pa; + sg_dma_address(&sg) = txctl->dmacontext; sg_dma_len(&sg) = skb->len; if (ath_tx_start_dma(sc, skb, &sg, 1, txctl) != 0) { /* * We have to do drop frame here. */ - pci_unmap_single(sc->pdev, *pa, skb->len, PCI_DMA_TODEVICE); + pci_unmap_single(sc->pdev, txctl->dmacontext, + skb->len, PCI_DMA_TODEVICE); tx_status.retries = 0; tx_status.flags = ATH_TX_ERROR; @@ -2419,9 +2414,7 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb) * ath_tx_start_dma() will be called either synchronously * or asynchrounsly once DMA is complete. */ - xmit_map_sg(sc, skb, - get_dma_mem_context(&txctl, dmacontext), - &txctl); + xmit_map_sg(sc, skb, &txctl); else ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE); -- cgit v1.2.1 From 60653678939dcbba3aa936250b58179aa3451eee Mon Sep 17 00:00:00 2001 From: Sujith Date: Thu, 14 Aug 2008 13:28:02 +0530 Subject: ath9k: Use definition from ieee80211.h Also, Max RX-ampdu and mpdu-density are ath9k specific. Rename appropriately. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 605599eb6d3f..2b3b11bb564b 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -22,8 +22,6 @@ #define ATH_PCI_VERSION "0.1" #define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13 -#define IEEE80211_ACTION_CAT_HT 7 -#define IEEE80211_ACTION_HT_TXCHWIDTH 0 static char *dev_info = "ath9k"; @@ -220,11 +218,8 @@ static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key) static void setup_ht_cap(struct ieee80211_ht_info *ht_info) { -/* Until mac80211 includes these fields */ - -#define IEEE80211_HT_CAP_DSSSCCK40 0x1000 -#define IEEE80211_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */ -#define IEEE80211_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */ +#define ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */ +#define ATH9K_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */ ht_info->ht_supported = 1; ht_info->cap = (u16)IEEE80211_HT_CAP_SUP_WIDTH @@ -232,8 +227,8 @@ static void setup_ht_cap(struct ieee80211_ht_info *ht_info) |(u16)IEEE80211_HT_CAP_SGI_40 |(u16)IEEE80211_HT_CAP_DSSSCCK40; - ht_info->ampdu_factor = IEEE80211_HT_CAP_MAXRXAMPDU_65536; - ht_info->ampdu_density = IEEE80211_HT_CAP_MPDUDENSITY_8; + ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536; + ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8; /* setup supported mcs set */ memset(ht_info->supp_mcs_set, 0, 16); ht_info->supp_mcs_set[0] = 0xff; -- cgit v1.2.1 From 19b73c7f68fb2eeb180eafa70f9859409ec9aa08 Mon Sep 17 00:00:00 2001 From: Sujith Date: Thu, 14 Aug 2008 13:28:20 +0530 Subject: ath9k: Add IEEE80211_HW_RX_INCLUDES_FCS to hw flags Don't trim the FCS before passing the frame to mac80211, move TSF_TO_TU to core.h and delete more unused macros. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 13 ------------- drivers/net/wireless/ath9k/beacon.c | 7 ------- drivers/net/wireless/ath9k/core.h | 11 +++++++---- drivers/net/wireless/ath9k/main.c | 8 +++----- drivers/net/wireless/ath9k/phy.h | 12 ++++++------ drivers/net/wireless/ath9k/recv.c | 2 +- 6 files changed, 17 insertions(+), 36 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 682d3bb4d494..18028a3abc58 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -564,8 +564,6 @@ enum ath9k_cipher { #define CTL_5GHT40 8 #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_S 2 @@ -606,9 +604,6 @@ struct ath9k_country_entry { #define REG_CLR_BIT(_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 INIT_AIFS 2 @@ -637,7 +632,6 @@ struct ath9k_country_entry { IEEE80211_WEP_KIDLEN + \ IEEE80211_WEP_CRCLEN)) -#define MAX_REG_ADD_COUNT 129 #define MAX_RATE_POWER 63 enum ath9k_power_mode { @@ -707,13 +701,6 @@ enum phytype { }; #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 { ATH9K_TP_SCALE_MAX = 0, ATH9K_TP_SCALE_50, diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index 89e5c65accd0..ee1185622ba6 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -551,9 +551,6 @@ void ath_beacon_free(struct ath_softc *sc) 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_hal *ah = sc->sc_ah; struct ath_buf *bf = NULL; @@ -715,7 +712,6 @@ void ath9k_beacon_tasklet(unsigned long data) sc->ast_be_xmit += bc; /* XXX per-vap? */ } -#undef TSF_TO_TU } /* @@ -751,8 +747,6 @@ void ath_bstuck_process(struct ath_softc *sc) 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; u32 nexttbtt, intval; struct ath_beacon_config conf; @@ -975,7 +969,6 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) ath_beacon_start_adhoc(sc, 0); } -#undef TSF_TO_TU } /* Function to collect beacon rssi data and resync beacon if necessary */ diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 406225ba4521..ca7e61353547 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -79,6 +79,9 @@ struct ath_node; } \ } while (0) +#define TSF_TO_TU(_h,_l) \ + ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) + /* XXX: remove */ #define memzero(_buf, _len) memset(_buf, 0, _len) @@ -382,10 +385,10 @@ int ath_rx_input(struct ath_softc *sc, struct sk_buff *skb, struct ath_recv_status *rx_status, enum ATH_RX_TYPE *status); -int ath__rx_indicate(struct ath_softc *sc, - struct sk_buff *skb, - struct ath_recv_status *status, - u16 keyix); +int _ath_rx_indicate(struct ath_softc *sc, + struct sk_buff *skb, + struct ath_recv_status *status, + u16 keyix); int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb, struct ath_recv_status *status); diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 2b3b11bb564b..55f48685b5ea 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1099,7 +1099,7 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, 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 ath_recv_status *status, u16 keyix) @@ -1119,9 +1119,6 @@ int ath__rx_indicate(struct ath_softc *sc, skb_pull(skb, padsize); } - /* remove FCS before passing up to protocol stack */ - skb_trim(skb, (skb->len - FCS_LEN)); - /* Prepare rx status */ ath9k_rx_prepare(sc, skb, status, &rx_status); @@ -1364,7 +1361,8 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto bad2; } - hw->flags = IEEE80211_HW_SIGNAL_DBM | + hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM; SET_IEEE80211_DEV(hw, &pdev->dev); diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath9k/phy.h index 0cd399a5344a..14702344448b 100644 --- a/drivers/net/wireless/ath9k/phy.h +++ b/drivers/net/wireless/ath9k/phy.h @@ -18,19 +18,19 @@ #define PHY_H bool ath9k_hw_ar9280_set_channel(struct ath_hal *ah, - struct ath9k_channel - *chan); + struct ath9k_channel + *chan); 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, u32 freqIndex, int regWrites); bool ath9k_hw_set_rf_regs(struct ath_hal *ah, - struct ath9k_channel *chan, - u16 modesIndex); + struct ath9k_channel *chan, + u16 modesIndex); void ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan); bool ath9k_hw_init_rf(struct ath_hal *ah, - int *status); + int *status); #define AR_PHY_BASE 0x9800 #define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2)) diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 91f635411ab5..6e13c638cc0b 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -448,7 +448,7 @@ static int ath_rx_indicate(struct ath_softc *sc, int type; /* 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 */ nskb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize); -- cgit v1.2.1 From e022edbd2bfb5f9a7ddf1cca43544f7b54c6fe02 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 22 Aug 2008 17:31:33 +0300 Subject: ath9k: Use mac80211 for multicast power save buffering Replace the internal ath9k implementation of multicast/broadcast frame power save buffering (AP mode) in ath9k with use of mac80211 ieee80211_get_buffered_bc() mechanism. This removes quite a bit of duplicated functionality and simplifies the driver part. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 1 + drivers/net/wireless/ath9k/beacon.c | 75 ++-------------- drivers/net/wireless/ath9k/core.c | 6 -- drivers/net/wireless/ath9k/core.h | 9 +- drivers/net/wireless/ath9k/main.c | 1 + drivers/net/wireless/ath9k/xmit.c | 173 +++++++++++++++--------------------- 6 files changed, 82 insertions(+), 183 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 18028a3abc58..841893b0b4d4 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -144,6 +144,7 @@ struct ath_desc { #define ATH9K_TXDESC_EXT_AND_CTL 0x0080 #define ATH9K_TXDESC_VMF 0x0100 #define ATH9K_TXDESC_FRAG_IS_ON 0x0200 +#define ATH9K_TXDESC_CAB 0x0400 #define ATH9K_RXDESC_INTREQ 0x0020 diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index ee1185622ba6..fdbabc180228 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -140,56 +140,6 @@ static void ath_beacon_setup(struct ath_softc *sc, 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; -} - -/* TODO: use ieee80211_get_buffered_bc() to fetch power saved mcast frames */ -/* 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. * @@ -200,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) { - struct ath_hal *ah = sc->sc_ah; struct ath_buf *bf; struct ath_vap *avp; struct sk_buff *skb; int cabq_depth; - int mcastq_depth; - int is_beacon_dtim = 0; struct ath_txq *cabq; - struct ath_txq *mcastq; struct ieee80211_tx_info *info; avp = sc->sc_vaps[if_id]; - mcastq = &avp->av_mcastq; cabq = sc->sc_cabq; ASSERT(avp); @@ -250,11 +195,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) skb_end_pointer(skb) - skb->head, PCI_DMA_TODEVICE); - /* TODO: convert to use ieee80211_get_buffered_bc() */ - /* XXX: spin_lock_bh should not be used here, but sparse bitches - * otherwise. We should fix sparse :) */ - spin_lock_bh(&mcastq->axq_lock); - mcastq_depth = avp->av_mcastq.axq_depth; + skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data); /* * if the CABQ traffic from previous DTIM is pending and the current @@ -268,10 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) cabq_depth = cabq->axq_depth; spin_unlock_bh(&cabq->axq_lock); - if (avp->av_boff.bo_tim) - is_beacon_dtim = avp->av_boff.bo_tim[4] & 1; - - if (mcastq_depth && is_beacon_dtim && cabq_depth) { + if (skb && cabq_depth) { /* * Unlock the cabq lock as ath_tx_draintxq acquires * the lock again which is a common function and that @@ -291,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 * insure cab frames are triggered by this beacon. */ - if (is_beacon_dtim) - trigger_mcastq(ah, mcastq, cabq); + while (skb) { + ath_tx_cabq(sc, skb); + skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data); + } - spin_unlock_bh(&mcastq->axq_lock); return bf; } @@ -426,7 +365,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) * NB: the beacon data buffer must be 32-bit aligned; * we assume the wbuf routines will return us something * 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 */ skb = ieee80211_beacon_get(sc->hw, avp->av_if_data); diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 57645ee83efb..c262ef279ff3 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -533,9 +533,6 @@ int ath_vap_attach(struct ath_softc *sc, /* Set the VAP opmode */ avp->av_opmode = opmode; 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); @@ -575,9 +572,6 @@ int ath_vap_detach(struct ath_softc *sc, int if_id) ath_stoprecv(sc); /* stop recv side */ ath_flushrecv(sc); /* flush recv queue */ - /* Reclaim any pending mcast bufs on the vap. */ - ath_tx_draintxq(sc, &avp->av_mcastq, false); - kfree(avp); sc->sc_vaps[if_id] = NULL; sc->sc_nvaps--; diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index ca7e61353547..de1d12f7c64a 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -568,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_tx_complete(struct ath_softc *sc, struct sk_buff *skb, struct ath_xmit_status *tx_status, struct ath_node *an); +void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb); /**********************/ /* Node / Aggregation */ @@ -713,12 +714,6 @@ struct ath_beacon_config { } 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 ath_beacon_config(struct ath_softc *sc, int if_id); int ath_beaconq_setup(struct ath_hal *ah); @@ -755,10 +750,8 @@ struct ath_vap { struct ieee80211_vif *av_if_data; enum ath9k_opmode av_opmode; /* VAP operational mode */ 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 */ 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_rate_node *rc_node; }; diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 55f48685b5ea..dca00c3a985a 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1362,6 +1362,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) } hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM; diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 04f94d2c8010..a18cea69904c 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -59,79 +59,6 @@ static u32 bits_per_symbol[][2] = { #define IS_HT_RATE(_rate) ((_rate) & 0x80) -/* - * Insert a chain of ath_buf (descriptors) on a multicast txq - * but do NOT start tx DMA on this queue. - * NB: must be called with txq lock held - */ - -static void ath_tx_mcastqaddbuf(struct ath_softc *sc, - struct ath_txq *txq, - struct list_head *head) -{ - struct ath_hal *ah = sc->sc_ah; - struct ath_buf *bf; - - if (list_empty(head)) - return; - - /* - * Insert the frame on the outbound list and - * pass it on to the hardware. - */ - bf = list_first_entry(head, struct ath_buf, list); - - /* - * The CAB queue is started from the SWBA handler since - * frames only go out on DTIM and to avoid possible races. - */ - ath9k_hw_set_interrupts(ah, 0); - - /* - * If there is anything in the mcastq, we want to set - * the "more data" bit in the last item in the queue to - * indicate that there is "more data". It makes sense to add - * it here since you are *always* going to have - * more data when adding to this queue, no matter where - * you call from. - */ - - if (txq->axq_depth) { - struct ath_buf *lbf; - struct ieee80211_hdr *hdr; - - /* - * Add the "more data flag" to the last frame - */ - - lbf = list_entry(txq->axq_q.prev, struct ath_buf, list); - hdr = (struct ieee80211_hdr *) - ((struct sk_buff *)(lbf->bf_mpdu))->data; - hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); - } - - /* - * Now, concat the frame onto the queue - */ - list_splice_tail_init(head, &txq->axq_q); - txq->axq_depth++; - txq->axq_totalqueued++; - txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list); - - DPRINTF(sc, ATH_DBG_QUEUE, - "%s: txq depth = %d\n", __func__, txq->axq_depth); - if (txq->axq_link != NULL) { - *txq->axq_link = bf->bf_daddr; - DPRINTF(sc, ATH_DBG_XMIT, - "%s: link[%u](%p)=%llx (%p)\n", - __func__, - txq->axq_qnum, txq->axq_link, - ito64(bf->bf_daddr), bf->bf_desc); - } - txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link); - ath9k_hw_set_interrupts(ah, sc->sc_imask); -} - /* * Insert a chain of ath_buf (descriptors) on a txq and * assume the descriptors are already chained together by caller. @@ -277,8 +204,6 @@ static int ath_tx_prepare(struct ath_softc *sc, __le16 fc; u8 *qc; - memset(txctl, 0, sizeof(struct ath_tx_control)); - txctl->dev = sc; hdr = (struct ieee80211_hdr *)skb->data; hdrlen = ieee80211_get_hdrlen_from_skb(skb); @@ -329,12 +254,18 @@ static int ath_tx_prepare(struct ath_softc *sc, /* Fill qnum */ - txctl->qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc); - txq = &sc->sc_txq[txctl->qnum]; + if (unlikely(txctl->flags & ATH9K_TXDESC_CAB)) { + txctl->qnum = 0; + txq = sc->sc_cabq; + } else { + txctl->qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc); + txq = &sc->sc_txq[txctl->qnum]; + } spin_lock_bh(&txq->axq_lock); /* Try to avoid running out of descriptors */ - if (txq->axq_depth >= (ATH_TXBUF - 20)) { + if (txq->axq_depth >= (ATH_TXBUF - 20) && + !(txctl->flags & ATH9K_TXDESC_CAB)) { DPRINTF(sc, ATH_DBG_FATAL, "%s: TX queue: %d is full, depth: %d\n", __func__, @@ -354,7 +285,7 @@ static int ath_tx_prepare(struct ath_softc *sc, /* Fill flags */ - txctl->flags = ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ + txctl->flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) txctl->flags |= ATH9K_TXDESC_NOACK; @@ -1982,13 +1913,18 @@ static int ath_tx_start_dma(struct ath_softc *sc, struct list_head bf_head; struct ath_desc *ds; struct ath_hal *ah = sc->sc_ah; - struct ath_txq *txq = &sc->sc_txq[txctl->qnum]; + struct ath_txq *txq; struct ath_tx_info_priv *tx_info_priv; struct ath_rc_series *rcs; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); __le16 fc = hdr->frame_control; + if (unlikely(txctl->flags & ATH9K_TXDESC_CAB)) + txq = sc->sc_cabq; + else + txq = &sc->sc_txq[txctl->qnum]; + /* For each sglist entry, allocate an ath_buf for DMA */ INIT_LIST_HEAD(&bf_head); spin_lock_bh(&sc->sc_txbuflock); @@ -2093,27 +2029,7 @@ static int ath_tx_start_dma(struct ath_softc *sc, bf->bf_tidno = txctl->tidno; } - if (is_multicast_ether_addr(hdr->addr1)) { - struct ath_vap *avp = sc->sc_vaps[txctl->if_id]; - - /* - * When servicing one or more stations in power-save - * mode (or) if there is some mcast data waiting on - * mcast queue (to prevent out of order delivery of - * mcast,bcast packets) multicast frames must be - * buffered until after the beacon. We use the private - * mcast queue for that. - */ - /* XXX? more bit in 802.11 frame header */ - spin_lock_bh(&avp->av_mcastq.axq_lock); - if (txctl->ps || avp->av_mcastq.axq_depth) - ath_tx_mcastqaddbuf(sc, - &avp->av_mcastq, &bf_head); - else - ath_tx_txqaddbuf(sc, txq, &bf_head); - spin_unlock_bh(&avp->av_mcastq.axq_lock); - } else - ath_tx_txqaddbuf(sc, txq, &bf_head); + ath_tx_txqaddbuf(sc, txq, &bf_head); } spin_unlock_bh(&txq->axq_lock); return 0; @@ -2407,6 +2323,7 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb) struct ath_tx_control txctl; int error = 0; + memset(&txctl, 0, sizeof(struct ath_tx_control)); error = ath_tx_prepare(sc, skb, &txctl); if (error == 0) /* @@ -2871,3 +2788,57 @@ void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an) } } } + +void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) +{ + int hdrlen, padsize; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ath_tx_control txctl; + + /* + * 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 */ + hdrlen = ieee80211_get_hdrlen_from_skb(skb); + if (hdrlen & 3) { + padsize = hdrlen % 4; + if (skb_headroom(skb) < padsize) { + DPRINTF(sc, ATH_DBG_XMIT, "%s: TX CABQ padding " + "failed\n", __func__); + dev_kfree_skb_any(skb); + return; + } + skb_push(skb, padsize); + memmove(skb->data, skb->data + padsize, hdrlen); + } + + DPRINTF(sc, ATH_DBG_XMIT, "%s: transmitting CABQ packet, skb: %p\n", + __func__, + skb); + + memset(&txctl, 0, sizeof(struct ath_tx_control)); + txctl.flags = ATH9K_TXDESC_CAB; + if (ath_tx_prepare(sc, skb, &txctl) == 0) { + /* + * Start DMA mapping. + * ath_tx_start_dma() will be called either synchronously + * or asynchrounsly once DMA is complete. + */ + xmit_map_sg(sc, skb, &txctl); + } else { + ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE); + DPRINTF(sc, ATH_DBG_XMIT, "%s: TX CABQ failed\n", __func__); + dev_kfree_skb_any(skb); + } +} + -- cgit v1.2.1 From c83be6885e2f1ee6e0b290b6cfc82014c675e087 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 25 Aug 2008 20:47:29 +0530 Subject: ath9k: Add LED support Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 16 ++--- drivers/net/wireless/ath9k/core.h | 29 ++++++++ drivers/net/wireless/ath9k/hw.c | 33 ++------- drivers/net/wireless/ath9k/main.c | 138 ++++++++++++++++++++++++++++++++++++- drivers/net/wireless/ath9k/reg.h | 6 -- 5 files changed, 176 insertions(+), 46 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 841893b0b4d4..020b97fd208c 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -757,14 +757,11 @@ struct ath9k_node_stats { #define ATH9K_RSSI_EP_MULTIPLIER (1<<7) -enum ath9k_gpio_output_mux_type { - ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT, - ATH9K_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED, - ATH9K_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED, - ATH9K_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED, - ATH9K_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED, - ATH9K_GPIO_OUTPUT_MUX_NUM_ENTRIES -}; +#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 enum { ATH9K_RESET_POWER_ON, @@ -1008,4 +1005,7 @@ void ath9k_hw_get_channel_centers(struct ath_hal *ah, bool ath9k_get_channel_edges(struct ath_hal *ah, u16 flags, u16 *low, 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 diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index de1d12f7c64a..0692fc340268 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -39,6 +39,7 @@ #include #include #include +#include #include "ath9k.h" #include "rc.h" @@ -802,6 +803,27 @@ void ath_slow_ant_div(struct ath_antdiv *antdiv, struct ath_rx_status *rx_stats); 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 */ /********************/ @@ -884,6 +906,7 @@ struct ath_ht_info { #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 ieee80211_hw *hw; @@ -988,6 +1011,12 @@ struct ath_softc { spinlock_t sc_txbuflock; spinlock_t sc_resetlock; 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); diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 47c60acac41f..2578411c6019 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -2800,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, - enum ath9k_gpio_output_mux_type - halSignalType) +void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio, + u32 ah_signal_type) { - u32 ah_signal_type; 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); gpio_shift = 2 * gpio; @@ -2834,16 +2813,12 @@ static bool ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio, AR_GPIO_OE_OUT, (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift), (AR_GPIO_OE_OUT_DRV << gpio_shift)); - - return true; } -static bool ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, - u32 val) +void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val) { REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), AR_GPIO_BIT(gpio)); - return true; } static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio) @@ -5923,7 +5898,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, else 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); diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index dca00c3a985a..996bb9c6540d 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1172,12 +1172,130 @@ enum ath9k_ht_macmode ath_cwm_macmode(struct ath_softc *sc) return sc->sc_ht_info.tx_chan_width; } +/********************************/ +/* LED functions */ +/********************************/ + +static void ath_led_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + 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) { struct ieee80211_hw *hw = sc->hw; DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__); + /* Deinit LED control */ + ath_deinit_leds(sc); + /* Unregister hw */ ieee80211_unregister_hw(hw); @@ -1271,18 +1389,21 @@ static int ath_attach(u16 devid, goto bad; } + /* Initialize LED control */ + ath_init_leds(sc); + /* initialize tx/rx engine */ error = ath_tx_init(sc, ATH_TXBUF); if (error != 0) - goto bad1; + goto detach; error = ath_rx_init(sc, ATH_RXBUF); if (error != 0) - goto bad1; + goto detach; return 0; -bad1: +detach: ath_detach(sc); bad: return error; @@ -1427,6 +1548,10 @@ static void ath_pci_remove(struct pci_dev *pdev) 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_disable_device(pdev); pci_set_power_state(pdev, 3); @@ -1436,6 +1561,8 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state) 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; int err; @@ -1452,6 +1579,11 @@ static int ath_pci_resume(struct pci_dev *pdev) if ((val & 0x0000ff00) != 0) 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; } diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath9k/reg.h index 42b0890a4685..60617ae66209 100644 --- a/drivers/net/wireless/ath9k/reg.h +++ b/drivers/net/wireless/ath9k/reg.h @@ -899,12 +899,6 @@ enum { #define AR_GPIO_OUTPUT_MUX2 0x4064 #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_EEPROM_STATUS_DATA 0x407c -- cgit v1.2.1 From 822ceaefaaaea4bcd7965e3f4b3479e805f7dfa5 Mon Sep 17 00:00:00 2001 From: Sujith Date: Tue, 26 Aug 2008 08:10:29 +0530 Subject: ath9k: Remove more dead code Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 5 ----- drivers/net/wireless/ath9k/beacon.c | 25 ------------------------- drivers/net/wireless/ath9k/hw.h | 4 ---- drivers/net/wireless/ath9k/main.c | 5 ----- 4 files changed, 39 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 020b97fd208c..28b8d84f49b4 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -628,11 +628,6 @@ struct ath9k_country_entry { (IEEE80211_WEP_IVLEN + \ IEEE80211_WEP_KIDLEN + \ IEEE80211_WEP_CRCLEN)) -#define IEEE80211_MAX_LEN (2300 + FCS_LEN + \ - (IEEE80211_WEP_IVLEN + \ - IEEE80211_WEP_KIDLEN + \ - IEEE80211_WEP_CRCLEN)) - #define MAX_RATE_POWER 63 enum ath9k_power_mode { diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index fdbabc180228..c43fd5861163 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -453,31 +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; - pci_unmap_single(sc->pdev, bf->bf_dmacontext, - skb_end_pointer(skb) - skb->head, - PCI_DMA_TODEVICE); - dev_kfree_skb_any(skb); - bf->bf_mpdu = NULL; - } - } -} - /* * Tasklet for Sending Beacons * diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h index 5cb3912ad392..2113818ee934 100644 --- a/drivers/net/wireless/ath9k/hw.h +++ b/drivers/net/wireless/ath9k/hw.h @@ -825,10 +825,6 @@ struct ath_hal_5416 { #define COEF_SCALE_S 24 #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_S 2 diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 996bb9c6540d..dc45eef3289a 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1167,11 +1167,6 @@ int ath_rx_subframe(struct ath_node *an, return 0; } -enum ath9k_ht_macmode ath_cwm_macmode(struct ath_softc *sc) -{ - return sc->sc_ht_info.tx_chan_width; -} - /********************************/ /* LED functions */ /********************************/ -- cgit v1.2.1 From 14cc709f338f44f1ff69fa0b0e35e9de3ee62eb5 Mon Sep 17 00:00:00 2001 From: Sujith Date: Tue, 26 Aug 2008 08:10:49 +0530 Subject: ath9k: Do not update frame's duration field When AR_DurUpdateEna is set, the frame's duration field is updated by the MAC based on the current rate. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.h | 1 - drivers/net/wireless/ath9k/xmit.c | 56 ++++++++------------------------------- 2 files changed, 11 insertions(+), 46 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 0692fc340268..b6b6868195cd 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -516,7 +516,6 @@ struct ath_tx_control { u32 keyix; int min_rate; int mcast_rate; - u16 nextfraglen; struct ath_softc *dev; dma_addr_t dmacontext; }; diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index a18cea69904c..87aebf175737 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -227,7 +227,6 @@ static int ath_tx_prepare(struct ath_softc *sc, } txctl->if_id = 0; - txctl->nextfraglen = 0; txctl->frmlen = skb->len + FCS_LEN - (hdrlen & 3); txctl->txpower = MAX_RATE_POWER; /* FIXME */ @@ -344,51 +343,18 @@ static int ath_tx_prepare(struct ath_softc *sc, } rix = rcs[0].rix; - /* - * Calculate duration. This logically belongs in the 802.11 - * layer but it lacks sufficient information to calculate it. - */ - if ((txctl->flags & ATH9K_TXDESC_NOACK) == 0 && !ieee80211_is_ctl(fc)) { - u16 dur; + if (ieee80211_has_morefrags(fc) || + (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) { /* - * XXX not right with fragmentation. - */ - if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) - dur = rt->info[rix].spAckDuration; - else - dur = rt->info[rix].lpAckDuration; - - if (le16_to_cpu(hdr->frame_control) & - IEEE80211_FCTL_MOREFRAGS) { - dur += dur; /* Add additional 'SIFS + ACK' */ - - /* - ** Compute size of next fragment in order to compute - ** durations needed to update NAV. - ** The last fragment uses the ACK duration only. - ** Add time for next fragment. - */ - dur += ath9k_hw_computetxtime(sc->sc_ah, rt, - txctl->nextfraglen, - rix, - (sc->sc_flags & SC_OP_PREAMBLE_SHORT)); - } - - if (ieee80211_has_morefrags(fc) || - (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) { - /* - ** Force hardware to use computed duration for next - ** fragment by disabling multi-rate retry, which - ** updates duration based on the multi-rate - ** duration table. - */ - rcs[1].tries = rcs[2].tries = rcs[3].tries = 0; - rcs[1].rix = rcs[2].rix = rcs[3].rix = 0; - /* reset tries but keep rate index */ - rcs[0].tries = ATH_TXMAXTRY; - } - - hdr->duration_id = cpu_to_le16(dur); + ** Force hardware to use computed duration for next + ** fragment by disabling multi-rate retry, which + ** updates duration based on the multi-rate + ** duration table. + */ + rcs[1].tries = rcs[2].tries = rcs[3].tries = 0; + rcs[1].rix = rcs[2].rix = rcs[3].rix = 0; + /* reset tries but keep rate index */ + rcs[0].tries = ATH_TXMAXTRY; } /* -- cgit v1.2.1 From 1fe1132bad8e98fa34cfb4a3901340d1214b95d7 Mon Sep 17 00:00:00 2001 From: Sujith Date: Tue, 26 Aug 2008 08:11:06 +0530 Subject: ath9k: Remove sc_lastrx as we don't use it anywhere Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.h | 1 - drivers/net/wireless/ath9k/xmit.c | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index b6b6868195cd..1faa1effa02c 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -970,7 +970,6 @@ struct ath_softc { struct ath_descdma sc_rxdma; int sc_rxbufsize; /* rx size based on mtu */ u32 *sc_rxlink; /* link ptr in last RX desc */ - u64 sc_lastrx; /* tsf of last rx'd frame */ /* TX */ struct list_head sc_txbuf; diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 87aebf175737..3fc6641e8bf7 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -2309,8 +2309,7 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb) void ath_tx_tasklet(struct ath_softc *sc) { - u64 tsf = ath9k_hw_gettsf64(sc->sc_ah); - int i, nacked = 0; + int i; u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1); ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask); @@ -2320,10 +2319,8 @@ void ath_tx_tasklet(struct ath_softc *sc) */ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i))) - nacked += ath_tx_processq(sc, &sc->sc_txq[i]); + ath_tx_processq(sc, &sc->sc_txq[i]); } - if (nacked) - sc->sc_lastrx = tsf; } void ath_tx_draintxq(struct ath_softc *sc, -- cgit v1.2.1 From 5701ed843ea87bf8a1d2c4dee5edcb463558db4a Mon Sep 17 00:00:00 2001 From: Sujith Date: Tue, 26 Aug 2008 08:11:26 +0530 Subject: ath9k: rc.h cleanup Use kernel doc syntax for comments and remove a few unused macros. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/rc.c | 18 ++-- drivers/net/wireless/ath9k/rc.h | 222 +++++++++++++++++++++------------------- 2 files changed, 125 insertions(+), 115 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 1dd7c71daf0a..390019ed398e 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -1141,14 +1141,14 @@ static void ath_rc_ratefind(struct ath_softc *sc, /* * 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 series[], - int *is_probe, - int is_retry) +static 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 series[], + int *is_probe, + int is_retry) { struct ath_vap *avp = ath_rc_priv->avp; @@ -1942,7 +1942,7 @@ static void ath_get_rate(void *priv, struct net_device *dev, struct ath_rate_node *ath_rc_priv; struct ath_node *an; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - int is_probe, chk, ret; + int is_probe = FALSE, chk, ret; s8 lowest_idx; __le16 fc = hdr->frame_control; u8 *qc, tid; diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h index 71aef9c75232..b95b41508b98 100644 --- a/drivers/net/wireless/ath9k/rc.h +++ b/drivers/net/wireless/ath9k/rc.h @@ -71,9 +71,6 @@ enum ieee80211_fixed_rate_mode { */ #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_DS WLAN_RC_PHY_HT_20_DS #define WLAN_PHY_HT_20_DS_HGI WLAN_RC_PHY_HT_20_DS_HGI @@ -102,18 +99,18 @@ enum { WLAN_RC_PHY_MAX }; -#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_20_DS_HGI) \ - || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) -#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_SS_HGI) \ - || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) +#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_20_DS_HGI) \ + || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) +#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_SS_HGI) \ + || (_phy == WLAN_RC_PHY_HT_40_DS_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_40_SS_HGI) \ - || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) + || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ + || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ + || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) #define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS) @@ -135,56 +132,59 @@ enum { #define WLAN_RC_SGI_FLAG (0x04) #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 -/* 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 { int rate_cnt; struct { - int valid; /* Valid for use in rate control */ - int valid_single_stream;/* Valid for use in rate control - for single stream operation */ - u8 phy; /* CCK/OFDM/TURBO/XR */ - u32 ratekbps; /* Rate in Kbits per second */ - u32 user_ratekbps; /* User rate in KBits per second */ - u8 ratecode; /* rate that goes into - hw descriptors */ - u8 short_preamble; /* Mask for enabling short preamble - in rate code for CCK */ - u8 dot11rate; /* Value that goes into supported - rates info element of MLME */ - u8 ctrl_rate; /* Index of next lower basic rate, - used for duration computation */ - int8_t rssi_ack_validmin; /* Rate control related */ - int8_t rssi_ack_deltamin; /* Rate control related */ - 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 */ + int valid; + int valid_single_stream; + u8 phy; + u32 ratekbps; + u32 user_ratekbps; + u8 ratecode; + u8 short_preamble; + u8 dot11rate; + u8 ctrl_rate; + int8_t rssi_ack_validmin; + int8_t rssi_ack_deltamin; + u8 base_index; + u8 cw40index; + u8 sgi_index; + u8 ht_index; + u32 max_4ms_framelen; } info[RATE_TABLE_SIZE]; - u32 probe_interval; /* interval for ratectrl to - probe for other rates */ - u32 rssi_reduce_interval; /* interval for ratectrl - to reduce RSSI */ - u8 initial_ratemax; /* the initial ratemax value used - in ath_rc_sib_update() */ + u32 probe_interval; + u32 rssi_reduce_interval; + u8 initial_ratemax; }; #define ATH_RC_PROBE_ALLOWED 0x00000001 #define ATH_RC_MINRATE_LASTRATE 0x00000002 -#define ATH_RC_SHORT_PREAMBLE 0x00000004 struct ath_rc_series { - u8 rix; - u8 tries; - u8 flags; - u32 max_4ms_framelen; + u8 rix; + u8 tries; + u8 flags; + u32 max_4ms_framelen; }; /* rcs_flags definition */ @@ -201,42 +201,56 @@ struct ath_rc_series { #define MAX_TX_RATE_PHY 48 struct ath_tx_ratectrl_state { - int8_t rssi_thres; /* required rssi for this rate (dB) */ - u8 per; /* recent estimate of packet error rate (%) */ + int8_t rssi_thres; /* required rssi for this rate (dB) */ + 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_state state[MAX_TX_RATE_TBL]; /* state */ - int8_t rssi_last; /* last ack rssi */ - int8_t rssi_last_lookup; /* last ack rssi used for lookup */ - int8_t rssi_last_prev; /* previous last ack rssi */ - int8_t rssi_last_prev2; /* 2nd previous last ack rssi */ - int32_t rssi_sum_cnt; /* count of rssi_sum for averaging */ - int32_t rssi_sum_rate; /* rate that we are averaging */ - int32_t rssi_sum; /* running sum of rssi for averaging */ - u32 valid_txrate_mask; /* mask of valid rates */ - u8 rate_table_size; /* rate table size */ - u8 rate_max; /* max rate that has recently worked */ - u8 probe_rate; /* rate we are probing at */ - u32 rssi_time; /* msec timestamp for last ack rssi */ - u32 rssi_down_time; /* msec timestamp for last down step */ - u32 probe_time; /* msec timestamp for last probe */ - u8 hw_maxretry_pktcnt; /* num packets since we got - HW max retry error */ - 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 */ + struct ath_tx_ratectrl_state state[MAX_TX_RATE_TBL]; + int8_t rssi_last; + int8_t rssi_last_lookup; + int8_t rssi_last_prev; + int8_t rssi_last_prev2; + int32_t rssi_sum_cnt; + int32_t rssi_sum_rate; + int32_t rssi_sum; + u8 rate_table_size; + u8 probe_rate; + u32 rssi_time; + u32 rssi_down_time; + u32 probe_time; + u8 hw_maxretry_pktcnt; + u8 max_valid_rate; + u8 valid_rate_index[MAX_TX_RATE_TBL]; + u32 per_down_time; /* 11n state */ - u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX]; /* valid rate count */ - u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][MAX_TX_RATE_TBL]; - u8 rc_phy_mode; - u8 rate_max_phy; /* Phy index for the max rate */ - u32 rate_max_lastused; /* msec timstamp of when we - last used rateMaxPhy */ - u32 probe_interval; /* interval for ratectrl to probe - for other rates */ + u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX]; + u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][MAX_TX_RATE_TBL]; + u8 rc_phy_mode; + u8 rate_max_phy; + u32 probe_interval; }; struct ath_rateset { @@ -248,29 +262,32 @@ struct ath_rateset { struct ath_rate_softc { /* phy tables that contain rate control data */ 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 */ struct ath_rate_node { - struct ath_tx_ratectrl tx_ratectrl; /* rate control state proper */ - u32 prev_data_rix; /* rate idx of last data frame */ + struct ath_tx_ratectrl tx_ratectrl; - /* map of rate ix -> negotiated rate set ix */ - u8 rixmap[MAX_TX_RATE_TBL]; + /* rate idx of last data frame */ + u32 prev_data_rix; - /* map of ht rate ix -> negotiated rate set ix */ - u8 ht_rixmap[MAX_TX_RATE_TBL]; + /* ht capabilities */ + u8 ht_cap; - u8 ht_cap; /* ht capabilities */ - u8 ant_tx; /* current transmit antenna */ + /* When TRUE, only single stream Tx possible */ + u8 single_stream; - u8 single_stream; /* When TRUE, only single - stream Tx possible */ - struct ath_rateset neg_rates; /* Negotiated rates */ - struct ath_rateset neg_ht_rates; /* Negotiated HT rates */ - struct ath_rate_softc *asc; /* back pointer to atheros softc */ - struct ath_vap *avp; /* back pointer to vap */ + /* Negotiated rates */ + struct ath_rateset neg_rates; + + /* Negotiated HT rates */ + struct ath_rateset neg_ht_rates; + + struct ath_rate_softc *asc; + struct ath_vap *avp; }; /* Driver data of ieee80211_tx_info */ @@ -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_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. */ u8 ath_rate_findrateix(struct ath_softc *sc, - u8 dot11_rate); + u8 dot11_rate); /* Routines to register/unregister rate control algorithm */ int ath_rate_control_register(void); -- cgit v1.2.1 From f59ac0481660e66cec67f1d6b024e78b9dc715fe Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Fri, 29 Aug 2008 16:26:43 -0700 Subject: cfg80211: keep track of supported interface modes It is obviously good for userspace to know up front which interface modes a given piece of hardware might support (even if adding such an interface might fail later because of concurrency issues), so let's make cfg80211 aware of that. For good measure, disallow adding interfaces in all other modes so drivers don't forget to announce support for one mode when they add it. Signed-off-by: Johannes Berg Signed-off-by: Stephen Blackheath Signed-off-by: Ivo van Doorn Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index dc45eef3289a..39a4a70d0130 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1482,6 +1482,11 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM; + hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); + SET_IEEE80211_DEV(hw, &pdev->dev); pci_set_drvdata(pdev, hw); -- cgit v1.2.1 From d203b8ef8e5acf9dad5a53d7067ef146e6b2e837 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 2 Sep 2008 12:07:56 -0700 Subject: ath9k: uses/needs led_classdev_[un]register ath9k uses LED classdev functions, so it needs to either select or depend on them. This patch uses the same selects that ath5k uses... drivers/built-in.o: In function `ath_unregister_led': main.c:(.text+0x138c1d): undefined reference to `led_classdev_unregister' drivers/built-in.o: In function `ath_register_led': main.c:(.text+0x139c16): undefined reference to `led_classdev_register' make[1]: *** [.tmp_vmlinux1] Error 1 Signed-off-by: Randy Dunlap cc: Jouni Malinen Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/Kconfig | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/Kconfig b/drivers/net/wireless/ath9k/Kconfig index 9e19dcceb3a2..80a692430413 100644 --- a/drivers/net/wireless/ath9k/Kconfig +++ b/drivers/net/wireless/ath9k/Kconfig @@ -1,6 +1,9 @@ config ATH9K tristate "Atheros 802.11n wireless cards support" depends on PCI && MAC80211 && WLAN_80211 + select MAC80211_LEDS + select LEDS_CLASS + select NEW_LEDS ---help--- This module adds support for wireless adapters based on Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets. -- cgit v1.2.1 From 00c5ae2fa0f8191a1b204e71f0ee11359e3b2c06 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 3 Sep 2008 11:26:42 +0800 Subject: mac80211: change MIMO_PS to SM_PS This patch follows 11n spec naming more rigorously replacing MIMO_PS with SM_PS (Spatial Multiplexing Power Save). (Originally submitted as 4 patches, "mac80211: change MIMO_PS to SM_PS", "iwlwifi: change MIMO_PS to SM_PS", "ath9k: change MIMO_PS to SM_PS", and "iwlwifi: remove double definition of SM PS". -- JWL) Signed-off-by: Ron Rindjunsky Signed-off-by: Tomas Winkler Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 245b7308a9ad..57d7cc87cb0f 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -224,7 +224,7 @@ static void setup_ht_cap(struct ieee80211_ht_info *ht_info) ht_info->ht_supported = 1; ht_info->cap = (u16)IEEE80211_HT_CAP_SUP_WIDTH - |(u16)IEEE80211_HT_CAP_MIMO_PS + |(u16)IEEE80211_HT_CAP_SM_PS |(u16)IEEE80211_HT_CAP_SGI_40 |(u16)IEEE80211_HT_CAP_DSSSCCK40; -- cgit v1.2.1 From 8feceb67929bd23bfca58d5f49df93d7fc315bb1 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 10 Sep 2008 18:49:27 +0530 Subject: ath9k: Re-order functions in main.c Some of the functions in main.c are re-ordered in such a way that all local functions are defined before mac80211 and pci callbacks. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 1722 ++++++++++++++++++------------------- 1 file changed, 861 insertions(+), 861 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 57d7cc87cb0f..07e5b5d877b6 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -325,1087 +325,1087 @@ static u8 parse_mpdudensity(u8 mpdudensity) } } -static int ath9k_start(struct ieee80211_hw *hw) +static void ath9k_ht_conf(struct ath_softc *sc, + struct ieee80211_bss_conf *bss_conf) { - struct ath_softc *sc = hw->priv; - struct ieee80211_channel *curchan = hw->conf.channel; - int error = 0, pos; - - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Starting driver with " - "initial channel: %d MHz\n", __func__, curchan->center_freq); +#define IEEE80211_HT_CAP_40MHZ_INTOLERANT BIT(14) + struct ath_ht_info *ht_info = &sc->sc_ht_info; - /* setup initial channel */ + if (bss_conf->assoc_ht) { + ht_info->ext_chan_offset = + bss_conf->ht_bss_conf->bss_cap & + IEEE80211_HT_IE_CHA_SEC_OFFSET; - pos = ath_get_channel(sc, curchan); - if (pos == -1) { - DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__); - return -EINVAL; - } + if (!(bss_conf->ht_conf->cap & + IEEE80211_HT_CAP_40MHZ_INTOLERANT) && + (bss_conf->ht_bss_conf->bss_cap & + IEEE80211_HT_IE_CHA_WIDTH)) + ht_info->tx_chan_width = ATH9K_HT_MACMODE_2040; + else + ht_info->tx_chan_width = ATH9K_HT_MACMODE_20; - sc->sc_ah->ah_channels[pos].chanmode = - (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A; + ath9k_hw_set11nmac2040(sc->sc_ah, ht_info->tx_chan_width); + ht_info->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + + bss_conf->ht_conf->ampdu_factor); + ht_info->mpdudensity = + parse_mpdudensity(bss_conf->ht_conf->ampdu_density); - /* open ath_dev */ - error = ath_open(sc, &sc->sc_ah->ah_channels[pos]); - if (error) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to complete ath_open\n", __func__); - return error; } - ieee80211_wake_queues(hw); - return 0; +#undef IEEE80211_HT_CAP_40MHZ_INTOLERANT } -static int ath9k_tx(struct ieee80211_hw *hw, - struct sk_buff *skb) +static void ath9k_bss_assoc_info(struct ath_softc *sc, + struct ieee80211_bss_conf *bss_conf) { - struct ath_softc *sc = hw->priv; - 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); - } + struct ieee80211_hw *hw = sc->hw; + struct ieee80211_channel *curchan = hw->conf.channel; + struct ath_vap *avp; + int pos; + DECLARE_MAC_BUF(mac); - /* Add the padding after the header if this is not already done */ - hdrlen = ieee80211_get_hdrlen_from_skb(skb); - if (hdrlen & 3) { - padsize = hdrlen % 4; - if (skb_headroom(skb) < padsize) - return -1; - skb_push(skb, padsize); - memmove(skb->data, skb->data + padsize, hdrlen); - } + if (bss_conf->assoc) { + DPRINTF(sc, ATH_DBG_CONFIG, "%s: Bss Info ASSOC %d\n", + __func__, + bss_conf->aid); - DPRINTF(sc, ATH_DBG_XMIT, "%s: transmitting packet, skb: %p\n", - __func__, - skb); + avp = sc->sc_vaps[0]; + if (avp == NULL) { + DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n", + __func__); + return; + } - if (ath_tx_start(sc, skb) != 0) { - DPRINTF(sc, ATH_DBG_XMIT, "%s: TX failed\n", __func__); - dev_kfree_skb_any(skb); - /* FIXME: Check for proper return value from ATH_DEV */ - return 0; - } + /* New association, store aid */ + if (avp->av_opmode == ATH9K_M_STA) { + sc->sc_curaid = bss_conf->aid; + ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid, + sc->sc_curaid); + } - return 0; -} + /* Configure the beacon */ + ath_beacon_config(sc, 0); + sc->sc_flags |= SC_OP_BEACONS; -static void ath9k_stop(struct ieee80211_hw *hw) -{ - struct ath_softc *sc = hw->priv; - int error; + /* Reset rssi stats */ + sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER; + sc->sc_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER; + sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER; + sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Driver halt\n", __func__); + /* Update chainmask */ + ath_update_chainmask(sc, bss_conf->assoc_ht); - error = ath_suspend(sc); - if (error) DPRINTF(sc, ATH_DBG_CONFIG, - "%s: Device is no longer present\n", __func__); + "%s: bssid %s aid 0x%x\n", + __func__, + print_mac(mac, sc->sc_curbssid), sc->sc_curaid); - ieee80211_stop_queues(hw); -} + DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n", + __func__, + curchan->center_freq); -static int ath9k_add_interface(struct ieee80211_hw *hw, - struct ieee80211_if_init_conf *conf) -{ - struct ath_softc *sc = hw->priv; - int error, ic_opmode = 0; + pos = ath_get_channel(sc, curchan); + if (pos == -1) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: Invalid channel\n", __func__); + return; + } - /* Support only vap for now */ + if (hw->conf.ht_conf.ht_supported) + sc->sc_ah->ah_channels[pos].chanmode = + ath_get_extchanmode(sc, curchan); + else + sc->sc_ah->ah_channels[pos].chanmode = + (curchan->band == IEEE80211_BAND_2GHZ) ? + CHANNEL_G : CHANNEL_A; - if (sc->sc_nvaps) - return -ENOBUFS; + /* set h/w channel */ + if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) + DPRINTF(sc, ATH_DBG_FATAL, + "%s: Unable to set channel\n", + __func__); - switch (conf->type) { - case IEEE80211_IF_TYPE_STA: - ic_opmode = ATH9K_M_STA; - break; - case IEEE80211_IF_TYPE_IBSS: - ic_opmode = ATH9K_M_IBSS; - break; - case IEEE80211_IF_TYPE_AP: - ic_opmode = ATH9K_M_HOSTAP; - break; - default: - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Interface type %d not yet supported\n", - __func__, conf->type); - return -EOPNOTSUPP; + ath_rate_newstate(sc, avp); + /* Update ratectrl about the new state */ + ath_rc_node_update(hw, avp->rc_node); + } else { + DPRINTF(sc, ATH_DBG_CONFIG, + "%s: Bss Info DISSOC\n", __func__); + sc->sc_curaid = 0; } +} - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a VAP of type: %d\n", - __func__, - ic_opmode); +void ath_get_beaconconfig(struct ath_softc *sc, + int if_id, + struct ath_beacon_config *conf) +{ + struct ieee80211_hw *hw = sc->hw; - error = ath_vap_attach(sc, 0, conf->vif, ic_opmode); - if (error) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to attach vap, error: %d\n", - __func__, error); - return error; - } + /* fill in beacon config data */ - return 0; + conf->beacon_interval = hw->conf.beacon_int; + conf->listen_interval = 100; + conf->dtim_count = 1; + conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval; } -static void ath9k_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_if_init_conf *conf) +void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, + struct ath_xmit_status *tx_status, struct ath_node *an) { - struct ath_softc *sc = hw->priv; - struct ath_vap *avp; - int error; + struct ieee80211_hw *hw = sc->hw; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach VAP\n", __func__); + DPRINTF(sc, ATH_DBG_XMIT, + "%s: TX complete: skb: %p\n", __func__, skb); - avp = sc->sc_vaps[0]; - if (avp == NULL) { - DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n", - __func__); - return; + if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || + tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { + /* free driver's private data area of tx_info */ + if (tx_info->driver_data[0] != NULL) + kfree(tx_info->driver_data[0]); + tx_info->driver_data[0] = NULL; } -#ifdef CONFIG_SLOW_ANT_DIV - ath_slow_ant_div_stop(&sc->sc_antdiv); -#endif - - /* Update ratectrl */ - ath_rate_newstate(sc, avp); + if (tx_status->flags & ATH_TX_BAR) { + tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; + tx_status->flags &= ~ATH_TX_BAR; + } - /* Reclaim beacon resources */ - 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); - ath_beacon_return(sc, avp); + 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; } - /* Set interrupt mask */ - sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); - ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask & ~ATH9K_INT_GLOBAL); - sc->sc_flags &= ~SC_OP_BEACONS; + tx_info->status.retry_count = tx_status->retries; - error = ath_vap_detach(sc, 0); - if (error) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to detach vap, error: %d\n", - __func__, error); + ieee80211_tx_status(hw, skb); + if (an) + ath_node_put(sc, an, ATH9K_BH_STATUS_CHANGE); } -static int ath9k_config(struct ieee80211_hw *hw, - struct ieee80211_conf *conf) +int _ath_rx_indicate(struct ath_softc *sc, + struct sk_buff *skb, + struct ath_recv_status *status, + u16 keyix) { - struct ath_softc *sc = hw->priv; - struct ieee80211_channel *curchan = hw->conf.channel; - int pos; - - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n", - __func__, - curchan->center_freq); + struct ieee80211_hw *hw = sc->hw; + struct ath_node *an = NULL; + struct ieee80211_rx_status rx_status; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + int hdrlen = ieee80211_get_hdrlen_from_skb(skb); + int padsize; + enum ATH_RX_TYPE st; - pos = ath_get_channel(sc, curchan); - if (pos == -1) { - DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__); - return -EINVAL; + /* see if any padding is done by the hw and remove it */ + if (hdrlen & 3) { + padsize = hdrlen % 4; + memmove(skb->data + padsize, skb->data, hdrlen); + skb_pull(skb, padsize); } - sc->sc_ah->ah_channels[pos].chanmode = - (curchan->band == IEEE80211_BAND_2GHZ) ? - CHANNEL_G : CHANNEL_A; + /* Prepare rx status */ + ath9k_rx_prepare(sc, skb, status, &rx_status); - if (sc->sc_curaid && hw->conf.ht_conf.ht_supported) - sc->sc_ah->ah_channels[pos].chanmode = - ath_get_extchanmode(sc, curchan); + if (!(keyix == ATH9K_RXKEYIX_INVALID) && + !(status->flags & ATH_RX_DECRYPT_ERROR)) { + rx_status.flag |= RX_FLAG_DECRYPTED; + } else if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) + && !(status->flags & ATH_RX_DECRYPT_ERROR) + && skb->len >= hdrlen + 4) { + keyix = skb->data[hdrlen + 3] >> 6; - sc->sc_config.txpowlimit = 2 * conf->power_level; + if (test_bit(keyix, sc->sc_keymap)) + rx_status.flag |= RX_FLAG_DECRYPTED; + } - /* set h/w channel */ - if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) - DPRINTF(sc, ATH_DBG_FATAL, "%s: Unable to set channel\n", - __func__); + spin_lock_bh(&sc->node_lock); + an = ath_node_find(sc, hdr->addr2); + spin_unlock_bh(&sc->node_lock); + + if (an) { + ath_rx_input(sc, an, + hw->conf.ht_conf.ht_supported, + skb, status, &st); + } + if (!an || (st != ATH_RX_CONSUMED)) + __ieee80211_rx(hw, skb, &rx_status); return 0; } -static int ath9k_config_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_if_conf *conf) +int ath_rx_subframe(struct ath_node *an, + struct sk_buff *skb, + struct ath_recv_status *status) { - struct ath_softc *sc = hw->priv; - struct ath_hal *ah = sc->sc_ah; - struct ath_vap *avp; - u32 rfilt = 0; - int error, i; - DECLARE_MAC_BUF(mac); - - avp = sc->sc_vaps[0]; - if (avp == NULL) { - DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n", - __func__); - 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) && - !is_zero_ether_addr(conf->bssid)) { - switch (vif->type) { - case IEEE80211_IF_TYPE_STA: - case IEEE80211_IF_TYPE_IBSS: - /* Update ratectrl about the new state */ - ath_rate_newstate(sc, avp); - - /* Set BSSID */ - memcpy(sc->sc_curbssid, conf->bssid, ETH_ALEN); - sc->sc_curaid = 0; - ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid, - sc->sc_curaid); + struct ath_softc *sc = an->an_sc; + struct ieee80211_hw *hw = sc->hw; + struct ieee80211_rx_status rx_status; - /* Set aggregation protection mode parameters */ - sc->sc_config.ath_aggr_prot = 0; + /* Prepare rx status */ + ath9k_rx_prepare(sc, skb, status, &rx_status); + if (!(status->flags & ATH_RX_DECRYPT_ERROR)) + rx_status.flag |= RX_FLAG_DECRYPTED; - /* - * Reset our TSF so that its value is lower than the - * beacon that we are trying to catch. - * Only then hw will update its TSF register with the - * new beacon. Reset the TSF before setting the BSSID - * to avoid allowing in any frames that would update - * our TSF only to have us clear it - * immediately thereafter. - */ - ath9k_hw_reset_tsf(sc->sc_ah); + __ieee80211_rx(hw, skb, &rx_status); - /* Disable BMISS interrupt when we're not associated */ - ath9k_hw_set_interrupts(sc->sc_ah, - sc->sc_imask & - ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS)); - sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); + return 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); +/********************************/ +/* LED functions */ +/********************************/ - /* need to reconfigure the beacon */ - sc->sc_flags &= ~SC_OP_BEACONS ; +static void ath_led_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); + struct ath_softc *sc = led->sc; - break; - default: - break; - } + 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; } +} - if ((conf->changed & IEEE80211_IFCC_BEACON) && - ((vif->type == IEEE80211_IF_TYPE_IBSS) || - (vif->type == IEEE80211_IF_TYPE_AP))) { - /* - * Allocate and setup the beacon frame. - * - * Stop any previous beacon DMA. This may be - * necessary, for example, when an ibss merge - * causes reconfiguration; we may be called - * with beacon transmission active. - */ - ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); +static int ath_register_led(struct ath_softc *sc, struct ath_led *led, + char *trigger) +{ + int ret; - error = ath_beacon_alloc(sc, 0); - if (error != 0) - return error; + led->sc = sc; + led->led_cdev.name = led->name; + led->led_cdev.default_trigger = trigger; + led->led_cdev.brightness_set = ath_led_brightness; - ath_beacon_sync(sc, 0); - } + 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; +} - /* Check for WLAN_CAPABILITY_PRIVACY ? */ - if ((avp->av_opmode != IEEE80211_IF_TYPE_STA)) { - for (i = 0; i < IEEE80211_WEP_NKID; i++) - if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i)) - ath9k_hw_keysetmac(sc->sc_ah, - (u16)i, - sc->sc_curbssid); +static void ath_unregister_led(struct ath_led *led) +{ + if (led->registered) { + led_classdev_unregister(&led->led_cdev); + led->registered = 0; } - - /* Only legacy IBSS for now */ - if (vif->type == IEEE80211_IF_TYPE_IBSS) - ath_update_chainmask(sc, 0); - - return 0; } -#define SUPPORTED_FILTERS \ - (FIF_PROMISC_IN_BSS | \ - FIF_ALLMULTI | \ - FIF_CONTROL | \ - FIF_OTHER_BSS | \ - FIF_BCN_PRBRESP_PROMISC | \ - FIF_FCSFAIL) - -/* FIXME: sc->sc_full_reset ? */ -static void ath9k_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, - int mc_count, - struct dev_mc_list *mclist) +static void ath_deinit_leds(struct ath_softc *sc) { - struct ath_softc *sc = hw->priv; - u32 rfilt; + 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); +} - changed_flags &= SUPPORTED_FILTERS; - *total_flags &= SUPPORTED_FILTERS; +static void ath_init_leds(struct ath_softc *sc) +{ + char *trigger; + int ret; - sc->rx_filter = *total_flags; - rfilt = ath_calcrxfilter(sc); - ath9k_hw_setrxfilter(sc->sc_ah, rfilt); + /* 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); - if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { - if (*total_flags & FIF_BCN_PRBRESP_PROMISC) - ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0); - } + 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; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set HW RX filter: 0x%x\n", - __func__, sc->rx_filter); -} + 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; -static void ath9k_sta_notify(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum sta_notify_cmd cmd, - const u8 *addr) -{ - struct ath_softc *sc = hw->priv; - struct ath_node *an; - unsigned long flags; - DECLARE_MAC_BUF(mac); + 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; - spin_lock_irqsave(&sc->node_lock, flags); - an = ath_node_find(sc, (u8 *) addr); - spin_unlock_irqrestore(&sc->node_lock, flags); + 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; - switch (cmd) { - case STA_NOTIFY_ADD: - spin_lock_irqsave(&sc->node_lock, flags); - if (!an) { - ath_node_attach(sc, (u8 *)addr, 0); - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a node: %s\n", - __func__, - print_mac(mac, addr)); - } else { - ath_node_get(sc, (u8 *)addr); - } - spin_unlock_irqrestore(&sc->node_lock, flags); - break; - case STA_NOTIFY_REMOVE: - if (!an) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Removal of a non-existent node\n", - __func__); - else { - ath_node_put(sc, an, ATH9K_BH_STATUS_INTACT); - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Put a node: %s\n", - __func__, - print_mac(mac, addr)); - } - break; - default: - break; - } + return; + +fail: + ath_deinit_leds(sc); } -static int ath9k_conf_tx(struct ieee80211_hw *hw, - u16 queue, - const struct ieee80211_tx_queue_params *params) +static int ath_detach(struct ath_softc *sc) { - struct ath_softc *sc = hw->priv; - struct ath9k_tx_queue_info qi; - int ret = 0, qnum; + struct ieee80211_hw *hw = sc->hw; - if (queue >= WME_NUM_AC) - return 0; + DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__); - qi.tqi_aifs = params->aifs; - qi.tqi_cwmin = params->cw_min; - qi.tqi_cwmax = params->cw_max; - qi.tqi_burstTime = params->txop; - qnum = ath_get_hal_qnum(queue, sc); + /* Deinit LED control */ + ath_deinit_leds(sc); - DPRINTF(sc, ATH_DBG_CONFIG, - "%s: Configure tx [queue/halq] [%d/%d], " - "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", - __func__, - queue, - qnum, - params->aifs, - params->cw_min, - params->cw_max, - params->txop); + /* Unregister hw */ - ret = ath_txq_update(sc, qnum, &qi); - if (ret) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: TXQ Update failed\n", __func__); + ieee80211_unregister_hw(hw); - return ret; -} + /* unregister Rate control */ + ath_rate_control_unregister(); -static int ath9k_set_key(struct ieee80211_hw *hw, - enum set_key_cmd cmd, - const u8 *local_addr, - const u8 *addr, - struct ieee80211_key_conf *key) -{ - struct ath_softc *sc = hw->priv; - int ret = 0; + /* tx/rx cleanup */ - DPRINTF(sc, ATH_DBG_KEYCACHE, " %s: Set HW Key\n", __func__); + ath_rx_cleanup(sc); + ath_tx_cleanup(sc); - switch (cmd) { - case SET_KEY: - ret = ath_key_config(sc, addr, key); - if (!ret) { - set_bit(key->keyidx, sc->sc_keymap); - key->hw_key_idx = key->keyidx; - /* push IV and Michael MIC generation to stack */ - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - if (key->alg == ALG_TKIP) - key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - } - break; - case DISABLE_KEY: - ath_key_delete(sc, key); - clear_bit(key->keyidx, sc->sc_keymap); - sc->sc_keytype = ATH9K_CIPHER_CLR; - break; - default: - ret = -EINVAL; - } + /* Deinit */ - return ret; + ath_deinit(sc); + + return 0; } -static void ath9k_ht_conf(struct ath_softc *sc, - struct ieee80211_bss_conf *bss_conf) +static int ath_attach(u16 devid, + struct ath_softc *sc) { -#define IEEE80211_HT_CAP_40MHZ_INTOLERANT BIT(14) - struct ath_ht_info *ht_info = &sc->sc_ht_info; - - if (bss_conf->assoc_ht) { - ht_info->ext_chan_offset = - bss_conf->ht_bss_conf->bss_cap & - IEEE80211_HT_IE_CHA_SEC_OFFSET; + struct ieee80211_hw *hw = sc->hw; + int error = 0; - if (!(bss_conf->ht_conf->cap & - IEEE80211_HT_CAP_40MHZ_INTOLERANT) && - (bss_conf->ht_bss_conf->bss_cap & - IEEE80211_HT_IE_CHA_WIDTH)) - ht_info->tx_chan_width = ATH9K_HT_MACMODE_2040; - else - ht_info->tx_chan_width = ATH9K_HT_MACMODE_20; + DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach ATH hw\n", __func__); - ath9k_hw_set11nmac2040(sc->sc_ah, ht_info->tx_chan_width); - ht_info->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + - bss_conf->ht_conf->ampdu_factor); - ht_info->mpdudensity = - parse_mpdudensity(bss_conf->ht_conf->ampdu_density); + error = ath_init(devid, sc); + if (error != 0) + return error; - } + /* Init nodes */ -#undef IEEE80211_HT_CAP_40MHZ_INTOLERANT -} + INIT_LIST_HEAD(&sc->node_list); + spin_lock_init(&sc->node_lock); -static void ath9k_bss_assoc_info(struct ath_softc *sc, - struct ieee80211_bss_conf *bss_conf) -{ - struct ieee80211_hw *hw = sc->hw; - struct ieee80211_channel *curchan = hw->conf.channel; - struct ath_vap *avp; - int pos; - DECLARE_MAC_BUF(mac); + /* get mac address from hardware and set in mac80211 */ - if (bss_conf->assoc) { - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Bss Info ASSOC %d\n", - __func__, - bss_conf->aid); + SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr); - avp = sc->sc_vaps[0]; - if (avp == NULL) { - DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n", - __func__); - return; - } + /* setup channels and rates */ - /* New association, store aid */ - if (avp->av_opmode == ATH9K_M_STA) { - sc->sc_curaid = bss_conf->aid; - ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid, - sc->sc_curaid); - } + sc->sbands[IEEE80211_BAND_2GHZ].channels = + sc->channels[IEEE80211_BAND_2GHZ]; + sc->sbands[IEEE80211_BAND_2GHZ].bitrates = + sc->rates[IEEE80211_BAND_2GHZ]; + sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; - /* Configure the beacon */ - ath_beacon_config(sc, 0); - sc->sc_flags |= SC_OP_BEACONS; + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) + /* Setup HT capabilities for 2.4Ghz*/ + setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_info); - /* Reset rssi stats */ - sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER; - sc->sc_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER; - sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER; - sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER; + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = + &sc->sbands[IEEE80211_BAND_2GHZ]; - /* Update chainmask */ - ath_update_chainmask(sc, bss_conf->assoc_ht); + if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) { + sc->sbands[IEEE80211_BAND_5GHZ].channels = + sc->channels[IEEE80211_BAND_5GHZ]; + sc->sbands[IEEE80211_BAND_5GHZ].bitrates = + sc->rates[IEEE80211_BAND_5GHZ]; + sc->sbands[IEEE80211_BAND_5GHZ].band = + IEEE80211_BAND_5GHZ; - DPRINTF(sc, ATH_DBG_CONFIG, - "%s: bssid %s aid 0x%x\n", - __func__, - print_mac(mac, sc->sc_curbssid), sc->sc_curaid); + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) + /* Setup HT capabilities for 5Ghz*/ + setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_info); - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n", - __func__, - curchan->center_freq); + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &sc->sbands[IEEE80211_BAND_5GHZ]; + } - pos = ath_get_channel(sc, curchan); - if (pos == -1) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Invalid channel\n", __func__); - return; - } + /* FIXME: Have to figure out proper hw init values later */ - if (hw->conf.ht_conf.ht_supported) - sc->sc_ah->ah_channels[pos].chanmode = - ath_get_extchanmode(sc, curchan); - else - sc->sc_ah->ah_channels[pos].chanmode = - (curchan->band == IEEE80211_BAND_2GHZ) ? - CHANNEL_G : CHANNEL_A; + hw->queues = 4; + hw->ampdu_queues = 1; - /* set h/w channel */ - if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to set channel\n", - __func__); + /* Register rate control */ + hw->rate_control_algorithm = "ath9k_rate_control"; + error = ath_rate_control_register(); + if (error != 0) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: Unable to register rate control " + "algorithm:%d\n", __func__, error); + ath_rate_control_unregister(); + goto bad; + } - ath_rate_newstate(sc, avp); - /* Update ratectrl about the new state */ - ath_rc_node_update(hw, avp->rc_node); - } else { - DPRINTF(sc, ATH_DBG_CONFIG, - "%s: Bss Info DISSOC\n", __func__); - sc->sc_curaid = 0; + error = ieee80211_register_hw(hw); + if (error != 0) { + ath_rate_control_unregister(); + goto bad; } + + /* Initialize LED control */ + ath_init_leds(sc); + + /* initialize tx/rx engine */ + + error = ath_tx_init(sc, ATH_TXBUF); + if (error != 0) + goto detach; + + error = ath_rx_init(sc, ATH_RXBUF); + if (error != 0) + goto detach; + + return 0; +detach: + ath_detach(sc); +bad: + return error; } -static void ath9k_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changed) +static int ath9k_start(struct ieee80211_hw *hw) { struct ath_softc *sc = hw->priv; + struct ieee80211_channel *curchan = hw->conf.channel; + int error = 0, pos; - if (changed & BSS_CHANGED_ERP_PREAMBLE) { - DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed PREAMBLE %d\n", - __func__, - bss_conf->use_short_preamble); - if (bss_conf->use_short_preamble) - sc->sc_flags |= SC_OP_PREAMBLE_SHORT; - else - sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT; - } + DPRINTF(sc, ATH_DBG_CONFIG, "%s: Starting driver with " + "initial channel: %d MHz\n", __func__, curchan->center_freq); - if (changed & BSS_CHANGED_ERP_CTS_PROT) { - DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed CTS PROT %d\n", - __func__, - bss_conf->use_cts_prot); - if (bss_conf->use_cts_prot && - hw->conf.channel->band != IEEE80211_BAND_5GHZ) - sc->sc_flags |= SC_OP_PROTECT_ENABLE; - else - sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; - } + /* setup initial channel */ - if (changed & BSS_CHANGED_HT) { - DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed HT %d\n", - __func__, - bss_conf->assoc_ht); - ath9k_ht_conf(sc, bss_conf); + pos = ath_get_channel(sc, curchan); + if (pos == -1) { + DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__); + return -EINVAL; } - if (changed & BSS_CHANGED_ASSOC) { - DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed ASSOC %d\n", - __func__, - bss_conf->assoc); - ath9k_bss_assoc_info(sc, bss_conf); + sc->sc_ah->ah_channels[pos].chanmode = + (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A; + + /* open ath_dev */ + error = ath_open(sc, &sc->sc_ah->ah_channels[pos]); + if (error) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: Unable to complete ath_open\n", __func__); + return error; } + + ieee80211_wake_queues(hw); + return 0; } -static u64 ath9k_get_tsf(struct ieee80211_hw *hw) +static int ath9k_tx(struct ieee80211_hw *hw, + struct sk_buff *skb) { - u64 tsf; struct ath_softc *sc = hw->priv; - struct ath_hal *ah = sc->sc_ah; + int hdrlen, padsize; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - tsf = ath9k_hw_gettsf64(ah); + /* + * 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); + } - return tsf; + /* Add the padding after the header if this is not already done */ + hdrlen = ieee80211_get_hdrlen_from_skb(skb); + if (hdrlen & 3) { + padsize = hdrlen % 4; + if (skb_headroom(skb) < padsize) + return -1; + skb_push(skb, padsize); + memmove(skb->data, skb->data + padsize, hdrlen); + } + + DPRINTF(sc, ATH_DBG_XMIT, "%s: transmitting packet, skb: %p\n", + __func__, + skb); + + if (ath_tx_start(sc, skb) != 0) { + DPRINTF(sc, ATH_DBG_XMIT, "%s: TX failed\n", __func__); + dev_kfree_skb_any(skb); + /* FIXME: Check for proper return value from ATH_DEV */ + return 0; + } + + return 0; } -static void ath9k_reset_tsf(struct ieee80211_hw *hw) +static void ath9k_stop(struct ieee80211_hw *hw) { struct ath_softc *sc = hw->priv; - struct ath_hal *ah = sc->sc_ah; + int error; - ath9k_hw_reset_tsf(ah); + DPRINTF(sc, ATH_DBG_CONFIG, "%s: Driver halt\n", __func__); + + error = ath_suspend(sc); + if (error) + DPRINTF(sc, ATH_DBG_CONFIG, + "%s: Device is no longer present\n", __func__); + + ieee80211_stop_queues(hw); } -static int ath9k_ampdu_action(struct ieee80211_hw *hw, - enum ieee80211_ampdu_mlme_action action, - const u8 *addr, - u16 tid, - u16 *ssn) +static int ath9k_add_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) { struct ath_softc *sc = hw->priv; - int ret = 0; + int error, ic_opmode = 0; - switch (action) { - case IEEE80211_AMPDU_RX_START: - ret = ath_rx_aggr_start(sc, addr, tid, ssn); - if (ret < 0) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to start RX aggregation\n", - __func__); - break; - case IEEE80211_AMPDU_RX_STOP: - ret = ath_rx_aggr_stop(sc, addr, tid); - if (ret < 0) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to stop RX aggregation\n", - __func__); + /* Support only vap for now */ + + if (sc->sc_nvaps) + return -ENOBUFS; + + switch (conf->type) { + case IEEE80211_IF_TYPE_STA: + ic_opmode = ATH9K_M_STA; break; - case IEEE80211_AMPDU_TX_START: - ret = ath_tx_aggr_start(sc, addr, tid, ssn); - if (ret < 0) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to start TX aggregation\n", - __func__); - else - ieee80211_start_tx_ba_cb_irqsafe(hw, (u8 *)addr, tid); + case IEEE80211_IF_TYPE_IBSS: + ic_opmode = ATH9K_M_IBSS; break; - case IEEE80211_AMPDU_TX_STOP: - ret = ath_tx_aggr_stop(sc, addr, tid); - if (ret < 0) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to stop TX aggregation\n", - __func__); - - ieee80211_stop_tx_ba_cb_irqsafe(hw, (u8 *)addr, tid); + case IEEE80211_IF_TYPE_AP: + ic_opmode = ATH9K_M_HOSTAP; break; default: DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unknown AMPDU action\n", __func__); + "%s: Interface type %d not yet supported\n", + __func__, conf->type); + return -EOPNOTSUPP; } - return ret; + DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a VAP of type: %d\n", + __func__, + ic_opmode); + + error = ath_vap_attach(sc, 0, conf->vif, ic_opmode); + if (error) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: Unable to attach vap, error: %d\n", + __func__, error); + return error; + } + + return 0; } -static struct ieee80211_ops ath9k_ops = { - .tx = ath9k_tx, - .start = ath9k_start, - .stop = ath9k_stop, - .add_interface = ath9k_add_interface, - .remove_interface = ath9k_remove_interface, - .config = ath9k_config, - .config_interface = ath9k_config_interface, - .configure_filter = ath9k_configure_filter, - .get_stats = NULL, - .sta_notify = ath9k_sta_notify, - .conf_tx = ath9k_conf_tx, - .get_tx_stats = NULL, - .bss_info_changed = ath9k_bss_info_changed, - .set_tim = NULL, - .set_key = ath9k_set_key, - .hw_scan = NULL, - .get_tkip_seq = NULL, - .set_rts_threshold = NULL, - .set_frag_threshold = NULL, - .set_retry_limit = NULL, - .get_tsf = ath9k_get_tsf, - .reset_tsf = ath9k_reset_tsf, - .tx_last_beacon = NULL, - .ampdu_action = ath9k_ampdu_action -}; - -void ath_get_beaconconfig(struct ath_softc *sc, - int if_id, - struct ath_beacon_config *conf) -{ - struct ieee80211_hw *hw = sc->hw; - - /* fill in beacon config data */ - - conf->beacon_interval = hw->conf.beacon_int; - conf->listen_interval = 100; - conf->dtim_count = 1; - conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval; -} - -void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, - struct ath_xmit_status *tx_status, struct ath_node *an) +static void ath9k_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) { - struct ieee80211_hw *hw = sc->hw; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ath_softc *sc = hw->priv; + struct ath_vap *avp; + int error; - DPRINTF(sc, ATH_DBG_XMIT, - "%s: TX complete: skb: %p\n", __func__, skb); + DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach VAP\n", __func__); - if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || - tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { - /* free driver's private data area of tx_info */ - if (tx_info->driver_data[0] != NULL) - kfree(tx_info->driver_data[0]); - tx_info->driver_data[0] = NULL; + avp = sc->sc_vaps[0]; + if (avp == NULL) { + DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n", + __func__); + return; } - if (tx_status->flags & ATH_TX_BAR) { - tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; - tx_status->flags &= ~ATH_TX_BAR; - } +#ifdef CONFIG_SLOW_ANT_DIV + ath_slow_ant_div_stop(&sc->sc_antdiv); +#endif - 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; + /* Update ratectrl */ + ath_rate_newstate(sc, avp); + + /* Reclaim beacon resources */ + 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); + ath_beacon_return(sc, avp); } - tx_info->status.retry_count = tx_status->retries; + /* Set interrupt mask */ + sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); + ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask & ~ATH9K_INT_GLOBAL); + sc->sc_flags &= ~SC_OP_BEACONS; - ieee80211_tx_status(hw, skb); - if (an) - ath_node_put(sc, an, ATH9K_BH_STATUS_CHANGE); + error = ath_vap_detach(sc, 0); + if (error) + DPRINTF(sc, ATH_DBG_FATAL, + "%s: Unable to detach vap, error: %d\n", + __func__, error); } -int _ath_rx_indicate(struct ath_softc *sc, - struct sk_buff *skb, - struct ath_recv_status *status, - u16 keyix) +static int ath9k_config(struct ieee80211_hw *hw, + struct ieee80211_conf *conf) { - struct ieee80211_hw *hw = sc->hw; - struct ath_node *an = NULL; - struct ieee80211_rx_status rx_status; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - int hdrlen = ieee80211_get_hdrlen_from_skb(skb); - int padsize; - enum ATH_RX_TYPE st; - - /* see if any padding is done by the hw and remove it */ - if (hdrlen & 3) { - padsize = hdrlen % 4; - memmove(skb->data + padsize, skb->data, hdrlen); - skb_pull(skb, padsize); - } - - /* Prepare rx status */ - ath9k_rx_prepare(sc, skb, status, &rx_status); - - if (!(keyix == ATH9K_RXKEYIX_INVALID) && - !(status->flags & ATH_RX_DECRYPT_ERROR)) { - rx_status.flag |= RX_FLAG_DECRYPTED; - } else if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) - && !(status->flags & ATH_RX_DECRYPT_ERROR) - && skb->len >= hdrlen + 4) { - keyix = skb->data[hdrlen + 3] >> 6; - - if (test_bit(keyix, sc->sc_keymap)) - rx_status.flag |= RX_FLAG_DECRYPTED; - } + struct ath_softc *sc = hw->priv; + struct ieee80211_channel *curchan = hw->conf.channel; + int pos; - spin_lock_bh(&sc->node_lock); - an = ath_node_find(sc, hdr->addr2); - spin_unlock_bh(&sc->node_lock); + DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n", + __func__, + curchan->center_freq); - if (an) { - ath_rx_input(sc, an, - hw->conf.ht_conf.ht_supported, - skb, status, &st); + pos = ath_get_channel(sc, curchan); + if (pos == -1) { + DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__); + return -EINVAL; } - if (!an || (st != ATH_RX_CONSUMED)) - __ieee80211_rx(hw, skb, &rx_status); - return 0; -} + sc->sc_ah->ah_channels[pos].chanmode = + (curchan->band == IEEE80211_BAND_2GHZ) ? + CHANNEL_G : CHANNEL_A; -int ath_rx_subframe(struct ath_node *an, - struct sk_buff *skb, - struct ath_recv_status *status) -{ - struct ath_softc *sc = an->an_sc; - struct ieee80211_hw *hw = sc->hw; - struct ieee80211_rx_status rx_status; + if (sc->sc_curaid && hw->conf.ht_conf.ht_supported) + sc->sc_ah->ah_channels[pos].chanmode = + ath_get_extchanmode(sc, curchan); - /* Prepare rx status */ - ath9k_rx_prepare(sc, skb, status, &rx_status); - if (!(status->flags & ATH_RX_DECRYPT_ERROR)) - rx_status.flag |= RX_FLAG_DECRYPTED; + sc->sc_config.txpowlimit = 2 * conf->power_level; - __ieee80211_rx(hw, skb, &rx_status); + /* set h/w channel */ + if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) + DPRINTF(sc, ATH_DBG_FATAL, "%s: Unable to set channel\n", + __func__); return 0; } -/********************************/ -/* LED functions */ -/********************************/ - -static void ath_led_brightness(struct led_classdev *led_cdev, - enum led_brightness brightness) +static int ath9k_config_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_if_conf *conf) { - struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); - struct ath_softc *sc = led->sc; + struct ath_softc *sc = hw->priv; + struct ath_hal *ah = sc->sc_ah; + struct ath_vap *avp; + u32 rfilt = 0; + int error, i; + DECLARE_MAC_BUF(mac); - 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; + avp = sc->sc_vaps[0]; + if (avp == NULL) { + DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n", + __func__); + return -EINVAL; } -} -static int ath_register_led(struct ath_softc *sc, struct ath_led *led, - char *trigger) -{ - int ret; + /* 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; + } - led->sc = sc; - led->led_cdev.name = led->name; - led->led_cdev.default_trigger = trigger; - led->led_cdev.brightness_set = ath_led_brightness; + if ((conf->changed & IEEE80211_IFCC_BSSID) && + !is_zero_ether_addr(conf->bssid)) { + switch (vif->type) { + case IEEE80211_IF_TYPE_STA: + case IEEE80211_IF_TYPE_IBSS: + /* Update ratectrl about the new state */ + ath_rate_newstate(sc, avp); - 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; -} + /* Set BSSID */ + memcpy(sc->sc_curbssid, conf->bssid, ETH_ALEN); + sc->sc_curaid = 0; + ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid, + sc->sc_curaid); -static void ath_unregister_led(struct ath_led *led) -{ - if (led->registered) { - led_classdev_unregister(&led->led_cdev); - led->registered = 0; - } -} + /* Set aggregation protection mode parameters */ + sc->sc_config.ath_aggr_prot = 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); -} + /* + * Reset our TSF so that its value is lower than the + * beacon that we are trying to catch. + * Only then hw will update its TSF register with the + * new beacon. Reset the TSF before setting the BSSID + * to avoid allowing in any frames that would update + * our TSF only to have us clear it + * immediately thereafter. + */ + ath9k_hw_reset_tsf(sc->sc_ah); -static void ath_init_leds(struct ath_softc *sc) -{ - char *trigger; - int ret; + /* Disable BMISS interrupt when we're not associated */ + ath9k_hw_set_interrupts(sc->sc_ah, + sc->sc_imask & + ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS)); + sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); - /* 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); + 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); - 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; + /* need to reconfigure the beacon */ + sc->sc_flags &= ~SC_OP_BEACONS ; - 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; + break; + default: + break; + } + } - 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; + if ((conf->changed & IEEE80211_IFCC_BEACON) && + ((vif->type == IEEE80211_IF_TYPE_IBSS) || + (vif->type == IEEE80211_IF_TYPE_AP))) { + /* + * Allocate and setup the beacon frame. + * + * Stop any previous beacon DMA. This may be + * necessary, for example, when an ibss merge + * causes reconfiguration; we may be called + * with beacon transmission active. + */ + ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); - 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; + error = ath_beacon_alloc(sc, 0); + if (error != 0) + return error; - return; + ath_beacon_sync(sc, 0); + } -fail: - ath_deinit_leds(sc); -} + /* Check for WLAN_CAPABILITY_PRIVACY ? */ + if ((avp->av_opmode != IEEE80211_IF_TYPE_STA)) { + for (i = 0; i < IEEE80211_WEP_NKID; i++) + if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i)) + ath9k_hw_keysetmac(sc->sc_ah, + (u16)i, + sc->sc_curbssid); + } -static int ath_detach(struct ath_softc *sc) -{ - struct ieee80211_hw *hw = sc->hw; + /* Only legacy IBSS for now */ + if (vif->type == IEEE80211_IF_TYPE_IBSS) + ath_update_chainmask(sc, 0); - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__); + return 0; +} - /* Deinit LED control */ - ath_deinit_leds(sc); +#define SUPPORTED_FILTERS \ + (FIF_PROMISC_IN_BSS | \ + FIF_ALLMULTI | \ + FIF_CONTROL | \ + FIF_OTHER_BSS | \ + FIF_BCN_PRBRESP_PROMISC | \ + FIF_FCSFAIL) - /* Unregister hw */ +/* FIXME: sc->sc_full_reset ? */ +static void ath9k_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, + int mc_count, + struct dev_mc_list *mclist) +{ + struct ath_softc *sc = hw->priv; + u32 rfilt; - ieee80211_unregister_hw(hw); + changed_flags &= SUPPORTED_FILTERS; + *total_flags &= SUPPORTED_FILTERS; - /* unregister Rate control */ - ath_rate_control_unregister(); + sc->rx_filter = *total_flags; + rfilt = ath_calcrxfilter(sc); + ath9k_hw_setrxfilter(sc->sc_ah, rfilt); - /* tx/rx cleanup */ + if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { + if (*total_flags & FIF_BCN_PRBRESP_PROMISC) + ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0); + } - ath_rx_cleanup(sc); - ath_tx_cleanup(sc); + DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set HW RX filter: 0x%x\n", + __func__, sc->rx_filter); +} - /* Deinit */ +static void ath9k_sta_notify(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, + const u8 *addr) +{ + struct ath_softc *sc = hw->priv; + struct ath_node *an; + unsigned long flags; + DECLARE_MAC_BUF(mac); - ath_deinit(sc); + spin_lock_irqsave(&sc->node_lock, flags); + an = ath_node_find(sc, (u8 *) addr); + spin_unlock_irqrestore(&sc->node_lock, flags); - return 0; + switch (cmd) { + case STA_NOTIFY_ADD: + spin_lock_irqsave(&sc->node_lock, flags); + if (!an) { + ath_node_attach(sc, (u8 *)addr, 0); + DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a node: %s\n", + __func__, + print_mac(mac, addr)); + } else { + ath_node_get(sc, (u8 *)addr); + } + spin_unlock_irqrestore(&sc->node_lock, flags); + break; + case STA_NOTIFY_REMOVE: + if (!an) + DPRINTF(sc, ATH_DBG_FATAL, + "%s: Removal of a non-existent node\n", + __func__); + else { + ath_node_put(sc, an, ATH9K_BH_STATUS_INTACT); + DPRINTF(sc, ATH_DBG_CONFIG, "%s: Put a node: %s\n", + __func__, + print_mac(mac, addr)); + } + break; + default: + break; + } } -static int ath_attach(u16 devid, - struct ath_softc *sc) +static int ath9k_conf_tx(struct ieee80211_hw *hw, + u16 queue, + const struct ieee80211_tx_queue_params *params) { - struct ieee80211_hw *hw = sc->hw; - int error = 0; + struct ath_softc *sc = hw->priv; + struct ath9k_tx_queue_info qi; + int ret = 0, qnum; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach ATH hw\n", __func__); + if (queue >= WME_NUM_AC) + return 0; - error = ath_init(devid, sc); - if (error != 0) - return error; + qi.tqi_aifs = params->aifs; + qi.tqi_cwmin = params->cw_min; + qi.tqi_cwmax = params->cw_max; + qi.tqi_burstTime = params->txop; + qnum = ath_get_hal_qnum(queue, sc); - /* Init nodes */ + DPRINTF(sc, ATH_DBG_CONFIG, + "%s: Configure tx [queue/halq] [%d/%d], " + "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", + __func__, + queue, + qnum, + params->aifs, + params->cw_min, + params->cw_max, + params->txop); - INIT_LIST_HEAD(&sc->node_list); - spin_lock_init(&sc->node_lock); + ret = ath_txq_update(sc, qnum, &qi); + if (ret) + DPRINTF(sc, ATH_DBG_FATAL, + "%s: TXQ Update failed\n", __func__); - /* get mac address from hardware and set in mac80211 */ + return ret; +} - SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr); +static int ath9k_set_key(struct ieee80211_hw *hw, + enum set_key_cmd cmd, + const u8 *local_addr, + const u8 *addr, + struct ieee80211_key_conf *key) +{ + struct ath_softc *sc = hw->priv; + int ret = 0; - /* setup channels and rates */ + DPRINTF(sc, ATH_DBG_KEYCACHE, " %s: Set HW Key\n", __func__); - sc->sbands[IEEE80211_BAND_2GHZ].channels = - sc->channels[IEEE80211_BAND_2GHZ]; - sc->sbands[IEEE80211_BAND_2GHZ].bitrates = - sc->rates[IEEE80211_BAND_2GHZ]; - sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; + switch (cmd) { + case SET_KEY: + ret = ath_key_config(sc, addr, key); + if (!ret) { + set_bit(key->keyidx, sc->sc_keymap); + key->hw_key_idx = key->keyidx; + /* push IV and Michael MIC generation to stack */ + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + if (key->alg == ALG_TKIP) + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + } + break; + case DISABLE_KEY: + ath_key_delete(sc, key); + clear_bit(key->keyidx, sc->sc_keymap); + sc->sc_keytype = ATH9K_CIPHER_CLR; + break; + default: + ret = -EINVAL; + } - if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) - /* Setup HT capabilities for 2.4Ghz*/ - setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_info); + return ret; +} - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = - &sc->sbands[IEEE80211_BAND_2GHZ]; +static void ath9k_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changed) +{ + struct ath_softc *sc = hw->priv; - if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) { - sc->sbands[IEEE80211_BAND_5GHZ].channels = - sc->channels[IEEE80211_BAND_5GHZ]; - sc->sbands[IEEE80211_BAND_5GHZ].bitrates = - sc->rates[IEEE80211_BAND_5GHZ]; - sc->sbands[IEEE80211_BAND_5GHZ].band = - IEEE80211_BAND_5GHZ; + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed PREAMBLE %d\n", + __func__, + bss_conf->use_short_preamble); + if (bss_conf->use_short_preamble) + sc->sc_flags |= SC_OP_PREAMBLE_SHORT; + else + sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT; + } - if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) - /* Setup HT capabilities for 5Ghz*/ - setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_info); + if (changed & BSS_CHANGED_ERP_CTS_PROT) { + DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed CTS PROT %d\n", + __func__, + bss_conf->use_cts_prot); + if (bss_conf->use_cts_prot && + hw->conf.channel->band != IEEE80211_BAND_5GHZ) + sc->sc_flags |= SC_OP_PROTECT_ENABLE; + else + sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; + } - hw->wiphy->bands[IEEE80211_BAND_5GHZ] = - &sc->sbands[IEEE80211_BAND_5GHZ]; + if (changed & BSS_CHANGED_HT) { + DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed HT %d\n", + __func__, + bss_conf->assoc_ht); + ath9k_ht_conf(sc, bss_conf); } - /* FIXME: Have to figure out proper hw init values later */ + if (changed & BSS_CHANGED_ASSOC) { + DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed ASSOC %d\n", + __func__, + bss_conf->assoc); + ath9k_bss_assoc_info(sc, bss_conf); + } +} - hw->queues = 4; - hw->ampdu_queues = 1; +static u64 ath9k_get_tsf(struct ieee80211_hw *hw) +{ + u64 tsf; + struct ath_softc *sc = hw->priv; + struct ath_hal *ah = sc->sc_ah; - /* Register rate control */ - hw->rate_control_algorithm = "ath9k_rate_control"; - error = ath_rate_control_register(); - if (error != 0) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to register rate control " - "algorithm:%d\n", __func__, error); - ath_rate_control_unregister(); - goto bad; - } + tsf = ath9k_hw_gettsf64(ah); - error = ieee80211_register_hw(hw); - if (error != 0) { - ath_rate_control_unregister(); - goto bad; - } + return tsf; +} - /* Initialize LED control */ - ath_init_leds(sc); +static void ath9k_reset_tsf(struct ieee80211_hw *hw) +{ + struct ath_softc *sc = hw->priv; + struct ath_hal *ah = sc->sc_ah; - /* initialize tx/rx engine */ + ath9k_hw_reset_tsf(ah); +} - error = ath_tx_init(sc, ATH_TXBUF); - if (error != 0) - goto detach; +static int ath9k_ampdu_action(struct ieee80211_hw *hw, + enum ieee80211_ampdu_mlme_action action, + const u8 *addr, + u16 tid, + u16 *ssn) +{ + struct ath_softc *sc = hw->priv; + int ret = 0; - error = ath_rx_init(sc, ATH_RXBUF); - if (error != 0) - goto detach; + switch (action) { + case IEEE80211_AMPDU_RX_START: + ret = ath_rx_aggr_start(sc, addr, tid, ssn); + if (ret < 0) + DPRINTF(sc, ATH_DBG_FATAL, + "%s: Unable to start RX aggregation\n", + __func__); + break; + case IEEE80211_AMPDU_RX_STOP: + ret = ath_rx_aggr_stop(sc, addr, tid); + if (ret < 0) + DPRINTF(sc, ATH_DBG_FATAL, + "%s: Unable to stop RX aggregation\n", + __func__); + break; + case IEEE80211_AMPDU_TX_START: + ret = ath_tx_aggr_start(sc, addr, tid, ssn); + if (ret < 0) + DPRINTF(sc, ATH_DBG_FATAL, + "%s: Unable to start TX aggregation\n", + __func__); + else + ieee80211_start_tx_ba_cb_irqsafe(hw, (u8 *)addr, tid); + break; + case IEEE80211_AMPDU_TX_STOP: + ret = ath_tx_aggr_stop(sc, addr, tid); + if (ret < 0) + DPRINTF(sc, ATH_DBG_FATAL, + "%s: Unable to stop TX aggregation\n", + __func__); - return 0; -detach: - ath_detach(sc); -bad: - return error; + ieee80211_stop_tx_ba_cb_irqsafe(hw, (u8 *)addr, tid); + break; + default: + DPRINTF(sc, ATH_DBG_FATAL, + "%s: Unknown AMPDU action\n", __func__); + } + + return ret; } +static struct ieee80211_ops ath9k_ops = { + .tx = ath9k_tx, + .start = ath9k_start, + .stop = ath9k_stop, + .add_interface = ath9k_add_interface, + .remove_interface = ath9k_remove_interface, + .config = ath9k_config, + .config_interface = ath9k_config_interface, + .configure_filter = ath9k_configure_filter, + .get_stats = NULL, + .sta_notify = ath9k_sta_notify, + .conf_tx = ath9k_conf_tx, + .get_tx_stats = NULL, + .bss_info_changed = ath9k_bss_info_changed, + .set_tim = NULL, + .set_key = ath9k_set_key, + .hw_scan = NULL, + .get_tkip_seq = NULL, + .set_rts_threshold = NULL, + .set_frag_threshold = NULL, + .set_retry_limit = NULL, + .get_tsf = ath9k_get_tsf, + .reset_tsf = ath9k_reset_tsf, + .tx_last_beacon = NULL, + .ampdu_action = ath9k_ampdu_action +}; + static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { void __iomem *mem; -- cgit v1.2.1 From 500c064d3a5f9c8aa604ef63a1346ab70eed443a Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 10 Sep 2008 18:50:17 +0530 Subject: ath9k: Add RF kill support RF kill support is enabled when CONFIG_RFKILL is set. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 7 +- drivers/net/wireless/ath9k/core.h | 16 +++ drivers/net/wireless/ath9k/hw.c | 70 +++++----- drivers/net/wireless/ath9k/main.c | 266 +++++++++++++++++++++++++++++++++++++ 4 files changed, 327 insertions(+), 32 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 28b8d84f49b4..0e897c276858 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -798,10 +798,11 @@ struct ath_hal { struct ath9k_channel *ah_curchan; u32 ah_nchan; - u16 ah_rfsilent; - bool ah_rfkillEnabled; bool ah_isPciExpress; u16 ah_txTrigLevel; + u16 ah_rfsilent; + u32 ah_rfkill_gpio; + u32 ah_rfkill_polarity; #ifndef ATH_NF_PER_CHAN struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; @@ -1003,4 +1004,6 @@ bool ath9k_get_channel_edges(struct ath_hal *ah, 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); +u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio); +void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio); #endif diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 1faa1effa02c..b66de29cf662 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -40,6 +40,7 @@ #include #include #include +#include #include "ath9k.h" #include "rc.h" @@ -823,6 +824,15 @@ struct ath_led { bool registered; }; +/* Rfkill */ +#define ATH_RFKILL_POLL_INTERVAL 2000 /* msecs */ + +struct ath_rfkill { + struct rfkill *rfkill; + struct delayed_work rfkill_poll; + char rfkill_name[32]; +}; + /********************/ /* Main driver core */ /********************/ @@ -906,6 +916,9 @@ struct ath_ht_info { #define SC_OP_PROTECT_ENABLE BIT(8) #define SC_OP_RXFLUSH BIT(9) #define SC_OP_LED_ASSOCIATED BIT(10) +#define SC_OP_RFKILL_REGISTERED BIT(11) +#define SC_OP_RFKILL_SW_BLOCKED BIT(12) +#define SC_OP_RFKILL_HW_BLOCKED BIT(13) struct ath_softc { struct ieee80211_hw *hw; @@ -1015,6 +1028,9 @@ struct ath_softc { struct ath_led assoc_led; struct ath_led tx_led; struct ath_led rx_led; + + /* Rfkill */ + struct ath_rfkill rf_kill; }; int ath_init(u16 devid, struct ath_softc *sc); diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 4ccbbc07cf1e..0251e59f2f84 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -2821,7 +2821,38 @@ void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val) AR_GPIO_BIT(gpio)); } -static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio) +/* + * Configure GPIO Input lines + */ +void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio) +{ + u32 gpio_shift; + + ASSERT(gpio < ah->ah_caps.num_gpio_pins); + + gpio_shift = gpio << 1; + + REG_RMW(ah, + AR_GPIO_OE_OUT, + (AR_GPIO_OE_OUT_DRV_NO << gpio_shift), + (AR_GPIO_OE_OUT_DRV << gpio_shift)); +} + +#ifdef CONFIG_RFKILL +static void ath9k_enable_rfkill(struct ath_hal *ah) +{ + REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, + AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); + + REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2, + AR_GPIO_INPUT_MUX2_RFSILENT); + + ath9k_hw_cfg_gpio_input(ah, ah->ah_rfkill_gpio); + REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB); +} +#endif + +u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio) { if (gpio >= ah->ah_caps.num_gpio_pins) return 0xffffffff; @@ -3034,17 +3065,17 @@ static bool ath9k_hw_fill_cap_info(struct ath_hal *ah) pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM; +#ifdef CONFIG_RFKILL ah->ah_rfsilent = ath9k_hw_get_eeprom(ahp, EEP_RF_SILENT); if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) { - ahp->ah_gpioSelect = + ah->ah_rfkill_gpio = MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL); - ahp->ah_polarity = + ah->ah_rfkill_polarity = MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY); - ath9k_hw_setcapability(ah, ATH9K_CAP_RFSILENT, 1, true, - NULL); pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT; } +#endif if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) || (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) || @@ -5961,6 +5992,10 @@ bool ath9k_hw_reset(struct ath_hal *ah, ath9k_hw_init_interrupt_masks(ah, ah->ah_opmode); ath9k_hw_init_qos(ah); +#ifdef CONFIG_RFKILL + if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + ath9k_enable_rfkill(ah); +#endif ath9k_hw_init_user_settings(ah); REG_WRITE(ah, AR_STA_ID1, @@ -6490,31 +6525,6 @@ ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask) return true; } -#ifdef CONFIG_ATH9K_RFKILL -static void ath9k_enable_rfkill(struct ath_hal *ah) -{ - struct ath_hal_5416 *ahp = AH5416(ah); - - REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, - AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); - - REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2, - AR_GPIO_INPUT_MUX2_RFSILENT); - - ath9k_hw_cfg_gpio_input(ah, ahp->ah_gpioSelect); - REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB); - - if (ahp->ah_gpioBit == ath9k_hw_gpio_get(ah, ahp->ah_gpioSelect)) { - - ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect, - !ahp->ah_gpioBit); - } else { - ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect, - ahp->ah_gpioBit); - } -} -#endif - void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId) diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 07e5b5d877b6..b493dff5643e 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -672,6 +672,209 @@ fail: ath_deinit_leds(sc); } +#ifdef CONFIG_RFKILL +/*******************/ +/* Rfkill */ +/*******************/ + +static void ath_radio_enable(struct ath_softc *sc) +{ + struct ath_hal *ah = sc->sc_ah; + int status; + + spin_lock_bh(&sc->sc_resetlock); + if (!ath9k_hw_reset(ah, ah->ah_curchan, + sc->sc_ht_info.tx_chan_width, + sc->sc_tx_chainmask, + sc->sc_rx_chainmask, + sc->sc_ht_extprotspacing, + false, &status)) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to reset channel %u (%uMhz) " + "flags 0x%x hal status %u\n", __func__, + ath9k_hw_mhz2ieee(ah, + ah->ah_curchan->channel, + ah->ah_curchan->channelFlags), + ah->ah_curchan->channel, + ah->ah_curchan->channelFlags, status); + } + spin_unlock_bh(&sc->sc_resetlock); + + ath_update_txpow(sc); + if (ath_startrecv(sc) != 0) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to restart recv logic\n", __func__); + return; + } + + if (sc->sc_flags & SC_OP_BEACONS) + ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */ + + /* Re-Enable interrupts */ + ath9k_hw_set_interrupts(ah, sc->sc_imask); + + /* Enable LED */ + ath9k_hw_cfg_output(ah, ATH_LED_PIN, + AR_GPIO_OUTPUT_MUX_AS_OUTPUT); + ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0); + + ieee80211_wake_queues(sc->hw); +} + +static void ath_radio_disable(struct ath_softc *sc) +{ + struct ath_hal *ah = sc->sc_ah; + int status; + + + ieee80211_stop_queues(sc->hw); + + /* Disable LED */ + ath9k_hw_set_gpio(ah, ATH_LED_PIN, 1); + ath9k_hw_cfg_gpio_input(ah, ATH_LED_PIN); + + /* Disable interrupts */ + ath9k_hw_set_interrupts(ah, 0); + + ath_draintxq(sc, false); /* clear pending tx frames */ + ath_stoprecv(sc); /* turn off frame recv */ + ath_flushrecv(sc); /* flush recv queue */ + + spin_lock_bh(&sc->sc_resetlock); + if (!ath9k_hw_reset(ah, ah->ah_curchan, + sc->sc_ht_info.tx_chan_width, + sc->sc_tx_chainmask, + sc->sc_rx_chainmask, + sc->sc_ht_extprotspacing, + false, &status)) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to reset channel %u (%uMhz) " + "flags 0x%x hal status %u\n", __func__, + ath9k_hw_mhz2ieee(ah, + ah->ah_curchan->channel, + ah->ah_curchan->channelFlags), + ah->ah_curchan->channel, + ah->ah_curchan->channelFlags, status); + } + spin_unlock_bh(&sc->sc_resetlock); + + ath9k_hw_phy_disable(ah); + ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); +} + +static bool ath_is_rfkill_set(struct ath_softc *sc) +{ + struct ath_hal *ah = sc->sc_ah; + + return ath9k_hw_gpio_get(ah, ah->ah_rfkill_gpio) == + ah->ah_rfkill_polarity; +} + +/* h/w rfkill poll function */ +static void ath_rfkill_poll(struct work_struct *work) +{ + struct ath_softc *sc = container_of(work, struct ath_softc, + rf_kill.rfkill_poll.work); + bool radio_on; + + if (sc->sc_flags & SC_OP_INVALID) + return; + + radio_on = !ath_is_rfkill_set(sc); + + /* + * enable/disable radio only when there is a + * state change in RF switch + */ + if (radio_on == !!(sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED)) { + enum rfkill_state state; + + if (sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED) { + state = radio_on ? RFKILL_STATE_SOFT_BLOCKED + : RFKILL_STATE_HARD_BLOCKED; + } else if (radio_on) { + ath_radio_enable(sc); + state = RFKILL_STATE_UNBLOCKED; + } else { + ath_radio_disable(sc); + state = RFKILL_STATE_HARD_BLOCKED; + } + + if (state == RFKILL_STATE_HARD_BLOCKED) + sc->sc_flags |= SC_OP_RFKILL_HW_BLOCKED; + else + sc->sc_flags &= ~SC_OP_RFKILL_HW_BLOCKED; + + rfkill_force_state(sc->rf_kill.rfkill, state); + } + + queue_delayed_work(sc->hw->workqueue, &sc->rf_kill.rfkill_poll, + msecs_to_jiffies(ATH_RFKILL_POLL_INTERVAL)); +} + +/* s/w rfkill handler */ +static int ath_sw_toggle_radio(void *data, enum rfkill_state state) +{ + struct ath_softc *sc = data; + + switch (state) { + case RFKILL_STATE_SOFT_BLOCKED: + if (!(sc->sc_flags & (SC_OP_RFKILL_HW_BLOCKED | + SC_OP_RFKILL_SW_BLOCKED))) + ath_radio_disable(sc); + sc->sc_flags |= SC_OP_RFKILL_SW_BLOCKED; + return 0; + case RFKILL_STATE_UNBLOCKED: + if ((sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED)) { + sc->sc_flags &= ~SC_OP_RFKILL_SW_BLOCKED; + if (sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED) { + DPRINTF(sc, ATH_DBG_FATAL, "Can't turn on the" + "radio as it is disabled by h/w \n"); + return -EPERM; + } + ath_radio_enable(sc); + } + return 0; + default: + return -EINVAL; + } +} + +/* Init s/w rfkill */ +static int ath_init_sw_rfkill(struct ath_softc *sc) +{ + sc->rf_kill.rfkill = rfkill_allocate(wiphy_dev(sc->hw->wiphy), + RFKILL_TYPE_WLAN); + if (!sc->rf_kill.rfkill) { + DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n"); + return -ENOMEM; + } + + snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name), + "ath9k-%s:rfkill", wiphy_name(sc->hw->wiphy)); + sc->rf_kill.rfkill->name = sc->rf_kill.rfkill_name; + sc->rf_kill.rfkill->data = sc; + sc->rf_kill.rfkill->toggle_radio = ath_sw_toggle_radio; + sc->rf_kill.rfkill->state = RFKILL_STATE_UNBLOCKED; + sc->rf_kill.rfkill->user_claim_unsupported = 1; + + return 0; +} + +/* Deinitialize rfkill */ +static void ath_deinit_rfkill(struct ath_softc *sc) +{ + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); + + if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) { + rfkill_unregister(sc->rf_kill.rfkill); + sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED; + sc->rf_kill.rfkill = NULL; + } +} +#endif /* CONFIG_RFKILL */ + static int ath_detach(struct ath_softc *sc) { struct ieee80211_hw *hw = sc->hw; @@ -681,6 +884,11 @@ static int ath_detach(struct ath_softc *sc) /* Deinit LED control */ ath_deinit_leds(sc); +#ifdef CONFIG_RFKILL + /* deinit rfkill */ + ath_deinit_rfkill(sc); +#endif + /* Unregister hw */ ieee80211_unregister_hw(hw); @@ -777,6 +985,16 @@ static int ath_attach(u16 devid, /* Initialize LED control */ ath_init_leds(sc); +#ifdef CONFIG_RFKILL + /* Initialze h/w Rfkill */ + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll); + + /* Initialize s/w rfkill */ + if (ath_init_sw_rfkill(sc)) + goto detach; +#endif + /* initialize tx/rx engine */ error = ath_tx_init(sc, ATH_TXBUF); @@ -822,6 +1040,33 @@ static int ath9k_start(struct ieee80211_hw *hw) return error; } +#ifdef CONFIG_RFKILL + /* Start rfkill polling */ + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + queue_delayed_work(sc->hw->workqueue, + &sc->rf_kill.rfkill_poll, 0); + + if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) { + if (rfkill_register(sc->rf_kill.rfkill)) { + DPRINTF(sc, ATH_DBG_FATAL, + "Unable to register rfkill\n"); + rfkill_free(sc->rf_kill.rfkill); + + /* Deinitialize the device */ + if (sc->pdev->irq) + free_irq(sc->pdev->irq, sc); + ath_detach(sc); + pci_iounmap(sc->pdev, sc->mem); + pci_release_region(sc->pdev, 0); + pci_disable_device(sc->pdev); + ieee80211_free_hw(hw); + return -EIO; + } else { + sc->sc_flags |= SC_OP_RFKILL_REGISTERED; + } + } +#endif + ieee80211_wake_queues(hw); return 0; } @@ -883,6 +1128,11 @@ static void ath9k_stop(struct ieee80211_hw *hw) "%s: Device is no longer present\n", __func__); ieee80211_stop_queues(hw); + +#ifdef CONFIG_RFKILL + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); +#endif } static int ath9k_add_interface(struct ieee80211_hw *hw, @@ -1554,6 +1804,12 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state) struct ath_softc *sc = hw->priv; ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); + +#ifdef CONFIG_RFKILL + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); +#endif + pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, 3); @@ -1586,6 +1842,16 @@ static int ath_pci_resume(struct pci_dev *pdev) AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); +#ifdef CONFIG_RFKILL + /* + * check the h/w rfkill state on resume + * and start the rfkill poll timer + */ + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + queue_delayed_work(sc->hw->workqueue, + &sc->rf_kill.rfkill_poll, 0); +#endif + return 0; } -- cgit v1.2.1 From 05c914fe330fa8e1cc67870dc0d3809dfd96c107 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 11 Sep 2008 00:01:58 +0200 Subject: mac80211: use nl80211 interface types There's really no reason for mac80211 to be using its own interface type defines. Use the nl80211 types and simplify the configuration code a bit: there's no need to translate them any more now. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index b493dff5643e..2a6e089062f3 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -140,7 +140,7 @@ static int ath_key_config(struct ath_softc *sc, struct ath9k_keyval hk; const u8 *mac = NULL; int ret = 0; - enum ieee80211_if_types opmode; + enum nl80211_iftype opmode; memset(&hk, 0, sizeof(hk)); @@ -179,14 +179,14 @@ static int ath_key_config(struct ath_softc *sc, */ if (is_broadcast_ether_addr(addr)) { switch (opmode) { - case IEEE80211_IF_TYPE_STA: + case NL80211_IFTYPE_STATION: /* default key: could be group WPA key * or could be static WEP key */ mac = NULL; break; - case IEEE80211_IF_TYPE_IBSS: + case NL80211_IFTYPE_ADHOC: break; - case IEEE80211_IF_TYPE_AP: + case NL80211_IFTYPE_AP: break; default: ASSERT(0); @@ -1147,13 +1147,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, return -ENOBUFS; switch (conf->type) { - case IEEE80211_IF_TYPE_STA: + case NL80211_IFTYPE_STATION: ic_opmode = ATH9K_M_STA; break; - case IEEE80211_IF_TYPE_IBSS: + case NL80211_IFTYPE_ADHOC: ic_opmode = ATH9K_M_IBSS; break; - case IEEE80211_IF_TYPE_AP: + case NL80211_IFTYPE_AP: ic_opmode = ATH9K_M_HOSTAP; break; default: @@ -1275,7 +1275,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, /* TODO: Need to decide which hw opmode to use for multi-interface * cases */ - if (vif->type == IEEE80211_IF_TYPE_AP && + if (vif->type == NL80211_IFTYPE_AP && ah->ah_opmode != ATH9K_M_HOSTAP) { ah->ah_opmode = ATH9K_M_HOSTAP; ath9k_hw_setopmode(ah); @@ -1287,8 +1287,8 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, if ((conf->changed & IEEE80211_IFCC_BSSID) && !is_zero_ether_addr(conf->bssid)) { switch (vif->type) { - case IEEE80211_IF_TYPE_STA: - case IEEE80211_IF_TYPE_IBSS: + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: /* Update ratectrl about the new state */ ath_rate_newstate(sc, avp); @@ -1333,8 +1333,8 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, } if ((conf->changed & IEEE80211_IFCC_BEACON) && - ((vif->type == IEEE80211_IF_TYPE_IBSS) || - (vif->type == IEEE80211_IF_TYPE_AP))) { + ((vif->type == NL80211_IFTYPE_ADHOC) || + (vif->type == NL80211_IFTYPE_AP))) { /* * Allocate and setup the beacon frame. * @@ -1353,7 +1353,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, } /* Check for WLAN_CAPABILITY_PRIVACY ? */ - if ((avp->av_opmode != IEEE80211_IF_TYPE_STA)) { + if ((avp->av_opmode != NL80211_IFTYPE_STATION)) { for (i = 0; i < IEEE80211_WEP_NKID; i++) if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i)) ath9k_hw_keysetmac(sc->sc_ah, @@ -1362,7 +1362,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, } /* Only legacy IBSS for now */ - if (vif->type == IEEE80211_IF_TYPE_IBSS) + if (vif->type == NL80211_IFTYPE_ADHOC) ath_update_chainmask(sc, 0); return 0; -- cgit v1.2.1 From 17741cdc264e4d768167766a252210e201c1519a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 11 Sep 2008 00:02:02 +0200 Subject: mac80211: share STA information with driver This patch changes mac80211 to share some more data about stations with drivers. Should help iwlwifi and ath9k when they get around to updating, and might also help with implementing rate control algorithms without internals. Signed-off-by: Johannes Berg Cc: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 2a6e089062f3..1ba18006f475 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1405,7 +1405,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, static void ath9k_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd cmd, - const u8 *addr) + struct ieee80211_sta *sta) { struct ath_softc *sc = hw->priv; struct ath_node *an; @@ -1413,19 +1413,18 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw, DECLARE_MAC_BUF(mac); spin_lock_irqsave(&sc->node_lock, flags); - an = ath_node_find(sc, (u8 *) addr); + an = ath_node_find(sc, sta->addr); spin_unlock_irqrestore(&sc->node_lock, flags); switch (cmd) { case STA_NOTIFY_ADD: spin_lock_irqsave(&sc->node_lock, flags); if (!an) { - ath_node_attach(sc, (u8 *)addr, 0); + ath_node_attach(sc, sta->addr, 0); DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a node: %s\n", - __func__, - print_mac(mac, addr)); + __func__, print_mac(mac, sta->addr)); } else { - ath_node_get(sc, (u8 *)addr); + ath_node_get(sc, sta->addr); } spin_unlock_irqrestore(&sc->node_lock, flags); break; @@ -1438,7 +1437,7 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw, ath_node_put(sc, an, ATH9K_BH_STATUS_INTACT); DPRINTF(sc, ATH_DBG_CONFIG, "%s: Put a node: %s\n", __func__, - print_mac(mac, addr)); + print_mac(mac, sta->addr)); } break; default: @@ -1581,45 +1580,44 @@ static void ath9k_reset_tsf(struct ieee80211_hw *hw) static int ath9k_ampdu_action(struct ieee80211_hw *hw, enum ieee80211_ampdu_mlme_action action, - const u8 *addr, - u16 tid, - u16 *ssn) + struct ieee80211_sta *sta, + u16 tid, u16 *ssn) { struct ath_softc *sc = hw->priv; int ret = 0; switch (action) { case IEEE80211_AMPDU_RX_START: - ret = ath_rx_aggr_start(sc, addr, tid, ssn); + ret = ath_rx_aggr_start(sc, sta->addr, tid, ssn); if (ret < 0) DPRINTF(sc, ATH_DBG_FATAL, "%s: Unable to start RX aggregation\n", __func__); break; case IEEE80211_AMPDU_RX_STOP: - ret = ath_rx_aggr_stop(sc, addr, tid); + ret = ath_rx_aggr_stop(sc, sta->addr, tid); if (ret < 0) DPRINTF(sc, ATH_DBG_FATAL, "%s: Unable to stop RX aggregation\n", __func__); break; case IEEE80211_AMPDU_TX_START: - ret = ath_tx_aggr_start(sc, addr, tid, ssn); + ret = ath_tx_aggr_start(sc, sta->addr, tid, ssn); if (ret < 0) DPRINTF(sc, ATH_DBG_FATAL, "%s: Unable to start TX aggregation\n", __func__); else - ieee80211_start_tx_ba_cb_irqsafe(hw, (u8 *)addr, tid); + ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); break; case IEEE80211_AMPDU_TX_STOP: - ret = ath_tx_aggr_stop(sc, addr, tid); + ret = ath_tx_aggr_stop(sc, sta->addr, tid); if (ret < 0) DPRINTF(sc, ATH_DBG_FATAL, "%s: Unable to stop TX aggregation\n", __func__); - ieee80211_stop_tx_ba_cb_irqsafe(hw, (u8 *)addr, tid); + ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); break; default: DPRINTF(sc, ATH_DBG_FATAL, -- cgit v1.2.1 From 323ce79a9cdbf838ea577677b1ddace8e0b4d4c6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 11 Sep 2008 02:45:11 +0200 Subject: mac80211: share sta->supp_rates As more preparation for a saner rate control algorithm API, share the supported rates bitmap in the public API. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/rc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 390019ed398e..226d70c73fe6 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -1825,7 +1825,7 @@ static void ath_setup_rates(struct ieee80211_local *local, struct sta_info *sta) sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; for (i = 0; i < sband->n_bitrates; i++) { - if (sta->supp_rates[local->hw.conf.channel->band] & BIT(i)) { + if (sta->sta.supp_rates[local->hw.conf.channel->band] & BIT(i)) { rc_priv->neg_rates.rs_rates[j] = (sband->bitrates[i].bitrate * 2) / 10; j++; -- cgit v1.2.1 From ae17e986091637e7ef5a8224c7b689029b105131 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 11 Sep 2008 03:04:36 +0200 Subject: mac80211: move txrate_idx into RC algorithms The sta_info->txrate_idx member isn't used by all RC algorithms in the way it was intended to be used, move it into those that require it (only PID) and keep track in the core code of which rate was last used for reporting to userspace and the mesh MLME. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/rc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 226d70c73fe6..1cc9daf44550 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -2039,7 +2039,6 @@ static void ath_rate_init(void *priv, void *priv_sta, DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; - sta->txrate_idx = rate_lowest_index(local, sband, sta); ath_setup_rates(local, sta); if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { -- cgit v1.2.1 From d0be7cc7688d0cc2e4daf952c43b5ce86e5c8a1d Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Wed, 17 Sep 2008 12:39:49 +0530 Subject: ath9k: connectivity is lost after Group rekeying is done Connectivtiy is lost after Group rekeying is done. The keytype maintained by ath9k is reset when group key is updated. Though sc_keytype can be reset only for broadcast key the proper fix would be to use mac80211 provided key type from txinfo during xmit and get rid of sc_keytype from ath9k ath_softc. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Senthil Balasubramanian Tested-by: Steven Noonan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.h | 1 - drivers/net/wireless/ath9k/main.c | 3 --- drivers/net/wireless/ath9k/xmit.c | 6 +++--- 3 files changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 4ee695b76b88..2f84093331ee 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -974,7 +974,6 @@ struct ath_softc { u32 sc_keymax; /* size of key cache */ DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); /* key use bit map */ u8 sc_splitmic; /* split TKIP MIC keys */ - int sc_keytype; /* RX */ struct list_head sc_rxbuf; diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 99badf1404c3..099719649c98 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -206,8 +206,6 @@ static int ath_key_config(struct ath_softc *sc, if (!ret) return -EIO; - if (mac) - sc->sc_keytype = hk.kv_type; return 0; } @@ -778,7 +776,6 @@ static int ath9k_set_key(struct ieee80211_hw *hw, case DISABLE_KEY: ath_key_delete(sc, key); clear_bit(key->keyidx, sc->sc_keymap); - sc->sc_keytype = ATH9K_CIPHER_CLR; break; default: ret = -EINVAL; diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 550129f717e2..8b332e11a656 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -315,11 +315,11 @@ static int ath_tx_prepare(struct ath_softc *sc, txctl->keyix = tx_info->control.hw_key->hw_key_idx; txctl->frmlen += tx_info->control.icv_len; - if (sc->sc_keytype == ATH9K_CIPHER_WEP) + if (tx_info->control.hw_key->alg == ALG_WEP) txctl->keytype = ATH9K_KEY_TYPE_WEP; - else if (sc->sc_keytype == ATH9K_CIPHER_TKIP) + else if (tx_info->control.hw_key->alg == ALG_TKIP) txctl->keytype = ATH9K_KEY_TYPE_TKIP; - else if (sc->sc_keytype == ATH9K_CIPHER_AES_CCM) + else if (tx_info->control.hw_key->alg == ALG_CCMP) txctl->keytype = ATH9K_KEY_TYPE_AES; } -- cgit v1.2.1 From 6115e8557a75b5f24b56ed46c60dffef7e7fa992 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Mon, 22 Sep 2008 14:22:39 +0530 Subject: ath9k: Fix IRQ nobody cared issue with ath9k IRQs should be disabled before calling free_irq. Also flush pending IRQs. Pasted the kernel log message for reference. kernel: irq 17: nobody cared (try booting with the "irqpoll" option) kernel: [] __report_bad_irq+0x2e/0x6f kernel: [] note_interrupt+0x1b5/0x207 kernel: [] ? handle_IRQ_event+0x21/0x48 kernel: [] handle_fasteoi_irq+0x8e/0xad kernel: [] do_IRQ+0x6c/0x84 kernel: [] common_interrupt+0x23/0x28 kernel: [] ? acpi_idle_enter_simple+0x198/0x205 kernel: [] ? menu_select+0x5c/0x78 kernel: [] cpuidle_idle_call+0x59/0x89 kernel: [] cpu_idle+0xae/0xcf kernel: [] rest_init+0x4e/0x50 kernel: ======================= kernel: handlers: kernel: [] (ath_isr+0x0/0x13a [ath9k]) kernel: Disabling IRQ #17 Signed-off-by: Senthil Balasubramanian Tested-by: Steven Noonan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.c | 4 ++-- drivers/net/wireless/ath9k/main.c | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index f6c45288d0e7..c04959357bda 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -294,8 +294,6 @@ static int ath_stop(struct ath_softc *sc) * hardware is gone (invalid). */ - if (!sc->sc_invalid) - ath9k_hw_set_interrupts(ah, 0); ath_draintxq(sc, false); if (!sc->sc_invalid) { ath_stoprecv(sc); @@ -1336,6 +1334,8 @@ void ath_deinit(struct ath_softc *sc) DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__); + tasklet_kill(&sc->intr_tq); + tasklet_kill(&sc->bcon_tasklet); ath_stop(sc); if (!sc->sc_invalid) ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 099719649c98..acebdf1d20a8 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1411,10 +1411,17 @@ static void ath_pci_remove(struct pci_dev *pdev) { struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath_softc *sc = hw->priv; + enum ath9k_int status; - if (pdev->irq) + if (pdev->irq) { + ath9k_hw_set_interrupts(sc->sc_ah, 0); + /* clear the ISR */ + ath9k_hw_getisr(sc->sc_ah, &status); + sc->sc_invalid = 1; free_irq(pdev->irq, sc); + } ath_detach(sc); + pci_iounmap(pdev, sc->mem); pci_release_region(pdev, 0); pci_disable_device(pdev); -- cgit v1.2.1 From 92cccc2cda9a744326bbd9f16c635187af7f8a09 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 23 Sep 2008 14:28:16 -0700 Subject: ath9k: disable MIB interrupts to fix interrupt storm Enabling the MIB interrupts has proven to cause an interrupt storm after 7 hours of run. We will make use of the MIB interrupt once we have ANI supported added so for now to cure this we disable the interrupt. The interrupt storm can be seen as follows after 7 hours of run as reported by Steven Noonan : 18:28:38 sum 1106.00 18:28:39 sum 1037.62 18:28:40 sum 1069.00 18:28:41 sum 1167.00 18:28:42 sum 1155.00 18:28:43 sum 1339.00 18:28:44 sum 18355.00 18:28:45 sum 17845.45 18:28:46 sum 15285.00 18:28:47 sum 17511.00 18:28:48 sum 17568.69 18:28:49 sum 17704.04 18:28:50 sum 18566.67 18:28:51 sum 18913.13 at 18:28:44 the MIB interrupt kicked off and caused huge latency which can be seen even on a video he submitted: http://www.youtube.com/watch?v=4GeCx1gZMpA Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index c04959357bda..87e37bc39145 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -795,6 +795,12 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) sc->sc_imask |= ATH9K_INT_CST; + /* Note: We disable MIB interrupts for now as we don't yet + * handle processing ANI, otherwise you will get an interrupt + * storm after about 7 hours of usage making the system unusable + * with huge latency. Once we do have ANI processing included + * we can re-enable this interrupt. */ +#if 0 /* * Enable MIB interrupts when there are hardware phy counters. * Note we only do this (at the moment) for station mode. @@ -802,6 +808,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) if (ath9k_hw_phycounters(ah) && ((sc->sc_opmode == ATH9K_M_STA) || (sc->sc_opmode == ATH9K_M_IBSS))) sc->sc_imask |= ATH9K_INT_MIB; +#endif /* * Some hardware processes the TIM IE and fires an * interrupt when the TIM bit is set. For hardware -- cgit v1.2.1 From 980b24da6f1725c2d0b32c9484d06cd7d09d3c4b Mon Sep 17 00:00:00 2001 From: Sujith Date: Wed, 17 Sep 2008 10:15:09 +0530 Subject: ath9k: Whitespace cleanup Also, remove comments that are not relevant anymore. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/beacon.c | 136 ++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 76 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index c43fd5861163..f8d952ca3f85 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -26,7 +26,6 @@ * the operating mode of the station (AP or AdHoc). Parameters are AIFS * settings and channel width min/max */ - static int ath_beaconq_config(struct ath_softc *sc) { struct ath_hal *ah = sc->sc_ah; @@ -63,19 +62,18 @@ static int ath_beaconq_config(struct ath_softc *sc) * up all required antenna switch parameters, rate codes, and channel flags. * Beacons are always sent out at the lowest rate, and are not retried. */ - static void ath_beacon_setup(struct ath_softc *sc, - struct ath_vap *avp, struct ath_buf *bf) + struct ath_vap *avp, struct ath_buf *bf) { struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; struct ath_hal *ah = sc->sc_ah; struct ath_desc *ds; - int flags, antenna; + struct ath9k_11n_rate_series series[4]; const struct ath9k_rate_table *rt; + int flags, antenna; u8 rix, rate; int ctsrate = 0; int ctsduration = 0; - struct ath9k_11n_rate_series series[4]; DPRINTF(sc, ATH_DBG_BEACON, "%s: m %p len %u\n", __func__, skb, skb->len); @@ -115,20 +113,21 @@ static void ath_beacon_setup(struct ath_softc *sc, rate |= rt->info[rix].shortPreamble; ath9k_hw_set11n_txdesc(ah, ds, - skb->len + FCS_LEN, /* frame length */ - ATH9K_PKT_TYPE_BEACON, /* Atheros packet type */ + skb->len + FCS_LEN, /* frame length */ + ATH9K_PKT_TYPE_BEACON, /* Atheros packet type */ avp->av_btxctl.txpower, /* txpower XXX */ - ATH9K_TXKEYIX_INVALID, /* no encryption */ - ATH9K_KEY_TYPE_CLEAR, /* no encryption */ - flags /* no ack, veol for beacons */ + ATH9K_TXKEYIX_INVALID, /* no encryption */ + ATH9K_KEY_TYPE_CLEAR, /* no encryption */ + flags /* no ack, + veol for beacons */ ); /* NB: beacon's BufLen must be a multiple of 4 bytes */ ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4), /* buffer length */ - true, /* first segment */ - true, /* last segment */ - ds /* first descriptor */ + true, /* first segment */ + true, /* last segment */ + ds /* first descriptor */ ); memzero(series, sizeof(struct ath9k_11n_rate_series) * 4); @@ -153,22 +152,23 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) struct ath_buf *bf; struct ath_vap *avp; struct sk_buff *skb; - int cabq_depth; struct ath_txq *cabq; struct ieee80211_tx_info *info; + int cabq_depth; + avp = sc->sc_vaps[if_id]; + ASSERT(avp); cabq = sc->sc_cabq; - ASSERT(avp); - if (avp->av_bcbuf == NULL) { DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n", __func__, avp, avp->av_bcbuf); return NULL; } + 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, @@ -179,17 +179,19 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) bf->bf_mpdu = skb; if (skb == NULL) return NULL; + info = IEEE80211_SKB_CB(skb); if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { /* * TODO: make sure the seq# gets assigned properly (vs. other * TX frames) */ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; sc->seq_no += 0x10; hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); hdr->seq_ctrl |= cpu_to_le16(sc->seq_no); } + bf->bf_buf_addr = bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data, skb_end_pointer(skb) - skb->head, @@ -241,7 +243,6 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) * Startup beacon transmission for adhoc mode when they are sent entirely * by the hardware using the self-linked descriptor + veol trick. */ - static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) { struct ath_hal *ah = sc->sc_ah; @@ -278,7 +279,6 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) * min/max, and enable aifs). The info structure does not need to be * persistant. */ - int ath_beaconq_setup(struct ath_hal *ah) { struct ath9k_tx_queue_info qi; @@ -299,11 +299,10 @@ int ath_beaconq_setup(struct ath_hal *ah) * the ATH interface. This routine also calculates the beacon "slot" for * staggared beacons in the mBSSID case. */ - int ath_beacon_alloc(struct ath_softc *sc, int if_id) { struct ath_vap *avp; - struct ieee80211_hdr *wh; + struct ieee80211_hdr *hdr; struct ath_buf *bf; struct sk_buff *skb; @@ -312,13 +311,11 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) /* Allocate a beacon descriptor if we haven't done so. */ if (!avp->av_bcbuf) { - /* - * Allocate beacon state for hostap/ibss. We know - * a buffer is available. - */ + /* Allocate beacon state for hostap/ibss. We know + * a buffer is available. */ avp->av_bcbuf = list_first_entry(&sc->sc_bbuf, - struct ath_buf, list); + struct ath_buf, list); list_del(&avp->av_bcbuf->list); if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP || @@ -362,9 +359,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) } /* - * NB: the beacon data buffer must be 32-bit aligned; - * we assume the wbuf routines will return us something - * with this alignment (perhaps should assert). + * NB: the beacon data buffer must be 32-bit aligned. * FIXME: Fill avp->av_btxctl.txpower and * avp->av_btxctl.shortPreamble */ @@ -408,8 +403,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) __func__, "stagger", avp->av_bslot, intval, (unsigned long long)tsfadjust); - wh = (struct ieee80211_hdr *)skb->data; - memcpy(&wh[1], &val, sizeof(val)); + hdr = (struct ieee80211_hdr *)skb->data; + memcpy(&hdr[1], &val, sizeof(val)); } bf->bf_buf_addr = bf->bf_dmacontext = @@ -425,9 +420,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) * Reclaim beacon resources and return buffer to the pool. * * Checks the VAP to put the beacon frame buffer back to the ATH object - * queue, and de-allocates any wbuf frames that were sent as CAB traffic. + * queue, and de-allocates any skbs that were sent as CAB traffic. */ - void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) { if (avp->av_bcbuf != NULL) { @@ -459,10 +453,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) * Transmit one or more beacon frames at SWBA. Dynamic updates to the frame * contents are done as needed and the slot time is also adjusted based on * current state. - * - * This tasklet is not scheduled, it's called in ISR context. */ - void ath9k_beacon_tasklet(unsigned long data) { struct ath_softc *sc = (struct ath_softc *)data; @@ -490,6 +481,8 @@ void ath9k_beacon_tasklet(unsigned long data) * and wait for the next. Missed beacons indicate * a problem and should not occur. If we miss too * many consecutive beacons reset the device. + * + * FIXME: Clean up this mess !! */ if (ath9k_hw_numtxpending(ah, sc->sc_bhalq) != 0) { sc->sc_bmisscount++; @@ -505,19 +498,16 @@ void ath9k_beacon_tasklet(unsigned long data) __func__, sc->sc_bmisscount); if (show_cycles) { /* - * Display cycle counter stats - * from HW to aide in debug of - * stickiness. + * Display cycle counter stats from HW + * to aide in debug of stickiness. */ - DPRINTF(sc, - ATH_DBG_BEACON, + DPRINTF(sc, ATH_DBG_BEACON, "%s: busy times: rx_clear=%d, " "rx_frame=%d, tx_frame=%d\n", __func__, rx_clear, rx_frame, tx_frame); } else { - DPRINTF(sc, - ATH_DBG_BEACON, + DPRINTF(sc, ATH_DBG_BEACON, "%s: unable to obtain " "busy times\n", __func__); } @@ -529,8 +519,7 @@ void ath9k_beacon_tasklet(unsigned long data) } else if (sc->sc_bmisscount >= BSTUCK_THRESH) { if (sc->sc_flags & SC_OP_NO_RESET) { if (sc->sc_bmisscount == BSTUCK_THRESH) { - DPRINTF(sc, - ATH_DBG_BEACON, + DPRINTF(sc, ATH_DBG_BEACON, "%s: beacon is officially " "stuck\n", __func__); ath9k_hw_dmaRegDump(ah); @@ -542,13 +531,12 @@ void ath9k_beacon_tasklet(unsigned long data) ath_bstuck_process(sc); } } - return; } + if (sc->sc_bmisscount != 0) { if (sc->sc_flags & SC_OP_NO_RESET) { - DPRINTF(sc, - ATH_DBG_BEACON, + DPRINTF(sc, ATH_DBG_BEACON, "%s: resume beacon xmit after %u misses\n", __func__, sc->sc_bmisscount); } else { @@ -572,10 +560,12 @@ void ath9k_beacon_tasklet(unsigned long data) tsftu = TSF_TO_TU(tsf>>32, tsf); slot = ((tsftu % intval) * ATH_BCBUF) / intval; if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF]; + DPRINTF(sc, ATH_DBG_BEACON, - "%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d\n", - __func__, slot, (unsigned long long) tsf, tsftu, - intval, if_id); + "%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d\n", + __func__, slot, (unsigned long long)tsf, tsftu, + intval, if_id); + bfaddr = 0; if (if_id != ATH_IF_ID_ANY) { bf = ath_beacon_generate(sc, if_id); @@ -632,9 +622,8 @@ void ath9k_beacon_tasklet(unsigned long data) * Tasklet for Beacon Stuck processing * * Processing for Beacon Stuck. - * Basically calls the ath_internal_reset function to reset the chip. + * Basically resets the chip. */ - void ath_bstuck_process(struct ath_softc *sc) { DPRINTF(sc, ATH_DBG_BEACON, @@ -658,13 +647,12 @@ void ath_bstuck_process(struct ath_softc *sc) * interrupt when we stop seeing beacons from the AP * we've associated with. */ - void ath_beacon_config(struct ath_softc *sc, int if_id) { struct ath_hal *ah = sc->sc_ah; - u32 nexttbtt, intval; struct ath_beacon_config conf; enum ath9k_opmode av_opmode; + u32 nexttbtt, intval; if (if_id != ATH_IF_ID_ANY) av_opmode = sc->sc_vaps[if_id]->av_opmode; @@ -673,12 +661,6 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) memzero(&conf, sizeof(struct ath_beacon_config)); - /* FIXME: Use default values for now - Sujith */ - /* Query beacon configuration first */ - /* - * Protocol stack doesn't support dynamic beacon configuration, - * use default configurations. - */ conf.beacon_interval = sc->hw->conf.beacon_int ? sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL; conf.listen_interval = 1; @@ -704,12 +686,14 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) intval = conf.beacon_interval & ATH9K_BEACON_PERIOD; } - if (nexttbtt == 0) /* e.g. for ap mode */ + if (nexttbtt == 0) /* e.g. for ap mode */ nexttbtt = intval; - else if (intval) /* NB: can be 0 for monitor mode */ + else if (intval) /* NB: can be 0 for monitor mode */ nexttbtt = roundup(nexttbtt, intval); + DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n", __func__, nexttbtt, intval, conf.beacon_interval); + /* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */ if (sc->sc_ah->ah_opmode == ATH9K_M_STA) { struct ath9k_beacon_state bs; @@ -723,19 +707,19 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) * last beacon we received (which may be none). */ dtimperiod = conf.dtim_period; - if (dtimperiod <= 0) /* NB: 0 if not known */ + if (dtimperiod <= 0) /* NB: 0 if not known */ dtimperiod = 1; dtimcount = conf.dtim_count; - if (dtimcount >= dtimperiod) /* NB: sanity check */ - dtimcount = 0; /* XXX? */ - cfpperiod = 1; /* NB: no PCF support yet */ + if (dtimcount >= dtimperiod) /* NB: sanity check */ + dtimcount = 0; + cfpperiod = 1; /* NB: no PCF support yet */ cfpcount = 0; sleepduration = conf.listen_interval * intval; if (sleepduration <= 0) sleepduration = intval; -#define FUDGE 2 +#define FUDGE 2 /* * Pull nexttbtt forward to reflect the current * TSF and calculate dtim+cfp state for the result. @@ -759,6 +743,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod; bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod; bs.bs_cfpmaxduration = 0; + /* * Calculate the number of consecutive beacons to miss * before taking a BMISS interrupt. The configuration @@ -767,9 +752,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) * result to at most 15 beacons. */ if (sleepduration > intval) { - bs.bs_bmissthreshold = - conf.listen_interval * - ATH_DEFAULT_BMISS_LIMIT / 2; + bs.bs_bmissthreshold = conf.listen_interval * + ATH_DEFAULT_BMISS_LIMIT / 2; } else { bs.bs_bmissthreshold = DIV_ROUND_UP(conf.bmiss_timeout, intval); @@ -789,8 +773,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) * XXX fixed at 100ms */ - bs.bs_sleepduration = - roundup(IEEE80211_MS_TO_TU(100), sleepduration); + bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), + sleepduration); if (bs.bs_sleepduration > bs.bs_dtimperiod) bs.bs_sleepduration = bs.bs_dtimperiod; @@ -834,9 +818,9 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS) { /* * Pull nexttbtt forward to reflect the current - * TSF . + * TSF */ -#define FUDGE 2 +#define FUDGE 2 if (!(intval & ATH9K_BEACON_RESET_TSF)) { tsf = ath9k_hw_gettsf64(ah); tsftu = TSF_TO_TU((u32)(tsf>>32), -- cgit v1.2.1 From 459f5f90f1bd959ced04761406415b178b315177 Mon Sep 17 00:00:00 2001 From: Sujith Date: Wed, 17 Sep 2008 10:15:36 +0530 Subject: ath9k: Fix nexttbtt calculation nexttbtt has to be obtained from the timestamp of the beacon obtained from mac80211. Fix this. And is not needed anymore. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/beacon.c | 9 ++++++--- drivers/net/wireless/ath9k/core.h | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index f8d952ca3f85..eedb465d25d3 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -16,7 +16,6 @@ /* Implementation of beacon processing. */ -#include #include "core.h" /* @@ -305,6 +304,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) struct ieee80211_hdr *hdr; struct ath_buf *bf; struct sk_buff *skb; + __le64 tstamp; avp = sc->sc_vaps[if_id]; ASSERT(avp); @@ -370,6 +370,9 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) return -ENOMEM; } + tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; + sc->bc_tstamp = le64_to_cpu(tstamp); + /* * Calculate a TSF adjustment factor required for * staggered beacons. Note that we assume the format @@ -669,8 +672,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval; /* extract tstamp from last beacon and convert to TU */ - nexttbtt = TSF_TO_TU(get_unaligned_le32(conf.u.last_tstamp + 4), - get_unaligned_le32(conf.u.last_tstamp)); + nexttbtt = TSF_TO_TU(sc->bc_tstamp >> 32, sc->bc_tstamp); + /* XXX conditionalize multi-bss support? */ if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { /* diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index b66de29cf662..6ff3befe39f7 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -1001,6 +1001,7 @@ struct ath_softc { u32 sc_bhalq; u32 sc_bmisscount; u32 ast_be_xmit; /* beacons transmitted */ + u64 bc_tstamp; /* Rate */ struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; -- cgit v1.2.1 From 31e9ab2b180bccb3977b9a82ff357ac4c6ee3c83 Mon Sep 17 00:00:00 2001 From: Sujith Date: Wed, 17 Sep 2008 10:16:07 +0530 Subject: ath9k: Fix TSF Adjust usage TSF adjust is needed only for AP mode when staggered beacons are used. Since we support only a single interface in IBSS mode, disable setting the TSF adjust register. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index c262ef279ff3..690f7c56af3d 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -534,7 +534,8 @@ int ath_vap_attach(struct ath_softc *sc, avp->av_opmode = opmode; avp->av_bslot = -1; - ath9k_hw_set_tsfadjust(sc->sc_ah, 1); + if (opmode == ATH9K_M_HOSTAP) + ath9k_hw_set_tsfadjust(sc->sc_ah, 1); sc->sc_vaps[if_id] = avp; sc->sc_nvaps++; -- cgit v1.2.1 From 4b7679a561e552eeda1e3567119bef2bca99b66e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 18 Sep 2008 18:14:18 +0200 Subject: mac80211: clean up rate control API Long awaited, hard work. This patch totally cleans up the rate control API to remove the requirement to include internal headers outside of net/mac80211/. There's one internal use in the PID algorithm left for mesh networking, we'll have to figure out a way to clean that one up and decide how to do the peer link evaluation, possibly independent of the rate control algorithm or via new API. Additionally, ath9k is left using the cross-inclusion hack for now, we will add new API where necessary to make this work properly, but right now I'm not expert enough to do it. It's still off better than before. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/rc.c | 98 ++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 56 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 1cc9daf44550..cca2fc5b0765 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -20,6 +20,7 @@ */ #include "core.h" +/* FIXME: remove this include! */ #include "../net/mac80211/rate.h" static u32 tx_triglevel_max; @@ -1812,20 +1813,18 @@ static void ath_rc_sib_init(struct ath_rate_node *ath_rc_priv) } -static void ath_setup_rates(struct ieee80211_local *local, struct sta_info *sta) +static void ath_setup_rates(struct ath_softc *sc, + struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, + struct ath_rate_node *rc_priv) { - struct ieee80211_supported_band *sband; - struct ieee80211_hw *hw = local_to_hw(local); - struct ath_softc *sc = hw->priv; - struct ath_rate_node *rc_priv = sta->rate_ctrl_priv; int i, j = 0; DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); - sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; for (i = 0; i < sband->n_bitrates; i++) { - if (sta->sta.supp_rates[local->hw.conf.channel->band] & BIT(i)) { + if (sta->supp_rates[sband->band] & BIT(i)) { rc_priv->neg_rates.rs_rates[j] = (sband->bitrates[i].bitrate * 2) / 10; j++; @@ -1852,19 +1851,17 @@ void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv) } /* Rate Control callbacks */ -static void ath_tx_status(void *priv, struct net_device *dev, +static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, struct sk_buff *skb) { struct ath_softc *sc = priv; struct ath_tx_info_priv *tx_info_priv; struct ath_node *an; - struct sta_info *sta; - struct ieee80211_local *local; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr; __le16 fc; - local = hw_to_local(sc->hw); hdr = (struct ieee80211_hdr *)skb->data; fc = hdr->frame_control; tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0]; @@ -1873,8 +1870,7 @@ static void ath_tx_status(void *priv, struct net_device *dev, an = ath_node_find(sc, hdr->addr1); spin_unlock_bh(&sc->node_lock); - sta = sta_info_get(local, hdr->addr1); - if (!an || !sta || !ieee80211_is_data(fc)) { + if (!an || !priv_sta || !ieee80211_is_data(fc)) { if (tx_info->driver_data[0] != NULL) { kfree(tx_info->driver_data[0]); tx_info->driver_data[0] = NULL; @@ -1882,24 +1878,22 @@ static void ath_tx_status(void *priv, struct net_device *dev, return; } if (tx_info->driver_data[0] != NULL) { - ath_rate_tx_complete(sc, an, sta->rate_ctrl_priv, tx_info_priv); + ath_rate_tx_complete(sc, an, priv_sta, tx_info_priv); kfree(tx_info->driver_data[0]); tx_info->driver_data[0] = NULL; } } static void ath_tx_aggr_resp(struct ath_softc *sc, - struct sta_info *sta, + struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, struct ath_node *an, u8 tidno) { - struct ieee80211_hw *hw = sc->hw; - struct ieee80211_local *local; struct ath_atx_tid *txtid; - struct ieee80211_supported_band *sband; u16 buffersize = 0; int state; - DECLARE_MAC_BUF(mac); + struct sta_info *si; if (!(sc->sc_flags & SC_OP_TXAGGR)) return; @@ -1908,11 +1902,16 @@ static void ath_tx_aggr_resp(struct ath_softc *sc, if (!txtid->paused) return; - local = hw_to_local(sc->hw); - sband = hw->wiphy->bands[hw->conf.channel->band]; + /* + * XXX: This is entirely busted, we aren't supposed to + * access the sta from here because it's internal + * to mac80211, and looking at the state without + * locking is wrong too. + */ + si = container_of(sta, struct sta_info, sta); buffersize = IEEE80211_MIN_AMPDU_BUF << sband->ht_info.ampdu_factor; /* FIXME */ - state = sta->ampdu_mlme.tid_state_tx[tidno]; + state = si->ampdu_mlme.tid_state_tx[tidno]; if (state & HT_ADDBA_RECEIVED_MSK) { txtid->addba_exchangecomplete = 1; @@ -1928,18 +1927,15 @@ static void ath_tx_aggr_resp(struct ath_softc *sc, } } -static void ath_get_rate(void *priv, struct net_device *dev, - struct ieee80211_supported_band *sband, - struct sk_buff *skb, - struct rate_selection *sel) +static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, + struct sk_buff *skb, struct rate_selection *sel) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct sta_info *sta; - struct ath_softc *sc = (struct ath_softc *)priv; + struct ath_softc *sc = priv; struct ieee80211_hw *hw = sc->hw; struct ath_tx_info_priv *tx_info_priv; - struct ath_rate_node *ath_rc_priv; + struct ath_rate_node *ath_rc_priv = priv_sta; struct ath_node *an; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); int is_probe = FALSE, chk, ret; @@ -1955,8 +1951,7 @@ static void ath_get_rate(void *priv, struct net_device *dev, ASSERT(tx_info->driver_data[0] != NULL); tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0]; - sta = sta_info_get(local, hdr->addr1); - lowest_idx = rate_lowest_index(local, sband, sta); + lowest_idx = rate_lowest_index(sband, sta); tx_info_priv->min_rate = (sband->bitrates[lowest_idx].bitrate * 2) / 10; /* lowest rate for management and multicast/broadcast frames */ if (!ieee80211_is_data(fc) || @@ -1965,8 +1960,6 @@ static void ath_get_rate(void *priv, struct net_device *dev, return; } - ath_rc_priv = sta->rate_ctrl_priv; - /* Find tx rate for unicast frames */ ath_rate_findrate(sc, ath_rc_priv, ATH_11N_TXMAXTRY, 4, @@ -1975,8 +1968,7 @@ static void ath_get_rate(void *priv, struct net_device *dev, &is_probe, false); if (is_probe) - sel->probe_idx = ((struct ath_tx_ratectrl *) - sta->rate_ctrl_priv)->probe_rate; + sel->probe_idx = ath_rc_priv->tx_ratectrl.probe_rate; /* Ratecontrol sometimes returns invalid rate index */ if (tx_info_priv->rcs[0].rix != 0xff) @@ -2020,37 +2012,31 @@ static void ath_get_rate(void *priv, struct net_device *dev, __func__, print_mac(mac, hdr->addr1)); } else if (chk == AGGR_EXCHANGE_PROGRESS) - ath_tx_aggr_resp(sc, sta, an, tid); + ath_tx_aggr_resp(sc, sband, sta, an, tid); } } } -static void ath_rate_init(void *priv, void *priv_sta, - struct ieee80211_local *local, - struct sta_info *sta) +static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta) { - struct ieee80211_supported_band *sband; - struct ieee80211_hw *hw = local_to_hw(local); - struct ieee80211_conf *conf = &local->hw.conf; - struct ath_softc *sc = hw->priv; + struct ath_softc *sc = priv; struct ath_rate_node *ath_rc_priv = priv_sta; int i, j = 0; DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); - sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; - - ath_setup_rates(local, sta); - if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { + ath_setup_rates(sc, sband, sta, ath_rc_priv); + if (sc->hw->conf.flags & IEEE80211_CONF_SUPPORT_HT_MODE) { for (i = 0; i < MCS_SET_SIZE; i++) { - if (conf->ht_conf.supp_mcs_set[i/8] & (1<<(i%8))) + if (sc->hw->conf.ht_conf.supp_mcs_set[i/8] & (1<<(i%8))) ath_rc_priv->neg_ht_rates.rs_rates[j++] = i; if (j == ATH_RATE_MAX) break; } ath_rc_priv->neg_ht_rates.rs_nrates = j; } - ath_rc_node_update(hw, priv_sta); + ath_rc_node_update(sc->hw, priv_sta); } static void ath_rate_clear(void *priv) @@ -2058,13 +2044,12 @@ static void ath_rate_clear(void *priv) return; } -static void *ath_rate_alloc(struct ieee80211_local *local) +static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) { - struct ieee80211_hw *hw = local_to_hw(local); struct ath_softc *sc = hw->priv; DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); - return local->hw.priv; + return hw->priv; } static void ath_rate_free(void *priv) @@ -2072,7 +2057,7 @@ static void ath_rate_free(void *priv) return; } -static void *ath_rate_alloc_sta(void *priv, gfp_t gfp) +static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) { struct ath_softc *sc = priv; struct ath_vap *avp = sc->sc_vaps[0]; @@ -2092,7 +2077,8 @@ static void *ath_rate_alloc_sta(void *priv, gfp_t gfp) return rate_priv; } -static void ath_rate_free_sta(void *priv, void *priv_sta) +static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta, + void *priv_sta) { struct ath_rate_node *rate_priv = priv_sta; struct ath_softc *sc = priv; @@ -2111,7 +2097,7 @@ static struct rate_control_ops ath_rate_ops = { .alloc = ath_rate_alloc, .free = ath_rate_free, .alloc_sta = ath_rate_alloc_sta, - .free_sta = ath_rate_free_sta + .free_sta = ath_rate_free_sta, }; int ath_rate_control_register(void) -- cgit v1.2.1 From e6c948e8b8e565c7666ea482994e422c4f19ea44 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 22 Sep 2008 01:14:02 -0700 Subject: ath9k: Add a few comments about mibevents Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/hw.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 0251e59f2f84..272c75816609 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -2526,6 +2526,11 @@ static void ath9k_ani_reset(struct ath_hal *ah) } } +/* + * Process a MIB interrupt. We may potentially be invoked because + * any of the MIB counters overflow/trigger so don't assume we're + * here because a PHY error counter triggered. + */ void ath9k_hw_procmibevent(struct ath_hal *ah, const struct ath9k_node_stats *stats) { @@ -2533,18 +2538,20 @@ void ath9k_hw_procmibevent(struct ath_hal *ah, u32 phyCnt1, phyCnt2; DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Processing Mib Intr\n"); - + /* Reset these counters regardless */ REG_WRITE(ah, AR_FILT_OFDM, 0); REG_WRITE(ah, AR_FILT_CCK, 0); if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING)) REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); + /* Clear the mib counters and save them in the stats */ ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats); ahp->ah_stats.ast_nodestats = *stats; if (!DO_ANI(ah)) return; + /* NB: these are not reset-on-read */ phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || @@ -2552,6 +2559,7 @@ void ath9k_hw_procmibevent(struct ath_hal *ah, struct ar5416AniState *aniState = ahp->ah_curani; u32 ofdmPhyErrCnt, cckPhyErrCnt; + /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */ ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; ahp->ah_stats.ast_ani_ofdmerrs += ofdmPhyErrCnt - aniState->ofdmPhyErrCount; @@ -2562,11 +2570,17 @@ void ath9k_hw_procmibevent(struct ath_hal *ah, cckPhyErrCnt - aniState->cckPhyErrCount; aniState->cckPhyErrCount = cckPhyErrCnt; + /* + * NB: figure out which counter triggered. If both + * trigger we'll only deal with one as the processing + * clobbers the error counter so the trigger threshold + * check will never be true. + */ if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh) ath9k_hw_ani_ofdm_err_trigger(ah); if (aniState->cckPhyErrCount > aniState->cckTrigHigh) ath9k_hw_ani_cck_err_trigger(ah); - + /* NB: always restart to insure the h/w counters are reset */ ath9k_ani_restart(ah); } } -- cgit v1.2.1 From 8ec8ebaeceedf3a845f9e23885f26d0d00eefeb7 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 6 Oct 2008 16:16:38 -0400 Subject: ath9k: fixup some merge damage This hunk was originally removed as part of "ath9k: Fix IRQ nobody cared issue with ath9k". Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 6c433a4d003e..d7f5257d2ec1 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -288,8 +288,6 @@ static int ath_stop(struct ath_softc *sc) * hardware is gone (invalid). */ - if (!(sc->sc_flags & SC_OP_INVALID)) - ath9k_hw_set_interrupts(ah, 0); ath_draintxq(sc, false); if (!(sc->sc_flags & SC_OP_INVALID)) { ath_stoprecv(sc); -- cgit v1.2.1 From 0345f37be64905846a1ef38378061d4c2730242e Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Fri, 3 Oct 2008 15:45:25 -0700 Subject: ath9k: kill ath9k's memzero() and use memset() instead Part of the cleanup on ath9k -- this was also causing some annoying compile time warnings. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/beacon.c | 8 ++++---- drivers/net/wireless/ath9k/core.c | 14 +++++++------- drivers/net/wireless/ath9k/core.h | 5 +---- drivers/net/wireless/ath9k/recv.c | 4 ++-- drivers/net/wireless/ath9k/xmit.c | 10 +++++----- 5 files changed, 19 insertions(+), 22 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index eedb465d25d3..9e15c30bbc06 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -129,7 +129,7 @@ static void ath_beacon_setup(struct ath_softc *sc, ds /* first descriptor */ ); - memzero(series, sizeof(struct ath9k_11n_rate_series) * 4); + memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); series[0].Tries = 1; series[0].Rate = rate; series[0].ChSel = sc->sc_tx_chainmask; @@ -282,7 +282,7 @@ int ath_beaconq_setup(struct ath_hal *ah) { struct ath9k_tx_queue_info qi; - memzero(&qi, sizeof(qi)); + memset(&qi, 0, sizeof(qi)); qi.tqi_aifs = 1; qi.tqi_cwmin = 0; qi.tqi_cwmax = 0; @@ -662,7 +662,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) else av_opmode = sc->sc_ah->ah_opmode; - memzero(&conf, sizeof(struct ath_beacon_config)); + memset(&conf, 0, sizeof(struct ath_beacon_config)); conf.beacon_interval = sc->hw->conf.beacon_int ? sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL; @@ -738,7 +738,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) } } while (nexttbtt < tsftu); #undef FUDGE - memzero(&bs, sizeof(bs)); + memset(&bs, 0, sizeof(bs)); bs.bs_intval = intval; bs.bs_nexttbtt = nexttbtt; bs.bs_dtimperiod = dtimperiod*intval; diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index d7f5257d2ec1..5af7dfbd423d 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -65,7 +65,7 @@ static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) for (i = 0; i < rt->rateCount; i++) sc->sc_rixmap[rt->info[i].rateCode] = (u8) i; - memzero(sc->sc_hwmap, sizeof(sc->sc_hwmap)); + memset(sc->sc_hwmap, 0, sizeof(sc->sc_hwmap)); for (i = 0; i < 256; i++) { u8 ix = rt->rateCodeToIndex[i]; @@ -417,7 +417,7 @@ static void ath_chainmask_sel_init(struct ath_softc *sc, struct ath_node *an) { struct ath_chainmask_sel *cm = &an->an_chainmask_sel; - memzero(cm, sizeof(struct ath_chainmask_sel)); + memset(cm, 0, sizeof(struct ath_chainmask_sel)); cm->cur_tx_mask = sc->sc_tx_chainmask; cm->cur_rx_mask = sc->sc_rx_chainmask; @@ -526,7 +526,7 @@ int ath_vap_attach(struct ath_softc *sc, if (avp == NULL) return -ENOMEM; - memzero(avp, sizeof(struct ath_vap)); + memset(avp, 0, sizeof(struct ath_vap)); avp->av_if_data = if_data; /* Set the VAP opmode */ avp->av_opmode = opmode; @@ -1219,7 +1219,7 @@ struct ath_node *ath_node_attach(struct ath_softc *sc, u8 *addr, int if_id) an = kmalloc(sizeof(struct ath_node), GFP_ATOMIC); if (an == NULL) return NULL; - memzero(an, sizeof(*an)); + memset(an, 0, sizeof(*an)); an->an_sc = sc; memcpy(an->an_addr, addr, ETH_ALEN); @@ -1606,7 +1606,7 @@ int ath_descdma_setup(struct ath_softc *sc, error = -ENOMEM; goto fail2; } - memzero(bf, bsize); + memset(bf, 0, bsize); dd->dd_bufptr = bf; INIT_LIST_HEAD(head); @@ -1638,7 +1638,7 @@ fail2: pci_free_consistent(sc->pdev, dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr); fail: - memzero(dd, sizeof(*dd)); + memset(dd, 0, sizeof(*dd)); return error; #undef ATH_DESC_4KB_BOUND_CHECK #undef ATH_DESC_4KB_BOUND_NUM_SKIPPED @@ -1663,7 +1663,7 @@ void ath_descdma_cleanup(struct ath_softc *sc, INIT_LIST_HEAD(head); kfree(dd->dd_bufptr); - memzero(dd, sizeof(*dd)); + memset(dd, 0, sizeof(*dd)); } /*************/ diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 872f0c5a0b0e..80814c9910c9 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -84,9 +84,6 @@ struct ath_node; #define TSF_TO_TU(_h,_l) \ ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) -/* XXX: remove */ -#define memzero(_buf, _len) memset(_buf, 0, _len) - #define ATH9K_BH_STATUS_INTACT 0 #define ATH9K_BH_STATUS_CHANGE 1 @@ -184,7 +181,7 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht); (_bf)->bf_lastbf = NULL; \ (_bf)->bf_lastfrm = NULL; \ (_bf)->bf_next = NULL; \ - memzero(&((_bf)->bf_state), \ + memset(&((_bf)->bf_state), 0, \ sizeof(struct ath_buf_state)); \ } while (0) diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 498256309ab7..f4be5d11c9d5 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -892,7 +892,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) hdr = (struct ieee80211_hdr *)skb->data; fc = hdr->frame_control; - memzero(&rx_status, sizeof(struct ath_recv_status)); + memset(&rx_status, 0, sizeof(struct ath_recv_status)); if (ds->ds_rxstat.rs_more) { /* @@ -1166,7 +1166,7 @@ int ath_rx_aggr_start(struct ath_softc *sc, } else { /* Ensure the memory is zeroed out (all internal * pointers are null) */ - memzero(rxtid->rxbuf, ATH_TID_MAX_BUFS * + memset(rxtid->rxbuf, 0, ATH_TID_MAX_BUFS * sizeof(struct ath_rxbuf)); DPRINTF(sc, ATH_DBG_AGGR, "%s: Allocated @%p\n", __func__, rxtid->rxbuf); diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 25929059c7dc..bdcb9e1799ca 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -729,7 +729,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) /* * Setup HAL rate series */ - memzero(series, sizeof(struct ath9k_11n_rate_series) * 4); + memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); for (i = 0; i < 4; i++) { if (!bf->bf_rcs[i].tries) @@ -817,7 +817,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) * Disable multi-rate retry when using RTS/CTS by clearing * series 1, 2 and 3. */ - memzero(&series[1], sizeof(struct ath9k_11n_rate_series) * 3); + memset(&series[1], 0, sizeof(struct ath9k_11n_rate_series) * 3); } /* @@ -930,7 +930,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3); } else { - memzero(ba, WME_BA_BMP_SIZE >> 3); + memset(ba, 0, WME_BA_BMP_SIZE >> 3); /* * AR5416 can become deaf/mute when BA @@ -943,7 +943,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, needreset = 1; } } else { - memzero(ba, WME_BA_BMP_SIZE >> 3); + memset(ba, 0, WME_BA_BMP_SIZE >> 3); } } @@ -2098,7 +2098,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) struct ath9k_tx_queue_info qi; int qnum; - memzero(&qi, sizeof(qi)); + memset(&qi, 0, sizeof(qi)); qi.tqi_subtype = subtype; qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; -- cgit v1.2.1 From a477e4e6d48d3ac7c7a75bad40585cb391e5c237 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Fri, 3 Oct 2008 15:45:26 -0700 Subject: ath9k: fix oops on trying to hold the wrong spinlock We were trying to hold the wrong spinlock due to a typo on IEEE80211_BAR_CTL_TID_S's definition. We use this to compute the tid number and then hold this this tid number's spinlock. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Sujith Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 80814c9910c9..5b4f1c48a618 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -309,7 +309,7 @@ void ath_descdma_cleanup(struct ath_softc *sc, #define ATH_RX_TIMEOUT 40 /* 40 milliseconds */ #define WME_NUM_TID 16 #define IEEE80211_BAR_CTL_TID_M 0xF000 /* tid mask */ -#define IEEE80211_BAR_CTL_TID_S 2 /* tid shift */ +#define IEEE80211_BAR_CTL_TID_S 12 /* tid shift */ enum ATH_RX_TYPE { ATH_RX_NON_CONSUMED = 0, -- cgit v1.2.1 From 6f255425ac3b10c3352c926e7b53e5ea1c364ca4 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Fri, 3 Oct 2008 15:45:27 -0700 Subject: ath9k: enable ANI to help with noisy environments This enables Adaptive Noise Immunity (ANI) on ath9k. ANI is as algorithm designed to minimize the detrimental effects of time-varying interferences. This should help with throughput in noisy environments. To use ANI we re-enable the MIB interrupt. Since ANI works on a timer and updates the noise floor we take advantage of this and also report a non-static noise floor now to mac80211. Signed-off-by: Sujith Manoharan Signed-off-by: Jouni Malinen Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath9k/core.c | 129 +++++++++++++++++++++++++++++++++++-- drivers/net/wireless/ath9k/core.h | 25 +++++++ drivers/net/wireless/ath9k/hw.c | 35 ++++++++-- drivers/net/wireless/ath9k/main.c | 18 +++++- drivers/net/wireless/ath9k/recv.c | 13 +--- 6 files changed, 197 insertions(+), 25 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 0e897c276858..accace5f7efb 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -854,7 +854,7 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, u8 rxchainmask, bool longcal, bool *isCalDone); -int16_t ath9k_hw_getchan_noise(struct ath_hal *ah, +s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan); void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId); diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 5af7dfbd423d..c5033f6f42ac 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -490,6 +490,122 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht) __func__, sc->sc_tx_chainmask, sc->sc_rx_chainmask); } +/*******/ +/* ANI */ +/*******/ + +/* + * This routine performs the periodic noise floor calibration function + * that is used to adjust and optimize the chip performance. This + * takes environmental changes (location, temperature) into account. + * When the task is complete, it reschedules itself depending on the + * appropriate interval that was calculated. + */ + +static void ath_ani_calibrate(unsigned long data) +{ + struct ath_softc *sc; + struct ath_hal *ah; + bool longcal = false; + bool shortcal = false; + bool aniflag = false; + unsigned int timestamp = jiffies_to_msecs(jiffies); + u32 cal_interval; + + sc = (struct ath_softc *)data; + ah = sc->sc_ah; + + /* + * don't calibrate when we're scanning. + * we are most likely not on our home channel. + */ + if (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC) + return; + + /* Long calibration runs independently of short calibration. */ + if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) { + longcal = true; + DPRINTF(sc, ATH_DBG_ANI, "%s: longcal @%lu\n", + __func__, jiffies); + sc->sc_ani.sc_longcal_timer = timestamp; + } + + /* Short calibration applies only while sc_caldone is false */ + if (!sc->sc_ani.sc_caldone) { + if ((timestamp - sc->sc_ani.sc_shortcal_timer) >= + ATH_SHORT_CALINTERVAL) { + shortcal = true; + DPRINTF(sc, ATH_DBG_ANI, "%s: shortcal @%lu\n", + __func__, jiffies); + sc->sc_ani.sc_shortcal_timer = timestamp; + sc->sc_ani.sc_resetcal_timer = timestamp; + } + } else { + if ((timestamp - sc->sc_ani.sc_resetcal_timer) >= + ATH_RESTART_CALINTERVAL) { + ath9k_hw_reset_calvalid(ah, ah->ah_curchan, + &sc->sc_ani.sc_caldone); + if (sc->sc_ani.sc_caldone) + sc->sc_ani.sc_resetcal_timer = timestamp; + } + } + + /* Verify whether we must check ANI */ + if ((timestamp - sc->sc_ani.sc_checkani_timer) >= + ATH_ANI_POLLINTERVAL) { + aniflag = true; + sc->sc_ani.sc_checkani_timer = timestamp; + } + + /* Skip all processing if there's nothing to do. */ + if (longcal || shortcal || aniflag) { + /* Call ANI routine if necessary */ + if (aniflag) + ath9k_hw_ani_monitor(ah, &sc->sc_halstats, + ah->ah_curchan); + + /* Perform calibration if necessary */ + if (longcal || shortcal) { + bool iscaldone = false; + + if (ath9k_hw_calibrate(ah, ah->ah_curchan, + sc->sc_rx_chainmask, longcal, + &iscaldone)) { + if (longcal) + sc->sc_ani.sc_noise_floor = + ath9k_hw_getchan_noise(ah, + ah->ah_curchan); + + DPRINTF(sc, ATH_DBG_ANI, + "%s: calibrate chan %u/%x nf: %d\n", + __func__, + ah->ah_curchan->channel, + ah->ah_curchan->channelFlags, + sc->sc_ani.sc_noise_floor); + } else { + DPRINTF(sc, ATH_DBG_ANY, + "%s: calibrate chan %u/%x failed\n", + __func__, + ah->ah_curchan->channel, + ah->ah_curchan->channelFlags); + } + sc->sc_ani.sc_caldone = iscaldone; + } + } + + /* + * Set timer interval based on previous results. + * The interval must be the shortest necessary to satisfy ANI, + * short calibration and long calibration. + */ + + cal_interval = ATH_ANI_POLLINTERVAL; + if (!sc->sc_ani.sc_caldone) + cal_interval = min(cal_interval, (u32)ATH_SHORT_CALINTERVAL); + + mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(cal_interval)); +} + /******************/ /* VAP management */ /******************/ @@ -676,12 +792,6 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) sc->sc_imask |= ATH9K_INT_CST; - /* Note: We disable MIB interrupts for now as we don't yet - * handle processing ANI, otherwise you will get an interrupt - * storm after about 7 hours of usage making the system unusable - * with huge latency. Once we do have ANI processing included - * we can re-enable this interrupt. */ -#if 0 /* * Enable MIB interrupts when there are hardware phy counters. * Note we only do this (at the moment) for station mode. @@ -690,7 +800,6 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) ((sc->sc_ah->ah_opmode == ATH9K_M_STA) || (sc->sc_ah->ah_opmode == ATH9K_M_IBSS))) sc->sc_imask |= ATH9K_INT_MIB; -#endif /* * Some hardware processes the TIM IE and fires an * interrupt when the TIM bit is set. For hardware @@ -991,6 +1100,10 @@ int ath_init(u16 devid, struct ath_softc *sc) } sc->sc_ah = ah; + /* Initializes the noise floor to a reasonable default value. + * Later on this will be updated during ANI processing. */ + sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR; + /* Get the hardware key cache size. */ sc->sc_keymax = ah->ah_caps.keycache_size; if (sc->sc_keymax > ATH_KEYMAX) { @@ -1098,6 +1211,8 @@ int ath_init(u16 devid, struct ath_softc *sc) goto bad2; } + setup_timer(&sc->sc_ani.timer, ath_ani_calibrate, (unsigned long)sc); + sc->sc_rc = ath_rate_attach(ah); if (sc->sc_rc == NULL) { error = -EIO; diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 5b4f1c48a618..cb3e61e57c4d 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -800,6 +800,28 @@ void ath_slow_ant_div(struct ath_antdiv *antdiv, struct ath_rx_status *rx_stats); void ath_setdefantenna(void *sc, u32 antenna); +/*******/ +/* ANI */ +/*******/ + +/* ANI values for STA only. + FIXME: Add appropriate values for AP later */ + +#define ATH_ANI_POLLINTERVAL 100 /* 100 milliseconds between ANI poll */ +#define ATH_SHORT_CALINTERVAL 1000 /* 1 second between calibrations */ +#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds between calibrations */ +#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes between calibrations */ + +struct ath_ani { + bool sc_caldone; + int16_t sc_noise_floor; + unsigned int sc_longcal_timer; + unsigned int sc_shortcal_timer; + unsigned int sc_resetcal_timer; + unsigned int sc_checkani_timer; + struct timer_list timer; +}; + /********************/ /* LED Control */ /********************/ @@ -1028,6 +1050,9 @@ struct ath_softc { /* Rfkill */ struct ath_rfkill rf_kill; + + /* ANI */ + struct ath_ani sc_ani; }; int ath_init(u16 devid, struct ath_softc *sc); diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 272c75816609..62e44a0ef996 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -329,7 +329,7 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah) ah->ah_config.ofdm_trig_high = 500; ah->ah_config.cck_trig_high = 200; ah->ah_config.cck_trig_low = 100; - ah->ah_config.enable_ani = 0; + ah->ah_config.enable_ani = 1; ah->ah_config.noise_immunity_level = 4; ah->ah_config.ofdm_weaksignal_det = 1; ah->ah_config.cck_weaksignal_thr = 0; @@ -8405,23 +8405,48 @@ u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags) } } -int16_t +/* We can tune this as we go by monitoring really low values */ +#define ATH9K_NF_TOO_LOW -60 + +/* AR5416 may return very high value (like -31 dBm), in those cases the nf + * is incorrect and we should use the static NF value. Later we can try to + * find out why they are reporting these values */ +static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf) +{ + if (nf > ATH9K_NF_TOO_LOW) { + DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, + "%s: noise floor value detected (%d) is " + "lower than what we think is a " + "reasonable value (%d)\n", + __func__, nf, ATH9K_NF_TOO_LOW); + return false; + } + return true; +} + +s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan) { struct ath9k_channel *ichan; + s16 nf; ichan = ath9k_regd_check_channel(ah, chan); if (ichan == NULL) { DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, "%s: invalid channel %u/0x%x; no mapping\n", __func__, chan->channel, chan->channelFlags); - return 0; + return ATH_DEFAULT_NOISE_FLOOR; } if (ichan->rawNoiseFloor == 0) { enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan); - return NOISE_FLOOR[mode]; + nf = NOISE_FLOOR[mode]; } else - return ichan->rawNoiseFloor; + nf = ichan->rawNoiseFloor; + + if (!ath9k_hw_nf_in_range(ah, nf)) + nf = ATH_DEFAULT_NOISE_FLOOR; + + return nf; } bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting) diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 2caba4403167..74726990d59e 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -274,10 +274,12 @@ static void ath9k_rx_prepare(struct ath_softc *sc, rx_status->mactime = status->tsf; rx_status->band = curchan->band; rx_status->freq = curchan->center_freq; - rx_status->noise = ATH_DEFAULT_NOISE_FLOOR; + rx_status->noise = sc->sc_ani.sc_noise_floor; rx_status->signal = rx_status->noise + status->rssi; rx_status->rate_idx = ath_rate2idx(sc, (status->rateKbps / 100)); rx_status->antenna = status->antenna; + + /* XXX Fix me, 64 cannot be the max rssi value, rigure it out */ rx_status->qual = status->rssi * 100 / 64; if (status->flags & ATH_RX_MIC_ERROR) @@ -427,6 +429,11 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, ath_rate_newstate(sc, avp); /* Update ratectrl about the new state */ ath_rc_node_update(hw, avp->rc_node); + + /* Start ANI */ + mod_timer(&sc->sc_ani.timer, + jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); + } else { DPRINTF(sc, ATH_DBG_CONFIG, "%s: Bss Info DISSOC\n", __func__); @@ -1173,6 +1180,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, return error; } + if (conf->type == NL80211_IFTYPE_AP) { + /* TODO: is this a suitable place to start ANI for AP mode? */ + /* Start ANI */ + mod_timer(&sc->sc_ani.timer, + jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); + } + return 0; } @@ -1195,6 +1209,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, #ifdef CONFIG_SLOW_ANT_DIV ath_slow_ant_div_stop(&sc->sc_antdiv); #endif + /* Stop ANI */ + del_timer_sync(&sc->sc_ani.timer); /* Update ratectrl */ ath_rate_newstate(sc, avp); diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index f4be5d11c9d5..4983402af559 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -999,20 +999,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) rx_status.flags |= ATH_RX_SHORT_GI; } - /* sc->sc_noise_floor is only available when the station + /* sc_noise_floor is only available when the station attaches to an AP, so we use a default value if we are not yet attached. */ - - /* XXX we should use either sc->sc_noise_floor or - * ath_hal_getChanNoise(ah, &sc->sc_curchan) - * to calculate the noise floor. - * However, the value returned by ath_hal_getChanNoise - * seems to be incorrect (-31dBm on the last test), - * so we will use a hard-coded value until we - * figure out what is going on. - */ rx_status.abs_rssi = - ds->ds_rxstat.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; + ds->ds_rxstat.rs_rssi + sc->sc_ani.sc_noise_floor; pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr, -- cgit v1.2.1 From 76708dee382a69b2f9d0e50f413f99fefb2dc509 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 5 Oct 2008 18:02:48 +0200 Subject: mac80211: free up 2 bytes in skb->cb Free up 2 bytes in skb->cb to be used for multi-rate retry later. Move iv_len and icv_len initialization into key alloc. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/xmit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index bdcb9e1799ca..3a4757942b3f 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -237,7 +237,7 @@ static int ath_tx_prepare(struct ath_softc *sc, if (tx_info->control.hw_key) { txctl->keyix = tx_info->control.hw_key->hw_key_idx; - txctl->frmlen += tx_info->control.icv_len; + txctl->frmlen += tx_info->control.hw_key->icv_len; if (tx_info->control.hw_key->alg == ALG_WEP) txctl->keytype = ATH9K_KEY_TYPE_WEP; -- cgit v1.2.1 From 1cf69cfbe117d645640a9230d6deb07c9db46c5f Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Fri, 10 Oct 2008 12:25:45 -0700 Subject: ath9k: remove nasty FAIL macro from ath9k_hw_reset() This is fucking horribe crap code so nuke it. There I cursed too in a commit log. Signed-off-by: Luis R. Rodriguez Signed-off-by: David S. Miller --- drivers/net/wireless/ath9k/hw.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 62e44a0ef996..372ae61c7b17 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -5867,7 +5867,6 @@ bool ath9k_hw_reset(struct ath_hal *ah, bool bChannelChange, int *status) { -#define FAIL(_code) do { ecode = _code; goto bad; } while (0) u32 saveLedState; struct ath_hal_5416 *ahp = AH5416(ah); struct ath9k_channel *curchan = ah->ah_curchan; @@ -5889,7 +5888,8 @@ bool ath9k_hw_reset(struct ath_hal *ah, DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid channel %u/0x%x; no mapping\n", __func__, chan->channel, chan->channelFlags); - FAIL(-EINVAL); + ecode = -EINVAL; + goto bad; } if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) @@ -5930,7 +5930,8 @@ bool ath9k_hw_reset(struct ath_hal *ah, if (!ath9k_hw_chip_reset(ah, chan)) { DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n", __func__); - FAIL(-EIO); + ecode = -EINVAL; + goto bad; } if (AR_SREV_9280(ah)) { @@ -5947,8 +5948,10 @@ bool ath9k_hw_reset(struct ath_hal *ah, } ecode = ath9k_hw_process_ini(ah, chan, macmode); - if (ecode != 0) + if (ecode != 0) { + ecode = -EINVAL; goto bad; + } if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) ath9k_hw_set_delta_slope(ah, chan); @@ -5961,7 +5964,8 @@ bool ath9k_hw_reset(struct ath_hal *ah, if (!ath9k_hw_eeprom_set_board_values(ah, chan)) { DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "%s: error setting board options\n", __func__); - FAIL(-EIO); + ecode = -EIO; + goto bad; } ath9k_hw_decrease_chain_power(ah, chan); @@ -5989,11 +5993,15 @@ bool ath9k_hw_reset(struct ath_hal *ah, REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); if (AR_SREV_9280_10_OR_LATER(ah)) { - if (!(ath9k_hw_ar9280_set_channel(ah, chan))) - FAIL(-EIO); + if (!(ath9k_hw_ar9280_set_channel(ah, chan))) { + ecode = -EIO; + goto bad; + } } else { - if (!(ath9k_hw_set_channel(ah, chan))) - FAIL(-EIO); + if (!(ath9k_hw_set_channel(ah, chan))) { + ecode = -EIO; + goto bad; + } } for (i = 0; i < AR_NUM_DCU; i++) @@ -6027,8 +6035,10 @@ bool ath9k_hw_reset(struct ath_hal *ah, ath9k_hw_init_bb(ah, chan); - if (!ath9k_hw_init_cal(ah, chan)) - FAIL(-ENODEV); + if (!ath9k_hw_init_cal(ah, chan)){ + ecode = -EIO;; + goto bad; + } rx_chainmask = ahp->ah_rxchainmask; if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) { @@ -6064,7 +6074,6 @@ bad: if (status) *status = ecode; return false; -#undef FAIL } bool ath9k_hw_phy_disable(struct ath_hal *ah) -- cgit v1.2.1 From d2a3b222cf976bc44bb9aed13f7b17feea28f633 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Fri, 10 Oct 2008 12:26:24 -0700 Subject: ath9k: Fix return code when ath9k_hw_setpower() fails on reset We were not reporting a status code back ath9k_hw_setpower() failed during reset so lets correct this. Reported-by: Jiri Slaby Signed-off-by: Luis R. Rodriguez Signed-off-by: David S. Miller --- drivers/net/wireless/ath9k/hw.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/ath9k') diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 372ae61c7b17..98bc25c9b3cf 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -5892,8 +5892,10 @@ bool ath9k_hw_reset(struct ath_hal *ah, goto bad; } - if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) - return false; + if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { + ecode = -EIO; + goto bad; + } if (curchan) ath9k_hw_getnf(ah, curchan); -- cgit v1.2.1