aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c275
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h19
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c4
3 files changed, 249 insertions, 49 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 94cc3354f3a6..2ed327a8d690 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -52,6 +52,7 @@
52#include <linux/ethtool.h> 52#include <linux/ethtool.h>
53#include <linux/uaccess.h> 53#include <linux/uaccess.h>
54#include <linux/slab.h> 54#include <linux/slab.h>
55#include <linux/etherdevice.h>
55 56
56#include <net/ieee80211_radiotap.h> 57#include <net/ieee80211_radiotap.h>
57 58
@@ -509,8 +510,71 @@ ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
509 } 510 }
510} 511}
511 512
513struct ath_vif_iter_data {
514 const u8 *hw_macaddr;
515 u8 mask[ETH_ALEN];
516 u8 active_mac[ETH_ALEN]; /* first active MAC */
517 bool need_set_hw_addr;
518 bool found_active;
519 bool any_assoc;
520};
521
522static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
523{
524 struct ath_vif_iter_data *iter_data = data;
525 int i;
526
527 if (iter_data->hw_macaddr)
528 for (i = 0; i < ETH_ALEN; i++)
529 iter_data->mask[i] &=
530 ~(iter_data->hw_macaddr[i] ^ mac[i]);
531
532 if (!iter_data->found_active) {
533 iter_data->found_active = true;
534 memcpy(iter_data->active_mac, mac, ETH_ALEN);
535 }
536
537 if (iter_data->need_set_hw_addr && iter_data->hw_macaddr)
538 if (compare_ether_addr(iter_data->hw_macaddr, mac) == 0)
539 iter_data->need_set_hw_addr = false;
540
541 if (!iter_data->any_assoc) {
542 struct ath5k_vif *avf = (void *)vif->drv_priv;
543 if (avf->assoc)
544 iter_data->any_assoc = true;
545 }
546}
547
548void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif)
549{
550 struct ath_common *common = ath5k_hw_common(sc->ah);
551 struct ath_vif_iter_data iter_data;
552
553 /*
554 * Use the hardware MAC address as reference, the hardware uses it
555 * together with the BSSID mask when matching addresses.
556 */
557 iter_data.hw_macaddr = common->macaddr;
558 memset(&iter_data.mask, 0xff, ETH_ALEN);
559 iter_data.found_active = false;
560 iter_data.need_set_hw_addr = true;
561
562 if (vif)
563 ath_vif_iter(&iter_data, vif->addr, vif);
564
565 /* Get list of all active MAC addresses */
566 ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter,
567 &iter_data);
568 memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN);
569
570 if (iter_data.need_set_hw_addr && iter_data.found_active)
571 ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac);
572
573 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
574}
575
512static void 576static void
513ath5k_mode_setup(struct ath5k_softc *sc) 577ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif)
514{ 578{
515 struct ath5k_hw *ah = sc->ah; 579 struct ath5k_hw *ah = sc->ah;
516 u32 rfilt; 580 u32 rfilt;
@@ -520,7 +584,7 @@ ath5k_mode_setup(struct ath5k_softc *sc)
520 ath5k_hw_set_rx_filter(ah, rfilt); 584 ath5k_hw_set_rx_filter(ah, rfilt);
521 585
522 if (ath5k_hw_hasbssidmask(ah)) 586 if (ath5k_hw_hasbssidmask(ah))
523 ath5k_hw_set_bssid_mask(ah, sc->bssidmask); 587 ath5k_update_bssid_mask(sc, vif);
524 588
525 /* configure operational mode */ 589 /* configure operational mode */
526 ath5k_hw_set_opmode(ah, sc->opmode); 590 ath5k_hw_set_opmode(ah, sc->opmode);
@@ -698,13 +762,13 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
698 flags |= AR5K_TXDESC_RTSENA; 762 flags |= AR5K_TXDESC_RTSENA;
699 cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; 763 cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
700 duration = le16_to_cpu(ieee80211_rts_duration(sc->hw, 764 duration = le16_to_cpu(ieee80211_rts_duration(sc->hw,
701 sc->vif, pktlen, info)); 765 info->control.vif, pktlen, info));
702 } 766 }
703 if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { 767 if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
704 flags |= AR5K_TXDESC_CTSENA; 768 flags |= AR5K_TXDESC_CTSENA;
705 cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; 769 cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
706 duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw, 770 duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw,
707 sc->vif, pktlen, info)); 771 info->control.vif, pktlen, info));
708 } 772 }
709 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 773 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
710 ieee80211_get_hdrlen_from_skb(skb), padsize, 774 ieee80211_get_hdrlen_from_skb(skb), padsize,
@@ -806,10 +870,13 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
806 list_add_tail(&bf->list, &sc->txbuf); 870 list_add_tail(&bf->list, &sc->txbuf);
807 } 871 }
808 872
809 /* beacon buffer */ 873 /* beacon buffers */
810 bf->desc = ds; 874 INIT_LIST_HEAD(&sc->bcbuf);
811 bf->daddr = da; 875 for (i = 0; i < ATH_BCBUF; i++, bf++, ds++, da += sizeof(*ds)) {
812 sc->bbuf = bf; 876 bf->desc = ds;
877 bf->daddr = da;
878 list_add_tail(&bf->list, &sc->bcbuf);
879 }
813 880
814 return 0; 881 return 0;
815err_free: 882err_free:
@@ -824,11 +891,12 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
824{ 891{
825 struct ath5k_buf *bf; 892 struct ath5k_buf *bf;
826 893
827 ath5k_txbuf_free_skb(sc, sc->bbuf);
828 list_for_each_entry(bf, &sc->txbuf, list) 894 list_for_each_entry(bf, &sc->txbuf, list)
829 ath5k_txbuf_free_skb(sc, bf); 895 ath5k_txbuf_free_skb(sc, bf);
830 list_for_each_entry(bf, &sc->rxbuf, list) 896 list_for_each_entry(bf, &sc->rxbuf, list)
831 ath5k_rxbuf_free_skb(sc, bf); 897 ath5k_rxbuf_free_skb(sc, bf);
898 list_for_each_entry(bf, &sc->bcbuf, list)
899 ath5k_txbuf_free_skb(sc, bf);
832 900
833 /* Free memory associated with all descriptors */ 901 /* Free memory associated with all descriptors */
834 pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); 902 pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
@@ -837,7 +905,6 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
837 905
838 kfree(sc->bufptr); 906 kfree(sc->bufptr);
839 sc->bufptr = NULL; 907 sc->bufptr = NULL;
840 sc->bbuf = NULL;
841} 908}
842 909
843 910
@@ -1083,7 +1150,7 @@ ath5k_rx_start(struct ath5k_softc *sc)
1083 spin_unlock_bh(&sc->rxbuflock); 1150 spin_unlock_bh(&sc->rxbuflock);
1084 1151
1085 ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ 1152 ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */
1086 ath5k_mode_setup(sc); /* set filters, etc. */ 1153 ath5k_mode_setup(sc, NULL); /* set filters, etc. */
1087 ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ 1154 ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */
1088 1155
1089 return 0; 1156 return 0;
@@ -1750,6 +1817,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1750{ 1817{
1751 int ret; 1818 int ret;
1752 struct ath5k_softc *sc = hw->priv; 1819 struct ath5k_softc *sc = hw->priv;
1820 struct ath5k_vif *avf = (void *)vif->drv_priv;
1753 struct sk_buff *skb; 1821 struct sk_buff *skb;
1754 1822
1755 if (WARN_ON(!vif)) { 1823 if (WARN_ON(!vif)) {
@@ -1766,11 +1834,11 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1766 1834
1767 ath5k_debug_dump_skb(sc, skb, "BC ", 1); 1835 ath5k_debug_dump_skb(sc, skb, "BC ", 1);
1768 1836
1769 ath5k_txbuf_free_skb(sc, sc->bbuf); 1837 ath5k_txbuf_free_skb(sc, avf->bbuf);
1770 sc->bbuf->skb = skb; 1838 avf->bbuf->skb = skb;
1771 ret = ath5k_beacon_setup(sc, sc->bbuf); 1839 ret = ath5k_beacon_setup(sc, avf->bbuf);
1772 if (ret) 1840 if (ret)
1773 sc->bbuf->skb = NULL; 1841 avf->bbuf->skb = NULL;
1774out: 1842out:
1775 return ret; 1843 return ret;
1776} 1844}
@@ -1786,16 +1854,14 @@ out:
1786static void 1854static void
1787ath5k_beacon_send(struct ath5k_softc *sc) 1855ath5k_beacon_send(struct ath5k_softc *sc)
1788{ 1856{
1789 struct ath5k_buf *bf = sc->bbuf;
1790 struct ath5k_hw *ah = sc->ah; 1857 struct ath5k_hw *ah = sc->ah;
1858 struct ieee80211_vif *vif;
1859 struct ath5k_vif *avf;
1860 struct ath5k_buf *bf;
1791 struct sk_buff *skb; 1861 struct sk_buff *skb;
1792 1862
1793 ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); 1863 ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
1794 1864
1795 if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION)) {
1796 ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
1797 return;
1798 }
1799 /* 1865 /*
1800 * Check if the previous beacon has gone out. If 1866 * Check if the previous beacon has gone out. If
1801 * not, don't don't try to post another: skip this 1867 * not, don't don't try to post another: skip this
@@ -1824,6 +1890,28 @@ ath5k_beacon_send(struct ath5k_softc *sc)
1824 sc->bmisscount = 0; 1890 sc->bmisscount = 0;
1825 } 1891 }
1826 1892
1893 if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
1894 u64 tsf = ath5k_hw_get_tsf64(ah);
1895 u32 tsftu = TSF_TO_TU(tsf);
1896 int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval;
1897 vif = sc->bslot[(slot + 1) % ATH_BCBUF];
1898 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
1899 "tsf %llx tsftu %x intval %u slot %u vif %p\n",
1900 (unsigned long long)tsf, tsftu, sc->bintval, slot, vif);
1901 } else /* only one interface */
1902 vif = sc->bslot[0];
1903
1904 if (!vif)
1905 return;
1906
1907 avf = (void *)vif->drv_priv;
1908 bf = avf->bbuf;
1909 if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
1910 sc->opmode == NL80211_IFTYPE_MONITOR)) {
1911 ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
1912 return;
1913 }
1914
1827 /* 1915 /*
1828 * Stop any current dma and put the new frame on the queue. 1916 * Stop any current dma and put the new frame on the queue.
1829 * This should never fail since we check above that no frames 1917 * This should never fail since we check above that no frames
@@ -1836,17 +1924,17 @@ ath5k_beacon_send(struct ath5k_softc *sc)
1836 1924
1837 /* refresh the beacon for AP mode */ 1925 /* refresh the beacon for AP mode */
1838 if (sc->opmode == NL80211_IFTYPE_AP) 1926 if (sc->opmode == NL80211_IFTYPE_AP)
1839 ath5k_beacon_update(sc->hw, sc->vif); 1927 ath5k_beacon_update(sc->hw, vif);
1840 1928
1841 ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); 1929 ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
1842 ath5k_hw_start_tx_dma(ah, sc->bhalq); 1930 ath5k_hw_start_tx_dma(ah, sc->bhalq);
1843 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", 1931 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
1844 sc->bhalq, (unsigned long long)bf->daddr, bf->desc); 1932 sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
1845 1933
1846 skb = ieee80211_get_buffered_bc(sc->hw, sc->vif); 1934 skb = ieee80211_get_buffered_bc(sc->hw, vif);
1847 while (skb) { 1935 while (skb) {
1848 ath5k_tx_queue(sc->hw, skb, sc->cabq); 1936 ath5k_tx_queue(sc->hw, skb, sc->cabq);
1849 skb = ieee80211_get_buffered_bc(sc->hw, sc->vif); 1937 skb = ieee80211_get_buffered_bc(sc->hw, vif);
1850 } 1938 }
1851 1939
1852 sc->bsent++; 1940 sc->bsent++;
@@ -1876,6 +1964,12 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
1876 u64 hw_tsf; 1964 u64 hw_tsf;
1877 1965
1878 intval = sc->bintval & AR5K_BEACON_PERIOD; 1966 intval = sc->bintval & AR5K_BEACON_PERIOD;
1967 if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
1968 intval /= ATH_BCBUF; /* staggered multi-bss beacons */
1969 if (intval < 15)
1970 ATH5K_WARN(sc, "intval %u is too low, min 15\n",
1971 intval);
1972 }
1879 if (WARN_ON(!intval)) 1973 if (WARN_ON(!intval))
1880 return; 1974 return;
1881 1975
@@ -2323,6 +2417,10 @@ ath5k_init(struct ath5k_softc *sc)
2323 ath_hw_keyreset(common, (u16) i); 2417 ath_hw_keyreset(common, (u16) i);
2324 2418
2325 ath5k_hw_set_ack_bitrate_high(ah, true); 2419 ath5k_hw_set_ack_bitrate_high(ah, true);
2420
2421 for (i = 0; i < ARRAY_SIZE(sc->bslot); i++)
2422 sc->bslot[i] = NULL;
2423
2326 ret = 0; 2424 ret = 0;
2327done: 2425done:
2328 mmiowb(); 2426 mmiowb();
@@ -2382,7 +2480,6 @@ ath5k_stop_hw(struct ath5k_softc *sc)
2382 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, 2480 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
2383 "putting device to sleep\n"); 2481 "putting device to sleep\n");
2384 } 2482 }
2385 ath5k_txbuf_free_skb(sc, sc->bbuf);
2386 2483
2387 mmiowb(); 2484 mmiowb();
2388 mutex_unlock(&sc->lock); 2485 mutex_unlock(&sc->lock);
@@ -2587,9 +2684,9 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
2587 } 2684 }
2588 2685
2589 SET_IEEE80211_PERM_ADDR(hw, mac); 2686 SET_IEEE80211_PERM_ADDR(hw, mac);
2687 memcpy(&sc->lladdr, mac, ETH_ALEN);
2590 /* All MAC address bits matter for ACKs */ 2688 /* All MAC address bits matter for ACKs */
2591 memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN); 2689 ath5k_update_bssid_mask(sc, NULL);
2592 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
2593 2690
2594 regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; 2691 regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
2595 ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); 2692 ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
@@ -2687,31 +2784,91 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
2687{ 2784{
2688 struct ath5k_softc *sc = hw->priv; 2785 struct ath5k_softc *sc = hw->priv;
2689 int ret; 2786 int ret;
2787 struct ath5k_hw *ah = sc->ah;
2788 struct ath5k_vif *avf = (void *)vif->drv_priv;
2690 2789
2691 mutex_lock(&sc->lock); 2790 mutex_lock(&sc->lock);
2692 if (sc->vif) { 2791
2693 ret = 0; 2792 if ((vif->type == NL80211_IFTYPE_AP ||
2793 vif->type == NL80211_IFTYPE_ADHOC)
2794 && (sc->num_ap_vifs + sc->num_adhoc_vifs) >= ATH_BCBUF) {
2795 ret = -ELNRNG;
2694 goto end; 2796 goto end;
2695 } 2797 }
2696 2798
2697 sc->vif = vif; 2799 /* Don't allow other interfaces if one ad-hoc is configured.
2800 * TODO: Fix the problems with ad-hoc and multiple other interfaces.
2801 * We would need to operate the HW in ad-hoc mode to allow TSF updates
2802 * for the IBSS, but this breaks with additional AP or STA interfaces
2803 * at the moment. */
2804 if (sc->num_adhoc_vifs ||
2805 (sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
2806 ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n");
2807 ret = -ELNRNG;
2808 goto end;
2809 }
2698 2810
2699 switch (vif->type) { 2811 switch (vif->type) {
2700 case NL80211_IFTYPE_AP: 2812 case NL80211_IFTYPE_AP:
2701 case NL80211_IFTYPE_STATION: 2813 case NL80211_IFTYPE_STATION:
2702 case NL80211_IFTYPE_ADHOC: 2814 case NL80211_IFTYPE_ADHOC:
2703 case NL80211_IFTYPE_MESH_POINT: 2815 case NL80211_IFTYPE_MESH_POINT:
2704 sc->opmode = vif->type; 2816 avf->opmode = vif->type;
2705 break; 2817 break;
2706 default: 2818 default:
2707 ret = -EOPNOTSUPP; 2819 ret = -EOPNOTSUPP;
2708 goto end; 2820 goto end;
2709 } 2821 }
2710 2822
2711 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode); 2823 sc->nvifs++;
2824 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode);
2712 2825
2826 /* Assign the vap/adhoc to a beacon xmit slot. */
2827 if ((avf->opmode == NL80211_IFTYPE_AP) ||
2828 (avf->opmode == NL80211_IFTYPE_ADHOC)) {
2829 int slot;
2830
2831 WARN_ON(list_empty(&sc->bcbuf));
2832 avf->bbuf = list_first_entry(&sc->bcbuf, struct ath5k_buf,
2833 list);
2834 list_del(&avf->bbuf->list);
2835
2836 avf->bslot = 0;
2837 for (slot = 0; slot < ATH_BCBUF; slot++) {
2838 if (!sc->bslot[slot]) {
2839 avf->bslot = slot;
2840 break;
2841 }
2842 }
2843 BUG_ON(sc->bslot[avf->bslot] != NULL);
2844 sc->bslot[avf->bslot] = vif;
2845 if (avf->opmode == NL80211_IFTYPE_AP)
2846 sc->num_ap_vifs++;
2847 else
2848 sc->num_adhoc_vifs++;
2849 }
2850
2851 /* Set combined mode - when APs are configured, operate in AP mode.
2852 * Otherwise use the mode of the new interface. This can currently
2853 * only deal with combinations of APs and STAs. Only one ad-hoc
2854 * interfaces is allowed above.
2855 */
2856 if (sc->num_ap_vifs)
2857 sc->opmode = NL80211_IFTYPE_AP;
2858 else
2859 sc->opmode = vif->type;
2860
2861 ath5k_hw_set_opmode(ah, sc->opmode);
2862
2863 /* Any MAC address is fine, all others are included through the
2864 * filter.
2865 */
2866 memcpy(&sc->lladdr, vif->addr, ETH_ALEN);
2713 ath5k_hw_set_lladdr(sc->ah, vif->addr); 2867 ath5k_hw_set_lladdr(sc->ah, vif->addr);
2714 ath5k_mode_setup(sc); 2868
2869 memcpy(&avf->lladdr, vif->addr, ETH_ALEN);
2870
2871 ath5k_mode_setup(sc, vif);
2715 2872
2716 ret = 0; 2873 ret = 0;
2717end: 2874end:
@@ -2724,15 +2881,29 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
2724 struct ieee80211_vif *vif) 2881 struct ieee80211_vif *vif)
2725{ 2882{
2726 struct ath5k_softc *sc = hw->priv; 2883 struct ath5k_softc *sc = hw->priv;
2727 u8 mac[ETH_ALEN] = {}; 2884 struct ath5k_vif *avf = (void *)vif->drv_priv;
2885 unsigned int i;
2728 2886
2729 mutex_lock(&sc->lock); 2887 mutex_lock(&sc->lock);
2730 if (sc->vif != vif) 2888 sc->nvifs--;
2731 goto end; 2889
2890 if (avf->bbuf) {
2891 ath5k_txbuf_free_skb(sc, avf->bbuf);
2892 list_add_tail(&avf->bbuf->list, &sc->bcbuf);
2893 for (i = 0; i < ATH_BCBUF; i++) {
2894 if (sc->bslot[i] == vif) {
2895 sc->bslot[i] = NULL;
2896 break;
2897 }
2898 }
2899 avf->bbuf = NULL;
2900 }
2901 if (avf->opmode == NL80211_IFTYPE_AP)
2902 sc->num_ap_vifs--;
2903 else if (avf->opmode == NL80211_IFTYPE_ADHOC)
2904 sc->num_adhoc_vifs--;
2732 2905
2733 ath5k_hw_set_lladdr(sc->ah, mac); 2906 ath5k_update_bssid_mask(sc, NULL);
2734 sc->vif = NULL;
2735end:
2736 mutex_unlock(&sc->lock); 2907 mutex_unlock(&sc->lock);
2737} 2908}
2738 2909
@@ -2815,6 +2986,19 @@ static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
2815 return ((u64)(mfilt[1]) << 32) | mfilt[0]; 2986 return ((u64)(mfilt[1]) << 32) | mfilt[0];
2816} 2987}
2817 2988
2989static bool ath_any_vif_assoc(struct ath5k_softc *sc)
2990{
2991 struct ath_vif_iter_data iter_data;
2992 iter_data.hw_macaddr = NULL;
2993 iter_data.any_assoc = false;
2994 iter_data.need_set_hw_addr = false;
2995 iter_data.found_active = true;
2996
2997 ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter,
2998 &iter_data);
2999 return iter_data.any_assoc;
3000}
3001
2818#define SUPPORTED_FIF_FLAGS \ 3002#define SUPPORTED_FIF_FLAGS \
2819 FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ 3003 FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \
2820 FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ 3004 FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
@@ -2885,7 +3069,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
2885 3069
2886 /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons 3070 /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
2887 * and probes for any BSSID */ 3071 * and probes for any BSSID */
2888 if (*new_flags & FIF_BCN_PRBRESP_PROMISC) 3072 if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (sc->nvifs > 1))
2889 rfilt |= AR5K_RX_FILTER_BEACON; 3073 rfilt |= AR5K_RX_FILTER_BEACON;
2890 3074
2891 /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not 3075 /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
@@ -3070,14 +3254,13 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3070 struct ieee80211_bss_conf *bss_conf, 3254 struct ieee80211_bss_conf *bss_conf,
3071 u32 changes) 3255 u32 changes)
3072{ 3256{
3257 struct ath5k_vif *avf = (void *)vif->drv_priv;
3073 struct ath5k_softc *sc = hw->priv; 3258 struct ath5k_softc *sc = hw->priv;
3074 struct ath5k_hw *ah = sc->ah; 3259 struct ath5k_hw *ah = sc->ah;
3075 struct ath_common *common = ath5k_hw_common(ah); 3260 struct ath_common *common = ath5k_hw_common(ah);
3076 unsigned long flags; 3261 unsigned long flags;
3077 3262
3078 mutex_lock(&sc->lock); 3263 mutex_lock(&sc->lock);
3079 if (WARN_ON(sc->vif != vif))
3080 goto unlock;
3081 3264
3082 if (changes & BSS_CHANGED_BSSID) { 3265 if (changes & BSS_CHANGED_BSSID) {
3083 /* Cache for later use during resets */ 3266 /* Cache for later use during resets */
@@ -3091,7 +3274,12 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3091 sc->bintval = bss_conf->beacon_int; 3274 sc->bintval = bss_conf->beacon_int;
3092 3275
3093 if (changes & BSS_CHANGED_ASSOC) { 3276 if (changes & BSS_CHANGED_ASSOC) {
3094 sc->assoc = bss_conf->assoc; 3277 avf->assoc = bss_conf->assoc;
3278 if (bss_conf->assoc)
3279 sc->assoc = bss_conf->assoc;
3280 else
3281 sc->assoc = ath_any_vif_assoc(sc);
3282
3095 if (sc->opmode == NL80211_IFTYPE_STATION) 3283 if (sc->opmode == NL80211_IFTYPE_STATION)
3096 set_beacon_filter(hw, sc->assoc); 3284 set_beacon_filter(hw, sc->assoc);
3097 ath5k_hw_set_ledstate(sc->ah, sc->assoc ? 3285 ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
@@ -3119,7 +3307,6 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3119 BSS_CHANGED_BEACON_INT)) 3307 BSS_CHANGED_BEACON_INT))
3120 ath5k_beacon_config(sc); 3308 ath5k_beacon_config(sc);
3121 3309
3122 unlock:
3123 mutex_unlock(&sc->lock); 3310 mutex_unlock(&sc->lock);
3124} 3311}
3125 3312
@@ -3394,6 +3581,8 @@ ath5k_pci_probe(struct pci_dev *pdev,
3394 hw->max_rate_tries = 11; 3581 hw->max_rate_tries = 11;
3395 } 3582 }
3396 3583
3584 hw->vif_data_size = sizeof(struct ath5k_vif);
3585
3397 /* Finish private driver data initialization */ 3586 /* Finish private driver data initialization */
3398 ret = ath5k_attach(pdev, hw); 3587 ret = ath5k_attach(pdev, hw);
3399 if (ret) 3588 if (ret)
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 7f9d0d3018e8..b9f6d13b7675 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -58,8 +58,7 @@
58 58
59#define ATH_RXBUF 40 /* number of RX buffers */ 59#define ATH_RXBUF 40 /* number of RX buffers */
60#define ATH_TXBUF 200 /* number of TX buffers */ 60#define ATH_TXBUF 200 /* number of TX buffers */
61#define ATH_BCBUF 1 /* number of beacon buffers */ 61#define ATH_BCBUF 4 /* number of beacon buffers */
62
63#define ATH5K_TXQ_LEN_MAX (ATH_TXBUF / 4) /* bufs per queue */ 62#define ATH5K_TXQ_LEN_MAX (ATH_TXBUF / 4) /* bufs per queue */
64#define ATH5K_TXQ_LEN_LOW (ATH5K_TXQ_LEN_MAX / 2) /* low mark */ 63#define ATH5K_TXQ_LEN_LOW (ATH5K_TXQ_LEN_MAX / 2) /* low mark */
65 64
@@ -152,6 +151,14 @@ struct ath5k_statistics {
152#define ATH_CHAN_MAX (14+14+14+252+20) 151#define ATH_CHAN_MAX (14+14+14+252+20)
153#endif 152#endif
154 153
154struct ath5k_vif {
155 bool assoc; /* are we associated or not */
156 enum nl80211_iftype opmode;
157 int bslot;
158 struct ath5k_buf *bbuf; /* beacon buffer */
159 u8 lladdr[ETH_ALEN];
160};
161
155/* Software Carrier, keeps track of the driver state 162/* Software Carrier, keeps track of the driver state
156 * associated with an instance of a device */ 163 * associated with an instance of a device */
157struct ath5k_softc { 164struct ath5k_softc {
@@ -188,10 +195,11 @@ struct ath5k_softc {
188 unsigned int curmode; /* current phy mode */ 195 unsigned int curmode; /* current phy mode */
189 struct ieee80211_channel *curchan; /* current h/w channel */ 196 struct ieee80211_channel *curchan; /* current h/w channel */
190 197
191 struct ieee80211_vif *vif; 198 u16 nvifs;
192 199
193 enum ath5k_int imask; /* interrupt mask copy */ 200 enum ath5k_int imask; /* interrupt mask copy */
194 201
202 u8 lladdr[ETH_ALEN];
195 u8 bssidmask[ETH_ALEN]; 203 u8 bssidmask[ETH_ALEN];
196 204
197 unsigned int led_pin, /* GPIO pin for driving LED */ 205 unsigned int led_pin, /* GPIO pin for driving LED */
@@ -219,7 +227,10 @@ struct ath5k_softc {
219 227
220 spinlock_t block; /* protects beacon */ 228 spinlock_t block; /* protects beacon */
221 struct tasklet_struct beacontq; /* beacon intr tasklet */ 229 struct tasklet_struct beacontq; /* beacon intr tasklet */
222 struct ath5k_buf *bbuf; /* beacon buffer */ 230 struct list_head bcbuf; /* beacon buffer */
231 struct ieee80211_vif *bslot[ATH_BCBUF];
232 u16 num_ap_vifs;
233 u16 num_adhoc_vifs;
223 unsigned int bhalq, /* SW q for outgoing beacons */ 234 unsigned int bhalq, /* SW q for outgoing beacons */
224 bmisscount, /* missed beacon transmits */ 235 bmisscount, /* missed beacon transmits */
225 bintval, /* beacon interval in TU */ 236 bintval, /* beacon interval in TU */
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 58912cd762d9..5b179d01f97d 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -167,7 +167,7 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
167 * ieee80211_duration() for a brief description of 167 * ieee80211_duration() for a brief description of
168 * what rate we should choose to TX ACKs. */ 168 * what rate we should choose to TX ACKs. */
169 tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, 169 tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
170 sc->vif, 10, rate)); 170 NULL, 10, rate));
171 171
172 ath5k_hw_reg_write(ah, tx_time, reg); 172 ath5k_hw_reg_write(ah, tx_time, reg);
173 173
@@ -1060,7 +1060,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1060 * XXX: rethink this after new mode changes to 1060 * XXX: rethink this after new mode changes to
1061 * mac80211 are integrated */ 1061 * mac80211 are integrated */
1062 if (ah->ah_version == AR5K_AR5212 && 1062 if (ah->ah_version == AR5K_AR5212 &&
1063 ah->ah_sc->vif != NULL) 1063 ah->ah_sc->nvifs)
1064 ath5k_hw_write_rate_duration(ah, mode); 1064 ath5k_hw_write_rate_duration(ah, mode);
1065 1065
1066 /* 1066 /*