Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 10341
b: refs/heads/master
c: 9f38c63
h: refs/heads/master
i:
  10339: 0f91e1a
v: v3
  • Loading branch information
John W. Linville authored and Jeff Garzik committed Oct 19, 2005
1 parent b66470f commit 943acd4
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 9 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: df49898a47061e82219c991dfbe9ac6ddf7a866b
refs/heads/master: 9f38c636ababfb41e58c9ec1e9719492ef7f0479
134 changes: 126 additions & 8 deletions trunk/drivers/net/b44.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,29 @@ static int b44_poll(struct net_device *dev, int *budget);
static void b44_poll_controller(struct net_device *dev);
#endif

static int dma_desc_align_mask;
static int dma_desc_sync_size;

static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
dma_addr_t dma_base,
unsigned long offset,
enum dma_data_direction dir)
{
dma_sync_single_range_for_device(&pdev->dev, dma_base,
offset & dma_desc_align_mask,
dma_desc_sync_size, dir);
}

static inline void b44_sync_dma_desc_for_cpu(struct pci_dev *pdev,
dma_addr_t dma_base,
unsigned long offset,
enum dma_data_direction dir)
{
dma_sync_single_range_for_cpu(&pdev->dev, dma_base,
offset & dma_desc_align_mask,
dma_desc_sync_size, dir);
}

static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
{
return readl(bp->regs + reg);
Expand Down Expand Up @@ -668,6 +691,11 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
dp->ctrl = cpu_to_le32(ctrl);
dp->addr = cpu_to_le32((u32) mapping + bp->rx_offset + bp->dma_offset);

if (bp->flags & B44_FLAG_RX_RING_HACK)
b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
dest_idx * sizeof(dp),
DMA_BIDIRECTIONAL);

return RX_PKT_BUF_SZ;
}

Expand All @@ -692,6 +720,11 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
pci_unmap_addr_set(dest_map, mapping,
pci_unmap_addr(src_map, mapping));

if (bp->flags & B44_FLAG_RX_RING_HACK)
b44_sync_dma_desc_for_cpu(bp->pdev, bp->rx_ring_dma,
src_idx * sizeof(src_desc),
DMA_BIDIRECTIONAL);

ctrl = src_desc->ctrl;
if (dest_idx == (B44_RX_RING_SIZE - 1))
ctrl |= cpu_to_le32(DESC_CTRL_EOT);
Expand All @@ -700,8 +733,14 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)

dest_desc->ctrl = ctrl;
dest_desc->addr = src_desc->addr;

src_map->skb = NULL;

if (bp->flags & B44_FLAG_RX_RING_HACK)
b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
dest_idx * sizeof(dest_desc),
DMA_BIDIRECTIONAL);

pci_dma_sync_single_for_device(bp->pdev, src_desc->addr,
RX_PKT_BUF_SZ,
PCI_DMA_FROMDEVICE);
Expand Down Expand Up @@ -959,6 +998,11 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
bp->tx_ring[entry].ctrl = cpu_to_le32(ctrl);
bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping+bp->dma_offset);

if (bp->flags & B44_FLAG_TX_RING_HACK)
b44_sync_dma_desc_for_device(bp->pdev, bp->tx_ring_dma,
entry * sizeof(bp->tx_ring[0]),
DMA_TO_DEVICE);

entry = NEXT_TX(entry);

bp->tx_prod = entry;
Expand Down Expand Up @@ -1064,6 +1108,16 @@ static void b44_init_rings(struct b44 *bp)
memset(bp->rx_ring, 0, B44_RX_RING_BYTES);
memset(bp->tx_ring, 0, B44_TX_RING_BYTES);

if (bp->flags & B44_FLAG_RX_RING_HACK)
dma_sync_single_for_device(&bp->pdev->dev, bp->rx_ring_dma,
DMA_TABLE_BYTES,
PCI_DMA_BIDIRECTIONAL);

if (bp->flags & B44_FLAG_TX_RING_HACK)
dma_sync_single_for_device(&bp->pdev->dev, bp->tx_ring_dma,
DMA_TABLE_BYTES,
PCI_DMA_TODEVICE);

