Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 79408
b: refs/heads/master
c: 280d0e1
h: refs/heads/master
v: v3
  • Loading branch information
Michael Buesch authored and David S. Miller committed Jan 28, 2008
1 parent 9b90bb6 commit 4e3938a
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 43 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d4df6f1a9edb80c99913548467397617ccee7855
refs/heads/master: 280d0e16bcbf5893505a0d0897f3ca1ddc0764fa
10 changes: 8 additions & 2 deletions trunk/drivers/net/wireless/b43/b43.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,14 +170,17 @@ enum {
#define B43_SHM_SH_SLOTT 0x0010 /* Slot time */
#define B43_SHM_SH_DTIMPER 0x0012 /* DTIM period */
#define B43_SHM_SH_NOSLPZNATDTIM 0x004C /* NOSLPZNAT DTIM */
/* SHM_SHARED beacon variables */
/* SHM_SHARED beacon/AP variables */
#define B43_SHM_SH_BTL0 0x0018 /* Beacon template length 0 */
#define B43_SHM_SH_BTL1 0x001A /* Beacon template length 1 */
#define B43_SHM_SH_BTSFOFF 0x001C /* Beacon TSF offset */
#define B43_SHM_SH_TIMBPOS 0x001E /* TIM B position in beacon */
#define B43_SHM_SH_DTIMP 0x0012 /* DTIP period */
#define B43_SHM_SH_MCASTCOOKIE 0x00A8 /* Last bcast/mcast frame ID */
#define B43_SHM_SH_SFFBLIM 0x0044 /* Short frame fallback retry limit */
#define B43_SHM_SH_LFFBLIM 0x0046 /* Long frame fallback retry limit */
#define B43_SHM_SH_BEACPHYCTL 0x0054 /* Beacon PHY TX control word (see PHY TX control) */
#define B43_SHM_SH_EXTNPHYCTL 0x00B0 /* Extended bytes for beacon PHY control (N) */
/* SHM_SHARED ACK/CTS control */
#define B43_SHM_SH_ACKCTSPHYCTL 0x0022 /* ACK/CTS PHY control word (see PHY TX control) */
/* SHM_SHARED probe response variables */
Expand Down Expand Up @@ -617,9 +620,12 @@ struct b43_wl {
/* Pointer to the ieee80211 hardware data structure */
struct ieee80211_hw *hw;

spinlock_t irq_lock;
struct mutex mutex;
spinlock_t irq_lock;
/* Lock for LEDs access. */
spinlock_t leds_lock;
/* Lock for SHM access. */
spinlock_t shm_lock;

/* We can only have one operating interface (802.11 core)
* at a time. General information about this interface follows.
Expand Down
82 changes: 55 additions & 27 deletions trunk/drivers/net/wireless/b43/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>


/* 32bit DMA ops. */
static
Expand Down Expand Up @@ -315,26 +317,24 @@ static struct b43_dmaring *priority_to_txring(struct b43_wldev *dev,
case 3:
ring = dev->dma.tx_ring0;
break;
case 4:
ring = dev->dma.tx_ring4;
break;
case 5:
ring = dev->dma.tx_ring5;
break;
}

return ring;
}

/* Bcm43xx-ring to mac80211-queue mapping */
/* b43-ring to mac80211-queue mapping */
static inline int txring_to_priority(struct b43_dmaring *ring)
{
static const u8 idx_to_prio[] = { 3, 2, 1, 0, 4, 5, };
static const u8 idx_to_prio[] = { 3, 2, 1, 0, };
unsigned int index;

/*FIXME: have only one queue, for now */
return 0;

return idx_to_prio[ring->index];
index = ring->index;
if (B43_WARN_ON(index >= ARRAY_SIZE(idx_to_prio)))
index = 0;
return idx_to_prio[index];
}

u16 b43_dmacontroller_base(int dma64bit, int controller_idx)
Expand Down Expand Up @@ -1043,26 +1043,30 @@ static u16 generate_cookie(struct b43_dmaring *ring, int slot)
* in the lower 12 bits.
* Note that the cookie must never be 0, as this
* is a special value used in RX path.
* It can also not be 0xFFFF because that is special
* for multicast frames.
*/
switch (ring->index) {
case 0:
cookie = 0xA000;
cookie = 0x1000;
break;
case 1:
cookie = 0xB000;
cookie = 0x2000;
break;
case 2:
cookie = 0xC000;
cookie = 0x3000;
break;
case 3:
cookie = 0xD000;
cookie = 0x4000;
break;
case 4:
cookie = 0xE000;
cookie = 0x5000;
break;
case 5:
cookie = 0xF000;
cookie = 0x6000;
break;
default:
B43_WARN_ON(1);
}
B43_WARN_ON(slot & ~0x0FFF);
cookie |= (u16) slot;
Expand All @@ -1078,22 +1082,22 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot)
struct b43_dmaring *ring = NULL;

