diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-30 13:13:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-30 13:13:37 -0400 |
commit | a4319d9fa02fb3f032596d18c6fcc8b05d01a3a5 (patch) | |
tree | 55bfcb36dcaf1935d1877810a79e398b34e46014 | |
parent | afd962a9e8708c571c5c0c4a6d098f931742c229 (diff) | |
parent | 031cf19e6f63941506c9baf76ac7adac06edcf08 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (47 commits)
net: Make "networking" one-click deselectable.
ipv6: Fix useless proc net sockstat6 removal
tcp: MD5: Use MIB counter instead of warning for MD5 mismatch.
pkt_sched: Fix OOPS on ingress qdisc add.
niu: Fix error checking in niu_ethflow_to_class.
IPv6: datagram_send_ctl() should exit immediately when an error occured
mac80211: fix mesh beaconing
PS3: gelic: use unsigned long for irqflags
mac80211: fix cfg80211 hooks for master interface
nl80211: fix dump callbacks
mac80211: partially fix skb->cb use
rtl8187: Improve wireless statistics for RTL8187B
rtl8187: Fix for TX sequence number problem
mac80211: append CONFIG_ to MAC80211_VERBOSE_PS_DEBUG in net/mac80211/tx.c.
mac80211: fix sparse integer as NULL pointer warning
drivers/net/wireless/iwlwifi/iwl-led.c: printk fix
mac80211: return correct error return from ieee80211_wep_init
mac80211: tx, use dev_kfree_skb_any for beacon_get
rt2x00: Clear queue entry flags during initialization
rt2x00: Force full register config after start()
...
57 files changed, 713 insertions, 486 deletions
diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt index 0843ed0163a5..28b6ec87c642 100644 --- a/Documentation/rfkill.txt +++ b/Documentation/rfkill.txt | |||
@@ -390,9 +390,10 @@ rfkill lines are inactive, it must return RFKILL_STATE_SOFT_BLOCKED if its soft | |||
390 | rfkill input line is active. Only if none of the rfkill input lines are | 390 | rfkill input line is active. Only if none of the rfkill input lines are |
391 | active, will it return RFKILL_STATE_UNBLOCKED. | 391 | active, will it return RFKILL_STATE_UNBLOCKED. |
392 | 392 | ||
393 | If it doesn't implement the get_state() hook, it must make sure that its calls | 393 | Since the device has a hardware rfkill line, it IS subject to state changes |
394 | to rfkill_force_state() are enough to keep the status always up-to-date, and it | 394 | external to rfkill. Therefore, the driver must make sure that it calls |
395 | must do a rfkill_force_state() on resume from sleep. | 395 | rfkill_force_state() to keep the status always up-to-date, and it must do a |
396 | rfkill_force_state() on resume from sleep. | ||
396 | 397 | ||
397 | Every time the driver gets a notification from the card that one of its rfkill | 398 | Every time the driver gets a notification from the card that one of its rfkill |
398 | lines changed state (polling might be needed on badly designed cards that don't | 399 | lines changed state (polling might be needed on badly designed cards that don't |
@@ -422,13 +423,24 @@ of the hardware is unknown), or read-write (where the hardware can be queried | |||
422 | about its current state). | 423 | about its current state). |
423 | 424 | ||
424 | The rfkill class will call the get_state hook of a device every time it needs | 425 | The rfkill class will call the get_state hook of a device every time it needs |
425 | to know the *real* current state of the hardware. This can happen often. | 426 | to know the *real* current state of the hardware. This can happen often, but |
427 | it does not do any polling, so it is not enough on hardware that is subject | ||
428 | to state changes outside of the rfkill subsystem. | ||
429 | |||
430 | Therefore, calling rfkill_force_state() when a state change happens is | ||
431 | mandatory when the device has a hardware rfkill line, or when something else | ||
432 | like the firmware could cause its state to be changed without going through the | ||
433 | rfkill class. | ||
426 | 434 | ||
427 | Some hardware provides events when its status changes. In these cases, it is | 435 | Some hardware provides events when its status changes. In these cases, it is |
428 | best for the driver to not provide a get_state hook, and instead register the | 436 | best for the driver to not provide a get_state hook, and instead register the |
429 | rfkill class *already* with the correct status, and keep it updated using | 437 | rfkill class *already* with the correct status, and keep it updated using |
430 | rfkill_force_state() when it gets an event from the hardware. | 438 | rfkill_force_state() when it gets an event from the hardware. |
431 | 439 | ||
440 | rfkill_force_state() must be used on the device resume handlers to update the | ||
441 | rfkill status, should there be any chance of the device status changing during | ||
442 | the sleep. | ||
443 | |||
432 | There is no provision for a statically-allocated rfkill struct. You must | 444 | There is no provision for a statically-allocated rfkill struct. You must |
433 | use rfkill_allocate() to allocate one. | 445 | use rfkill_allocate() to allocate one. |
434 | 446 | ||
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 8ee7d7bb951b..e4765b713aba 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
@@ -6417,7 +6417,7 @@ static int niu_ethflow_to_class(int flow_type, u64 *class) | |||
6417 | *class = CLASS_CODE_SCTP_IPV6; | 6417 | *class = CLASS_CODE_SCTP_IPV6; |
6418 | break; | 6418 | break; |
6419 | default: | 6419 | default: |
6420 | return -1; | 6420 | return 0; |
6421 | } | 6421 | } |
6422 | 6422 | ||
6423 | return 1; | 6423 | return 1; |
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index 6b2dee0cf3a9..a834b52a6a2c 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c | |||
@@ -1024,7 +1024,7 @@ static int gelic_wl_set_encode(struct net_device *netdev, | |||
1024 | struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); | 1024 | struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); |
1025 | struct iw_point *enc = &data->encoding; | 1025 | struct iw_point *enc = &data->encoding; |
1026 | __u16 flags; | 1026 | __u16 flags; |
1027 | unsigned int irqflag; | 1027 | unsigned long irqflag; |
1028 | int key_index, index_specified; | 1028 | int key_index, index_specified; |
1029 | int ret = 0; | 1029 | int ret = 0; |
1030 | 1030 | ||
@@ -1097,7 +1097,7 @@ static int gelic_wl_get_encode(struct net_device *netdev, | |||
1097 | { | 1097 | { |
1098 | struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); | 1098 | struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); |
1099 | struct iw_point *enc = &data->encoding; | 1099 | struct iw_point *enc = &data->encoding; |
1100 | unsigned int irqflag; | 1100 | unsigned long irqflag; |
1101 | unsigned int key_index, index_specified; | 1101 | unsigned int key_index, index_specified; |
1102 | int ret = 0; | 1102 | int ret = 0; |
1103 | 1103 | ||
@@ -1215,7 +1215,7 @@ static int gelic_wl_set_encodeext(struct net_device *netdev, | |||
1215 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | 1215 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; |
1216 | __u16 alg; | 1216 | __u16 alg; |
1217 | __u16 flags; | 1217 | __u16 flags; |
1218 | unsigned int irqflag; | 1218 | unsigned long irqflag; |
1219 | int key_index; | 1219 | int key_index; |
1220 | int ret = 0; | 1220 | int ret = 0; |
1221 | 1221 | ||
@@ -1303,7 +1303,7 @@ static int gelic_wl_get_encodeext(struct net_device *netdev, | |||
1303 | struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); | 1303 | struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); |
1304 | struct iw_point *enc = &data->encoding; | 1304 | struct iw_point *enc = &data->encoding; |
1305 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | 1305 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; |
1306 | unsigned int irqflag; | 1306 | unsigned long irqflag; |
1307 | int key_index; | 1307 | int key_index; |
1308 | int ret = 0; | 1308 | int ret = 0; |
1309 | int max_key_len; | 1309 | int max_key_len; |
@@ -1426,7 +1426,7 @@ static int gelic_wl_priv_set_psk(struct net_device *net_dev, | |||
1426 | { | 1426 | { |
1427 | struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev)); | 1427 | struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev)); |
1428 | unsigned int len; | 1428 | unsigned int len; |
1429 | unsigned int irqflag; | 1429 | unsigned long irqflag; |
1430 | int ret = 0; | 1430 | int ret = 0; |
1431 | 1431 | ||
1432 | pr_debug("%s:<- len=%d\n", __func__, data->data.length); | 1432 | pr_debug("%s:<- len=%d\n", __func__, data->data.length); |
@@ -1467,7 +1467,7 @@ static int gelic_wl_priv_get_psk(struct net_device *net_dev, | |||
1467 | { | 1467 | { |
1468 | struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev)); | 1468 | struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev)); |
1469 | char *p; | 1469 | char *p; |
1470 | unsigned int irqflag; | 1470 | unsigned long irqflag; |
1471 | unsigned int i; | 1471 | unsigned int i; |
1472 | 1472 | ||
1473 | pr_debug("%s:<-\n", __func__); | 1473 | pr_debug("%s:<-\n", __func__); |
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index d9769c527346..ff3fad794b61 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -43,7 +43,9 @@ | |||
43 | #include <linux/version.h> | 43 | #include <linux/version.h> |
44 | #include <linux/module.h> | 44 | #include <linux/module.h> |
45 | #include <linux/delay.h> | 45 | #include <linux/delay.h> |
46 | #include <linux/hardirq.h> | ||
46 | #include <linux/if.h> | 47 | #include <linux/if.h> |
48 | #include <linux/io.h> | ||
47 | #include <linux/netdevice.h> | 49 | #include <linux/netdevice.h> |
48 | #include <linux/cache.h> | 50 | #include <linux/cache.h> |
49 | #include <linux/pci.h> | 51 | #include <linux/pci.h> |
@@ -471,9 +473,6 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
471 | /* Set private data */ | 473 | /* Set private data */ |
472 | pci_set_drvdata(pdev, hw); | 474 | pci_set_drvdata(pdev, hw); |
473 | 475 | ||
474 | /* Enable msi for devices that support it */ | ||
475 | pci_enable_msi(pdev); | ||
476 | |||
477 | /* Setup interrupt handler */ | 476 | /* Setup interrupt handler */ |
478 | ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); | 477 | ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); |
479 | if (ret) { | 478 | if (ret) { |
@@ -551,7 +550,6 @@ err_ah: | |||
551 | err_irq: | 550 | err_irq: |
552 | free_irq(pdev->irq, sc); | 551 | free_irq(pdev->irq, sc); |
553 | err_free: | 552 | err_free: |
554 | pci_disable_msi(pdev); | ||
555 | ieee80211_free_hw(hw); | 553 | ieee80211_free_hw(hw); |
556 | err_map: | 554 | err_map: |
557 | pci_iounmap(pdev, mem); | 555 | pci_iounmap(pdev, mem); |
@@ -573,7 +571,6 @@ ath5k_pci_remove(struct pci_dev *pdev) | |||
573 | ath5k_detach(pdev, hw); | 571 | ath5k_detach(pdev, hw); |
574 | ath5k_hw_detach(sc->ah); | 572 | ath5k_hw_detach(sc->ah); |
575 | free_irq(pdev->irq, sc); | 573 | free_irq(pdev->irq, sc); |
576 | pci_disable_msi(pdev); | ||
577 | pci_iounmap(pdev, sc->iobase); | 574 | pci_iounmap(pdev, sc->iobase); |
578 | pci_release_region(pdev, 0); | 575 | pci_release_region(pdev, 0); |
579 | pci_disable_device(pdev); | 576 | pci_disable_device(pdev); |
@@ -590,6 +587,9 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
590 | ath5k_led_off(sc); | 587 | ath5k_led_off(sc); |
591 | 588 | ||
592 | ath5k_stop_hw(sc); | 589 | ath5k_stop_hw(sc); |
590 | |||
591 | free_irq(pdev->irq, sc); | ||
592 | pci_disable_msi(pdev); | ||
593 | pci_save_state(pdev); | 593 | pci_save_state(pdev); |
594 | pci_disable_device(pdev); | 594 | pci_disable_device(pdev); |
595 | pci_set_power_state(pdev, PCI_D3hot); | 595 | pci_set_power_state(pdev, PCI_D3hot); |
@@ -605,15 +605,12 @@ ath5k_pci_resume(struct pci_dev *pdev) | |||
605 | struct ath5k_hw *ah = sc->ah; | 605 | struct ath5k_hw *ah = sc->ah; |
606 | int i, err; | 606 | int i, err; |
607 | 607 | ||
608 | err = pci_set_power_state(pdev, PCI_D0); | 608 | pci_restore_state(pdev); |
609 | if (err) | ||
610 | return err; | ||
611 | 609 | ||
612 | err = pci_enable_device(pdev); | 610 | err = pci_enable_device(pdev); |
613 | if (err) | 611 | if (err) |
614 | return err; | 612 | return err; |
615 | 613 | ||
616 | pci_restore_state(pdev); | ||
617 | /* | 614 | /* |
618 | * Suspend/Resume resets the PCI configuration space, so we have to | 615 | * Suspend/Resume resets the PCI configuration space, so we have to |
619 | * re-disable the RETRY_TIMEOUT register (0x41) to keep | 616 | * re-disable the RETRY_TIMEOUT register (0x41) to keep |
@@ -621,7 +618,17 @@ ath5k_pci_resume(struct pci_dev *pdev) | |||
621 | */ | 618 | */ |
622 | pci_write_config_byte(pdev, 0x41, 0); | 619 | pci_write_config_byte(pdev, 0x41, 0); |
623 | 620 | ||
624 | ath5k_init(sc); | 621 | pci_enable_msi(pdev); |
622 | |||
623 | err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); | ||
624 | if (err) { | ||
625 | ATH5K_ERR(sc, "request_irq failed\n"); | ||
626 | goto err_msi; | ||
627 | } | ||
628 | |||
629 | err = ath5k_init(sc); | ||
630 | if (err) | ||
631 | goto err_irq; | ||
625 | ath5k_led_enable(sc); | 632 | ath5k_led_enable(sc); |
626 | 633 | ||
627 | /* | 634 | /* |
@@ -635,6 +642,12 @@ ath5k_pci_resume(struct pci_dev *pdev) | |||
635 | ath5k_hw_reset_key(ah, i); | 642 | ath5k_hw_reset_key(ah, i); |
636 | 643 | ||
637 | return 0; | 644 | return 0; |
645 | err_irq: | ||
646 | free_irq(pdev->irq, sc); | ||
647 | err_msi: | ||
648 | pci_disable_msi(pdev); | ||
649 | pci_disable_device(pdev); | ||
650 | return err; | ||
638 | } | 651 | } |
639 | #endif /* CONFIG_PM */ | 652 | #endif /* CONFIG_PM */ |
640 | 653 | ||
@@ -1224,7 +1237,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1224 | 1237 | ||
1225 | pktlen = skb->len; | 1238 | pktlen = skb->len; |
1226 | 1239 | ||
1227 | if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)) { | 1240 | if (info->control.hw_key) { |
1228 | keyidx = info->control.hw_key->hw_key_idx; | 1241 | keyidx = info->control.hw_key->hw_key_idx; |
1229 | pktlen += info->control.icv_len; | 1242 | pktlen += info->control.icv_len; |
1230 | } | 1243 | } |
@@ -1249,6 +1262,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1249 | 1262 | ||
1250 | txq->link = &ds->ds_link; | 1263 | txq->link = &ds->ds_link; |
1251 | ath5k_hw_tx_start(ah, txq->qnum); | 1264 | ath5k_hw_tx_start(ah, txq->qnum); |
1265 | mmiowb(); | ||
1252 | spin_unlock_bh(&txq->lock); | 1266 | spin_unlock_bh(&txq->lock); |
1253 | 1267 | ||
1254 | return 0; | 1268 | return 0; |
@@ -1583,7 +1597,6 @@ ath5k_rx_stop(struct ath5k_softc *sc) | |||
1583 | ath5k_hw_stop_pcu_recv(ah); /* disable PCU */ | 1597 | ath5k_hw_stop_pcu_recv(ah); /* disable PCU */ |
1584 | ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ | 1598 | ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ |
1585 | ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ | 1599 | ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ |
1586 | mdelay(3); /* 3ms is long enough for 1 frame */ | ||
1587 | 1600 | ||
1588 | ath5k_debug_printrxbuffs(sc, ah); | 1601 | ath5k_debug_printrxbuffs(sc, ah); |
1589 | 1602 | ||
@@ -1682,31 +1695,44 @@ ath5k_tasklet_rx(unsigned long data) | |||
1682 | struct ath5k_rx_status rs = {}; | 1695 | struct ath5k_rx_status rs = {}; |
1683 | struct sk_buff *skb; | 1696 | struct sk_buff *skb; |
1684 | struct ath5k_softc *sc = (void *)data; | 1697 | struct ath5k_softc *sc = (void *)data; |
1685 | struct ath5k_buf *bf; | 1698 | struct ath5k_buf *bf, *bf_last; |
1686 | struct ath5k_desc *ds; | 1699 | struct ath5k_desc *ds; |
1687 | int ret; | 1700 | int ret; |
1688 | int hdrlen; | 1701 | int hdrlen; |
1689 | int pad; | 1702 | int pad; |
1690 | 1703 | ||
1691 | spin_lock(&sc->rxbuflock); | 1704 | spin_lock(&sc->rxbuflock); |
1705 | if (list_empty(&sc->rxbuf)) { | ||
1706 | ATH5K_WARN(sc, "empty rx buf pool\n"); | ||
1707 | goto unlock; | ||
1708 | } | ||
1709 | bf_last = list_entry(sc->rxbuf.prev, struct ath5k_buf, list); | ||
1692 | do { | 1710 | do { |
1693 | rxs.flag = 0; | 1711 | rxs.flag = 0; |
1694 | 1712 | ||
1695 | if (unlikely(list_empty(&sc->rxbuf))) { | ||
1696 | ATH5K_WARN(sc, "empty rx buf pool\n"); | ||
1697 | break; | ||
1698 | } | ||
1699 | bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); | 1713 | bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); |
1700 | BUG_ON(bf->skb == NULL); | 1714 | BUG_ON(bf->skb == NULL); |
1701 | skb = bf->skb; | 1715 | skb = bf->skb; |
1702 | ds = bf->desc; | 1716 | ds = bf->desc; |
1703 | 1717 | ||
1704 | /* TODO only one segment */ | 1718 | /* |
1705 | pci_dma_sync_single_for_cpu(sc->pdev, sc->desc_daddr, | 1719 | * last buffer must not be freed to ensure proper hardware |
1706 | sc->desc_len, PCI_DMA_FROMDEVICE); | 1720 | * function. When the hardware finishes also a packet next to |
1707 | 1721 | * it, we are sure, it doesn't use it anymore and we can go on. | |
1708 | if (unlikely(ds->ds_link == bf->daddr)) /* this is the end */ | 1722 | */ |
1709 | break; | 1723 | if (bf_last == bf) |
1724 | bf->flags |= 1; | ||
1725 | if (bf->flags) { | ||
1726 | struct ath5k_buf *bf_next = list_entry(bf->list.next, | ||
1727 | struct ath5k_buf, list); | ||
1728 | ret = sc->ah->ah_proc_rx_desc(sc->ah, bf_next->desc, | ||
1729 | &rs); | ||
1730 | if (ret) | ||
1731 | break; | ||
1732 | bf->flags &= ~1; | ||
1733 | /* skip the overwritten one (even status is martian) */ | ||
1734 | goto next; | ||
1735 | } | ||
1710 | 1736 | ||
1711 | ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs); | 1737 | ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs); |
1712 | if (unlikely(ret == -EINPROGRESS)) | 1738 | if (unlikely(ret == -EINPROGRESS)) |
@@ -1752,8 +1778,6 @@ ath5k_tasklet_rx(unsigned long data) | |||
1752 | goto next; | 1778 | goto next; |
1753 | } | 1779 | } |
1754 | accept: | 1780 | accept: |
1755 | pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, | ||
1756 | rs.rs_datalen, PCI_DMA_FROMDEVICE); | ||
1757 | pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, | 1781 | pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, |
1758 | PCI_DMA_FROMDEVICE); | 1782 | PCI_DMA_FROMDEVICE); |
1759 | bf->skb = NULL; | 1783 | bf->skb = NULL; |
@@ -1816,6 +1840,7 @@ accept: | |||
1816 | next: | 1840 | next: |
1817 | list_move_tail(&bf->list, &sc->rxbuf); | 1841 | list_move_tail(&bf->list, &sc->rxbuf); |
1818 | } while (ath5k_rxbuf_setup(sc, bf) == 0); | 1842 | } while (ath5k_rxbuf_setup(sc, bf) == 0); |
1843 | unlock: | ||
1819 | spin_unlock(&sc->rxbuflock); | 1844 | spin_unlock(&sc->rxbuflock); |
1820 | } | 1845 | } |
1821 | 1846 | ||
@@ -1840,9 +1865,6 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1840 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { | 1865 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { |
1841 | ds = bf->desc; | 1866 | ds = bf->desc; |
1842 | 1867 | ||
1843 | /* TODO only one segment */ | ||
1844 | pci_dma_sync_single_for_cpu(sc->pdev, sc->desc_daddr, | ||
1845 | sc->desc_len, PCI_DMA_FROMDEVICE); | ||
1846 | ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); | 1868 | ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); |
1847 | if (unlikely(ret == -EINPROGRESS)) | 1869 | if (unlikely(ret == -EINPROGRESS)) |
1848 | break; | 1870 | break; |
@@ -2015,8 +2037,6 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
2015 | ATH5K_WARN(sc, "beacon queue %u didn't stop?\n", sc->bhalq); | 2037 | ATH5K_WARN(sc, "beacon queue %u didn't stop?\n", sc->bhalq); |
2016 | /* NB: hw still stops DMA, so proceed */ | 2038 | /* NB: hw still stops DMA, so proceed */ |
2017 | } | 2039 | } |
2018 | pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, bf->skb->len, | ||
2019 | PCI_DMA_TODEVICE); | ||
2020 | 2040 | ||
2021 | ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr); | 2041 | ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr); |
2022 | ath5k_hw_tx_start(ah, sc->bhalq); | 2042 | ath5k_hw_tx_start(ah, sc->bhalq); |
@@ -2240,6 +2260,7 @@ ath5k_init(struct ath5k_softc *sc) | |||
2240 | 2260 | ||
2241 | ret = 0; | 2261 | ret = 0; |
2242 | done: | 2262 | done: |
2263 | mmiowb(); | ||
2243 | mutex_unlock(&sc->lock); | 2264 | mutex_unlock(&sc->lock); |
2244 | return ret; | 2265 | return ret; |
2245 | } | 2266 | } |
@@ -2272,6 +2293,7 @@ ath5k_stop_locked(struct ath5k_softc *sc) | |||
2272 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { | 2293 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { |
2273 | ath5k_led_off(sc); | 2294 | ath5k_led_off(sc); |
2274 | ath5k_hw_set_intr(ah, 0); | 2295 | ath5k_hw_set_intr(ah, 0); |
2296 | synchronize_irq(sc->pdev->irq); | ||
2275 | } | 2297 | } |
2276 | ath5k_txq_cleanup(sc); | 2298 | ath5k_txq_cleanup(sc); |
2277 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { | 2299 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { |
@@ -2321,9 +2343,13 @@ ath5k_stop_hw(struct ath5k_softc *sc) | |||
2321 | } | 2343 | } |
2322 | } | 2344 | } |
2323 | ath5k_txbuf_free(sc, sc->bbuf); | 2345 | ath5k_txbuf_free(sc, sc->bbuf); |
2346 | mmiowb(); | ||
2324 | mutex_unlock(&sc->lock); | 2347 | mutex_unlock(&sc->lock); |
2325 | 2348 | ||
2326 | del_timer_sync(&sc->calib_tim); | 2349 | del_timer_sync(&sc->calib_tim); |
2350 | tasklet_kill(&sc->rxtq); | ||
2351 | tasklet_kill(&sc->txtq); | ||
2352 | tasklet_kill(&sc->restq); | ||
2327 | 2353 | ||
2328 | return ret; | 2354 | return ret; |
2329 | } | 2355 | } |
@@ -2550,8 +2576,6 @@ ath5k_init_leds(struct ath5k_softc *sc) | |||
2550 | struct pci_dev *pdev = sc->pdev; | 2576 | struct pci_dev *pdev = sc->pdev; |
2551 | char name[ATH5K_LED_MAX_NAME_LEN + 1]; | 2577 | char name[ATH5K_LED_MAX_NAME_LEN + 1]; |
2552 | 2578 | ||
2553 | sc->led_on = 0; /* active low */ | ||
2554 | |||
2555 | /* | 2579 | /* |
2556 | * Auto-enable soft led processing for IBM cards and for | 2580 | * Auto-enable soft led processing for IBM cards and for |
2557 | * 5211 minipci cards. | 2581 | * 5211 minipci cards. |
@@ -2560,11 +2584,13 @@ ath5k_init_leds(struct ath5k_softc *sc) | |||
2560 | pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) { | 2584 | pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) { |
2561 | __set_bit(ATH_STAT_LEDSOFT, sc->status); | 2585 | __set_bit(ATH_STAT_LEDSOFT, sc->status); |
2562 | sc->led_pin = 0; | 2586 | sc->led_pin = 0; |
2587 | sc->led_on = 0; /* active low */ | ||
2563 | } | 2588 | } |
2564 | /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */ | 2589 | /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */ |
2565 | if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) { | 2590 | if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) { |
2566 | __set_bit(ATH_STAT_LEDSOFT, sc->status); | 2591 | __set_bit(ATH_STAT_LEDSOFT, sc->status); |
2567 | sc->led_pin = 1; | 2592 | sc->led_pin = 1; |
2593 | sc->led_on = 1; /* active high */ | ||
2568 | } | 2594 | } |
2569 | if (!test_bit(ATH_STAT_LEDSOFT, sc->status)) | 2595 | if (!test_bit(ATH_STAT_LEDSOFT, sc->status)) |
2570 | goto out; | 2596 | goto out; |
@@ -2783,6 +2809,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
2783 | /* XXX: assoc id is set to 0 for now, mac80211 doesn't have | 2809 | /* XXX: assoc id is set to 0 for now, mac80211 doesn't have |
2784 | * a clean way of letting us retrieve this yet. */ | 2810 | * a clean way of letting us retrieve this yet. */ |
2785 | ath5k_hw_set_associd(ah, ah->ah_bssid, 0); | 2811 | ath5k_hw_set_associd(ah, ah->ah_bssid, 0); |
2812 | mmiowb(); | ||
2786 | } | 2813 | } |
2787 | 2814 | ||
2788 | if (conf->changed & IEEE80211_IFCC_BEACON && | 2815 | if (conf->changed & IEEE80211_IFCC_BEACON && |
@@ -2971,6 +2998,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2971 | } | 2998 | } |
2972 | 2999 | ||
2973 | unlock: | 3000 | unlock: |
3001 | mmiowb(); | ||
2974 | mutex_unlock(&sc->lock); | 3002 | mutex_unlock(&sc->lock); |
2975 | return ret; | 3003 | return ret; |
2976 | } | 3004 | } |
@@ -3032,8 +3060,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
3032 | 3060 | ||
3033 | ath5k_debug_dump_skb(sc, skb, "BC ", 1); | 3061 | ath5k_debug_dump_skb(sc, skb, "BC ", 1); |
3034 | 3062 | ||
3035 | mutex_lock(&sc->lock); | ||
3036 | |||
3037 | if (sc->opmode != IEEE80211_IF_TYPE_IBSS) { | 3063 | if (sc->opmode != IEEE80211_IF_TYPE_IBSS) { |
3038 | ret = -EIO; | 3064 | ret = -EIO; |
3039 | goto end; | 3065 | goto end; |
@@ -3044,11 +3070,12 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
3044 | ret = ath5k_beacon_setup(sc, sc->bbuf); | 3070 | ret = ath5k_beacon_setup(sc, sc->bbuf); |
3045 | if (ret) | 3071 | if (ret) |
3046 | sc->bbuf->skb = NULL; | 3072 | sc->bbuf->skb = NULL; |
3047 | else | 3073 | else { |
3048 | ath5k_beacon_config(sc); | 3074 | ath5k_beacon_config(sc); |
3075 | mmiowb(); | ||
3076 | } | ||
3049 | 3077 | ||
3050 | end: | 3078 | end: |
3051 | mutex_unlock(&sc->lock); | ||
3052 | return ret; | 3079 | return ret; |
3053 | } | 3080 | } |
3054 | 3081 | ||
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h index 47f414b09e67..d7e03e6b8271 100644 --- a/drivers/net/wireless/ath5k/base.h +++ b/drivers/net/wireless/ath5k/base.h | |||
@@ -56,7 +56,7 @@ | |||
56 | 56 | ||
57 | struct ath5k_buf { | 57 | struct ath5k_buf { |
58 | struct list_head list; | 58 | struct list_head list; |
59 | unsigned int flags; /* tx descriptor flags */ | 59 | unsigned int flags; /* rx descriptor flags */ |
60 | struct ath5k_desc *desc; /* virtual addr of desc */ | 60 | struct ath5k_desc *desc; /* virtual addr of desc */ |
61 | dma_addr_t daddr; /* physical addr of desc */ | 61 | dma_addr_t daddr; /* physical addr of desc */ |
62 | struct sk_buff *skb; /* skbuff for buf */ | 62 | struct sk_buff *skb; /* skbuff for buf */ |
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index c6d12c53bda4..7ca87a557312 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c | |||
@@ -1440,6 +1440,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) | |||
1440 | 1440 | ||
1441 | /* Stop queue */ | 1441 | /* Stop queue */ |
1442 | ath5k_hw_reg_write(ah, tx_queue, AR5K_CR); | 1442 | ath5k_hw_reg_write(ah, tx_queue, AR5K_CR); |
1443 | ath5k_hw_reg_read(ah, AR5K_CR); | ||
1443 | } else { | 1444 | } else { |
1444 | /* | 1445 | /* |
1445 | * Schedule TX disable and wait until queue is empty | 1446 | * Schedule TX disable and wait until queue is empty |
@@ -1456,6 +1457,8 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) | |||
1456 | 1457 | ||
1457 | /* Clear register */ | 1458 | /* Clear register */ |
1458 | ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD); | 1459 | ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD); |
1460 | if (pending) | ||
1461 | return -EBUSY; | ||
1459 | } | 1462 | } |
1460 | 1463 | ||
1461 | /* TODO: Check for success else return error */ | 1464 | /* TODO: Check for success else return error */ |
@@ -1716,6 +1719,7 @@ enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask) | |||
1716 | 1719 | ||
1717 | /* ..re-enable interrupts */ | 1720 | /* ..re-enable interrupts */ |
1718 | ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER); | 1721 | ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER); |
1722 | ath5k_hw_reg_read(ah, AR5K_IER); | ||
1719 | 1723 | ||
1720 | return old_mask; | 1724 | return old_mask; |
1721 | } | 1725 | } |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index e78319aa47c1..3bf3a869361f 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -4645,8 +4645,7 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4645 | } | 4645 | } |
4646 | 4646 | ||
4647 | /* fill hw info */ | 4647 | /* fill hw info */ |
4648 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | 4648 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
4649 | IEEE80211_HW_RX_INCLUDES_FCS | | ||
4650 | IEEE80211_HW_SIGNAL_DBM | | 4649 | IEEE80211_HW_SIGNAL_DBM | |
4651 | IEEE80211_HW_NOISE_DBM; | 4650 | IEEE80211_HW_NOISE_DBM; |
4652 | 4651 | ||
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 8d54502222a6..9dda8169f7cc 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -192,7 +192,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
192 | const struct b43_phy *phy = &dev->phy; | 192 | const struct b43_phy *phy = &dev->phy; |
193 | const struct ieee80211_hdr *wlhdr = | 193 | const struct ieee80211_hdr *wlhdr = |
194 | (const struct ieee80211_hdr *)fragment_data; | 194 | (const struct ieee80211_hdr *)fragment_data; |
195 | int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)); | 195 | int use_encryption = !!info->control.hw_key; |
196 | __le16 fctl = wlhdr->frame_control; | 196 | __le16 fctl = wlhdr->frame_control; |
197 | struct ieee80211_rate *fbrate; | 197 | struct ieee80211_rate *fbrate; |
198 | u8 rate, rate_fb; | 198 | u8 rate, rate_fb; |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index a1b8bf3ee732..2541c81932f0 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -3702,8 +3702,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev) | |||
3702 | } | 3702 | } |
3703 | 3703 | ||
3704 | /* fill hw info */ | 3704 | /* fill hw info */ |
3705 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | 3705 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
3706 | IEEE80211_HW_RX_INCLUDES_FCS | | ||
3707 | IEEE80211_HW_SIGNAL_DBM | | 3706 | IEEE80211_HW_SIGNAL_DBM | |
3708 | IEEE80211_HW_NOISE_DBM; | 3707 | IEEE80211_HW_NOISE_DBM; |
3709 | hw->queues = 1; /* FIXME: hardware has more queues */ | 3708 | hw->queues = 1; /* FIXME: hardware has more queues */ |
@@ -3846,10 +3845,10 @@ static int b43legacy_resume(struct ssb_device *dev) | |||
3846 | goto out; | 3845 | goto out; |
3847 | } | 3846 | } |
3848 | } | 3847 | } |
3849 | mutex_unlock(&wl->mutex); | ||
3850 | 3848 | ||
3851 | b43legacydbg(wl, "Device resumed.\n"); | 3849 | b43legacydbg(wl, "Device resumed.\n"); |
3852 | out: | 3850 | out: |
3851 | mutex_unlock(&wl->mutex); | ||
3853 | return err; | 3852 | return err; |
3854 | } | 3853 | } |
3855 | 3854 | ||
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index e969ed8d412d..68e1f8c78727 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
@@ -192,7 +192,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
192 | u16 cookie) | 192 | u16 cookie) |
193 | { | 193 | { |
194 | const struct ieee80211_hdr *wlhdr; | 194 | const struct ieee80211_hdr *wlhdr; |
195 | int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)); | 195 | int use_encryption = !!info->control.hw_key; |
196 | u16 fctl; | 196 | u16 fctl; |
197 | u8 rate; | 197 | u8 rate; |
198 | struct ieee80211_rate *rate_fb; | 198 | struct ieee80211_rate *rate_fb; |
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index 5bf9e00b070c..c6f886ec08a3 100644 --- a/drivers/net/wireless/ipw2100.c +++ b/drivers/net/wireless/ipw2100.c | |||
@@ -6442,6 +6442,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev) | |||
6442 | if (err) { | 6442 | if (err) { |
6443 | printk(KERN_ERR "%s: pci_enable_device failed on resume\n", | 6443 | printk(KERN_ERR "%s: pci_enable_device failed on resume\n", |
6444 | dev->name); | 6444 | dev->name); |
6445 | mutex_unlock(&priv->action_mutex); | ||
6445 | return err; | 6446 | return err; |
6446 | } | 6447 | } |
6447 | pci_restore_state(pci_dev); | 6448 | pci_restore_state(pci_dev); |
@@ -7146,7 +7147,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev, | |||
7146 | err = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE, &val, &len); | 7147 | err = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE, &val, &len); |
7147 | if (err) { | 7148 | if (err) { |
7148 | IPW_DEBUG_WX("failed querying ordinals.\n"); | 7149 | IPW_DEBUG_WX("failed querying ordinals.\n"); |
7149 | return err; | 7150 | goto done; |
7150 | } | 7151 | } |
7151 | 7152 | ||
7152 | switch (val & TX_RATE_MASK) { | 7153 | switch (val & TX_RATE_MASK) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index c2a76785b665..a51e0eaa1334 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -630,7 +630,9 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv, | |||
630 | struct ieee80211_rx_status *stats) | 630 | struct ieee80211_rx_status *stats) |
631 | { | 631 | { |
632 | struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data; | 632 | struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data; |
633 | #ifdef CONFIG_IWL3945_LEDS | ||
633 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); | 634 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); |
635 | #endif | ||
634 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); | 636 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); |
635 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); | 637 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); |
636 | short len = le16_to_cpu(rx_hdr->len); | 638 | short len = le16_to_cpu(rx_hdr->len); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index a44188bf4459..e3427c205ccf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -818,8 +818,7 @@ int iwl_setup_mac(struct iwl_priv *priv) | |||
818 | hw->rate_control_algorithm = "iwl-4965-rs"; | 818 | hw->rate_control_algorithm = "iwl-4965-rs"; |
819 | 819 | ||
820 | /* Tell mac80211 our characteristics */ | 820 | /* Tell mac80211 our characteristics */ |
821 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | 821 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
822 | IEEE80211_HW_SIGNAL_DBM | | ||
823 | IEEE80211_HW_NOISE_DBM; | 822 | IEEE80211_HW_NOISE_DBM; |
824 | /* Default value; 4 EDCA QOS priorities */ | 823 | /* Default value; 4 EDCA QOS priorities */ |
825 | hw->queues = 4; | 824 | hw->queues = 4; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 58384805a494..d6d729e86bdb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -68,12 +68,8 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv); | |||
68 | #endif | 68 | #endif |
69 | 69 | ||
70 | #else | 70 | #else |
71 | static inline void IWL_DEBUG(int level, const char *fmt, ...) | 71 | #define IWL_DEBUG(level, fmt, args...) |
72 | { | 72 | #define IWL_DEBUG_LIMIT(level, fmt, args...) |
73 | } | ||
74 | static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...) | ||
75 | { | ||
76 | } | ||
77 | #endif /* CONFIG_IWLWIFI_DEBUG */ | 73 | #endif /* CONFIG_IWLWIFI_DEBUG */ |
78 | 74 | ||
79 | 75 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 899d7a2567a8..61250e6a7d1b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
@@ -268,7 +268,9 @@ static int iwl_get_blink_rate(struct iwl_priv *priv) | |||
268 | if (tpt < 0) /* wrapparound */ | 268 | if (tpt < 0) /* wrapparound */ |
269 | tpt = -tpt; | 269 | tpt = -tpt; |
270 | 270 | ||
271 | IWL_DEBUG_LED("tpt %lld current_tpt %lld\n", tpt, current_tpt); | 271 | IWL_DEBUG_LED("tpt %lld current_tpt %llu\n", |
272 | (long long)tpt, | ||
273 | (unsigned long long)current_tpt); | ||
272 | priv->led_tpt = current_tpt; | 274 | priv->led_tpt = current_tpt; |
273 | 275 | ||
274 | if (!priv->allow_blinking) | 276 | if (!priv->allow_blinking) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index efc750d2fc5c..5a00ac23e2d0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -270,6 +270,7 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv, | |||
270 | static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, | 270 | static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, |
271 | struct iwl_rx_mem_buffer *rxb) | 271 | struct iwl_rx_mem_buffer *rxb) |
272 | { | 272 | { |
273 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
273 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 274 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
274 | struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; | 275 | struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; |
275 | 276 | ||
@@ -277,6 +278,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, | |||
277 | scan_notif->scanned_channels, | 278 | scan_notif->scanned_channels, |
278 | scan_notif->tsf_low, | 279 | scan_notif->tsf_low, |
279 | scan_notif->tsf_high, scan_notif->status); | 280 | scan_notif->tsf_high, scan_notif->status); |
281 | #endif | ||
280 | 282 | ||
281 | /* The HW is no longer scanning */ | 283 | /* The HW is no longer scanning */ |
282 | clear_bit(STATUS_SCAN_HW, &priv->status); | 284 | clear_bit(STATUS_SCAN_HW, &priv->status); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 9b50b1052b09..f72cd0bf6aa3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -906,7 +906,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
906 | * first entry */ | 906 | * first entry */ |
907 | iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); | 907 | iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); |
908 | 908 | ||
909 | if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)) | 909 | if (info->control.hw_key) |
910 | iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); | 910 | iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); |
911 | 911 | ||
912 | /* Set up TFD's 2nd entry to point directly to remainder of skb, | 912 | /* Set up TFD's 2nd entry to point directly to remainder of skb, |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 4a22d3fba75b..7c82ecfa30a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -2667,7 +2667,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2667 | * first entry */ | 2667 | * first entry */ |
2668 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); | 2668 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); |
2669 | 2669 | ||
2670 | if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)) | 2670 | if (info->control.hw_key) |
2671 | iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0); | 2671 | iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0); |
2672 | 2672 | ||
2673 | /* Set up TFD's 2nd entry to point directly to remainder of skb, | 2673 | /* Set up TFD's 2nd entry to point directly to remainder of skb, |
@@ -7899,8 +7899,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7899 | priv->ibss_beacon = NULL; | 7899 | priv->ibss_beacon = NULL; |
7900 | 7900 | ||
7901 | /* Tell mac80211 our characteristics */ | 7901 | /* Tell mac80211 our characteristics */ |
7902 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | 7902 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
7903 | IEEE80211_HW_SIGNAL_DBM | | ||
7904 | IEEE80211_HW_NOISE_DBM; | 7903 | IEEE80211_HW_NOISE_DBM; |
7905 | 7904 | ||
7906 | /* 4 EDCA QOS priorities */ | 7905 | /* 4 EDCA QOS priorities */ |
diff --git a/drivers/net/wireless/libertas/persistcfg.c b/drivers/net/wireless/libertas/persistcfg.c index 6d0ff8decaf7..3309a9c3cfef 100644 --- a/drivers/net/wireless/libertas/persistcfg.c +++ b/drivers/net/wireless/libertas/persistcfg.c | |||
@@ -48,7 +48,7 @@ static ssize_t bootflag_get(struct device *dev, | |||
48 | if (ret) | 48 | if (ret) |
49 | return ret; | 49 | return ret; |
50 | 50 | ||
51 | return snprintf(buf, 12, "0x%x\n", le32_to_cpu(defs.bootflag)); | 51 | return snprintf(buf, 12, "%d\n", le32_to_cpu(defs.bootflag)); |
52 | } | 52 | } |
53 | 53 | ||
54 | /** | 54 | /** |
@@ -63,8 +63,8 @@ static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr, | |||
63 | int ret; | 63 | int ret; |
64 | 64 | ||
65 | memset(&cmd, 0, sizeof(cmd)); | 65 | memset(&cmd, 0, sizeof(cmd)); |
66 | ret = sscanf(buf, "%x", &datum); | 66 | ret = sscanf(buf, "%d", &datum); |
67 | if (ret != 1) | 67 | if ((ret != 1) || (datum > 1)) |
68 | return -EINVAL; | 68 | return -EINVAL; |
69 | 69 | ||
70 | *((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum); | 70 | *((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum); |
@@ -91,7 +91,7 @@ static ssize_t boottime_get(struct device *dev, | |||
91 | if (ret) | 91 | if (ret) |
92 | return ret; | 92 | return ret; |
93 | 93 | ||
94 | return snprintf(buf, 12, "0x%x\n", defs.boottime); | 94 | return snprintf(buf, 12, "%d\n", defs.boottime); |
95 | } | 95 | } |
96 | 96 | ||
97 | /** | 97 | /** |
@@ -106,8 +106,8 @@ static ssize_t boottime_set(struct device *dev, | |||
106 | int ret; | 106 | int ret; |
107 | 107 | ||
108 | memset(&cmd, 0, sizeof(cmd)); | 108 | memset(&cmd, 0, sizeof(cmd)); |
109 | ret = sscanf(buf, "%x", &datum); | 109 | ret = sscanf(buf, "%d", &datum); |
110 | if (ret != 1) | 110 | if ((ret != 1) || (datum > 255)) |
111 | return -EINVAL; | 111 | return -EINVAL; |
112 | 112 | ||
113 | /* A too small boot time will result in the device booting into | 113 | /* A too small boot time will result in the device booting into |
@@ -143,7 +143,7 @@ static ssize_t channel_get(struct device *dev, | |||
143 | if (ret) | 143 | if (ret) |
144 | return ret; | 144 | return ret; |
145 | 145 | ||
146 | return snprintf(buf, 12, "0x%x\n", le16_to_cpu(defs.channel)); | 146 | return snprintf(buf, 12, "%d\n", le16_to_cpu(defs.channel)); |
147 | } | 147 | } |
148 | 148 | ||
149 | /** | 149 | /** |
@@ -154,11 +154,11 @@ static ssize_t channel_set(struct device *dev, struct device_attribute *attr, | |||
154 | { | 154 | { |
155 | struct lbs_private *priv = to_net_dev(dev)->priv; | 155 | struct lbs_private *priv = to_net_dev(dev)->priv; |
156 | struct cmd_ds_mesh_config cmd; | 156 | struct cmd_ds_mesh_config cmd; |
157 | uint16_t datum; | 157 | uint32_t datum; |
158 | int ret; | 158 | int ret; |
159 | 159 | ||
160 | memset(&cmd, 0, sizeof(cmd)); | 160 | memset(&cmd, 0, sizeof(cmd)); |
161 | ret = sscanf(buf, "%hx", &datum); | 161 | ret = sscanf(buf, "%d", &datum); |
162 | if (ret != 1 || datum < 1 || datum > 11) | 162 | if (ret != 1 || datum < 1 || datum > 11) |
163 | return -EINVAL; | 163 | return -EINVAL; |
164 | 164 | ||
@@ -274,8 +274,8 @@ static ssize_t protocol_id_set(struct device *dev, | |||
274 | int ret; | 274 | int ret; |
275 | 275 | ||
276 | memset(&cmd, 0, sizeof(cmd)); | 276 | memset(&cmd, 0, sizeof(cmd)); |
277 | ret = sscanf(buf, "%x", &datum); | 277 | ret = sscanf(buf, "%d", &datum); |
278 | if (ret != 1) | 278 | if ((ret != 1) || (datum > 255)) |
279 | return -EINVAL; | 279 | return -EINVAL; |
280 | 280 | ||
281 | /* fetch all other Information Element parameters */ | 281 | /* fetch all other Information Element parameters */ |
@@ -328,8 +328,8 @@ static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr, | |||
328 | int ret; | 328 | int ret; |
329 | 329 | ||
330 | memset(&cmd, 0, sizeof(cmd)); | 330 | memset(&cmd, 0, sizeof(cmd)); |
331 | ret = sscanf(buf, "%x", &datum); | 331 | ret = sscanf(buf, "%d", &datum); |
332 | if (ret != 1) | 332 | if ((ret != 1) || (datum > 255)) |
333 | return -EINVAL; | 333 | return -EINVAL; |
334 | 334 | ||
335 | /* fetch all other Information Element parameters */ | 335 | /* fetch all other Information Element parameters */ |
@@ -382,8 +382,8 @@ static ssize_t capability_set(struct device *dev, struct device_attribute *attr, | |||
382 | int ret; | 382 | int ret; |
383 | 383 | ||
384 | memset(&cmd, 0, sizeof(cmd)); | 384 | memset(&cmd, 0, sizeof(cmd)); |
385 | ret = sscanf(buf, "%x", &datum); | 385 | ret = sscanf(buf, "%d", &datum); |
386 | if (ret != 1) | 386 | if ((ret != 1) || (datum > 255)) |
387 | return -EINVAL; | 387 | return -EINVAL; |
388 | 388 | ||
389 | /* fetch all other Information Element parameters */ | 389 | /* fetch all other Information Element parameters */ |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 5816230d58f8..248d31a7aa33 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -500,7 +500,7 @@ failed_hw: | |||
500 | device_unregister(data->dev); | 500 | device_unregister(data->dev); |
501 | failed_drvdata: | 501 | failed_drvdata: |
502 | ieee80211_free_hw(hw); | 502 | ieee80211_free_hw(hw); |
503 | hwsim_radios[i] = 0; | 503 | hwsim_radios[i] = NULL; |
504 | failed: | 504 | failed: |
505 | mac80211_hwsim_free(); | 505 | mac80211_hwsim_free(); |
506 | return err; | 506 | return err; |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 3558cb210747..3078417b326b 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1121,6 +1121,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry) | |||
1121 | int pipe = usb_sndbulkpipe(usb_dev, 1); | 1121 | int pipe = usb_sndbulkpipe(usb_dev, 1); |
1122 | int length; | 1122 | int length; |
1123 | u16 reg; | 1123 | u16 reg; |
1124 | u32 word, len; | ||
1124 | 1125 | ||
1125 | /* | 1126 | /* |
1126 | * Add the descriptor in front of the skb. | 1127 | * Add the descriptor in front of the skb. |
@@ -1130,6 +1131,17 @@ static void rt2500usb_write_beacon(struct queue_entry *entry) | |||
1130 | skbdesc->desc = entry->skb->data; | 1131 | skbdesc->desc = entry->skb->data; |
1131 | 1132 | ||
1132 | /* | 1133 | /* |
1134 | * Adjust the beacon databyte count. The current number is | ||
1135 | * calculated before this function gets called, but falsely | ||
1136 | * assumes that the descriptor was already present in the SKB. | ||
1137 | */ | ||
1138 | rt2x00_desc_read(skbdesc->desc, 0, &word); | ||
1139 | len = rt2x00_get_field32(word, TXD_W0_DATABYTE_COUNT); | ||
1140 | len += skbdesc->desc_len; | ||
1141 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, len); | ||
1142 | rt2x00_desc_write(skbdesc->desc, 0, word); | ||
1143 | |||
1144 | /* | ||
1133 | * Disable beaconing while we are reloading the beacon data, | 1145 | * Disable beaconing while we are reloading the beacon data, |
1134 | * otherwise we might be sending out invalid data. | 1146 | * otherwise we might be sending out invalid data. |
1135 | */ | 1147 | */ |
@@ -1650,7 +1662,6 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1650 | * Initialize all hw fields. | 1662 | * Initialize all hw fields. |
1651 | */ | 1663 | */ |
1652 | rt2x00dev->hw->flags = | 1664 | rt2x00dev->hw->flags = |
1653 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | ||
1654 | IEEE80211_HW_RX_INCLUDES_FCS | | 1665 | IEEE80211_HW_RX_INCLUDES_FCS | |
1655 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 1666 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1656 | IEEE80211_HW_SIGNAL_DBM; | 1667 | IEEE80211_HW_SIGNAL_DBM; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 07b03b3c7ef1..db2dc976d831 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -108,7 +108,10 @@ | |||
108 | #define SHORT_PIFS ( SIFS + SHORT_SLOT_TIME ) | 108 | #define SHORT_PIFS ( SIFS + SHORT_SLOT_TIME ) |
109 | #define DIFS ( PIFS + SLOT_TIME ) | 109 | #define DIFS ( PIFS + SLOT_TIME ) |
110 | #define SHORT_DIFS ( SHORT_PIFS + SHORT_SLOT_TIME ) | 110 | #define SHORT_DIFS ( SHORT_PIFS + SHORT_SLOT_TIME ) |
111 | #define EIFS ( SIFS + (8 * (IEEE80211_HEADER + ACK_SIZE)) ) | 111 | #define EIFS ( SIFS + DIFS + \ |
112 | (8 * (IEEE80211_HEADER + ACK_SIZE)) ) | ||
113 | #define SHORT_EIFS ( SIFS + SHORT_DIFS + \ | ||
114 | (8 * (IEEE80211_HEADER + ACK_SIZE)) ) | ||
112 | 115 | ||
113 | /* | 116 | /* |
114 | * Chipset identification | 117 | * Chipset identification |
@@ -597,6 +600,7 @@ enum rt2x00_flags { | |||
597 | DEVICE_STARTED_SUSPEND, | 600 | DEVICE_STARTED_SUSPEND, |
598 | DEVICE_ENABLED_RADIO, | 601 | DEVICE_ENABLED_RADIO, |
599 | DEVICE_DISABLED_RADIO_HW, | 602 | DEVICE_DISABLED_RADIO_HW, |
603 | DEVICE_DIRTY_CONFIG, | ||
600 | 604 | ||
601 | /* | 605 | /* |
602 | * Driver features | 606 | * Driver features |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index f20ca712504f..3f89516e8332 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -271,7 +271,7 @@ config: | |||
271 | libconf.sifs = SIFS; | 271 | libconf.sifs = SIFS; |
272 | libconf.pifs = short_slot_time ? SHORT_PIFS : PIFS; | 272 | libconf.pifs = short_slot_time ? SHORT_PIFS : PIFS; |
273 | libconf.difs = short_slot_time ? SHORT_DIFS : DIFS; | 273 | libconf.difs = short_slot_time ? SHORT_DIFS : DIFS; |
274 | libconf.eifs = EIFS; | 274 | libconf.eifs = short_slot_time ? SHORT_EIFS : EIFS; |
275 | } | 275 | } |
276 | 276 | ||
277 | libconf.conf = conf; | 277 | libconf.conf = conf; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 8c93eb8353b0..f42283ad7b02 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -1013,6 +1013,7 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) | |||
1013 | rt2x00dev->intf_associated = 0; | 1013 | rt2x00dev->intf_associated = 0; |
1014 | 1014 | ||
1015 | __set_bit(DEVICE_STARTED, &rt2x00dev->flags); | 1015 | __set_bit(DEVICE_STARTED, &rt2x00dev->flags); |
1016 | __set_bit(DEVICE_DIRTY_CONFIG, &rt2x00dev->flags); | ||
1016 | 1017 | ||
1017 | return 0; | 1018 | return 0; |
1018 | } | 1019 | } |
@@ -1237,9 +1238,9 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1237 | /* | 1238 | /* |
1238 | * Reconfigure device. | 1239 | * Reconfigure device. |
1239 | */ | 1240 | */ |
1240 | rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, 1); | 1241 | retval = rt2x00mac_config(rt2x00dev->hw, &rt2x00dev->hw->conf); |
1241 | if (!rt2x00dev->hw->conf.radio_enabled) | 1242 | if (retval) |
1242 | rt2x00lib_disable_radio(rt2x00dev); | 1243 | goto exit; |
1243 | 1244 | ||
1244 | /* | 1245 | /* |
1245 | * Iterator over each active interface to | 1246 | * Iterator over each active interface to |
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index f2c9b0e79b5f..c5fb3a72cf37 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -125,13 +125,6 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | |||
125 | void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | 125 | void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); |
126 | 126 | ||
127 | /** | 127 | /** |
128 | * rt2x00queue_free_skb - free a skb | ||
129 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
130 | * @skb: The skb to free. | ||
131 | */ | ||
132 | void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | ||
133 | |||
134 | /** | ||
135 | * rt2x00queue_write_tx_frame - Write TX frame to hardware | 128 | * rt2x00queue_write_tx_frame - Write TX frame to hardware |
136 | * @queue: Queue over which the frame should be send | 129 | * @queue: Queue over which the frame should be send |
137 | * @skb: The skb to send | 130 | * @skb: The skb to send |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index f1dcbaa80c3c..c3ee4ecba792 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -63,7 +63,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
63 | */ | 63 | */ |
64 | memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb)); | 64 | memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb)); |
65 | rts_info = IEEE80211_SKB_CB(skb); | 65 | rts_info = IEEE80211_SKB_CB(skb); |
66 | rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | 66 | rts_info->control.hw_key = NULL; |
67 | rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS; | 67 | rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS; |
68 | rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT; | 68 | rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT; |
69 | rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS; | 69 | rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS; |
@@ -83,6 +83,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
83 | (struct ieee80211_rts *)(skb->data)); | 83 | (struct ieee80211_rts *)(skb->data)); |
84 | 84 | ||
85 | if (rt2x00queue_write_tx_frame(queue, skb)) { | 85 | if (rt2x00queue_write_tx_frame(queue, skb)) { |
86 | dev_kfree_skb_any(skb); | ||
86 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); | 87 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); |
87 | return NETDEV_TX_BUSY; | 88 | return NETDEV_TX_BUSY; |
88 | } | 89 | } |
@@ -96,7 +97,6 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
96 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 97 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
97 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; | 98 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; |
98 | enum data_queue_qid qid = skb_get_queue_mapping(skb); | 99 | enum data_queue_qid qid = skb_get_queue_mapping(skb); |
99 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
100 | struct data_queue *queue; | 100 | struct data_queue *queue; |
101 | u16 frame_control; | 101 | u16 frame_control; |
102 | 102 | ||
@@ -152,18 +152,6 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
152 | } | 152 | } |
153 | } | 153 | } |
154 | 154 | ||
155 | /* | ||
156 | * XXX: This is as wrong as the old mac80211 code was, | ||
157 | * due to beacons not getting sequence numbers assigned | ||
158 | * properly. | ||
159 | */ | ||
160 | if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
161 | if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | ||
162 | intf->seqno += 0x10; | ||
163 | ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
164 | ieee80211hdr->seq_ctrl |= cpu_to_le16(intf->seqno); | ||
165 | } | ||
166 | |||
167 | if (rt2x00queue_write_tx_frame(queue, skb)) { | 155 | if (rt2x00queue_write_tx_frame(queue, skb)) { |
168 | ieee80211_stop_queue(rt2x00dev->hw, qid); | 156 | ieee80211_stop_queue(rt2x00dev->hw, qid); |
169 | return NETDEV_TX_BUSY; | 157 | return NETDEV_TX_BUSY; |
@@ -322,6 +310,7 @@ EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); | |||
322 | int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | 310 | int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) |
323 | { | 311 | { |
324 | struct rt2x00_dev *rt2x00dev = hw->priv; | 312 | struct rt2x00_dev *rt2x00dev = hw->priv; |
313 | int force_reconfig; | ||
325 | 314 | ||
326 | /* | 315 | /* |
327 | * Mac80211 might be calling this function while we are trying | 316 | * Mac80211 might be calling this function while we are trying |
@@ -341,7 +330,17 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | |||
341 | rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); | 330 | rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); |
342 | } | 331 | } |
343 | 332 | ||
344 | rt2x00lib_config(rt2x00dev, conf, 0); | 333 | /* |
334 | * When the DEVICE_DIRTY_CONFIG flag is set, the device has recently | ||
335 | * been started and the configuration must be forced upon the hardware. | ||
336 | * Otherwise registers will not be intialized correctly and could | ||
337 | * result in non-working hardware because essential registers aren't | ||
338 | * initialized. | ||
339 | */ | ||
340 | force_reconfig = | ||
341 | __test_and_clear_bit(DEVICE_DIRTY_CONFIG, &rt2x00dev->flags); | ||
342 | |||
343 | rt2x00lib_config(rt2x00dev, conf, force_reconfig); | ||
345 | 344 | ||
346 | /* | 345 | /* |
347 | * Reenable RX only if the radio should be on. | 346 | * Reenable RX only if the radio should be on. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 7f442030f5ad..3b27f6aa860c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -120,6 +120,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
120 | { | 120 | { |
121 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 121 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
122 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 122 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); |
123 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
123 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | 124 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; |
124 | struct ieee80211_rate *rate = | 125 | struct ieee80211_rate *rate = |
125 | ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); | 126 | ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); |
@@ -200,6 +201,31 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
200 | } | 201 | } |
201 | 202 | ||
202 | /* | 203 | /* |
204 | * Hardware should insert sequence counter. | ||
205 | * FIXME: We insert a software sequence counter first for | ||
206 | * hardware that doesn't support hardware sequence counting. | ||
207 | * | ||
208 | * This is wrong because beacons are not getting sequence | ||
209 | * numbers assigned properly. | ||
210 | * | ||
211 | * A secondary problem exists for drivers that cannot toggle | ||
212 | * sequence counting per-frame, since those will override the | ||
213 | * sequence counter given by mac80211. | ||
214 | */ | ||
215 | if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
216 | spin_lock(&intf->lock); | ||
217 | |||
218 | if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) | ||
219 | intf->seqno += 0x10; | ||
220 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
221 | hdr->seq_ctrl |= cpu_to_le16(intf->seqno); | ||
222 | |||
223 | spin_unlock(&intf->lock); | ||
224 | |||
225 | __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); | ||
226 | } | ||
227 | |||
228 | /* | ||
203 | * PLCP setup | 229 | * PLCP setup |
204 | * Length calculation depends on OFDM/CCK rate. | 230 | * Length calculation depends on OFDM/CCK rate. |
205 | */ | 231 | */ |
@@ -466,9 +492,12 @@ void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev) | |||
466 | if (!rt2x00dev->ops->lib->init_rxentry) | 492 | if (!rt2x00dev->ops->lib->init_rxentry) |
467 | return; | 493 | return; |
468 | 494 | ||
469 | for (i = 0; i < queue->limit; i++) | 495 | for (i = 0; i < queue->limit; i++) { |
496 | queue->entries[i].flags = 0; | ||
497 | |||
470 | rt2x00dev->ops->lib->init_rxentry(rt2x00dev, | 498 | rt2x00dev->ops->lib->init_rxentry(rt2x00dev, |
471 | &queue->entries[i]); | 499 | &queue->entries[i]); |
500 | } | ||
472 | } | 501 | } |
473 | 502 | ||
474 | void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev) | 503 | void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev) |
@@ -482,9 +511,12 @@ void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev) | |||
482 | if (!rt2x00dev->ops->lib->init_txentry) | 511 | if (!rt2x00dev->ops->lib->init_txentry) |
483 | continue; | 512 | continue; |
484 | 513 | ||
485 | for (i = 0; i < queue->limit; i++) | 514 | for (i = 0; i < queue->limit; i++) { |
515 | queue->entries[i].flags = 0; | ||
516 | |||
486 | rt2x00dev->ops->lib->init_txentry(rt2x00dev, | 517 | rt2x00dev->ops->lib->init_txentry(rt2x00dev, |
487 | &queue->entries[i]); | 518 | &queue->entries[i]); |
519 | } | ||
488 | } | 520 | } |
489 | } | 521 | } |
490 | 522 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 8945945c892e..a4a8c57004db 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -199,6 +199,7 @@ struct txdone_entry_desc { | |||
199 | * @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame. | 199 | * @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame. |
200 | * @ENTRY_TXD_CTS_FRAME: This frame is a CTS-to-self frame. | 200 | * @ENTRY_TXD_CTS_FRAME: This frame is a CTS-to-self frame. |
201 | * @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate. | 201 | * @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate. |
202 | * @ENTRY_TXD_GENERATE_SEQ: This frame requires sequence counter. | ||
202 | * @ENTRY_TXD_FIRST_FRAGMENT: This is the first frame. | 203 | * @ENTRY_TXD_FIRST_FRAGMENT: This is the first frame. |
203 | * @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment. | 204 | * @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment. |
204 | * @ENTRY_TXD_REQ_TIMESTAMP: Require timestamp to be inserted. | 205 | * @ENTRY_TXD_REQ_TIMESTAMP: Require timestamp to be inserted. |
@@ -210,6 +211,7 @@ enum txentry_desc_flags { | |||
210 | ENTRY_TXD_RTS_FRAME, | 211 | ENTRY_TXD_RTS_FRAME, |
211 | ENTRY_TXD_CTS_FRAME, | 212 | ENTRY_TXD_CTS_FRAME, |
212 | ENTRY_TXD_OFDM_RATE, | 213 | ENTRY_TXD_OFDM_RATE, |
214 | ENTRY_TXD_GENERATE_SEQ, | ||
213 | ENTRY_TXD_FIRST_FRAGMENT, | 215 | ENTRY_TXD_FIRST_FRAGMENT, |
214 | ENTRY_TXD_MORE_FRAG, | 216 | ENTRY_TXD_MORE_FRAG, |
215 | ENTRY_TXD_REQ_TIMESTAMP, | 217 | ENTRY_TXD_REQ_TIMESTAMP, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 83862e7f7aec..933e6cc9359d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -122,6 +122,38 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, | |||
122 | } | 122 | } |
123 | EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); | 123 | EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); |
124 | 124 | ||
125 | int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev, | ||
126 | const u8 request, const u8 requesttype, | ||
127 | const u16 offset, void *buffer, | ||
128 | const u16 buffer_length, | ||
129 | const int timeout) | ||
130 | { | ||
131 | int status = 0; | ||
132 | unsigned char *tb; | ||
133 | u16 off, len, bsize; | ||
134 | |||
135 | mutex_lock(&rt2x00dev->usb_cache_mutex); | ||
136 | |||
137 | tb = buffer; | ||
138 | off = offset; | ||
139 | len = buffer_length; | ||
140 | while (len && !status) { | ||
141 | bsize = min_t(u16, CSR_CACHE_SIZE, len); | ||
142 | status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request, | ||
143 | requesttype, off, tb, | ||
144 | bsize, timeout); | ||
145 | |||
146 | tb += bsize; | ||
147 | len -= bsize; | ||
148 | off += bsize; | ||
149 | } | ||
150 | |||
151 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
152 | |||
153 | return status; | ||
154 | } | ||
155 | EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_large_buff); | ||
156 | |||
125 | /* | 157 | /* |
126 | * TX data handlers. | 158 | * TX data handlers. |
127 | */ | 159 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index aad794adf52c..ee3875f894aa 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -70,8 +70,7 @@ | |||
70 | /* | 70 | /* |
71 | * Cache size | 71 | * Cache size |
72 | */ | 72 | */ |
73 | #define CSR_CACHE_SIZE 8 | 73 | #define CSR_CACHE_SIZE 64 |
74 | #define CSR_CACHE_SIZE_FIRMWARE 64 | ||
75 | 74 | ||
76 | /* | 75 | /* |
77 | * USB request types. | 76 | * USB request types. |
@@ -172,6 +171,25 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, | |||
172 | const u16 buffer_length, const int timeout); | 171 | const u16 buffer_length, const int timeout); |
173 | 172 | ||
174 | /** | 173 | /** |
174 | * rt2x00usb_vendor_request_large_buff - Send register command to device (buffered) | ||
175 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
176 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | ||
177 | * @requesttype: Request type &USB_VENDOR_REQUEST_* | ||
178 | * @offset: Register start offset to perform action on | ||
179 | * @buffer: Buffer where information will be read/written to by device | ||
180 | * @buffer_length: Size of &buffer | ||
181 | * @timeout: Operation timeout | ||
182 | * | ||
183 | * This function is used to transfer register data in blocks larger | ||
184 | * then CSR_CACHE_SIZE. Use for firmware upload, keys and beacons. | ||
185 | */ | ||
186 | int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev, | ||
187 | const u8 request, const u8 requesttype, | ||
188 | const u16 offset, void *buffer, | ||
189 | const u16 buffer_length, | ||
190 | const int timeout); | ||
191 | |||
192 | /** | ||
175 | * rt2x00usb_vendor_request_sw - Send single register command to device | 193 | * rt2x00usb_vendor_request_sw - Send single register command to device |
176 | * @rt2x00dev: Pointer to &struct rt2x00_dev | 194 | * @rt2x00dev: Pointer to &struct rt2x00_dev |
177 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | 195 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index f7c1f92c1448..fbe2a652e014 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1544,7 +1544,8 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1544 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); | 1544 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1545 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); | 1545 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1546 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1546 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1547 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | 1547 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, |
1548 | test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); | ||
1548 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); | 1549 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); |
1549 | rt2x00_desc_write(txd, 1, word); | 1550 | rt2x00_desc_write(txd, 1, word); |
1550 | 1551 | ||
@@ -2278,7 +2279,6 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2278 | * Initialize all hw fields. | 2279 | * Initialize all hw fields. |
2279 | */ | 2280 | */ |
2280 | rt2x00dev->hw->flags = | 2281 | rt2x00dev->hw->flags = |
2281 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | ||
2282 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 2282 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
2283 | IEEE80211_HW_SIGNAL_DBM; | 2283 | IEEE80211_HW_SIGNAL_DBM; |
2284 | rt2x00dev->hw->extra_tx_headroom = 0; | 2284 | rt2x00dev->hw->extra_tx_headroom = 0; |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index d383735ab8f2..9761eaaa08be 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -890,9 +890,6 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data, | |||
890 | unsigned int i; | 890 | unsigned int i; |
891 | int status; | 891 | int status; |
892 | u32 reg; | 892 | u32 reg; |
893 | const char *ptr = data; | ||
894 | char *cache; | ||
895 | int buflen; | ||
896 | 893 | ||
897 | /* | 894 | /* |
898 | * Wait for stable hardware. | 895 | * Wait for stable hardware. |
@@ -911,31 +908,12 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data, | |||
911 | 908 | ||
912 | /* | 909 | /* |
913 | * Write firmware to device. | 910 | * Write firmware to device. |
914 | * We setup a seperate cache for this action, | ||
915 | * since we are going to write larger chunks of data | ||
916 | * then normally used cache size. | ||
917 | */ | 911 | */ |
918 | cache = kmalloc(CSR_CACHE_SIZE_FIRMWARE, GFP_KERNEL); | 912 | rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, |
919 | if (!cache) { | 913 | USB_VENDOR_REQUEST_OUT, |
920 | ERROR(rt2x00dev, "Failed to allocate firmware cache.\n"); | 914 | FIRMWARE_IMAGE_BASE, |
921 | return -ENOMEM; | 915 | data, len, |
922 | } | 916 | REGISTER_TIMEOUT32(len)); |
923 | |||
924 | for (i = 0; i < len; i += CSR_CACHE_SIZE_FIRMWARE) { | ||
925 | buflen = min_t(int, len - i, CSR_CACHE_SIZE_FIRMWARE); | ||
926 | |||
927 | memcpy(cache, ptr, buflen); | ||
928 | |||
929 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | ||
930 | USB_VENDOR_REQUEST_OUT, | ||
931 | FIRMWARE_IMAGE_BASE + i, 0, | ||
932 | cache, buflen, | ||
933 | REGISTER_TIMEOUT32(buflen)); | ||
934 | |||
935 | ptr += buflen; | ||
936 | } | ||
937 | |||
938 | kfree(cache); | ||
939 | 917 | ||
940 | /* | 918 | /* |
941 | * Send firmware request to device to load firmware, | 919 | * Send firmware request to device to load firmware, |
@@ -1303,7 +1281,8 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1303 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); | 1281 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1304 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); | 1282 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1305 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1283 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1306 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | 1284 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, |
1285 | test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); | ||
1307 | rt2x00_desc_write(txd, 1, word); | 1286 | rt2x00_desc_write(txd, 1, word); |
1308 | 1287 | ||
1309 | rt2x00_desc_read(txd, 2, &word); | 1288 | rt2x00_desc_read(txd, 2, &word); |
@@ -1352,6 +1331,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry) | |||
1352 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 1331 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1353 | unsigned int beacon_base; | 1332 | unsigned int beacon_base; |
1354 | u32 reg; | 1333 | u32 reg; |
1334 | u32 word, len; | ||
1355 | 1335 | ||
1356 | /* | 1336 | /* |
1357 | * Add the descriptor in front of the skb. | 1337 | * Add the descriptor in front of the skb. |
@@ -1361,6 +1341,17 @@ static void rt73usb_write_beacon(struct queue_entry *entry) | |||
1361 | skbdesc->desc = entry->skb->data; | 1341 | skbdesc->desc = entry->skb->data; |
1362 | 1342 | ||
1363 | /* | 1343 | /* |
1344 | * Adjust the beacon databyte count. The current number is | ||
1345 | * calculated before this function gets called, but falsely | ||
1346 | * assumes that the descriptor was already present in the SKB. | ||
1347 | */ | ||
1348 | rt2x00_desc_read(skbdesc->desc, 0, &word); | ||
1349 | len = rt2x00_get_field32(word, TXD_W0_DATABYTE_COUNT); | ||
1350 | len += skbdesc->desc_len; | ||
1351 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, len); | ||
1352 | rt2x00_desc_write(skbdesc->desc, 0, word); | ||
1353 | |||
1354 | /* | ||
1364 | * Disable beaconing while we are reloading the beacon data, | 1355 | * Disable beaconing while we are reloading the beacon data, |
1365 | * otherwise we might be sending out invalid data. | 1356 | * otherwise we might be sending out invalid data. |
1366 | */ | 1357 | */ |
@@ -1374,10 +1365,10 @@ static void rt73usb_write_beacon(struct queue_entry *entry) | |||
1374 | * Write entire beacon with descriptor to register. | 1365 | * Write entire beacon with descriptor to register. |
1375 | */ | 1366 | */ |
1376 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | 1367 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); |
1377 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 1368 | rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, |
1378 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, | 1369 | USB_VENDOR_REQUEST_OUT, beacon_base, |
1379 | entry->skb->data, entry->skb->len, | 1370 | entry->skb->data, entry->skb->len, |
1380 | REGISTER_TIMEOUT32(entry->skb->len)); | 1371 | REGISTER_TIMEOUT32(entry->skb->len)); |
1381 | 1372 | ||
1382 | /* | 1373 | /* |
1383 | * Clean up the beacon skb. | 1374 | * Clean up the beacon skb. |
@@ -1871,7 +1862,6 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1871 | * Initialize all hw fields. | 1862 | * Initialize all hw fields. |
1872 | */ | 1863 | */ |
1873 | rt2x00dev->hw->flags = | 1864 | rt2x00dev->hw->flags = |
1874 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | ||
1875 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 1865 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1876 | IEEE80211_HW_SIGNAL_DBM; | 1866 | IEEE80211_HW_SIGNAL_DBM; |
1877 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 1867 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h index 3afb49f8866a..1b0d750f6623 100644 --- a/drivers/net/wireless/rtl8187.h +++ b/drivers/net/wireless/rtl8187.h | |||
@@ -47,11 +47,13 @@ struct rtl8187_rx_hdr { | |||
47 | struct rtl8187b_rx_hdr { | 47 | struct rtl8187b_rx_hdr { |
48 | __le32 flags; | 48 | __le32 flags; |
49 | __le64 mac_time; | 49 | __le64 mac_time; |
50 | u8 noise; | 50 | u8 sq; |
51 | u8 signal; | 51 | u8 rssi; |
52 | u8 agc; | 52 | u8 agc; |
53 | u8 reserved; | 53 | u8 flags2; |
54 | __le32 unused; | 54 | __le16 snr_long2end; |
55 | s8 pwdb_g12; | ||
56 | u8 fot; | ||
55 | } __attribute__((packed)); | 57 | } __attribute__((packed)); |
56 | 58 | ||
57 | /* {rtl8187,rtl8187b}_tx_info is in skb */ | 59 | /* {rtl8187,rtl8187b}_tx_info is in skb */ |
@@ -100,6 +102,7 @@ struct rtl8187_priv { | |||
100 | struct usb_device *udev; | 102 | struct usb_device *udev; |
101 | u32 rx_conf; | 103 | u32 rx_conf; |
102 | u16 txpwr_base; | 104 | u16 txpwr_base; |
105 | u16 seqno; | ||
103 | u8 asic_rev; | 106 | u8 asic_rev; |
104 | u8 is_rtl8187b; | 107 | u8 is_rtl8187b; |
105 | enum { | 108 | enum { |
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index d3067b1216ca..177988efd660 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c | |||
@@ -169,6 +169,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
169 | { | 169 | { |
170 | struct rtl8187_priv *priv = dev->priv; | 170 | struct rtl8187_priv *priv = dev->priv; |
171 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 171 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
172 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; | ||
172 | unsigned int ep; | 173 | unsigned int ep; |
173 | void *buf; | 174 | void *buf; |
174 | struct urb *urb; | 175 | struct urb *urb; |
@@ -234,6 +235,20 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
234 | ep = epmap[skb_get_queue_mapping(skb)]; | 235 | ep = epmap[skb_get_queue_mapping(skb)]; |
235 | } | 236 | } |
236 | 237 | ||
238 | /* FIXME: The sequence that follows is needed for this driver to | ||
239 | * work with mac80211 since "mac80211: fix TX sequence numbers". | ||
240 | * As with the temporary code in rt2x00, changes will be needed | ||
241 | * to get proper sequence numbers on beacons. In addition, this | ||
242 | * patch places the sequence number in the hardware state, which | ||
243 | * limits us to a single virtual state. | ||
244 | */ | ||
245 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
246 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | ||
247 | priv->seqno += 0x10; | ||
248 | ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
249 | ieee80211hdr->seq_ctrl |= cpu_to_le16(priv->seqno); | ||
250 | } | ||
251 | |||
237 | info->driver_data[0] = dev; | 252 | info->driver_data[0] = dev; |
238 | info->driver_data[1] = urb; | 253 | info->driver_data[1] = urb; |
239 | 254 | ||
@@ -257,6 +272,7 @@ static void rtl8187_rx_cb(struct urb *urb) | |||
257 | struct ieee80211_rx_status rx_status = { 0 }; | 272 | struct ieee80211_rx_status rx_status = { 0 }; |
258 | int rate, signal; | 273 | int rate, signal; |
259 | u32 flags; | 274 | u32 flags; |
275 | u32 quality; | ||
260 | 276 | ||
261 | spin_lock(&priv->rx_queue.lock); | 277 | spin_lock(&priv->rx_queue.lock); |
262 | if (skb->next) | 278 | if (skb->next) |
@@ -280,44 +296,57 @@ static void rtl8187_rx_cb(struct urb *urb) | |||
280 | flags = le32_to_cpu(hdr->flags); | 296 | flags = le32_to_cpu(hdr->flags); |
281 | signal = hdr->signal & 0x7f; | 297 | signal = hdr->signal & 0x7f; |
282 | rx_status.antenna = (hdr->signal >> 7) & 1; | 298 | rx_status.antenna = (hdr->signal >> 7) & 1; |
283 | rx_status.signal = signal; | ||
284 | rx_status.noise = hdr->noise; | 299 | rx_status.noise = hdr->noise; |
285 | rx_status.mactime = le64_to_cpu(hdr->mac_time); | 300 | rx_status.mactime = le64_to_cpu(hdr->mac_time); |
286 | priv->signal = signal; | ||
287 | priv->quality = signal; | 301 | priv->quality = signal; |
302 | rx_status.qual = priv->quality; | ||
288 | priv->noise = hdr->noise; | 303 | priv->noise = hdr->noise; |
304 | rate = (flags >> 20) & 0xF; | ||
305 | if (rate > 3) { /* OFDM rate */ | ||
306 | if (signal > 90) | ||
307 | signal = 90; | ||
308 | else if (signal < 25) | ||
309 | signal = 25; | ||
310 | signal = 90 - signal; | ||
311 | } else { /* CCK rate */ | ||
312 | if (signal > 95) | ||
313 | signal = 95; | ||
314 | else if (signal < 30) | ||
315 | signal = 30; | ||
316 | signal = 95 - signal; | ||
317 | } | ||
318 | rx_status.signal = signal; | ||
319 | priv->signal = signal; | ||
289 | } else { | 320 | } else { |
290 | struct rtl8187b_rx_hdr *hdr = | 321 | struct rtl8187b_rx_hdr *hdr = |
291 | (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); | 322 | (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); |
323 | /* The Realtek datasheet for the RTL8187B shows that the RX | ||
324 | * header contains the following quantities: signal quality, | ||
325 | * RSSI, AGC, the received power in dB, and the measured SNR. | ||
326 | * In testing, none of these quantities show qualitative | ||
327 | * agreement with AP signal strength, except for the AGC, | ||
328 | * which is inversely proportional to the strength of the | ||
329 | * signal. In the following, the quality and signal strength | ||
330 | * are derived from the AGC. The arbitrary scaling constants | ||
331 | * are chosen to make the results close to the values obtained | ||
332 | * for a BCM4312 using b43 as the driver. The noise is ignored | ||
333 | * for now. | ||
334 | */ | ||
292 | flags = le32_to_cpu(hdr->flags); | 335 | flags = le32_to_cpu(hdr->flags); |
293 | signal = hdr->agc >> 1; | 336 | quality = 170 - hdr->agc; |
294 | rx_status.antenna = (hdr->signal >> 7) & 1; | 337 | if (quality > 100) |
295 | rx_status.signal = 64 - min(hdr->noise, (u8)64); | 338 | quality = 100; |
296 | rx_status.noise = hdr->noise; | 339 | signal = 14 - hdr->agc / 2; |
340 | rx_status.qual = quality; | ||
341 | priv->quality = quality; | ||
342 | rx_status.signal = signal; | ||
343 | priv->signal = signal; | ||
344 | rx_status.antenna = (hdr->rssi >> 7) & 1; | ||
297 | rx_status.mactime = le64_to_cpu(hdr->mac_time); | 345 | rx_status.mactime = le64_to_cpu(hdr->mac_time); |
298 | priv->signal = hdr->signal; | 346 | rate = (flags >> 20) & 0xF; |
299 | priv->quality = hdr->agc >> 1; | ||
300 | priv->noise = hdr->noise; | ||
301 | } | 347 | } |
302 | 348 | ||
303 | skb_trim(skb, flags & 0x0FFF); | 349 | skb_trim(skb, flags & 0x0FFF); |
304 | rate = (flags >> 20) & 0xF; | ||
305 | if (rate > 3) { /* OFDM rate */ | ||
306 | if (signal > 90) | ||
307 | signal = 90; | ||
308 | else if (signal < 25) | ||
309 | signal = 25; | ||
310 | signal = 90 - signal; | ||
311 | } else { /* CCK rate */ | ||
312 | if (signal > 95) | ||
313 | signal = 95; | ||
314 | else if (signal < 30) | ||
315 | signal = 30; | ||
316 | signal = 95 - signal; | ||
317 | } | ||
318 | |||
319 | rx_status.qual = priv->quality; | ||
320 | rx_status.signal = signal; | ||
321 | rx_status.rate_idx = rate; | 350 | rx_status.rate_idx = rate; |
322 | rx_status.freq = dev->conf.channel->center_freq; | 351 | rx_status.freq = dev->conf.channel->center_freq; |
323 | rx_status.band = dev->conf.channel->band; | 352 | rx_status.band = dev->conf.channel->band; |
@@ -1015,9 +1044,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1015 | 1044 | ||
1016 | priv->mode = IEEE80211_IF_TYPE_MNTR; | 1045 | priv->mode = IEEE80211_IF_TYPE_MNTR; |
1017 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 1046 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1018 | IEEE80211_HW_RX_INCLUDES_FCS | | 1047 | IEEE80211_HW_RX_INCLUDES_FCS; |
1019 | IEEE80211_HW_SIGNAL_UNSPEC; | ||
1020 | dev->max_signal = 65; | ||
1021 | 1048 | ||
1022 | eeprom.data = dev; | 1049 | eeprom.data = dev; |
1023 | eeprom.register_read = rtl8187_eeprom_register_read; | 1050 | eeprom.register_read = rtl8187_eeprom_register_read; |
@@ -1132,10 +1159,16 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1132 | (*channel++).hw_value = txpwr >> 8; | 1159 | (*channel++).hw_value = txpwr >> 8; |
1133 | } | 1160 | } |
1134 | 1161 | ||
1135 | if (priv->is_rtl8187b) | 1162 | if (priv->is_rtl8187b) { |
1136 | printk(KERN_WARNING "rtl8187: 8187B chip detected. Support " | 1163 | printk(KERN_WARNING "rtl8187: 8187B chip detected. Support " |
1137 | "is EXPERIMENTAL, and could damage your\n" | 1164 | "is EXPERIMENTAL, and could damage your\n" |
1138 | " hardware, use at your own risk\n"); | 1165 | " hardware, use at your own risk\n"); |
1166 | dev->flags |= IEEE80211_HW_SIGNAL_DBM; | ||
1167 | } else { | ||
1168 | dev->flags |= IEEE80211_HW_SIGNAL_UNSPEC; | ||
1169 | dev->max_signal = 65; | ||
1170 | } | ||
1171 | |||
1139 | if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) | 1172 | if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) |
1140 | printk(KERN_INFO "rtl8187: inconsistency between id with OEM" | 1173 | printk(KERN_INFO "rtl8187: inconsistency between id with OEM" |
1141 | " info!\n"); | 1174 | " info!\n"); |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index fcc532bb6a7e..4d7b98b05030 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -935,7 +935,6 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | |||
935 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; | 935 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; |
936 | 936 | ||
937 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 937 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
938 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | ||
939 | IEEE80211_HW_SIGNAL_DB; | 938 | IEEE80211_HW_SIGNAL_DB; |
940 | 939 | ||
941 | hw->max_signal = 100; | 940 | hw->max_signal = 100; |
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index c5f6e54ec6ae..741d1a62cc3f 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h | |||
@@ -68,7 +68,8 @@ enum rfkill_state { | |||
68 | * @user_claim_unsupported: Whether the hardware supports exclusive | 68 | * @user_claim_unsupported: Whether the hardware supports exclusive |
69 | * RF-kill control by userspace. Set this before registering. | 69 | * RF-kill control by userspace. Set this before registering. |
70 | * @user_claim: Set when the switch is controlled exlusively by userspace. | 70 | * @user_claim: Set when the switch is controlled exlusively by userspace. |
71 | * @mutex: Guards switch state transitions | 71 | * @mutex: Guards switch state transitions. It serializes callbacks |
72 | * and also protects the state. | ||
72 | * @data: Pointer to the RF button drivers private data which will be | 73 | * @data: Pointer to the RF button drivers private data which will be |
73 | * passed along when toggling radio state. | 74 | * passed along when toggling radio state. |
74 | * @toggle_radio(): Mandatory handler to control state of the radio. | 75 | * @toggle_radio(): Mandatory handler to control state of the radio. |
@@ -89,12 +90,13 @@ struct rfkill { | |||
89 | const char *name; | 90 | const char *name; |
90 | enum rfkill_type type; | 91 | enum rfkill_type type; |
91 | 92 | ||
92 | enum rfkill_state state; | ||
93 | bool user_claim_unsupported; | 93 | bool user_claim_unsupported; |
94 | bool user_claim; | 94 | bool user_claim; |
95 | 95 | ||
96 | /* the mutex serializes callbacks and also protects | ||
97 | * the state */ | ||
96 | struct mutex mutex; | 98 | struct mutex mutex; |
97 | 99 | enum rfkill_state state; | |
98 | void *data; | 100 | void *data; |
99 | int (*toggle_radio)(void *data, enum rfkill_state state); | 101 | int (*toggle_radio)(void *data, enum rfkill_state state); |
100 | int (*get_state)(void *data, enum rfkill_state *state); | 102 | int (*get_state)(void *data, enum rfkill_state *state); |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 7ea44f6621f2..a640385e0598 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -316,7 +316,10 @@ struct sk_buff { | |||
316 | #ifdef CONFIG_IPV6_NDISC_NODETYPE | 316 | #ifdef CONFIG_IPV6_NDISC_NODETYPE |
317 | __u8 ndisc_nodetype:2; | 317 | __u8 ndisc_nodetype:2; |
318 | #endif | 318 | #endif |
319 | /* 14 bit hole */ | 319 | #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) |
320 | __u8 do_not_encrypt:1; | ||
321 | #endif | ||
322 | /* 0/13/14 bit hole */ | ||
320 | 323 | ||
321 | #ifdef CONFIG_NET_DMA | 324 | #ifdef CONFIG_NET_DMA |
322 | dma_cookie_t dma_cookie; | 325 | dma_cookie_t dma_cookie; |
diff --git a/include/linux/snmp.h b/include/linux/snmp.h index 5df62ef1280c..7a6e6bba4a71 100644 --- a/include/linux/snmp.h +++ b/include/linux/snmp.h | |||
@@ -214,6 +214,8 @@ enum | |||
214 | LINUX_MIB_TCPDSACKIGNOREDOLD, /* TCPSACKIgnoredOld */ | 214 | LINUX_MIB_TCPDSACKIGNOREDOLD, /* TCPSACKIgnoredOld */ |
215 | LINUX_MIB_TCPDSACKIGNOREDNOUNDO, /* TCPSACKIgnoredNoUndo */ | 215 | LINUX_MIB_TCPDSACKIGNOREDNOUNDO, /* TCPSACKIgnoredNoUndo */ |
216 | LINUX_MIB_TCPSPURIOUSRTOS, /* TCPSpuriousRTOs */ | 216 | LINUX_MIB_TCPSPURIOUSRTOS, /* TCPSpuriousRTOs */ |
217 | LINUX_MIB_TCPMD5NOTFOUND, /* TCPMD5NotFound */ | ||
218 | LINUX_MIB_TCPMD5UNEXPECTED, /* TCPMD5Unexpected */ | ||
217 | __LINUX_MIB_MAX | 219 | __LINUX_MIB_MAX |
218 | }; | 220 | }; |
219 | 221 | ||
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 4dd3d93e1960..b52721008be8 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -206,8 +206,6 @@ struct ieee80211_bss_conf { | |||
206 | * These flags are used with the @flags member of &ieee80211_tx_info. | 206 | * These flags are used with the @flags member of &ieee80211_tx_info. |
207 | * | 207 | * |
208 | * @IEEE80211_TX_CTL_REQ_TX_STATUS: request TX status callback for this frame. | 208 | * @IEEE80211_TX_CTL_REQ_TX_STATUS: request TX status callback for this frame. |
209 | * @IEEE80211_TX_CTL_DO_NOT_ENCRYPT: send this frame without encryption; | ||
210 | * e.g., for EAPOL frame | ||
211 | * @IEEE80211_TX_CTL_USE_RTS_CTS: use RTS-CTS before sending frame | 209 | * @IEEE80211_TX_CTL_USE_RTS_CTS: use RTS-CTS before sending frame |
212 | * @IEEE80211_TX_CTL_USE_CTS_PROTECT: use CTS protection for the frame (e.g., | 210 | * @IEEE80211_TX_CTL_USE_CTS_PROTECT: use CTS protection for the frame (e.g., |
213 | * for combined 802.11g / 802.11b networks) | 211 | * for combined 802.11g / 802.11b networks) |
@@ -220,7 +218,6 @@ struct ieee80211_bss_conf { | |||
220 | * @IEEE80211_TX_CTL_SHORT_PREAMBLE: TBD | 218 | * @IEEE80211_TX_CTL_SHORT_PREAMBLE: TBD |
221 | * @IEEE80211_TX_CTL_LONG_RETRY_LIMIT: this frame should be send using the | 219 | * @IEEE80211_TX_CTL_LONG_RETRY_LIMIT: this frame should be send using the |
222 | * through set_retry_limit configured long retry value | 220 | * through set_retry_limit configured long retry value |
223 | * @IEEE80211_TX_CTL_EAPOL_FRAME: internal to mac80211 | ||
224 | * @IEEE80211_TX_CTL_SEND_AFTER_DTIM: send this frame after DTIM beacon | 221 | * @IEEE80211_TX_CTL_SEND_AFTER_DTIM: send this frame after DTIM beacon |
225 | * @IEEE80211_TX_CTL_AMPDU: this frame should be sent as part of an A-MPDU | 222 | * @IEEE80211_TX_CTL_AMPDU: this frame should be sent as part of an A-MPDU |
226 | * @IEEE80211_TX_CTL_OFDM_HT: this frame can be sent in HT OFDM rates. number | 223 | * @IEEE80211_TX_CTL_OFDM_HT: this frame can be sent in HT OFDM rates. number |
@@ -253,7 +250,6 @@ struct ieee80211_bss_conf { | |||
253 | */ | 250 | */ |
254 | enum mac80211_tx_control_flags { | 251 | enum mac80211_tx_control_flags { |
255 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), | 252 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), |
256 | IEEE80211_TX_CTL_DO_NOT_ENCRYPT = BIT(1), | ||
257 | IEEE80211_TX_CTL_USE_RTS_CTS = BIT(2), | 253 | IEEE80211_TX_CTL_USE_RTS_CTS = BIT(2), |
258 | IEEE80211_TX_CTL_USE_CTS_PROTECT = BIT(3), | 254 | IEEE80211_TX_CTL_USE_CTS_PROTECT = BIT(3), |
259 | IEEE80211_TX_CTL_NO_ACK = BIT(4), | 255 | IEEE80211_TX_CTL_NO_ACK = BIT(4), |
@@ -263,7 +259,6 @@ enum mac80211_tx_control_flags { | |||
263 | IEEE80211_TX_CTL_FIRST_FRAGMENT = BIT(8), | 259 | IEEE80211_TX_CTL_FIRST_FRAGMENT = BIT(8), |
264 | IEEE80211_TX_CTL_SHORT_PREAMBLE = BIT(9), | 260 | IEEE80211_TX_CTL_SHORT_PREAMBLE = BIT(9), |
265 | IEEE80211_TX_CTL_LONG_RETRY_LIMIT = BIT(10), | 261 | IEEE80211_TX_CTL_LONG_RETRY_LIMIT = BIT(10), |
266 | IEEE80211_TX_CTL_EAPOL_FRAME = BIT(11), | ||
267 | IEEE80211_TX_CTL_SEND_AFTER_DTIM = BIT(12), | 262 | IEEE80211_TX_CTL_SEND_AFTER_DTIM = BIT(12), |
268 | IEEE80211_TX_CTL_AMPDU = BIT(13), | 263 | IEEE80211_TX_CTL_AMPDU = BIT(13), |
269 | IEEE80211_TX_CTL_OFDM_HT = BIT(14), | 264 | IEEE80211_TX_CTL_OFDM_HT = BIT(14), |
@@ -323,7 +318,6 @@ struct ieee80211_tx_info { | |||
323 | struct ieee80211_vif *vif; | 318 | struct ieee80211_vif *vif; |
324 | struct ieee80211_key_conf *hw_key; | 319 | struct ieee80211_key_conf *hw_key; |
325 | unsigned long jiffies; | 320 | unsigned long jiffies; |
326 | int ifindex; | ||
327 | u16 aid; | 321 | u16 aid; |
328 | s8 rts_cts_rate_idx, alt_retry_rate_idx; | 322 | s8 rts_cts_rate_idx, alt_retry_rate_idx; |
329 | u8 retry_limit; | 323 | u8 retry_limit; |
@@ -746,7 +740,6 @@ enum ieee80211_tkip_key_type { | |||
746 | * Measurement, Channel Switch, Quieting, TPC | 740 | * Measurement, Channel Switch, Quieting, TPC |
747 | */ | 741 | */ |
748 | enum ieee80211_hw_flags { | 742 | enum ieee80211_hw_flags { |
749 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE = 1<<0, | ||
750 | IEEE80211_HW_RX_INCLUDES_FCS = 1<<1, | 743 | IEEE80211_HW_RX_INCLUDES_FCS = 1<<1, |
751 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING = 1<<2, | 744 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING = 1<<2, |
752 | IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE = 1<<3, | 745 | IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE = 1<<3, |
diff --git a/net/Kconfig b/net/Kconfig index b98668751749..7612cc8c337c 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
@@ -2,9 +2,7 @@ | |||
2 | # Network configuration | 2 | # Network configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | menu "Networking" | 5 | menuconfig NET |
6 | |||
7 | config NET | ||
8 | bool "Networking support" | 6 | bool "Networking support" |
9 | ---help--- | 7 | ---help--- |
10 | Unless you really know what you are doing, you should say Y here. | 8 | Unless you really know what you are doing, you should say Y here. |
@@ -22,7 +20,6 @@ config NET | |||
22 | recommended to read the NET-HOWTO, available from | 20 | recommended to read the NET-HOWTO, available from |
23 | <http://www.tldp.org/docs.html#howto>. | 21 | <http://www.tldp.org/docs.html#howto>. |
24 | 22 | ||
25 | # Make sure that all config symbols are dependent on NET | ||
26 | if NET | 23 | if NET |
27 | 24 | ||
28 | menu "Networking options" | 25 | menu "Networking options" |
@@ -252,5 +249,3 @@ source "net/rfkill/Kconfig" | |||
252 | source "net/9p/Kconfig" | 249 | source "net/9p/Kconfig" |
253 | 250 | ||
254 | endif # if NET | 251 | endif # if NET |
255 | endmenu # Networking | ||
256 | |||
diff --git a/net/core/dev.c b/net/core/dev.c index 8d13a9b9f1df..63d6bcddbf46 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2100,7 +2100,7 @@ static int ing_filter(struct sk_buff *skb) | |||
2100 | rxq = &dev->rx_queue; | 2100 | rxq = &dev->rx_queue; |
2101 | 2101 | ||
2102 | q = rxq->qdisc; | 2102 | q = rxq->qdisc; |
2103 | if (q) { | 2103 | if (q != &noop_qdisc) { |
2104 | spin_lock(qdisc_lock(q)); | 2104 | spin_lock(qdisc_lock(q)); |
2105 | result = qdisc_enqueue_root(skb, q); | 2105 | result = qdisc_enqueue_root(skb, q); |
2106 | spin_unlock(qdisc_lock(q)); | 2106 | spin_unlock(qdisc_lock(q)); |
@@ -2113,7 +2113,7 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb, | |||
2113 | struct packet_type **pt_prev, | 2113 | struct packet_type **pt_prev, |
2114 | int *ret, struct net_device *orig_dev) | 2114 | int *ret, struct net_device *orig_dev) |
2115 | { | 2115 | { |
2116 | if (!skb->dev->rx_queue.qdisc) | 2116 | if (skb->dev->rx_queue.qdisc == &noop_qdisc) |
2117 | goto out; | 2117 | goto out; |
2118 | 2118 | ||
2119 | if (*pt_prev) { | 2119 | if (*pt_prev) { |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 4e0c92274189..84640172d65d 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -485,6 +485,9 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb) | |||
485 | C(head); | 485 | C(head); |
486 | C(data); | 486 | C(data); |
487 | C(truesize); | 487 | C(truesize); |
488 | #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) | ||
489 | C(do_not_encrypt); | ||
490 | #endif | ||
488 | atomic_set(&n->users, 1); | 491 | atomic_set(&n->users, 1); |
489 | 492 | ||
490 | atomic_inc(&(skb_shinfo(skb)->dataref)); | 493 | atomic_inc(&(skb_shinfo(skb)->dataref)); |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 834356ea99df..8f5a403f6f6b 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -232,6 +232,8 @@ static const struct snmp_mib snmp4_net_list[] = { | |||
232 | SNMP_MIB_ITEM("TCPDSACKIgnoredOld", LINUX_MIB_TCPDSACKIGNOREDOLD), | 232 | SNMP_MIB_ITEM("TCPDSACKIgnoredOld", LINUX_MIB_TCPDSACKIGNOREDOLD), |
233 | SNMP_MIB_ITEM("TCPDSACKIgnoredNoUndo", LINUX_MIB_TCPDSACKIGNOREDNOUNDO), | 233 | SNMP_MIB_ITEM("TCPDSACKIgnoredNoUndo", LINUX_MIB_TCPDSACKIGNOREDNOUNDO), |
234 | SNMP_MIB_ITEM("TCPSpuriousRTOs", LINUX_MIB_TCPSPURIOUSRTOS), | 234 | SNMP_MIB_ITEM("TCPSpuriousRTOs", LINUX_MIB_TCPSPURIOUSRTOS), |
235 | SNMP_MIB_ITEM("TCPMD5NotFound", LINUX_MIB_TCPMD5NOTFOUND), | ||
236 | SNMP_MIB_ITEM("TCPMD5Unexpected", LINUX_MIB_TCPMD5UNEXPECTED), | ||
235 | SNMP_MIB_SENTINEL | 237 | SNMP_MIB_SENTINEL |
236 | }; | 238 | }; |
237 | 239 | ||
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index a2b06d0cc26b..b3875c0d83c7 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -1116,18 +1116,12 @@ static int tcp_v4_inbound_md5_hash(struct sock *sk, struct sk_buff *skb) | |||
1116 | return 0; | 1116 | return 0; |
1117 | 1117 | ||
1118 | if (hash_expected && !hash_location) { | 1118 | if (hash_expected && !hash_location) { |
1119 | LIMIT_NETDEBUG(KERN_INFO "MD5 Hash expected but NOT found " | 1119 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND); |
1120 | "(" NIPQUAD_FMT ", %d)->(" NIPQUAD_FMT ", %d)\n", | ||
1121 | NIPQUAD(iph->saddr), ntohs(th->source), | ||
1122 | NIPQUAD(iph->daddr), ntohs(th->dest)); | ||
1123 | return 1; | 1120 | return 1; |
1124 | } | 1121 | } |
1125 | 1122 | ||
1126 | if (!hash_expected && hash_location) { | 1123 | if (!hash_expected && hash_location) { |
1127 | LIMIT_NETDEBUG(KERN_INFO "MD5 Hash NOT expected but found " | 1124 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED); |
1128 | "(" NIPQUAD_FMT ", %d)->(" NIPQUAD_FMT ", %d)\n", | ||
1129 | NIPQUAD(iph->saddr), ntohs(th->source), | ||
1130 | NIPQUAD(iph->daddr), ntohs(th->dest)); | ||
1131 | return 1; | 1125 | return 1; |
1132 | } | 1126 | } |
1133 | 1127 | ||
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index f7b535dec860..410046a8cc91 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -732,7 +732,7 @@ int datagram_send_ctl(struct net *net, | |||
732 | LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n", | 732 | LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n", |
733 | cmsg->cmsg_type); | 733 | cmsg->cmsg_type); |
734 | err = -EINVAL; | 734 | err = -EINVAL; |
735 | break; | 735 | goto exit_f; |
736 | } | 736 | } |
737 | } | 737 | } |
738 | 738 | ||
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index f82f6074cf85..0179b66864f1 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
@@ -286,7 +286,6 @@ proc_net_fail: | |||
286 | 286 | ||
287 | void ipv6_misc_proc_exit(void) | 287 | void ipv6_misc_proc_exit(void) |
288 | { | 288 | { |
289 | proc_net_remove(&init_net, "sockstat6"); | ||
290 | proc_net_remove(&init_net, "dev_snmp6"); | 289 | proc_net_remove(&init_net, "dev_snmp6"); |
291 | proc_net_remove(&init_net, "snmp6"); | 290 | proc_net_remove(&init_net, "snmp6"); |
292 | unregister_pernet_subsys(&ipv6_proc_ops); | 291 | unregister_pernet_subsys(&ipv6_proc_ops); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index cff778b23a7f..1db45216b232 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -849,28 +849,17 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb) | |||
849 | hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr); | 849 | hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr); |
850 | hash_location = tcp_parse_md5sig_option(th); | 850 | hash_location = tcp_parse_md5sig_option(th); |
851 | 851 | ||
852 | /* do we have a hash as expected? */ | 852 | /* We've parsed the options - do we have a hash? */ |
853 | if (!hash_expected) { | 853 | if (!hash_expected && !hash_location) |
854 | if (!hash_location) | 854 | return 0; |
855 | return 0; | 855 | |
856 | if (net_ratelimit()) { | 856 | if (hash_expected && !hash_location) { |
857 | printk(KERN_INFO "MD5 Hash NOT expected but found " | 857 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND); |
858 | "(" NIP6_FMT ", %u)->" | ||
859 | "(" NIP6_FMT ", %u)\n", | ||
860 | NIP6(ip6h->saddr), ntohs(th->source), | ||
861 | NIP6(ip6h->daddr), ntohs(th->dest)); | ||
862 | } | ||
863 | return 1; | 858 | return 1; |
864 | } | 859 | } |
865 | 860 | ||
866 | if (!hash_location) { | 861 | if (!hash_expected && hash_location) { |
867 | if (net_ratelimit()) { | 862 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED); |
868 | printk(KERN_INFO "MD5 Hash expected but NOT found " | ||
869 | "(" NIP6_FMT ", %u)->" | ||
870 | "(" NIP6_FMT ", %u)\n", | ||
871 | NIP6(ip6h->saddr), ntohs(th->source), | ||
872 | NIP6(ip6h->daddr), ntohs(th->dest)); | ||
873 | } | ||
874 | return 1; | 863 | return 1; |
875 | } | 864 | } |
876 | 865 | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 8e7ba0e62cf5..297c257864c7 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -81,6 +81,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex, | |||
81 | enum nl80211_iftype type, u32 *flags, | 81 | enum nl80211_iftype type, u32 *flags, |
82 | struct vif_params *params) | 82 | struct vif_params *params) |
83 | { | 83 | { |
84 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
84 | struct net_device *dev; | 85 | struct net_device *dev; |
85 | enum ieee80211_if_types itype; | 86 | enum ieee80211_if_types itype; |
86 | struct ieee80211_sub_if_data *sdata; | 87 | struct ieee80211_sub_if_data *sdata; |
@@ -95,6 +96,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex, | |||
95 | if (itype == IEEE80211_IF_TYPE_INVALID) | 96 | if (itype == IEEE80211_IF_TYPE_INVALID) |
96 | return -EINVAL; | 97 | return -EINVAL; |
97 | 98 | ||
99 | if (dev == local->mdev) | ||
100 | return -EOPNOTSUPP; | ||
101 | |||
98 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 102 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
99 | 103 | ||
100 | ret = ieee80211_if_change_type(sdata, itype); | 104 | ret = ieee80211_if_change_type(sdata, itype); |
@@ -117,12 +121,16 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
117 | u8 key_idx, u8 *mac_addr, | 121 | u8 key_idx, u8 *mac_addr, |
118 | struct key_params *params) | 122 | struct key_params *params) |
119 | { | 123 | { |
124 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
120 | struct ieee80211_sub_if_data *sdata; | 125 | struct ieee80211_sub_if_data *sdata; |
121 | struct sta_info *sta = NULL; | 126 | struct sta_info *sta = NULL; |
122 | enum ieee80211_key_alg alg; | 127 | enum ieee80211_key_alg alg; |
123 | struct ieee80211_key *key; | 128 | struct ieee80211_key *key; |
124 | int err; | 129 | int err; |
125 | 130 | ||
131 | if (dev == local->mdev) | ||
132 | return -EOPNOTSUPP; | ||
133 | |||
126 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 134 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
127 | 135 | ||
128 | switch (params->cipher) { | 136 | switch (params->cipher) { |
@@ -167,10 +175,14 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
167 | static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | 175 | static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, |
168 | u8 key_idx, u8 *mac_addr) | 176 | u8 key_idx, u8 *mac_addr) |
169 | { | 177 | { |
178 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
170 | struct ieee80211_sub_if_data *sdata; | 179 | struct ieee80211_sub_if_data *sdata; |
171 | struct sta_info *sta; | 180 | struct sta_info *sta; |
172 | int ret; | 181 | int ret; |
173 | 182 | ||
183 | if (dev == local->mdev) | ||
184 | return -EOPNOTSUPP; | ||
185 | |||
174 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 186 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
175 | 187 | ||
176 | rcu_read_lock(); | 188 | rcu_read_lock(); |
@@ -211,7 +223,8 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
211 | void (*callback)(void *cookie, | 223 | void (*callback)(void *cookie, |
212 | struct key_params *params)) | 224 | struct key_params *params)) |
213 | { | 225 | { |
214 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 226 | struct ieee80211_local *local = wiphy_priv(wiphy); |
227 | struct ieee80211_sub_if_data *sdata; | ||
215 | struct sta_info *sta = NULL; | 228 | struct sta_info *sta = NULL; |
216 | u8 seq[6] = {0}; | 229 | u8 seq[6] = {0}; |
217 | struct key_params params; | 230 | struct key_params params; |
@@ -220,6 +233,11 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
220 | u16 iv16; | 233 | u16 iv16; |
221 | int err = -ENOENT; | 234 | int err = -ENOENT; |
222 | 235 | ||
236 | if (dev == local->mdev) | ||
237 | return -EOPNOTSUPP; | ||
238 | |||
239 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
240 | |||
223 | rcu_read_lock(); | 241 | rcu_read_lock(); |
224 | 242 | ||
225 | if (mac_addr) { | 243 | if (mac_addr) { |
@@ -293,8 +311,12 @@ static int ieee80211_config_default_key(struct wiphy *wiphy, | |||
293 | struct net_device *dev, | 311 | struct net_device *dev, |
294 | u8 key_idx) | 312 | u8 key_idx) |
295 | { | 313 | { |
314 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
296 | struct ieee80211_sub_if_data *sdata; | 315 | struct ieee80211_sub_if_data *sdata; |
297 | 316 | ||
317 | if (dev == local->mdev) | ||
318 | return -EOPNOTSUPP; | ||
319 | |||
298 | rcu_read_lock(); | 320 | rcu_read_lock(); |
299 | 321 | ||
300 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 322 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
@@ -475,9 +497,15 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, | |||
475 | static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, | 497 | static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, |
476 | struct beacon_parameters *params) | 498 | struct beacon_parameters *params) |
477 | { | 499 | { |
478 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 500 | struct ieee80211_local *local = wiphy_priv(wiphy); |
501 | struct ieee80211_sub_if_data *sdata; | ||
479 | struct beacon_data *old; | 502 | struct beacon_data *old; |
480 | 503 | ||
504 | if (dev == local->mdev) | ||
505 | return -EOPNOTSUPP; | ||
506 | |||
507 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
508 | |||
481 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP) | 509 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP) |
482 | return -EINVAL; | 510 | return -EINVAL; |
483 | 511 | ||
@@ -492,9 +520,15 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, | |||
492 | static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, | 520 | static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, |
493 | struct beacon_parameters *params) | 521 | struct beacon_parameters *params) |
494 | { | 522 | { |
495 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 523 | struct ieee80211_local *local = wiphy_priv(wiphy); |
524 | struct ieee80211_sub_if_data *sdata; | ||
496 | struct beacon_data *old; | 525 | struct beacon_data *old; |
497 | 526 | ||
527 | if (dev == local->mdev) | ||
528 | return -EOPNOTSUPP; | ||
529 | |||
530 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
531 | |||
498 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP) | 532 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP) |
499 | return -EINVAL; | 533 | return -EINVAL; |
500 | 534 | ||
@@ -508,9 +542,15 @@ static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, | |||
508 | 542 | ||
509 | static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) | 543 | static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) |
510 | { | 544 | { |
511 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 545 | struct ieee80211_local *local = wiphy_priv(wiphy); |
546 | struct ieee80211_sub_if_data *sdata; | ||
512 | struct beacon_data *old; | 547 | struct beacon_data *old; |
513 | 548 | ||
549 | if (dev == local->mdev) | ||
550 | return -EOPNOTSUPP; | ||
551 | |||
552 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
553 | |||
514 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP) | 554 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP) |
515 | return -EINVAL; | 555 | return -EINVAL; |
516 | 556 | ||
@@ -646,11 +686,14 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
646 | static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | 686 | static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, |
647 | u8 *mac, struct station_parameters *params) | 687 | u8 *mac, struct station_parameters *params) |
648 | { | 688 | { |
649 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 689 | struct ieee80211_local *local = wiphy_priv(wiphy); |
650 | struct sta_info *sta; | 690 | struct sta_info *sta; |
651 | struct ieee80211_sub_if_data *sdata; | 691 | struct ieee80211_sub_if_data *sdata; |
652 | int err; | 692 | int err; |
653 | 693 | ||
694 | if (dev == local->mdev || params->vlan == local->mdev) | ||
695 | return -EOPNOTSUPP; | ||
696 | |||
654 | /* Prevent a race with changing the rate control algorithm */ | 697 | /* Prevent a race with changing the rate control algorithm */ |
655 | if (!netif_running(dev)) | 698 | if (!netif_running(dev)) |
656 | return -ENETDOWN; | 699 | return -ENETDOWN; |
@@ -701,10 +744,15 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | |||
701 | static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, | 744 | static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, |
702 | u8 *mac) | 745 | u8 *mac) |
703 | { | 746 | { |
704 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 747 | struct ieee80211_local *local = wiphy_priv(wiphy); |
705 | struct ieee80211_local *local = sdata->local; | 748 | struct ieee80211_sub_if_data *sdata; |
706 | struct sta_info *sta; | 749 | struct sta_info *sta; |
707 | 750 | ||
751 | if (dev == local->mdev) | ||
752 | return -EOPNOTSUPP; | ||
753 | |||
754 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
755 | |||
708 | if (mac) { | 756 | if (mac) { |
709 | rcu_read_lock(); | 757 | rcu_read_lock(); |
710 | 758 | ||
@@ -730,10 +778,13 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
730 | u8 *mac, | 778 | u8 *mac, |
731 | struct station_parameters *params) | 779 | struct station_parameters *params) |
732 | { | 780 | { |
733 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 781 | struct ieee80211_local *local = wiphy_priv(wiphy); |
734 | struct sta_info *sta; | 782 | struct sta_info *sta; |
735 | struct ieee80211_sub_if_data *vlansdata; | 783 | struct ieee80211_sub_if_data *vlansdata; |
736 | 784 | ||
785 | if (dev == local->mdev || params->vlan == local->mdev) | ||
786 | return -EOPNOTSUPP; | ||
787 | |||
737 | rcu_read_lock(); | 788 | rcu_read_lock(); |
738 | 789 | ||
739 | /* XXX: get sta belonging to dev */ | 790 | /* XXX: get sta belonging to dev */ |
@@ -752,7 +803,7 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
752 | return -EINVAL; | 803 | return -EINVAL; |
753 | } | 804 | } |
754 | 805 | ||
755 | sta->sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); | 806 | sta->sdata = vlansdata; |
756 | ieee80211_send_layer2_update(sta); | 807 | ieee80211_send_layer2_update(sta); |
757 | } | 808 | } |
758 | 809 | ||
@@ -767,15 +818,20 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
767 | static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev, | 818 | static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev, |
768 | u8 *dst, u8 *next_hop) | 819 | u8 *dst, u8 *next_hop) |
769 | { | 820 | { |
770 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 821 | struct ieee80211_local *local = wiphy_priv(wiphy); |
771 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 822 | struct ieee80211_sub_if_data *sdata; |
772 | struct mesh_path *mpath; | 823 | struct mesh_path *mpath; |
773 | struct sta_info *sta; | 824 | struct sta_info *sta; |
774 | int err; | 825 | int err; |
775 | 826 | ||
827 | if (dev == local->mdev) | ||
828 | return -EOPNOTSUPP; | ||
829 | |||
776 | if (!netif_running(dev)) | 830 | if (!netif_running(dev)) |
777 | return -ENETDOWN; | 831 | return -ENETDOWN; |
778 | 832 | ||
833 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
834 | |||
779 | if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) | 835 | if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) |
780 | return -ENOTSUPP; | 836 | return -ENOTSUPP; |
781 | 837 | ||
@@ -817,14 +873,19 @@ static int ieee80211_change_mpath(struct wiphy *wiphy, | |||
817 | struct net_device *dev, | 873 | struct net_device *dev, |
818 | u8 *dst, u8 *next_hop) | 874 | u8 *dst, u8 *next_hop) |
819 | { | 875 | { |
820 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 876 | struct ieee80211_local *local = wiphy_priv(wiphy); |
821 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 877 | struct ieee80211_sub_if_data *sdata; |
822 | struct mesh_path *mpath; | 878 | struct mesh_path *mpath; |
823 | struct sta_info *sta; | 879 | struct sta_info *sta; |
824 | 880 | ||
881 | if (dev == local->mdev) | ||
882 | return -EOPNOTSUPP; | ||
883 | |||
825 | if (!netif_running(dev)) | 884 | if (!netif_running(dev)) |
826 | return -ENETDOWN; | 885 | return -ENETDOWN; |
827 | 886 | ||
887 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
888 | |||
828 | if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) | 889 | if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) |
829 | return -ENOTSUPP; | 890 | return -ENOTSUPP; |
830 | 891 | ||
@@ -891,9 +952,15 @@ static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev, | |||
891 | u8 *dst, u8 *next_hop, struct mpath_info *pinfo) | 952 | u8 *dst, u8 *next_hop, struct mpath_info *pinfo) |
892 | 953 | ||
893 | { | 954 | { |
894 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 955 | struct ieee80211_local *local = wiphy_priv(wiphy); |
956 | struct ieee80211_sub_if_data *sdata; | ||
895 | struct mesh_path *mpath; | 957 | struct mesh_path *mpath; |
896 | 958 | ||
959 | if (dev == local->mdev) | ||
960 | return -EOPNOTSUPP; | ||
961 | |||
962 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
963 | |||
897 | if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) | 964 | if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) |
898 | return -ENOTSUPP; | 965 | return -ENOTSUPP; |
899 | 966 | ||
@@ -913,9 +980,15 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev, | |||
913 | int idx, u8 *dst, u8 *next_hop, | 980 | int idx, u8 *dst, u8 *next_hop, |
914 | struct mpath_info *pinfo) | 981 | struct mpath_info *pinfo) |
915 | { | 982 | { |
916 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 983 | struct ieee80211_local *local = wiphy_priv(wiphy); |
984 | struct ieee80211_sub_if_data *sdata; | ||
917 | struct mesh_path *mpath; | 985 | struct mesh_path *mpath; |
918 | 986 | ||
987 | if (dev == local->mdev) | ||
988 | return -EOPNOTSUPP; | ||
989 | |||
990 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
991 | |||
919 | if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) | 992 | if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) |
920 | return -ENOTSUPP; | 993 | return -ENOTSUPP; |
921 | 994 | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index f1a83d450ea0..a4c5b90de769 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -1233,18 +1233,12 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1233 | /* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to | 1233 | /* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to |
1234 | * make a prepared TX frame (one that has been given to hw) to look like brand | 1234 | * make a prepared TX frame (one that has been given to hw) to look like brand |
1235 | * new IEEE 802.11 frame that is ready to go through TX processing again. | 1235 | * new IEEE 802.11 frame that is ready to go through TX processing again. |
1236 | * Also, tx_packet_data in cb is restored from tx_control. */ | 1236 | */ |
1237 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, | 1237 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, |
1238 | struct ieee80211_key *key, | 1238 | struct ieee80211_key *key, |
1239 | struct sk_buff *skb) | 1239 | struct sk_buff *skb) |
1240 | { | 1240 | { |
1241 | int hdrlen, iv_len, mic_len; | 1241 | int hdrlen, iv_len, mic_len; |
1242 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1243 | |||
1244 | info->flags &= IEEE80211_TX_CTL_REQ_TX_STATUS | | ||
1245 | IEEE80211_TX_CTL_DO_NOT_ENCRYPT | | ||
1246 | IEEE80211_TX_CTL_REQUEUE | | ||
1247 | IEEE80211_TX_CTL_EAPOL_FRAME; | ||
1248 | 1242 | ||
1249 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1243 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
1250 | 1244 | ||
@@ -1731,8 +1725,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1731 | result = ieee80211_wep_init(local); | 1725 | result = ieee80211_wep_init(local); |
1732 | 1726 | ||
1733 | if (result < 0) { | 1727 | if (result < 0) { |
1734 | printk(KERN_DEBUG "%s: Failed to initialize wep\n", | 1728 | printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n", |
1735 | wiphy_name(local->hw.wiphy)); | 1729 | wiphy_name(local->hw.wiphy), result); |
1736 | goto fail_wep; | 1730 | goto fail_wep; |
1737 | } | 1731 | } |
1738 | 1732 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d7c371e36bf0..acb04133a95d 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -606,7 +606,6 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, | |||
606 | int encrypt) | 606 | int encrypt) |
607 | { | 607 | { |
608 | struct ieee80211_sub_if_data *sdata; | 608 | struct ieee80211_sub_if_data *sdata; |
609 | struct ieee80211_tx_info *info; | ||
610 | 609 | ||
611 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 610 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
612 | skb->dev = sdata->local->mdev; | 611 | skb->dev = sdata->local->mdev; |
@@ -614,11 +613,8 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, | |||
614 | skb_set_network_header(skb, 0); | 613 | skb_set_network_header(skb, 0); |
615 | skb_set_transport_header(skb, 0); | 614 | skb_set_transport_header(skb, 0); |
616 | 615 | ||
617 | info = IEEE80211_SKB_CB(skb); | 616 | skb->iif = sdata->dev->ifindex; |
618 | memset(info, 0, sizeof(struct ieee80211_tx_info)); | 617 | skb->do_not_encrypt = !encrypt; |
619 | info->control.ifindex = sdata->dev->ifindex; | ||
620 | if (!encrypt) | ||
621 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | ||
622 | 618 | ||
623 | dev_queue_xmit(skb); | 619 | dev_queue_xmit(skb); |
624 | } | 620 | } |
@@ -3303,6 +3299,7 @@ void ieee80211_start_mesh(struct net_device *dev) | |||
3303 | ifsta = &sdata->u.sta; | 3299 | ifsta = &sdata->u.sta; |
3304 | ifsta->state = IEEE80211_MESH_UP; | 3300 | ifsta->state = IEEE80211_MESH_UP; |
3305 | ieee80211_sta_timer((unsigned long)sdata); | 3301 | ieee80211_sta_timer((unsigned long)sdata); |
3302 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); | ||
3306 | } | 3303 | } |
3307 | #endif | 3304 | #endif |
3308 | 3305 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 0fbadd8b983c..69019e943873 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -305,7 +305,7 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
305 | rcu_read_unlock(); | 305 | rcu_read_unlock(); |
306 | 306 | ||
307 | local->total_ps_buffered = total; | 307 | local->total_ps_buffered = total; |
308 | #ifdef MAC80211_VERBOSE_PS_DEBUG | 308 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
309 | printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n", | 309 | printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n", |
310 | wiphy_name(local->hw.wiphy), purged); | 310 | wiphy_name(local->hw.wiphy), purged); |
311 | #endif | 311 | #endif |
@@ -342,7 +342,7 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
342 | purge_old_ps_buffers(tx->local); | 342 | purge_old_ps_buffers(tx->local); |
343 | if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= | 343 | if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= |
344 | AP_MAX_BC_BUFFER) { | 344 | AP_MAX_BC_BUFFER) { |
345 | #ifdef MAC80211_VERBOSE_PS_DEBUG | 345 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
346 | if (net_ratelimit()) { | 346 | if (net_ratelimit()) { |
347 | printk(KERN_DEBUG "%s: BC TX buffer full - " | 347 | printk(KERN_DEBUG "%s: BC TX buffer full - " |
348 | "dropping the oldest frame\n", | 348 | "dropping the oldest frame\n", |
@@ -389,7 +389,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
389 | purge_old_ps_buffers(tx->local); | 389 | purge_old_ps_buffers(tx->local); |
390 | if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) { | 390 | if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) { |
391 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf); | 391 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf); |
392 | #ifdef MAC80211_VERBOSE_PS_DEBUG | 392 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
393 | if (net_ratelimit()) { | 393 | if (net_ratelimit()) { |
394 | printk(KERN_DEBUG "%s: STA %s TX " | 394 | printk(KERN_DEBUG "%s: STA %s TX " |
395 | "buffer full - dropping oldest frame\n", | 395 | "buffer full - dropping oldest frame\n", |
@@ -439,14 +439,14 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
439 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 439 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
440 | u16 fc = tx->fc; | 440 | u16 fc = tx->fc; |
441 | 441 | ||
442 | if (unlikely(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)) | 442 | if (unlikely(tx->skb->do_not_encrypt)) |
443 | tx->key = NULL; | 443 | tx->key = NULL; |
444 | else if (tx->sta && (key = rcu_dereference(tx->sta->key))) | 444 | else if (tx->sta && (key = rcu_dereference(tx->sta->key))) |
445 | tx->key = key; | 445 | tx->key = key; |
446 | else if ((key = rcu_dereference(tx->sdata->default_key))) | 446 | else if ((key = rcu_dereference(tx->sdata->default_key))) |
447 | tx->key = key; | 447 | tx->key = key; |
448 | else if (tx->sdata->drop_unencrypted && | 448 | else if (tx->sdata->drop_unencrypted && |
449 | !(info->flags & IEEE80211_TX_CTL_EAPOL_FRAME) && | 449 | (tx->skb->protocol != cpu_to_be16(ETH_P_PAE)) && |
450 | !(info->flags & IEEE80211_TX_CTL_INJECTED)) { | 450 | !(info->flags & IEEE80211_TX_CTL_INJECTED)) { |
451 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); | 451 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); |
452 | return TX_DROP; | 452 | return TX_DROP; |
@@ -476,7 +476,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
476 | } | 476 | } |
477 | 477 | ||
478 | if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | 478 | if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) |
479 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | 479 | tx->skb->do_not_encrypt = 1; |
480 | 480 | ||
481 | return TX_CONTINUE; | 481 | return TX_CONTINUE; |
482 | } | 482 | } |
@@ -732,6 +732,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
732 | memcpy(skb_put(frag, copylen), pos, copylen); | 732 | memcpy(skb_put(frag, copylen), pos, copylen); |
733 | memcpy(frag->cb, first->cb, sizeof(frag->cb)); | 733 | memcpy(frag->cb, first->cb, sizeof(frag->cb)); |
734 | skb_copy_queue_mapping(frag, first); | 734 | skb_copy_queue_mapping(frag, first); |
735 | frag->do_not_encrypt = first->do_not_encrypt; | ||
735 | 736 | ||
736 | pos += copylen; | 737 | pos += copylen; |
737 | left -= copylen; | 738 | left -= copylen; |
@@ -852,7 +853,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
852 | 853 | ||
853 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 854 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
854 | 855 | ||
855 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | 856 | skb->do_not_encrypt = 1; |
856 | info->flags |= IEEE80211_TX_CTL_INJECTED; | 857 | info->flags |= IEEE80211_TX_CTL_INJECTED; |
857 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; | 858 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; |
858 | 859 | ||
@@ -925,8 +926,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
925 | skb_trim(skb, skb->len - FCS_LEN); | 926 | skb_trim(skb, skb->len - FCS_LEN); |
926 | } | 927 | } |
927 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) | 928 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) |
928 | info->flags &= | 929 | tx->skb->do_not_encrypt = 0; |
929 | ~IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | ||
930 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) | 930 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) |
931 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 931 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
932 | break; | 932 | break; |
@@ -1042,10 +1042,9 @@ static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
1042 | struct sk_buff *skb, | 1042 | struct sk_buff *skb, |
1043 | struct net_device *mdev) | 1043 | struct net_device *mdev) |
1044 | { | 1044 | { |
1045 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1046 | struct net_device *dev; | 1045 | struct net_device *dev; |
1047 | 1046 | ||
1048 | dev = dev_get_by_index(&init_net, info->control.ifindex); | 1047 | dev = dev_get_by_index(&init_net, skb->iif); |
1049 | if (unlikely(dev && !is_ieee80211_device(dev, mdev))) { | 1048 | if (unlikely(dev && !is_ieee80211_device(dev, mdev))) { |
1050 | dev_put(dev); | 1049 | dev_put(dev); |
1051 | dev = NULL; | 1050 | dev = NULL; |
@@ -1306,8 +1305,8 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, | |||
1306 | bool may_encrypt; | 1305 | bool may_encrypt; |
1307 | int ret; | 1306 | int ret; |
1308 | 1307 | ||
1309 | if (info->control.ifindex) | 1308 | if (skb->iif) |
1310 | odev = dev_get_by_index(&init_net, info->control.ifindex); | 1309 | odev = dev_get_by_index(&init_net, skb->iif); |
1311 | if (unlikely(odev && !is_ieee80211_device(odev, dev))) { | 1310 | if (unlikely(odev && !is_ieee80211_device(odev, dev))) { |
1312 | dev_put(odev); | 1311 | dev_put(odev); |
1313 | odev = NULL; | 1312 | odev = NULL; |
@@ -1321,9 +1320,13 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, | |||
1321 | return 0; | 1320 | return 0; |
1322 | } | 1321 | } |
1323 | 1322 | ||
1323 | memset(info, 0, sizeof(*info)); | ||
1324 | |||
1325 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1326 | |||
1324 | osdata = IEEE80211_DEV_TO_SUB_IF(odev); | 1327 | osdata = IEEE80211_DEV_TO_SUB_IF(odev); |
1325 | 1328 | ||
1326 | may_encrypt = !(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT); | 1329 | may_encrypt = !skb->do_not_encrypt; |
1327 | 1330 | ||
1328 | headroom = osdata->local->tx_headroom; | 1331 | headroom = osdata->local->tx_headroom; |
1329 | if (may_encrypt) | 1332 | if (may_encrypt) |
@@ -1348,7 +1351,6 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1348 | struct net_device *dev) | 1351 | struct net_device *dev) |
1349 | { | 1352 | { |
1350 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1353 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1351 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1352 | struct ieee80211_radiotap_header *prthdr = | 1354 | struct ieee80211_radiotap_header *prthdr = |
1353 | (struct ieee80211_radiotap_header *)skb->data; | 1355 | (struct ieee80211_radiotap_header *)skb->data; |
1354 | u16 len_rthdr; | 1356 | u16 len_rthdr; |
@@ -1371,11 +1373,11 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1371 | skb->dev = local->mdev; | 1373 | skb->dev = local->mdev; |
1372 | 1374 | ||
1373 | /* needed because we set skb device to master */ | 1375 | /* needed because we set skb device to master */ |
1374 | info->control.ifindex = dev->ifindex; | 1376 | skb->iif = dev->ifindex; |
1375 | 1377 | ||
1376 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | 1378 | /* sometimes we do encrypt injected frames, will be fixed |
1377 | /* Interfaces should always request a status report */ | 1379 | * up in radiotap parser if not wanted */ |
1378 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | 1380 | skb->do_not_encrypt = 0; |
1379 | 1381 | ||
1380 | /* | 1382 | /* |
1381 | * fix up the pointers accounting for the radiotap | 1383 | * fix up the pointers accounting for the radiotap |
@@ -1419,7 +1421,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1419 | struct net_device *dev) | 1421 | struct net_device *dev) |
1420 | { | 1422 | { |
1421 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1423 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1422 | struct ieee80211_tx_info *info; | ||
1423 | struct ieee80211_sub_if_data *sdata; | 1424 | struct ieee80211_sub_if_data *sdata; |
1424 | int ret = 1, head_need; | 1425 | int ret = 1, head_need; |
1425 | u16 ethertype, hdrlen, meshhdrlen = 0; | 1426 | u16 ethertype, hdrlen, meshhdrlen = 0; |
@@ -1645,14 +1646,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1645 | nh_pos += hdrlen; | 1646 | nh_pos += hdrlen; |
1646 | h_pos += hdrlen; | 1647 | h_pos += hdrlen; |
1647 | 1648 | ||
1648 | info = IEEE80211_SKB_CB(skb); | 1649 | skb->iif = dev->ifindex; |
1649 | memset(info, 0, sizeof(*info)); | ||
1650 | info->control.ifindex = dev->ifindex; | ||
1651 | if (ethertype == ETH_P_PAE) | ||
1652 | info->flags |= IEEE80211_TX_CTL_EAPOL_FRAME; | ||
1653 | |||
1654 | /* Interfaces should always request a status report */ | ||
1655 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1656 | 1650 | ||
1657 | skb->dev = local->mdev; | 1651 | skb->dev = local->mdev; |
1658 | dev->stats.tx_packets++; | 1652 | dev->stats.tx_packets++; |
@@ -1922,6 +1916,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1922 | 1916 | ||
1923 | info = IEEE80211_SKB_CB(skb); | 1917 | info = IEEE80211_SKB_CB(skb); |
1924 | 1918 | ||
1919 | skb->do_not_encrypt = 1; | ||
1920 | |||
1925 | info->band = band; | 1921 | info->band = band; |
1926 | rate_control_get_rate(local->mdev, sband, skb, &rsel); | 1922 | rate_control_get_rate(local->mdev, sband, skb, &rsel); |
1927 | 1923 | ||
@@ -1931,7 +1927,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1931 | "no rate found\n", | 1927 | "no rate found\n", |
1932 | wiphy_name(local->hw.wiphy)); | 1928 | wiphy_name(local->hw.wiphy)); |
1933 | } | 1929 | } |
1934 | dev_kfree_skb(skb); | 1930 | dev_kfree_skb_any(skb); |
1935 | skb = NULL; | 1931 | skb = NULL; |
1936 | goto out; | 1932 | goto out; |
1937 | } | 1933 | } |
@@ -1940,7 +1936,6 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1940 | info->tx_rate_idx = rsel.rate_idx; | 1936 | info->tx_rate_idx = rsel.rate_idx; |
1941 | 1937 | ||
1942 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | 1938 | info->flags |= IEEE80211_TX_CTL_NO_ACK; |
1943 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | ||
1944 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | 1939 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
1945 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | 1940 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
1946 | if (sdata->bss_conf.use_short_preamble && | 1941 | if (sdata->bss_conf.use_short_preamble && |
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 872d2fcd1a5b..5c2bf0a3d4db 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
@@ -31,13 +31,13 @@ int ieee80211_wep_init(struct ieee80211_local *local) | |||
31 | local->wep_tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, | 31 | local->wep_tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, |
32 | CRYPTO_ALG_ASYNC); | 32 | CRYPTO_ALG_ASYNC); |
33 | if (IS_ERR(local->wep_tx_tfm)) | 33 | if (IS_ERR(local->wep_tx_tfm)) |
34 | return -ENOMEM; | 34 | return PTR_ERR(local->wep_tx_tfm); |
35 | 35 | ||
36 | local->wep_rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, | 36 | local->wep_rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, |
37 | CRYPTO_ALG_ASYNC); | 37 | CRYPTO_ALG_ASYNC); |
38 | if (IS_ERR(local->wep_rx_tfm)) { | 38 | if (IS_ERR(local->wep_rx_tfm)) { |
39 | crypto_free_blkcipher(local->wep_tx_tfm); | 39 | crypto_free_blkcipher(local->wep_tx_tfm); |
40 | return -ENOMEM; | 40 | return PTR_ERR(local->wep_rx_tfm); |
41 | } | 41 | } |
42 | 42 | ||
43 | return 0; | 43 | return 0; |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 07edda0b8a5c..28437f0001db 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -188,6 +188,9 @@ int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, | |||
188 | { | 188 | { |
189 | int i; | 189 | int i; |
190 | 190 | ||
191 | /* XXX: currently broken due to cb/requeue use */ | ||
192 | return -EPERM; | ||
193 | |||
191 | /* prepare the filter and save it for the SW queue | 194 | /* prepare the filter and save it for the SW queue |
192 | * matching the received HW queue */ | 195 | * matching the received HW queue */ |
193 | 196 | ||
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 7a560b785097..c6f2f388cb72 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c | |||
@@ -130,7 +130,6 @@ static void update_rfkill_state(struct rfkill *rfkill) | |||
130 | 130 | ||
131 | /** | 131 | /** |
132 | * rfkill_toggle_radio - wrapper for toggle_radio hook | 132 | * rfkill_toggle_radio - wrapper for toggle_radio hook |
133 | * | ||
134 | * @rfkill: the rfkill struct to use | 133 | * @rfkill: the rfkill struct to use |
135 | * @force: calls toggle_radio even if cache says it is not needed, | 134 | * @force: calls toggle_radio even if cache says it is not needed, |
136 | * and also makes sure notifications of the state will be | 135 | * and also makes sure notifications of the state will be |
@@ -141,8 +140,8 @@ static void update_rfkill_state(struct rfkill *rfkill) | |||
141 | * calls and handling all the red tape such as issuing notifications | 140 | * calls and handling all the red tape such as issuing notifications |
142 | * if the call is successful. | 141 | * if the call is successful. |
143 | * | 142 | * |
144 | * Note that @force cannot override a (possibly cached) state of | 143 | * Note that the @force parameter cannot override a (possibly cached) |
145 | * RFKILL_STATE_HARD_BLOCKED. Any device making use of | 144 | * state of RFKILL_STATE_HARD_BLOCKED. Any device making use of |
146 | * RFKILL_STATE_HARD_BLOCKED implements either get_state() or | 145 | * RFKILL_STATE_HARD_BLOCKED implements either get_state() or |
147 | * rfkill_force_state(), so the cache either is bypassed or valid. | 146 | * rfkill_force_state(), so the cache either is bypassed or valid. |
148 | * | 147 | * |
@@ -150,7 +149,7 @@ static void update_rfkill_state(struct rfkill *rfkill) | |||
150 | * even if the radio is in RFKILL_STATE_HARD_BLOCKED state, so as to | 149 | * even if the radio is in RFKILL_STATE_HARD_BLOCKED state, so as to |
151 | * give the driver a hint that it should double-BLOCK the transmitter. | 150 | * give the driver a hint that it should double-BLOCK the transmitter. |
152 | * | 151 | * |
153 | * Caller must have aquired rfkill_mutex. | 152 | * Caller must have acquired rfkill->mutex. |
154 | */ | 153 | */ |
155 | static int rfkill_toggle_radio(struct rfkill *rfkill, | 154 | static int rfkill_toggle_radio(struct rfkill *rfkill, |
156 | enum rfkill_state state, | 155 | enum rfkill_state state, |
@@ -200,12 +199,12 @@ static int rfkill_toggle_radio(struct rfkill *rfkill, | |||
200 | 199 | ||
201 | /** | 200 | /** |
202 | * rfkill_switch_all - Toggle state of all switches of given type | 201 | * rfkill_switch_all - Toggle state of all switches of given type |
203 | * @type: type of interfaces to be affeceted | 202 | * @type: type of interfaces to be affected |
204 | * @state: the new state | 203 | * @state: the new state |
205 | * | 204 | * |
206 | * This function toggles state of all switches of given type unless | 205 | * This function toggles the state of all switches of given type, |
207 | * a specific switch is claimed by userspace in which case it is | 206 | * unless a specific switch is claimed by userspace (in which case, |
208 | * left alone. | 207 | * that switch is left alone). |
209 | */ | 208 | */ |
210 | void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) | 209 | void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) |
211 | { | 210 | { |
@@ -216,8 +215,11 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) | |||
216 | rfkill_states[type] = state; | 215 | rfkill_states[type] = state; |
217 | 216 | ||
218 | list_for_each_entry(rfkill, &rfkill_list, node) { | 217 | list_for_each_entry(rfkill, &rfkill_list, node) { |
219 | if ((!rfkill->user_claim) && (rfkill->type == type)) | 218 | if ((!rfkill->user_claim) && (rfkill->type == type)) { |
219 | mutex_lock(&rfkill->mutex); | ||
220 | rfkill_toggle_radio(rfkill, state, 0); | 220 | rfkill_toggle_radio(rfkill, state, 0); |
221 | mutex_unlock(&rfkill->mutex); | ||
222 | } | ||
221 | } | 223 | } |
222 | 224 | ||
223 | mutex_unlock(&rfkill_mutex); | 225 | mutex_unlock(&rfkill_mutex); |
@@ -228,7 +230,7 @@ EXPORT_SYMBOL(rfkill_switch_all); | |||
228 | * rfkill_epo - emergency power off all transmitters | 230 | * rfkill_epo - emergency power off all transmitters |
229 | * | 231 | * |
230 | * This kicks all rfkill devices to RFKILL_STATE_SOFT_BLOCKED, ignoring | 232 | * This kicks all rfkill devices to RFKILL_STATE_SOFT_BLOCKED, ignoring |
231 | * everything in its path but rfkill_mutex. | 233 | * everything in its path but rfkill_mutex and rfkill->mutex. |
232 | */ | 234 | */ |
233 | void rfkill_epo(void) | 235 | void rfkill_epo(void) |
234 | { | 236 | { |
@@ -236,7 +238,9 @@ void rfkill_epo(void) | |||
236 | 238 | ||
237 | mutex_lock(&rfkill_mutex); | 239 | mutex_lock(&rfkill_mutex); |
238 | list_for_each_entry(rfkill, &rfkill_list, node) { | 240 | list_for_each_entry(rfkill, &rfkill_list, node) { |
241 | mutex_lock(&rfkill->mutex); | ||
239 | rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); | 242 | rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); |
243 | mutex_unlock(&rfkill->mutex); | ||
240 | } | 244 | } |
241 | mutex_unlock(&rfkill_mutex); | 245 | mutex_unlock(&rfkill_mutex); |
242 | } | 246 | } |
@@ -252,7 +256,12 @@ EXPORT_SYMBOL_GPL(rfkill_epo); | |||
252 | * a notification by the firmware/hardware of the current *real* | 256 | * a notification by the firmware/hardware of the current *real* |
253 | * state of the radio rfkill switch. | 257 | * state of the radio rfkill switch. |
254 | * | 258 | * |
255 | * It may not be called from an atomic context. | 259 | * Devices which are subject to external changes on their rfkill |
260 | * state (such as those caused by a hardware rfkill line) MUST | ||
261 | * have their driver arrange to call rfkill_force_state() as soon | ||
262 | * as possible after such a change. | ||
263 | * | ||
264 | * This function may not be called from an atomic context. | ||
256 | */ | 265 | */ |
257 | int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state) | 266 | int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state) |
258 | { | 267 | { |
@@ -367,6 +376,9 @@ static ssize_t rfkill_claim_store(struct device *dev, | |||
367 | if (!capable(CAP_NET_ADMIN)) | 376 | if (!capable(CAP_NET_ADMIN)) |
368 | return -EPERM; | 377 | return -EPERM; |
369 | 378 | ||
379 | if (rfkill->user_claim_unsupported) | ||
380 | return -EOPNOTSUPP; | ||
381 | |||
370 | /* | 382 | /* |
371 | * Take the global lock to make sure the kernel is not in | 383 | * Take the global lock to make sure the kernel is not in |
372 | * the middle of rfkill_switch_all | 384 | * the middle of rfkill_switch_all |
@@ -375,19 +387,17 @@ static ssize_t rfkill_claim_store(struct device *dev, | |||
375 | if (error) | 387 | if (error) |
376 | return error; | 388 | return error; |
377 | 389 | ||
378 | if (rfkill->user_claim_unsupported) { | ||
379 | error = -EOPNOTSUPP; | ||
380 | goto out_unlock; | ||
381 | } | ||
382 | if (rfkill->user_claim != claim) { | 390 | if (rfkill->user_claim != claim) { |
383 | if (!claim) | 391 | if (!claim) { |
392 | mutex_lock(&rfkill->mutex); | ||
384 | rfkill_toggle_radio(rfkill, | 393 | rfkill_toggle_radio(rfkill, |
385 | rfkill_states[rfkill->type], | 394 | rfkill_states[rfkill->type], |
386 | 0); | 395 | 0); |
396 | mutex_unlock(&rfkill->mutex); | ||
397 | } | ||
387 | rfkill->user_claim = claim; | 398 | rfkill->user_claim = claim; |
388 | } | 399 | } |
389 | 400 | ||
390 | out_unlock: | ||
391 | mutex_unlock(&rfkill_mutex); | 401 | mutex_unlock(&rfkill_mutex); |
392 | 402 | ||
393 | return error ? error : count; | 403 | return error ? error : count; |
@@ -516,8 +526,11 @@ static void rfkill_remove_switch(struct rfkill *rfkill) | |||
516 | { | 526 | { |
517 | mutex_lock(&rfkill_mutex); | 527 | mutex_lock(&rfkill_mutex); |
518 | list_del_init(&rfkill->node); | 528 | list_del_init(&rfkill->node); |
519 | rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); | ||
520 | mutex_unlock(&rfkill_mutex); | 529 | mutex_unlock(&rfkill_mutex); |
530 | |||
531 | mutex_lock(&rfkill->mutex); | ||
532 | rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); | ||
533 | mutex_unlock(&rfkill->mutex); | ||
521 | } | 534 | } |
522 | 535 | ||
523 | /** | 536 | /** |
@@ -526,9 +539,10 @@ static void rfkill_remove_switch(struct rfkill *rfkill) | |||
526 | * @type: type of the switch (RFKILL_TYPE_*) | 539 | * @type: type of the switch (RFKILL_TYPE_*) |
527 | * | 540 | * |
528 | * This function should be called by the network driver when it needs | 541 | * This function should be called by the network driver when it needs |
529 | * rfkill structure. Once the structure is allocated the driver shoud | 542 | * rfkill structure. Once the structure is allocated the driver should |
530 | * finish its initialization by setting name, private data, enable_radio | 543 | * finish its initialization by setting the name, private data, enable_radio |
531 | * and disable_radio methods and then register it with rfkill_register(). | 544 | * and disable_radio methods and then register it with rfkill_register(). |
545 | * | ||
532 | * NOTE: If registration fails the structure shoudl be freed by calling | 546 | * NOTE: If registration fails the structure shoudl be freed by calling |
533 | * rfkill_free() otherwise rfkill_unregister() should be used. | 547 | * rfkill_free() otherwise rfkill_unregister() should be used. |
534 | */ | 548 | */ |
@@ -560,7 +574,7 @@ EXPORT_SYMBOL(rfkill_allocate); | |||
560 | * rfkill_free - Mark rfkill structure for deletion | 574 | * rfkill_free - Mark rfkill structure for deletion |
561 | * @rfkill: rfkill structure to be destroyed | 575 | * @rfkill: rfkill structure to be destroyed |
562 | * | 576 | * |
563 | * Decrements reference count of rfkill structure so it is destroyed. | 577 | * Decrements reference count of the rfkill structure so it is destroyed. |
564 | * Note that rfkill_free() should _not_ be called after rfkill_unregister(). | 578 | * Note that rfkill_free() should _not_ be called after rfkill_unregister(). |
565 | */ | 579 | */ |
566 | void rfkill_free(struct rfkill *rfkill) | 580 | void rfkill_free(struct rfkill *rfkill) |
@@ -585,8 +599,10 @@ static void rfkill_led_trigger_register(struct rfkill *rfkill) | |||
585 | static void rfkill_led_trigger_unregister(struct rfkill *rfkill) | 599 | static void rfkill_led_trigger_unregister(struct rfkill *rfkill) |
586 | { | 600 | { |
587 | #ifdef CONFIG_RFKILL_LEDS | 601 | #ifdef CONFIG_RFKILL_LEDS |
588 | if (rfkill->led_trigger.name) | 602 | if (rfkill->led_trigger.name) { |
589 | led_trigger_unregister(&rfkill->led_trigger); | 603 | led_trigger_unregister(&rfkill->led_trigger); |
604 | rfkill->led_trigger.name = NULL; | ||
605 | } | ||
590 | #endif | 606 | #endif |
591 | } | 607 | } |
592 | 608 | ||
@@ -622,8 +638,8 @@ int rfkill_register(struct rfkill *rfkill) | |||
622 | 638 | ||
623 | error = device_add(dev); | 639 | error = device_add(dev); |
624 | if (error) { | 640 | if (error) { |
625 | rfkill_led_trigger_unregister(rfkill); | ||
626 | rfkill_remove_switch(rfkill); | 641 | rfkill_remove_switch(rfkill); |
642 | rfkill_led_trigger_unregister(rfkill); | ||
627 | return error; | 643 | return error; |
628 | } | 644 | } |
629 | 645 | ||
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index b0601642e227..4840aff47256 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -572,44 +572,21 @@ static u32 qdisc_alloc_handle(struct net_device *dev) | |||
572 | static struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue, | 572 | static struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue, |
573 | struct Qdisc *qdisc) | 573 | struct Qdisc *qdisc) |
574 | { | 574 | { |
575 | struct Qdisc *oqdisc = dev_queue->qdisc_sleeping; | ||
575 | spinlock_t *root_lock; | 576 | spinlock_t *root_lock; |
576 | struct Qdisc *oqdisc; | ||
577 | int ingress; | ||
578 | |||
579 | ingress = 0; | ||
580 | if (qdisc && qdisc->flags&TCQ_F_INGRESS) | ||
581 | ingress = 1; | ||
582 | |||
583 | if (ingress) { | ||
584 | oqdisc = dev_queue->qdisc; | ||
585 | } else { | ||
586 | oqdisc = dev_queue->qdisc_sleeping; | ||
587 | } | ||
588 | 577 | ||
589 | root_lock = qdisc_root_lock(oqdisc); | 578 | root_lock = qdisc_root_lock(oqdisc); |
590 | spin_lock_bh(root_lock); | 579 | spin_lock_bh(root_lock); |
591 | 580 | ||
592 | if (ingress) { | 581 | /* Prune old scheduler */ |
593 | /* Prune old scheduler */ | 582 | if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1) |
594 | if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1) { | 583 | qdisc_reset(oqdisc); |
595 | /* delete */ | ||
596 | qdisc_reset(oqdisc); | ||
597 | dev_queue->qdisc = NULL; | ||
598 | } else { /* new */ | ||
599 | dev_queue->qdisc = qdisc; | ||
600 | } | ||
601 | 584 | ||
602 | } else { | 585 | /* ... and graft new one */ |
603 | /* Prune old scheduler */ | 586 | if (qdisc == NULL) |
604 | if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1) | 587 | qdisc = &noop_qdisc; |
605 | qdisc_reset(oqdisc); | 588 | dev_queue->qdisc_sleeping = qdisc; |
606 | 589 | dev_queue->qdisc = &noop_qdisc; | |
607 | /* ... and graft new one */ | ||
608 | if (qdisc == NULL) | ||
609 | qdisc = &noop_qdisc; | ||
610 | dev_queue->qdisc_sleeping = qdisc; | ||
611 | dev_queue->qdisc = &noop_qdisc; | ||
612 | } | ||
613 | 590 | ||
614 | spin_unlock_bh(root_lock); | 591 | spin_unlock_bh(root_lock); |
615 | 592 | ||
@@ -678,7 +655,8 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, | |||
678 | 655 | ||
679 | ingress = 0; | 656 | ingress = 0; |
680 | num_q = dev->num_tx_queues; | 657 | num_q = dev->num_tx_queues; |
681 | if (q && q->flags & TCQ_F_INGRESS) { | 658 | if ((q && q->flags & TCQ_F_INGRESS) || |
659 | (new && new->flags & TCQ_F_INGRESS)) { | ||
682 | num_q = 1; | 660 | num_q = 1; |
683 | ingress = 1; | 661 | ingress = 1; |
684 | } | 662 | } |
@@ -692,13 +670,10 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, | |||
692 | if (!ingress) | 670 | if (!ingress) |
693 | dev_queue = netdev_get_tx_queue(dev, i); | 671 | dev_queue = netdev_get_tx_queue(dev, i); |
694 | 672 | ||
695 | if (ingress) { | 673 | old = dev_graft_qdisc(dev_queue, new); |
696 | old = dev_graft_qdisc(dev_queue, q); | 674 | if (new && i > 0) |
697 | } else { | 675 | atomic_inc(&new->refcnt); |
698 | old = dev_graft_qdisc(dev_queue, new); | 676 | |
699 | if (new && i > 0) | ||
700 | atomic_inc(&new->refcnt); | ||
701 | } | ||
702 | notify_and_destroy(skb, n, classid, old, new); | 677 | notify_and_destroy(skb, n, classid, old, new); |
703 | } | 678 | } |
704 | 679 | ||
@@ -817,7 +792,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue, | |||
817 | goto err_out3; | 792 | goto err_out3; |
818 | } | 793 | } |
819 | } | 794 | } |
820 | if (parent) | 795 | if (parent && !(sch->flags & TCQ_F_INGRESS)) |
821 | list_add_tail(&sch->list, &dev_queue->qdisc->list); | 796 | list_add_tail(&sch->list, &dev_queue->qdisc->list); |
822 | 797 | ||
823 | return sch; | 798 | return sch; |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index fd2a6cadb115..345838a2e369 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -596,7 +596,7 @@ static void transition_one_qdisc(struct net_device *dev, | |||
596 | int *need_watchdog_p = _need_watchdog; | 596 | int *need_watchdog_p = _need_watchdog; |
597 | 597 | ||
598 | rcu_assign_pointer(dev_queue->qdisc, new_qdisc); | 598 | rcu_assign_pointer(dev_queue->qdisc, new_qdisc); |
599 | if (new_qdisc != &noqueue_qdisc) | 599 | if (need_watchdog_p && new_qdisc != &noqueue_qdisc) |
600 | *need_watchdog_p = 1; | 600 | *need_watchdog_p = 1; |
601 | } | 601 | } |
602 | 602 | ||
@@ -619,6 +619,7 @@ void dev_activate(struct net_device *dev) | |||
619 | 619 | ||
620 | need_watchdog = 0; | 620 | need_watchdog = 0; |
621 | netdev_for_each_tx_queue(dev, transition_one_qdisc, &need_watchdog); | 621 | netdev_for_each_tx_queue(dev, transition_one_qdisc, &need_watchdog); |
622 | transition_one_qdisc(dev, &dev->rx_queue, NULL); | ||
622 | 623 | ||
623 | if (need_watchdog) { | 624 | if (need_watchdog) { |
624 | dev->trans_start = jiffies; | 625 | dev->trans_start = jiffies; |
@@ -677,6 +678,7 @@ void dev_deactivate(struct net_device *dev) | |||
677 | bool running; | 678 | bool running; |
678 | 679 | ||
679 | netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc); | 680 | netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc); |
681 | dev_deactivate_queue(dev, &dev->rx_queue, &noop_qdisc); | ||
680 | 682 | ||
681 | dev_watchdog_down(dev); | 683 | dev_watchdog_down(dev); |
682 | 684 | ||
@@ -718,7 +720,7 @@ static void dev_init_scheduler_queue(struct net_device *dev, | |||
718 | void dev_init_scheduler(struct net_device *dev) | 720 | void dev_init_scheduler(struct net_device *dev) |
719 | { | 721 | { |
720 | netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc); | 722 | netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc); |
721 | dev_init_scheduler_queue(dev, &dev->rx_queue, NULL); | 723 | dev_init_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc); |
722 | 724 | ||
723 | setup_timer(&dev->watchdog_timer, dev_watchdog, (unsigned long)dev); | 725 | setup_timer(&dev->watchdog_timer, dev_watchdog, (unsigned long)dev); |
724 | } | 726 | } |
@@ -745,6 +747,6 @@ static void shutdown_scheduler_queue(struct net_device *dev, | |||
745 | void dev_shutdown(struct net_device *dev) | 747 | void dev_shutdown(struct net_device *dev) |
746 | { | 748 | { |
747 | netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc); | 749 | netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc); |
748 | shutdown_scheduler_queue(dev, &dev->rx_queue, NULL); | 750 | shutdown_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc); |
749 | WARN_ON(timer_pending(&dev->watchdog_timer)); | 751 | WARN_ON(timer_pending(&dev->watchdog_timer)); |
750 | } | 752 | } |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index b7fefffd2d0d..59eb2cf42e5f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -29,16 +29,16 @@ static struct genl_family nl80211_fam = { | |||
29 | }; | 29 | }; |
30 | 30 | ||
31 | /* internal helper: get drv and dev */ | 31 | /* internal helper: get drv and dev */ |
32 | static int get_drv_dev_by_info_ifindex(struct genl_info *info, | 32 | static int get_drv_dev_by_info_ifindex(struct nlattr **attrs, |
33 | struct cfg80211_registered_device **drv, | 33 | struct cfg80211_registered_device **drv, |
34 | struct net_device **dev) | 34 | struct net_device **dev) |
35 | { | 35 | { |
36 | int ifindex; | 36 | int ifindex; |
37 | 37 | ||
38 | if (!info->attrs[NL80211_ATTR_IFINDEX]) | 38 | if (!attrs[NL80211_ATTR_IFINDEX]) |
39 | return -EINVAL; | 39 | return -EINVAL; |
40 | 40 | ||
41 | ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); | 41 | ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); |
42 | *dev = dev_get_by_index(&init_net, ifindex); | 42 | *dev = dev_get_by_index(&init_net, ifindex); |
43 | if (!*dev) | 43 | if (!*dev) |
44 | return -ENODEV; | 44 | return -ENODEV; |
@@ -291,21 +291,31 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * | |||
291 | 291 | ||
292 | mutex_lock(&cfg80211_drv_mutex); | 292 | mutex_lock(&cfg80211_drv_mutex); |
293 | list_for_each_entry(dev, &cfg80211_drv_list, list) { | 293 | list_for_each_entry(dev, &cfg80211_drv_list, list) { |
294 | if (++wp_idx < wp_start) | 294 | if (wp_idx < wp_start) { |
295 | wp_idx++; | ||
295 | continue; | 296 | continue; |
297 | } | ||
296 | if_idx = 0; | 298 | if_idx = 0; |
297 | 299 | ||
298 | mutex_lock(&dev->devlist_mtx); | 300 | mutex_lock(&dev->devlist_mtx); |
299 | list_for_each_entry(wdev, &dev->netdev_list, list) { | 301 | list_for_each_entry(wdev, &dev->netdev_list, list) { |
300 | if (++if_idx < if_start) | 302 | if (if_idx < if_start) { |
303 | if_idx++; | ||
301 | continue; | 304 | continue; |
305 | } | ||
302 | if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid, | 306 | if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid, |
303 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 307 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
304 | wdev->netdev) < 0) | 308 | wdev->netdev) < 0) { |
305 | break; | 309 | mutex_unlock(&dev->devlist_mtx); |
310 | goto out; | ||
311 | } | ||
312 | if_idx++; | ||
306 | } | 313 | } |
307 | mutex_unlock(&dev->devlist_mtx); | 314 | mutex_unlock(&dev->devlist_mtx); |
315 | |||
316 | wp_idx++; | ||
308 | } | 317 | } |
318 | out: | ||
309 | mutex_unlock(&cfg80211_drv_mutex); | 319 | mutex_unlock(&cfg80211_drv_mutex); |
310 | 320 | ||
311 | cb->args[0] = wp_idx; | 321 | cb->args[0] = wp_idx; |
@@ -321,7 +331,7 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) | |||
321 | struct net_device *netdev; | 331 | struct net_device *netdev; |
322 | int err; | 332 | int err; |
323 | 333 | ||
324 | err = get_drv_dev_by_info_ifindex(info, &dev, &netdev); | 334 | err = get_drv_dev_by_info_ifindex(info->attrs, &dev, &netdev); |
325 | if (err) | 335 | if (err) |
326 | return err; | 336 | return err; |
327 | 337 | ||
@@ -392,7 +402,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) | |||
392 | } else | 402 | } else |
393 | return -EINVAL; | 403 | return -EINVAL; |
394 | 404 | ||
395 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 405 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
396 | if (err) | 406 | if (err) |
397 | return err; | 407 | return err; |
398 | ifindex = dev->ifindex; | 408 | ifindex = dev->ifindex; |
@@ -477,7 +487,7 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) | |||
477 | int ifindex, err; | 487 | int ifindex, err; |
478 | struct net_device *dev; | 488 | struct net_device *dev; |
479 | 489 | ||
480 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 490 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
481 | if (err) | 491 | if (err) |
482 | return err; | 492 | return err; |
483 | ifindex = dev->ifindex; | 493 | ifindex = dev->ifindex; |
@@ -545,7 +555,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) | |||
545 | if (info->attrs[NL80211_ATTR_MAC]) | 555 | if (info->attrs[NL80211_ATTR_MAC]) |
546 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 556 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); |
547 | 557 | ||
548 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 558 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
549 | if (err) | 559 | if (err) |
550 | return err; | 560 | return err; |
551 | 561 | ||
@@ -618,7 +628,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) | |||
618 | if (!info->attrs[NL80211_ATTR_KEY_DEFAULT]) | 628 | if (!info->attrs[NL80211_ATTR_KEY_DEFAULT]) |
619 | return -EINVAL; | 629 | return -EINVAL; |
620 | 630 | ||
621 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 631 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
622 | if (err) | 632 | if (err) |
623 | return err; | 633 | return err; |
624 | 634 | ||
@@ -699,7 +709,7 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) | |||
699 | return -EINVAL; | 709 | return -EINVAL; |
700 | } | 710 | } |
701 | 711 | ||
702 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 712 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
703 | if (err) | 713 | if (err) |
704 | return err; | 714 | return err; |
705 | 715 | ||
@@ -735,7 +745,7 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) | |||
735 | if (info->attrs[NL80211_ATTR_MAC]) | 745 | if (info->attrs[NL80211_ATTR_MAC]) |
736 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 746 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); |
737 | 747 | ||
738 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 748 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
739 | if (err) | 749 | if (err) |
740 | return err; | 750 | return err; |
741 | 751 | ||
@@ -764,7 +774,7 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) | |||
764 | struct beacon_parameters params; | 774 | struct beacon_parameters params; |
765 | int haveinfo = 0; | 775 | int haveinfo = 0; |
766 | 776 | ||
767 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 777 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
768 | if (err) | 778 | if (err) |
769 | return err; | 779 | return err; |
770 | 780 | ||
@@ -843,7 +853,7 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) | |||
843 | int err; | 853 | int err; |
844 | struct net_device *dev; | 854 | struct net_device *dev; |
845 | 855 | ||
846 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 856 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
847 | if (err) | 857 | if (err) |
848 | return err; | 858 | return err; |
849 | 859 | ||
@@ -937,67 +947,78 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, | |||
937 | } | 947 | } |
938 | 948 | ||
939 | static int nl80211_dump_station(struct sk_buff *skb, | 949 | static int nl80211_dump_station(struct sk_buff *skb, |
940 | struct netlink_callback *cb) | 950 | struct netlink_callback *cb) |
941 | { | 951 | { |
942 | int wp_idx = 0; | ||
943 | int if_idx = 0; | ||
944 | int sta_idx = cb->args[2]; | ||
945 | int wp_start = cb->args[0]; | ||
946 | int if_start = cb->args[1]; | ||
947 | struct station_info sinfo; | 952 | struct station_info sinfo; |
948 | struct cfg80211_registered_device *dev; | 953 | struct cfg80211_registered_device *dev; |
949 | struct wireless_dev *wdev; | 954 | struct net_device *netdev; |
950 | u8 mac_addr[ETH_ALEN]; | 955 | u8 mac_addr[ETH_ALEN]; |
956 | int ifidx = cb->args[0]; | ||
957 | int sta_idx = cb->args[1]; | ||
951 | int err; | 958 | int err; |
952 | int exit = 0; | ||
953 | 959 | ||
954 | /* TODO: filter by device */ | 960 | if (!ifidx) { |
955 | mutex_lock(&cfg80211_drv_mutex); | 961 | err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, |
956 | list_for_each_entry(dev, &cfg80211_drv_list, list) { | 962 | nl80211_fam.attrbuf, nl80211_fam.maxattr, |
957 | if (exit) | 963 | nl80211_policy); |
964 | if (err) | ||
965 | return err; | ||
966 | |||
967 | if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]) | ||
968 | return -EINVAL; | ||
969 | |||
970 | ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]); | ||
971 | if (!ifidx) | ||
972 | return -EINVAL; | ||
973 | } | ||
974 | |||
975 | netdev = dev_get_by_index(&init_net, ifidx); | ||
976 | if (!netdev) | ||
977 | return -ENODEV; | ||
978 | |||
979 | dev = cfg80211_get_dev_from_ifindex(ifidx); | ||
980 | if (IS_ERR(dev)) { | ||
981 | err = PTR_ERR(dev); | ||
982 | goto out_put_netdev; | ||
983 | } | ||
984 | |||
985 | if (!dev->ops->dump_station) { | ||
986 | err = -ENOSYS; | ||
987 | goto out_err; | ||
988 | } | ||
989 | |||
990 | rtnl_lock(); | ||
991 | |||
992 | while (1) { | ||
993 | err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx, | ||
994 | mac_addr, &sinfo); | ||
995 | if (err == -ENOENT) | ||
958 | break; | 996 | break; |
959 | if (++wp_idx < wp_start) | 997 | if (err) |
960 | continue; | 998 | goto out_err_rtnl; |
961 | if_idx = 0; | ||
962 | 999 | ||
963 | mutex_lock(&dev->devlist_mtx); | 1000 | if (nl80211_send_station(skb, |
964 | list_for_each_entry(wdev, &dev->netdev_list, list) { | 1001 | NETLINK_CB(cb->skb).pid, |
965 | if (exit) | 1002 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
966 | break; | 1003 | netdev, mac_addr, |
967 | if (++if_idx < if_start) | 1004 | &sinfo) < 0) |
968 | continue; | 1005 | goto out; |
969 | if (!dev->ops->dump_station) | ||
970 | continue; | ||
971 | 1006 | ||
972 | for (;; ++sta_idx) { | 1007 | sta_idx++; |
973 | rtnl_lock(); | ||
974 | err = dev->ops->dump_station(&dev->wiphy, | ||
975 | wdev->netdev, sta_idx, mac_addr, | ||
976 | &sinfo); | ||
977 | rtnl_unlock(); | ||
978 | if (err) { | ||
979 | sta_idx = 0; | ||
980 | break; | ||
981 | } | ||
982 | if (nl80211_send_station(skb, | ||
983 | NETLINK_CB(cb->skb).pid, | ||
984 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | ||
985 | wdev->netdev, mac_addr, | ||
986 | &sinfo) < 0) { | ||
987 | exit = 1; | ||
988 | break; | ||
989 | } | ||
990 | } | ||
991 | } | ||
992 | mutex_unlock(&dev->devlist_mtx); | ||
993 | } | 1008 | } |
994 | mutex_unlock(&cfg80211_drv_mutex); | ||
995 | 1009 | ||
996 | cb->args[0] = wp_idx; | ||
997 | cb->args[1] = if_idx; | ||
998 | cb->args[2] = sta_idx; | ||
999 | 1010 | ||
1000 | return skb->len; | 1011 | out: |
1012 | cb->args[1] = sta_idx; | ||
1013 | err = skb->len; | ||
1014 | out_err_rtnl: | ||
1015 | rtnl_unlock(); | ||
1016 | out_err: | ||
1017 | cfg80211_put_dev(dev); | ||
1018 | out_put_netdev: | ||
1019 | dev_put(netdev); | ||
1020 | |||
1021 | return err; | ||
1001 | } | 1022 | } |
1002 | 1023 | ||
1003 | static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) | 1024 | static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) |
@@ -1016,7 +1037,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) | |||
1016 | 1037 | ||
1017 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 1038 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); |
1018 | 1039 | ||
1019 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 1040 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
1020 | if (err) | 1041 | if (err) |
1021 | return err; | 1042 | return err; |
1022 | 1043 | ||
@@ -1112,7 +1133,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
1112 | params.plink_action = | 1133 | params.plink_action = |
1113 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); | 1134 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); |
1114 | 1135 | ||
1115 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 1136 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
1116 | if (err) | 1137 | if (err) |
1117 | return err; | 1138 | return err; |
1118 | 1139 | ||
@@ -1172,7 +1193,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
1172 | ¶ms.station_flags)) | 1193 | ¶ms.station_flags)) |
1173 | return -EINVAL; | 1194 | return -EINVAL; |
1174 | 1195 | ||
1175 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 1196 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
1176 | if (err) | 1197 | if (err) |
1177 | return err; | 1198 | return err; |
1178 | 1199 | ||
@@ -1207,7 +1228,7 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) | |||
1207 | if (info->attrs[NL80211_ATTR_MAC]) | 1228 | if (info->attrs[NL80211_ATTR_MAC]) |
1208 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 1229 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); |
1209 | 1230 | ||
1210 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 1231 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
1211 | if (err) | 1232 | if (err) |
1212 | return err; | 1233 | return err; |
1213 | 1234 | ||
@@ -1277,68 +1298,78 @@ static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq, | |||
1277 | } | 1298 | } |
1278 | 1299 | ||
1279 | static int nl80211_dump_mpath(struct sk_buff *skb, | 1300 | static int nl80211_dump_mpath(struct sk_buff *skb, |
1280 | struct netlink_callback *cb) | 1301 | struct netlink_callback *cb) |
1281 | { | 1302 | { |
1282 | int wp_idx = 0; | ||
1283 | int if_idx = 0; | ||
1284 | int sta_idx = cb->args[2]; | ||
1285 | int wp_start = cb->args[0]; | ||
1286 | int if_start = cb->args[1]; | ||
1287 | struct mpath_info pinfo; | 1303 | struct mpath_info pinfo; |
1288 | struct cfg80211_registered_device *dev; | 1304 | struct cfg80211_registered_device *dev; |
1289 | struct wireless_dev *wdev; | 1305 | struct net_device *netdev; |
1290 | u8 dst[ETH_ALEN]; | 1306 | u8 dst[ETH_ALEN]; |
1291 | u8 next_hop[ETH_ALEN]; | 1307 | u8 next_hop[ETH_ALEN]; |
1308 | int ifidx = cb->args[0]; | ||
1309 | int path_idx = cb->args[1]; | ||
1292 | int err; | 1310 | int err; |
1293 | int exit = 0; | ||
1294 | 1311 | ||
1295 | /* TODO: filter by device */ | 1312 | if (!ifidx) { |
1296 | mutex_lock(&cfg80211_drv_mutex); | 1313 | err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, |
1297 | list_for_each_entry(dev, &cfg80211_drv_list, list) { | 1314 | nl80211_fam.attrbuf, nl80211_fam.maxattr, |
1298 | if (exit) | 1315 | nl80211_policy); |
1316 | if (err) | ||
1317 | return err; | ||
1318 | |||
1319 | if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]) | ||
1320 | return -EINVAL; | ||
1321 | |||
1322 | ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]); | ||
1323 | if (!ifidx) | ||
1324 | return -EINVAL; | ||
1325 | } | ||
1326 | |||
1327 | netdev = dev_get_by_index(&init_net, ifidx); | ||
1328 | if (!netdev) | ||
1329 | return -ENODEV; | ||
1330 | |||
1331 | dev = cfg80211_get_dev_from_ifindex(ifidx); | ||
1332 | if (IS_ERR(dev)) { | ||
1333 | err = PTR_ERR(dev); | ||
1334 | goto out_put_netdev; | ||
1335 | } | ||
1336 | |||
1337 | if (!dev->ops->dump_mpath) { | ||
1338 | err = -ENOSYS; | ||
1339 | goto out_err; | ||
1340 | } | ||
1341 | |||
1342 | rtnl_lock(); | ||
1343 | |||
1344 | while (1) { | ||
1345 | err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx, | ||
1346 | dst, next_hop, &pinfo); | ||
1347 | if (err == -ENOENT) | ||
1299 | break; | 1348 | break; |
1300 | if (++wp_idx < wp_start) | 1349 | if (err) |
1301 | continue; | 1350 | goto out_err_rtnl; |
1302 | if_idx = 0; | ||
1303 | 1351 | ||
1304 | mutex_lock(&dev->devlist_mtx); | 1352 | if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid, |
1305 | list_for_each_entry(wdev, &dev->netdev_list, list) { | 1353 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
1306 | if (exit) | 1354 | netdev, dst, next_hop, |
1307 | break; | 1355 | &pinfo) < 0) |
1308 | if (++if_idx < if_start) | 1356 | goto out; |
1309 | continue; | ||
1310 | if (!dev->ops->dump_mpath) | ||
1311 | continue; | ||
1312 | 1357 | ||
1313 | for (;; ++sta_idx) { | 1358 | path_idx++; |
1314 | rtnl_lock(); | ||
1315 | err = dev->ops->dump_mpath(&dev->wiphy, | ||
1316 | wdev->netdev, sta_idx, dst, | ||
1317 | next_hop, &pinfo); | ||
1318 | rtnl_unlock(); | ||
1319 | if (err) { | ||
1320 | sta_idx = 0; | ||
1321 | break; | ||
1322 | } | ||
1323 | if (nl80211_send_mpath(skb, | ||
1324 | NETLINK_CB(cb->skb).pid, | ||
1325 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | ||
1326 | wdev->netdev, dst, next_hop, | ||
1327 | &pinfo) < 0) { | ||
1328 | exit = 1; | ||
1329 | break; | ||
1330 | } | ||
1331 | } | ||
1332 | } | ||
1333 | mutex_unlock(&dev->devlist_mtx); | ||
1334 | } | 1359 | } |
1335 | mutex_unlock(&cfg80211_drv_mutex); | ||
1336 | 1360 | ||
1337 | cb->args[0] = wp_idx; | ||
1338 | cb->args[1] = if_idx; | ||
1339 | cb->args[2] = sta_idx; | ||
1340 | 1361 | ||
1341 | return skb->len; | 1362 | out: |
1363 | cb->args[1] = path_idx; | ||
1364 | err = skb->len; | ||
1365 | out_err_rtnl: | ||
1366 | rtnl_unlock(); | ||
1367 | out_err: | ||
1368 | cfg80211_put_dev(dev); | ||
1369 | out_put_netdev: | ||
1370 | dev_put(netdev); | ||
1371 | |||
1372 | return err; | ||
1342 | } | 1373 | } |
1343 | 1374 | ||
1344 | static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) | 1375 | static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) |
@@ -1358,7 +1389,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) | |||
1358 | 1389 | ||
1359 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); | 1390 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); |
1360 | 1391 | ||
1361 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 1392 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
1362 | if (err) | 1393 | if (err) |
1363 | return err; | 1394 | return err; |
1364 | 1395 | ||
@@ -1411,7 +1442,7 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info) | |||
1411 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); | 1442 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); |
1412 | next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); | 1443 | next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); |
1413 | 1444 | ||
1414 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 1445 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
1415 | if (err) | 1446 | if (err) |
1416 | return err; | 1447 | return err; |
1417 | 1448 | ||
@@ -1446,7 +1477,7 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) | |||
1446 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); | 1477 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); |
1447 | next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); | 1478 | next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); |
1448 | 1479 | ||
1449 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 1480 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
1450 | if (err) | 1481 | if (err) |
1451 | return err; | 1482 | return err; |
1452 | 1483 | ||
@@ -1475,7 +1506,7 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) | |||
1475 | if (info->attrs[NL80211_ATTR_MAC]) | 1506 | if (info->attrs[NL80211_ATTR_MAC]) |
1476 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); | 1507 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); |
1477 | 1508 | ||
1478 | err = get_drv_dev_by_info_ifindex(info, &drv, &dev); | 1509 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
1479 | if (err) | 1510 | if (err) |
1480 | return err; | 1511 | return err; |
1481 | 1512 | ||