Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 134238
b: refs/heads/master
c: 2f47690
h: refs/heads/master
v: v3
  • Loading branch information
Larry Finger authored and John W. Linville committed Jan 29, 2009
1 parent 194ea03 commit ebf4d20
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 20 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2a57cf3e83f89150f2ac9b6f01caf3fcdbb36486
refs/heads/master: 2f47690ed42a85820783dee7f16ae47edadf8fad
4 changes: 3 additions & 1 deletion trunk/drivers/net/wireless/rtl818x/rtl8187.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ struct rtl8187_priv {
struct usb_device *udev;
u32 rx_conf;
struct usb_anchor anchored;
struct delayed_work work;
struct ieee80211_hw *dev;
u16 txpwr_base;
u8 asic_rev;
u8 is_rtl8187b;
Expand All @@ -117,7 +119,7 @@ struct rtl8187_priv {
struct {
__le64 buf;
struct sk_buff_head queue;
} b_tx_status;
} b_tx_status; /* This queue is used by both -b and non-b devices */
};

void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
Expand Down
73 changes: 55 additions & 18 deletions trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,25 +177,33 @@ static void rtl8187_tx_cb(struct urb *urb)
sizeof(struct rtl8187_tx_hdr));
ieee80211_tx_info_clear_status(info);

if (!urb->status &&
!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
priv->is_rtl8187b) {
skb_queue_tail(&priv->b_tx_status.queue, skb);
if (!(urb->status) && !(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
if (priv->is_rtl8187b) {
skb_queue_tail(&priv->b_tx_status.queue, skb);

/* queue is "full", discard last items */
while (skb_queue_len(&priv->b_tx_status.queue) > 5) {
struct sk_buff *old_skb;
/* queue is "full", discard last items */
while (skb_queue_len(&priv->b_tx_status.queue) > 5) {
struct sk_buff *old_skb;

dev_dbg(&priv->udev->dev,
"transmit status queue full\n");
dev_dbg(&priv->udev->dev,
"transmit status queue full\n");

old_skb = skb_dequeue(&priv->b_tx_status.queue);
ieee80211_tx_status_irqsafe(hw, old_skb);
}
} else {
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && !urb->status)
old_skb = skb_dequeue(&priv->b_tx_status.queue);
ieee80211_tx_status_irqsafe(hw, old_skb);
}
return;
} else {
info->flags |= IEEE80211_TX_STAT_ACK;
}
}
if (priv->is_rtl8187b)
ieee80211_tx_status_irqsafe(hw, skb);
else {
/* Retry information for the RTI8187 is only available by
* reading a register in the device. We are in interrupt mode
* here, thus queue the skb and finish on a work queue. */
skb_queue_tail(&priv->b_tx_status.queue, skb);
queue_delayed_work(hw->workqueue, &priv->work, 0);
}
}

Expand Down Expand Up @@ -645,7 +653,7 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)

rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81);
rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0);

// TODO: set RESP_RATE and BRSR properly
rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0);
Expand Down Expand Up @@ -765,9 +773,6 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);

rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1);
reg = rtl818x_ioread8(priv, &priv->map->RATE_FALLBACK);
reg |= RTL818X_RATE_FALLBACK_ENABLE;
rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, reg);

rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
Expand Down Expand Up @@ -855,6 +860,34 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
return 0;
}

static void rtl8187_work(struct work_struct *work)
{
/* The RTL8187 returns the retry count through register 0xFFFA. In
* addition, it appears to be a cumulative retry count, not the
* 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.
* The "error" should not matter for purposes of rate setting. */
struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
work.work);
struct ieee80211_tx_info *info;
struct ieee80211_hw *dev = priv->dev;
static u16 retry;
u16 tmp;

mutex_lock(&priv->conf_mutex);
tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA);
while (skb_queue_len(&priv->b_tx_status.queue) > 0) {
struct sk_buff *old_skb;

old_skb = skb_dequeue(&priv->b_tx_status.queue);
info = IEEE80211_SKB_CB(old_skb);
info->status.rates[0].count = tmp - retry + 1;
ieee80211_tx_status_irqsafe(dev, old_skb);
}
retry = tmp;
mutex_unlock(&priv->conf_mutex);
}

static int rtl8187_start(struct ieee80211_hw *dev)
{
struct rtl8187_priv *priv = dev->priv;
Expand All @@ -869,6 +902,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
mutex_lock(&priv->conf_mutex);

init_usb_anchor(&priv->anchored);
priv->dev = dev;

if (priv->is_rtl8187b) {
reg = RTL818X_RX_CONF_MGMT |
Expand Down Expand Up @@ -936,6 +970,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
reg |= RTL818X_CMD_TX_ENABLE;
reg |= RTL818X_CMD_RX_ENABLE;
rtl818x_iowrite8(priv, &priv->map->CMD, reg);
INIT_DELAYED_WORK(&priv->work, rtl8187_work);
mutex_unlock(&priv->conf_mutex);

return 0;
Expand Down Expand Up @@ -966,6 +1001,8 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
dev_kfree_skb_any(skb);

usb_kill_anchored_urbs(&priv->anchored);
if (!priv->is_rtl8187b)
cancel_delayed_work_sync(&priv->work);
mutex_unlock(&priv->conf_mutex);
}

Expand Down

0 comments on commit ebf4d20

Please sign in to comment.