drivers: wireless: bcm4329: set MMC_PM_KEEP_POWER on suspend
[linux-2.6.git] / drivers / net / b44.c
index 25f1337..41ea84e 100644 (file)
@@ -5,11 +5,13 @@
  * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
  * Copyright (C) 2006 Felix Fietkau (nbd@openwrt.org)
  * Copyright (C) 2006 Broadcom Corporation.
- * Copyright (C) 2007 Michael Buesch <mb@bu3sch.de>
+ * Copyright (C) 2007 Michael Buesch <m@bues.ch>
  *
  * Distribute under GPL.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
 #include <linux/ssb/ssb.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -34,8 +38,8 @@
 #include "b44.h"
 
 #define DRV_MODULE_NAME                "b44"
-#define PFX DRV_MODULE_NAME    ": "
 #define DRV_MODULE_VERSION     "2.0"
+#define DRV_DESCRIPTION                "Broadcom 44xx/47xx 10/100 PCI ethernet driver"
 
 #define B44_DEF_MSG_ENABLE       \
        (NETIF_MSG_DRV          | \
@@ -73,8 +77,8 @@
          (BP)->tx_cons - (BP)->tx_prod - TX_RING_GAP(BP))
 #define NEXT_TX(N)             (((N) + 1) & (B44_TX_RING_SIZE - 1))
 
-#define RX_PKT_OFFSET          30
-#define RX_PKT_BUF_SZ          (1536 + RX_PKT_OFFSET + 64)
+#define RX_PKT_OFFSET          (RX_HEADER_LEN + 2)
+#define RX_PKT_BUF_SZ          (1536 + RX_PKT_OFFSET)
 
 /* minimum number of free TX descriptors required to wake up TX process */
 #define B44_TX_WAKEUP_THRESH           (B44_TX_RING_SIZE / 4)
 #define B44_ETHIPV6UDP_HLEN    62
 #define B44_ETHIPV4UDP_HLEN    42
 
-static char version[] __devinitdata =
-       DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION "\n";
-
 MODULE_AUTHOR("Felix Fietkau, Florian Schirmer, Pekka Pietikainen, David S. Miller");
-MODULE_DESCRIPTION("Broadcom 44xx/47xx 10/100 PCI ethernet driver");
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
 
@@ -102,7 +103,7 @@ MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
 
 
 #ifdef CONFIG_B44_PCI
-static const struct pci_device_id b44_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(b44_pci_tbl) = {
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B0) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B1) },
@@ -133,7 +134,6 @@ static void b44_init_rings(struct b44 *);
 
 static void b44_init_hw(struct b44 *, int);
 
-static int dma_desc_align_mask;
 static int dma_desc_sync_size;
 static int instance;
 
@@ -148,9 +148,8 @@ static inline void b44_sync_dma_desc_for_device(struct ssb_device *sdev,
                                                unsigned long offset,
                                                enum dma_data_direction dir)
 {
-       dma_sync_single_range_for_device(sdev->dev, dma_base,
-                                        offset & dma_desc_align_mask,
-                                        dma_desc_sync_size, dir);
+       dma_sync_single_for_device(sdev->dma_dev, dma_base + offset,
+                                  dma_desc_sync_size, dir);
 }
 
 static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
@@ -158,9 +157,8 @@ static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
                                             unsigned long offset,
                                             enum dma_data_direction dir)
 {
-       dma_sync_single_range_for_cpu(sdev->dev, dma_base,
-                                     offset & dma_desc_align_mask,
-                                     dma_desc_sync_size, dir);
+       dma_sync_single_for_cpu(sdev->dma_dev, dma_base + offset,
+                               dma_desc_sync_size, dir);
 }
 
 static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
@@ -189,11 +187,10 @@ static int b44_wait_bit(struct b44 *bp, unsigned long reg,
                udelay(10);
        }
        if (i == timeout) {
-               printk(KERN_ERR PFX "%s: BUG!  Timeout waiting for bit %08x of register "
-                      "%lx to %s.\n",
-                      bp->dev->name,
-                      bit, reg,
-                      (clear ? "clear" : "set"));
+               if (net_ratelimit())
+                       netdev_err(bp->dev, "BUG!  Timeout waiting for bit %08x of register %lx to %s\n",
+                                  bit, reg, clear ? "clear" : "set");
+
                return -ENODEV;
        }
        return 0;
@@ -333,13 +330,12 @@ static int b44_phy_reset(struct b44 *bp)
        err = b44_readphy(bp, MII_BMCR, &val);
        if (!err) {
                if (val & BMCR_RESET) {
-                       printk(KERN_ERR PFX "%s: PHY Reset would not complete.\n",
-                              bp->dev->name);
+                       netdev_err(bp->dev, "PHY Reset would not complete\n");
                        err = -ENODEV;
                }
        }
 
-       return 0;
+       return err;
 }
 
 static void __b44_set_flow_ctrl(struct b44 *bp, u32 pause_flags)
@@ -384,11 +380,11 @@ static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote)
        __b44_set_flow_ctrl(bp, pause_enab);
 }
 
