commit d225a4499b88a844d00790a2f4c339b13643c124 Author: Jiri Slaby Date: Fri Jul 6 23:07:36 2007 +0200 implement tx diff --git a/ath/if_ath_pci.c b/ath/if_ath_pci.c index 0fc213e..cf6b618 100644 --- a/ath/if_ath_pci.c +++ b/ath/if_ath_pci.c @@ -47,7 +47,7 @@ } while (0) #define DPRINTF(sc, _m, _fmt...) do { \ - if (sc->debug & (_m) && printk_ratelimit()) \ + if ((sc->debug & (_m)) && net_ratelimit()) \ printk(_fmt); \ } while (0) enum { @@ -209,6 +209,68 @@ static int ath_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf) return 0; } +static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) +{ + struct ieee80211_tx_status txs = {}; + struct ath_buf *bf, *bf0; + struct ath_desc *ds; + struct sk_buff *skb; + int ret; + + spin_lock(&txq->lock); + list_for_each_entry_safe(bf, bf0, &txq->q, list) { + ds = bf->desc; + + ret = sc->ah->ah_proc_tx_desc(sc->ah, ds); + if (ret == -EINPROGRESS) + break; + else if (ret) { + printk(KERN_ERR "ath: error %d while processing " + "queue %u\n", ret, txq->qnum); + break; + } + + skb = bf->skb; + bf->skb = NULL; + pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, + PCI_DMA_TODEVICE); + + txs.control = bf->ctl; + txs.retry_count = ds->ds_txstat.ts_shortretry + + ds->ds_txstat.ts_longretry; + if (ds->ds_txstat.ts_status) { + if (ds->ds_txstat.ts_status & AR5K_TXERR_XRETRY) { + txs.excessive_retries = 1; + } else if (ds->ds_txstat.ts_status & AR5K_TXERR_FILT) { + txs.flags |= IEEE80211_TX_STATUS_TX_FILTERED; + } + } else { + txs.flags |= IEEE80211_TX_STATUS_ACK; + txs.ack_signal = ds->ds_txstat.ts_rssi; + } + + ieee80211_tx_status(sc->hw, skb, &txs); + + printk(KERN_DEBUG "DONE skb: %p, rssi: %d, stat: %x, seq: %u, stamp: %u\n", skb, ds->ds_txstat.ts_rssi, ds->ds_txstat.ts_status, ds->ds_txstat.ts_seqnum, ds->ds_txstat.ts_tstamp); + + spin_lock(&sc->txbuflock); + list_move_tail(&bf->list, &sc->txbuf); + spin_unlock(&sc->txbuflock); + } + if (list_empty(&txq->q)) + txq->link = NULL; + spin_unlock(&txq->lock); +} + +static void ath_tasklet_tx(unsigned long data) +{ + struct ath_softc *sc = (void *)data; + + ath_tx_processq(sc, sc->txq); + + ieee80211_wake_queue(sc->hw, 0); +} + /* * Calculate the receive filter according to the * operating mode and state: @@ -411,22 +473,14 @@ static void ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq) #ifdef AR_DEBUG struct ath_hw *ah = sc->ah; #endif - struct ath_buf *bf; + struct ath_buf *bf, *bf0; /* * NB: this assumes output has been stopped and * we do not need to block ath_tx_tasklet */ - for (;;) { - spin_lock_bh(&txq->axq_lock); - if (list_empty(&txq->axq_q)) { - txq->axq_link = NULL; - spin_unlock_bh(&txq->axq_lock); - break; - } - bf = list_first_entry(&txq->axq_q, struct ath_buf, list); - list_del(&bf->list); - spin_unlock_bh(&txq->axq_lock); + spin_lock_bh(&txq->lock); + list_for_each_entry_safe(bf, bf0, &txq->q, list) { #ifdef AR_DEBUG if (sc->debug & ATH_DEBUG_RESET) ath_printtxbuf(bf, !ah->ah_proc_tx_desc(ah, bf->desc)); @@ -437,9 +491,11 @@ static void ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq) bf->skb = NULL; spin_lock_bh(&sc->txbuflock); - list_add_tail(&bf->list, &sc->txbuf); + list_move_tail(&bf->list, &sc->txbuf); spin_unlock_bh(&sc->txbuflock); } + txq->link = NULL; + spin_unlock_bh(&txq->lock); } /* @@ -452,28 +508,28 @@ static void ath_draintxq(struct ath_softc *sc) /* XXX return value */ if (!sc->invalid) { +#ifdef BLE /* don't touch the hardware if marked invalid */ (void)ath5k_hw_stop_tx_dma(ah, sc->bhalq); DPRINTF(sc, ATH_DEBUG_RESET, "%s: beacon queue %x\n", __func__, ath5k_hw_get_tx_buf(ah, sc->bhalq)); - for (i = 0; i < AR5K_NUM_TX_QUEUES; i++) - if (test_bit(i, sc->txqsetup)) { - ath5k_hw_stop_tx_dma(ah, sc->txq[i].axq_qnum); +#endif + for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) + if (sc->txqs[i].setup) { + ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum); DPRINTF(sc, ATH_DEBUG_RESET, "%s: txq [%u] %x, " "link %p\n", __func__, - sc->txq[i].axq_qnum, + sc->txqs[i].qnum, ath5k_hw_get_tx_buf(ah, - sc->txq[i].axq_qnum), - sc->txq[i].axq_link); + sc->txqs[i].qnum), + sc->txqs[i].link); } } ieee80211_start_queues(sc->hw); /* XXX move to callers */ - for (i = 0; i < AR5K_NUM_TX_QUEUES; i++) - if (test_bit(i, sc->txqsetup)) - ath_tx_draintxq(sc, &sc->txq[i]); - -// sc->tx_timer = 0; + for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) + if (sc->txqs[i].setup) + ath_tx_draintxq(sc, &sc->txqs[i]); } static int ath_stop_locked(struct ath_softc *sc) @@ -583,7 +639,7 @@ static int ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) * hardware at the new frequency, and then re-enable * the relevant bits of the h/w. */ - ath5k_hw_set_intr(ah, 0); /* disable interrupts */ + ath5k_hw_set_intr(ah, 0); /* disable interrupts */ ath_draintxq(sc); /* clear pending tx frames */ ath_stoprecv(sc); /* turn off frame recv */ ret = ath5k_hw_reset(ah, IEEE80211_IF_TYPE_STA, chan, true); @@ -620,27 +676,118 @@ static int ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) return 0; } +static int ath_tx_bf(struct ath_softc *sc, struct ath_buf *bf, + struct ieee80211_tx_control *ctl) +{ + struct ath_hw *ah = sc->ah; + struct ath_txq *txq = sc->txq; + struct ath_desc *ds = bf->desc; + struct sk_buff *skb = bf->skb; + unsigned int hdrpad, pktlen, flags; + int ret; + + flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; + bf->ctl = *ctl; + /* XXX endianness */ + bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, + PCI_DMA_TODEVICE); + + if (ctl->flags & IEEE80211_TXCTL_NO_ACK) + flags |= AR5K_TXDESC_NOACK; + + if ((ieee80211_get_hdrlen_from_skb(skb) & 3) && net_ratelimit()) { + printk(KERN_DEBUG "len is not %%4: %u\n", ieee80211_get_hdrlen_from_skb(skb)); + } + hdrpad = 0; + pktlen = skb->len - hdrpad + FCS_LEN; + ret = ah->ah_setup_tx_desc(ah, ds, pktlen, + ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, + ctl->power_level > 60 ? 60 : ctl->power_level, ctl->tx_rate, + ctl->retry_limit, AR5K_TXKEYIX_INVALID, 0, flags, 0, 0); + if (ret) + goto err_unmap; + + ds->ds_link = 0; + ds->ds_data = bf->skbaddr; + + ret = ah->ah_fill_tx_desc(ah, ds, skb->len, true, true); + if (ret) + goto err_unmap; + + spin_lock_bh(&txq->lock); + list_add_tail(&bf->list, &txq->q); + if (txq->link == NULL) /* is this first packet? */ + ath5k_hw_put_tx_buf(ah, txq->qnum, bf->daddr); + else /* no, so only link it */ + *txq->link = bf->daddr; + + txq->link = &ds->ds_link; + ath5k_hw_tx_start(ah, txq->qnum); + spin_unlock_bh(&txq->lock); + + printk(KERN_DEBUG "bf: %p, skb: %p, flags: %x, daddr: %x, dlink: %x, tlink: %x\n", bf, skb, flags, bf->daddr, ds->ds_link, *txq->link); + + return 0; +err_unmap: + pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE); + return ret; +} + static int ath_tx(struct ieee80211_hw *hw, struct sk_buff *skb, - struct ieee80211_tx_control *control) + struct ieee80211_tx_control *ctl) { - printk("%s\n", __FUNCTION__); + struct ath_softc *sc = hw->priv; + struct ath_buf *bf; + unsigned long flags; +// unsigned int a; + +/* skb_pad(skb, 4); + printk(KERN_DEBUG "%p/%p, %p/%p, %u, %u\n" KERN_DEBUG, skb->head, skb->data, skb->tail, skb->end, skb->len, skb->data_len); + for (a = 0; a < min(200U, skb->len) + 4; a++) { + printk("%.2x %s", skb->data[a], ((a+1) % 8) ? "" : " "); + if (!((a+1) % 16)) + printk("\n" KERN_DEBUG); + } + printk("\n");*/ + + spin_lock_irqsave(&sc->txbuflock, flags); + if (list_empty(&sc->txbuf)) { + if (net_ratelimit()) + printk(KERN_ERR "ath: no further txbuf available, " + "dropping packet\n"); + sc->stats.ast_tx_nobuf++; + spin_unlock_irqrestore(&sc->txbuflock, flags); + return -1; + } + bf = list_first_entry(&sc->txbuf, struct ath_buf, list); + list_del(&bf->list); + if (list_empty(&sc->txbuf)) { + sc->stats.ast_tx_qstop++; + ieee80211_stop_queues(hw); + } + spin_unlock_irqrestore(&sc->txbuflock, flags); + + bf->skb = skb; - dev_kfree_skb_any(skb); + if (ath_tx_bf(sc, bf, ctl)) { + bf->skb = NULL; + spin_lock_irqsave(&sc->txbuflock, flags); + list_add_tail(&bf->list, &sc->txbuf); + spin_unlock_irqrestore(&sc->txbuflock, flags); + dev_kfree_skb_any(skb); + return 0; + } return 0; } static int ath_open(struct ieee80211_hw *hw) { - printk("%s\n", __FUNCTION__); - return ath_init(hw->priv); } static int ath_stop(struct ieee80211_hw *hw) { - printk("%s\n", __FUNCTION__); - return ath_stop_hw(hw->priv); } @@ -738,10 +885,10 @@ static irqreturn_t ath_intr(int irq, void *dev_id) ath5k_hw_update_tx_triglevel(ah, true); } /* if (status & AR5K_INT_RX) - tasklet_schedule(&sc->rxtq); + tasklet_schedule(&sc->rxtq);*/ if (status & AR5K_INT_TX) tasklet_schedule(&sc->txtq); - if (status & AR5K_INT_BMISS) { +/* if (status & AR5K_INT_BMISS) { sc->stats.ast_bmiss++; tasklet_schedule(&sc->bmisstq); }*/ @@ -752,7 +899,7 @@ static irqreturn_t ath_intr(int irq, void *dev_id) } } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0); - if (!counter && printk_ratelimit()) + if (!counter && net_ratelimit()) printk(KERN_WARNING "ath: too many interrupts, giving up for " "now\n"); @@ -1062,13 +1209,14 @@ static int ath_desc_alloc(struct ath_softc *sc, struct pci_dev *pdev) bf->daddr = da; list_add_tail(&bf->list, &sc->txbuf); } - +#ifdef BLE INIT_LIST_HEAD(&sc->bbuf); for (i = 0; i < ATH_BCBUF; i++, bf++, ds++, da += sizeof(*ds)) { bf->desc = ds; bf->daddr = da; list_add_tail(&bf->list, &sc->bbuf); } +#endif return 0; err_free: @@ -1099,7 +1247,7 @@ static void ath_descdma_cleanup(struct ath_softc *sc, struct pci_dev *pdev, static void ath_desc_free(struct ath_softc *sc, struct pci_dev *pdev) { - ath_descdma_cleanup(sc, pdev, &sc->bbuf); +// ath_descdma_cleanup(sc, pdev, &sc->bbuf); ath_descdma_cleanup(sc, pdev, &sc->txbuf); ath_descdma_cleanup(sc, pdev, &sc->rxbuf); @@ -1109,7 +1257,7 @@ static void ath_desc_free(struct ath_softc *sc, struct pci_dev *pdev) kfree(sc->bufptr); sc->bufptr = NULL; } - +#ifdef BLE static int ath_beaconq_setup(struct ath_hw *ah) { struct ath5k_txq_info qi; @@ -1123,11 +1271,12 @@ static int ath_beaconq_setup(struct ath_hw *ah) return ath5k_hw_setup_tx_queue(ah, AR5K_TX_QUEUE_BEACON, &qi); } - +#endif static struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) { struct ath_hw *ah = sc->ah; + struct ath_txq *txq; struct ath5k_txq_info qi; int qnum; @@ -1158,34 +1307,34 @@ static struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, */ return ERR_PTR(qnum); } - if (qnum >= ARRAY_SIZE(sc->txq)) { + if (qnum >= ARRAY_SIZE(sc->txqs)) { printk(KERN_ERR "hal qnum %u out of range, max %u!\n", - qnum, ARRAY_SIZE(sc->txq)); + qnum, ARRAY_SIZE(sc->txqs)); ath5k_hw_release_tx_queue(ah, qnum); return ERR_PTR(-EINVAL); } - if (!test_bit(qnum, sc->txqsetup)) { - struct ath_txq *txq = &sc->txq[qnum]; - - txq->axq_qnum = qnum; - txq->axq_depth = 0; - txq->axq_intrcnt = 0; - txq->axq_link = NULL; - INIT_LIST_HEAD(&txq->axq_q); - spin_lock_init(&txq->axq_lock); - set_bit(qnum, sc->txqsetup); + printk(KERN_DEBUG "QNUM: %d\n", qnum); + txq = &sc->txqs[qnum]; + if (!txq->setup) { + txq->qnum = qnum; + txq->intrcnt = 0; + txq->link = NULL; + INIT_LIST_HEAD(&txq->q); + spin_lock_init(&txq->lock); + txq->setup = true; } - return &sc->txq[qnum]; + return &sc->txqs[qnum]; } static void ath_tx_cleanup(struct ath_softc *sc) { + struct ath_txq *txq = sc->txqs; unsigned int i; - for (i = 0; i < AR5K_NUM_TX_QUEUES; i++) - if (test_bit(i, sc->txqsetup)) { - ath5k_hw_release_tx_queue(sc->ah, sc->txq[i].axq_qnum); - clear_bit(i, sc->txqsetup); + for (i = 0; i < ARRAY_SIZE(sc->txqs); i++, txq++) + if (txq->setup) { + ath5k_hw_release_tx_queue(sc->ah, txq->qnum); + txq->setup = false; } } @@ -1260,6 +1409,7 @@ static int ath_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) goto err; } +#ifdef BLE /* * Allocate hardware transmit queues: one queue for * beacon frames and one data queue for each QoS @@ -1282,15 +1432,15 @@ static int ath_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) sc->cabq = NULL; goto err_queues; } - -#ifdef BLE - /* NB: insure BK queue is the lowest priority h/w queue */ - if (!ath_tx_setup(sc, WME_AC_BK, AR5K_WME_AC_BK)) { - printk(KERN_ERR "unable to setup xmit queue for %s traffic!\n", - ieee80211_wme_acnames[WME_AC_BK]); - error = EIO; - goto bad2; +#endif + tasklet_init(&sc->txtq, ath_tasklet_tx, (unsigned long)sc); + sc->txq = ath_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK); + if (IS_ERR(sc->txq)) { + dev_err(&pdev->dev, "can't setup xmit queue\n"); + ret = PTR_ERR(sc->txq); + goto err_queues; } +#ifdef BLE if (!ath_tx_setup(sc, WME_AC_BE, AR5K_WME_AC_BE) || !ath_tx_setup(sc, WME_AC_VI, AR5K_WME_AC_VI) || !ath_tx_setup(sc, WME_AC_VO, AR5K_WME_AC_VO)) { @@ -1397,7 +1547,7 @@ static int ath_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) return 0; err_queues: ath_tx_cleanup(sc); -err_desc: +//err_desc: ath_desc_free(sc, pdev); err: return ret; diff --git a/ath/if_athvar.h b/ath/if_athvar.h index 1b7d2c5..9439994 100644 --- a/ath/if_athvar.h +++ b/ath/if_athvar.h @@ -109,15 +109,12 @@ struct ath_node { struct ath_buf { struct list_head list; - //int nseg; - int flags; /* tx descriptor flags */ + unsigned int flags; /* tx descriptor flags */ struct ath_desc *desc; /* virtual addr of desc */ dma_addr_t daddr; /* physical addr of desc */ struct sk_buff *skb; /* skbuff for buf */ - dma_addr_t skbaddr; /* physical addr of skb data */ -#ifdef BLE - struct ieee80211_node *bf_node; /* pointer to the node */ -#endif + dma_addr_t skbaddr;/* physical addr of skb data */ + struct ieee80211_tx_control ctl; }; /* @@ -130,36 +127,23 @@ struct ath_buf { * hardware queue). */ struct ath_txq { - u_int axq_qnum; /* hardware q number */ - u_int axq_depth; /* queue depth (stat only) */ - u_int axq_intrcnt; /* interrupt count */ - u32 *axq_link; /* link ptr in last TX desc */ - struct list_head axq_q; /* transmit queue */ - spinlock_t axq_lock; /* lock on q and link */ + unsigned int qnum; /* hardware q number */ + unsigned int intrcnt; /* interrupt count */ + u32 *link; /* link ptr in last TX desc */ + struct list_head q; /* transmit queue */ + spinlock_t lock; /* lock on q and link */ /* * State for patching up CTS when bursting. */ - struct ath_buf *axq_linkbuf; /* va of last buffer */ - struct ath_desc *axq_lastdsWithCTS; - /* first desc of last descriptor - * that contains CTS - */ - struct ath_desc *axq_gatingds; /* final desc of the gating desc - * that determines whether - * lastdsWithCTS has been DMA'ed - * or not - */ + struct ath_buf *linkbuf; /* va of last buffer */ + struct ath_desc *lastdsWithCTS; /* first desc of last descriptor that + * contains CTS */ + struct ath_desc *gatingds; /* final desc of the gating desc that + * determines whether lastdsWithCTS has + * been DMA'ed or not */ + bool setup; }; -#define ATH_TXQ_INSERT_TAIL(_tq, _elm, _field) do { \ - STAILQ_INSERT_TAIL(&(_tq)->axq_q, (_elm), _field); \ - (_tq)->axq_depth++; \ -} while (0) -#define ATH_TXQ_REMOVE_HEAD(_tq, _field) do { \ - STAILQ_REMOVE_HEAD(&(_tq)->axq_q, _field); \ - (_tq)->axq_depth--; \ -} while (0) - #if CHAN_DEBUG #define ATH_CHAN_MAX (26+26+26+200+200) #else @@ -170,7 +154,6 @@ struct ath_softc { struct pci_dev *pdev; /* for dma mapping */ void __iomem *iobase; /* address of the device */ struct mutex lock; /* dev-level lock */ -// struct net_device_stats sc_devstats; /* device statistics */ struct ath_stats stats; /* private statistics */ struct ieee80211_hw *hw; /* IEEE 802.11 common */ struct ieee80211_hw_mode modes[NUM_IEEE80211_MODES]; @@ -265,40 +248,39 @@ struct ath_softc { u8 pad[64]; } u_rx_rt; int sc_rx_th_len; -#endif struct tasklet_struct fataltq; /* fatal int tasklet */ -#ifdef BLE struct tasklet_struct sc_radartq; /* Radar detection */ #endif unsigned int rxbufsize; /* rx size based on mtu */ struct list_head rxbuf; /* receive buffer */ - struct tasklet_struct rxtq; /* rx intr tasklet */ - struct tasklet_struct rxorntq; /* rxorn intr tasklet */ u32 *rxlink; /* link ptr in last RX desc */ #ifdef BLE + struct tasklet_struct rxtq; /* rx intr tasklet */ + struct tasklet_struct rxorntq; /* rxorn intr tasklet */ +//#ifdef BLE u8 sc_defant; /* current default antenna */ u8 sc_rxotherant; /* rx's on non-default antenna*/ #endif struct list_head txbuf; /* transmit buffer */ spinlock_t txbuflock; /* txbuf lock */ - struct ath_txq txq[AR5K_NUM_TX_QUEUES]; - DECLARE_BITMAP(txqsetup, AR5K_NUM_TX_QUEUES); /* h/w queues setup */ + struct ath_txq txqs[2]; /* beacon and tx*/ #ifdef BLE int sc_tx_timer; /* transmit timeout */ u_int sc_txintrperiod;/* tx interrupt batching */ struct ath_txq *sc_ac2q[5]; /* WME AC -> h/w q map */ #endif + struct ath_txq *txq; /* beacon and tx*/ struct tasklet_struct txtq; /* tx intr tasklet */ +#ifdef BLE struct list_head bbuf; /* beacon buffers */ unsigned int bhalq; /* HAL q for outgoing beacons */ -#ifdef BLE u_int sc_bmisscount; /* missed beacon transmits */ u32 sc_ant_tx[8]; /* recent tx frames/antenna */ struct ieee80211_beacon_offsets boff; /* dynamic update state */ -#endif struct ath_txq *cabq; /* tx q for cab frames */ +#endif struct tasklet_struct bmisstq; /* bmiss intr tasklet */ #ifdef BLE struct tasklet_struct sc_bstuckq; /* stuck beacon processing */ diff --git a/openhal/ath5k.h b/openhal/ath5k.h index 6f8f180..c2a109e 100644 --- a/openhal/ath5k.h +++ b/openhal/ath5k.h @@ -976,15 +976,15 @@ struct ath_hw { /* * Function pointers */ - bool (*ah_setup_tx_desc)(struct ath_hw *, struct ath_desc *, + int (*ah_setup_tx_desc)(struct ath_hw *, struct ath_desc *, unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); bool (*ah_setup_xtx_desc)(struct ath_hw *, struct ath_desc *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); - bool (*ah_fill_tx_desc)(struct ath_hw *, struct ath_desc *, - unsigned int, bool, bool, const struct ath_desc *); + int (*ah_fill_tx_desc)(struct ath_hw *, struct ath_desc *, + unsigned int, bool, bool); int (*ah_proc_tx_desc)(struct ath_hw *, struct ath_desc *); int (*ah_proc_rx_desc)(struct ath_hw *, struct ath_desc *, u32, struct ath_desc *); @@ -1012,10 +1012,10 @@ void ath5k_hw_start_rx(struct ath_hw *hal); int ath5k_hw_stop_rx_dma(struct ath_hw *hal); u32 ath5k_hw_get_rx_buf(struct ath_hw *hal); void ath5k_hw_put_rx_buf(struct ath_hw *hal, u32 phys_addr); -bool ath5k_hw_tx_start(struct ath_hw *hal, unsigned int queue); +int ath5k_hw_tx_start(struct ath_hw *hal, unsigned int queue); bool ath5k_hw_stop_tx_dma(struct ath_hw *hal, unsigned int queue); u32 ath5k_hw_get_tx_buf(struct ath_hw *hal, unsigned int queue); -bool ath5k_hw_put_tx_buf(struct ath_hw *hal, unsigned int queue, u32 phys_addr); +int ath5k_hw_put_tx_buf(struct ath_hw *hal, unsigned int queue, u32 phys_addr); bool ath5k_hw_update_tx_triglevel(struct ath_hw *hal, bool increase); /* Interrupt handling */ bool ath5k_hw_is_intr_pending(struct ath_hw *hal); diff --git a/openhal/ath5k_hw.c b/openhal/ath5k_hw.c index 0fef518..6232ce0 100644 --- a/openhal/ath5k_hw.c +++ b/openhal/ath5k_hw.c @@ -42,22 +42,22 @@ static int ath5k_hw_nic_reset(struct ath_hw *, u32); static int ath5k_hw_nic_wakeup(struct ath_hw *, int, bool); static u16 ath5k_hw_radio_revision(struct ath_hw *, unsigned int); static int ath5k_hw_txpower(struct ath_hw *, struct ieee80211_channel *, unsigned int); -static bool ath5k_hw_setup_4word_tx_desc(struct ath_hw *, struct ath_desc *, +static int ath5k_hw_setup_4word_tx_desc(struct ath_hw *, struct ath_desc *, unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); static bool ath5k_hw_setup_xr_tx_desc(struct ath_hw *, struct ath_desc *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); -static bool ath5k_hw_fill_4word_tx_desc(struct ath_hw *, struct ath_desc *, - unsigned int, bool, bool, const struct ath_desc *); +static int ath5k_hw_fill_4word_tx_desc(struct ath_hw *, struct ath_desc *, + unsigned int, bool, bool); static int ath5k_hw_proc_4word_tx_status(struct ath_hw *, struct ath_desc *); -static bool ath5k_hw_setup_2word_tx_desc(struct ath_hw *, struct ath_desc *, +static int ath5k_hw_setup_2word_tx_desc(struct ath_hw *, struct ath_desc *, unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); -static bool ath5k_hw_fill_2word_tx_desc(struct ath_hw *, struct ath_desc *, - unsigned int, bool, bool, const struct ath_desc *); +static int ath5k_hw_fill_2word_tx_desc(struct ath_hw *, struct ath_desc *, + unsigned int, bool, bool); static int ath5k_hw_proc_2word_tx_status(struct ath_hw *, struct ath_desc *); static int ath5k_hw_proc_new_rx_status(struct ath_hw *, struct ath_desc *, u32, struct ath_desc *); @@ -1457,8 +1457,7 @@ void ath5k_hw_put_rx_buf(struct ath_hw *hal, u32 phys_addr) * Start DMA transmit for a specific queue * (see also QCU/DCU functions) */ -bool -ath5k_hw_tx_start(struct ath_hw *hal, unsigned int queue) +int ath5k_hw_tx_start(struct ath_hw *hal, unsigned int queue) { u32 tx_queue; @@ -1467,10 +1466,9 @@ ath5k_hw_tx_start(struct ath_hw *hal, unsigned int queue) /* Return if queue is declared inactive */ if (hal->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) - return false; + return -EIO; if (hal->ah_version == AR5K_AR5210) { - tx_queue = ath5k_hw_reg_read(hal, AR5K_CR); /* @@ -1492,20 +1490,20 @@ ath5k_hw_tx_start(struct ath_hw *hal, unsigned int queue) AR5K_BSR); break; default: - return false; + return -EINVAL; } /* Start queue */ ath5k_hw_reg_write(hal, tx_queue, AR5K_CR); } else { /* Return if queue is disabled */ if (AR5K_REG_READ_Q(hal, AR5K_QCU_TXD, queue)) - return false; + return -EIO; /* Start queue */ AR5K_REG_WRITE_Q(hal, AR5K_QCU_TXE, queue); } - return true; + return 0; } /* @@ -1606,8 +1604,7 @@ ath5k_hw_get_tx_buf(struct ath_hw *hal, unsigned int queue) * Set the address of the TX Descriptor for a specific queue * (see also QCU/DCU functions) */ -bool -ath5k_hw_put_tx_buf(struct ath_hw *hal, unsigned int queue, u32 phys_addr) +int ath5k_hw_put_tx_buf(struct ath_hw *hal, unsigned int queue, u32 phys_addr) { u16 tx_reg; AR5K_TRACE; @@ -1627,7 +1624,7 @@ ath5k_hw_put_tx_buf(struct ath_hw *hal, unsigned int queue, u32 phys_addr) tx_reg = AR5K_NOQCU_TXDP1; break; default: - return false; + return -EINVAL; } } else { /* @@ -1636,7 +1633,7 @@ ath5k_hw_put_tx_buf(struct ath_hw *hal, unsigned int queue, u32 phys_addr) * (this won't work if the queue is still active) */ if (AR5K_REG_READ_Q(hal, AR5K_QCU_TXE, queue)) - return false; + return -EIO; tx_reg = AR5K_QUEUE_TXDP(queue); } @@ -1644,7 +1641,7 @@ ath5k_hw_put_tx_buf(struct ath_hw *hal, unsigned int queue, u32 phys_addr) /* Set descriptor pointer */ ath5k_hw_reg_write(hal, phys_addr, tx_reg); - return true; + return 0; } /* @@ -3725,22 +3722,20 @@ ath5k_hw_get_slot_time(struct ath_hw *hal) /* * Initialize the 2-word tx descriptor on 5210/5211 */ -static bool +static int ath5k_hw_setup_2word_tx_desc(struct ath_hw *hal, struct ath_desc *desc, - unsigned int packet_length, u_int header_length, enum ath5k_pkt_type type, u_int tx_power, - unsigned int tx_rate0, u_int tx_tries0, u_int key_index, u_int antenna_mode, - unsigned int flags, u_int rtscts_rate, u_int rtscts_duration) + unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type, + unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0, + unsigned int key_index, unsigned int antenna_mode, unsigned int flags, + unsigned int rtscts_rate, unsigned int rtscts_duration) { u32 frame_type; struct ath5k_hw_2w_tx_desc *tx_desc; tx_desc = (struct ath5k_hw_2w_tx_desc*)&desc->ds_ctl0; - /* - * Validate input - */ if (tx_tries0 == 0) - return false; + return -EINVAL; /* Initialize control descriptor */ tx_desc->tx_control_0 = 0; @@ -3749,17 +3744,18 @@ ath5k_hw_setup_2word_tx_desc(struct ath_hw *hal, struct ath_desc *desc, /* Setup control descriptor */ /*Verify packet length*/ - if ((tx_desc->tx_control_0 = (packet_length & - AR5K_2W_TX_DESC_CTL0_FRAME_LEN)) != packet_length) - return false; + tx_desc->tx_control_0 = pkt_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN; + if (tx_desc->tx_control_0 != pkt_len) + return -EINVAL; /* * Verify header length * XXX: I only found that on 5210 code, does it work on 5211 ? */ - if (hal->ah_version == AR5K_AR5210) - if ((tx_desc->tx_control_0 = (header_length & - AR5K_2W_TX_DESC_CTL0_HEADER_LEN)) != header_length) - return false; + if (hal->ah_version == AR5K_AR5210) { + tx_desc->tx_control_0 = hdr_len & AR5K_2W_TX_DESC_CTL0_HEADER_LEN; + if (tx_desc->tx_control_0 != hdr_len) + return -EINVAL; + } /*Diferences between 5210-5211*/ if (hal->ah_version == AR5K_AR5210) { @@ -3816,17 +3812,18 @@ ath5k_hw_setup_2word_tx_desc(struct ath_hw *hal, struct ath_desc *desc, rtscts_duration & AR5K_2W_TX_DESC_CTL1_RTS_DURATION; } - return true; + return 0; } /* * Initialize the 4-word tx descriptor on 5212 */ -static bool -ath5k_hw_setup_4word_tx_desc(struct ath_hw *hal, struct ath_desc *desc, - unsigned int packet_length, u_int header_length, enum ath5k_pkt_type type, u_int tx_power, - unsigned int tx_rate0, u_int tx_tries0, u_int key_index, u_int antenna_mode, - unsigned int flags, u_int rtscts_rate, u_int rtscts_duration) +static int ath5k_hw_setup_4word_tx_desc(struct ath_hw *hal, + struct ath_desc *desc, unsigned int pkt_len, unsigned int hdr_len, + enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0, + unsigned int tx_tries0, unsigned int key_index, + unsigned int antenna_mode, unsigned int flags, unsigned int rtscts_rate, + unsigned int rtscts_duration) { struct ath5k_hw_4w_tx_desc *tx_desc; @@ -3838,7 +3835,7 @@ ath5k_hw_setup_4word_tx_desc(struct ath_hw *hal, struct ath_desc *desc, * Validate input */ if (tx_tries0 == 0) - return false; + return -EINVAL; /* Initialize status descriptor */ tx_desc->tx_control_0 = 0; @@ -3847,20 +3844,18 @@ ath5k_hw_setup_4word_tx_desc(struct ath_hw *hal, struct ath_desc *desc, tx_desc->tx_control_3 = 0; /* Setup status descriptor */ - if ((tx_desc->tx_control_0 = (packet_length & - AR5K_4W_TX_DESC_CTL0_FRAME_LEN)) != packet_length) - return false; + tx_desc->tx_control_0 = pkt_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; + if (tx_desc->tx_control_0 != pkt_len) + return -EINVAL; tx_desc->tx_control_0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); - tx_desc->tx_control_1 = - AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); - tx_desc->tx_control_2 = - AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES, - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); - tx_desc->tx_control_3 = - tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; + tx_desc->tx_control_1 = AR5K_REG_SM(type, + AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); + tx_desc->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES, + AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); + tx_desc->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; #define _TX_FLAGS(_c, _flag) \ if (flags & AR5K_TXDESC_##_flag) \ @@ -3880,28 +3875,24 @@ ath5k_hw_setup_4word_tx_desc(struct ath_hw *hal, struct ath_desc *desc, * WEP crap */ if (key_index != AR5K_TXKEYIX_INVALID) { - tx_desc->tx_control_0 |= - AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; - tx_desc->tx_control_1 |= - AR5K_REG_SM(key_index, - AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); + tx_desc->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; + tx_desc->tx_control_1 |= AR5K_REG_SM(key_index, + AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); } /* * RTS/CTS */ if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) { - if ((flags & AR5K_TXDESC_RTSENA) && - (flags & AR5K_TXDESC_CTSENA)) - return false; - tx_desc->tx_control_2 |= - rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION; - tx_desc->tx_control_3 |= - AR5K_REG_SM(rtscts_rate, - AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); + if ((flags & AR5K_TXDESC_RTSENA) &&(flags & AR5K_TXDESC_CTSENA)) + return -EINVAL; + tx_desc->tx_control_2 |= rtscts_duration & + AR5K_4W_TX_DESC_CTL2_RTS_DURATION; + tx_desc->tx_control_3 |= AR5K_REG_SM(rtscts_rate, + AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); } - return true; + return 0; } /* @@ -3942,9 +3933,9 @@ ath5k_hw_setup_xr_tx_desc(struct ath_hw *hal, struct ath_desc *desc, /* * Fill the 2-word tx descriptor on 5210/5211 */ -static bool -ath5k_hw_fill_2word_tx_desc(struct ath_hw *hal, struct ath_desc *desc, - unsigned int segment_length, bool first_segment, bool last_segment, const struct ath_desc *last_desc) +static int ath5k_hw_fill_2word_tx_desc(struct ath_hw *hal, + struct ath_desc *desc, unsigned int segment_length, + bool first_segment, bool last_segment) { struct ath5k_hw_2w_tx_desc *tx_desc; @@ -3954,9 +3945,9 @@ ath5k_hw_fill_2word_tx_desc(struct ath_hw *hal, struct ath_desc *desc, memset(desc->ds_hw, 0, sizeof(desc->ds_hw)); /* Validate segment length and initialize the descriptor */ - if ((tx_desc->tx_control_1 = (segment_length & - AR5K_2W_TX_DESC_CTL1_BUF_LEN)) != segment_length) - return false; + tx_desc->tx_control_1 = segment_length & AR5K_2W_TX_DESC_CTL1_BUF_LEN; + if (tx_desc->tx_control_1 != segment_length) + return -EINVAL; if (first_segment != true) tx_desc->tx_control_0 &= ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN; @@ -3964,17 +3955,16 @@ ath5k_hw_fill_2word_tx_desc(struct ath_hw *hal, struct ath_desc *desc, if (last_segment != true) tx_desc->tx_control_1 |= AR5K_2W_TX_DESC_CTL1_MORE; - return true; + return 0; } /* * Fill the 4-word tx descriptor on 5212 * XXX: Added an argument *last_desc -need revision */ -static bool -ath5k_hw_fill_4word_tx_desc(struct ath_hw *hal, struct ath_desc *desc, - unsigned int segment_length, bool first_segment, bool last_segment, - const struct ath_desc *last_desc) +static int ath5k_hw_fill_4word_tx_desc(struct ath_hw *hal, + struct ath_desc *desc, unsigned int segment_length, + bool first_segment, bool last_segment) { struct ath5k_hw_4w_tx_desc *tx_desc; struct ath5k_hw_tx_status *tx_status; @@ -3987,9 +3977,9 @@ ath5k_hw_fill_4word_tx_desc(struct ath_hw *hal, struct ath_desc *desc, memset(tx_status, 0, sizeof(struct ath5k_hw_tx_status)); /* Validate segment length and initialize the descriptor */ - if ((tx_desc->tx_control_1 = (segment_length & - AR5K_4W_TX_DESC_CTL1_BUF_LEN)) != segment_length) - return false; + tx_desc->tx_control_1 = segment_length & AR5K_4W_TX_DESC_CTL1_BUF_LEN; + if (tx_desc->tx_control_1 != segment_length) + return -EINVAL; if (first_segment != true) tx_desc->tx_control_0 &= ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN; @@ -3997,7 +3987,7 @@ ath5k_hw_fill_4word_tx_desc(struct ath_hw *hal, struct ath_desc *desc, if (last_segment != true) tx_desc->tx_control_1 |= AR5K_4W_TX_DESC_CTL1_MORE; - return true; + return 0; } /* @@ -4019,40 +4009,31 @@ static int ath5k_hw_proc_2word_tx_status(struct ath_hw *hal, /* * Get descriptor status */ - desc->ds_us.tx.ts_tstamp = - AR5K_REG_MS(tx_status->tx_status_0, - AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); - desc->ds_us.tx.ts_shortretry = - AR5K_REG_MS(tx_status->tx_status_0, - AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); - desc->ds_us.tx.ts_longretry = - AR5K_REG_MS(tx_status->tx_status_0, - AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); + desc->ds_us.tx.ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, + AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); + desc->ds_us.tx.ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, + AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); + desc->ds_us.tx.ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, + AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); /*TODO: desc->ds_us.tx.ts_virtcol + test*/ - desc->ds_us.tx.ts_seqnum = - AR5K_REG_MS(tx_status->tx_status_1, - AR5K_DESC_TX_STATUS1_SEQ_NUM); - desc->ds_us.tx.ts_rssi = - AR5K_REG_MS(tx_status->tx_status_1, - AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); + desc->ds_us.tx.ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, + AR5K_DESC_TX_STATUS1_SEQ_NUM); + desc->ds_us.tx.ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, + AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); desc->ds_us.tx.ts_antenna = 1; desc->ds_us.tx.ts_status = 0; - desc->ds_us.tx.ts_rate = - AR5K_REG_MS(tx_desc->tx_control_0, - AR5K_2W_TX_DESC_CTL0_XMIT_RATE); + desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_0, + AR5K_2W_TX_DESC_CTL0_XMIT_RATE); - if ((tx_status->tx_status_0 & - AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0) { + if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){ if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) desc->ds_us.tx.ts_status |= AR5K_TXERR_XRETRY; - if (tx_status->tx_status_0 & - AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) + if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) desc->ds_us.tx.ts_status |= AR5K_TXERR_FIFO; - if (tx_status->tx_status_0 & - AR5K_DESC_TX_STATUS0_FILTERED) + if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) desc->ds_us.tx.ts_status |= AR5K_TXERR_FILT; } @@ -4079,69 +4060,55 @@ static int ath5k_hw_proc_4word_tx_status(struct ath_hw *hal, /* * Get descriptor status */ - desc->ds_us.tx.ts_tstamp = - AR5K_REG_MS(tx_status->tx_status_0, - AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); - desc->ds_us.tx.ts_shortretry = - AR5K_REG_MS(tx_status->tx_status_0, - AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); - desc->ds_us.tx.ts_longretry = - AR5K_REG_MS(tx_status->tx_status_0, - AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); - desc->ds_us.tx.ts_seqnum = - AR5K_REG_MS(tx_status->tx_status_1, - AR5K_DESC_TX_STATUS1_SEQ_NUM); - desc->ds_us.tx.ts_rssi = - AR5K_REG_MS(tx_status->tx_status_1, - AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); + desc->ds_us.tx.ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, + AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); + desc->ds_us.tx.ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, + AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); + desc->ds_us.tx.ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, + AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); + desc->ds_us.tx.ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, + AR5K_DESC_TX_STATUS1_SEQ_NUM); + desc->ds_us.tx.ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, + AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); desc->ds_us.tx.ts_antenna = (tx_status->tx_status_1 & - AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1; + AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1; desc->ds_us.tx.ts_status = 0; switch (AR5K_REG_MS(tx_status->tx_status_1, - AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) { + AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) { case 0: desc->ds_us.tx.ts_rate = tx_desc->tx_control_3 & - AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; + AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; break; case 1: - desc->ds_us.tx.ts_rate = - AR5K_REG_MS(tx_desc->tx_control_3, - AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); - desc->ds_us.tx.ts_longretry += - AR5K_REG_MS(tx_desc->tx_control_2, - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); + desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3, + AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); + desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2, + AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); break; case 2: - desc->ds_us.tx.ts_rate = - AR5K_REG_MS(tx_desc->tx_control_3, - AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); - desc->ds_us.tx.ts_longretry += - AR5K_REG_MS(tx_desc->tx_control_2, - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); + desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3, + AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); + desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2, + AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); break; case 3: - desc->ds_us.tx.ts_rate = - AR5K_REG_MS(tx_desc->tx_control_3, - AR5K_4W_TX_DESC_CTL3_XMIT_RATE3); - desc->ds_us.tx.ts_longretry += - AR5K_REG_MS(tx_desc->tx_control_2, - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3); + desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3, + AR5K_4W_TX_DESC_CTL3_XMIT_RATE3); + desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2, + AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3); break; } - if ((tx_status->tx_status_0 & - AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0) { + if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){ if (tx_status->tx_status_0 & - AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) + AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) desc->ds_us.tx.ts_status |= AR5K_TXERR_XRETRY; - if (tx_status->tx_status_0 & - AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) + if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) desc->ds_us.tx.ts_status |= AR5K_TXERR_FIFO; - if (tx_status->tx_status_0 & - AR5K_DESC_TX_STATUS0_FILTERED) + if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) desc->ds_us.tx.ts_status |= AR5K_TXERR_FILT; }