Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 90121
b: refs/heads/master
c: b27faf8
h: refs/heads/master
i:
  90119: 8e2028c
v: v3
  • Loading branch information
Michael Buesch authored and John W. Linville committed Mar 7, 2008
1 parent f792405 commit 8481675
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 164 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: e6f5b934fba8c44c87c551e066aa7ca6fde2939e
refs/heads/master: b27faf8ebf256429df8851477e02609448c0781f
16 changes: 7 additions & 9 deletions trunk/drivers/net/wireless/b43/b43.h
Original file line number Diff line number Diff line change
Expand Up @@ -589,15 +589,13 @@ struct b43_phy {

/* Data structures for DMA transmission, per 80211 core. */
struct b43_dma {
struct b43_dmaring *tx_ring0;
struct b43_dmaring *tx_ring1;
struct b43_dmaring *tx_ring2;
struct b43_dmaring *tx_ring3;
struct b43_dmaring *tx_ring4;
struct b43_dmaring *tx_ring5;

struct b43_dmaring *rx_ring0;
struct b43_dmaring *rx_ring3; /* only available on core.rev < 5 */
struct b43_dmaring *tx_ring_AC_BK; /* Background */
struct b43_dmaring *tx_ring_AC_BE; /* Best Effort */
struct b43_dmaring *tx_ring_AC_VI; /* Video */
struct b43_dmaring *tx_ring_AC_VO; /* Voice */
struct b43_dmaring *tx_ring_mcast; /* Multicast */

struct b43_dmaring *rx_ring;
};

/* Context information for a noise calculation (Link Quality). */
Expand Down
224 changes: 73 additions & 151 deletions trunk/drivers/net/wireless/b43/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -879,15 +879,15 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
}

/* Main cleanup function. */
static void b43_destroy_dmaring(struct b43_dmaring *ring)
static void b43_destroy_dmaring(struct b43_dmaring *ring,
const char *ringname)
{
if (!ring)
return;

b43dbg(ring->dev->wl, "DMA-%u 0x%04X (%s) max used slots: %d/%d\n",
(unsigned int)(ring->type),
ring->mmio_base,
(ring->tx) ? "TX" : "RX", ring->max_used_slots, ring->nr_slots);
b43dbg(ring->dev->wl, "DMA-%u %s max used slots: %d/%d\n",
(unsigned int)(ring->type), ringname,
ring->max_used_slots, ring->nr_slots);
/* Device IRQs are disabled prior entering this function,
* so no need to take care of concurrency with rx handler stuff.
*/
Expand All @@ -900,33 +900,26 @@ static void b43_destroy_dmaring(struct b43_dmaring *ring)
kfree(ring);
}

#define destroy_ring(dma, ring) do { \
b43_destroy_dmaring((dma)->ring, __stringify(ring)); \
(dma)->ring = NULL; \
} while (0)

void b43_dma_free(struct b43_wldev *dev)
{
struct b43_dma *dma = &dev->dma;

b43_destroy_dmaring(dma->rx_ring3);
dma->rx_ring3 = NULL;
b43_destroy_dmaring(dma->rx_ring0);
dma->rx_ring0 = NULL;

b43_destroy_dmaring(dma->tx_ring5);
dma->tx_ring5 = NULL;
b43_destroy_dmaring(dma->tx_ring4);
dma->tx_ring4 = NULL;
b43_destroy_dmaring(dma->tx_ring3);
dma->tx_ring3 = NULL;
b43_destroy_dmaring(dma->tx_ring2);
dma->tx_ring2 = NULL;
b43_destroy_dmaring(dma->tx_ring1);
dma->tx_ring1 = NULL;
b43_destroy_dmaring(dma->tx_ring0);
dma->tx_ring0 = NULL;
destroy_ring(dma, rx_ring);
destroy_ring(dma, tx_ring_AC_BK);
destroy_ring(dma, tx_ring_AC_BE);
destroy_ring(dma, tx_ring_AC_VI);
destroy_ring(dma, tx_ring_AC_VO);
destroy_ring(dma, tx_ring_mcast);
}

