Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 172214
b: refs/heads/master
c: e7824a5
h: refs/heads/master
v: v3
  • Loading branch information
Luis R. Rodriguez authored and John W. Linville committed Nov 28, 2009
1 parent 54abd8b commit ecc5383
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6b65b6ad016f048547127946d1afe4ba41c74296
refs/heads/master: e7824a50662f7f79b1a739f705b4d906c31cf221
2 changes: 2 additions & 0 deletions trunk/drivers/net/wireless/ath/ath9k/ath9k.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,8 @@ struct ath_led {
#define SC_OP_WAIT_FOR_TX_ACK BIT(18)
#define SC_OP_BEACON_SYNC BIT(19)
#define SC_OP_BT_PRIORITY_DETECTED BIT(21)
#define SC_OP_NULLFUNC_COMPLETED BIT(22)
#define SC_OP_PS_ENABLED BIT(23)

struct ath_wiphy;
struct ath_rate_table;
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/ath/ath9k/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ struct ath_buf {
dma_addr_t bf_daddr; /* physical addr of desc */
dma_addr_t bf_buf_addr; /* physical addr of data buffer */
bool bf_stale;
bool bf_isnullfunc;
u16 bf_flags;
struct ath_buf_state bf_state;
dma_addr_t bf_dmacontext;
Expand Down
9 changes: 9 additions & 0 deletions trunk/drivers/net/wireless/ath/ath9k/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
ds->ds_txstat.ts_status = 0;
ds->ds_txstat.ts_flags = 0;

if (ads->ds_txstatus1 & AR_FrmXmitOK)
ds->ds_txstat.ts_status |= ATH9K_TX_ACKED;
if (ads->ds_txstatus1 & AR_ExcessiveRetries)
ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
if (ads->ds_txstatus1 & AR_Filtered)
Expand Down Expand Up @@ -926,6 +928,13 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
}
EXPORT_SYMBOL(ath9k_hw_setuprxdesc);

/*
* This can stop or re-enables RX.
*
* If bool is set this will kill any frame which is currently being
* transferred between the MAC and baseband and also prevent any new
* frames from getting started.
*/
bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
{
u32 reg;
Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/net/wireless/ath/ath9k/mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
#define ATH9K_TXERR_FIFO 0x04
#define ATH9K_TXERR_XTXOP 0x08
#define ATH9K_TXERR_TIMER_EXPIRED 0x10
#define ATH9K_TX_ACKED 0x20

#define ATH9K_TX_BA 0x01
#define ATH9K_TX_PWRMGMT 0x02
Expand Down Expand Up @@ -380,6 +381,11 @@ struct ar5416_desc {
#define AR_TxBaStatus 0x40000000
#define AR_TxStatusRsvd01 0x80000000

/*
* AR_FrmXmitOK - Frame transmission success flag. If set, the frame was
* transmitted successfully. If clear, no ACK or BA was received to indicate
* successful transmission when we were expecting an ACK or BA.
*/
#define AR_FrmXmitOK 0x00000001
#define AR_ExcessiveRetries 0x00000002
#define AR_FIFOUnderrun 0x00000004
Expand Down
20 changes: 18 additions & 2 deletions trunk/drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2701,20 +2701,36 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
}
}

/*
* We just prepare to enable PS. We have to wait until our AP has
* ACK'd our null data frame to disable RX otherwise we'll ignore
* those ACKs and end up retransmitting the same null data frames.
* IEEE80211_CONF_CHANGE_PS is only passed by mac80211 for STA mode.
*/
if (changed & IEEE80211_CONF_CHANGE_PS) {
if (conf->flags & IEEE80211_CONF_PS) {
sc->sc_flags |= SC_OP_PS_ENABLED;
if (!(ah->caps.hw_caps &
ATH9K_HW_CAP_AUTOSLEEP)) {
if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
sc->imask |= ATH9K_INT_TIM_TIMER;
ath9k_hw_set_interrupts(sc->sc_ah,
sc->imask);
}
ath9k_hw_setrxabort(sc->sc_ah, 1);
}
sc->ps_enabled = true;
/*
* At this point we know hardware has received an ACK
* of a previously sent null data frame.
*/
if ((sc->sc_flags & SC_OP_NULLFUNC_COMPLETED)) {
sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED;
sc->ps_enabled = true;
ath9k_hw_setrxabort(sc->sc_ah, 1);
}
} else {
sc->ps_enabled = false;
sc->sc_flags &= ~(SC_OP_PS_ENABLED |
SC_OP_NULLFUNC_COMPLETED);
ath9k_setpower(sc, ATH9K_PM_AWAKE);
if (!(ah->caps.hw_caps &
ATH9K_HW_CAP_AUTOSLEEP)) {
Expand Down
15 changes: 12 additions & 3 deletions trunk/drivers/net/wireless/ath/ath9k/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -1332,13 +1332,22 @@ enum {
#define AR_MCAST_FIL0 0x8040
#define AR_MCAST_FIL1 0x8044

/*
* AR_DIAG_SW - Register which can be used for diagnostics and testing purposes.
*
* The force RX abort (AR_DIAG_RX_ABORT, bit 25) can be used in conjunction with
* RX block (AR_DIAG_RX_DIS, bit 5) to help fast channel change to shut down
* receive. The force RX abort bit will kill any frame which is currently being
* transferred between the MAC and baseband. The RX block bit (AR_DIAG_RX_DIS)
* will prevent any new frames from getting started.
*/
#define AR_DIAG_SW 0x8048
#define AR_DIAG_CACHE_ACK 0x00000001
#define AR_DIAG_ACK_DIS 0x00000002
#define AR_DIAG_CTS_DIS 0x00000004
#define AR_DIAG_ENCRYPT_DIS 0x00000008
#define AR_DIAG_DECRYPT_DIS 0x00000010
#define AR_DIAG_RX_DIS 0x00000020
#define AR_DIAG_RX_DIS 0x00000020 /* RX block */
#define AR_DIAG_LOOP_BACK 0x00000040
#define AR_DIAG_CORR_FCS 0x00000080
#define AR_DIAG_CHAN_INFO 0x00000100
Expand All @@ -1347,12 +1356,12 @@ enum {
#define AR_DIAG_FRAME_NV0 0x00020000
#define AR_DIAG_OBS_PT_SEL1 0x000C0000
#define AR_DIAG_OBS_PT_SEL1_S 18
#define AR_DIAG_FORCE_RX_CLEAR 0x00100000
#define AR_DIAG_FORCE_RX_CLEAR 0x00100000 /* force rx_clear high */
#define AR_DIAG_IGNORE_VIRT_CS 0x00200000
#define AR_DIAG_FORCE_CH_IDLE_HIGH 0x00400000
#define AR_DIAG_EIFS_CTRL_ENA 0x00800000
#define AR_DIAG_DUAL_CHAIN_INFO 0x01000000
#define AR_DIAG_RX_ABORT 0x02000000
#define AR_DIAG_RX_ABORT 0x02000000 /* Force RX abort */
#define AR_DIAG_SATURATE_CYCLE_CNT 0x04000000
#define AR_DIAG_OBS_PT_SEL2 0x08000000
#define AR_DIAG_RX_CLEAR_CTL_LOW 0x10000000
Expand Down
21 changes: 21 additions & 0 deletions trunk/drivers/net/wireless/ath/ath9k/xmit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1644,6 +1644,14 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
}

bf->bf_buf_addr = bf->bf_dmacontext;

/* tag if this is a nullfunc frame to enable PS when AP acks it */
if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) {
bf->bf_isnullfunc = true;
sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED;
} else
bf->bf_isnullfunc = false;

return 0;
}

Expand Down Expand Up @@ -2038,6 +2046,19 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
break;
}

/*
* We now know the nullfunc frame has been ACKed so we
* can disable RX.
*/
if (bf->bf_isnullfunc &&
(ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) {
if ((sc->sc_flags & SC_OP_PS_ENABLED)) {
sc->ps_enabled = true;
ath9k_hw_setrxabort(sc->sc_ah, 1);
} else
sc->sc_flags |= SC_OP_NULLFUNC_COMPLETED;
}

/*
* Remove ath_buf's of the same transmit unit from txq,
* however leave the last descriptor back as the holding
Expand Down

0 comments on commit ecc5383

Please sign in to comment.