-#ifdef SSB_DRIVER_MIPS
-extern char *nvram_get(char *name);
+#ifdef CONFIG_BCM47XX
+#include <asm/mach-bcm47xx/nvram.h>
 static void b44_wap54g10_workaround(struct b44 *bp)
 {
-       const char *str;
+       char buf[20];
        u32 val;
        int err;
 
@@ -397,10 +393,9 @@ static void b44_wap54g10_workaround(struct b44 *bp)
         * see https://dev.openwrt.org/ticket/146
         * check and reset bit "isolate"
         */
-       str = nvram_get("boardnum");
-       if (!str)
+       if (nvram_getenv("boardnum", buf, sizeof(buf)) < 0)
                return;
-       if (simple_strtoul(str, NULL, 0) == 2) {
+       if (simple_strtoul(buf, NULL, 0) == 2) {
                err = __b44_readphy(bp, 0, MII_BMCR, &val);
                if (err)
                        goto error;
@@ -413,7 +408,7 @@ static void b44_wap54g10_workaround(struct b44 *bp)
        }
        return;
 error:
-       printk(KERN_WARNING PFX "PHY: cannot reset MII transceiver isolate bit.\n");
+       pr_warning("PHY: cannot reset MII transceiver isolate bit\n");
 }
 #else
 static inline void b44_wap54g10_workaround(struct b44 *bp)
@@ -506,18 +501,15 @@ static void b44_stats_update(struct b44 *bp)
 static void b44_link_report(struct b44 *bp)
 {
        if (!netif_carrier_ok(bp->dev)) {
-               printk(KERN_INFO PFX "%s: Link is down.\n", bp->dev->name);
+               netdev_info(bp->dev, "Link is down\n");
        } else {
-               printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n",
-                      bp->dev->name,
-                      (bp->flags & B44_FLAG_100_BASE_T) ? 100 : 10,
-                      (bp->flags & B44_FLAG_FULL_DUPLEX) ? "full" : "half");
-
-               printk(KERN_INFO PFX "%s: Flow control is %s for TX and "
-                      "%s for RX.\n",
-                      bp->dev->name,
-                      (bp->flags & B44_FLAG_TX_PAUSE) ? "on" : "off",
-                      (bp->flags & B44_FLAG_RX_PAUSE) ? "on" : "off");
+               netdev_info(bp->dev, "Link is up at %d Mbps, %s duplex\n",
+                           (bp->flags & B44_FLAG_100_BASE_T) ? 100 : 10,
+                           (bp->flags & B44_FLAG_FULL_DUPLEX) ? "full" : "half");
+
+               netdev_info(bp->dev, "Flow control is %s for TX and %s for RX\n",
+                           (bp->flags & B44_FLAG_TX_PAUSE) ? "on" : "off",
+                           (bp->flags & B44_FLAG_RX_PAUSE) ? "on" : "off");
        }
 }
 
@@ -576,11 +568,9 @@ static void b44_check_phy(struct b44 *bp)
                }
 
                if (bmsr & BMSR_RFAULT)
-                       printk(KERN_WARNING PFX "%s: Remote fault detected in PHY\n",
-                              bp->dev->name);
+                       netdev_warn(bp->dev, "Remote fault detected in PHY\n");
                if (bmsr & BMSR_JCD)
-                       printk(KERN_WARNING PFX "%s: Jabber detected in PHY\n",
-                              bp->dev->name);
+                       netdev_warn(bp->dev, "Jabber detected in PHY\n");
        }
 }
 
@@ -613,12 +603,12 @@ static void b44_tx(struct b44 *bp)
 
                BUG_ON(skb == NULL);
 
-               dma_unmap_single(bp->sdev->dev,
+               dma_unmap_single(bp->sdev->dma_dev,
                                 rp->mapping,
                                 skb->len,
                                 DMA_TO_DEVICE);
                rp->skb = NULL;
-               dev_kfree_skb_irq(skb);
+               dev_kfree_skb(skb);
        }
 
        bp->tx_cons = cons;
@@ -653,36 +643,36 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
        if (skb == NULL)
                return -ENOMEM;
 
-       mapping = dma_map_single(bp->sdev->dev, skb->data,
+       mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
                                 RX_PKT_BUF_SZ,
                                 DMA_FROM_DEVICE);
 
        /* Hardware bug work-around, the chip is unable to do PCI DMA
           to/from anything above 1GB :-( */