switch (cookie & 0xF000) {
case 0xA000:
case 0x1000:
ring = dma->tx_ring0;
break;
case 0xB000:
case 0x2000:
ring = dma->tx_ring1;
break;
case 0xC000:
case 0x3000:
ring = dma->tx_ring2;
break;
case 0xD000:
case 0x4000:
ring = dma->tx_ring3;
break;
case 0xE000:
case 0x5000:
ring = dma->tx_ring4;
break;
case 0xF000:
case 0x6000:
ring = dma->tx_ring5;
break;
default:
Expand All @@ -1117,6 +1121,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
struct b43_dmadesc_meta *meta;
struct b43_dmadesc_meta *meta_hdr;
struct sk_buff *bounce_skb;
u16 cookie;

#define SLOTS_PER_PACKET 2
B43_WARN_ON(skb_shinfo(skb)->nr_frags);
Expand All @@ -1127,9 +1132,9 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
memset(meta_hdr, 0, sizeof(*meta_hdr));

header = &(ring->txhdr_cache[slot * sizeof(struct b43_txhdr_fw4)]);
cookie = generate_cookie(ring, slot);
b43_generate_txhdr(ring->dev, header,
skb->data, skb->len, ctl,
generate_cookie(ring, slot));
skb->data, skb->len, ctl, cookie);

meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
sizeof(struct b43_txhdr_fw4), 1);
Expand Down Expand Up @@ -1169,14 +1174,20 @@ static int dma_tx_fragment(struct b43_dmaring *ring,

ops->fill_descriptor(ring, desc, meta->dmaaddr, skb->len, 0, 1, 1);

if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
/* Tell the firmware about the cookie of the last
* mcast frame, so it can clear the more-data bit in it. */
b43_shm_write16(ring->dev, B43_SHM_SHARED,
B43_SHM_SH_MCASTCOOKIE, cookie);
}
/* Now transfer the whole frame. */
wmb();
ops->poke_tx(ring, next_slot(ring, slot));
return 0;

out_free_bounce:
out_free_bounce:
dev_kfree_skb_any(skb);
out_unmap_hdr:
out_unmap_hdr:
unmap_descbuffer(ring, meta_hdr->dmaaddr,
sizeof(struct b43_txhdr_fw4), 1);
return err;
Expand Down Expand Up @@ -1207,10 +1218,27 @@ int b43_dma_tx(struct b43_wldev *dev,
struct sk_buff *skb, struct ieee80211_tx_control *ctl)
{
struct b43_dmaring *ring;
struct ieee80211_hdr *hdr;
int err = 0;
unsigned long flags;

ring = priority_to_txring(dev, ctl->queue);
if (unlikely(skb->len < 2 + 2 + 6)) {
/* Too short, this can't be a valid frame. */
return -EINVAL;
}

hdr = (struct ieee80211_hdr *)skb->data;
if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
/* The multicast ring will be sent after the DTIM */
ring = dev->dma.tx_ring4;
/* Set the more-data bit. Ucode will clear it on
* the last frame for us. */
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
} else {
/* Decide by priority where to put this frame. */
ring = priority_to_txring(dev, ctl->queue);
}

