aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtl8187_dev.c
diff options
context:
space:
mode:
authorHin-Tak Leung <hintak.leung@gmail.com>2008-07-08 07:36:04 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-07-08 14:16:07 -0400
commit6f7853f3cbe457067e9fe05461f56c7ea4ac488c (patch)
tree3edd16656fe0bc9614d24bd7c88f1c55f05e5772 /drivers/net/wireless/rtl8187_dev.c
parentf8a08c34265b59710a8fc049911f487477c19fab (diff)
rtl8187: change rtl8187_dev.c to support RTL8187B (part 2)
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br> Signed-off-by: Hin-Tak Leung <htl10@users.sourceforge.net> Signed-off-by: Pavel Roskin <proski@gnu.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtl8187_dev.c')
-rw-r--r--drivers/net/wireless/rtl8187_dev.c208
1 files changed, 168 insertions, 40 deletions
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index b17f237c9e28..3bc4a1c39258 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -155,9 +155,11 @@ static void rtl8187_tx_cb(struct urb *urb)
155 struct sk_buff *skb = (struct sk_buff *)urb->context; 155 struct sk_buff *skb = (struct sk_buff *)urb->context;
156 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 156 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
157 struct ieee80211_hw *hw = info->driver_data[0]; 157 struct ieee80211_hw *hw = info->driver_data[0];
158 struct rtl8187_priv *priv = hw->priv;
158 159
159 usb_free_urb(info->driver_data[1]); 160 usb_free_urb(info->driver_data[1]);
160 skb_pull(skb, sizeof(struct rtl8187_tx_hdr)); 161 skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) :
162 sizeof(struct rtl8187_tx_hdr));
161 memset(&info->status, 0, sizeof(info->status)); 163 memset(&info->status, 0, sizeof(info->status));
162 info->flags |= IEEE80211_TX_STAT_ACK; 164 info->flags |= IEEE80211_TX_STAT_ACK;
163 ieee80211_tx_status_irqsafe(hw, skb); 165 ieee80211_tx_status_irqsafe(hw, skb);
@@ -167,7 +169,8 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
167{ 169{
168 struct rtl8187_priv *priv = dev->priv; 170 struct rtl8187_priv *priv = dev->priv;
169 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 171 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
170 struct rtl8187_tx_hdr *hdr; 172 unsigned int ep;
173 void *buf;
171 struct urb *urb; 174 struct urb *urb;
172 __le16 rts_dur = 0; 175 __le16 rts_dur = 0;
173 u32 flags; 176 u32 flags;
@@ -195,16 +198,47 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
195 flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; 198 flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
196 } 199 }
197 200
198 hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); 201 if (!priv->is_rtl8187b) {
199 hdr->flags = cpu_to_le32(flags); 202 struct rtl8187_tx_hdr *hdr =
200 hdr->len = 0; 203 (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
201 hdr->rts_duration = rts_dur; 204 hdr->flags = cpu_to_le32(flags);
202 hdr->retry = cpu_to_le32(info->control.retry_limit << 8); 205 hdr->len = 0;
206 hdr->rts_duration = rts_dur;
207 hdr->retry = cpu_to_le32(info->control.retry_limit << 8);
208 buf = hdr;
209
210 ep = 2;
211 } else {
212 /* fc needs to be calculated before skb_push() */
213 unsigned int epmap[4] = { 6, 7, 5, 4 };
214 struct ieee80211_hdr *tx_hdr =
215 (struct ieee80211_hdr *)(skb->data);
216 u16 fc = le16_to_cpu(tx_hdr->frame_control);
217
218 struct rtl8187b_tx_hdr *hdr =
219 (struct rtl8187b_tx_hdr *)skb_push(skb, sizeof(*hdr));
220 struct ieee80211_rate *txrate =
221 ieee80211_get_tx_rate(dev, info);
222 memset(hdr, 0, sizeof(*hdr));
223 hdr->flags = cpu_to_le32(flags);
224 hdr->rts_duration = rts_dur;
225 hdr->retry = cpu_to_le32(info->control.retry_limit << 8);
226 hdr->tx_duration =
227 ieee80211_generic_frame_duration(dev, priv->vif,
228 skb->len, txrate);
229 buf = hdr;
230
231 if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
232 ep = 12;
233 else
234 ep = epmap[skb_get_queue_mapping(skb)];
235 }
203 236
204 info->driver_data[0] = dev; 237 info->driver_data[0] = dev;
205 info->driver_data[1] = urb; 238 info->driver_data[1] = urb;
206 usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, 2), 239
207 hdr, skb->len, rtl8187_tx_cb, skb); 240 usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep),
241 buf, skb->len, rtl8187_tx_cb, skb);
208 rc = usb_submit_urb(urb, GFP_ATOMIC); 242 rc = usb_submit_urb(urb, GFP_ATOMIC);
209 if (rc < 0) { 243 if (rc < 0) {
210 usb_free_urb(urb); 244 usb_free_urb(urb);
@@ -220,7 +254,6 @@ static void rtl8187_rx_cb(struct urb *urb)
220 struct rtl8187_rx_info *info = (struct rtl8187_rx_info *)skb->cb; 254 struct rtl8187_rx_info *info = (struct rtl8187_rx_info *)skb->cb;
221 struct ieee80211_hw *dev = info->dev; 255 struct ieee80211_hw *dev = info->dev;
222 struct rtl8187_priv *priv = dev->priv; 256 struct rtl8187_priv *priv = dev->priv;
223 struct rtl8187_rx_hdr *hdr;
224 struct ieee80211_rx_status rx_status = { 0 }; 257 struct ieee80211_rx_status rx_status = { 0 };
225 int rate, signal; 258 int rate, signal;
226 u32 flags; 259 u32 flags;
@@ -241,11 +274,33 @@ static void rtl8187_rx_cb(struct urb *urb)
241 } 274 }
242 275
243 skb_put(skb, urb->actual_length); 276 skb_put(skb, urb->actual_length);
244 hdr = (struct rtl8187_rx_hdr *)(skb_tail_pointer(skb) - sizeof(*hdr)); 277 if (!priv->is_rtl8187b) {
245 flags = le32_to_cpu(hdr->flags); 278 struct rtl8187_rx_hdr *hdr =
246 skb_trim(skb, flags & 0x0FFF); 279 (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
280 flags = le32_to_cpu(hdr->flags);
281 signal = hdr->signal & 0x7f;
282 rx_status.antenna = (hdr->signal >> 7) & 1;
283 rx_status.signal = signal;
284 rx_status.noise = hdr->noise;
285 rx_status.mactime = le64_to_cpu(hdr->mac_time);
286 priv->signal = signal;
287 priv->quality = signal;
288 priv->noise = hdr->noise;
289 } else {
290 struct rtl8187b_rx_hdr *hdr =
291 (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
292 flags = le32_to_cpu(hdr->flags);
293 signal = hdr->agc >> 1;
294 rx_status.antenna = (hdr->signal >> 7) & 1;
295 rx_status.signal = 64 - min(hdr->noise, (u8)64);
296 rx_status.noise = hdr->noise;
297 rx_status.mactime = le64_to_cpu(hdr->mac_time);
298 priv->signal = hdr->signal;
299 priv->quality = hdr->agc >> 1;
300 priv->noise = hdr->noise;
301 }
247 302
248 signal = hdr->agc >> 1; 303 skb_trim(skb, flags & 0x0FFF);
249 rate = (flags >> 20) & 0xF; 304 rate = (flags >> 20) & 0xF;
250 if (rate > 3) { /* OFDM rate */ 305 if (rate > 3) { /* OFDM rate */
251 if (signal > 90) 306 if (signal > 90)
@@ -261,13 +316,11 @@ static void rtl8187_rx_cb(struct urb *urb)
261 signal = 95 - signal; 316 signal = 95 - signal;
262 } 317 }
263 318
264 rx_status.antenna = (hdr->signal >> 7) & 1; 319 rx_status.qual = priv->quality;
265 rx_status.qual = 64 - min(hdr->noise, (u8)64);
266 rx_status.signal = signal; 320 rx_status.signal = signal;
267 rx_status.rate_idx = rate; 321 rx_status.rate_idx = rate;
268 rx_status.freq = dev->conf.channel->center_freq; 322 rx_status.freq = dev->conf.channel->center_freq;
269 rx_status.band = dev->conf.channel->band; 323 rx_status.band = dev->conf.channel->band;
270 rx_status.mactime = le64_to_cpu(hdr->mac_time);
271 rx_status.flag |= RX_FLAG_TSFT; 324 rx_status.flag |= RX_FLAG_TSFT;
272 if (flags & (1 << 13)) 325 if (flags & (1 << 13))
273 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; 326 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
@@ -307,7 +360,8 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
307 break; 360 break;
308 } 361 }
309 usb_fill_bulk_urb(entry, priv->udev, 362 usb_fill_bulk_urb(entry, priv->udev,
310 usb_rcvbulkpipe(priv->udev, 1), 363 usb_rcvbulkpipe(priv->udev,
364 priv->is_rtl8187b ? 3 : 1),
311 skb_tail_pointer(skb), 365 skb_tail_pointer(skb),
312 RTL8187_MAX_RX, rtl8187_rx_cb, skb); 366 RTL8187_MAX_RX, rtl8187_rx_cb, skb);
313 info = (struct rtl8187_rx_info *)skb->cb; 367 info = (struct rtl8187_rx_info *)skb->cb;
@@ -786,18 +840,20 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
786 msleep(10); 840 msleep(10);
787 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); 841 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
788 842
789 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); 843 if (!priv->is_rtl8187b) {
790 844 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
791 if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) { 845
792 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9); 846 if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
793 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14); 847 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
794 rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14); 848 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
795 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73); 849 rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14);
796 } else { 850 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
797 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14); 851 } else {
798 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24); 852 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
799 rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24); 853 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
800 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5); 854 rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24);
855 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
856 }
801 } 857 }
802 858
803 rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2); 859 rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
@@ -813,14 +869,20 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev,
813{ 869{
814 struct rtl8187_priv *priv = dev->priv; 870 struct rtl8187_priv *priv = dev->priv;
815 int i; 871 int i;
872 u8 reg;
816 873
817 for (i = 0; i < ETH_ALEN; i++) 874 for (i = 0; i < ETH_ALEN; i++)
818 rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]); 875 rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
819 876
820 if (is_valid_ether_addr(conf->bssid)) 877 if (is_valid_ether_addr(conf->bssid)) {
821 rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA); 878 reg = RTL818X_MSR_INFRA;
822 else 879 if (priv->is_rtl8187b)
823 rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK); 880 reg |= RTL818X_MSR_ENEDCA;
881 rtl818x_iowrite8(priv, &priv->map->MSR, reg);
882 } else {
883 reg = RTL818X_MSR_NO_LINK;
884 rtl818x_iowrite8(priv, &priv->map->MSR, reg);
885 }
824 886
825 return 0; 887 return 0;
826} 888}
@@ -907,6 +969,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
907 struct rtl8187_priv *priv; 969 struct rtl8187_priv *priv;
908 struct eeprom_93cx6 eeprom; 970 struct eeprom_93cx6 eeprom;
909 struct ieee80211_channel *channel; 971 struct ieee80211_channel *channel;
972 const char *chip_name;
910 u16 txpwr, reg; 973 u16 txpwr, reg;
911 int err, i; 974 int err, i;
912 DECLARE_MAC_BUF(mac); 975 DECLARE_MAC_BUF(mac);
@@ -918,6 +981,8 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
918 } 981 }
919 982
920 priv = dev->priv; 983 priv = dev->priv;
984 priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B) ||
985 !memcmp(udev->product, "RTL8187B", 8);
921 986
922 SET_IEEE80211_DEV(dev, &intf->dev); 987 SET_IEEE80211_DEV(dev, &intf->dev);
923 usb_set_intfdata(intf, dev); 988 usb_set_intfdata(intf, dev);
@@ -946,8 +1011,13 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
946 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 1011 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
947 IEEE80211_HW_RX_INCLUDES_FCS | 1012 IEEE80211_HW_RX_INCLUDES_FCS |
948 IEEE80211_HW_SIGNAL_UNSPEC; 1013 IEEE80211_HW_SIGNAL_UNSPEC;
949 dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr); 1014 dev->extra_tx_headroom = (!priv->is_rtl8187b) ?
950 dev->queues = 1; 1015 sizeof(struct rtl8187_tx_hdr) :
1016 sizeof(struct rtl8187b_tx_hdr);
1017 if (!priv->is_rtl8187b)
1018 dev->queues = 1;
1019 else
1020 dev->queues = 4;
951 dev->max_signal = 65; 1021 dev->max_signal = 65;
952 1022
953 eeprom.data = dev; 1023 eeprom.data = dev;
@@ -982,10 +1052,24 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
982 (*channel++).hw_value = txpwr & 0xFF; 1052 (*channel++).hw_value = txpwr & 0xFF;
983 (*channel++).hw_value = txpwr >> 8; 1053 (*channel++).hw_value = txpwr >> 8;
984 } 1054 }
985 for (i = 0; i < 2; i++) { 1055 if (!priv->is_rtl8187b) {
986 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6 + i, 1056 for (i = 0; i < 2; i++) {
1057 eeprom_93cx6_read(&eeprom,
1058 RTL8187_EEPROM_TXPWR_CHAN_6 + i,
1059 &txpwr);
1060 (*channel++).hw_value = txpwr & 0xFF;
1061 (*channel++).hw_value = txpwr >> 8;
1062 }
1063 } else {
1064 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6,
987 &txpwr); 1065 &txpwr);
988 (*channel++).hw_value = txpwr & 0xFF; 1066 (*channel++).hw_value = txpwr & 0xFF;
1067
1068 eeprom_93cx6_read(&eeprom, 0x0A, &txpwr);
1069 (*channel++).hw_value = txpwr & 0xFF;
1070
1071 eeprom_93cx6_read(&eeprom, 0x1C, &txpwr);
1072 (*channel++).hw_value = txpwr & 0xFF;
989 (*channel++).hw_value = txpwr >> 8; 1073 (*channel++).hw_value = txpwr >> 8;
990 } 1074 }
991 1075
@@ -1001,6 +1085,50 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1001 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); 1085 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
1002 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 1086 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
1003 1087
1088 if (!priv->is_rtl8187b) {
1089 u32 reg32;
1090 reg32 = rtl818x_ioread32(priv, &priv->map->TX_CONF);
1091 reg32 &= RTL818X_TX_CONF_HWVER_MASK;
1092 switch (reg32) {
1093 case RTL818X_TX_CONF_R8187vD_1:
1094 case RTL818X_TX_CONF_R8187vD_2:
1095 chip_name = "RTL8187vD";
1096 break;
1097 default:
1098 chip_name = "RTL8187vB (default)";
1099 }
1100 } else {
1101 printk(KERN_WARNING "rtl8187: 8187B chip detected. Support "
1102 "is EXPERIMENTAL, and could damage your\n"
1103 " hardware, use at your own risk\n");
1104 /*
1105 * Force USB request to write radio registers for 8187B, Realtek
1106 * only uses it in their sources
1107 */
1108 /*if (priv->asic_rev == 0) {
1109 printk(KERN_WARNING "rtl8187: Forcing use of USB "
1110 "requests to write to radio registers\n");
1111 priv->asic_rev = 1;
1112 }*/
1113 switch (rtl818x_ioread8(priv, (u8 *)0xFFE1)) {
1114 case RTL818X_R8187B_B:
1115 chip_name = "RTL8187BvB";
1116 priv->hw_rev = RTL8187BvB;
1117 break;
1118 case RTL818X_R8187B_D:
1119 chip_name = "RTL8187BvD";
1120 priv->hw_rev = RTL8187BvD;
1121 break;
1122 case RTL818X_R8187B_E:
1123 chip_name = "RTL8187BvE";
1124 priv->hw_rev = RTL8187BvE;
1125 break;
1126 default:
1127 chip_name = "RTL8187BvB (default)";
1128 priv->hw_rev = RTL8187BvB;
1129 }
1130 }
1131
1004 priv->rf = rtl8187_detect_rf(dev); 1132 priv->rf = rtl8187_detect_rf(dev);
1005 1133
1006 err = ieee80211_register_hw(dev); 1134 err = ieee80211_register_hw(dev);
@@ -1009,9 +1137,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1009 goto err_free_dev; 1137 goto err_free_dev;
1010 } 1138 }
1011 1139
1012 printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n", 1140 printk(KERN_INFO "%s: hwaddr %s, %s V%d + %s\n",
1013 wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr), 1141 wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
1014 priv->asic_rev, priv->rf->name); 1142 chip_name, priv->asic_rev, priv->rf->name);
1015 1143
1016 return 0; 1144 return 0;
1017 1145