int b43_dma_init(struct b43_wldev *dev)
{
struct b43_dma *dma = &dev->dma;
struct b43_dmaring *ring;
int err;
u64 dmamask;
enum b43_dmatype type;
Expand Down Expand Up @@ -956,83 +949,57 @@ int b43_dma_init(struct b43_wldev *dev)

err = -ENOMEM;
/* setup TX DMA channels. */
ring = b43_setup_dmaring(dev, 0, 1, type);
if (!ring)
dma->tx_ring_AC_BK = b43_setup_dmaring(dev, 0, 1, type);
if (!dma->tx_ring_AC_BK)
goto out;
dma->tx_ring0 = ring;

ring = b43_setup_dmaring(dev, 1, 1, type);
if (!ring)
goto err_destroy_tx0;
dma->tx_ring1 = ring;
dma->tx_ring_AC_BE = b43_setup_dmaring(dev, 1, 1, type);
if (!dma->tx_ring_AC_BE)
goto err_destroy_bk;

ring = b43_setup_dmaring(dev, 2, 1, type);
if (!ring)
goto err_destroy_tx1;
dma->tx_ring2 = ring;
dma->tx_ring_AC_VI = b43_setup_dmaring(dev, 2, 1, type);
if (!dma->tx_ring_AC_VI)
goto err_destroy_be;

ring = b43_setup_dmaring(dev, 3, 1, type);
if (!ring)
goto err_destroy_tx2;
dma->tx_ring3 = ring;
dma->tx_ring_AC_VO = b43_setup_dmaring(dev, 3, 1, type);
if (!dma->tx_ring_AC_VO)
goto err_destroy_vi;

ring = b43_setup_dmaring(dev, 4, 1, type);
if (!ring)
goto err_destroy_tx3;
dma->tx_ring4 = ring;
dma->tx_ring_mcast = b43_setup_dmaring(dev, 4, 1, type);
if (!dma->tx_ring_mcast)
goto err_destroy_vo;

ring = b43_setup_dmaring(dev, 5, 1, type);
if (!ring)
goto err_destroy_tx4;
dma->tx_ring5 = ring;
/* setup RX DMA channel. */
dma->rx_ring = b43_setup_dmaring(dev, 0, 0, type);
if (!dma->rx_ring)
goto err_destroy_mcast;

/* setup RX DMA channels. */
ring = b43_setup_dmaring(dev, 0, 0, type);
if (!ring)
goto err_destroy_tx5;
dma->rx_ring0 = ring;

if (dev->dev->id.revision < 5) {
ring = b43_setup_dmaring(dev, 3, 0, type);
if (!ring)
goto err_destroy_rx0;
dma->rx_ring3 = ring;
}
/* No support for the TX status DMA ring. */
B43_WARN_ON(dev->dev->id.revision < 5);

b43dbg(dev->wl, "%u-bit DMA initialized\n",
(unsigned int)type);
err = 0;
out:
out:
return err;

err_destroy_rx0:
b43_destroy_dmaring(dma->rx_ring0);
dma->rx_ring0 = NULL;
err_destroy_tx5:
b43_destroy_dmaring(dma->tx_ring5);
dma->tx_ring5 = NULL;
err_destroy_tx4:
b43_destroy_dmaring(dma->tx_ring4);
dma->tx_ring4 = NULL;
err_destroy_tx3:
b43_destroy_dmaring(dma->tx_ring3);
dma->tx_ring3 = NULL;
err_destroy_tx2:
b43_destroy_dmaring(dma->tx_ring2);
dma->tx_ring2 = NULL;
err_destroy_tx1:
b43_destroy_dmaring(dma->tx_ring1);
dma->tx_ring1 = NULL;
err_destroy_tx0:
b43_destroy_dmaring(dma->tx_ring0);
dma->tx_ring0 = NULL;
goto out;
err_destroy_mcast:
destroy_ring(dma, tx_ring_mcast);
err_destroy_vo:
destroy_ring(dma, tx_ring_AC_VO);
err_destroy_vi:
destroy_ring(dma, tx_ring_AC_VI);
err_destroy_be:
destroy_ring(dma, tx_ring_AC_BE);
err_destroy_bk:
destroy_ring(dma, tx_ring_AC_BK);
return err;
}

/* Generate a cookie for the TX header. */
static u16 generate_cookie(struct b43_dmaring *ring, int slot)
{
u16 cookie = 0x1000;
u16 cookie;

/* Use the upper 4 bits of the cookie as
* DMA controller ID and store the slot number
Expand All @@ -1042,30 +1009,9 @@ static u16 generate_cookie(struct b43_dmaring *ring, int slot)
* It can also not be 0xFFFF because that is special
* for multicast frames.
*/
switch (ring->index) {
case 0:
cookie = 0x1000;
break;
case 1:
cookie = 0x2000;
break;
case 2:
cookie = 0x3000;
break;
case 3:
cookie = 0x4000;
break;
case 4:
cookie = 0x5000;
break;
case 5:
cookie = 0x6000;
break;
default:
B43_WARN_ON(1);
}
cookie = (((u16)ring->index + 1) << 12);
B43_WARN_ON(slot & ~0x0FFF);
cookie |= (u16) slot;
cookie |= (u16)slot;

return cookie;
}
Expand All @@ -1079,22 +1025,19 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot)