-       if (dma_mapping_error(mapping) ||
-               mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
+       if (dma_mapping_error(bp->sdev->dma_dev, mapping) ||
+               mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) {
                /* Sigh... */
-               if (!dma_mapping_error(mapping))
-                       dma_unmap_single(bp->sdev->dev, mapping,
-                                       RX_PKT_BUF_SZ, DMA_FROM_DEVICE);
+               if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
+                       dma_unmap_single(bp->sdev->dma_dev, mapping,
+                                            RX_PKT_BUF_SZ, DMA_FROM_DEVICE);
                dev_kfree_skb_any(skb);
                skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA);
                if (skb == NULL)
                        return -ENOMEM;
-               mapping = dma_map_single(bp->sdev->dev, skb->data,
+               mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
                                         RX_PKT_BUF_SZ,
                                         DMA_FROM_DEVICE);
-               if (dma_mapping_error(mapping) ||
-                       mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
-                       if (!dma_mapping_error(mapping))
-                               dma_unmap_single(bp->sdev->dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
+               if (dma_mapping_error(bp->sdev->dma_dev, mapping) ||
+                   mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) {
+                       if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
+                               dma_unmap_single(bp->sdev->dma_dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
                        dev_kfree_skb_any(skb);
                        return -ENOMEM;
                }
+               bp->force_copybreak = 1;
        }
 
        rh = (struct rx_header *) skb->data;
-       skb_reserve(skb, RX_PKT_OFFSET);
 
        rh->len = 0;
        rh->flags = 0;
@@ -693,17 +683,17 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
        if (src_map != NULL)
                src_map->skb = NULL;
 
-       ctrl  = (DESC_CTRL_LEN & (RX_PKT_BUF_SZ - RX_PKT_OFFSET));
+       ctrl = (DESC_CTRL_LEN & RX_PKT_BUF_SZ);
        if (dest_idx == (B44_RX_RING_SIZE - 1))
                ctrl |= DESC_CTRL_EOT;
 
        dp = &bp->rx_ring[dest_idx];
        dp->ctrl = cpu_to_le32(ctrl);
-       dp->addr = cpu_to_le32((u32) mapping + RX_PKT_OFFSET + bp->dma_offset);
+       dp->addr = cpu_to_le32((u32) mapping + bp->dma_offset);
 
        if (bp->flags & B44_FLAG_RX_RING_HACK)
                b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
-                                           dest_idx * sizeof(dp),
+                                           dest_idx * sizeof(*dp),
                                            DMA_BIDIRECTIONAL);
 
        return RX_PKT_BUF_SZ;
@@ -731,7 +721,7 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
 
        if (bp->flags & B44_FLAG_RX_RING_HACK)
                b44_sync_dma_desc_for_cpu(bp->sdev, bp->rx_ring_dma,
-                                        src_idx * sizeof(src_desc),
+                                        src_idx * sizeof(*src_desc),
                                         DMA_BIDIRECTIONAL);
 
        ctrl = src_desc->ctrl;
@@ -747,10 +737,10 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
 
        if (bp->flags & B44_FLAG_RX_RING_HACK)
                b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
-                                            dest_idx * sizeof(dest_desc),
+                                            dest_idx * sizeof(*dest_desc),
                                             DMA_BIDIRECTIONAL);
 
-       dma_sync_single_for_device(bp->sdev->dev, le32_to_cpu(src_desc->addr),
+       dma_sync_single_for_device(bp->sdev->dma_dev, dest_map->mapping,
                                   RX_PKT_BUF_SZ,
                                   DMA_FROM_DEVICE);
 }
@@ -772,9 +762,9 @@ static int b44_rx(struct b44 *bp, int budget)
                struct rx_header *rh;
                u16 len;
 
-               dma_sync_single_for_cpu(bp->sdev->dev, map,
-                                           RX_PKT_BUF_SZ,
-                                           DMA_FROM_DEVICE);
+               dma_sync_single_for_cpu(bp->sdev->dma_dev, map,
+                                       RX_PKT_BUF_SZ,
+                                       DMA_FROM_DEVICE);
                rh = (struct rx_header *) skb->data;
                len = le16_to_cpu(rh->len);
                if ((len > (RX_PKT_BUF_SZ - RX_PKT_OFFSET)) ||
@@ -782,7 +772,7 @@ static int b44_rx(struct b44 *bp, int budget)
                drop_it:
                        b44_recycle_rx(bp, cons, bp->rx_prod);
                drop_it_no_recycle:
-                       bp->stats.rx_dropped++;
+                       bp->dev->stats.rx_dropped++;
                        goto next_pkt;
                }
 
@@ -801,21 +791,21 @@ static int b44_rx(struct b44 *bp, int budget)
                /* Omit CRC. */
                len -= 4;
 
-               if (len > RX_COPY_THRESHOLD) {
+               if (!bp->force_copybreak && len > RX_COPY_THRESHOLD) {
                        int skb_size;
                        skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod);
                        if (skb_size < 0)
                                goto drop_it;
-                       dma_unmap_single(bp->sdev->dev, map,
+                       dma_unmap_single(bp->sdev->dma_dev, map,
                                         skb_size, DMA_FROM_DEVICE);
                        /* Leave out rx_header */
-                       skb_put(skb, len + RX_PKT_OFFSET);
-                       skb_pull(skb, RX_PKT_OFFSET);
+                       skb_put(skb, len + RX_PKT_OFFSET);
+                       skb_pull(skb, RX_PKT_OFFSET);
                } else {
                        struct sk_buff *copy_skb;
 
                        b44_recycle_rx(bp, cons, bp->rx_prod);
-                       copy_skb = dev_alloc_skb(len + 2);
+                       copy_skb = netdev_alloc_skb(bp->dev, len + 2);
                        if (copy_skb == NULL)
                                goto drop_it_no_recycle;
 
@@ -826,10 +816,9 @@ static int b44_rx(struct b44 *bp, int budget)
                                                         copy_skb->data, len);
                        skb = copy_skb;
                }
-               skb->ip_summed = CHECKSUM_NONE;
+               skb_checksum_none_assert(skb);
                skb->protocol = eth_type_trans(skb, bp->dev);
                netif_receive_skb(skb);
-               bp->dev->last_rx = jiffies;
                received++;
                budget--;
        next_pkt:
@@ -847,25 +836,32 @@ static int b44_rx(struct b44 *bp, int budget)
 static int b44_poll(struct napi_struct *napi, int budget)
 {
        struct b44 *bp = container_of(napi, struct b44, napi);
-       struct net_device *netdev = bp->dev;
        int work_done;
+       unsigned long flags;
 
-       spin_lock_irq(&bp->lock);
+       spin_lock_irqsave(&bp->lock, flags);
 
        if (bp->istat & (ISTAT_TX | ISTAT_TO)) {
                /* spin_lock(&bp->tx_lock); */
                b44_tx(bp);
                /* spin_unlock(&bp->tx_lock); */
        }
-       spin_unlock_irq(&bp->lock);
+       if (bp->istat & ISTAT_RFO) {    /* fast recovery, in ~20msec */
+               bp->istat &= ~ISTAT_RFO;
+               b44_disable_ints(bp);
+               ssb_device_enable(bp->sdev, 0); /* resets ISTAT_RFO */
+               b44_init_rings(bp);
+               b44_init_hw(bp, B44_FULL_RESET_SKIP_PHY);
+               netif_wake_queue(bp->dev);
+       }
+
+       spin_unlock_irqrestore(&bp->lock, flags);
 
        work_done = 0;
        if (bp->istat & ISTAT_RX)
                work_done += b44_rx(bp, budget);
 
        if (bp->istat & ISTAT_ERRORS) {
-               unsigned long flags;
-
                spin_lock_irqsave(&bp->lock, flags);
                b44_halt(bp);
                b44_init_rings(bp);
@@ -876,7 +872,7 @@ static int b44_poll(struct napi_struct *napi, int budget)
        }
 
        if (work_done < budget) {
-               netif_rx_complete(netdev, napi);
+               napi_complete(napi);
                b44_enable_ints(bp);
        }
 
@@ -904,20 +900,17 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id)
                handled = 1;
 
                if (unlikely(!netif_running(dev))) {
-                       printk(KERN_INFO "%s: late interrupt.\n", dev->name);
+                       netdev_info(dev, "late interrupt\n");
                        goto irq_ack;
                }
 
-               if (netif_rx_schedule_prep(dev, &bp->napi)) {
+               if (napi_schedule_prep(&bp->napi)) {
                        /* NOTE: These writes are posted by the readback of
                         *       the ISTAT register below.
                         */
                        bp->istat = istat;
                        __b44_disable_ints(bp);
-                       __netif_rx_schedule(dev, &bp->napi);
-               } else {
-                       printk(KERN_ERR PFX "%s: Error, poll already scheduled\n",
-                              dev->name);
+                       __napi_schedule(&bp->napi);
                }
 
 irq_ack:
@@ -932,8 +925,7 @@ static void b44_tx_timeout(struct net_device *dev)
 {
        struct b44 *bp = netdev_priv(dev);
 
-       printk(KERN_ERR PFX "%s: transmit timed out, resetting\n",
-              dev->name);
+       netdev_err(dev, "transmit timed out, resetting\n");
 
        spin_lock_irq(&bp->lock);
 
@@ -948,43 +940,43 @@ static void b44_tx_timeout(struct net_device *dev)
        netif_wake_queue(dev);
 }
 
-static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct b44 *bp = netdev_priv(dev);
        int rc = NETDEV_TX_OK;
        dma_addr_t mapping;
        u32 len, entry, ctrl;
+       unsigned long flags;
 
        len = skb->len;
-       spin_lock_irq(&bp->lock);
+       spin_lock_irqsave(&bp->lock, flags);
 
        /* This is a hard error, log it. */
        if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) {
                netif_stop_queue(dev);
-               printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
-                      dev->name);
+               netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
                goto err_out;
        }
 
