aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtl818x
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-02-03 15:41:58 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-03 15:41:58 -0500
commit1725d409caba16ea5fc694bd50e95e79e8ced11a (patch)
tree688fe26dd4ceda5364692f0ce307aadb6f04f331 /drivers/net/wireless/rtl818x
parentb3ff29d2ccfe3af065a9b393699a8fbf2abd1b15 (diff)
parentb8abde45d7d6ab9e8ceced9b5990eeb1149d0b97 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/rtl818x')
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187.h4
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c86
2 files changed, 66 insertions, 24 deletions
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h
index 3b1e1c2aad26..9718f61809cf 100644
--- a/drivers/net/wireless/rtl818x/rtl8187.h
+++ b/drivers/net/wireless/rtl818x/rtl8187.h
@@ -100,6 +100,8 @@ struct rtl8187_priv {
100 struct usb_device *udev; 100 struct usb_device *udev;
101 u32 rx_conf; 101 u32 rx_conf;
102 struct usb_anchor anchored; 102 struct usb_anchor anchored;
103 struct delayed_work work;
104 struct ieee80211_hw *dev;
103 u16 txpwr_base; 105 u16 txpwr_base;
104 u8 asic_rev; 106 u8 asic_rev;
105 u8 is_rtl8187b; 107 u8 is_rtl8187b;
@@ -117,7 +119,7 @@ struct rtl8187_priv {
117 struct { 119 struct {
118 __le64 buf; 120 __le64 buf;
119 struct sk_buff_head queue; 121 struct sk_buff_head queue;
120 } b_tx_status; 122 } b_tx_status; /* This queue is used by both -b and non-b devices */
121}; 123};
122 124
123void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); 125void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 22bc07ef2f37..82bd47e7c617 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -177,25 +177,33 @@ static void rtl8187_tx_cb(struct urb *urb)
177 sizeof(struct rtl8187_tx_hdr)); 177 sizeof(struct rtl8187_tx_hdr));
178 ieee80211_tx_info_clear_status(info); 178 ieee80211_tx_info_clear_status(info);
179 179
180 if (!urb->status && 180 if (!(urb->status) && !(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
181 !(info->flags & IEEE80211_TX_CTL_NO_ACK) && 181 if (priv->is_rtl8187b) {
182 priv->is_rtl8187b) { 182 skb_queue_tail(&priv->b_tx_status.queue, skb);
183 skb_queue_tail(&priv->b_tx_status.queue, skb);
184 183
185 /* queue is "full", discard last items */ 184 /* queue is "full", discard last items */
186 while (skb_queue_len(&priv->b_tx_status.queue) > 5) { 185 while (skb_queue_len(&priv->b_tx_status.queue) > 5) {
187 struct sk_buff *old_skb; 186 struct sk_buff *old_skb;
188 187
189 dev_dbg(&priv->udev->dev, 188 dev_dbg(&priv->udev->dev,
190 "transmit status queue full\n"); 189 "transmit status queue full\n");
191 190
192 old_skb = skb_dequeue(&priv->b_tx_status.queue); 191 old_skb = skb_dequeue(&priv->b_tx_status.queue);
193 ieee80211_tx_status_irqsafe(hw, old_skb); 192 ieee80211_tx_status_irqsafe(hw, old_skb);
194 } 193 }
195 } else { 194 return;
196 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && !urb->status) 195 } else {
197 info->flags |= IEEE80211_TX_STAT_ACK; 196 info->flags |= IEEE80211_TX_STAT_ACK;
197 }
198 }
199 if (priv->is_rtl8187b)
198 ieee80211_tx_status_irqsafe(hw, skb); 200 ieee80211_tx_status_irqsafe(hw, skb);
201 else {
202 /* Retry information for the RTI8187 is only available by
203 * reading a register in the device. We are in interrupt mode
204 * here, thus queue the skb and finish on a work queue. */
205 skb_queue_tail(&priv->b_tx_status.queue, skb);
206 queue_delayed_work(hw->workqueue, &priv->work, 0);
199 } 207 }
200} 208}
201 209
@@ -391,7 +399,7 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
391 struct rtl8187_rx_info *info; 399 struct rtl8187_rx_info *info;
392 int ret = 0; 400 int ret = 0;
393 401
394 while (skb_queue_len(&priv->rx_queue) < 8) { 402 while (skb_queue_len(&priv->rx_queue) < 16) {
395 skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL); 403 skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL);
396 if (!skb) { 404 if (!skb) {
397 ret = -ENOMEM; 405 ret = -ENOMEM;
@@ -645,7 +653,7 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
645 653
646 rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); 654 rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
647 rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); 655 rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
648 rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81); 656 rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0);
649 657
650 // TODO: set RESP_RATE and BRSR properly 658 // TODO: set RESP_RATE and BRSR properly
651 rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0); 659 rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0);
@@ -765,9 +773,6 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
765 rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); 773 rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
766 774
767 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1); 775 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1);
768 reg = rtl818x_ioread8(priv, &priv->map->RATE_FALLBACK);
769 reg |= RTL818X_RATE_FALLBACK_ENABLE;
770 rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, reg);
771 776
772 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100); 777 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
773 rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2); 778 rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
@@ -855,6 +860,34 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
855 return 0; 860 return 0;
856} 861}
857 862
863static void rtl8187_work(struct work_struct *work)
864{
865 /* The RTL8187 returns the retry count through register 0xFFFA. In
866 * addition, it appears to be a cumulative retry count, not the
867 * value for the current TX packet. When multiple TX entries are
868 * queued, the retry count will be valid for the last one in the queue.
869 * The "error" should not matter for purposes of rate setting. */
870 struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
871 work.work);
872 struct ieee80211_tx_info *info;
873 struct ieee80211_hw *dev = priv->dev;
874 static u16 retry;
875 u16 tmp;
876
877 mutex_lock(&priv->conf_mutex);
878 tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA);
879 while (skb_queue_len(&priv->b_tx_status.queue) > 0) {
880 struct sk_buff *old_skb;
881
882 old_skb = skb_dequeue(&priv->b_tx_status.queue);
883 info = IEEE80211_SKB_CB(old_skb);
884 info->status.rates[0].count = tmp - retry + 1;
885 ieee80211_tx_status_irqsafe(dev, old_skb);
886 }
887 retry = tmp;
888 mutex_unlock(&priv->conf_mutex);
889}
890
858static int rtl8187_start(struct ieee80211_hw *dev) 891static int rtl8187_start(struct ieee80211_hw *dev)
859{ 892{
860 struct rtl8187_priv *priv = dev->priv; 893 struct rtl8187_priv *priv = dev->priv;
@@ -869,6 +902,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
869 mutex_lock(&priv->conf_mutex); 902 mutex_lock(&priv->conf_mutex);
870 903
871 init_usb_anchor(&priv->anchored); 904 init_usb_anchor(&priv->anchored);
905 priv->dev = dev;
872 906
873 if (priv->is_rtl8187b) { 907 if (priv->is_rtl8187b) {
874 reg = RTL818X_RX_CONF_MGMT | 908 reg = RTL818X_RX_CONF_MGMT |
@@ -936,6 +970,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
936 reg |= RTL818X_CMD_TX_ENABLE; 970 reg |= RTL818X_CMD_TX_ENABLE;
937 reg |= RTL818X_CMD_RX_ENABLE; 971 reg |= RTL818X_CMD_RX_ENABLE;
938 rtl818x_iowrite8(priv, &priv->map->CMD, reg); 972 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
973 INIT_DELAYED_WORK(&priv->work, rtl8187_work);
939 mutex_unlock(&priv->conf_mutex); 974 mutex_unlock(&priv->conf_mutex);
940 975
941 return 0; 976 return 0;
@@ -966,6 +1001,8 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
966 dev_kfree_skb_any(skb); 1001 dev_kfree_skb_any(skb);
967 1002
968 usb_kill_anchored_urbs(&priv->anchored); 1003 usb_kill_anchored_urbs(&priv->anchored);
1004 if (!priv->is_rtl8187b)
1005 cancel_delayed_work_sync(&priv->work);
969 mutex_unlock(&priv->conf_mutex); 1006 mutex_unlock(&priv->conf_mutex);
970} 1007}
971 1008
@@ -974,19 +1011,21 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
974{ 1011{
975 struct rtl8187_priv *priv = dev->priv; 1012 struct rtl8187_priv *priv = dev->priv;
976 int i; 1013 int i;
1014 int ret = -EOPNOTSUPP;
977 1015
1016 mutex_lock(&priv->conf_mutex);
978 if (priv->mode != NL80211_IFTYPE_MONITOR) 1017 if (priv->mode != NL80211_IFTYPE_MONITOR)
979 return -EOPNOTSUPP; 1018 goto exit;
980 1019
981 switch (conf->type) { 1020 switch (conf->type) {
982 case NL80211_IFTYPE_STATION: 1021 case NL80211_IFTYPE_STATION:
983 priv->mode = conf->type; 1022 priv->mode = conf->type;
984 break; 1023 break;
985 default: 1024 default:
986 return -EOPNOTSUPP; 1025 goto exit;
987 } 1026 }
988 1027
989 mutex_lock(&priv->conf_mutex); 1028 ret = 0;
990 priv->vif = conf->vif; 1029 priv->vif = conf->vif;
991 1030
992 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 1031 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
@@ -995,8 +1034,9 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
995 ((u8 *)conf->mac_addr)[i]); 1034 ((u8 *)conf->mac_addr)[i]);
996 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 1035 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
997 1036
1037exit:
998 mutex_unlock(&priv->conf_mutex); 1038 mutex_unlock(&priv->conf_mutex);
999 return 0; 1039 return ret;
1000} 1040}
1001 1041
1002static void rtl8187_remove_interface(struct ieee80211_hw *dev, 1042static void rtl8187_remove_interface(struct ieee80211_hw *dev,