diff options
Diffstat (limited to 'drivers/net/wireless/b43legacy/dma.c')
-rw-r--r-- | drivers/net/wireless/b43legacy/dma.c | 46 |
1 files changed, 32 insertions, 14 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; |