-       mapping = dma_map_single(bp->sdev->dev, skb->data, len, DMA_TO_DEVICE);
-       if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) {
+       mapping = dma_map_single(bp->sdev->dma_dev, skb->data, len, DMA_TO_DEVICE);
+       if (dma_mapping_error(bp->sdev->dma_dev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
                struct sk_buff *bounce_skb;
 
                /* Chip can't handle DMA to/from >1GB, use bounce buffer */
-               if (!dma_mapping_error(mapping))
-                       dma_unmap_single(bp->sdev->dev, mapping, len,
-                                       DMA_TO_DEVICE);
+               if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
+                       dma_unmap_single(bp->sdev->dma_dev, mapping, len,
+                                            DMA_TO_DEVICE);
 
-               bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA);
+               bounce_skb = __netdev_alloc_skb(dev, len, GFP_ATOMIC | GFP_DMA);
                if (!bounce_skb)
                        goto err_out;
 
-               mapping = dma_map_single(bp->sdev->dev, bounce_skb->data,
-                                        len, DMA_TO_DEVICE);
-               if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) {
-                       if (!dma_mapping_error(mapping))
-                               dma_unmap_single(bp->sdev->dev, mapping,
+               mapping = dma_map_single(bp->sdev->dma_dev, bounce_skb->data,
                                         len, DMA_TO_DEVICE);
+               if (dma_mapping_error(bp->sdev->dma_dev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
+                       if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
+                               dma_unmap_single(bp->sdev->dma_dev, mapping,
+                                                    len, DMA_TO_DEVICE);
                        dev_kfree_skb_any(bounce_skb);
                        goto err_out;
                }
@@ -1026,10 +1018,8 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (TX_BUFFS_AVAIL(bp) < 1)
                netif_stop_queue(dev);
 
-       dev->trans_start = jiffies;
-
 out_unlock:
-       spin_unlock_irq(&bp->lock);
+       spin_unlock_irqrestore(&bp->lock, flags);
 
        return rc;
 
@@ -1082,8 +1072,8 @@ static void b44_free_rings(struct b44 *bp)
 
                if (rp->skb == NULL)
                        continue;
-               dma_unmap_single(bp->sdev->dev, rp->mapping, RX_PKT_BUF_SZ,
-                                       DMA_FROM_DEVICE);
+               dma_unmap_single(bp->sdev->dma_dev, rp->mapping, RX_PKT_BUF_SZ,
+                                DMA_FROM_DEVICE);
                dev_kfree_skb_any(rp->skb);
                rp->skb = NULL;
        }
@@ -1094,8 +1084,8 @@ static void b44_free_rings(struct b44 *bp)
 
                if (rp->skb == NULL)
                        continue;
-               dma_unmap_single(bp->sdev->dev, rp->mapping, rp->skb->len,
-                                       DMA_TO_DEVICE);
+               dma_unmap_single(bp->sdev->dma_dev, rp->mapping, rp->skb->len,
+                                DMA_TO_DEVICE);
                dev_kfree_skb_any(rp->skb);
                rp->skb = NULL;
        }
@@ -1117,14 +1107,12 @@ static void b44_init_rings(struct b44 *bp)
        memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
 
        if (bp->flags & B44_FLAG_RX_RING_HACK)
-               dma_sync_single_for_device(bp->sdev->dev, bp->rx_ring_dma,
-                                         DMA_TABLE_BYTES,
-                                         DMA_BIDIRECTIONAL);
+               dma_sync_single_for_device(bp->sdev->dma_dev, bp->rx_ring_dma,
+                                          DMA_TABLE_BYTES, DMA_BIDIRECTIONAL);
 
        if (bp->flags & B44_FLAG_TX_RING_HACK)
-               dma_sync_single_for_device(bp->sdev->dev, bp->tx_ring_dma,
-                                         DMA_TABLE_BYTES,
-                                         DMA_TO_DEVICE);
+               dma_sync_single_for_device(bp->sdev->dma_dev, bp->tx_ring_dma,
+                                          DMA_TABLE_BYTES, DMA_TO_DEVICE);
 
        for (i = 0; i < bp->rx_pending; i++) {
                if (b44_alloc_rx_skb(bp, -1, i) < 0)
@@ -1144,25 +1132,23 @@ static void b44_free_consistent(struct b44 *bp)
        bp->tx_buffers = NULL;
        if (bp->rx_ring) {
                if (bp->flags & B44_FLAG_RX_RING_HACK) {
-                       dma_unmap_single(bp->sdev->dev, bp->rx_ring_dma,
-                                       DMA_TABLE_BYTES,
-                                       DMA_BIDIRECTIONAL);
+                       dma_unmap_single(bp->sdev->dma_dev, bp->rx_ring_dma,
+                                        DMA_TABLE_BYTES, DMA_BIDIRECTIONAL);
                        kfree(bp->rx_ring);
                } else
-                       dma_free_coherent(bp->sdev->dev, DMA_TABLE_BYTES,
-                                           bp->rx_ring, bp->rx_ring_dma);
+                       dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
+                                         bp->rx_ring, bp->rx_ring_dma);
                bp->rx_ring = NULL;
                bp->flags &= ~B44_FLAG_RX_RING_HACK;
        }
        if (bp->tx_ring) {
                if (bp->flags & B44_FLAG_TX_RING_HACK) {
-                       dma_unmap_single(bp->sdev->dev, bp->tx_ring_dma,
-                                       DMA_TABLE_BYTES,
-                                       DMA_TO_DEVICE);
+                       dma_unmap_single(bp->sdev->dma_dev, bp->tx_ring_dma,
+                                        DMA_TABLE_BYTES, DMA_TO_DEVICE);
                        kfree(bp->tx_ring);
                } else
-                       dma_free_coherent(bp->sdev->dev, DMA_TABLE_BYTES,
-                                           bp->tx_ring, bp->tx_ring_dma);
+                       dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
+                                         bp->tx_ring, bp->tx_ring_dma);
                bp->tx_ring = NULL;
                bp->flags &= ~B44_FLAG_TX_RING_HACK;
        }
@@ -1187,7 +1173,8 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
                goto out_err;
 
        size = DMA_TABLE_BYTES;
-       bp->rx_ring = dma_alloc_coherent(bp->sdev->dev, size, &bp->rx_ring_dma, gfp);
+       bp->rx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size,
+                                        &bp->rx_ring_dma, gfp);
        if (!bp->rx_ring) {
                /* Allocation may have failed due to pci_alloc_consistent
                   insisting on use of GFP_DMA, which is more restrictive
@@ -1199,12 +1186,12 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
                if (!rx_ring)
                        goto out_err;
 
-               rx_ring_dma = dma_map_single(bp->sdev->dev, rx_ring,
-                                           DMA_TABLE_BYTES,
-                                           DMA_BIDIRECTIONAL);
+               rx_ring_dma = dma_map_single(bp->sdev->dma_dev, rx_ring,
+                                            DMA_TABLE_BYTES,
+                                            DMA_BIDIRECTIONAL);
 
-               if (dma_mapping_error(rx_ring_dma) ||
-                       rx_ring_dma + size > DMA_30BIT_MASK) {
+               if (dma_mapping_error(bp->sdev->dma_dev, rx_ring_dma) ||
+                       rx_ring_dma + size > DMA_BIT_MASK(30)) {
                        kfree(rx_ring);
                        goto out_err;
                }
@@ -1214,9 +1201,10 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
                bp->flags |= B44_FLAG_RX_RING_HACK;
        }
 
-       bp->tx_ring = dma_alloc_coherent(bp->sdev->dev, size, &bp->tx_ring_dma, gfp);
+       bp->tx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size,
+                                        &bp->tx_ring_dma, gfp);
        if (!bp->tx_ring) {
-               /* Allocation may have failed due to dma_alloc_coherent
+               /* Allocation may have failed due to ssb_dma_alloc_consistent
                   insisting on use of GFP_DMA, which is more restrictive
                   than necessary...  */
                struct dma_desc *tx_ring;
@@ -1226,12 +1214,12 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
                if (!tx_ring)
                        goto out_err;
 
-               tx_ring_dma = dma_map_single(bp->sdev->dev, tx_ring,
-                                           DMA_TABLE_BYTES,
-                                           DMA_TO_DEVICE);
+               tx_ring_dma = dma_map_single(bp->sdev->dma_dev, tx_ring,
+                                            DMA_TABLE_BYTES,
+                                            DMA_TO_DEVICE);
 
-               if (dma_mapping_error(tx_ring_dma) ||
-                       tx_ring_dma + size > DMA_30BIT_MASK) {
+               if (dma_mapping_error(bp->sdev->dma_dev, tx_ring_dma) ||
+                       tx_ring_dma + size > DMA_BIT_MASK(30)) {
                        kfree(tx_ring);
                        goto out_err;
                }
@@ -1264,8 +1252,14 @@ static void b44_clear_stats(struct b44 *bp)
 static void b44_chip_reset(struct b44 *bp, int reset_kind)
 {
        struct ssb_device *sdev = bp->sdev;
+       bool was_enabled;
 
-       if (ssb_device_is_enabled(bp->sdev)) {
+       was_enabled = ssb_device_is_enabled(bp->sdev);
+
+       ssb_device_enable(bp->sdev, 0);
+       ssb_pcicore_dev_irqvecs_enable(&sdev->bus->pcicore, sdev);
+
+       if (was_enabled) {
                bw32(bp, B44_RCV_LAZY, 0);
                bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE);
                b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 200, 1);
@@ -1277,10 +1271,8 @@ static void b44_chip_reset(struct b44 *bp, int reset_kind)
                }
                bw32(bp, B44_DMARX_CTRL, 0);
                bp->rx_prod = bp->rx_cons = 0;
-       } else
-               ssb_pcicore_dev_irqvecs_enable(&sdev->bus->pcicore, sdev);
+       }
 