spin_lock_irqsave(&ring->lock, flags);
B43_WARN_ON(!ring->tx);
if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) {
Expand Down Expand Up @@ -1238,7 +1266,7 @@ int b43_dma_tx(struct b43_wldev *dev,
b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
}
}
out_unlock:
out_unlock:
spin_unlock_irqrestore(&ring->lock, flags);

return err;
Expand Down
42 changes: 29 additions & 13 deletions trunk/drivers/net/wireless/b43/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,13 +252,12 @@ static void b43_ram_write(struct b43_wldev *dev, u16 offset, u32 val)
b43_write32(dev, B43_MMIO_RAM_DATA, val);
}

static inline
void b43_shm_control_word(struct b43_wldev *dev, u16 routing, u16 offset)
static inline void b43_shm_control_word(struct b43_wldev *dev,
u16 routing, u16 offset)
{
u32 control;

/* "offset" is the WORD offset. */

control = routing;
control <<= 16;
control |= offset;
Expand All @@ -267,8 +266,11 @@ static inline

u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
{
struct b43_wl *wl = dev->wl;
unsigned long flags;
u32 ret;

spin_lock_irqsave(&wl->shm_lock, flags);
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
Expand All @@ -279,76 +281,89 @@ u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
b43_shm_control_word(dev, routing, (offset >> 2) + 1);
ret |= b43_read16(dev, B43_MMIO_SHM_DATA);

return ret;
goto out;
}
offset >>= 2;
}
b43_shm_control_word(dev, routing, offset);
ret = b43_read32(dev, B43_MMIO_SHM_DATA);
out:
spin_unlock_irqrestore(&wl->shm_lock, flags);

return ret;
}

u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset)
{
struct b43_wl *wl = dev->wl;
unsigned long flags;
u16 ret;

spin_lock_irqsave(&wl->shm_lock, flags);
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
/* Unaligned access */
b43_shm_control_word(dev, routing, offset >> 2);
ret = b43_read16(dev, B43_MMIO_SHM_DATA_UNALIGNED);

return ret;
goto out;
}
offset >>= 2;
}
b43_shm_control_word(dev, routing, offset);
ret = b43_read16(dev, B43_MMIO_SHM_DATA);
out:
spin_unlock_irqrestore(&wl->shm_lock, flags);

return ret;
}

void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
{
struct b43_wl *wl = dev->wl;
unsigned long flags;

spin_lock_irqsave(&wl->shm_lock, flags);
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
/* Unaligned access */
b43_shm_control_word(dev, routing, offset >> 2);
mmiowb();
b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED,
(value >> 16) & 0xffff);
mmiowb();
b43_shm_control_word(dev, routing, (offset >> 2) + 1);
mmiowb();
b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff);
return;
goto out;
}
offset >>= 2;
}
b43_shm_control_word(dev, routing, offset);
mmiowb();
b43_write32(dev, B43_MMIO_SHM_DATA, value);
out:
spin_unlock_irqrestore(&wl->shm_lock, flags);
}

void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
{
struct b43_wl *wl = dev->wl;
unsigned long flags;

spin_lock_irqsave(&wl->shm_lock, flags);
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
/* Unaligned access */
b43_shm_control_word(dev, routing, offset >> 2);
mmiowb();
b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value);
return;
goto out;
}
offset >>= 2;
}
b43_shm_control_word(dev, routing, offset);
mmiowb();
b43_write16(dev, B43_MMIO_SHM_DATA, value);
out:
spin_unlock_irqrestore(&wl->shm_lock, flags);
}

/* Read HostFlags */
Expand Down Expand Up @@ -3931,6 +3946,7 @@ static int b43_wireless_init(struct ssb_device *dev)
wl->hw = hw;
spin_lock_init(&wl->irq_lock);
spin_lock_init(&wl->leds_lock);
spin_lock_init(&wl->shm_lock);
mutex_init(&wl->mutex);
INIT_LIST_HEAD(&wl->devlist);

Expand Down

0 comments on commit 4e3938a

Please sign in to comment.