diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-10-21 06:40:02 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-10-31 19:00:23 -0400 |
commit | e6a9854b05c1a6af1308fe2b8c68f35abf28a3ee (patch) | |
tree | 241f611f8194586ccabf61bacb060508773b9d05 /drivers/net/wireless/b43legacy | |
parent | cb121bad67a32cde37adc2729b7e18aa4fd3063e (diff) |
mac80211/drivers: rewrite the rate control API
So after the previous changes we were still unhappy with how
convoluted the API is and decided to make things simpler for
everybody. This completely changes the rate control API, now
taking into account 802.11n with MCS rates and more control,
most drivers don't support that though.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43legacy')
-rw-r--r-- | drivers/net/wireless/b43legacy/dma.c | 46 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/pio.c | 31 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/xmit.c | 26 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/xmit.h | 2 |
5 files changed, 82 insertions, 25 deletions
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index fb6819e40f38..308c2647f002 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c | |||
@@ -1411,6 +1411,7 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, | |||
1411 | struct b43legacy_dmaring *ring; | 1411 | struct b43legacy_dmaring *ring; |
1412 | struct b43legacy_dmadesc_generic *desc; | 1412 | struct b43legacy_dmadesc_generic *desc; |
1413 | struct b43legacy_dmadesc_meta *meta; | 1413 | struct b43legacy_dmadesc_meta *meta; |
1414 | int retry_limit; | ||
1414 | int slot; | 1415 | int slot; |
1415 | 1416 | ||
1416 | ring = parse_cookie(dev, status->cookie, &slot); | 1417 | ring = parse_cookie(dev, status->cookie, &slot); |
@@ -1437,25 +1438,42 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, | |||
1437 | struct ieee80211_tx_info *info; | 1438 | struct ieee80211_tx_info *info; |
1438 | BUG_ON(!meta->skb); | 1439 | BUG_ON(!meta->skb); |
1439 | info = IEEE80211_SKB_CB(meta->skb); | 1440 | info = IEEE80211_SKB_CB(meta->skb); |
1440 | /* Call back to inform the ieee80211 subsystem about the | ||
1441 | * status of the transmission. | ||
1442 | * Some fields of txstat are already filled in dma_tx(). | ||
1443 | */ | ||
1444 | 1441 | ||
1445 | memset(&info->status, 0, sizeof(info->status)); | 1442 | /* preserve the confiured retry limit before clearing the status |
1443 | * The xmit function has overwritten the rc's value with the actual | ||
1444 | * retry limit done by the hardware */ | ||
1445 | retry_limit = info->status.rates[0].count; | ||
1446 | ieee80211_tx_info_clear_status(info); | ||
1446 | 1447 | ||
1447 | if (status->acked) { | 1448 | if (status->acked) |
1448 | info->flags |= IEEE80211_TX_STAT_ACK; | 1449 | info->flags |= IEEE80211_TX_STAT_ACK; |
1450 | |||
1451 | if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) { | ||
1452 | /* | ||
1453 | * If the short retries (RTS, not data frame) have exceeded | ||
1454 | * the limit, the hw will not have tried the selected rate, | ||
1455 | * but will have used the fallback rate instead. | ||
1456 | * Don't let the rate control count attempts for the selected | ||
1457 | * rate in this case, otherwise the statistics will be off. | ||
1458 | */ | ||
1459 | info->status.rates[0].count = 0; | ||
1460 | info->status.rates[1].count = status->frame_count; | ||
1449 | } else { | 1461 | } else { |
1450 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | 1462 | if (status->frame_count > retry_limit) { |
1451 | info->status.excessive_retries = 1; | 1463 | info->status.rates[0].count = retry_limit; |
1464 | info->status.rates[1].count = status->frame_count - | ||
1465 | retry_limit; | ||
1466 | |||
1467 | } else { | ||
1468 | info->status.rates[0].count = status->frame_count; | ||
1469 | info->status.rates[1].idx = -1; | ||
1470 | } | ||
1452 | } | 1471 | } |
1453 | if (status->frame_count == 0) { | 1472 | |
1454 | /* The frame was not transmitted at all. */ | 1473 | /* Call back to inform the ieee80211 subsystem about the |
1455 | info->status.retry_count = 0; | 1474 | * status of the transmission. |
1456 | } else | 1475 | * Some fields of txstat are already filled in dma_tx(). |
1457 | info->status.retry_count = status->frame_count | 1476 | */ |
1458 | - 1; | ||
1459 | ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb); | 1477 | ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb); |
1460 | /* skb is freed by ieee80211_tx_status_irqsafe() */ | 1478 | /* skb is freed by ieee80211_tx_status_irqsafe() */ |
1461 | meta->skb = NULL; | 1479 | meta->skb = NULL; |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 78e46365f69e..9edbdf9cb50f 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -3682,7 +3682,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev) | |||
3682 | BIT(NL80211_IFTYPE_WDS) | | 3682 | BIT(NL80211_IFTYPE_WDS) | |
3683 | BIT(NL80211_IFTYPE_ADHOC); | 3683 | BIT(NL80211_IFTYPE_ADHOC); |
3684 | hw->queues = 1; /* FIXME: hardware has more queues */ | 3684 | hw->queues = 1; /* FIXME: hardware has more queues */ |
3685 | hw->max_altrates = 1; | 3685 | hw->max_rates = 2; |
3686 | SET_IEEE80211_DEV(hw, dev->dev); | 3686 | SET_IEEE80211_DEV(hw, dev->dev); |
3687 | if (is_valid_ether_addr(sprom->et1mac)) | 3687 | if (is_valid_ether_addr(sprom->et1mac)) |
3688 | SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); | 3688 | SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); |
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c index a86c7647fa2d..746d5361bba0 100644 --- a/drivers/net/wireless/b43legacy/pio.c +++ b/drivers/net/wireless/b43legacy/pio.c | |||
@@ -491,6 +491,7 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev, | |||
491 | struct b43legacy_pioqueue *queue; | 491 | struct b43legacy_pioqueue *queue; |
492 | struct b43legacy_pio_txpacket *packet; | 492 | struct b43legacy_pio_txpacket *packet; |
493 | struct ieee80211_tx_info *info; | 493 | struct ieee80211_tx_info *info; |
494 | int retry_limit; | ||
494 | 495 | ||
495 | queue = parse_cookie(dev, status->cookie, &packet); | 496 | queue = parse_cookie(dev, status->cookie, &packet); |
496 | B43legacy_WARN_ON(!queue); | 497 | B43legacy_WARN_ON(!queue); |
@@ -503,11 +504,37 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev, | |||
503 | sizeof(struct b43legacy_txhdr_fw3)); | 504 | sizeof(struct b43legacy_txhdr_fw3)); |
504 | 505 | ||
505 | info = IEEE80211_SKB_CB(packet->skb); | 506 | info = IEEE80211_SKB_CB(packet->skb); |
506 | memset(&info->status, 0, sizeof(info->status)); | 507 | |
508 | /* preserve the confiured retry limit before clearing the status | ||
509 | * The xmit function has overwritten the rc's value with the actual | ||
510 | * retry limit done by the hardware */ | ||
511 | retry_limit = info->status.rates[0].count; | ||
512 | ieee80211_tx_info_clear_status(info); | ||
507 | 513 | ||
508 | if (status->acked) | 514 | if (status->acked) |
509 | info->flags |= IEEE80211_TX_STAT_ACK; | 515 | info->flags |= IEEE80211_TX_STAT_ACK; |
510 | info->status.retry_count = status->frame_count - 1; | 516 | |
517 | if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) { | ||
518 | /* | ||
519 | * If the short retries (RTS, not data frame) have exceeded | ||
520 | * the limit, the hw will not have tried the selected rate, | ||
521 | * but will have used the fallback rate instead. | ||
522 | * Don't let the rate control count attempts for the selected | ||
523 | * rate in this case, otherwise the statistics will be off. | ||
524 | */ | ||
525 | info->status.rates[0].count = 0; | ||
526 | info->status.rates[1].count = status->frame_count; | ||
527 | } else { | ||
528 | if (status->frame_count > retry_limit) { | ||
529 | info->status.rates[0].count = retry_limit; | ||
530 | info->status.rates[1].count = status->frame_count - | ||
531 | retry_limit; | ||
532 | |||
533 | } else { | ||
534 | info->status.rates[0].count = status->frame_count; | ||
535 | info->status.rates[1].idx = -1; | ||
536 | } | ||
537 | } | ||
511 | ieee80211_tx_status_irqsafe(dev->wl->hw, packet->skb); | 538 | ieee80211_tx_status_irqsafe(dev->wl->hw, packet->skb); |
512 | packet->skb = NULL; | 539 | packet->skb = NULL; |
513 | 540 | ||
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index 65e833781608..12fca99f7578 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
@@ -188,7 +188,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
188 | struct b43legacy_txhdr_fw3 *txhdr, | 188 | struct b43legacy_txhdr_fw3 *txhdr, |
189 | const unsigned char *fragment_data, | 189 | const unsigned char *fragment_data, |
190 | unsigned int fragment_len, | 190 | unsigned int fragment_len, |
191 | const struct ieee80211_tx_info *info, | 191 | struct ieee80211_tx_info *info, |
192 | u16 cookie) | 192 | u16 cookie) |
193 | { | 193 | { |
194 | const struct ieee80211_hdr *wlhdr; | 194 | const struct ieee80211_hdr *wlhdr; |
@@ -201,6 +201,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
201 | u32 mac_ctl = 0; | 201 | u32 mac_ctl = 0; |
202 | u16 phy_ctl = 0; | 202 | u16 phy_ctl = 0; |
203 | struct ieee80211_rate *tx_rate; | 203 | struct ieee80211_rate *tx_rate; |
204 | struct ieee80211_tx_rate *rates; | ||
204 | 205 | ||
205 | wlhdr = (const struct ieee80211_hdr *)fragment_data; | 206 | wlhdr = (const struct ieee80211_hdr *)fragment_data; |
206 | 207 | ||
@@ -274,7 +275,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
274 | /* PHY TX Control word */ | 275 | /* PHY TX Control word */ |
275 | if (rate_ofdm) | 276 | if (rate_ofdm) |
276 | phy_ctl |= B43legacy_TX4_PHY_OFDM; | 277 | phy_ctl |= B43legacy_TX4_PHY_OFDM; |
277 | if (dev->short_preamble) | 278 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) |
278 | phy_ctl |= B43legacy_TX4_PHY_SHORTPRMBL; | 279 | phy_ctl |= B43legacy_TX4_PHY_SHORTPRMBL; |
279 | switch (info->antenna_sel_tx) { | 280 | switch (info->antenna_sel_tx) { |
280 | case 0: | 281 | case 0: |
@@ -291,6 +292,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
291 | } | 292 | } |
292 | 293 | ||
293 | /* MAC control */ | 294 | /* MAC control */ |
295 | rates = info->control.rates; | ||
294 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | 296 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) |
295 | mac_ctl |= B43legacy_TX4_MAC_ACK; | 297 | mac_ctl |= B43legacy_TX4_MAC_ACK; |
296 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) | 298 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) |
@@ -299,12 +301,22 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
299 | mac_ctl |= B43legacy_TX4_MAC_STMSDU; | 301 | mac_ctl |= B43legacy_TX4_MAC_STMSDU; |
300 | if (rate_fb_ofdm) | 302 | if (rate_fb_ofdm) |
301 | mac_ctl |= B43legacy_TX4_MAC_FALLBACKOFDM; | 303 | mac_ctl |= B43legacy_TX4_MAC_FALLBACKOFDM; |
302 | if (info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT) | 304 | |
305 | /* Overwrite rates[0].count to make the retry calculation | ||
306 | * in the tx status easier. need the actual retry limit to | ||
307 | * detect whether the fallback rate was used. | ||
308 | */ | ||
309 | if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || | ||
310 | (rates[0].count <= dev->wl->hw->conf.long_frame_max_tx_count)) { | ||
311 | rates[0].count = dev->wl->hw->conf.long_frame_max_tx_count; | ||
303 | mac_ctl |= B43legacy_TX4_MAC_LONGFRAME; | 312 | mac_ctl |= B43legacy_TX4_MAC_LONGFRAME; |
313 | } else { | ||
314 | rates[0].count = dev->wl->hw->conf.short_frame_max_tx_count; | ||
315 | } | ||
304 | 316 | ||
305 | /* Generate the RTS or CTS-to-self frame */ | 317 | /* Generate the RTS or CTS-to-self frame */ |
306 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | 318 | if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || |
307 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) { | 319 | (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) { |
308 | unsigned int len; | 320 | unsigned int len; |
309 | struct ieee80211_hdr *hdr; | 321 | struct ieee80211_hdr *hdr; |
310 | int rts_rate; | 322 | int rts_rate; |
@@ -319,7 +331,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
319 | if (rts_rate_fb_ofdm) | 331 | if (rts_rate_fb_ofdm) |
320 | mac_ctl |= B43legacy_TX4_MAC_CTSFALLBACKOFDM; | 332 | mac_ctl |= B43legacy_TX4_MAC_CTSFALLBACKOFDM; |
321 | 333 | ||
322 | if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { | 334 | if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { |
323 | ieee80211_ctstoself_get(dev->wl->hw, | 335 | ieee80211_ctstoself_get(dev->wl->hw, |
324 | info->control.vif, | 336 | info->control.vif, |
325 | fragment_data, | 337 | fragment_data, |
@@ -362,7 +374,7 @@ int b43legacy_generate_txhdr(struct b43legacy_wldev *dev, | |||
362 | u8 *txhdr, | 374 | u8 *txhdr, |
363 | const unsigned char *fragment_data, | 375 | const unsigned char *fragment_data, |
364 | unsigned int fragment_len, | 376 | unsigned int fragment_len, |
365 | const struct ieee80211_tx_info *info, | 377 | struct ieee80211_tx_info *info, |
366 | u16 cookie) | 378 | u16 cookie) |
367 | { | 379 | { |
368 | return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr, | 380 | return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr, |
diff --git a/drivers/net/wireless/b43legacy/xmit.h b/drivers/net/wireless/b43legacy/xmit.h index e56777e0feab..62e09d02788f 100644 --- a/drivers/net/wireless/b43legacy/xmit.h +++ b/drivers/net/wireless/b43legacy/xmit.h | |||
@@ -80,7 +80,7 @@ int b43legacy_generate_txhdr(struct b43legacy_wldev *dev, | |||
80 | u8 *txhdr, | 80 | u8 *txhdr, |
81 | const unsigned char *fragment_data, | 81 | const unsigned char *fragment_data, |
82 | unsigned int fragment_len, | 82 | unsigned int fragment_len, |
83 | const struct ieee80211_tx_info *info, | 83 | struct ieee80211_tx_info *info, |
84 | u16 cookie); | 84 | u16 cookie); |
85 | 85 | ||
86 | 86 | ||