ath5k: remove double cache alignment, ath_rxbuf_alloc() already does it
[pandora-kernel.git] / drivers / net / wireless / ath / ath5k / base.c
index 9c6ab53..4cefd9e 100644 (file)
@@ -195,12 +195,13 @@ static int __devinit      ath5k_pci_probe(struct pci_dev *pdev,
                                const struct pci_device_id *id);
 static void __devexit  ath5k_pci_remove(struct pci_dev *pdev);
 #ifdef CONFIG_PM
-static int             ath5k_pci_suspend(struct pci_dev *pdev,
-                                       pm_message_t state);
-static int             ath5k_pci_resume(struct pci_dev *pdev);
+static int             ath5k_pci_suspend(struct device *dev);
+static int             ath5k_pci_resume(struct device *dev);
+
+SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
+#define ATH5K_PM_OPS   (&ath5k_pm_ops)
 #else
-#define ath5k_pci_suspend NULL
-#define ath5k_pci_resume NULL
+#define ATH5K_PM_OPS   NULL
 #endif /* CONFIG_PM */
 
 static struct pci_driver ath5k_pci_driver = {
@@ -208,8 +209,7 @@ static struct pci_driver ath5k_pci_driver = {
        .id_table       = ath5k_pci_id_table,
        .probe          = ath5k_pci_probe,
        .remove         = __devexit_p(ath5k_pci_remove),
-       .suspend        = ath5k_pci_suspend,
-       .resume         = ath5k_pci_resume,
+       .driver.pm      = ATH5K_PM_OPS,
 };
 
 
@@ -323,10 +323,13 @@ static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
 static inline void ath5k_rxbuf_free(struct ath5k_softc *sc,
                                struct ath5k_buf *bf)
 {
+       struct ath5k_hw *ah = sc->ah;
+       struct ath_common *common = ath5k_hw_common(ah);
+
        BUG_ON(!bf);
        if (!bf->skb)
                return;
-       pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
+       pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize,
                        PCI_DMA_FROMDEVICE);
        dev_kfree_skb_any(bf->skb);
        bf->skb = NULL;
@@ -437,6 +440,22 @@ ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
 
        return name;
 }