-       ssb_device_enable(bp->sdev, 0);
        b44_clear_stats(bp);
 
        /*
@@ -1293,14 +1285,18 @@ static void b44_chip_reset(struct b44 *bp, int reset_kind)
        switch (sdev->bus->bustype) {
        case SSB_BUSTYPE_SSB:
                bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
-                    (((ssb_clockspeed(sdev->bus) + (B44_MDC_RATIO / 2)) / B44_MDC_RATIO)
+                    (DIV_ROUND_CLOSEST(ssb_clockspeed(sdev->bus),
+                                       B44_MDC_RATIO)
                     & MDIO_CTRL_MAXF_MASK)));
                break;
        case SSB_BUSTYPE_PCI:
-       case SSB_BUSTYPE_PCMCIA:
                bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
                     (0x0d & MDIO_CTRL_MAXF_MASK)));
                break;
+       case SSB_BUSTYPE_PCMCIA:
+       case SSB_BUSTYPE_SDIO:
+               WARN_ON(1); /* A device with this bus does not exist. */
+               break;
        }
 
        br32(bp, B44_MDIO_CTRL);
@@ -1328,7 +1324,7 @@ static void b44_halt(struct b44 *bp)
        /* reset PHY */
        b44_phy_reset(bp);
        /* power down PHY */