for (i = 0; i < bp->rx_pending; i++) {
if (b44_alloc_rx_skb(bp, -1, i) < 0)
break;
Expand All @@ -1085,14 +1139,28 @@ static void b44_free_consistent(struct b44 *bp)
bp->tx_buffers = NULL;
}
if (bp->rx_ring) {
pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
bp->rx_ring, bp->rx_ring_dma);
if (bp->flags & B44_FLAG_RX_RING_HACK) {
dma_unmap_single(&bp->pdev->dev, bp->rx_ring_dma,
DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL);
kfree(bp->rx_ring);
} else
pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
bp->rx_ring, bp->rx_ring_dma);
bp->rx_ring = NULL;
bp->flags &= ~B44_FLAG_RX_RING_HACK;
}
if (bp->tx_ring) {
pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
bp->tx_ring, bp->tx_ring_dma);
if (bp->flags & B44_FLAG_TX_RING_HACK) {
dma_unmap_single(&bp->pdev->dev, bp->tx_ring_dma,
DMA_TABLE_BYTES,
DMA_TO_DEVICE);
kfree(bp->tx_ring);
} else
pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
bp->tx_ring, bp->tx_ring_dma);
bp->tx_ring = NULL;
bp->flags &= ~B44_FLAG_TX_RING_HACK;
}
}

Expand All @@ -1118,12 +1186,56 @@ static int b44_alloc_consistent(struct b44 *bp)

size = DMA_TABLE_BYTES;
bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
if (!bp->rx_ring)
goto out_err;
if (!bp->rx_ring) {
/* Allocation may have failed due to pci_alloc_consistent
insisting on use of GFP_DMA, which is more restrictive
than necessary... */
struct dma_desc *rx_ring;
dma_addr_t rx_ring_dma;

if (!(rx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL)))
goto out_err;

memset(rx_ring, 0, size);
rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL);

if (rx_ring_dma + size > B44_DMA_MASK) {
kfree(rx_ring);
goto out_err;
}

bp->rx_ring = rx_ring;
bp->rx_ring_dma = rx_ring_dma;
bp->flags |= B44_FLAG_RX_RING_HACK;
}

bp->tx_ring = pci_alloc_consistent(bp->pdev, size, &bp->tx_ring_dma);
if (!bp->tx_ring)
goto out_err;
if (!bp->tx_ring) {
/* Allocation may have failed due to pci_alloc_consistent
insisting on use of GFP_DMA, which is more restrictive
than necessary... */
struct dma_desc *tx_ring;
dma_addr_t tx_ring_dma;

if (!(tx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL)))
goto out_err;

memset(tx_ring, 0, size);
tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
DMA_TABLE_BYTES,
DMA_TO_DEVICE);

if (tx_ring_dma + size > B44_DMA_MASK) {
kfree(tx_ring);
goto out_err;
}

bp->tx_ring = tx_ring;
bp->tx_ring_dma = tx_ring_dma;
bp->flags |= B44_FLAG_TX_RING_HACK;
}

return 0;

Expand Down Expand Up @@ -1973,6 +2085,12 @@ static struct pci_driver b44_driver = {

static int __init b44_init(void)
{
unsigned int dma_desc_align_size = dma_get_cache_alignment();

/* Setup paramaters for syncing RX/TX DMA descriptors */
dma_desc_align_mask = ~(dma_desc_align_size - 1);
dma_desc_sync_size = max(dma_desc_align_size, sizeof(struct dma_desc));

return pci_module_init(&b44_driver);
}

Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/b44.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,8 @@ struct b44 {
#define B44_FLAG_ADV_100HALF 0x04000000
#define B44_FLAG_ADV_100FULL 0x08000000
#define B44_FLAG_INTERNAL_PHY 0x10000000
#define B44_FLAG_RX_RING_HACK 0x20000000
#define B44_FLAG_TX_RING_HACK 0x40000000

u32 rx_offset;

Expand Down

0 comments on commit 943acd4

Please sign in to comment.