+static unsigned int ath5k_ioread32(void *hw_priv, u32 reg_offset)
+{
+       struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv;
+       return ath5k_hw_reg_read(ah, reg_offset);
+}
+
+static void ath5k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
+{
+       struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv;
+       ath5k_hw_reg_write(ah, val, reg_offset);
+}
+
+static const struct ath_ops ath5k_common_ops = {
+       .read = ath5k_ioread32,
+       .write = ath5k_iowrite32,
+};
 
 static int __devinit
 ath5k_pci_probe(struct pci_dev *pdev,
@@ -444,6 +463,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
 {
        void __iomem *mem;
        struct ath5k_softc *sc;
+       struct ath_common *common;
        struct ieee80211_hw *hw;
        int ret;
        u8 csz;
@@ -547,7 +567,6 @@ ath5k_pci_probe(struct pci_dev *pdev,
        __set_bit(ATH_STAT_INVALID, sc->status);
 
        sc->iobase = mem; /* So we can unmap it on detach */
-       sc->common.cachelsz = csz << 2; /* convert to bytes */
        sc->opmode = NL80211_IFTYPE_STATION;
        sc->bintval = 1000;
        mutex_init(&sc->lock);
@@ -565,13 +584,28 @@ ath5k_pci_probe(struct pci_dev *pdev,
                goto err_free;
        }
 
-       /* Initialize device */
-       sc->ah = ath5k_hw_attach(sc);
-       if (IS_ERR(sc->ah)) {
-               ret = PTR_ERR(sc->ah);
+       /*If we passed the test malloc a ath5k_hw struct*/
+       sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
+       if (!sc->ah) {
+               ret = -ENOMEM;
+               ATH5K_ERR(sc, "out of memory\n");
                goto err_irq;
        }
 
+       sc->ah->ah_sc = sc;
+       sc->ah->ah_iobase = sc->iobase;
+       common = ath5k_hw_common(sc->ah);
+       common->ops = &ath5k_common_ops;
+       common->ah = sc->ah;
+       common->hw = hw;
+       common->cachelsz = csz << 2; /* convert to bytes */
+
+       /* Initialize device */
+       ret = ath5k_hw_attach(sc);
+       if (ret) {
+               goto err_free_ah;
+       }
+
        /* set up multi-rate retry capabilities */
        if (sc->ah->ah_version == AR5K_AR5212) {
                hw->max_rates = 4;
@@ -640,6 +674,8 @@ err_ah:
        ath5k_hw_detach(sc->ah);
 err_irq:
        free_irq(pdev->irq, sc);
+err_free_ah:
+       kfree(sc->ah);
 err_free:
        ieee80211_free_hw(hw);
 err_map:
@@ -661,6 +697,7 @@ ath5k_pci_remove(struct pci_dev *pdev)
        ath5k_debug_finish_device(sc);
        ath5k_detach(pdev, hw);
        ath5k_hw_detach(sc->ah);
+       kfree(sc->ah);
        free_irq(pdev->irq, sc);
        pci_iounmap(pdev, sc->iobase);
        pci_release_region(pdev, 0);
@@ -669,33 +706,20 @@ ath5k_pci_remove(struct pci_dev *pdev)
 }
 
 #ifdef CONFIG_PM
-static int
-ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int ath5k_pci_suspend(struct device *dev)
 {
-       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev));
        struct ath5k_softc *sc = hw->priv;
 
        ath5k_led_off(sc);
-
-       pci_save_state(pdev);
-       pci_disable_device(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
-
        return 0;
 }
 
-static int
-ath5k_pci_resume(struct pci_dev *pdev)
+static int ath5k_pci_resume(struct device *dev)
 {
+       struct pci_dev *pdev = to_pci_dev(dev);
        struct ieee80211_hw *hw = pci_get_drvdata(pdev);
        struct ath5k_softc *sc = hw->priv;
-       int err;
-
-       pci_restore_state(pdev);
-
-       err = pci_enable_device(pdev);
-       if (err)
-               return err;
 
        /*
         * Suspend/Resume resets the PCI configuration space, so we have to
@@ -718,7 +742,7 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re
 {
        struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
        struct ath5k_softc *sc = hw->priv;
-       struct ath_regulatory *regulatory = &sc->common.regulatory;
+       struct ath_regulatory *regulatory = ath5k_hw_regulatory(sc->ah);
 
        return ath_reg_notifier_apply(wiphy, request, regulatory);
 }
@@ -728,7 +752,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
 {
        struct ath5k_softc *sc = hw->priv;
        struct ath5k_hw *ah = sc->ah;
-       struct ath_regulatory *regulatory = &sc->common.regulatory;
+       struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
        u8 mac[ETH_ALEN] = {};
        int ret;
 
@@ -815,7 +839,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
 
        SET_IEEE80211_PERM_ADDR(hw, mac);
        /* All MAC address bits matter for ACKs */
-       memset(sc->bssidmask, 0xff, ETH_ALEN);
+       memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
        ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
 
        regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
@@ -1125,7 +1149,6 @@ ath5k_mode_setup(struct ath5k_softc *sc)
        /* configure operational mode */
        ath5k_hw_set_opmode(ah);
 
-       ath5k_hw_set_mcast_filter(ah, 0, 0);
        ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
 }
 
@@ -1153,24 +1176,26 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
 static
 struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
 {
+       struct ath_common *common = ath5k_hw_common(sc->ah);
        struct sk_buff *skb;
 
        /*
         * Allocate buffer with headroom_needed space for the
         * fake physical layer header at the start.
         */
-       skb = ath_rxbuf_alloc(&sc->common,
-                             sc->rxbufsize + sc->common.cachelsz - 1,
+       skb = ath_rxbuf_alloc(common,
+                             common->rx_bufsize,
                              GFP_ATOMIC);
 
        if (!skb) {
                ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
-                               sc->rxbufsize + sc->common.cachelsz - 1);
+                               common->rx_bufsize);
                return NULL;
        }
 
        *skb_addr = pci_map_single(sc->pdev,
-               skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
+                                  skb->data, common->rx_bufsize,
+                                  PCI_DMA_FROMDEVICE);
        if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {
                ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
                dev_kfree_skb(skb);
@@ -1606,13 +1631,14 @@ static int
 ath5k_rx_start(struct ath5k_softc *sc)
 {
        struct ath5k_hw *ah = sc->ah;
+       struct ath_common *common = ath5k_hw_common(ah);
        struct ath5k_buf *bf;
        int ret;
 
-       sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->common.cachelsz);
+       common->rx_bufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz);
 
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n",
-               sc->common.cachelsz, sc->rxbufsize);
+       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n",
+                 common->cachelsz, common->rx_bufsize);
 
        spin_lock_bh(&sc->rxbuflock);
        sc->rxlink = NULL;
@@ -1685,13 +1711,14 @@ static void
 ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
                     struct ieee80211_rx_status *rxs)
 {
+       struct ath_common *common = ath5k_hw_common(sc->ah);
        u64 tsf, bc_tstamp;
        u32 hw_tu;
        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
 
        if (ieee80211_is_beacon(mgmt->frame_control) &&
            le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
-           memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) {
+           memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) == 0) {
                /*
                 * Received an IBSS beacon with the same BSSID. Hardware *must*
                 * have updated the local TSF. We have to work around various
@@ -1746,6 +1773,8 @@ ath5k_tasklet_rx(unsigned long data)
        struct sk_buff *skb, *next_skb;
        dma_addr_t next_skb_addr;
        struct ath5k_softc *sc = (void *)data;
+       struct ath5k_hw *ah = sc->ah;
+       struct ath_common *common = ath5k_hw_common(ah);
        struct ath5k_buf *bf;
        struct ath5k_desc *ds;
        int ret;
@@ -1823,7 +1852,7 @@ accept:
                if (!next_skb)
                        goto next;
 
-               pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
+               pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize,
                                PCI_DMA_FROMDEVICE);
                skb_put(skb, rs.rs_datalen);
 
@@ -3177,6 +3206,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
 {
        struct ath5k_softc *sc = hw->priv;
        struct ath5k_hw *ah = sc->ah;
+       struct ath_common *common = ath5k_hw_common(ah);
        unsigned long flags;
 
        mutex_lock(&sc->lock);
@@ -3185,10 +3215,9 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
 
        if (changes & BSS_CHANGED_BSSID) {
                /* Cache for later use during resets */
-               memcpy(ah->ah_bssid, bss_conf->bssid, ETH_ALEN);
-               /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
-                * a clean way of letting us retrieve this yet. */
-               ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+               memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
+               common->curaid = 0;
+               ath5k_hw_set_associd(ah);
                mmiowb();
        }
 
@@ -3201,6 +3230,14 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
                        set_beacon_filter(hw, sc->assoc);
                ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
                        AR5K_LED_ASSOC : AR5K_LED_INIT);
+               if (bss_conf->assoc) {
+                       ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
+                                 "Bss Info ASSOC %d, bssid: %pM\n",
+                                 bss_conf->aid, common->curbssid);
+                       common->curaid = bss_conf->aid;
+                       ath5k_hw_set_associd(ah);
+                       /* Once ANI is available you would start it here */
+               }
        }
 
        if (changes & BSS_CHANGED_BEACON) {