switch (cookie & 0xF000) {
case 0x1000:
ring = dma->tx_ring0;
ring = dma->tx_ring_AC_BK;
break;
case 0x2000:
ring = dma->tx_ring1;
ring = dma->tx_ring_AC_BE;
break;
case 0x3000:
ring = dma->tx_ring2;
ring = dma->tx_ring_AC_VI;
break;
case 0x4000:
ring = dma->tx_ring3;
ring = dma->tx_ring_AC_VO;
break;
case 0x5000:
ring = dma->tx_ring4;
break;
case 0x6000:
ring = dma->tx_ring5;
ring = dma->tx_ring_mcast;
break;
default:
B43_WARN_ON(1);
Expand Down Expand Up @@ -1239,20 +1182,20 @@ static struct b43_dmaring * select_ring_by_priority(struct b43_wldev *dev,
B43_WARN_ON(1);
/* fallthrough */
case 0:
ring = dev->dma.tx_ring3; /* AC_VO */
ring = dev->dma.tx_ring_AC_VO;
break;
case 1:
ring = dev->dma.tx_ring2; /* AC_VI */
ring = dev->dma.tx_ring_AC_VI;
break;
case 2:
ring = dev->dma.tx_ring1; /* AC_BE */
ring = dev->dma.tx_ring_AC_BE;
break;
case 3:
ring = dev->dma.tx_ring0; /* AC_BK */
ring = dev->dma.tx_ring_AC_BK;
break;
}
} else
ring = dev->dma.tx_ring1;
ring = dev->dma.tx_ring_AC_BE;

return ring;
}
Expand All @@ -1273,7 +1216,7 @@ int b43_dma_tx(struct b43_wldev *dev,
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;
ring = dev->dma.tx_ring_mcast;
/* Set the more-data bit. Ucode will clear it on
* the last frame for us. */
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
Expand Down Expand Up @@ -1441,25 +1384,6 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
skb = meta->skb;

if (ring->index == 3) {
/* We received an xmit status. */
struct b43_hwtxstatus *hw = (struct b43_hwtxstatus *)skb->data;
int i = 0;

while (hw->cookie == 0) {
if (i > 100)
break;
i++;
udelay(2);
barrier();
}
b43_handle_hwtxstatus(ring->dev, hw);
/* recycle the descriptor buffer. */
sync_descbuffer_for_device(ring, meta->dmaaddr,
ring->rx_buffersize);

return;
}
rxhdr = (struct b43_rxhdr_fw4 *)skb->data;
len = le16_to_cpu(rxhdr->frame_len);
if (len == 0) {
Expand Down Expand Up @@ -1516,7 +1440,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
skb_pull(skb, ring->frameoffset);

b43_rx(ring->dev, skb, rxhdr);
drop:
drop:
return;
}

Expand Down Expand Up @@ -1562,21 +1486,19 @@ static void b43_dma_tx_resume_ring(struct b43_dmaring *ring)
void b43_dma_tx_suspend(struct b43_wldev *dev)
{
b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
b43_dma_tx_suspend_ring(dev->dma.tx_ring0);
b43_dma_tx_suspend_ring(dev->dma.tx_ring1);
b43_dma_tx_suspend_ring(dev->dma.tx_ring2);
b43_dma_tx_suspend_ring(dev->dma.tx_ring3);
b43_dma_tx_suspend_ring(dev->dma.tx_ring4);
b43_dma_tx_suspend_ring(dev->dma.tx_ring5);
b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_BK);
b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_BE);
b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_VI);
b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_VO);
b43_dma_tx_suspend_ring(dev->dma.tx_ring_mcast);
}

void b43_dma_tx_resume(struct b43_wldev *dev)
{
b43_dma_tx_resume_ring(dev->dma.tx_ring5);
b43_dma_tx_resume_ring(dev->dma.tx_ring4);
b43_dma_tx_resume_ring(dev->dma.tx_ring3);
b43_dma_tx_resume_ring(dev->dma.tx_ring2);
b43_dma_tx_resume_ring(dev->dma.tx_ring1);
b43_dma_tx_resume_ring(dev->dma.tx_ring0);
b43_dma_tx_resume_ring(dev->dma.tx_ring_mcast);
b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_VO);
b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_VI);
b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_BE);
b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_BK);
b43_power_saving_ctl_bits(dev, 0);
}
5 changes: 2 additions & 3 deletions trunk/drivers/net/wireless/b43/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1594,11 +1594,10 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)

/* Check the DMA reason registers for received data. */
if (dma_reason[0] & B43_DMAIRQ_RX_DONE)
b43_dma_rx(dev->dma.rx_ring0);
if (dma_reason[3] & B43_DMAIRQ_RX_DONE)
b43_dma_rx(dev->dma.rx_ring3);
b43_dma_rx(dev->dma.rx_ring);
B43_WARN_ON(dma_reason[1] & B43_DMAIRQ_RX_DONE);
B43_WARN_ON(dma_reason[2] & B43_DMAIRQ_RX_DONE);
B43_WARN_ON(dma_reason[3] & B43_DMAIRQ_RX_DONE);
B43_WARN_ON(dma_reason[4] & B43_DMAIRQ_RX_DONE);
B43_WARN_ON(dma_reason[5] & B43_DMAIRQ_RX_DONE);

Expand Down

0 comments on commit 8481675

Please sign in to comment.