diff options
Diffstat (limited to 'drivers/net/wireless/b43legacy')
| -rw-r--r-- | drivers/net/wireless/b43legacy/b43legacy.h | 55 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/debugfs.c | 10 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/dma.c | 492 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/dma.h | 114 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/ilt.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/leds.c | 6 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 327 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/main.h | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/phy.c | 8 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/phy.h | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/pio.c | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/radio.c | 32 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/radio.h | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/rfkill.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/sysfs.c | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/b43legacy/xmit.c | 31 |
16 files changed, 391 insertions, 702 deletions
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index c81b2f53b0c..482476fdb1f 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -8,13 +8,13 @@ #include <linux/stringify.h> #include <linux/netdevice.h> #include <linux/pci.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <linux/io.h> #include <linux/ssb/ssb.h> #include <linux/ssb/ssb_driver_chipcommon.h> +#include <linux/completion.h> -#include <linux/wireless.h> #include <net/mac80211.h> #include "debugfs.h" @@ -23,10 +23,6 @@ #include "phy.h" -/* The unique identifier of the firmware that's officially supported by this - * driver version. */ -#define B43legacy_SUPPORTED_FIRMWARE_ID "FW10" - #define B43legacy_IRQWAIT_MAX_RETRIES 20 /* MMIO offsets */ @@ -488,7 +484,7 @@ struct b43legacy_phy { /* Current Interference Mitigation mode */ int interfmode; /* Stack of saved values from the Interference Mitigation code. - * Each value in the stack is layed out as follows: + * Each value in the stack is laid out as follows: * bit 0-11: offset * bit 12-15: register ID * bit 16-32: value @@ -532,6 +528,8 @@ struct b43legacy_dma { struct b43legacy_dmaring *rx_ring0; struct b43legacy_dmaring *rx_ring3; /* only on core.rev < 5 */ + + u32 translation; /* Routing bits */ }; /* Data structures for PIO transmission, per 80211 core. */ @@ -563,8 +561,16 @@ struct b43legacy_key { u8 algorithm; }; +#define B43legacy_QOS_QUEUE_NUM 4 + struct b43legacy_wldev; +/* QOS parameters for a queue. */ +struct b43legacy_qos_params { + /* The QOS parameters */ + struct ieee80211_tx_queue_params p; +}; + /* Data structure for the WLAN parts (802.11 cores) of the b43legacy chip. */ struct b43legacy_wl { /* Pointer to the active wireless device on this chip */ @@ -576,6 +582,9 @@ struct b43legacy_wl { struct mutex mutex; /* locks wireless core state */ spinlock_t leds_lock; /* lock for leds */ + /* firmware loading work */ + struct work_struct firmware_load; + /* We can only have one operating interface (802.11 core) * at a time. General information about this interface follows. */ @@ -614,6 +623,18 @@ struct b43legacy_wl { bool beacon1_uploaded; bool beacon_templates_virgin; /* Never wrote the templates? */ struct work_struct beacon_update_trigger; + /* The current QOS parameters for the 4 queues. */ + struct b43legacy_qos_params qos_params[B43legacy_QOS_QUEUE_NUM]; + + /* Packet transmit work */ + struct work_struct tx_work; + + /* Queue of packets to be transmitted. */ + struct sk_buff_head tx_queue[B43legacy_QOS_QUEUE_NUM]; + + /* Flag that implement the queues stopping. */ + bool tx_queue_stopped[B43legacy_QOS_QUEUE_NUM]; + }; /* Pointers to the firmware data and meta information about it. */ @@ -713,6 +734,10 @@ struct b43legacy_wldev { /* Firmware data */ struct b43legacy_firmware fw; + const struct firmware *fwp; /* needed to pass fw pointer */ + + /* completion struct for firmware loading */ + struct completion fw_load_complete; /* Devicelist in struct b43legacy_wl (all 802.11 cores) */ struct list_head list; @@ -813,15 +838,15 @@ struct b43legacy_lopair *b43legacy_get_lopair(struct b43legacy_phy *phy, /* Message printing */ -void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...) - __attribute__((format(printf, 2, 3))); -void b43legacyerr(struct b43legacy_wl *wl, const char *fmt, ...) - __attribute__((format(printf, 2, 3))); -void b43legacywarn(struct b43legacy_wl *wl, const char *fmt, ...) - __attribute__((format(printf, 2, 3))); +__printf(2, 3) +void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...); +__printf(2, 3) +void b43legacyerr(struct b43legacy_wl *wl, const char *fmt, ...); +__printf(2, 3) +void b43legacywarn(struct b43legacy_wl *wl, const char *fmt, ...); #if B43legacy_DEBUG -void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...) - __attribute__((format(printf, 2, 3))); +__printf(2, 3) +void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...); #else /* DEBUG */ # define b43legacydbg(wl, fmt...) do { /* nothing */ } while (0) #endif /* DEBUG */ diff --git a/drivers/net/wireless/b43legacy/debugfs.c b/drivers/net/wireless/b43legacy/debugfs.c index f232618f2cd..1965edb765a 100644 --- a/drivers/net/wireless/b43legacy/debugfs.c +++ b/drivers/net/wireless/b43legacy/debugfs.c @@ -4,7 +4,7 @@ debugfs driver debugging code - Copyright (c) 2005-2007 Michael Buesch <mb@bu3sch.de> + Copyright (c) 2005-2007 Michael Buesch <m@bues.ch> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -197,12 +197,6 @@ static int restart_write_file(struct b43legacy_wldev *dev, const char *buf, size #undef fappend -static int b43legacy_debugfs_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { @@ -331,7 +325,7 @@ out_unlock: .read = _read, \ .write = _write, \ .fops = { \ - .open = b43legacy_debugfs_open, \ + .open = simple_open, \ .read = b43legacy_debugfs_read, \ .write = b43legacy_debugfs_write, \ .llseek = generic_file_llseek, \ diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index e03e01d0bc3..b2ed1795130 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c @@ -4,7 +4,7 @@ DMA ringbuffer and descriptor allocation/management - Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de> + Copyright (c) 2005, 2006 Michael Buesch <m@bues.ch> Some code in this file is derived from the b44.c driver Copyright (C) 2002 David S. Miller @@ -42,10 +42,9 @@ /* 32bit DMA ops. */ static -struct b43legacy_dmadesc_generic *op32_idx2desc( - struct b43legacy_dmaring *ring, - int slot, - struct b43legacy_dmadesc_meta **meta) +struct b43legacy_dmadesc32 *op32_idx2desc(struct b43legacy_dmaring *ring, + int slot, + struct b43legacy_dmadesc_meta **meta) { struct b43legacy_dmadesc32 *desc; @@ -53,11 +52,11 @@ struct b43legacy_dmadesc_generic *op32_idx2desc( desc = ring->descbase; desc = &(desc[slot]); - return (struct b43legacy_dmadesc_generic *)desc; + return desc; } static void op32_fill_descriptor(struct b43legacy_dmaring *ring, - struct b43legacy_dmadesc_generic *desc, + struct b43legacy_dmadesc32 *desc, dma_addr_t dmaaddr, u16 bufsize, int start, int end, int irq) { @@ -67,13 +66,13 @@ static void op32_fill_descriptor(struct b43legacy_dmaring *ring, u32 addr; u32 addrext; - slot = (int)(&(desc->dma32) - descbase); + slot = (int)(desc - descbase); B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); addr = (u32)(dmaaddr & ~SSB_DMA_TRANSLATION_MASK); addrext = (u32)(dmaaddr & SSB_DMA_TRANSLATION_MASK) >> SSB_DMA_TRANSLATION_SHIFT; - addr |= ssb_dma_translation(ring->dev->dev); + addr |= ring->dev->dma.translation; ctl = (bufsize - ring->frameoffset) & B43legacy_DMA32_DCTL_BYTECNT; if (slot == ring->nr_slots - 1) @@ -87,8 +86,8 @@ static void op32_fill_descriptor(struct b43legacy_dmaring *ring, ctl |= (addrext << B43legacy_DMA32_DCTL_ADDREXT_SHIFT) & B43legacy_DMA32_DCTL_ADDREXT_MASK; - desc->dma32.control = cpu_to_le32(ctl); - desc->dma32.address = cpu_to_le32(addr); + desc->control = cpu_to_le32(ctl); + desc->address = cpu_to_le32(addr); } static void op32_poke_tx(struct b43legacy_dmaring *ring, int slot) @@ -128,121 +127,6 @@ static void op32_set_current_rxslot(struct b43legacy_dmaring *ring, (u32)(slot * sizeof(struct b43legacy_dmadesc32))); } -static const struct b43legacy_dma_ops dma32_ops = { - .idx2desc = op32_idx2desc, - .fill_descriptor = op32_fill_descriptor, - .poke_tx = op32_poke_tx, - .tx_suspend = op32_tx_suspend, - .tx_resume = op32_tx_resume, - .get_current_rxslot = op32_get_current_rxslot, - .set_current_rxslot = op32_set_current_rxslot, -}; - -/* 64bit DMA ops. */ -static -struct b43legacy_dmadesc_generic *op64_idx2desc( - struct b43legacy_dmaring *ring, - int slot, - struct b43legacy_dmadesc_meta - **meta) -{ - struct b43legacy_dmadesc64 *desc; - - *meta = &(ring->meta[slot]); - desc = ring->descbase; - desc = &(desc[slot]); - - return (struct b43legacy_dmadesc_generic *)desc; -} - -static void op64_fill_descriptor(struct b43legacy_dmaring *ring, - struct b43legacy_dmadesc_generic *desc, - dma_addr_t dmaaddr, u16 bufsize, - int start, int end, int irq) -{ - struct b43legacy_dmadesc64 *descbase = ring->descbase; - int slot; - u32 ctl0 = 0; - u32 ctl1 = 0; - u32 addrlo; - u32 addrhi; - u32 addrext; - - slot = (int)(&(desc->dma64) - descbase); - B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); - - addrlo = (u32)(dmaaddr & 0xFFFFFFFF); - addrhi = (((u64)dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK); - addrext = (((u64)dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK) - >> SSB_DMA_TRANSLATION_SHIFT; - addrhi |= ssb_dma_translation(ring->dev->dev); - if (slot == ring->nr_slots - 1) - ctl0 |= B43legacy_DMA64_DCTL0_DTABLEEND; - if (start) - ctl0 |= B43legacy_DMA64_DCTL0_FRAMESTART; - if (end) - ctl0 |= B43legacy_DMA64_DCTL0_FRAMEEND; - if (irq) - ctl0 |= B43legacy_DMA64_DCTL0_IRQ; - ctl1 |= (bufsize - ring->frameoffset) - & B43legacy_DMA64_DCTL1_BYTECNT; - ctl1 |= (addrext << B43legacy_DMA64_DCTL1_ADDREXT_SHIFT) - & B43legacy_DMA64_DCTL1_ADDREXT_MASK; - - desc->dma64.control0 = cpu_to_le32(ctl0); - desc->dma64.control1 = cpu_to_le32(ctl1); - desc->dma64.address_low = cpu_to_le32(addrlo); - desc->dma64.address_high = cpu_to_le32(addrhi); -} - -static void op64_poke_tx(struct b43legacy_dmaring *ring, int slot) -{ - b43legacy_dma_write(ring, B43legacy_DMA64_TXINDEX, - (u32)(slot * sizeof(struct b43legacy_dmadesc64))); -} - -static void op64_tx_suspend(struct b43legacy_dmaring *ring) -{ - b43legacy_dma_write(ring, B43legacy_DMA64_TXCTL, - b43legacy_dma_read(ring, B43legacy_DMA64_TXCTL) - | B43legacy_DMA64_TXSUSPEND); -} - -static void op64_tx_resume(struct b43legacy_dmaring *ring) -{ - b43legacy_dma_write(ring, B43legacy_DMA64_TXCTL, - b43legacy_dma_read(ring, B43legacy_DMA64_TXCTL) - & ~B43legacy_DMA64_TXSUSPEND); -} - -static int op64_get_current_rxslot(struct b43legacy_dmaring *ring) -{ - u32 val; - - val = b43legacy_dma_read(ring, B43legacy_DMA64_RXSTATUS); - val &= B43legacy_DMA64_RXSTATDPTR; - - return (val / sizeof(struct b43legacy_dmadesc64)); -} - -static void op64_set_current_rxslot(struct b43legacy_dmaring *ring, - int slot) -{ - b43legacy_dma_write(ring, B43legacy_DMA64_RXINDEX, - (u32)(slot * sizeof(struct b43legacy_dmadesc64))); -} - -static const struct b43legacy_dma_ops dma64_ops = { - .idx2desc = op64_idx2desc, - .fill_descriptor = op64_fill_descriptor, - .poke_tx = op64_poke_tx, - .tx_suspend = op64_tx_suspend, - .tx_resume = op64_tx_resume, - .get_current_rxslot = op64_get_current_rxslot, - .set_current_rxslot = op64_set_current_rxslot, -}; - - static inline int free_slots(struct b43legacy_dmaring *ring) { return (ring->nr_slots - ring->used_slots); @@ -358,14 +242,6 @@ return 0; static u16 b43legacy_dmacontroller_base(enum b43legacy_dmatype type, int controller_idx) { - static const u16 map64[] = { - B43legacy_MMIO_DMA64_BASE0, - B43legacy_MMIO_DMA64_BASE1, - B43legacy_MMIO_DMA64_BASE2, - B43legacy_MMIO_DMA64_BASE3, - B43legacy_MMIO_DMA64_BASE4, - B43legacy_MMIO_DMA64_BASE5, - }; static const u16 map32[] = { B43legacy_MMIO_DMA32_BASE0, B43legacy_MMIO_DMA32_BASE1, @@ -375,11 +251,6 @@ static u16 b43legacy_dmacontroller_base(enum b43legacy_dmatype type, B43legacy_MMIO_DMA32_BASE5, }; - if (type == B43legacy_DMA_64BIT) { - B43legacy_WARN_ON(!(controller_idx >= 0 && - controller_idx < ARRAY_SIZE(map64))); - return map64[controller_idx]; - } B43legacy_WARN_ON(!(controller_idx >= 0 && controller_idx < ARRAY_SIZE(map32))); return map32[controller_idx]; @@ -460,16 +331,11 @@ void free_descriptor_buffer(struct b43legacy_dmaring *ring, static int alloc_ringmemory(struct b43legacy_dmaring *ring) { /* GFP flags must match the flags in free_ringmemory()! */ - ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev, - B43legacy_DMA_RINGMEMSIZE, - &(ring->dmabase), - GFP_KERNEL); - if (!ring->descbase) { - b43legacyerr(ring->dev->wl, "DMA ringmemory allocation" - " failed\n"); + ring->descbase = dma_zalloc_coherent(ring->dev->dev->dma_dev, + B43legacy_DMA_RINGMEMSIZE, + &(ring->dmabase), GFP_KERNEL); + if (!ring->descbase) return -ENOMEM; - } - memset(ring->descbase, 0, B43legacy_DMA_RINGMEMSIZE); return 0; } @@ -491,25 +357,15 @@ static int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev, might_sleep(); - offset = (type == B43legacy_DMA_64BIT) ? - B43legacy_DMA64_RXCTL : B43legacy_DMA32_RXCTL; + offset = B43legacy_DMA32_RXCTL; b43legacy_write32(dev, mmio_base + offset, 0); for (i = 0; i < 10; i++) { - offset = (type == B43legacy_DMA_64BIT) ? - B43legacy_DMA64_RXSTATUS : B43legacy_DMA32_RXSTATUS; + offset = B43legacy_DMA32_RXSTATUS; value = b43legacy_read32(dev, mmio_base + offset); - if (type == B43legacy_DMA_64BIT) { - value &= B43legacy_DMA64_RXSTAT; - if (value == B43legacy_DMA64_RXSTAT_DISABLED) { - i = -1; - break; - } - } else { - value &= B43legacy_DMA32_RXSTATE; - if (value == B43legacy_DMA32_RXSTAT_DISABLED) { - i = -1; - break; - } + value &= B43legacy_DMA32_RXSTATE; + if (value == B43legacy_DMA32_RXSTAT_DISABLED) { + i = -1; + break; } msleep(1); } @@ -533,43 +389,24 @@ static int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, might_sleep(); for (i = 0; i < 10; i++) { - offset = (type == B43legacy_DMA_64BIT) ? - B43legacy_DMA64_TXSTATUS : B43legacy_DMA32_TXSTATUS; + offset = B43legacy_DMA32_TXSTATUS; value = b43legacy_read32(dev, mmio_base + offset); - if (type == B43legacy_DMA_64BIT) { - value &= B43legacy_DMA64_TXSTAT; - if (value == B43legacy_DMA64_TXSTAT_DISABLED || - value == B43legacy_DMA64_TXSTAT_IDLEWAIT || - value == B43legacy_DMA64_TXSTAT_STOPPED) - break; - } else { - value &= B43legacy_DMA32_TXSTATE; - if (value == B43legacy_DMA32_TXSTAT_DISABLED || - value == B43legacy_DMA32_TXSTAT_IDLEWAIT || - value == B43legacy_DMA32_TXSTAT_STOPPED) - break; - } + value &= B43legacy_DMA32_TXSTATE; + if (value == B43legacy_DMA32_TXSTAT_DISABLED || + value == B43legacy_DMA32_TXSTAT_IDLEWAIT || + value == B43legacy_DMA32_TXSTAT_STOPPED) + break; msleep(1); } - offset = (type == B43legacy_DMA_64BIT) ? B43legacy_DMA64_TXCTL : - B43legacy_DMA32_TXCTL; + offset = B43legacy_DMA32_TXCTL; b43legacy_write32(dev, mmio_base + offset, 0); for (i = 0; i < 10; i++) { - offset = (type == B43legacy_DMA_64BIT) ? - B43legacy_DMA64_TXSTATUS : B43legacy_DMA32_TXSTATUS; + offset = B43legacy_DMA32_TXSTATUS; value = b43legacy_read32(dev, mmio_base + offset); - if (type == B43legacy_DMA_64BIT) { - value &= B43legacy_DMA64_TXSTAT; - if (value == B43legacy_DMA64_TXSTAT_DISABLED) { - i = -1; - break; - } - } else { - value &= B43legacy_DMA32_TXSTATE; - if (value == B43legacy_DMA32_TXSTAT_DISABLED) { - i = -1; - break; - } + value &= B43legacy_DMA32_TXSTATE; + if (value == B43legacy_DMA32_TXSTAT_DISABLED) { + i = -1; + break; } msleep(1); } @@ -601,9 +438,6 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring, if ((u64)addr + buffersize > (1ULL << 32)) goto address_error; break; - case B43legacy_DMA_64BIT: - /* Currently we can't have addresses beyond 64 bits in the kernel. */ - break; } /* The address is OK. */ @@ -617,7 +451,7 @@ address_error: } static int setup_rx_descbuffer(struct b43legacy_dmaring *ring, - struct b43legacy_dmadesc_generic *desc, + struct b43legacy_dmadesc32 *desc, struct b43legacy_dmadesc_meta *meta, gfp_t gfp_flags) { @@ -653,8 +487,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring, meta->skb = skb; meta->dmaaddr = dmaaddr; - ring->ops->fill_descriptor(ring, desc, dmaaddr, - ring->rx_buffersize, 0, 0, 0); + op32_fill_descriptor(ring, desc, dmaaddr, ring->rx_buffersize, 0, 0, 0); rxhdr = (struct b43legacy_rxhdr_fw3 *)(skb->data); rxhdr->frame_len = 0; @@ -671,11 +504,11 @@ static int alloc_initial_descbuffers(struct b43legacy_dmaring *ring) { int i; int err = -ENOMEM; - struct b43legacy_dmadesc_generic *desc; + struct b43legacy_dmadesc32 *desc; struct b43legacy_dmadesc_meta *meta; for (i = 0; i < ring->nr_slots; i++) { - desc = ring->ops->idx2desc(ring, i, &meta); + desc = op32_idx2desc(ring, i, &meta); err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL); if (err) { @@ -692,7 +525,7 @@ out: err_unwind: for (i--; i >= 0; i--) { - desc = ring->ops->idx2desc(ring, i, &meta); + desc = op32_idx2desc(ring, i, &meta); unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0); dev_kfree_skb(meta->skb); @@ -709,84 +542,36 @@ static int dmacontroller_setup(struct b43legacy_dmaring *ring) int err = 0; u32 value; u32 addrext; - u32 trans = ssb_dma_translation(ring->dev->dev); + u32 trans = ring->dev->dma.translation; + u32 ringbase = (u32)(ring->dmabase); if (ring->tx) { - if (ring->type == B43legacy_DMA_64BIT) { - u64 ringbase = (u64)(ring->dmabase); - - addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK) - >> SSB_DMA_TRANSLATION_SHIFT; - value = B43legacy_DMA64_TXENABLE; - value |= (addrext << B43legacy_DMA64_TXADDREXT_SHIFT) - & B43legacy_DMA64_TXADDREXT_MASK; - b43legacy_dma_write(ring, B43legacy_DMA64_TXCTL, - value); - b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGLO, - (ringbase & 0xFFFFFFFF)); - b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGHI, - ((ringbase >> 32) - & ~SSB_DMA_TRANSLATION_MASK) - | trans); - } else { - u32 ringbase = (u32)(ring->dmabase); - - addrext = (ringbase & SSB_DMA_TRANSLATION_MASK) - >> SSB_DMA_TRANSLATION_SHIFT; - value = B43legacy_DMA32_TXENABLE; - value |= (addrext << B43legacy_DMA32_TXADDREXT_SHIFT) - & B43legacy_DMA32_TXADDREXT_MASK; - b43legacy_dma_write(ring, B43legacy_DMA32_TXCTL, - value); - b43legacy_dma_write(ring, B43legacy_DMA32_TXRING, - (ringbase & - ~SSB_DMA_TRANSLATION_MASK) - | trans); - } + addrext = (ringbase & SSB_DMA_TRANSLATION_MASK) + >> SSB_DMA_TRANSLATION_SHIFT; + value = B43legacy_DMA32_TXENABLE; + value |= (addrext << B43legacy_DMA32_TXADDREXT_SHIFT) + & B43legacy_DMA32_TXADDREXT_MASK; + b43legacy_dma_write(ring, B43legacy_DMA32_TXCTL, value); + b43legacy_dma_write(ring, B43legacy_DMA32_TXRING, + (ringbase & ~SSB_DMA_TRANSLATION_MASK) + | trans); } else { err = alloc_initial_descbuffers(ring); if (err) goto out; - if (ring->type == B43legacy_DMA_64BIT) { - u64 ringbase = (u64)(ring->dmabase); - - addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK) - >> SSB_DMA_TRANSLATION_SHIFT; - value = (ring->frameoffset << - B43legacy_DMA64_RXFROFF_SHIFT); - value |= B43legacy_DMA64_RXENABLE; - value |= (addrext << B43legacy_DMA64_RXADDREXT_SHIFT) - & B43legacy_DMA64_RXADDREXT_MASK; - b43legacy_dma_write(ring, B43legacy_DMA64_RXCTL, - value); - b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGLO, - (ringbase & 0xFFFFFFFF)); - b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGHI, - ((ringbase >> 32) & - ~SSB_DMA_TRANSLATION_MASK) | - trans); - b43legacy_dma_write(ring, B43legacy_DMA64_RXINDEX, - 200); - } else { - u32 ringbase = (u32)(ring->dmabase); - - addrext = (ringbase & SSB_DMA_TRANSLATION_MASK) - >> SSB_DMA_TRANSLATION_SHIFT; - value = (ring->frameoffset << - B43legacy_DMA32_RXFROFF_SHIFT); - value |= B43legacy_DMA32_RXENABLE; - value |= (addrext << - B43legacy_DMA32_RXADDREXT_SHIFT) - & B43legacy_DMA32_RXADDREXT_MASK; - b43legacy_dma_write(ring, B43legacy_DMA32_RXCTL, - value); - b43legacy_dma_write(ring, B43legacy_DMA32_RXRING, - (ringbase & - ~SSB_DMA_TRANSLATION_MASK) - | trans); - b43legacy_dma_write(ring, B43legacy_DMA32_RXINDEX, - 200); - } + + addrext = (ringbase & SSB_DMA_TRANSLATION_MASK) + >> SSB_DMA_TRANSLATION_SHIFT; + value = (ring->frameoffset << + B43legacy_DMA32_RXFROFF_SHIFT); + value |= B43legacy_DMA32_RXENABLE; + value |= (addrext << B43legacy_DMA32_RXADDREXT_SHIFT) + & B43legacy_DMA32_RXADDREXT_MASK; + b43legacy_dma_write(ring, B43legacy_DMA32_RXCTL, value); + b43legacy_dma_write(ring, B43legacy_DMA32_RXRING, + (ringbase & ~SSB_DMA_TRANSLATION_MASK) + | trans); + b43legacy_dma_write(ring, B43legacy_DMA32_RXINDEX, 200); } out: @@ -799,32 +584,23 @@ static void dmacontroller_cleanup(struct b43legacy_dmaring *ring) if (ring->tx) { b43legacy_dmacontroller_tx_reset(ring->dev, ring->mmio_base, ring->type); - if (ring->type == B43legacy_DMA_64BIT) { - b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGLO, 0); - b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGHI, 0); - } else - b43legacy_dma_write(ring, B43legacy_DMA32_TXRING, 0); + b43legacy_dma_write(ring, B43legacy_DMA32_TXRING, 0); } else { b43legacy_dmacontroller_rx_reset(ring->dev, ring->mmio_base, ring->type); - if (ring->type == B43legacy_DMA_64BIT) { - b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGLO, 0); - b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGHI, 0); - } else - b43legacy_dma_write(ring, B43legacy_DMA32_RXRING, 0); + b43legacy_dma_write(ring, B43legacy_DMA32_RXRING, 0); } } static void free_all_descbuffers(struct b43legacy_dmaring *ring) { - struct b43legacy_dmadesc_generic *desc; struct b43legacy_dmadesc_meta *meta; int i; if (!ring->used_slots) return; for (i = 0; i < ring->nr_slots; i++) { - desc = ring->ops->idx2desc(ring, i, &meta); + op32_idx2desc(ring, i, &meta); if (!meta->skb) { B43legacy_WARN_ON(!ring->tx); @@ -845,9 +621,6 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev) u32 tmp; u16 mmio_base; - tmp = b43legacy_read32(dev, SSB_TMSHIGH); - if (tmp & SSB_TMSHIGH_DMA64) - return DMA_BIT_MASK(64); mmio_base = b43legacy_dmacontroller_base(0, 0); b43legacy_write32(dev, mmio_base + B43legacy_DMA32_TXCTL, @@ -866,8 +639,6 @@ static enum b43legacy_dmatype dma_mask_to_engine_type(u64 dmamask) return B43legacy_DMA_30BIT; if (dmamask == DMA_BIT_MASK(32)) return B43legacy_DMA_32BIT; - if (dmamask == DMA_BIT_MASK(64)) - return B43legacy_DMA_64BIT; B43legacy_WARN_ON(1); return B43legacy_DMA_30BIT; } @@ -938,12 +709,8 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, ring->nr_slots = nr_slots; ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index); ring->index = controller_index; - if (type == B43legacy_DMA_64BIT) - ring->ops = &dma64_ops; - else - ring->ops = &dma32_ops; if (for_tx) { - ring->tx = 1; + ring->tx = true; ring->current_slot = -1; } else { if (ring->index == 0) { @@ -955,7 +722,6 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, } else B43legacy_WARN_ON(1); } - spin_lock_init(&ring->lock); #ifdef CONFIG_B43LEGACY_DEBUG ring->last_injected_overflow = jiffies; #endif @@ -1034,26 +800,23 @@ void b43legacy_dma_free(struct b43legacy_wldev *dev) static int b43legacy_dma_set_mask(struct b43legacy_wldev *dev, u64 mask) { u64 orig_mask = mask; - bool fallback = 0; + bool fallback = false; int err; /* Try to set the DMA mask. If it fails, try falling back to a * lower mask, as we can always also support a lower one. */ while (1) { - err = dma_set_mask(dev->dev->dma_dev, mask); - if (!err) { - err = dma_set_coherent_mask(dev->dev->dma_dev, mask); - if (!err) - break; - } + err = dma_set_mask_and_coherent(dev->dev->dma_dev, mask); + if (!err) + break; if (mask == DMA_BIT_MASK(64)) { mask = DMA_BIT_MASK(32); - fallback = 1; + fallback = true; continue; } if (mask == DMA_BIT_MASK(32)) { mask = DMA_BIT_MASK(30); - fallback = 1; + fallback = true; continue; } b43legacyerr(dev->wl, "The machine/kernel does not support " @@ -1086,7 +849,7 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev) #ifdef CONFIG_B43LEGACY_PIO b43legacywarn(dev->wl, "DMA for this device not supported. " "Falling back to PIO\n"); - dev->__using_pio = 1; + dev->__using_pio = true; return -EAGAIN; #else b43legacyerr(dev->wl, "DMA for this device not supported and " @@ -1094,6 +857,7 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev) return -EOPNOTSUPP; #endif } + dma->translation = ssb_dma_translation(dev->dev); err = -ENOMEM; /* setup TX DMA channels. */ @@ -1247,12 +1011,11 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, struct sk_buff **in_skb) { struct sk_buff *skb = *in_skb; - const struct b43legacy_dma_ops *ops = ring->ops; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); u8 *header; int slot, old_top_slot, old_used_slots; int err; - struct b43legacy_dmadesc_generic *desc; + struct b43legacy_dmadesc32 *desc; struct b43legacy_dmadesc_meta *meta; struct b43legacy_dmadesc_meta *meta_hdr; struct sk_buff *bounce_skb; @@ -1265,7 +1028,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, /* Get a slot for the header. */ slot = request_slot(ring); - desc = ops->idx2desc(ring, slot, &meta_hdr); + desc = op32_idx2desc(ring, slot, &meta_hdr); memset(meta_hdr, 0, sizeof(*meta_hdr)); header = &(ring->txhdr_cache[slot * sizeof( @@ -1287,21 +1050,21 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, ring->used_slots = old_used_slots; return -EIO; } - ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr, + op32_fill_descriptor(ring, desc, meta_hdr->dmaaddr, sizeof(struct b43legacy_txhdr_fw3), 1, 0, 0); /* Get a slot for the payload. */ slot = request_slot(ring); - desc = ops->idx2desc(ring, slot, &meta); + desc = op32_idx2desc(ring, slot, &meta); memset(meta, 0, sizeof(*meta)); meta->skb = skb; - meta->is_last_fragment = 1; + meta->is_last_fragment = true; meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); /* create a bounce buffer in zone_dma on mapping failure. */ if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { - bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); + bounce_skb = alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); if (!bounce_skb) { ring->current_slot = old_top_slot; ring->used_slots = old_used_slots; @@ -1328,12 +1091,12 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, } } - ops->fill_descriptor(ring, desc, meta->dmaaddr, + op32_fill_descriptor(ring, desc, meta->dmaaddr, skb->len, 0, 1, 1); wmb(); /* previous stuff MUST be done */ /* Now transfer the whole frame. */ - ops->poke_tx(ring, next_slot(ring, slot)); + op32_poke_tx(ring, next_slot(ring, slot)); return 0; out_free_bounce: @@ -1371,13 +1134,9 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev, struct sk_buff *skb) { struct b43legacy_dmaring *ring; - struct ieee80211_hdr *hdr; int err = 0; - unsigned long flags; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ring = priority_to_txring(dev, skb_get_queue_mapping(skb)); - spin_lock_irqsave(&ring->lock, flags); B43legacy_WARN_ON(!ring->tx); if (unlikely(ring->stopped)) { @@ -1387,70 +1146,76 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev, * For now, just refuse the transmit. */ if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE)) b43legacyerr(dev->wl, "Packet after queue stopped\n"); - err = -ENOSPC; - goto out_unlock; + return -ENOSPC; } if (unlikely(WARN_ON(free_slots(ring) < SLOTS_PER_PACKET))) { /* If we get here, we have a real error with the queue * full, but queues not stopped. */ b43legacyerr(dev->wl, "DMA queue overflow\n"); - err = -ENOSPC; - goto out_unlock; + return -ENOSPC; } /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing * into the skb data or cb now. */ - hdr = NULL; - info = NULL; err = dma_tx_fragment(ring, &skb); if (unlikely(err == -ENOKEY)) { /* Drop this packet, as we don't have the encryption key * anymore and must not transmit it unencrypted. */ dev_kfree_skb_any(skb); - err = 0; - goto out_unlock; + return 0; } if (unlikely(err)) { b43legacyerr(dev->wl, "DMA tx mapping failure\n"); - goto out_unlock; + return err; } if ((free_slots(ring) < SLOTS_PER_PACKET) || should_inject_overflow(ring)) { /* This TX ring is full. */ - ieee80211_stop_queue(dev->wl->hw, txring_to_priority(ring)); - ring->stopped = 1; + unsigned int skb_mapping = skb_get_queue_mapping(skb); + ieee80211_stop_queue(dev->wl->hw, skb_mapping); + dev->wl->tx_queue_stopped[skb_mapping] = 1; + ring->stopped = true; if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE)) b43legacydbg(dev->wl, "Stopped TX ring %d\n", ring->index); } -out_unlock: - spin_unlock_irqrestore(&ring->lock, flags); - return err; } void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, const struct b43legacy_txstatus *status) { - const struct b43legacy_dma_ops *ops; struct b43legacy_dmaring *ring; - struct b43legacy_dmadesc_generic *desc; struct b43legacy_dmadesc_meta *meta; int retry_limit; int slot; + int firstused; ring = parse_cookie(dev, status->cookie, &slot); if (unlikely(!ring)) return; - B43legacy_WARN_ON(!irqs_disabled()); - spin_lock(&ring->lock); - B43legacy_WARN_ON(!ring->tx); - ops = ring->ops; + + /* Sanity check: TX packets are processed in-order on one ring. + * Check if the slot deduced from the cookie really is the first + * used slot. */ + firstused = ring->current_slot - ring->used_slots + 1; + if (firstused < 0) + firstused = ring->nr_slots + firstused; + if (unlikely(slot != firstused)) { + /* This possibly is a firmware bug and will result in + * malfunction, memory leaks and/or stall of DMA functionality. + */ + b43legacydbg(dev->wl, "Out of order TX status report on DMA " + "ring %d. Expected %d, but got %d\n", + ring->index, firstused, slot); + return; + } + while (1) { B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); - desc = ops->idx2desc(ring, slot, &meta); + op32_idx2desc(ring, slot, &meta); if (meta->skb) unmap_descbuffer(ring, meta->dmaaddr, @@ -1520,21 +1285,27 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, dev->stats.last_tx = jiffies; if (ring->stopped) { B43legacy_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET); - ieee80211_wake_queue(dev->wl->hw, txring_to_priority(ring)); - ring->stopped = 0; + ring->stopped = false; + } + + if (dev->wl->tx_queue_stopped[ring->queue_prio]) { + dev->wl->tx_queue_stopped[ring->queue_prio] = 0; + } else { + /* If the driver queue is running wake the corresponding + * mac80211 queue. */ + ieee80211_wake_queue(dev->wl->hw, ring->queue_prio); if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE)) b43legacydbg(dev->wl, "Woke up TX ring %d\n", - ring->index); + ring->index); } - - spin_unlock(&ring->lock); + /* Add work to the queue. */ + ieee80211_queue_work(dev->wl->hw, &dev->wl->tx_work); } static void dma_rx(struct b43legacy_dmaring *ring, int *slot) { - const struct b43legacy_dma_ops *ops = ring->ops; - struct b43legacy_dmadesc_generic *desc; + struct b43legacy_dmadesc32 *desc; struct b43legacy_dmadesc_meta *meta; struct b43legacy_rxhdr_fw3 *rxhdr; struct sk_buff *skb; @@ -1542,7 +1313,7 @@ static void dma_rx(struct b43legacy_dmaring *ring, int err; dma_addr_t dmaaddr; - desc = ops->idx2desc(ring, *slot, &meta); + desc = op32_idx2desc(ring, *slot, &meta); sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize); skb = meta->skb; @@ -1594,7 +1365,7 @@ static void dma_rx(struct b43legacy_dmaring *ring, s32 tmp = len; while (1) { - desc = ops->idx2desc(ring, *slot, &meta); + desc = op32_idx2desc(ring, *slot, &meta); /* recycle the descriptor buffer. */ sync_descbuffer_for_device(ring, meta->dmaaddr, ring->rx_buffersize); @@ -1631,13 +1402,12 @@ drop: void b43legacy_dma_rx(struct b43legacy_dmaring *ring) { - const struct b43legacy_dma_ops *ops = ring->ops; int slot; int current_slot; int used_slots = 0; B43legacy_WARN_ON(ring->tx); - current_slot = ops->get_current_rxslot(ring); + current_slot = op32_get_current_rxslot(ring); B43legacy_WARN_ON(!(current_slot >= 0 && current_slot < ring->nr_slots)); @@ -1646,28 +1416,20 @@ void b43legacy_dma_rx(struct b43legacy_dmaring *ring) dma_rx(ring, &slot); update_max_used_slots(ring, ++used_slots); } - ops->set_current_rxslot(ring, slot); + op32_set_current_rxslot(ring, slot); ring->current_slot = slot; } static void b43legacy_dma_tx_suspend_ring(struct b43legacy_dmaring *ring) { - unsigned long flags; - - spin_lock_irqsave(&ring->lock, flags); B43legacy_WARN_ON(!ring->tx); - ring->ops->tx_suspend(ring); - spin_unlock_irqrestore(&ring->lock, flags); + op32_tx_suspend(ring); } static void b43legacy_dma_tx_resume_ring(struct b43legacy_dmaring *ring) { - unsigned long flags; - - spin_lock_irqsave(&ring->lock, flags); B43legacy_WARN_ON(!ring->tx); - ring->ops->tx_resume(ring); - spin_unlock_irqrestore(&ring->lock, flags); + op32_tx_resume(ring); } void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev) diff --git a/drivers/net/wireless/b43legacy/dma.h b/drivers/net/wireless/b43legacy/dma.h index f89c3422628..c3282f906bc 100644 --- a/drivers/net/wireless/b43legacy/dma.h +++ b/drivers/net/wireless/b43legacy/dma.h @@ -5,7 +5,7 @@ #include <linux/spinlock.h> #include <linux/workqueue.h> #include <linux/linkage.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include "b43legacy.h" @@ -82,90 +82,6 @@ struct b43legacy_dmadesc32 { #define B43legacy_DMA32_DCTL_FRAMESTART 0x80000000 - -/*** 64-bit DMA Engine. ***/ - -/* 64-bit DMA controller registers. */ -#define B43legacy_DMA64_TXCTL 0x00 -#define B43legacy_DMA64_TXENABLE 0x00000001 -#define B43legacy_DMA64_TXSUSPEND 0x00000002 -#define B43legacy_DMA64_TXLOOPBACK 0x00000004 -#define B43legacy_DMA64_TXFLUSH 0x00000010 -#define B43legacy_DMA64_TXADDREXT_MASK 0x00030000 -#define B43legacy_DMA64_TXADDREXT_SHIFT 16 -#define B43legacy_DMA64_TXINDEX 0x04 -#define B43legacy_DMA64_TXRINGLO 0x08 -#define B43legacy_DMA64_TXRINGHI 0x0C -#define B43legacy_DMA64_TXSTATUS 0x10 -#define B43legacy_DMA64_TXSTATDPTR 0x00001FFF -#define B43legacy_DMA64_TXSTAT 0xF0000000 -#define B43legacy_DMA64_TXSTAT_DISABLED 0x00000000 -#define B43legacy_DMA64_TXSTAT_ACTIVE 0x10000000 -#define B43legacy_DMA64_TXSTAT_IDLEWAIT 0x20000000 -#define B43legacy_DMA64_TXSTAT_STOPPED 0x30000000 -#define B43legacy_DMA64_TXSTAT_SUSP 0x40000000 -#define B43legacy_DMA64_TXERROR 0x14 -#define B43legacy_DMA64_TXERRDPTR 0x0001FFFF -#define B43legacy_DMA64_TXERR 0xF0000000 -#define B43legacy_DMA64_TXERR_NOERR 0x00000000 -#define B43legacy_DMA64_TXERR_PROT 0x10000000 -#define B43legacy_DMA64_TXERR_UNDERRUN 0x20000000 -#define B43legacy_DMA64_TXERR_TRANSFER 0x30000000 -#define B43legacy_DMA64_TXERR_DESCREAD 0x40000000 -#define B43legacy_DMA64_TXERR_CORE 0x50000000 -#define B43legacy_DMA64_RXCTL 0x20 -#define B43legacy_DMA64_RXENABLE 0x00000001 -#define B43legacy_DMA64_RXFROFF_MASK 0x000000FE -#define B43legacy_DMA64_RXFROFF_SHIFT 1 -#define B43legacy_DMA64_RXDIRECTFIFO 0x00000100 -#define B43legacy_DMA64_RXADDREXT_MASK 0x00030000 -#define B43legacy_DMA64_RXADDREXT_SHIFT 16 -#define B43legacy_DMA64_RXINDEX 0x24 -#define B43legacy_DMA64_RXRINGLO 0x28 -#define B43legacy_DMA64_RXRINGHI 0x2C -#define B43legacy_DMA64_RXSTATUS 0x30 -#define B43legacy_DMA64_RXSTATDPTR 0x00001FFF -#define B43legacy_DMA64_RXSTAT 0xF0000000 -#define B43legacy_DMA64_RXSTAT_DISABLED 0x00000000 -#define B43legacy_DMA64_RXSTAT_ACTIVE 0x10000000 -#define B43legacy_DMA64_RXSTAT_IDLEWAIT 0x20000000 -#define B43legacy_DMA64_RXSTAT_STOPPED 0x30000000 -#define B43legacy_DMA64_RXSTAT_SUSP 0x40000000 -#define B43legacy_DMA64_RXERROR 0x34 -#define B43legacy_DMA64_RXERRDPTR 0x0001FFFF -#define B43legacy_DMA64_RXERR 0xF0000000 -#define B43legacy_DMA64_RXERR_NOERR 0x00000000 -#define B43legacy_DMA64_RXERR_PROT 0x10000000 -#define B43legacy_DMA64_RXERR_UNDERRUN 0x20000000 -#define B43legacy_DMA64_RXERR_TRANSFER 0x30000000 -#define B43legacy_DMA64_RXERR_DESCREAD 0x40000000 -#define B43legacy_DMA64_RXERR_CORE 0x50000000 - -/* 64-bit DMA descriptor. */ -struct b43legacy_dmadesc64 { - __le32 control0; - __le32 control1; - __le32 address_low; - __le32 address_high; -} __packed; -#define B43legacy_DMA64_DCTL0_DTABLEEND 0x10000000 -#define B43legacy_DMA64_DCTL0_IRQ 0x20000000 -#define B43legacy_DMA64_DCTL0_FRAMEEND 0x40000000 -#define B43legacy_DMA64_DCTL0_FRAMESTART 0x80000000 -#define B43legacy_DMA64_DCTL1_BYTECNT 0x00001FFF -#define B43legacy_DMA64_DCTL1_ADDREXT_MASK 0x00030000 -#define B43legacy_DMA64_DCTL1_ADDREXT_SHIFT 16 - - - -struct b43legacy_dmadesc_generic { - union { - struct b43legacy_dmadesc32 dma32; - struct b43legacy_dmadesc64 dma64; - } __packed; -} __packed; - - /* Misc DMA constants */ #define B43legacy_DMA_RINGMEMSIZE PAGE_SIZE #define B43legacy_DMA0_RX_FRAMEOFFSET 30 @@ -197,35 +113,12 @@ struct b43legacy_dmadesc_meta { bool is_last_fragment; }; -struct b43legacy_dmaring; - -/* Lowlevel DMA operations that differ between 32bit and 64bit DMA. */ -struct b43legacy_dma_ops { - struct b43legacy_dmadesc_generic * (*idx2desc) - (struct b43legacy_dmaring *ring, - int slot, - struct b43legacy_dmadesc_meta - **meta); - void (*fill_descriptor)(struct b43legacy_dmaring *ring, - struct b43legacy_dmadesc_generic *desc, - dma_addr_t dmaaddr, u16 bufsize, - int start, int end, int irq); - void (*poke_tx)(struct b43legacy_dmaring *ring, int slot); - void (*tx_suspend)(struct b43legacy_dmaring *ring); - void (*tx_resume)(struct b43legacy_dmaring *ring); - int (*get_current_rxslot)(struct b43legacy_dmaring *ring); - void (*set_current_rxslot)(struct b43legacy_dmaring *ring, int slot); -}; - enum b43legacy_dmatype { B43legacy_DMA_30BIT = 30, B43legacy_DMA_32BIT = 32, - B43legacy_DMA_64BIT = 64, }; struct b43legacy_dmaring { - /* Lowlevel DMA ops. */ - const struct b43legacy_dma_ops *ops; /* Kernel virtual base address of the ring memory. */ void *descbase; /* Meta data about all descriptors. */ @@ -257,8 +150,9 @@ struct b43legacy_dmaring { enum b43legacy_dmatype type; /* Boolean. Is this ring stopped at ieee80211 level? */ bool stopped; - /* Lock, only used for TX. */ - spinlock_t lock; + /* The QOS priority assigned to this ring. Only used for TX rings. + * This is the mac80211 "queue" value. */ + u8 queue_prio; struct b43legacy_wldev *dev; #ifdef CONFIG_B43LEGACY_DEBUG /* Maximum number of used slots. */ diff --git a/drivers/net/wireless/b43legacy/ilt.c b/drivers/net/wireless/b43legacy/ilt.c index a849078aea6..ee5682e5420 100644 --- a/drivers/net/wireless/b43legacy/ilt.c +++ b/drivers/net/wireless/b43legacy/ilt.c @@ -4,7 +4,7 @@ Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>, Stefano Brivio <stefano.brivio@polimi.it> - Michael Buesch <mbuesch@freenet.de> + Michael Buesch <m@bues.ch> Danny van Dyk <kugelfang@gentoo.org> Andreas Jaggi <andreas.jaggi@waterwave.ch> diff --git a/drivers/net/wireless/b43legacy/leds.c b/drivers/net/wireless/b43legacy/leds.c index 37e9be89356..fd4565389c7 100644 --- a/drivers/net/wireless/b43legacy/leds.c +++ b/drivers/net/wireless/b43legacy/leds.c @@ -5,7 +5,7 @@ Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>, Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it> - Copyright (c) 2005-2007 Michael Buesch <mb@bu3sch.de> + Copyright (c) 2005-2007 Michael Buesch <m@bues.ch> Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org> Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> @@ -203,11 +203,11 @@ void b43legacy_leds_init(struct b43legacy_wldev *dev) if (sprom[i] == 0xFF) { /* There is no LED information in the SPROM * for this LED. Hardcode it here. */ - activelow = 0; + activelow = false; switch (i) { case 0: behaviour = B43legacy_LED_ACTIVITY; - activelow = 1; + activelow = true; if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ) behaviour = B43legacy_LED_RADIO_ALL; break; diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 1f11e1670bf..1aec2146a2b 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -4,7 +4,7 @@ * * Copyright (c) 2005 Martin Langer <martin-langer@gmx.de> * Copyright (c) 2005-2008 Stefano Brivio <stefano.brivio@polimi.it> - * Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de> + * Copyright (c) 2005, 2006 Michael Buesch <m@bues.ch> * Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org> * Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> * Copyright (c) 2007 Larry Finger <Larry.Finger@lwfinger.net> @@ -31,11 +31,10 @@ #include <linux/delay.h> #include <linux/init.h> -#include <linux/moduleparam.h> +#include <linux/module.h> #include <linux/if_arp.h> #include <linux/etherdevice.h> #include <linux/firmware.h> -#include <linux/wireless.h> #include <linux/workqueue.h> #include <linux/sched.h> #include <linux/skbuff.h> @@ -61,7 +60,6 @@ MODULE_AUTHOR("Stefano Brivio"); MODULE_AUTHOR("Michael Buesch"); MODULE_LICENSE("GPL"); -MODULE_FIRMWARE(B43legacy_SUPPORTED_FIRMWARE_ID); MODULE_FIRMWARE("b43legacy/ucode2.fw"); MODULE_FIRMWARE("b43legacy/ucode4.fw"); @@ -724,9 +722,9 @@ void b43legacy_wireless_core_reset(struct b43legacy_wldev *dev, u32 flags) macctl &= ~B43legacy_MACCTL_GMODE; if (flags & B43legacy_TMSLOW_GMODE) { macctl |= B43legacy_MACCTL_GMODE; - dev->phy.gmode = 1; + dev->phy.gmode = true; } else - dev->phy.gmode = 0; + dev->phy.gmode = false; macctl |= B43legacy_MACCTL_IHR_ENABLED; b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); } @@ -813,7 +811,7 @@ static void b43legacy_calculate_link_quality(struct b43legacy_wldev *dev) if (dev->noisecalc.calculation_running) return; dev->noisecalc.channel_at_start = dev->phy.channel; - dev->noisecalc.calculation_running = 1; + dev->noisecalc.calculation_running = true; dev->noisecalc.nr_samples = 0; b43legacy_generate_noise_sample(dev); @@ -875,7 +873,7 @@ static void handle_irq_noise(struct b43legacy_wldev *dev) dev->stats.link_noise = average; drop_calculation: - dev->noisecalc.calculation_running = 0; + dev->noisecalc.calculation_running = false; return; } generate_new: @@ -891,7 +889,7 @@ static void handle_irq_tbtt_indication(struct b43legacy_wldev *dev) b43legacy_power_saving_ctl_bits(dev, -1, -1); } if (b43legacy_is_mode(dev->wl, NL80211_IFTYPE_ADHOC)) - dev->dfq_valid = 1; + dev->dfq_valid = true; } static void handle_irq_atim_end(struct b43legacy_wldev *dev) @@ -900,7 +898,7 @@ static void handle_irq_atim_end(struct b43legacy_wldev *dev) b43legacy_write32(dev, B43legacy_MMIO_MACCMD, b43legacy_read32(dev, B43legacy_MMIO_MACCMD) | B43legacy_MACCMD_DFQ_VALID); - dev->dfq_valid = 0; + dev->dfq_valid = false; } } @@ -973,14 +971,14 @@ static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev, unsigned int i, len, variable_len; const struct ieee80211_mgmt *bcn; const u8 *ie; - bool tim_found = 0; + bool tim_found = false; unsigned int rate; u16 ctl; int antenna; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon); bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data); - len = min((size_t)dev->wl->current_beacon->len, + len = min_t(size_t, dev->wl->current_beacon->len, 0x200 - sizeof(struct b43legacy_plcp_hdr6)); rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value; @@ -1021,7 +1019,7 @@ static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev, /* A valid TIM is at least 4 bytes long. */ if (ie_len < 4) break; - tim_found = 1; + tim_found = true; tim_position = sizeof(struct b43legacy_plcp_hdr6); tim_position += offsetof(struct ieee80211_mgmt, @@ -1058,6 +1056,7 @@ static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value); dur = ieee80211_generic_frame_duration(dev->wl->hw, dev->wl->vif, + IEEE80211_BAND_2GHZ, size, rate); /* Write PLCP in two parts and timing for packet transfer */ @@ -1123,6 +1122,7 @@ static const u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, IEEE80211_STYPE_PROBE_RESP); dur = ieee80211_generic_frame_duration(dev->wl->hw, dev->wl->vif, + IEEE80211_BAND_2GHZ, *dest_size, rate); hdr->duration_id = dur; @@ -1155,7 +1155,7 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, b43legacy_write_probe_resp_plcp(dev, 0x350, size, &b43legacy_b_ratetable[3]); - size = min((size_t)size, + size = min_t(size_t, size, 0x200 - sizeof(struct b43legacy_plcp_hdr6)); b43legacy_write_template_common(dev, probe_resp_data, size, ram_offset, @@ -1174,7 +1174,7 @@ static void b43legacy_upload_beacon0(struct b43legacy_wldev *dev) * but we don't use that feature anyway. */ b43legacy_write_probe_resp_template(dev, 0x268, 0x4A, &__b43legacy_ratetable[3]); - wl->beacon0_uploaded = 1; + wl->beacon0_uploaded = true; } static void b43legacy_upload_beacon1(struct b43legacy_wldev *dev) @@ -1184,7 +1184,7 @@ static void b43legacy_upload_beacon1(struct b43legacy_wldev *dev) if (wl->beacon1_uploaded) return; b43legacy_write_beacon_template(dev, 0x468, 0x1A); - wl->beacon1_uploaded = 1; + wl->beacon1_uploaded = true; } static void handle_irq_beacon(struct b43legacy_wldev *dev) @@ -1214,7 +1214,7 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev) if (unlikely(wl->beacon_templates_virgin)) { /* We never uploaded a beacon before. * Upload both templates now, but only mark one valid. */ - wl->beacon_templates_virgin = 0; + wl->beacon_templates_virgin = false; b43legacy_upload_beacon0(dev); b43legacy_upload_beacon1(dev); cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); @@ -1277,8 +1277,8 @@ static void b43legacy_update_templates(struct b43legacy_wl *wl) if (wl->current_beacon) dev_kfree_skb_any(wl->current_beacon); wl->current_beacon = beacon; - wl->beacon0_uploaded = 0; - wl->beacon1_uploaded = 0; + wl->beacon0_uploaded = false; + wl->beacon1_uploaded = false; ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger); } @@ -1508,14 +1508,22 @@ static void b43legacy_release_firmware(struct b43legacy_wldev *dev) static void b43legacy_print_fw_helptext(struct b43legacy_wl *wl) { - b43legacyerr(wl, "You must go to http://linuxwireless.org/en/users/" + b43legacyerr(wl, "You must go to http://wireless.kernel.org/en/users/" "Drivers/b43#devicefirmware " "and download the correct firmware (version 3).\n"); } +static void b43legacy_fw_cb(const struct firmware *firmware, void *context) +{ + struct b43legacy_wldev *dev = context; + + dev->fwp = firmware; + complete(&dev->fw_load_complete); +} + static int do_request_fw(struct b43legacy_wldev *dev, const char *name, - const struct firmware **fw) + const struct firmware **fw, bool async) { char path[sizeof(modparam_fwpostfix) + 32]; struct b43legacy_fw_header *hdr; @@ -1528,7 +1536,24 @@ static int do_request_fw(struct b43legacy_wldev *dev, snprintf(path, ARRAY_SIZE(path), "b43legacy%s/%s.fw", modparam_fwpostfix, name); - err = request_firmware(fw, path, dev->dev->dev); + b43legacyinfo(dev->wl, "Loading firmware %s\n", path); + if (async) { + init_completion(&dev->fw_load_complete); + err = request_firmware_nowait(THIS_MODULE, 1, path, + dev->dev->dev, GFP_KERNEL, + dev, b43legacy_fw_cb); + if (err) { + b43legacyerr(dev->wl, "Unable to load firmware\n"); + return err; + } + /* stall here until fw ready */ + wait_for_completion(&dev->fw_load_complete); + if (!dev->fwp) + err = -EINVAL; + *fw = dev->fwp; + } else { + err = request_firmware(fw, path, dev->dev->dev); + } if (err) { b43legacyerr(dev->wl, "Firmware file \"%s\" not found " "or load failed.\n", path); @@ -1559,15 +1584,20 @@ err_format: return -EPROTO; } -static int b43legacy_request_firmware(struct b43legacy_wldev *dev) +static int b43legacy_one_core_attach(struct ssb_device *dev, + struct b43legacy_wl *wl); +static void b43legacy_one_core_detach(struct ssb_device *dev); + +static void b43legacy_request_firmware(struct work_struct *work) { + struct b43legacy_wl *wl = container_of(work, + struct b43legacy_wl, firmware_load); + struct b43legacy_wldev *dev = wl->current_dev; struct b43legacy_firmware *fw = &dev->fw; const u8 rev = dev->dev->id.revision; const char *filename; - u32 tmshigh; int err; - tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH); if (!fw->ucode) { if (rev == 2) filename = "ucode2"; @@ -1575,7 +1605,7 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev) filename = "ucode4"; else filename = "ucode5"; - err = do_request_fw(dev, filename, &fw->ucode); + err = do_request_fw(dev, filename, &fw->ucode, true); if (err) goto err_load; } @@ -1584,7 +1614,7 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev) filename = "pcm4"; else filename = "pcm5"; - err = do_request_fw(dev, filename, &fw->pcm); + err = do_request_fw(dev, filename, &fw->pcm, false); if (err) goto err_load; } @@ -1602,7 +1632,7 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev) default: goto err_no_initvals; } - err = do_request_fw(dev, filename, &fw->initvals); + err = do_request_fw(dev, filename, &fw->initvals, false); if (err) goto err_load; } @@ -1622,12 +1652,18 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev) default: goto err_no_initvals; } - err = do_request_fw(dev, filename, &fw->initvals_band); + err = do_request_fw(dev, filename, &fw->initvals_band, false); if (err) goto err_load; } + err = ieee80211_register_hw(wl->hw); + if (err) + goto err_one_core_detach; + return; - return 0; +err_one_core_detach: + b43legacy_one_core_detach(dev->dev); + goto error; err_load: b43legacy_print_fw_helptext(dev->wl); @@ -1641,7 +1677,7 @@ err_no_initvals: error: b43legacy_release_firmware(dev); - return err; + return; } static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) @@ -1909,7 +1945,7 @@ static int b43legacy_gpio_init(struct b43legacy_wldev *dev) return 0; ssb_write32(gpiodev, B43legacy_GPIO_CONTROL, (ssb_read32(gpiodev, B43legacy_GPIO_CONTROL) - & mask) | set); + & ~mask) | set); return 0; } @@ -2155,9 +2191,6 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev) macctl |= B43legacy_MACCTL_INFRA; b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); - err = b43legacy_request_firmware(dev); - if (err) - goto out; err = b43legacy_upload_microcode(dev); if (err) goto out; /* firmware is released later */ @@ -2234,7 +2267,7 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev) b43legacy_write32(dev, B43legacy_MMIO_DMA5_IRQ_MASK, 0x0000DC00); value32 = ssb_read32(dev->dev, SSB_TMSLOW); - value32 |= 0x00100000; + value32 |= B43legacy_TMSLOW_MACPHYCLKEN; ssb_write32(dev->dev, SSB_TMSLOW, value32); b43legacy_write16(dev, B43legacy_MMIO_POWERUP_DELAY, @@ -2442,34 +2475,69 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl) return err; } -static int b43legacy_op_tx(struct ieee80211_hw *hw, - struct sk_buff *skb) +static void b43legacy_tx_work(struct work_struct *work) +{ + struct b43legacy_wl *wl = container_of(work, struct b43legacy_wl, + tx_work); + struct b43legacy_wldev *dev; + struct sk_buff *skb; + int queue_num; + int err = 0; + + mutex_lock(&wl->mutex); + dev = wl->current_dev; + if (unlikely(!dev || b43legacy_status(dev) < B43legacy_STAT_STARTED)) { + mutex_unlock(&wl->mutex); + return; + } + + for (queue_num = 0; queue_num < B43legacy_QOS_QUEUE_NUM; queue_num++) { + while (skb_queue_len(&wl->tx_queue[queue_num])) { + skb = skb_dequeue(&wl->tx_queue[queue_num]); + if (b43legacy_using_pio(dev)) + err = b43legacy_pio_tx(dev, skb); + else + err = b43legacy_dma_tx(dev, skb); + if (err == -ENOSPC) { + wl->tx_queue_stopped[queue_num] = 1; + ieee80211_stop_queue(wl->hw, queue_num); + skb_queue_head(&wl->tx_queue[queue_num], skb); + break; + } + if (unlikely(err)) + dev_kfree_skb(skb); /* Drop it */ + err = 0; + } + + if (!err) + wl->tx_queue_stopped[queue_num] = 0; + } + + mutex_unlock(&wl->mutex); +} + +static void b43legacy_op_tx(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); - struct b43legacy_wldev *dev = wl->current_dev; - int err = -ENODEV; - unsigned long flags; - if (unlikely(!dev)) - goto out; - if (unlikely(b43legacy_status(dev) < B43legacy_STAT_STARTED)) - goto out; - /* DMA-TX is done without a global lock. */ - if (b43legacy_using_pio(dev)) { - spin_lock_irqsave(&wl->irq_lock, flags); - err = b43legacy_pio_tx(dev, skb); - spin_unlock_irqrestore(&wl->irq_lock, flags); - } else - err = b43legacy_dma_tx(dev, skb); -out: - if (unlikely(err)) { - /* Drop the packet. */ + if (unlikely(skb->len < 2 + 2 + 6)) { + /* Too short, this can't be a valid frame. */ dev_kfree_skb_any(skb); + return; } - return NETDEV_TX_OK; + B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags); + + skb_queue_tail(&wl->tx_queue[skb->queue_mapping], skb); + if (!wl->tx_queue_stopped[skb->queue_mapping]) + ieee80211_queue_work(wl->hw, &wl->tx_work); + else + ieee80211_stop_queue(wl->hw, skb->queue_mapping); } -static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, u16 queue, +static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params) { return 0; @@ -2512,7 +2580,7 @@ static int find_wldev_for_phymode(struct b43legacy_wl *wl, if (d->phy.possible_phymodes & phymode) { /* Ok, this device supports the PHY-mode. * Set the gmode bit. */ - *gmode = 1; + *gmode = true; *dev = d; return 0; @@ -2548,7 +2616,7 @@ static int b43legacy_switch_phymode(struct b43legacy_wl *wl, struct b43legacy_wldev *uninitialized_var(up_dev); struct b43legacy_wldev *down_dev; int err; - bool gmode = 0; + bool gmode = false; int prev_status; err = find_wldev_for_phymode(wl, new_mode, &up_dev, &gmode); @@ -2591,7 +2659,7 @@ static int b43legacy_switch_phymode(struct b43legacy_wl *wl, if (prev_status >= B43legacy_STAT_STARTED) { err = b43legacy_wireless_core_start(up_dev); if (err) { - b43legacyerr(wl, "Fatal: Coult not start device for " + b43legacyerr(wl, "Fatal: Could not start device for " "newly selected %s-PHY mode\n", phymode_to_string(new_mode)); b43legacy_wireless_core_exit(up_dev); @@ -2635,11 +2703,9 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, unsigned long flags; unsigned int new_phymode = 0xFFFF; int antenna_tx; - int antenna_rx; int err = 0; antenna_tx = B43legacy_ANTENNA_DEFAULT; - antenna_rx = B43legacy_ANTENNA_DEFAULT; mutex_lock(&wl->mutex); dev = wl->current_dev; @@ -2654,7 +2720,7 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, goto out_unlock_mutex; /* Switch the PHY mode (if necessary). */ - switch (conf->channel->band) { + switch (conf->chandef.chan->band) { case IEEE80211_BAND_2GHZ: if (phy->type == B43legacy_PHYTYPE_B) new_phymode = B43legacy_PHYMODE_B; @@ -2682,8 +2748,9 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, /* Switch to the requested channel. * The firmware takes care of races with the TX handler. */ - if (conf->channel->hw_value != phy->channel) - b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0); + if (conf->chandef.chan->hw_value != phy->channel) + b43legacy_radio_selectchannel(dev, conf->chandef.chan->hw_value, + 0); dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR); @@ -2776,14 +2843,12 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw, { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev; - struct b43legacy_phy *phy; unsigned long flags; mutex_lock(&wl->mutex); B43legacy_WARN_ON(wl->vif != vif); dev = wl->current_dev; - phy = &dev->phy; /* Disable IRQs while reconfiguring the device. * This makes it possible to drop the spinlock throughout @@ -2885,6 +2950,7 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev) { struct b43legacy_wl *wl = dev->wl; unsigned long flags; + int queue_num; if (b43legacy_status(dev) < B43legacy_STAT_STARTED) return; @@ -2904,11 +2970,16 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev) /* Must unlock as it would otherwise deadlock. No races here. * Cancel the possibly running self-rearming periodic work. */ cancel_delayed_work_sync(&dev->periodic_work); + cancel_work_sync(&wl->tx_work); mutex_lock(&wl->mutex); - ieee80211_stop_queues(wl->hw); /* FIXME this could cause a deadlock */ + /* Drain all TX queues. */ + for (queue_num = 0; queue_num < B43legacy_QOS_QUEUE_NUM; queue_num++) { + while (skb_queue_len(&wl->tx_queue[queue_num])) + dev_kfree_skb(skb_dequeue(&wl->tx_queue[queue_num])); + } - b43legacy_mac_suspend(dev); +b43legacy_mac_suspend(dev); free_irq(dev->dev->irq, dev); b43legacydbg(wl, "Wireless interface stopped\n"); } @@ -2975,7 +3046,7 @@ static int b43legacy_phy_versioning(struct b43legacy_wldev *dev) break; default: unsupported = 1; - }; + } if (unsupported) { b43legacyerr(dev->wl, "FOUND UNSUPPORTED PHY " "(Analog %u, Type %u, Revision %u)\n", @@ -3050,12 +3121,12 @@ static void setup_struct_phy_for_init(struct b43legacy_wldev *dev, /* Assume the radio is enabled. If it's not enabled, the state will * immediately get fixed on the first periodic work run. */ - dev->radio_hw_enable = 1; + dev->radio_hw_enable = true; phy->savedpctlreg = 0xFFFF; - phy->aci_enable = 0; - phy->aci_wlan_automatic = 0; - phy->aci_hw_rssi = 0; + phy->aci_enable = false; + phy->aci_wlan_automatic = false; + phy->aci_hw_rssi = false; lo = phy->_lo_pairs; if (lo) @@ -3087,7 +3158,7 @@ static void setup_struct_phy_for_init(struct b43legacy_wldev *dev, static void setup_struct_wldev_for_init(struct b43legacy_wldev *dev) { /* Flags */ - dev->dfq_valid = 0; + dev->dfq_valid = false; /* Stats */ memset(&dev->stats, 0, sizeof(dev->stats)); @@ -3105,37 +3176,6 @@ static void setup_struct_wldev_for_init(struct b43legacy_wldev *dev) memset(&dev->noisecalc, 0, sizeof(dev->noisecalc)); } -static void b43legacy_imcfglo_timeouts_workaround(struct b43legacy_wldev *dev) -{ -#ifdef CONFIG_SSB_DRIVER_PCICORE - struct ssb_bus *bus = dev->dev->bus; - u32 tmp; - - if (bus->pcicore.dev && - bus->pcicore.dev->id.coreid == SSB_DEV_PCI && - bus->pcicore.dev->id.revision <= 5) { - /* IMCFGLO timeouts workaround. */ - tmp = ssb_read32(dev->dev, SSB_IMCFGLO); - switch (bus->bustype) { - case SSB_BUSTYPE_PCI: - case SSB_BUSTYPE_PCMCIA: - tmp &= ~SSB_IMCFGLO_REQTO; - tmp &= ~SSB_IMCFGLO_SERTO; - tmp |= 0x32; - break; - case SSB_BUSTYPE_SSB: - tmp &= ~SSB_IMCFGLO_REQTO; - tmp &= ~SSB_IMCFGLO_SERTO; - tmp |= 0x53; - break; - default: - break; - } - ssb_write32(dev->dev, SSB_IMCFGLO, tmp); - } -#endif /* CONFIG_SSB_DRIVER_PCICORE */ -} - static void b43legacy_set_synth_pu_delay(struct b43legacy_wldev *dev, bool idle) { u16 pu_delay = 1050; @@ -3224,9 +3264,9 @@ static void prepare_phy_data_for_init(struct b43legacy_wldev *dev) phy->lofcal = 0xFFFF; phy->initval = 0xFFFF; - phy->aci_enable = 0; - phy->aci_wlan_automatic = 0; - phy->aci_hw_rssi = 0; + phy->aci_enable = false; + phy->aci_wlan_automatic = false; + phy->aci_hw_rssi = false; phy->antenna_diversity = 0xFFFF; memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig)); @@ -3279,7 +3319,6 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev) /* Enable IRQ routing to this device. */ ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev); - b43legacy_imcfglo_timeouts_workaround(dev); prepare_phy_data_for_init(dev); b43legacy_phy_calibrate(dev); err = b43legacy_chip_init(dev); @@ -3393,7 +3432,7 @@ static int b43legacy_op_add_interface(struct ieee80211_hw *hw, b43legacydbg(wl, "Adding Interface type %d\n", vif->type); dev = wl->current_dev; - wl->operating = 1; + wl->operating = true; wl->vif = vif; wl->if_type = vif->type; memcpy(wl->mac_addr, vif->addr, ETH_ALEN); @@ -3427,7 +3466,7 @@ static void b43legacy_op_remove_interface(struct ieee80211_hw *hw, B43legacy_WARN_ON(wl->vif != vif); wl->vif = NULL; - wl->operating = 0; + wl->operating = false; spin_lock_irqsave(&wl->irq_lock, flags); b43legacy_adjust_opmode(dev); @@ -3451,10 +3490,10 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) memset(wl->bssid, 0, ETH_ALEN); memset(wl->mac_addr, 0, ETH_ALEN); wl->filter_flags = 0; - wl->beacon0_uploaded = 0; - wl->beacon1_uploaded = 0; - wl->beacon_templates_virgin = 1; - wl->radio_enabled = 1; + wl->beacon0_uploaded = false; + wl->beacon1_uploaded = false; + wl->beacon_templates_virgin = true; + wl->radio_enabled = true; mutex_lock(&wl->mutex); @@ -3493,7 +3532,7 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw) if (b43legacy_status(dev) >= B43legacy_STAT_STARTED) b43legacy_wireless_core_stop(dev); b43legacy_wireless_core_exit(dev); - wl->radio_enabled = 0; + wl->radio_enabled = false; mutex_unlock(&wl->mutex); } @@ -3520,7 +3559,7 @@ static int b43legacy_op_get_survey(struct ieee80211_hw *hw, int idx, if (idx != 0) return -ENOENT; - survey->channel = conf->channel; + survey->channel = conf->chandef.chan; survey->filled = SURVEY_INFO_NOISE_DBM; survey->noise = dev->stats.link_noise; @@ -3652,7 +3691,7 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev) have_bphy = 1; dev->phy.gmode = (have_gphy || have_bphy); - dev->phy.radio_on = 1; + dev->phy.radio_on = true; tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0; b43legacy_wireless_core_reset(dev, tmp); @@ -3729,26 +3768,8 @@ static int b43legacy_one_core_attach(struct ssb_device *dev, struct b43legacy_wl *wl) { struct b43legacy_wldev *wldev; - struct pci_dev *pdev; int err = -ENOMEM; - if (!list_empty(&wl->devlist)) { - /* We are not the first core on this chip. */ - pdev = (dev->bus->bustype == SSB_BUSTYPE_PCI) ? dev->bus->host_pci : NULL; - /* Only special chips support more than one wireless - * core, although some of the other chips have more than - * one wireless core as well. Check for this and - * bail out early. - */ - if (!pdev || - ((pdev->device != 0x4321) && - (pdev->device != 0x4313) && - (pdev->device != 0x431A))) { - b43legacydbg(wl, "Ignoring unconnected 802.11 core\n"); - return -ENODEV; - } - } - wldev = kzalloc(sizeof(*wldev), GFP_KERNEL); if (!wldev) goto out; @@ -3761,7 +3782,7 @@ static int b43legacy_one_core_attach(struct ssb_device *dev, (void (*)(unsigned long))b43legacy_interrupt_tasklet, (unsigned long)wldev); if (modparam_pio) - wldev->__using_pio = 1; + wldev->__using_pio = true; INIT_LIST_HEAD(&wldev->list); err = b43legacy_wireless_core_attach(wldev); @@ -3785,7 +3806,7 @@ static void b43legacy_sprom_fixup(struct ssb_bus *bus) /* boardflags workarounds */ if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && bus->boardinfo.type == 0x4E && - bus->boardinfo.rev > 0x40) + bus->sprom.board_rev > 0x40) bus->sprom.boardflags_lo |= B43legacy_BFL_PACTRL; } @@ -3804,6 +3825,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev) struct ieee80211_hw *hw; struct b43legacy_wl *wl; int err = -ENOMEM; + int queue_num; b43legacy_sprom_fixup(dev->bus); @@ -3838,9 +3860,17 @@ static int b43legacy_wireless_init(struct ssb_device *dev) mutex_init(&wl->mutex); INIT_LIST_HEAD(&wl->devlist); INIT_WORK(&wl->beacon_update_trigger, b43legacy_beacon_update_trigger_work); + INIT_WORK(&wl->tx_work, b43legacy_tx_work); + + /* Initialize queues and flags. */ + for (queue_num = 0; queue_num < B43legacy_QOS_QUEUE_NUM; queue_num++) { + skb_queue_head_init(&wl->tx_queue[queue_num]); + wl->tx_queue_stopped[queue_num] = 0; + } ssb_set_devtypedata(dev, wl); - b43legacyinfo(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id); + b43legacyinfo(wl, "Broadcom %04X WLAN found (core revision %u)\n", + dev->bus->chip_id, dev->id.revision); err = 0; out: return err; @@ -3867,17 +3897,13 @@ static int b43legacy_probe(struct ssb_device *dev, if (err) goto err_wireless_exit; - if (first) { - err = ieee80211_register_hw(wl->hw); - if (err) - goto err_one_core_detach; - } + /* setup and start work to load firmware */ + INIT_WORK(&wl->firmware_load, b43legacy_request_firmware); + schedule_work(&wl->firmware_load); out: return err; -err_one_core_detach: - b43legacy_one_core_detach(dev); err_wireless_exit: if (first) b43legacy_wireless_exit(dev, wl); @@ -3892,8 +3918,12 @@ static void b43legacy_remove(struct ssb_device *dev) /* We must cancel any work here before unregistering from ieee80211, * as the ieee80211 unreg will destroy the workqueue. */ cancel_work_sync(&wldev->restart_work); + cancel_work_sync(&wl->firmware_load); + complete(&wldev->fw_load_complete); B43legacy_WARN_ON(!wl); + if (!wldev->fw.ucode) + return; /* NULL if fw never loaded */ if (wl->current_dev == wldev) ieee80211_unregister_hw(wl->hw); @@ -4002,8 +4032,7 @@ static void b43legacy_print_driverinfo(void) feat_dma = "D"; #endif printk(KERN_INFO "Broadcom 43xx-legacy driver loaded " - "[ Features: %s%s%s%s, Firmware-ID: " - B43legacy_SUPPORTED_FIRMWARE_ID " ]\n", + "[ Features: %s%s%s%s ]\n", feat_pci, feat_leds, feat_pio, feat_dma); } diff --git a/drivers/net/wireless/b43legacy/main.h b/drivers/net/wireless/b43legacy/main.h index 1f0e2e379b0..b74a058d7ba 100644 --- a/drivers/net/wireless/b43legacy/main.h +++ b/drivers/net/wireless/b43legacy/main.h @@ -4,7 +4,7 @@ Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>, Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it> - Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de> + Copyright (c) 2005, 2006 Michael Buesch <m@bues.ch> Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org> Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> Copyright (c) 2007 Larry Finger <Larry.Finger@lwfinger.net> diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c index 28e477d0158..995c7d0c212 100644 --- a/drivers/net/wireless/b43legacy/phy.c +++ b/drivers/net/wireless/b43legacy/phy.c @@ -4,7 +4,7 @@ Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>, Stefano Brivio <stefano.brivio@polimi.it> - Michael Buesch <mbuesch@freenet.de> + Michael Buesch <m@bues.ch> Danny van Dyk <kugelfang@gentoo.org> Andreas Jaggi <andreas.jaggi@waterwave.ch> Copyright (c) 2007 Larry Finger <Larry.Finger@lwfinger.net> @@ -408,7 +408,7 @@ static void b43legacy_phy_setupg(struct b43legacy_wldev *dev) if (is_bcm_board_vendor(dev) && (dev->dev->bus->boardinfo.type == 0x0416) && - (dev->dev->bus->boardinfo.rev == 0x0017)) + (dev->dev->bus->sprom.board_rev == 0x0017)) return; b43legacy_ilt_write(dev, 0x5001, 0x0002); @@ -424,7 +424,7 @@ static void b43legacy_phy_setupg(struct b43legacy_wldev *dev) if (is_bcm_board_vendor(dev) && (dev->dev->bus->boardinfo.type == 0x0416) && - (dev->dev->bus->boardinfo.rev == 0x0017)) + (dev->dev->bus->sprom.board_rev == 0x0017)) return; b43legacy_ilt_write(dev, 0x0401, 0x0002); @@ -1860,7 +1860,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) * which accounts for the factor of 4 */ #define REG_MAX_PWR 20 max_pwr = min(REG_MAX_PWR * 4 - - dev->dev->bus->sprom.antenna_gain.ghz24.a0 + - dev->dev->bus->sprom.antenna_gain.a0 - 0x6, max_pwr); /* find the desired power in Q5.2 - power_level is in dBm diff --git a/drivers/net/wireless/b43legacy/phy.h b/drivers/net/wireless/b43legacy/phy.h index ecbe409f9a9..831a7a4760e 100644 --- a/drivers/net/wireless/b43legacy/phy.h +++ b/drivers/net/wireless/b43legacy/phy.h @@ -4,7 +4,7 @@ Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>, Stefano Brivio <stefano.brivio@polimi.it> - Michael Buesch <mbuesch@freenet.de> + Michael Buesch <m@bues.ch> Danny van Dyk <kugelfang@gentoo.org> Andreas Jaggi <andreas.jaggi@waterwave.ch> Copyright (c) 2007 Larry Finger <Larry.Finger@lwfinger.net> diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c index b033b0ed4ca..282eedec675 100644 --- a/drivers/net/wireless/b43legacy/pio.c +++ b/drivers/net/wireless/b43legacy/pio.c @@ -4,7 +4,7 @@ PIO Transmission - Copyright (c) 2005 Michael Buesch <mb@bu3sch.de> + Copyright (c) 2005 Michael Buesch <m@bues.ch> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -382,7 +382,7 @@ static void cancel_transfers(struct b43legacy_pioqueue *queue) { struct b43legacy_pio_txpacket *packet, *tmp_packet; - tasklet_disable(&queue->txtask); + tasklet_kill(&queue->txtask); list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) free_txpacket(packet, 0); diff --git a/drivers/net/wireless/b43legacy/radio.c b/drivers/net/wireless/b43legacy/radio.c index 2df545cfad1..89617769039 100644 --- a/drivers/net/wireless/b43legacy/radio.c +++ b/drivers/net/wireless/b43legacy/radio.c @@ -4,7 +4,7 @@ Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>, Stefano Brivio <stefano.brivio@polimi.it> - Michael Buesch <mbuesch@freenet.de> + Michael Buesch <m@bues.ch> Danny van Dyk <kugelfang@gentoo.org> Andreas Jaggi <andreas.jaggi@waterwave.ch> Copyright (c) 2007 Larry Finger <Larry.Finger@lwfinger.net> @@ -1067,7 +1067,7 @@ b43legacy_radio_interference_mitigation_enable(struct b43legacy_wldev *dev, if (b43legacy_phy_read(dev, 0x0033) & 0x0800) break; - phy->aci_enable = 1; + phy->aci_enable = true; phy_stacksave(B43legacy_PHY_RADIO_BITFIELD); phy_stacksave(B43legacy_PHY_G_CRS); @@ -1279,7 +1279,7 @@ b43legacy_radio_interference_mitigation_disable(struct b43legacy_wldev *dev, if (!(b43legacy_phy_read(dev, 0x0033) & 0x0800)) break; - phy->aci_enable = 0; + phy->aci_enable = false; phy_stackrestore(B43legacy_PHY_RADIO_BITFIELD); phy_stackrestore(B43legacy_PHY_G_CRS); @@ -1346,10 +1346,10 @@ int b43legacy_radio_set_interference_mitigation(struct b43legacy_wldev *dev, (phy->rev == 0) || (!phy->gmode)) return -ENODEV; - phy->aci_wlan_automatic = 0; + phy->aci_wlan_automatic = false; switch (mode) { case B43legacy_RADIO_INTERFMODE_AUTOWLAN: - phy->aci_wlan_automatic = 1; + phy->aci_wlan_automatic = true; if (phy->aci_enable) mode = B43legacy_RADIO_INTERFMODE_MANUALWLAN; else @@ -1371,8 +1371,8 @@ int b43legacy_radio_set_interference_mitigation(struct b43legacy_wldev *dev, currentmode); if (mode == B43legacy_RADIO_INTERFMODE_NONE) { - phy->aci_enable = 0; - phy->aci_hw_rssi = 0; + phy->aci_enable = false; + phy->aci_hw_rssi = false; } else b43legacy_radio_interference_mitigation_enable(dev, mode); phy->interfmode = mode; @@ -1998,7 +1998,7 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev) if (phy->type == B43legacy_PHYTYPE_G) { if (is_bcm_board_vendor(dev) && dev->dev->bus->boardinfo.type == 0x421 && - dev->dev->bus->boardinfo.rev >= 30) + dev->dev->bus->sprom.board_rev >= 30) att = 3; else if (is_bcm_board_vendor(dev) && dev->dev->bus->boardinfo.type == 0x416) @@ -2008,7 +2008,7 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev) } else { if (is_bcm_board_vendor(dev) && dev->dev->bus->boardinfo.type == 0x421 && - dev->dev->bus->boardinfo.rev >= 30) + dev->dev->bus->sprom.board_rev >= 30) att = 7; else att = 6; @@ -2018,7 +2018,7 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev) if (phy->type == B43legacy_PHYTYPE_G) { if (is_bcm_board_vendor(dev) && dev->dev->bus->boardinfo.type == 0x421 && - dev->dev->bus->boardinfo.rev >= 30) + dev->dev->bus->sprom.board_rev >= 30) att = 3; else if (is_bcm_board_vendor(dev) && dev->dev->bus->boardinfo.type == @@ -2052,9 +2052,9 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev) } if (is_bcm_board_vendor(dev) && dev->dev->bus->boardinfo.type == 0x421) { - if (dev->dev->bus->boardinfo.rev < 0x43) + if (dev->dev->bus->sprom.board_rev < 0x43) att = 2; - else if (dev->dev->bus->boardinfo.rev < 0x51) + else if (dev->dev->bus->sprom.board_rev < 0x51) att = 3; } if (att == 0xFFFF) @@ -2102,7 +2102,7 @@ void b43legacy_radio_turn_on(struct b43legacy_wldev *dev) phy->radio_off_context.rfover); b43legacy_phy_write(dev, B43legacy_PHY_RFOVERVAL, phy->radio_off_context.rfoverval); - phy->radio_off_context.valid = 0; + phy->radio_off_context.valid = false; } channel = phy->channel; err = b43legacy_radio_selectchannel(dev, @@ -2113,7 +2113,7 @@ void b43legacy_radio_turn_on(struct b43legacy_wldev *dev) default: B43legacy_BUG_ON(1); } - phy->radio_on = 1; + phy->radio_on = true; } void b43legacy_radio_turn_off(struct b43legacy_wldev *dev, bool force) @@ -2131,14 +2131,14 @@ void b43legacy_radio_turn_off(struct b43legacy_wldev *dev, bool force) if (!force) { phy->radio_off_context.rfover = rfover; phy->radio_off_context.rfoverval = rfoverval; - phy->radio_off_context.valid = 1; + phy->radio_off_context.valid = true; } b43legacy_phy_write(dev, B43legacy_PHY_RFOVER, rfover | 0x008C); b43legacy_phy_write(dev, B43legacy_PHY_RFOVERVAL, rfoverval & 0xFF73); } else b43legacy_phy_write(dev, 0x0015, 0xAA00); - phy->radio_on = 0; + phy->radio_on = false; b43legacydbg(dev->wl, "Radio initialized\n"); } diff --git a/drivers/net/wireless/b43legacy/radio.h b/drivers/net/wireless/b43legacy/radio.h index ec4de2811c5..bccb3d7da68 100644 --- a/drivers/net/wireless/b43legacy/radio.h +++ b/drivers/net/wireless/b43legacy/radio.h @@ -4,7 +4,7 @@ Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>, Stefano Brivio <stefano.brivio@polimi.it> - Michael Buesch <mbuesch@freenet.de> + Michael Buesch <m@bues.ch> Danny van Dyk <kugelfang@gentoo.org> Andreas Jaggi <andreas.jaggi@waterwave.ch> diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c index b90f223fb31..c4559bcbc70 100644 --- a/drivers/net/wireless/b43legacy/rfkill.c +++ b/drivers/net/wireless/b43legacy/rfkill.c @@ -3,7 +3,7 @@ Broadcom B43 wireless driver RFKILL support - Copyright (c) 2007 Michael Buesch <mb@bu3sch.de> + Copyright (c) 2007 Michael Buesch <m@bues.ch> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/drivers/net/wireless/b43legacy/sysfs.c b/drivers/net/wireless/b43legacy/sysfs.c index 56c384fa9b1..2a1da15c913 100644 --- a/drivers/net/wireless/b43legacy/sysfs.c +++ b/drivers/net/wireless/b43legacy/sysfs.c @@ -4,7 +4,7 @@ SYSFS support routines - Copyright (c) 2006 Michael Buesch <mb@bu3sch.de> + Copyright (c) 2006 Michael Buesch <m@bues.ch> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -42,7 +42,7 @@ static int get_integer(const char *buf, size_t count) if (count == 0) goto out; - count = min(count, (size_t)10); + count = min_t(size_t, count, 10); memcpy(tmp, buf, count); ret = simple_strtol(tmp, NULL, 10); out: diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index 7d177d97f1f..34bf3f0b729 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c @@ -6,7 +6,7 @@ Copyright (C) 2005 Martin Langer <martin-langer@gmx.de> Copyright (C) 2005 Stefano Brivio <stefano.brivio@polimi.it> - Copyright (C) 2005, 2006 Michael Buesch <mb@bu3sch.de> + Copyright (C) 2005, 2006 Michael Buesch <m@bues.ch> Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org> Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> Copyright (C) 2007 Larry Finger <Larry.Finger@lwfinger.net> @@ -215,7 +215,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value); txhdr->mac_frame_ctl = wlhdr->frame_control; - memcpy(txhdr->tx_receiver, wlhdr->addr1, 6); + memcpy(txhdr->tx_receiver, wlhdr->addr1, ETH_ALEN); /* Calculate duration for fallback rate */ if ((rate_fb->hw_value == rate) || @@ -228,6 +228,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, } else { txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, info->control.vif, + info->band, fragment_len, rate_fb); } @@ -253,7 +254,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, B43legacy_TX4_MAC_KEYALG_SHIFT) & B43legacy_TX4_MAC_KEYALG; wlhdr_len = ieee80211_hdrlen(wlhdr->frame_control); - iv_len = min((size_t)info->control.hw_key->iv_len, + iv_len = min_t(size_t, info->control.hw_key->iv_len, ARRAY_SIZE(txhdr->iv)); memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len); } else { @@ -268,8 +269,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) (&txhdr->plcp), plcp_fragment_len, rate); - b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) - (&txhdr->plcp_fb), plcp_fragment_len, + b43legacy_generate_plcp_hdr(&txhdr->plcp_fb, plcp_fragment_len, rate_fb->hw_value); /* PHY TX Control word */ @@ -277,19 +277,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, phy_ctl |= B43legacy_TX4_PHY_ENC_OFDM; if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) phy_ctl |= B43legacy_TX4_PHY_SHORTPRMBL; - switch (info->antenna_sel_tx) { - case 0: - phy_ctl |= B43legacy_TX4_PHY_ANTLAST; - break; - case 1: - phy_ctl |= B43legacy_TX4_PHY_ANT0; - break; - case 2: - phy_ctl |= B43legacy_TX4_PHY_ANT1; - break; - default: - B43legacy_BUG_ON(1); - } + phy_ctl |= B43legacy_TX4_PHY_ANTLAST; /* MAC control */ rates = info->control.rates; @@ -321,11 +309,9 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, struct ieee80211_hdr *hdr; int rts_rate; int rts_rate_fb; - int rts_rate_ofdm; int rts_rate_fb_ofdm; rts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info)->hw_value; - rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate); rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate); rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb); if (rts_rate_fb_ofdm) @@ -353,8 +339,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) (&txhdr->rts_plcp), len, rts_rate); - b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) - (&txhdr->rts_plcp_fb), + b43legacy_generate_plcp_hdr(&txhdr->rts_plcp_fb, len, rts_rate_fb); hdr = (struct ieee80211_hdr *)(&txhdr->rts_frame); txhdr->rts_dur_fb = hdr->duration_id; @@ -572,7 +557,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev, status.mactime += mactime; if (low_mactime_now <= mactime) status.mactime -= 0x10000; - status.flag |= RX_FLAG_TSFT; + status.flag |= RX_FLAG_MACTIME_START; } chanid = (chanstat & B43legacy_RX_CHAN_ID) >> |