-       printk(KERN_INFO PFX "%s: powering down PHY\n", bp->dev->name);
+       netdev_info(bp->dev, "powering down PHY\n");
        bw32(bp, B44_MAC_CTRL, MAC_CTRL_PHY_PDOWN);
        /* now reset the chip, but without enabling the MAC&PHY
         * part of it. This has to be done _after_ we shut down the PHY */
@@ -1500,8 +1496,7 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset)
                for (k = 0; k< ethaddr_bytes; k++) {
                        ppattern[offset + magicsync +
                                (j * ETH_ALEN) + k] = macaddr[k];
-                       len++;
-                       set_bit(len, (unsigned long *) pmask);
+                       set_bit(len++, (unsigned long *) pmask);
                }
        }
        return len - 1;
@@ -1520,7 +1515,7 @@ static void b44_setup_pseudo_magicp(struct b44 *bp)
 
        pwol_pattern = kzalloc(B44_PATTERN_SIZE, GFP_KERNEL);
        if (!pwol_pattern) {
-               printk(KERN_ERR PFX "Memory not available for WOL\n");
+               pr_err("Memory not available for WOL\n");
                return;
        }
 
@@ -1643,7 +1638,7 @@ static int b44_close(struct net_device *dev)
 static struct net_device_stats *b44_get_stats(struct net_device *dev)
 {
        struct b44 *bp = netdev_priv(dev);
-       struct net_device_stats *nstat = &bp->stats;
+       struct net_device_stats *nstat = &dev->stats;
        struct b44_hw_stats *hwstat = &bp->hw_stats;
 
        /* Convert HW stats into netdevice stats. */
@@ -1684,13 +1679,15 @@ static struct net_device_stats *b44_get_stats(struct net_device *dev)
 
 static int __b44_load_mcast(struct b44 *bp, struct net_device *dev)
 {
-       struct dev_mc_list *mclist;
+       struct netdev_hw_addr *ha;
        int i, num_ents;
 
-       num_ents = min_t(int, dev->mc_count, B44_MCAST_TABLE_SIZE);
-       mclist = dev->mc_list;
-       for (i = 0; mclist && i < num_ents; i++, mclist = mclist->next) {
-               __b44_cam_write(bp, mclist->dmi_addr, i + 1);
+       num_ents = min_t(int, netdev_mc_count(dev), B44_MCAST_TABLE_SIZE);
+       i = 0;
+       netdev_for_each_mc_addr(ha, dev) {
+               if (i == num_ents)
+                       break;
+               __b44_cam_write(bp, ha->addr, i++ + 1);
        }
        return i+1;
 }
@@ -1712,7 +1709,7 @@ static void __b44_set_rx_mode(struct net_device *dev)
                __b44_set_mac_addr(bp);
 
                if ((dev->flags & IFF_ALLMULTI) ||
-                   (dev->mc_count > B44_MCAST_TABLE_SIZE))
+                   (netdev_mc_count(dev) > B44_MCAST_TABLE_SIZE))
                        val |= RXCONFIG_ALLMULTI;
                else
                        i = __b44_load_mcast(bp, dev);
@@ -1752,15 +1749,18 @@ static void b44_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *inf
        struct b44 *bp = netdev_priv(dev);
        struct ssb_bus *bus = bp->sdev->bus;
 
-       strncpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
-       strncpy(info->version, DRV_MODULE_VERSION, sizeof(info->driver));
+       strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
+       strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
        switch (bus->bustype) {
        case SSB_BUSTYPE_PCI:
-               strncpy(info->bus_info, pci_name(bus->host_pci), sizeof(info->bus_info));
+               strlcpy(info->bus_info, pci_name(bus->host_pci), sizeof(info->bus_info));
                break;
-       case SSB_BUSTYPE_PCMCIA:
        case SSB_BUSTYPE_SSB:
-               strncpy(info->bus_info, "SSB", sizeof(info->bus_info));
+               strlcpy(info->bus_info, "SSB", sizeof(info->bus_info));
+               break;
+       case SSB_BUSTYPE_PCMCIA:
+       case SSB_BUSTYPE_SDIO:
+               WARN_ON(1); /* A device with this bus does not exist. */
                break;
        }
 }
