]> err.no Git - linux-2.6/blobdiff - drivers/net/wireless/ath5k/base.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6] / drivers / net / wireless / ath5k / base.c
index 2028866f59951068ebb799ee3209ef22d9ff13c6..0676c6d84383082ab18e7ac1e1657f0271656418 100644 (file)
@@ -40,7 +40,6 @@
  *
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/hardirq.h>
@@ -252,7 +251,7 @@ static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
                return;
        pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len,
                        PCI_DMA_TODEVICE);
-       dev_kfree_skb(bf->skb);
+       dev_kfree_skb_any(bf->skb);
        bf->skb = NULL;
 }
 
@@ -467,6 +466,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
        mutex_init(&sc->lock);
        spin_lock_init(&sc->rxbuflock);
        spin_lock_init(&sc->txbuflock);
+       spin_lock_init(&sc->block);
 
        /* Set private data */
        pci_set_drvdata(pdev, hw);
@@ -587,7 +587,6 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
        ath5k_stop_hw(sc);
 
        free_irq(pdev->irq, sc);
-       pci_disable_msi(pdev);
        pci_save_state(pdev);
        pci_disable_device(pdev);
        pci_set_power_state(pdev, PCI_D3hot);
@@ -616,12 +615,10 @@ ath5k_pci_resume(struct pci_dev *pdev)
         */
        pci_write_config_byte(pdev, 0x41, 0);
 
-       pci_enable_msi(pdev);
-
        err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
        if (err) {
                ATH5K_ERR(sc, "request_irq failed\n");
-               goto err_msi;
+               goto err_no_irq;
        }
 
        err = ath5k_init(sc);
@@ -642,8 +639,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
        return 0;
 err_irq:
        free_irq(pdev->irq, sc);
-err_msi:
-       pci_disable_msi(pdev);
+err_no_irq:
        pci_disable_device(pdev);
        return err;
 }
@@ -2184,8 +2180,11 @@ ath5k_beacon_config(struct ath5k_softc *sc)
 
                sc->imask |= AR5K_INT_SWBA;
 
-               if (ath5k_hw_hasveol(ah))
+               if (ath5k_hw_hasveol(ah)) {
+                       spin_lock(&sc->block);
                        ath5k_beacon_send(sc);
+                       spin_unlock(&sc->block);
+               }
        }
        /* TODO else AP */
 
@@ -2408,7 +2407,9 @@ ath5k_intr(int irq, void *dev_id)
                                                  TSF_TO_TU(tsf),
                                                  (unsigned long long) tsf);
                                } else {
+                                       spin_lock(&sc->block);
                                        ath5k_beacon_send(sc);
+                                       spin_unlock(&sc->block);
                                }
                        }
                        if (status & AR5K_INT_RXEOL) {
@@ -2750,6 +2751,11 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
                ret = -EOPNOTSUPP;
                goto end;
        }
+
+       /* Set to a reasonable value. Note that this will
+        * be set to mac80211's value at ath5k_config(). */
+       sc->bintval = 1000;
+
        ret = 0;
 end:
        mutex_unlock(&sc->lock);
@@ -2794,9 +2800,6 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        struct ath5k_hw *ah = sc->ah;
        int ret;
 
-       /* Set to a reasonable value. Note that this will
-        * be set to mac80211's value at ath5k_config(). */
-       sc->bintval = 1000;
        mutex_lock(&sc->lock);
        if (sc->vif != vif) {
                ret = -EIO;
@@ -3055,6 +3058,7 @@ static int
 ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct ath5k_softc *sc = hw->priv;
+       unsigned long flags;
        int ret;
 
        ath5k_debug_dump_skb(sc, skb, "BC  ", 1);
@@ -3064,12 +3068,14 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
                goto end;
        }
 
+       spin_lock_irqsave(&sc->block, flags);
        ath5k_txbuf_free(sc, sc->bbuf);
        sc->bbuf->skb = skb;
        ret = ath5k_beacon_setup(sc, sc->bbuf);
        if (ret)
                sc->bbuf->skb = NULL;
-       else {
+       spin_unlock_irqrestore(&sc->block, flags);
+       if (!ret) {
                ath5k_beacon_config(sc);
                mmiowb();
        }