aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath5k/base.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-05-15 06:55:29 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-21 21:48:11 -0400
commite039fa4a4195ac4ee895e6f3d1334beed63256fe (patch)
treecfd0762d73df96b73052378be7b157c4ac6e7035 /drivers/net/wireless/ath5k/base.c
parente24549485f859be6518929bb1c9c0257d79f033d (diff)
mac80211: move TX info into skb->cb
This patch converts mac80211 and all drivers to have transmit information and status in skb->cb rather than allocating extra memory for it and copying all the data around. To make it fit, a union is used where only data that is necessary for all steps is kept outside of the union. A number of fixes were done by Ivo, as well as the rt2x00 part of this patch. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath5k/base.c')
-rw-r--r--drivers/net/wireless/ath5k/base.c70
1 files changed, 32 insertions, 38 deletions
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 32ee351a7650..7d97934265db 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -167,8 +167,7 @@ static struct pci_driver ath5k_pci_driver = {
167/* 167/*
168 * Prototypes - MAC 802.11 stack related functions 168 * Prototypes - MAC 802.11 stack related functions
169 */ 169 */
170static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb, 170static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
171 struct ieee80211_tx_control *ctl);
172static int ath5k_reset(struct ieee80211_hw *hw); 171static int ath5k_reset(struct ieee80211_hw *hw);
173static int ath5k_start(struct ieee80211_hw *hw); 172static int ath5k_start(struct ieee80211_hw *hw);
174static void ath5k_stop(struct ieee80211_hw *hw); 173static void ath5k_stop(struct ieee80211_hw *hw);
@@ -196,8 +195,7 @@ static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
196static u64 ath5k_get_tsf(struct ieee80211_hw *hw); 195static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
197static void ath5k_reset_tsf(struct ieee80211_hw *hw); 196static void ath5k_reset_tsf(struct ieee80211_hw *hw);
198static int ath5k_beacon_update(struct ieee80211_hw *hw, 197static int ath5k_beacon_update(struct ieee80211_hw *hw,
199 struct sk_buff *skb, 198 struct sk_buff *skb);
200 struct ieee80211_tx_control *ctl);
201 199
202static struct ieee80211_ops ath5k_hw_ops = { 200static struct ieee80211_ops ath5k_hw_ops = {
203 .tx = ath5k_tx, 201 .tx = ath5k_tx,
@@ -251,9 +249,7 @@ static void ath5k_desc_free(struct ath5k_softc *sc,
251static int ath5k_rxbuf_setup(struct ath5k_softc *sc, 249static int ath5k_rxbuf_setup(struct ath5k_softc *sc,
252 struct ath5k_buf *bf); 250 struct ath5k_buf *bf);
253static int ath5k_txbuf_setup(struct ath5k_softc *sc, 251static int ath5k_txbuf_setup(struct ath5k_softc *sc,
254 struct ath5k_buf *bf, 252 struct ath5k_buf *bf);
255 struct ieee80211_tx_control *ctl);
256
257static inline void ath5k_txbuf_free(struct ath5k_softc *sc, 253static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
258 struct ath5k_buf *bf) 254 struct ath5k_buf *bf)
259{ 255{
@@ -289,8 +285,7 @@ static void ath5k_tx_processq(struct ath5k_softc *sc,
289static void ath5k_tasklet_tx(unsigned long data); 285static void ath5k_tasklet_tx(unsigned long data);
290/* Beacon handling */ 286/* Beacon handling */
291static int ath5k_beacon_setup(struct ath5k_softc *sc, 287static int ath5k_beacon_setup(struct ath5k_softc *sc,
292 struct ath5k_buf *bf, 288 struct ath5k_buf *bf);
293 struct ieee80211_tx_control *ctl);
294static void ath5k_beacon_send(struct ath5k_softc *sc); 289static void ath5k_beacon_send(struct ath5k_softc *sc);
295static void ath5k_beacon_config(struct ath5k_softc *sc); 290static void ath5k_beacon_config(struct ath5k_softc *sc);
296static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); 291static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
@@ -1295,37 +1290,36 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1295} 1290}
1296 1291
1297static int 1292static int
1298ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, 1293ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1299 struct ieee80211_tx_control *ctl)
1300{ 1294{
1301 struct ath5k_hw *ah = sc->ah; 1295 struct ath5k_hw *ah = sc->ah;
1302 struct ath5k_txq *txq = sc->txq; 1296 struct ath5k_txq *txq = sc->txq;
1303 struct ath5k_desc *ds = bf->desc; 1297 struct ath5k_desc *ds = bf->desc;
1304 struct sk_buff *skb = bf->skb; 1298 struct sk_buff *skb = bf->skb;
1299 struct ieee80211_tx_info *info = (void*) skb->cb;
1305 unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID; 1300 unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
1306 int ret; 1301 int ret;
1307 1302
1308 flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; 1303 flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
1309 bf->ctl = *ctl; 1304
1310 /* XXX endianness */ 1305 /* XXX endianness */
1311 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, 1306 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
1312 PCI_DMA_TODEVICE); 1307 PCI_DMA_TODEVICE);
1313 1308
1314 if (ctl->flags & IEEE80211_TXCTL_NO_ACK) 1309 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
1315 flags |= AR5K_TXDESC_NOACK; 1310 flags |= AR5K_TXDESC_NOACK;
1316 1311
1317 pktlen = skb->len; 1312 pktlen = skb->len;
1318 1313
1319 if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) { 1314 if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)) {
1320 keyidx = ctl->hw_key->hw_key_idx; 1315 keyidx = info->control.hw_key->hw_key_idx;
1321 pktlen += ctl->icv_len; 1316 pktlen += info->control.icv_len;
1322 } 1317 }
1323
1324 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 1318 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
1325 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, 1319 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
1326 (sc->power_level * 2), 1320 (sc->power_level * 2),
1327 ieee80211_get_tx_rate(sc->hw, ctl)->hw_value, 1321 ieee80211_get_tx_rate(sc->hw, info)->hw_value,
1328 ctl->retry_limit, keyidx, 0, flags, 0, 0); 1322 info->control.retry_limit, keyidx, 0, flags, 0, 0);
1329 if (ret) 1323 if (ret)
1330 goto err_unmap; 1324 goto err_unmap;
1331 1325
@@ -1927,11 +1921,11 @@ next:
1927static void 1921static void
1928ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) 1922ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1929{ 1923{
1930 struct ieee80211_tx_status txs = {};
1931 struct ath5k_tx_status ts = {}; 1924 struct ath5k_tx_status ts = {};
1932 struct ath5k_buf *bf, *bf0; 1925 struct ath5k_buf *bf, *bf0;
1933 struct ath5k_desc *ds; 1926 struct ath5k_desc *ds;
1934 struct sk_buff *skb; 1927 struct sk_buff *skb;
1928 struct ieee80211_tx_info *info;
1935 int ret; 1929 int ret;
1936 1930
1937 spin_lock(&txq->lock); 1931 spin_lock(&txq->lock);
@@ -1951,24 +1945,25 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1951 } 1945 }
1952 1946
1953 skb = bf->skb; 1947 skb = bf->skb;
1948 info = (void*) skb->cb;
1954 bf->skb = NULL; 1949 bf->skb = NULL;
1950
1955 pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, 1951 pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
1956 PCI_DMA_TODEVICE); 1952 PCI_DMA_TODEVICE);
1957 1953
1958 txs.control = bf->ctl; 1954 info->status.retry_count = ts.ts_shortretry + ts.ts_longretry / 6;
1959 txs.retry_count = ts.ts_shortretry + ts.ts_longretry / 6;
1960 if (unlikely(ts.ts_status)) { 1955 if (unlikely(ts.ts_status)) {
1961 sc->ll_stats.dot11ACKFailureCount++; 1956 sc->ll_stats.dot11ACKFailureCount++;
1962 if (ts.ts_status & AR5K_TXERR_XRETRY) 1957 if (ts.ts_status & AR5K_TXERR_XRETRY)
1963 txs.excessive_retries = 1; 1958 info->status.excessive_retries = 1;
1964 else if (ts.ts_status & AR5K_TXERR_FILT) 1959 else if (ts.ts_status & AR5K_TXERR_FILT)
1965 txs.flags |= IEEE80211_TX_STATUS_TX_FILTERED; 1960 info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
1966 } else { 1961 } else {
1967 txs.flags |= IEEE80211_TX_STATUS_ACK; 1962 info->flags |= IEEE80211_TX_STAT_ACK;
1968 txs.ack_signal = ts.ts_rssi; 1963 info->status.ack_signal = ts.ts_rssi;
1969 } 1964 }
1970 1965
1971 ieee80211_tx_status(sc->hw, skb, &txs); 1966 ieee80211_tx_status(sc->hw, skb);
1972 sc->tx_stats[txq->qnum].count++; 1967 sc->tx_stats[txq->qnum].count++;
1973 1968
1974 spin_lock(&sc->txbuflock); 1969 spin_lock(&sc->txbuflock);
@@ -2005,10 +2000,10 @@ ath5k_tasklet_tx(unsigned long data)
2005 * Setup the beacon frame for transmit. 2000 * Setup the beacon frame for transmit.
2006 */ 2001 */
2007static int 2002static int
2008ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, 2003ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2009 struct ieee80211_tx_control *ctl)
2010{ 2004{
2011 struct sk_buff *skb = bf->skb; 2005 struct sk_buff *skb = bf->skb;
2006 struct ieee80211_tx_info *info = (void*) skb->cb;
2012 struct ath5k_hw *ah = sc->ah; 2007 struct ath5k_hw *ah = sc->ah;
2013 struct ath5k_desc *ds; 2008 struct ath5k_desc *ds;
2014 int ret, antenna = 0; 2009 int ret, antenna = 0;
@@ -2047,7 +2042,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
2047 ret = ah->ah_setup_tx_desc(ah, ds, skb->len, 2042 ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
2048 ieee80211_get_hdrlen_from_skb(skb), 2043 ieee80211_get_hdrlen_from_skb(skb),
2049 AR5K_PKT_TYPE_BEACON, (sc->power_level * 2), 2044 AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
2050 ieee80211_get_tx_rate(sc->hw, ctl)->hw_value, 2045 ieee80211_get_tx_rate(sc->hw, info)->hw_value,
2051 1, AR5K_TXKEYIX_INVALID, 2046 1, AR5K_TXKEYIX_INVALID,
2052 antenna, flags, 0, 0); 2047 antenna, flags, 0, 0);
2053 if (ret) 2048 if (ret)
@@ -2626,11 +2621,11 @@ ath5k_led_event(struct ath5k_softc *sc, int event)
2626\********************/ 2621\********************/
2627 2622
2628static int 2623static int
2629ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb, 2624ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2630 struct ieee80211_tx_control *ctl)
2631{ 2625{
2632 struct ath5k_softc *sc = hw->priv; 2626 struct ath5k_softc *sc = hw->priv;
2633 struct ath5k_buf *bf; 2627 struct ath5k_buf *bf;
2628 struct ieee80211_tx_info *info = (void*) skb->cb;
2634 unsigned long flags; 2629 unsigned long flags;
2635 int hdrlen; 2630 int hdrlen;
2636 int pad; 2631 int pad;
@@ -2656,13 +2651,13 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
2656 memmove(skb->data, skb->data+pad, hdrlen); 2651 memmove(skb->data, skb->data+pad, hdrlen);
2657 } 2652 }
2658 2653
2659 sc->led_txrate = ieee80211_get_tx_rate(hw, ctl)->hw_value; 2654 sc->led_txrate = ieee80211_get_tx_rate(hw, info)->hw_value;
2660 2655
2661 spin_lock_irqsave(&sc->txbuflock, flags); 2656 spin_lock_irqsave(&sc->txbuflock, flags);
2662 if (list_empty(&sc->txbuf)) { 2657 if (list_empty(&sc->txbuf)) {
2663 ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); 2658 ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
2664 spin_unlock_irqrestore(&sc->txbuflock, flags); 2659 spin_unlock_irqrestore(&sc->txbuflock, flags);
2665 ieee80211_stop_queue(hw, ctl->queue); 2660 ieee80211_stop_queue(hw, info->queue);
2666 return -1; 2661 return -1;
2667 } 2662 }
2668 bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); 2663 bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
@@ -2674,7 +2669,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
2674 2669
2675 bf->skb = skb; 2670 bf->skb = skb;
2676 2671
2677 if (ath5k_txbuf_setup(sc, bf, ctl)) { 2672 if (ath5k_txbuf_setup(sc, bf)) {
2678 bf->skb = NULL; 2673 bf->skb = NULL;
2679 spin_lock_irqsave(&sc->txbuflock, flags); 2674 spin_lock_irqsave(&sc->txbuflock, flags);
2680 list_add_tail(&bf->list, &sc->txbuf); 2675 list_add_tail(&bf->list, &sc->txbuf);
@@ -3052,8 +3047,7 @@ ath5k_reset_tsf(struct ieee80211_hw *hw)
3052} 3047}
3053 3048
3054static int 3049static int
3055ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, 3050ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
3056 struct ieee80211_tx_control *ctl)
3057{ 3051{
3058 struct ath5k_softc *sc = hw->priv; 3052 struct ath5k_softc *sc = hw->priv;
3059 int ret; 3053 int ret;
@@ -3069,7 +3063,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
3069 3063
3070 ath5k_txbuf_free(sc, sc->bbuf); 3064 ath5k_txbuf_free(sc, sc->bbuf);
3071 sc->bbuf->skb = skb; 3065 sc->bbuf->skb = skb;
3072 ret = ath5k_beacon_setup(sc, sc->bbuf, ctl); 3066 ret = ath5k_beacon_setup(sc, sc->bbuf);
3073 if (ret) 3067 if (ret)
3074 sc->bbuf->skb = NULL; 3068 sc->bbuf->skb = NULL;
3075 else 3069 else