@@ -1806,8 +1806,8 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        if (bp->flags & B44_FLAG_ADV_100FULL)
                cmd->advertising |= ADVERTISED_100baseT_Full;
        cmd->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
-       cmd->speed = (bp->flags & B44_FLAG_100_BASE_T) ?
-               SPEED_100 : SPEED_10;
+       ethtool_cmd_speed_set(cmd, ((bp->flags & B44_FLAG_100_BASE_T) ?
+                                   SPEED_100 : SPEED_10));
        cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
                DUPLEX_FULL : DUPLEX_HALF;
        cmd->port = 0;
@@ -1819,7 +1819,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        if (cmd->autoneg == AUTONEG_ENABLE)
                cmd->advertising |= ADVERTISED_Autoneg;
        if (!netif_running(dev)){
-               cmd->speed = 0;
+               ethtool_cmd_speed_set(cmd, 0);
                cmd->duplex = 0xff;
        }
        cmd->maxtxpkt = 0;
@@ -1830,6 +1830,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
        struct b44 *bp = netdev_priv(dev);
+       u32 speed = ethtool_cmd_speed(cmd);
 
        /* We do not support gigabit. */
        if (cmd->autoneg == AUTONEG_ENABLE) {
@@ -1837,8 +1838,8 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                    (ADVERTISED_1000baseT_Half |
                     ADVERTISED_1000baseT_Full))
                        return -EINVAL;
-       } else if ((cmd->speed != SPEED_100 &&
-                   cmd->speed != SPEED_10) ||
+       } else if ((speed != SPEED_100 &&
+                   speed != SPEED_10) ||
                   (cmd->duplex != DUPLEX_HALF &&
                    cmd->duplex != DUPLEX_FULL)) {
                        return -EINVAL;
@@ -1872,7 +1873,7 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        } else {
                bp->flags |= B44_FLAG_FORCE_LINK;
                bp->flags &= ~(B44_FLAG_100_BASE_T | B44_FLAG_FULL_DUPLEX);
-               if (cmd->speed == SPEED_100)
+               if (speed == SPEED_100)
                        bp->flags |= B44_FLAG_100_BASE_T;
                if (cmd->duplex == DUPLEX_FULL)
                        bp->flags |= B44_FLAG_FULL_DUPLEX;
@@ -2090,7 +2091,7 @@ static int __devinit b44_get_invariants(struct b44 *bp)
        memcpy(bp->dev->dev_addr, addr, 6);
 
        if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){
-               printk(KERN_ERR PFX "Invalid MAC address found in EEPROM\n");
+               pr_err("Invalid MAC address found in EEPROM\n");
                return -EINVAL;
        }
 
@@ -2108,24 +2109,36 @@ static int __devinit b44_get_invariants(struct b44 *bp)
        return err;
 }
 
