aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtl8187_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rtl8187_dev.c')
-rw-r--r--drivers/net/wireless/rtl8187_dev.c129
1 files changed, 110 insertions, 19 deletions
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index bf9f0cc5a645..b0a92f543da4 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -41,6 +41,57 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
41 41
42MODULE_DEVICE_TABLE(usb, rtl8187_table); 42MODULE_DEVICE_TABLE(usb, rtl8187_table);
43 43
44static void rtl8187_iowrite_async_cb(struct urb *urb)
45{
46 kfree(urb->context);
47 usb_free_urb(urb);
48}
49
50static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr,
51 void *data, u16 len)
52{
53 struct usb_ctrlrequest *dr;
54 struct urb *urb;
55 struct rtl8187_async_write_data {
56 u8 data[4];
57 struct usb_ctrlrequest dr;
58 } *buf;
59
60 buf = kmalloc(sizeof(*buf), GFP_ATOMIC);
61 if (!buf)
62 return;
63
64 urb = usb_alloc_urb(0, GFP_ATOMIC);
65 if (!urb) {
66 kfree(buf);
67 return;
68 }
69
70 dr = &buf->dr;
71
72 dr->bRequestType = RTL8187_REQT_WRITE;
73 dr->bRequest = RTL8187_REQ_SET_REG;
74 dr->wValue = addr;
75 dr->wIndex = 0;
76 dr->wLength = cpu_to_le16(len);
77
78 memcpy(buf, data, len);
79
80 usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0),
81 (unsigned char *)dr, buf, len,
82 rtl8187_iowrite_async_cb, buf);
83 usb_submit_urb(urb, GFP_ATOMIC);
84}
85
86static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv,
87 __le32 *addr, u32 val)
88{
89 __le32 buf = cpu_to_le32(val);
90
91 rtl8187_iowrite_async(priv, cpu_to_le16((unsigned long)addr),
92 &buf, sizeof(buf));
93}
94
44void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) 95void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
45{ 96{
46 struct rtl8187_priv *priv = dev->priv; 97 struct rtl8187_priv *priv = dev->priv;
@@ -125,6 +176,7 @@ static void rtl8187_rx_cb(struct urb *urb)
125 struct rtl8187_rx_hdr *hdr; 176 struct rtl8187_rx_hdr *hdr;
126 struct ieee80211_rx_status rx_status = { 0 }; 177 struct ieee80211_rx_status rx_status = { 0 };
127 int rate, signal; 178 int rate, signal;
179 u32 flags;
128 180
129 spin_lock(&priv->rx_queue.lock); 181 spin_lock(&priv->rx_queue.lock);
130 if (skb->next) 182 if (skb->next)
@@ -143,10 +195,11 @@ static void rtl8187_rx_cb(struct urb *urb)
143 195
144 skb_put(skb, urb->actual_length); 196 skb_put(skb, urb->actual_length);
145 hdr = (struct rtl8187_rx_hdr *)(skb_tail_pointer(skb) - sizeof(*hdr)); 197 hdr = (struct rtl8187_rx_hdr *)(skb_tail_pointer(skb) - sizeof(*hdr));
146 skb_trim(skb, le16_to_cpu(hdr->len) & 0x0FFF); 198 flags = le32_to_cpu(hdr->flags);
199 skb_trim(skb, flags & 0x0FFF);
147 200
148 signal = hdr->agc >> 1; 201 signal = hdr->agc >> 1;
149 rate = (le16_to_cpu(hdr->rate) >> 4) & 0xF; 202 rate = (flags >> 20) & 0xF;
150 if (rate > 3) { /* OFDM rate */ 203 if (rate > 3) { /* OFDM rate */
151 if (signal > 90) 204 if (signal > 90)
152 signal = 90; 205 signal = 90;
@@ -169,6 +222,8 @@ static void rtl8187_rx_cb(struct urb *urb)
169 rx_status.channel = dev->conf.channel; 222 rx_status.channel = dev->conf.channel;
170 rx_status.phymode = dev->conf.phymode; 223 rx_status.phymode = dev->conf.phymode;
171 rx_status.mactime = le64_to_cpu(hdr->mac_time); 224 rx_status.mactime = le64_to_cpu(hdr->mac_time);
225 if (flags & (1 << 13))
226 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
172 ieee80211_rx_irqsafe(dev, skb, &rx_status); 227 ieee80211_rx_irqsafe(dev, skb, &rx_status);
173 228
174 skb = dev_alloc_skb(RTL8187_MAX_RX); 229 skb = dev_alloc_skb(RTL8187_MAX_RX);
@@ -293,8 +348,6 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
293 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); 348 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
294 349
295 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 350 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
296 for (i = 0; i < ETH_ALEN; i++)
297 rtl818x_iowrite8(priv, &priv->map->MAC[i], priv->hwaddr[i]);
298 351
299 rtl818x_iowrite16(priv, (__le16 *)0xFFF4, 0xFFFF); 352 rtl818x_iowrite16(priv, (__le16 *)0xFFF4, 0xFFFF);
300 reg = rtl818x_ioread8(priv, &priv->map->CONFIG1); 353 reg = rtl818x_ioread8(priv, &priv->map->CONFIG1);
@@ -365,7 +418,7 @@ static void rtl8187_set_channel(struct ieee80211_hw *dev, int channel)
365 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); 418 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
366} 419}
367 420
368static int rtl8187_open(struct ieee80211_hw *dev) 421static int rtl8187_start(struct ieee80211_hw *dev)
369{ 422{
370 struct rtl8187_priv *priv = dev->priv; 423 struct rtl8187_priv *priv = dev->priv;
371 u32 reg; 424 u32 reg;
@@ -383,16 +436,13 @@ static int rtl8187_open(struct ieee80211_hw *dev)
383 RTL818X_RX_CONF_RX_AUTORESETPHY | 436 RTL818X_RX_CONF_RX_AUTORESETPHY |
384 RTL818X_RX_CONF_BSSID | 437 RTL818X_RX_CONF_BSSID |
385 RTL818X_RX_CONF_MGMT | 438 RTL818X_RX_CONF_MGMT |
386 RTL818X_RX_CONF_CTRL |
387 RTL818X_RX_CONF_DATA | 439 RTL818X_RX_CONF_DATA |
388 (7 << 13 /* RX FIFO threshold NONE */) | 440 (7 << 13 /* RX FIFO threshold NONE */) |
389 (7 << 10 /* MAX RX DMA */) | 441 (7 << 10 /* MAX RX DMA */) |
390 RTL818X_RX_CONF_BROADCAST | 442 RTL818X_RX_CONF_BROADCAST |
391 RTL818X_RX_CONF_MULTICAST |
392 RTL818X_RX_CONF_NICMAC; 443 RTL818X_RX_CONF_NICMAC;
393 if (priv->mode == IEEE80211_IF_TYPE_MNTR)
394 reg |= RTL818X_RX_CONF_MONITOR;
395 444
445 priv->rx_conf = reg;
396 rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); 446 rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
397 447
398 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); 448 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
@@ -419,7 +469,7 @@ static int rtl8187_open(struct ieee80211_hw *dev)
419 return 0; 469 return 0;
420} 470}
421 471
422static int rtl8187_stop(struct ieee80211_hw *dev) 472static void rtl8187_stop(struct ieee80211_hw *dev)
423{ 473{
424 struct rtl8187_priv *priv = dev->priv; 474 struct rtl8187_priv *priv = dev->priv;
425 struct rtl8187_rx_info *info; 475 struct rtl8187_rx_info *info;
@@ -445,28 +495,31 @@ static int rtl8187_stop(struct ieee80211_hw *dev)
445 usb_kill_urb(info->urb); 495 usb_kill_urb(info->urb);
446 kfree_skb(skb); 496 kfree_skb(skb);
447 } 497 }
448 return 0; 498 return;
449} 499}
450 500
451static int rtl8187_add_interface(struct ieee80211_hw *dev, 501static int rtl8187_add_interface(struct ieee80211_hw *dev,
452 struct ieee80211_if_init_conf *conf) 502 struct ieee80211_if_init_conf *conf)
453{ 503{
454 struct rtl8187_priv *priv = dev->priv; 504 struct rtl8187_priv *priv = dev->priv;
505 int i;
455 506
456 /* NOTE: using IEEE80211_IF_TYPE_MGMT to indicate no mode selected */ 507 if (priv->mode != IEEE80211_IF_TYPE_MNTR)
457 if (priv->mode != IEEE80211_IF_TYPE_MGMT) 508 return -EOPNOTSUPP;
458 return -1;
459 509
460 switch (conf->type) { 510 switch (conf->type) {
461 case IEEE80211_IF_TYPE_STA: 511 case IEEE80211_IF_TYPE_STA:
462 case IEEE80211_IF_TYPE_MNTR:
463 priv->mode = conf->type; 512 priv->mode = conf->type;
464 break; 513 break;
465 default: 514 default:
466 return -EOPNOTSUPP; 515 return -EOPNOTSUPP;
467 } 516 }
468 517
469 priv->hwaddr = conf->mac_addr ? conf->mac_addr : dev->wiphy->perm_addr; 518 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
519 for (i = 0; i < ETH_ALEN; i++)
520 rtl818x_iowrite8(priv, &priv->map->MAC[i],
521 ((u8 *)conf->mac_addr)[i]);
522 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
470 523
471 return 0; 524 return 0;
472} 525}
@@ -475,7 +528,7 @@ static void rtl8187_remove_interface(struct ieee80211_hw *dev,
475 struct ieee80211_if_init_conf *conf) 528 struct ieee80211_if_init_conf *conf)
476{ 529{
477 struct rtl8187_priv *priv = dev->priv; 530 struct rtl8187_priv *priv = dev->priv;
478 priv->mode = IEEE80211_IF_TYPE_MGMT; 531 priv->mode = IEEE80211_IF_TYPE_MNTR;
479} 532}
480 533
481static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) 534static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
@@ -523,14 +576,52 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev, int if_id,
523 return 0; 576 return 0;
524} 577}
525 578
579static void rtl8187_configure_filter(struct ieee80211_hw *dev,
580 unsigned int changed_flags,
581 unsigned int *total_flags,
582 int mc_count, struct dev_addr_list *mc_list)
583{
584 struct rtl8187_priv *priv = dev->priv;
585
586 *total_flags = 0;
587
588 if (changed_flags & FIF_PROMISC_IN_BSS)
589 priv->rx_conf ^= RTL818X_RX_CONF_NICMAC;
590 if (changed_flags & FIF_ALLMULTI)
591 priv->rx_conf ^= RTL818X_RX_CONF_MULTICAST;
592 if (changed_flags & FIF_FCSFAIL)
593 priv->rx_conf ^= RTL818X_RX_CONF_FCS;
594 if (changed_flags & FIF_CONTROL)
595 priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
596 if (changed_flags & FIF_OTHER_BSS)
597 priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
598
599 if (mc_count > 0)
600 priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
601
602 if (priv->rx_conf & RTL818X_RX_CONF_NICMAC)
603 *total_flags |= FIF_PROMISC_IN_BSS;
604 if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
605 *total_flags |= FIF_ALLMULTI;
606 if (priv->rx_conf & RTL818X_RX_CONF_FCS)
607 *total_flags |= FIF_FCSFAIL;
608 if (priv->rx_conf & RTL818X_RX_CONF_CTRL)
609 *total_flags |= FIF_CONTROL;
610 if (priv->rx_conf & RTL818X_RX_CONF_MONITOR)
611 *total_flags |= FIF_OTHER_BSS;
612
613 rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf);
614}
615
526static const struct ieee80211_ops rtl8187_ops = { 616static const struct ieee80211_ops rtl8187_ops = {
527 .tx = rtl8187_tx, 617 .tx = rtl8187_tx,
528 .open = rtl8187_open, 618 .start = rtl8187_start,
529 .stop = rtl8187_stop, 619 .stop = rtl8187_stop,
530 .add_interface = rtl8187_add_interface, 620 .add_interface = rtl8187_add_interface,
531 .remove_interface = rtl8187_remove_interface, 621 .remove_interface = rtl8187_remove_interface,
532 .config = rtl8187_config, 622 .config = rtl8187_config,
533 .config_interface = rtl8187_config_interface, 623 .config_interface = rtl8187_config_interface,
624 .configure_filter = rtl8187_configure_filter,
534}; 625};
535 626
536static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) 627static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
@@ -604,7 +695,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
604 priv->modes[1].rates = priv->rates; 695 priv->modes[1].rates = priv->rates;
605 priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels); 696 priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels);
606 priv->modes[1].channels = priv->channels; 697 priv->modes[1].channels = priv->channels;
607 priv->mode = IEEE80211_IF_TYPE_MGMT; 698 priv->mode = IEEE80211_IF_TYPE_MNTR;
608 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 699 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
609 IEEE80211_HW_RX_INCLUDES_FCS; 700 IEEE80211_HW_RX_INCLUDES_FCS;
610 dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr); 701 dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr);