diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-05-15 06:55:29 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-21 21:48:11 -0400 |
commit | e039fa4a4195ac4ee895e6f3d1334beed63256fe (patch) | |
tree | cfd0762d73df96b73052378be7b157c4ac6e7035 /drivers/net/wireless/ath5k/base.c | |
parent | e24549485f859be6518929bb1c9c0257d79f033d (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.c | 70 |
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 | */ |
170 | static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | 170 | static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); |
171 | struct ieee80211_tx_control *ctl); | ||
172 | static int ath5k_reset(struct ieee80211_hw *hw); | 171 | static int ath5k_reset(struct ieee80211_hw *hw); |
173 | static int ath5k_start(struct ieee80211_hw *hw); | 172 | static int ath5k_start(struct ieee80211_hw *hw); |
174 | static void ath5k_stop(struct ieee80211_hw *hw); | 173 | static void ath5k_stop(struct ieee80211_hw *hw); |
@@ -196,8 +195,7 @@ static int ath5k_get_tx_stats(struct ieee80211_hw *hw, | |||
196 | static u64 ath5k_get_tsf(struct ieee80211_hw *hw); | 195 | static u64 ath5k_get_tsf(struct ieee80211_hw *hw); |
197 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); | 196 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); |
198 | static int ath5k_beacon_update(struct ieee80211_hw *hw, | 197 | static 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 | ||
202 | static struct ieee80211_ops ath5k_hw_ops = { | 200 | static 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, | |||
251 | static int ath5k_rxbuf_setup(struct ath5k_softc *sc, | 249 | static int ath5k_rxbuf_setup(struct ath5k_softc *sc, |
252 | struct ath5k_buf *bf); | 250 | struct ath5k_buf *bf); |
253 | static int ath5k_txbuf_setup(struct ath5k_softc *sc, | 251 | static 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 | |||
257 | static inline void ath5k_txbuf_free(struct ath5k_softc *sc, | 253 | static 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, | |||
289 | static void ath5k_tasklet_tx(unsigned long data); | 285 | static void ath5k_tasklet_tx(unsigned long data); |
290 | /* Beacon handling */ | 286 | /* Beacon handling */ |
291 | static int ath5k_beacon_setup(struct ath5k_softc *sc, | 287 | static int ath5k_beacon_setup(struct ath5k_softc *sc, |
292 | struct ath5k_buf *bf, | 288 | struct ath5k_buf *bf); |
293 | struct ieee80211_tx_control *ctl); | ||
294 | static void ath5k_beacon_send(struct ath5k_softc *sc); | 289 | static void ath5k_beacon_send(struct ath5k_softc *sc); |
295 | static void ath5k_beacon_config(struct ath5k_softc *sc); | 290 | static void ath5k_beacon_config(struct ath5k_softc *sc); |
296 | static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); | 291 | static 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 | ||
1297 | static int | 1292 | static int |
1298 | ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | 1293 | ath5k_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: | |||
1927 | static void | 1921 | static void |
1928 | ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | 1922 | ath5k_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 | */ |
2007 | static int | 2002 | static int |
2008 | ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | 2003 | ath5k_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 | ||
2628 | static int | 2623 | static int |
2629 | ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | 2624 | ath5k_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 | ||
3054 | static int | 3049 | static int |
3055 | ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | 3050 | ath5k_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 |