diff options
46 files changed, 673 insertions, 404 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/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/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/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/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/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 | ||
