rtl8187: Change rate-control feedback
The driver for the RTL8187L chips returns IEEE80211_TX_STAT_ACK for all packets, even if the maximum number of retries was exhausted. In addition it fails to setup max_rates in the ieee80211_hw struct, This behavior may be responsible for the problems noted in Bug 14168. As the bug is very old, testers have not been found, and I do not have the case where the indicated signal is less than -70 dBm. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Acked-by: Hin-Tak Leung <htl10@users.sourceforge.net> Cc: Stable <stable@kernel.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
1ffe4dd126
commit
6410db593e
|
@ -869,23 +869,35 @@ static void rtl8187_work(struct work_struct *work)
|
||||||
/* The RTL8187 returns the retry count through register 0xFFFA. In
|
/* The RTL8187 returns the retry count through register 0xFFFA. In
|
||||||
* addition, it appears to be a cumulative retry count, not the
|
* addition, it appears to be a cumulative retry count, not the
|
||||||
* value for the current TX packet. When multiple TX entries are
|
* value for the current TX packet. When multiple TX entries are
|
||||||
* queued, the retry count will be valid for the last one in the queue.
|
* waiting in the queue, the retry count will be the total for all.
|
||||||
* The "error" should not matter for purposes of rate setting. */
|
* The "error" may matter for purposes of rate setting, but there is
|
||||||
|
* no other choice with this hardware.
|
||||||
|
*/
|
||||||
struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
|
struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
|
||||||
work.work);
|
work.work);
|
||||||
struct ieee80211_tx_info *info;
|
struct ieee80211_tx_info *info;
|
||||||
struct ieee80211_hw *dev = priv->dev;
|
struct ieee80211_hw *dev = priv->dev;
|
||||||
static u16 retry;
|
static u16 retry;
|
||||||
u16 tmp;
|
u16 tmp;
|
||||||
|
u16 avg_retry;
|
||||||
|
int length;
|
||||||
|
|
||||||
mutex_lock(&priv->conf_mutex);
|
mutex_lock(&priv->conf_mutex);
|
||||||
tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA);
|
tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA);
|
||||||
|
length = skb_queue_len(&priv->b_tx_status.queue);
|
||||||
|
if (unlikely(!length))
|
||||||
|
length = 1;
|
||||||
|
if (unlikely(tmp < retry))
|
||||||
|
tmp = retry;
|
||||||
|
avg_retry = (tmp - retry) / length;
|
||||||
while (skb_queue_len(&priv->b_tx_status.queue) > 0) {
|
while (skb_queue_len(&priv->b_tx_status.queue) > 0) {
|
||||||
struct sk_buff *old_skb;
|
struct sk_buff *old_skb;
|
||||||
|
|
||||||
old_skb = skb_dequeue(&priv->b_tx_status.queue);
|
old_skb = skb_dequeue(&priv->b_tx_status.queue);
|
||||||
info = IEEE80211_SKB_CB(old_skb);
|
info = IEEE80211_SKB_CB(old_skb);
|
||||||
info->status.rates[0].count = tmp - retry + 1;
|
info->status.rates[0].count = avg_retry + 1;
|
||||||
|
if (info->status.rates[0].count > RETRY_COUNT)
|
||||||
|
info->flags &= ~IEEE80211_TX_STAT_ACK;
|
||||||
ieee80211_tx_status_irqsafe(dev, old_skb);
|
ieee80211_tx_status_irqsafe(dev, old_skb);
|
||||||
}
|
}
|
||||||
retry = tmp;
|
retry = tmp;
|
||||||
|
@ -931,8 +943,8 @@ static int rtl8187_start(struct ieee80211_hw *dev)
|
||||||
rtl818x_iowrite32(priv, &priv->map->TX_CONF,
|
rtl818x_iowrite32(priv, &priv->map->TX_CONF,
|
||||||
RTL818X_TX_CONF_HW_SEQNUM |
|
RTL818X_TX_CONF_HW_SEQNUM |
|
||||||
RTL818X_TX_CONF_DISREQQSIZE |
|
RTL818X_TX_CONF_DISREQQSIZE |
|
||||||
(7 << 8 /* short retry limit */) |
|
(RETRY_COUNT << 8 /* short retry limit */) |
|
||||||
(7 << 0 /* long retry limit */) |
|
(RETRY_COUNT << 0 /* long retry limit */) |
|
||||||
(7 << 21 /* MAX TX DMA */));
|
(7 << 21 /* MAX TX DMA */));
|
||||||
rtl8187_init_urbs(dev);
|
rtl8187_init_urbs(dev);
|
||||||
rtl8187b_init_status_urb(dev);
|
rtl8187b_init_status_urb(dev);
|
||||||
|
@ -1376,6 +1388,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
|
||||||
dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
|
dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
|
||||||
IEEE80211_HW_SIGNAL_DBM |
|
IEEE80211_HW_SIGNAL_DBM |
|
||||||
IEEE80211_HW_RX_INCLUDES_FCS;
|
IEEE80211_HW_RX_INCLUDES_FCS;
|
||||||
|
/* Initialize rate-control variables */
|
||||||
|
dev->max_rates = 1;
|
||||||
|
dev->max_rate_tries = RETRY_COUNT;
|
||||||
|
|
||||||
eeprom.data = dev;
|
eeprom.data = dev;
|
||||||
eeprom.register_read = rtl8187_eeprom_register_read;
|
eeprom.register_read = rtl8187_eeprom_register_read;
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#define RFKILL_MASK_8187_89_97 0x2
|
#define RFKILL_MASK_8187_89_97 0x2
|
||||||
#define RFKILL_MASK_8198 0x4
|
#define RFKILL_MASK_8198 0x4
|
||||||
|
|
||||||
|
#define RETRY_COUNT 7
|
||||||
|
|
||||||
struct rtl8187_rx_info {
|
struct rtl8187_rx_info {
|
||||||
struct urb *urb;
|
struct urb *urb;
|
||||||
struct ieee80211_hw *dev;
|
struct ieee80211_hw *dev;
|
||||||
|
|
Reference in New Issue