+static const struct net_device_ops b44_netdev_ops = {
+       .ndo_open               = b44_open,
+       .ndo_stop               = b44_close,
+       .ndo_start_xmit         = b44_start_xmit,
+       .ndo_get_stats          = b44_get_stats,
+       .ndo_set_multicast_list = b44_set_rx_mode,
+       .ndo_set_mac_address    = b44_set_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_do_ioctl           = b44_ioctl,
+       .ndo_tx_timeout         = b44_tx_timeout,
+       .ndo_change_mtu         = b44_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = b44_poll_controller,
+#endif
+};
+
 static int __devinit b44_init_one(struct ssb_device *sdev,
                                  const struct ssb_device_id *ent)
 {
-       static int b44_version_printed = 0;
        struct net_device *dev;
        struct b44 *bp;
        int err;
-       DECLARE_MAC_BUF(mac);
 
        instance++;
 
-       if (b44_version_printed++ == 0)
-               printk(KERN_INFO "%s", version);
-
+       pr_info_once("%s version %s\n", DRV_DESCRIPTION, DRV_MODULE_VERSION);
 
        dev = alloc_etherdev(sizeof(*bp));
        if (!dev) {
-               dev_err(sdev->dev, "Etherdev alloc failed, aborting.\n");
+               dev_err(sdev->dev, "Etherdev alloc failed, aborting\n");
                err = -ENOMEM;
                goto out;
        }
@@ -2138,6 +2151,7 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
        bp = netdev_priv(dev);
        bp->sdev = sdev;
        bp->dev = dev;
+       bp->force_copybreak = 0;
 
        bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
 
@@ -2146,41 +2160,30 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
        bp->rx_pending = B44_DEF_RX_RING_PENDING;
        bp->tx_pending = B44_DEF_TX_RING_PENDING;
 
-       dev->open = b44_open;
-       dev->stop = b44_close;
-       dev->hard_start_xmit = b44_start_xmit;
-       dev->get_stats = b44_get_stats;
-       dev->set_multicast_list = b44_set_rx_mode;
-       dev->set_mac_address = b44_set_mac_addr;
-       dev->do_ioctl = b44_ioctl;
-       dev->tx_timeout = b44_tx_timeout;
+       dev->netdev_ops = &b44_netdev_ops;
        netif_napi_add(dev, &bp->napi, b44_poll, 64);
        dev->watchdog_timeo = B44_TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = b44_poll_controller;
-#endif
-       dev->change_mtu = b44_change_mtu;
        dev->irq = sdev->irq;
        SET_ETHTOOL_OPS(dev, &b44_ethtool_ops);
 
-       netif_carrier_off(dev);
-
        err = ssb_bus_powerup(sdev->bus, 0);
        if (err) {
                dev_err(sdev->dev,
                        "Failed to powerup the bus\n");
                goto err_out_free_dev;
        }
-       err = ssb_dma_set_mask(sdev, DMA_30BIT_MASK);
-       if (err) {
+
+       if (dma_set_mask(sdev->dma_dev, DMA_BIT_MASK(30)) ||
+           dma_set_coherent_mask(sdev->dma_dev, DMA_BIT_MASK(30))) {
                dev_err(sdev->dev,
-                       "Required 30BIT DMA mask unsupported by the system.\n");
+                       "Required 30BIT DMA mask unsupported by the system\n");
                goto err_out_powerdown;
        }
+
        err = b44_get_invariants(bp);
        if (err) {
                dev_err(sdev->dev,
-                       "Problem fetching invariants of chip, aborting.\n");
+                       "Problem fetching invariants of chip, aborting\n");
                goto err_out_powerdown;
        }
 
@@ -2200,10 +2203,12 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
 
        err = register_netdev(dev);
        if (err) {
-               dev_err(sdev->dev, "Cannot register net device, aborting.\n");
+               dev_err(sdev->dev, "Cannot register net device, aborting\n");
                goto err_out_powerdown;
        }
 
+       netif_carrier_off(dev);
+
        ssb_set_drvdata(sdev, dev);
 
        /* Chip reset provides power to the b44 MAC & PCI cores, which
@@ -2211,8 +2216,11 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
         */
        b44_chip_reset(bp, B44_CHIP_RESET_FULL);
 
-       printk(KERN_INFO "%s: Broadcom 44xx/47xx 10/100BaseT Ethernet %s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
+       /* do a phy reset to test if there is an active phy */
+       if (b44_phy_reset(bp) < 0)
+               bp->phy_addr = B44_PHY_ADDR_NO_PHY;
+
+       netdev_info(dev, "%s %pM\n", DRV_DESCRIPTION, dev->dev_addr);
 
        return 0;
 
@@ -2231,6 +2239,7 @@ static void __devexit b44_remove_one(struct ssb_device *sdev)
        struct net_device *dev = ssb_get_drvdata(sdev);
 
        unregister_netdev(dev);
+       ssb_device_disable(sdev, 0);
        ssb_bus_may_powerdown(sdev->bus);
        free_netdev(dev);
        ssb_pcihost_set_power_state(sdev, PCI_D3hot);
@@ -2282,18 +2291,27 @@ static int b44_resume(struct ssb_device *sdev)
        if (!netif_running(dev))
                return 0;
 
+       spin_lock_irq(&bp->lock);
+       b44_init_rings(bp);
+       b44_init_hw(bp, B44_FULL_RESET);
+       spin_unlock_irq(&bp->lock);
+
+       /*
+        * As a shared interrupt, the handler can be called immediately. To be
+        * able to check the interrupt status the hardware must already be
+        * powered back on (b44_init_hw).
+        */
        rc = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev);
        if (rc) {
-               printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name);
+               netdev_err(dev, "request_irq failed\n");
+               spin_lock_irq(&bp->lock);
+               b44_halt(bp);
+               b44_free_rings(bp);
+               spin_unlock_irq(&bp->lock);
                return rc;
        }
 
-       spin_lock_irq(&bp->lock);
-
-       b44_init_rings(bp);
-       b44_init_hw(bp, B44_FULL_RESET);
        netif_device_attach(bp->dev);
-       spin_unlock_irq(&bp->lock);
 
        b44_enable_ints(bp);
        netif_wake_queue(dev);
@@ -2312,7 +2330,7 @@ static struct ssb_driver b44_ssb_driver = {
        .resume         = b44_resume,
 };
 
-static inline int b44_pci_init(void)
+static inline int __init b44_pci_init(void)
 {
        int err = 0;
 #ifdef CONFIG_B44_PCI
@@ -2321,7 +2339,7 @@ static inline int b44_pci_init(void)
        return err;
 }
 
-static inline void b44_pci_exit(void)
+static inline void __exit b44_pci_exit(void)
 {
 #ifdef CONFIG_B44_PCI
        ssb_pcihost_unregister(&b44_pci_driver);
@@ -2334,7 +2352,6 @@ static int __init b44_init(void)
        int err;
 
        /* Setup paramaters for syncing RX/TX DMA descriptors */
-       dma_desc_align_mask = ~(dma_desc_align_size - 1);
        dma_desc_sync_size = max_t(unsigned int, dma_desc_align_size, sizeof(struct dma_desc));
 
        err = b44_pci_init();