ath5: descriptor cleanup series
cover ath5: descriptor cleanup series
hi!
this series is a bunch of smaller changes i made while reviewing rx buffer handling and some stuff i picked up while carefully reviewing the descriptor definitions from the HAL against what we have. it's mostly cosmetics and refactoring.
greetings,
bruno
---
Bruno Randolf (17):
ath5k: more debug prints for resets
ath5k: rename ath5k_txbuf_free() to ath5k_txbuf_free_skb()
ath5k: fix some comment typos
ath5k: fix rx descriptor debugging
ath5k: print more errors when decriptor setup fails
ath5k: reset more pointers after we free skbs
ath5k: unify rx descriptor error handling
ath5k: split descriptor handling and frame receive
ath5k: move checks and stats into new function
ath5k: use direct function calls for descriptors when possible
ath5k: cosmetic changes in ath5k_hw_proc_5212_rx_status()
ath5k: remove pointless rx error overlay struct
ath5k: review and add comments for descriptors
ath5k: update 5210/5211 frame types
ath5k: take descriptor differences between 5210 and 5211 into account
ath5k: review RX descriptor functions
ath5k: report PHY error frames only for chips which need it
drivers/net/wireless/ath/ath5k/ath5k.h | 12 + drivers/net/wireless/ath/ath5k/base.c | 335 ++++++++++++++++++-------------- drivers/net/wireless/ath/ath5k/debug.c | 5 drivers/net/wireless/ath/ath5k/desc.c | 145 +++++++------- drivers/net/wireless/ath/ath5k/desc.h | 310 ++++++++++++++---------------- 5 files changed, 409 insertions(+), 398 deletions(-)
Signature · 1 line
Signature
PATCH 1/17 ath5k: more debug prints for resets
Add a debug print for every case of reset.
--- drivers/net/wireless/ath/ath5k/base.c | 14 +++++++++++--- drivers/net/wireless/ath/ath5k/debug.c | 1 + 2 files changed, 12 insertions(+), 3 deletions(-)
drivers/net/wireless/ath/ath5k/base.c +11 -3
@@ -1111,8 +1111,9 @@ ath5k_setup_bands(struct ieee80211_hw *hw)static int ath5k_chan_set (struct ath5k_softc *sc,struct ieee80211_channel *chan) { -ATH5K_DBG (sc,ATH5K_DEBUG_RESET ,"(%u MHz) -> (%u MHz)\n" , - sc->curchan->center_freq, chan->center_freq); +ATH5K_DBG (sc,ATH5K_DEBUG_RESET , +"channel set, resetting (%u -> %u MHz)\n" , + sc->curchan->center_freq, chan->center_freq);/* * To switch channels clear any pending DMA operations;
@@ -2298,6 +2299,8 @@ ath5k_beacon_send(struct ath5k_softc *sc)ATH5K_DBG (sc,ATH5K_DEBUG_BEACON ,"stuck beacon time (%u missed)\n" , sc->bmisscount); +ATH5K_DBG (sc,ATH5K_DEBUG_RESET , +"stuck beacon, resetting\n" );tasklet_schedule (&sc->restq); }return ;
@@ -2705,6 +2708,8 @@ ath5k_intr(int irq, void *dev_id)* Fatal errors are unrecoverable. * Typically these are caused by DMA errors. */ +ATH5K_DBG (sc,ATH5K_DEBUG_RESET , +"fatal int, resetting\n" );tasklet_schedule (&sc->restq); }else if (unlikely (status &AR5K_INT_RXORN )) {/*
@@ -2717,8 +2722,11 @@ ath5k_intr(int irq, void *dev_id)* this guess is copied from the HAL. */ sc->stats.rxorn_intr++; -if (ah->ah_mac_srev <AR5K_SREV_AR5212 ) +if (ah->ah_mac_srev <AR5K_SREV_AR5212 ) { +ATH5K_DBG (sc,ATH5K_DEBUG_RESET , +"rx overrun, resetting\n" );tasklet_schedule (&sc->restq); + }else tasklet_schedule (&sc->rxtq); }else {
drivers/net/wireless/ath/ath5k/debug.c +1 -0
@@ -278,6 +278,7 @@ static ssize_t write_file_reset(struct file *file, size_t count, loff_t *ppos) { struct ath5k_softc *sc = file->private_data; +ATH5K_DBG (sc,ATH5K_DEBUG_RESET ,"debug file triggered reset\n" );tasklet_schedule (&sc->restq);return count; }
PATCH 2/17 ath5k: rename ath5k_txbuf_free() to ath5k_txbuf_free_skb()
In reply to Bruno RandolfRename ath5k_txbuf_free() to ath5k_txbuf_free_skb() since this is what it does:
it frees the skb and not the buf. Same for ath5k_rxbuf_free().
--- drivers/net/wireless/ath/ath5k/base.c | 17 +++++++++-------- 1 files changed, 9 insertions(+), 8 deletions(-)
drivers/net/wireless/ath/ath5k/base.c +9 -8
@@ -311,7 +311,8 @@ static int ath5k_rxbuf_setup(struct ath5k_softc *sc,static int ath5k_txbuf_setup (struct ath5k_softc *sc,struct ath5k_buf *bf,struct ath5k_txq *txq,int padsize); -static inline void ath5k_txbuf_free (struct ath5k_softc *sc, + +static inline void ath5k_txbuf_free_skb (struct ath5k_softc *sc,struct ath5k_buf *bf) {BUG_ON (!bf);
@@ -323,7 +324,7 @@ static inline void ath5k_txbuf_free(struct ath5k_softc *sc, bf->skb =NULL ; } -static inline void ath5k_rxbuf_free (struct ath5k_softc *sc, +static inline void ath5k_rxbuf_free_skb (struct ath5k_softc *sc,struct ath5k_buf *bf) {struct ath5k_hw *ah = sc->ah;
@@ -1444,11 +1445,11 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev) {struct ath5k_buf *bf; -ath5k_txbuf_free (sc, sc->bbuf); +ath5k_txbuf_free_skb (sc, sc->bbuf);list_for_each_entry (bf, &sc->txbuf, list) -ath5k_txbuf_free (sc, bf); +ath5k_txbuf_free_skb (sc, bf);list_for_each_entry (bf, &sc->rxbuf, list) -ath5k_rxbuf_free (sc, bf); +ath5k_rxbuf_free_skb (sc, bf);/* Free memory associated with all descriptors */ pci_free_consistent (pdev, sc->desc_len, sc->desc, sc->desc_daddr);
@@ -1603,7 +1604,7 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)list_for_each_entry_safe (bf, bf0, &txq->q, list) {ath5k_debug_printtxbuf (sc, bf); -ath5k_txbuf_free (sc, bf); +ath5k_txbuf_free_skb (sc, bf);spin_lock_bh (&sc->txbuflock);list_move_tail (&bf->list, &sc->txbuf);
@@ -2650,7 +2651,7 @@ ath5k_stop_hw(struct ath5k_softc *sc)ATH5K_DBG (sc,ATH5K_DEBUG_RESET ,"putting device to sleep\n" ); } -ath5k_txbuf_free (sc, sc->bbuf); +ath5k_txbuf_free_skb (sc, sc->bbuf);mmiowb ();mutex_unlock (&sc->lock);
@@ -3376,7 +3377,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)ath5k_debug_dump_skb (sc, skb,"BC " ,1 ); -ath5k_txbuf_free (sc, sc->bbuf); +ath5k_txbuf_free_skb (sc, sc->bbuf); sc->bbuf->skb = skb; ret =ath5k_beacon_setup (sc, sc->bbuf);if (ret)
PATCH 3/17 ath5k: fix some comment typos
In reply to Bruno RandolfFix comment about dma sizes, brackets were missing. Replace 'insure' with 'ensure'.
--- drivers/net/wireless/ath/ath5k/ath5k.h | 2 +- drivers/net/wireless/ath/ath5k/base.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/net/wireless/ath/ath5k/ath5k.h +1 -1
@@ -566,7 +566,7 @@ enum ath5k_pkt_type { )/* -* DMA size definitions (2^n+2) +* DMA size definitions (2^(n+2)) */ enum ath5k_dmasize {AR5K_DMASIZE_4B =0 ,
drivers/net/wireless/ath/ath5k/base.c +3 -3
@@ -1230,13 +1230,13 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)* not get overrun under high load (as can happen with a * 5212 when ANI processing enables PHY error frames). * -* To insure the last descriptor is self-linked we create +* To ensure the last descriptor is self-linked we create * each descriptor as self-linked and add it to the end. As * each additional descriptor is added the previous self-linked -* entry is ``fixed'' naturally. This should be safe even +* entry is "fixed" naturally. This should be safe even * if DMA is happening. When processing RX interrupts we * never remove/process the last, self-linked, entry on the -* descriptor list. This insures the hardware always has +* descriptor list. This ensures the hardware always has * someplace to write a new frame. */ ds = bf->desc;
PATCH 4/17 ath5k: fix rx descriptor debugging
In reply to Bruno RandolfIn the debug ouptut rx_status_0 was printed twice instead of rx_status_1. Also make the debug message more clear.
--- drivers/net/wireless/ath/ath5k/debug.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath5k/debug.c +2 -2
@@ -925,7 +925,7 @@ ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done, ds, (unsigned long long )bf->daddr, ds->ds_link, ds->ds_data, rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1, - rd->u.rx_stat.rx_status_0, rd->u.rx_stat.rx_status_0, + rd->u.rx_stat.rx_status_0, rd->u.rx_stat.rx_status_1, !done ? ' ' : (rs->rs_status == 0) ? '*' : '!'); }
@@ -940,7 +940,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)if (likely (!(sc->debug.level &ATH5K_DEBUG_RESET )))return ; -printk (KERN_DEBUG "rx queue %x, link %p\n" , +printk (KERN_DEBUG "rxdp %x, rxlink %p\n" ,ath5k_hw_get_rxdp (ah), sc->rxlink);spin_lock_bh (&sc->rxbuflock);
PATCH 5/17 ath5k: print more errors when decriptor setup fails
In reply to Bruno Randolf--- drivers/net/wireless/ath/ath5k/base.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)
drivers/net/wireless/ath/ath5k/base.c +3 -1
@@ -1243,8 +1243,10 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) ds->ds_link = bf->daddr;/* link to self */ ds->ds_data = bf->skbaddr; ret = ah->ah_setup_rx_desc (ah, ds, ah->common.rx_bufsize,0 ); -if (ret) +if (ret) { +ATH5K_ERR (sc,"%s: could not setup RX desc\n" , __func__);return ret; + }if (sc->rxlink !=NULL ) *sc->rxlink = bf->daddr;
PATCH 6/17 ath5k: reset more pointers after we free skbs
In reply to Bruno RandolfAfter we free skbs for receive or transmit descriptors, make sure we have no pointers to the now invalid memory address.
--- drivers/net/wireless/ath/ath5k/base.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
drivers/net/wireless/ath/ath5k/base.c +7 -0
@@ -322,6 +322,8 @@ static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, PCI_DMA_TODEVICE);dev_kfree_skb_any (bf->skb); bf->skb =NULL ; + bf->skbaddr =0 ; + bf->desc->ds_data =0 ; } static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc,
@@ -337,6 +339,8 @@ static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, PCI_DMA_FROMDEVICE);dev_kfree_skb_any (bf->skb); bf->skb =NULL ; + bf->skbaddr =0 ; + bf->desc->ds_data =0 ; }
@@ -1455,9 +1459,12 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)/* Free memory associated with all descriptors */ pci_free_consistent (pdev, sc->desc_len, sc->desc, sc->desc_daddr); + sc->desc =NULL ; + sc->desc_daddr =0 ;kfree (sc->bufptr); sc->bufptr =NULL ; + sc->bbuf =NULL ; }
PATCH 7/17 ath5k: unify rx descriptor error handling
In reply to Bruno RandolfThere is no reason for a special handling (return) here, just break like we do with the checks before.
--- drivers/net/wireless/ath/ath5k/base.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath5k/base.c +1 -2
@@ -1937,8 +1937,7 @@ ath5k_tasklet_rx(unsigned long data)else if (unlikely (ret)) {ATH5K_ERR (sc,"error in processing rx descriptor\n" ); sc->stats.rxerr_proc++; -spin_unlock (&sc->rxbuflock); -return ; +break ; } sc->stats.rx_all_count++;
PATCH 8/17 ath5k: split descriptor handling and frame receive
In reply to Bruno RandolfMove frame reception into it's own function to have a clearer separation between buffer and descriptor handling and things that are done when we actually receive a frame.
--- drivers/net/wireless/ath/ath5k/base.c | 149 +++++++++++++++++---------------- 1 files changed, 78 insertions(+), 71 deletions(-)
drivers/net/wireless/ath/ath5k/base.c +78 -71
@@ -357,7 +357,6 @@ static void ath5k_txq_release(struct ath5k_softc *sc);static int ath5k_rx_start (struct ath5k_softc *sc);static void ath5k_rx_stop (struct ath5k_softc *sc);static unsigned int ath5k_rx_decrypted (struct ath5k_softc *sc, -struct ath5k_desc *ds,struct sk_buff *skb,struct ath5k_rx_status *rs);static void ath5k_tasklet_rx (unsigned long data);
@@ -1732,8 +1731,8 @@ ath5k_rx_stop(struct ath5k_softc *sc) }static unsigned int -ath5k_rx_decrypted (struct ath5k_softc *sc,struct ath5k_desc *ds, -struct sk_buff *skb,struct ath5k_rx_status *rs) +ath5k_rx_decrypted (struct ath5k_softc *sc,struct sk_buff *skb, +struct ath5k_rx_status *rs) {struct ath5k_hw *ah = sc->ah;struct ath_common *common =ath5k_hw_common (ah);
@@ -1900,9 +1899,83 @@ static int ath5k_remove_padding(struct sk_buff *skb) }static void -ath5k_tasklet_rx (unsigned long data) +ath5k_receive_frame (struct ath5k_softc *sc,struct sk_buff *skb, +struct ath5k_rx_status *rs) {struct ieee80211_rx_status *rxs; + +/* The MAC header is padded to have 32-bit boundary if the +* packet payload is non-zero. The general calculation for +* padsize would take into account odd header lengths: +* padsize = (4 - hdrlen % 4) % 4; However, since only +* even-length headers are used, padding can only be 0 or 2 +* bytes and we can optimize this a bit. In addition, we must +* not try to remove padding from short control frames that do +* not have payload. */ +ath5k_remove_padding (skb); + + rxs =IEEE80211_SKB_RXCB (skb); + + rxs->flag =0 ; +if (unlikely (rs->rs_status &AR5K_RXERR_MIC )) + rxs->flag |=RX_FLAG_MMIC_ERROR ; + +/* +* always extend the mac timestamp, since this information is +* also needed for proper IBSS merging. +* +* XXX: it might be too late to do it here, since rs_tstamp is +* 15bit only. that means TSF extension has to be done within +* 32768usec (about 32ms). it might be necessary to move this to +* the interrupt handler, like it is done in madwifi. +* +* Unfortunately we don't know when the hardware takes the rx +* timestamp (beginning of phy frame, data frame, end of rx?). +* The only thing we know is that it is hardware specific... +* On AR5213 it seems the rx timestamp is at the end of the +* frame, but i'm not sure. +* +* NOTE: mac80211 defines mactime at the beginning of the first +* data symbol. Since we don't have any time references it's +* impossible to comply to that. This affects IBSS merge only +* right now, so it's not too bad... +*/ + rxs->mactime =ath5k_extend_tsf (sc->ah, rs->rs_tstamp); + rxs->flag |=RX_FLAG_TSFT ; + + rxs->freq = sc->curchan->center_freq; + rxs->band = sc->curband->band; + + rxs->signal = sc->ah->ah_noise_floor + rs->rs_rssi; + + rxs->antenna = rs->rs_antenna; + +if (rs->rs_antenna >0 && rs->rs_antenna <5 ) + sc->stats.antenna_rx[rs->rs_antenna]++; +else + sc->stats.antenna_rx[0 ]++;/* invalid */ + + rxs->rate_idx =ath5k_hw_to_driver_rix (sc, rs->rs_rate); + rxs->flag |=ath5k_rx_decrypted (sc, skb, rs); + +if (rxs->rate_idx >=0 && rs->rs_rate == + sc->curband->bitrates[rxs->rate_idx].hw_value_short) + rxs->flag |=RX_FLAG_SHORTPRE ; + +ath5k_debug_dump_skb (sc, skb,"RX " ,0 ); + +ath5k_update_beacon_rssi (sc, skb, rs->rs_rssi); + +/* check beacons in IBSS mode */ +if (sc->opmode ==NL80211_IFTYPE_ADHOC ) +ath5k_check_ibss_tsf (sc, skb, rxs); + +ieee80211_rx (sc->hw, skb); +} + +static void +ath5k_tasklet_rx (unsigned long data) +{struct ath5k_rx_status rs = {};struct sk_buff *skb, *next_skb;dma_addr_t next_skb_addr;
@@ -1912,7 +1985,6 @@ ath5k_tasklet_rx(unsigned long data)struct ath5k_buf *bf;struct ath5k_desc *ds;int ret; -int rx_flag;spin_lock (&sc->rxbuflock);if (list_empty (&sc->rxbuf)) {
@@ -1920,8 +1992,6 @@ ath5k_tasklet_rx(unsigned long data) goto unlock; } do { - rx_flag = 0; - bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); BUG_ON(bf->skb == NULL); skb = bf->skb;
@@ -1970,7 +2040,6 @@ ath5k_tasklet_rx(unsigned long data) goto accept; }if (rs.rs_status &AR5K_RXERR_MIC ) { - rx_flag |=RX_FLAG_MMIC_ERROR ; sc->stats.rxerr_mic++; goto accept; }
@@ -2001,69 +2070,7 @@ accept: PCI_DMA_FROMDEVICE);skb_put (skb, rs.rs_datalen); -/* The MAC header is padded to have 32-bit boundary if the -* packet payload is non-zero. The general calculation for -* padsize would take into account odd header lengths: -* padsize = (4 - hdrlen % 4) % 4; However, since only -* even-length headers are used, padding can only be 0 or 2 -* bytes and we can optimize this a bit. In addition, we must -* not try to remove padding from short control frames that do -* not have payload. */ -ath5k_remove_padding (skb); - - rxs =IEEE80211_SKB_RXCB (skb); - -/* -* always extend the mac timestamp, since this information is -* also needed for proper IBSS merging. -* -* XXX: it might be too late to do it here, since rs_tstamp is -* 15bit only. that means TSF extension has to be done within -* 32768usec (about 32ms). it might be necessary to move this to -* the interrupt handler, like it is done in madwifi. -* -* Unfortunately we don't know when the hardware takes the rx -* timestamp (beginning of phy frame, data frame, end of rx?). -* The only thing we know is that it is hardware specific... -* On AR5213 it seems the rx timestamp is at the end of the -* frame, but i'm not sure. -* -* NOTE: mac80211 defines mactime at the beginning of the first -* data symbol. Since we don't have any time references it's -* impossible to comply to that. This affects IBSS merge only -* right now, so it's not too bad... -*/ - rxs->mactime =ath5k_extend_tsf (sc->ah, rs.rs_tstamp); - rxs->flag = rx_flag |RX_FLAG_TSFT ; - - rxs->freq = sc->curchan->center_freq; - rxs->band = sc->curband->band; - - rxs->signal = sc->ah->ah_noise_floor + rs.rs_rssi; - - rxs->antenna = rs.rs_antenna; - -if (rs.rs_antenna >0 && rs.rs_antenna <5 ) - sc->stats.antenna_rx[rs.rs_antenna]++; -else - sc->stats.antenna_rx[0 ]++;/* invalid */ - - rxs->rate_idx =ath5k_hw_to_driver_rix (sc, rs.rs_rate); - rxs->flag |=ath5k_rx_decrypted (sc, ds, skb, &rs); - -if (rxs->rate_idx >=0 && rs.rs_rate == - sc->curband->bitrates[rxs->rate_idx].hw_value_short) - rxs->flag |=RX_FLAG_SHORTPRE ; - -ath5k_debug_dump_skb (sc, skb,"RX " ,0 ); - -ath5k_update_beacon_rssi (sc, skb, rs.rs_rssi); - -/* check beacons in IBSS mode */ -if (sc->opmode ==NL80211_IFTYPE_ADHOC ) -ath5k_check_ibss_tsf (sc, skb, rxs); - -ieee80211_rx (sc->hw, skb); +ath5k_receive_frame (sc, skb, &rs); bf->skb = next_skb; bf->skbaddr = next_skb_addr;
PATCH 9/17 ath5k: move checks and stats into new function
In reply to Bruno RandolfCreate a new function ath5k_receive_frame_ok() which checks for errors, updates error statistics and tells us if we want to further "receive" this frame or not. This way we can avoid a goto and have a cleaner separation between buffer handling and other things.
--- drivers/net/wireless/ath/ath5k/base.c | 130 ++++++++++++++++++--------------- 1 files changed, 70 insertions(+), 60 deletions(-)
drivers/net/wireless/ath/ath5k/base.c +70 -60
@@ -1973,6 +1973,61 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,ieee80211_rx (sc->hw, skb); } +/** ath5k_frame_receive_ok() - Do we want to receive this frame or not? +* +* Check if we want to further process this frame or not. Also update +* statistics. Return true if we want this frame, false if not. +*/ +static bool +ath5k_receive_frame_ok (struct ath5k_softc *sc,struct ath5k_rx_status *rs) +{ + sc->stats.rx_all_count++; + +if (unlikely (rs->rs_status)) { +if (rs->rs_status &AR5K_RXERR_CRC ) + sc->stats.rxerr_crc++; +if (rs->rs_status &AR5K_RXERR_FIFO ) + sc->stats.rxerr_fifo++; +if (rs->rs_status &AR5K_RXERR_PHY ) { + sc->stats.rxerr_phy++; +if (rs->rs_phyerr >0 && rs->rs_phyerr <32 ) + sc->stats.rxerr_phy_code[rs->rs_phyerr]++; +return false; + } +if (rs->rs_status &AR5K_RXERR_DECRYPT ) { +/* +* Decrypt error. If the error occurred +* because there was no hardware key, then +* let the frame through so the upper layers +* can process it. This is necessary for 5210 +* parts which have no way to setup a ``clear'' +* key cache entry. +* +* XXX do key cache faulting +*/ + sc->stats.rxerr_decrypt++; +if (rs->rs_keyix ==AR5K_RXKEYIX_INVALID && + !(rs->rs_status &AR5K_RXERR_CRC )) +return true; + } +if (rs->rs_status &AR5K_RXERR_MIC ) { + sc->stats.rxerr_mic++; +return true; + } + +/* let crypto-error packets fall through in MNTR */ +if ((rs->rs_status & ~(AR5K_RXERR_DECRYPT |AR5K_RXERR_MIC )) || + sc->opmode !=NL80211_IFTYPE_MONITOR ) +return false; + } + +if (unlikely (rs->rs_more)) { + sc->stats.rxerr_jumbo++; +return false; + } +return true; +} +static void ath5k_tasklet_rx (unsigned long data) {
@@ -2010,70 +2065,27 @@ ath5k_tasklet_rx(unsigned long data)break ; } - sc->stats.rx_all_count++; - -if (unlikely (rs.rs_status)) { -if (rs.rs_status &AR5K_RXERR_CRC ) - sc->stats.rxerr_crc++; -if (rs.rs_status &AR5K_RXERR_FIFO ) - sc->stats.rxerr_fifo++; -if (rs.rs_status &AR5K_RXERR_PHY ) { - sc->stats.rxerr_phy++; -if (rs.rs_phyerr >0 && rs.rs_phyerr <32 ) - sc->stats.rxerr_phy_code[rs.rs_phyerr]++; - goto next; - } -if (rs.rs_status &AR5K_RXERR_DECRYPT ) { -/* -* Decrypt error. If the error occurred -* because there was no hardware key, then -* let the frame through so the upper layers -* can process it. This is necessary for 5210 -* parts which have no way to setup a ``clear'' -* key cache entry. -* -* XXX do key cache faulting -*/ - sc->stats.rxerr_decrypt++; -if (rs.rs_keyix ==AR5K_RXKEYIX_INVALID && - !(rs.rs_status &AR5K_RXERR_CRC )) - goto accept; - } -if (rs.rs_status &AR5K_RXERR_MIC ) { - sc->stats.rxerr_mic++; - goto accept; - } +if (ath5k_receive_frame_ok (sc, &rs)) { + next_skb =ath5k_rx_skb_alloc (sc, &next_skb_addr); -/* let crypto-error packets fall through in MNTR */ -if ((rs.rs_status & - ~(AR5K_RXERR_DECRYPT |AR5K_RXERR_MIC )) || - sc->opmode !=NL80211_IFTYPE_MONITOR ) +/* +* If we can't replace bf->skb with a new skb under +* memory pressure, just skip this packet +*/ +if (!next_skb) goto next; - } - -if (unlikely (rs.rs_more)) { - sc->stats.rxerr_jumbo++; - goto next; - } -accept: - next_skb =ath5k_rx_skb_alloc (sc, &next_skb_addr); - -/* -* If we can't replace bf->skb with a new skb under memory -* pressure, just skip this packet -*/ -if (!next_skb) - goto next; +pci_unmap_single (sc->pdev, bf->skbaddr, + common->rx_bufsize, +PCI_DMA_FROMDEVICE ); -pci_unmap_single (sc->pdev, bf->skbaddr, common->rx_bufsize, -PCI_DMA_FROMDEVICE ); -skb_put (skb, rs.rs_datalen); +skb_put (skb, rs.rs_datalen); -ath5k_receive_frame (sc, skb, &rs); +ath5k_receive_frame (sc, skb, &rs); - bf->skb = next_skb; - bf->skbaddr = next_skb_addr; + bf->skb = next_skb; + bf->skbaddr = next_skb_addr; + } next:list_move_tail (&bf->list, &sc->rxbuf); }while (ath5k_rxbuf_setup (sc, bf) ==0 );
@@ -2082,8 +2094,6 @@ unlock: } - -/*************\ * TX Handling * \*************/
PATCH 10/17 ath5k: use direct function calls for descriptors when possible
In reply to Bruno RandolfUse direct function calls for ath5k_hw_setup_rx_desc() and ath5k_hw_setup_mrr_tx_desc() instead of a function pointer which always pointed to the same function in the case of ath5k_hw_setup_rx_desc() and which is easily unified in the case of ath5k_hw_setup_mrr_tx_desc().
Also simplify the initialization function for the remaining function pointers.
--- drivers/net/wireless/ath/ath5k/ath5k.h | 10 ++++---- drivers/net/wireless/ath/ath5k/base.c | 7 +++-- drivers/net/wireless/ath/ath5k/desc.c | 41 +++++++++----------------------- 3 files changed, 20 insertions(+), 38 deletions(-)
drivers/net/wireless/ath/ath5k/ath5k.h +5 -5
@@ -1127,15 +1127,10 @@ struct ath5k_hw {/* * Function pointers */ -int (*ah_setup_rx_desc)(struct ath5k_hw *ah,struct ath5k_desc *desc, -u32 size,unsigned int flags);int (*ah_setup_tx_desc)(struct ath5k_hw *,struct ath5k_desc *,unsigned int ,unsigned int ,int ,enum ath5k_pkt_type ,unsigned int ,unsigned int ,unsigned int ,unsigned int ,unsigned int ,unsigned int ,unsigned int ,unsigned int ); -int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *,struct ath5k_desc *, -unsigned int ,unsigned int ,unsigned int ,unsigned int , -unsigned int ,unsigned int );int (*ah_proc_tx_desc)(struct ath5k_hw *,struct ath5k_desc *,struct ath5k_tx_status *); int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *,
@@ -1236,6 +1231,11 @@ int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);/* Hardware Descriptor Functions */ int ath5k_hw_init_desc_functions (struct ath5k_hw *ah); +int ath5k_hw_setup_rx_desc (struct ath5k_hw *ah,struct ath5k_desc *desc, +u32 size,unsigned int flags); +int ath5k_hw_setup_mrr_tx_desc (struct ath5k_hw *ah,struct ath5k_desc *desc, +unsigned int tx_rate1,u_int tx_tries1,u_int tx_rate2, +u_int tx_tries2,unsigned int tx_rate3,u_int tx_tries3);/* GPIO Functions */ void ath5k_hw_set_ledstate (struct ath5k_hw *ah,unsigned int state);
drivers/net/wireless/ath/ath5k/base.c +4 -3
@@ -769,7 +769,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)* return false w/o doing anything. MAC's that do * support it will return true w/o doing anything. */ - ret = ah->ah_setup_mrr_tx_desc (ah,NULL ,0 ,0 ,0 ,0 ,0 ,0 ); + ret =ath5k_hw_setup_mrr_tx_desc (ah,NULL ,0 ,0 ,0 ,0 ,0 ,0 ); +if (ret <0 ) goto err;if (ret >0 )
@@ -1245,7 +1246,7 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) ds = bf->desc; ds->ds_link = bf->daddr;/* link to self */ ds->ds_data = bf->skbaddr; - ret = ah->ah_setup_rx_desc (ah, ds, ah->common.rx_bufsize,0 ); + ret =ath5k_hw_setup_rx_desc (ah, ds, ah->common.rx_bufsize,0 );if (ret) {ATH5K_ERR (sc,"%s: could not setup RX desc\n" , __func__);return ret;
@@ -1354,7 +1355,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, mrr_tries[i] = info->control.rates[i +1 ].count; } - ah->ah_setup_mrr_tx_desc (ah, ds, +ath5k_hw_setup_mrr_tx_desc (ah, ds, mrr_rate[0 ], mrr_tries[0 ], mrr_rate[1 ], mrr_tries[1 ], mrr_rate[2 ], mrr_tries[2 ]);
drivers/net/wireless/ath/ath5k/desc.c +11 -30
76 lines not on this page · raw message
PATCH 11/17 ath5k: cosmetic changes in ath5k_hw_proc_5212_rx_status()
In reply to Bruno RandolfJust whitespace and indentation.
--- drivers/net/wireless/ath/ath5k/desc.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-)
drivers/net/wireless/ath/ath5k/desc.c +5 -5
@@ -577,7 +577,8 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,* Proccess the rx status descriptor on 5212 */ static int ath5k_hw_proc_5212_rx_status (struct ath5k_hw *ah, -struct ath5k_desc *desc,struct ath5k_rx_status *rs) +struct ath5k_desc *desc, +struct ath5k_rx_status *rs) {struct ath5k_hw_rx_status *rx_status;struct ath5k_hw_rx_error *rx_err;
@@ -589,7 +590,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,/* No frame received / not ready */ if (unlikely (!(rx_status->rx_status_1 & -AR5K_5212_RX_DESC_STATUS1_DONE ))) +AR5K_5212_RX_DESC_STATUS1_DONE )))return -EINPROGRESS ;/*
@@ -615,7 +616,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,*/ if (rx_status->rx_status_1 &AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID ) rs->rs_keyix =AR5K_REG_MS (rx_status->rx_status_1, -AR5K_5212_RX_DESC_STATUS1_KEY_INDEX ); +AR5K_5212_RX_DESC_STATUS1_KEY_INDEX );else rs->rs_keyix =AR5K_RXKEYIX_INVALID ;
@@ -623,7 +624,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,* Receive/descriptor errors */ if (!(rx_status->rx_status_1 & -AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK )) { +AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK )) {if (rx_status->rx_status_1 &AR5K_5212_RX_DESC_STATUS1_CRC_ERROR ) rs->rs_status |=AR5K_RXERR_CRC ;
@@ -644,7 +645,6 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) rs->rs_status |= AR5K_RXERR_MIC; } -return 0 ; }
PATCH 12/17 ath5k: remove pointless rx error overlay struct
In reply to Bruno Randolfath5k_hw_rx_error was only used once, where we could easily just use ath5k_hw_rx_status as well, so remove it.
--- drivers/net/wireless/ath/ath5k/debug.c | 2 +- drivers/net/wireless/ath/ath5k/desc.c | 12 ++++-------- drivers/net/wireless/ath/ath5k/desc.h | 24 ++++-------------------- 3 files changed, 9 insertions(+), 29 deletions(-)
drivers/net/wireless/ath/ath5k/debug.c +1 -1
@@ -925,7 +925,7 @@ ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done, ds, (unsigned long long )bf->daddr, ds->ds_link, ds->ds_data, rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1, - rd->u.rx_stat.rx_status_0, rd->u.rx_stat.rx_status_1, + rd->rx_stat.rx_status_0, rd->rx_stat.rx_status_1, !done ? ' ' : (rs->rs_status == 0) ? '*' : '!'); }
drivers/net/wireless/ath/ath5k/desc.c +4 -8
@@ -510,7 +510,7 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, {struct ath5k_hw_rx_status *rx_status; - rx_status = &desc->ud.ds_rx.u.rx_stat; + rx_status = &desc->ud.ds_rx.rx_stat;/* No frame received / not ready */ if (unlikely(!(rx_status->rx_status_1 &
@@ -581,12 +581,8 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, struct ath5k_rx_status *rs) {struct ath5k_hw_rx_status *rx_status; -struct ath5k_hw_rx_error *rx_err; - rx_status = &desc->ud.ds_rx.u.rx_stat; - -/* Overlay on error */ - rx_err = &desc->ud.ds_rx.u.rx_err; + rx_status = &desc->ud.ds_rx.rx_stat;/* No frame received / not ready */ if (unlikely(!(rx_status->rx_status_1 &
@@ -632,8 +628,8 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,if (rx_status->rx_status_1 &AR5K_5212_RX_DESC_STATUS1_PHY_ERROR ) { rs->rs_status |=AR5K_RXERR_PHY ; - rs->rs_phyerr |=AR5K_REG_MS (rx_err->rx_error_1, -AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE ); + rs->rs_phyerr |=AR5K_REG_MS (rx_status->rx_status_1, +AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE );ath5k_ani_phy_error_report (ah, rs->rs_phyerr); }
drivers/net/wireless/ath/ath5k/desc.h +4 -20
@@ -96,21 +96,8 @@ struct ath5k_hw_rx_status {#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x7fff0000#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 16#define AR5K_5212_RX_DESC_STATUS1_KEY_CACHE_MISS 0x80000000 - -/* -* common hardware RX error descriptor -*/ -struct ath5k_hw_rx_error { -u32 rx_error_0;/* RX status word 0 */ -u32 rx_error_1;/* RX status word 1 */ -} __packed; - -/* RX error word 0 fields/flags */ -#define AR5K_RX_DESC_ERROR0 0x00000000 - -/* RX error word 1 fields/flags */ -#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00 -#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8 +#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE 0x0000ff00 +#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE_S 8/** * enum ath5k_phy_error_code - PHY Error codes
@@ -316,11 +303,8 @@ struct ath5k_hw_5212_tx_desc {* common hardware RX descriptor */ struct ath5k_hw_all_rx_desc { -struct ath5k_hw_rx_ctl rx_ctl; -union { -struct ath5k_hw_rx_status rx_stat; -struct ath5k_hw_rx_error rx_err; - } u; +struct ath5k_hw_rx_ctl rx_ctl; +struct ath5k_hw_rx_status rx_stat; } __packed;/*
PATCH 13/17 ath5k: review and add comments for descriptors
In reply to Bruno RandolfI carefully reviewed desh.h against the HAL sources. Added comments and made differences between 5210, 5211 and 5212 more clear by adding _521x to the defines which are specific to that chipset. Renamed some defines. No functional changes.
--- drivers/net/wireless/ath/ath5k/desc.c | 22 +-- drivers/net/wireless/ath/ath5k/desc.h | 276 ++++++++++++++++----------------- 2 files changed, 144 insertions(+), 154 deletions(-)
drivers/net/wireless/ath/ath5k/desc.c +11 -11
@@ -95,10 +95,10 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,* XXX: I only found that on 5210 code, does it work on 5211 ? */ if (ah->ah_version ==AR5K_AR5210 ) { -if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN ) +if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210 )return -EINVAL ; tx_ctl->tx_control_0 |= -AR5K_REG_SM (hdr_len,AR5K_2W_TX_DESC_CTL0_HEADER_LEN ); +AR5K_REG_SM (hdr_len,AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210 ); }/*Differences between 5210-5211*/
@@ -114,7 +114,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, } tx_ctl->tx_control_0 |= -AR5K_REG_SM (frame_type,AR5K_2W_TX_DESC_CTL0_FRAME_TYPE ) | +AR5K_REG_SM (frame_type,AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210 ) |AR5K_REG_SM (tx_rate0,AR5K_2W_TX_DESC_CTL0_XMIT_RATE ); }else {
@@ -123,7 +123,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,AR5K_REG_SM (antenna_mode,AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT ); tx_ctl->tx_control_1 |= -AR5K_REG_SM (type,AR5K_2W_TX_DESC_CTL1_FRAME_TYPE ); +AR5K_REG_SM (type,AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211 ); }#define _TX_FLAGS (_c, _flag) \ if (flags & AR5K_TXDESC_##_flag) { \
@@ -147,7 +147,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID ; tx_ctl->tx_control_1 |=AR5K_REG_SM (key_index, -AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX ); +AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX ); }/*
@@ -156,7 +156,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,if ((ah->ah_version ==AR5K_AR5210 ) && (flags & (AR5K_TXDESC_RTSENA |AR5K_TXDESC_CTSENA ))) tx_ctl->tx_control_1 |= rtscts_duration & -AR5K_2W_TX_DESC_CTL1_RTS_DURATION ; +AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210 ;return 0 ; }
@@ -255,7 +255,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,if (key_index !=AR5K_TXKEYIX_INVALID ) { tx_ctl->tx_control_0 |=AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID ; tx_ctl->tx_control_1 |=AR5K_REG_SM (key_index, -AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX ); +AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX ); }/*
@@ -409,11 +409,11 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, ts->ts_rssi =AR5K_REG_MS (tx_status->tx_status_1,AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH ); ts->ts_antenna = (tx_status->tx_status_1 & -AR5K_DESC_TX_STATUS1_XMIT_ANTENNA ) ?2 :1 ; +AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212 ) ?2 :1 ; ts->ts_status =0 ; ts->ts_final_idx =AR5K_REG_MS (tx_status->tx_status_1, -AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX ); +AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212 );/* The longretry counter has the number of un-acked retries * for the final rate. To get the total number of retries
@@ -527,7 +527,7 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, rs->rs_rate =AR5K_REG_MS (rx_status->rx_status_0,AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE ); rs->rs_antenna =AR5K_REG_MS (rx_status->rx_status_0, -AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA ); +AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211 ); rs->rs_more = !!(rx_status->rx_status_0 &AR5K_5210_RX_DESC_STATUS0_MORE );/* TODO: this timestamp is 13 bit, later on we assume 15 bit */
@@ -555,7 +555,7 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, rs->rs_status |=AR5K_RXERR_CRC ;if (rx_status->rx_status_1 & -AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN ) +AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210 ) rs->rs_status |=AR5K_RXERR_FIFO ; if (rx_status->rx_status_1 &
drivers/net/wireless/ath/ath5k/desc.h +133 -143
389 lines not on this page · raw message
PATCH 14/17 ath5k: update 5210/5211 frame types
In reply to Bruno RandolfUpdate 5210 frame types to match the HAL. We have to apply the same bitshift to the constants as we use later.
Add 5211 specific frame types.
--- drivers/net/wireless/ath/ath5k/desc.c | 2 +- drivers/net/wireless/ath/ath5k/desc.h | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-)
drivers/net/wireless/ath/ath5k/desc.c +1 -1
@@ -110,7 +110,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,case AR5K_PKT_TYPE_PIFS : frame_type =AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS ;default : - frame_type = type/*<< 2 ?*/ ; + frame_type = type; } tx_ctl->tx_control_0 |=
drivers/net/wireless/ath/ath5k/desc.h +7 -5
@@ -169,11 +169,13 @@ struct ath5k_hw_2w_tx_ctl {#define AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210 0xfff80000/* [5210] lower 13 bit of duration */ /* Frame types */ -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL 0x00 -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM 0x04 -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL 0x08 -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY 0x0c -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS 0x10 +#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL 0 +#define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM 1 +#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL 2 +#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY 3 +#define AR5K_AR5211_TX_DESC_FRAME_TYPE_BEACON 3 +#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS 4 +#define AR5K_AR5211_TX_DESC_FRAME_TYPE_PRESP 4/* * 5212 hardware 4-word TX control descriptor
PATCH 15/17 ath5k: take descriptor differences between 5210 and 5211 into account
In reply to Bruno RandolfThere are some differences between 5210 and 5211 descriptors which we did not take into account before.
--- drivers/net/wireless/ath/ath5k/desc.c | 29 ++++++++++++++++++++++------- drivers/net/wireless/ath/ath5k/desc.h | 6 +++--- 2 files changed, 25 insertions(+), 10 deletions(-)
drivers/net/wireless/ath/ath5k/desc.c +22 -7
@@ -91,8 +91,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, tx_ctl->tx_control_1 = pkt_len &AR5K_2W_TX_DESC_CTL1_BUF_LEN ;/* -* Verify and set header length -* XXX: I only found that on 5210 code, does it work on 5211 ? +* Verify and set header length (only 5210) */ if (ah->ah_version ==AR5K_AR5210 ) {if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210 )
@@ -125,19 +124,28 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, tx_ctl->tx_control_1 |=AR5K_REG_SM (type,AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211 ); } +#define _TX_FLAGS (_c, _flag) \ if (flags & AR5K_TXDESC_##_flag) { \ tx_ctl->tx_control_##_c |= \ AR5K_2W_TX_DESC_CTL##_c##_##_flag; \ } - +#define _TX_FLAGS_5211 (_c, _flag) \ + if (flags & AR5K_TXDESC_##_flag) { \ + tx_ctl->tx_control_##_c |= \ + AR5K_2W_TX_DESC_CTL##_c##_##_flag##_5211; \ + }_TX_FLAGS (0 ,CLRDMASK ); -_TX_FLAGS (0 ,VEOL );_TX_FLAGS (0 ,INTREQ );_TX_FLAGS (0 ,RTSENA ); -_TX_FLAGS (1 ,NOACK ); + +if (ah->ah_version ==AR5K_AR5211 ) { +_TX_FLAGS_5211 (0 ,VEOL ); +_TX_FLAGS_5211 (1 ,NOACK ); + }#undef _TX_FLAGS +#undef _TX_FLAGS_5211/* * WEP crap
@@ -526,13 +534,20 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL); rs->rs_rate =AR5K_REG_MS (rx_status->rx_status_0,AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE ); - rs->rs_antenna =AR5K_REG_MS (rx_status->rx_status_0, -AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211 ); rs->rs_more = !!(rx_status->rx_status_0 &AR5K_5210_RX_DESC_STATUS0_MORE );/* TODO: this timestamp is 13 bit, later on we assume 15 bit */ rs->rs_tstamp =AR5K_REG_MS (rx_status->rx_status_1,AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP ); + +if (ah->ah_version ==AR5K_AR5211 ) + rs->rs_antenna =AR5K_REG_MS (rx_status->rx_status_0, +AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211 ); +else + rs->rs_antenna = (rx_status->rx_status_0 & +AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210 ) + ?2 :1 ; + rs->rs_status =0 ; rs->rs_phyerr =0 ;
drivers/net/wireless/ath/ath5k/desc.h +3 -3
@@ -45,7 +45,7 @@ struct ath5k_hw_rx_status {/* RX status word 0 fields/flags */ #define AR5K_5210_RX_DESC_STATUS0_DATA_LEN 0x00000fff/* RX data length */ #define AR5K_5210_RX_DESC_STATUS0_MORE 0x00001000/* more desc for this frame */ -#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210 0x00004000/* [5210] receive on ant 1 TODO */ +#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210 0x00004000/* [5210] receive on ant 1 */ #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000/* reception rate */ #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE_S 15#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x07f80000/* rssi */
@@ -139,7 +139,7 @@ struct ath5k_hw_2w_tx_ctl {#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE_S 18#define AR5K_2W_TX_DESC_CTL0_RTSENA 0x00400000/* RTS/CTS enable */ #define AR5K_2W_TX_DESC_CTL0_LONG_PACKET_5210 0x00800000/* [5210] long packet */ -#define AR5K_2W_TX_DESC_CTL0_VEOL 0x00800000/* [5211] virtual end-of-list TODO */ +#define AR5K_2W_TX_DESC_CTL0_VEOL_5211 0x00800000/* [5211] virtual end-of-list */ #define AR5K_2W_TX_DESC_CTL0_CLRDMASK 0x01000000/* clear destination mask */ #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 0x02000000/* [5210] antenna selection */ #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211 0x1e000000/* [5211] antenna selection */
@@ -165,7 +165,7 @@ struct ath5k_hw_2w_tx_ctl {#define AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_S 13#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211 0x00700000/* [5211] frame type */ #define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211_S 20 -#define AR5K_2W_TX_DESC_CTL1_NOACK 0x00800000/* [5211] no ACK TODO */ +#define AR5K_2W_TX_DESC_CTL1_NOACK_5211 0x00800000/* [5211] no ACK */ #define AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210 0xfff80000/* [5210] lower 13 bit of duration */ /* Frame types */
PATCH 16/17 ath5k: review RX descriptor functions
In reply to Bruno RandolfReviewed RX descriptor functions against the HAL sources. Some minor changes:
- check size before making changes to the descriptor
- whitespace
- add comments about 5210 timestamps. this needs to be adressed later!
- FIFO overrun error only available on 5210
- rs_phyerr should not be OR'ed
- clear the whole ath5k_rx_status structure before using, instead of zeroing specific fields.
--- drivers/net/wireless/ath/ath5k/desc.c | 34 +++++++++++++++++++-------------- 1 files changed, 20 insertions(+), 14 deletions(-)
drivers/net/wireless/ath/ath5k/desc.c +20 -14
@@ -499,10 +499,11 @@ int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,*/ memset (&desc->ud.ds_rx,0 ,sizeof (struct ath5k_hw_all_rx_desc )); +if (unlikely (size & ~AR5K_DESC_RX_CTL1_BUF_LEN )) +return -EINVAL ; +/* Setup descriptor */ rx_ctl->rx_control_1 = size &AR5K_DESC_RX_CTL1_BUF_LEN ; -if (unlikely (rx_ctl->rx_control_1 != size)) -return -EINVAL ;if (flags &AR5K_RXDESC_INTREQ ) rx_ctl->rx_control_1 |=AR5K_DESC_RX_CTL1_INTREQ ;
@@ -522,9 +523,11 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,/* No frame received / not ready */ if (unlikely (!(rx_status->rx_status_1 & -AR5K_5210_RX_DESC_STATUS1_DONE ))) +AR5K_5210_RX_DESC_STATUS1_DONE )))return -EINPROGRESS ; +memset (rs,0 ,sizeof (struct ath5k_rx_status )); +/* * Frame receive status */
@@ -536,7 +539,11 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); rs->rs_more = !!(rx_status->rx_status_0 &AR5K_5210_RX_DESC_STATUS0_MORE ); -/* TODO: this timestamp is 13 bit, later on we assume 15 bit */ +/* TODO: this timestamp is 13 bit, later on we assume 15 bit! +* also the HAL code for 5210 says the timestamp is bits [10..22] of the +* TSF, and extends the timestamp here to 15 bit. +* we need to check on 5210... +*/ rs->rs_tstamp =AR5K_REG_MS (rx_status->rx_status_1,AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP );
@@ -548,9 +555,6 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210) ?2 :1 ; - rs->rs_status =0 ; - rs->rs_phyerr =0 ; -/* * Key table status */
@@ -564,19 +568,21 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,* Receive/descriptor errors */ if (!(rx_status->rx_status_1 & -AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK )) { +AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK )) {if (rx_status->rx_status_1 &AR5K_5210_RX_DESC_STATUS1_CRC_ERROR ) rs->rs_status |=AR5K_RXERR_CRC ; -if (rx_status->rx_status_1 & -AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210 ) +/* only on 5210 */ +if ((ah->ah_version ==AR5K_AR5210 ) && + (rx_status->rx_status_1 & +AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210 )) rs->rs_status |=AR5K_RXERR_FIFO ;if (rx_status->rx_status_1 &AR5K_5210_RX_DESC_STATUS1_PHY_ERROR ) { rs->rs_status |=AR5K_RXERR_PHY ; - rs->rs_phyerr |=AR5K_REG_MS (rx_status->rx_status_1, + rs->rs_phyerr =AR5K_REG_MS (rx_status->rx_status_1,AR5K_5210_RX_DESC_STATUS1_PHY_ERROR ); }
@@ -604,6 +610,8 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, AR5K_5212_RX_DESC_STATUS1_DONE)))return -EINPROGRESS ; +memset (rs,0 ,sizeof (struct ath5k_rx_status )); +/* * Frame receive status */
@@ -619,8 +627,6 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, AR5K_5212_RX_DESC_STATUS0_MORE); rs->rs_tstamp =AR5K_REG_MS (rx_status->rx_status_1,AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP ); - rs->rs_status =0 ; - rs->rs_phyerr =0 ;/* * Key table status
@@ -643,7 +649,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,if (rx_status->rx_status_1 &AR5K_5212_RX_DESC_STATUS1_PHY_ERROR ) { rs->rs_status |=AR5K_RXERR_PHY ; - rs->rs_phyerr |=AR5K_REG_MS (rx_status->rx_status_1, + rs->rs_phyerr =AR5K_REG_MS (rx_status->rx_status_1,AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE );ath5k_ani_phy_error_report (ah, rs->rs_phyerr); }
PATCH 17/17 ath5k: report PHY error frames only for chips which need it
In reply to Bruno RandolfOnly report PHY error frames for ANI on chipsets which do not have PHY error counters in hardware.
--- drivers/net/wireless/ath/ath5k/desc.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/net/wireless/ath/ath5k/desc.c +2 -1
@@ -651,7 +651,8 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, rs->rs_status |=AR5K_RXERR_PHY ; rs->rs_phyerr =AR5K_REG_MS (rx_status->rx_status_1,AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE ); -ath5k_ani_phy_error_report (ah, rs->rs_phyerr); +if (!ah->ah_capabilities.cap_has_phyerr_counters) +ath5k_ani_phy_error_report (ah, rs->rs_phyerr); } if (rx_status->rx_status_1 &