[PATCH] 2.4.0-test11 - drivers/net/epic100.c - use of DMA mapping

2000-11-26 Thread Francois ROMIEU

Hello,

  the following updates the epic100.c driver to the DMA mapping api.
It compiles. It survives ping flood (small/big sizes), insmod/rmmod and seems
to work as it should on an intel machine. Big-endian testers welcome.

--- linux-2.4.0-test11.orig/drivers/net/epic100.c   Sun Nov 26 11:41:47 2000
+++ linux-2.4.0-test11/drivers/net/epic100.cSun Nov 26 13:57:01 2000
@@ -73,6 +73,8 @@
 #define TX_RING_SIZE   16
 #define TX_QUEUE_LEN   10  /* Limit ring entries actually used.  */
 #define RX_RING_SIZE   32
+#define TX_TOTAL_SIZE  TX_RING_SIZE*sizeof(struct epic_tx_desc)
+#define RX_TOTAL_SIZE  RX_RING_SIZE*sizeof(struct epic_rx_desc)
 
 /* Operational parameters that usually are not changed. */
 /* Time in jiffies before concluding the transmitter is hung. */
@@ -172,8 +174,6 @@
 #define EPIC_IOTYPE PCI_USES_MASTER|PCI_USES_MEM|PCI_ADDR1
 #endif
 
-#define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
-
 typedef enum {
SMSC_83C170_0,
SMSC_83C170,
@@ -276,14 +276,16 @@
 
 
 struct epic_private {
-   /* Tx and Rx rings first so that they remain paragraph aligned. */
-   struct epic_rx_desc rx_ring[RX_RING_SIZE];
-   struct epic_tx_desc tx_ring[TX_RING_SIZE];
+   struct epic_rx_desc *rx_ring;
+   struct epic_tx_desc *tx_ring;
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
struct sk_buff* tx_skbuff[TX_RING_SIZE];
/* The addresses of receive-in-place skbuffs. */
struct sk_buff* rx_skbuff[RX_RING_SIZE];
 
+   dma_addr_t tx_ring_dma;
+   dma_addr_t rx_ring_dma;
+
/* Ring pointers. */
spinlock_t lock;/* Group with Tx control cache 
line. */
unsigned int cur_tx, dirty_tx;
@@ -342,6 +344,8 @@
struct epic_chip_info *ci = _chip_info[ent->driver_data];
long ioaddr;
int chip_idx = (int) ent->driver_data;
+   void *ring_space;
+   dma_addr_t ring_dma;
 
card_idx++;

@@ -392,6 +396,21 @@
}
 #endif
 
+   pdev->driver_data = dev;
+   ep = dev->priv;
+
+   ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, _dma);
+   if (!ring_space)
+   goto err_out_iounmap;
+   ep->tx_ring = (struct epic_tx_desc *)ring_space;
+   ep->tx_ring_dma = ring_dma;
+
+   ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, _dma);
+   if (!ring_space)
+   goto err_out_unmap_tx;
+   ep->rx_ring = (struct epic_rx_desc *)ring_space;
+   ep->rx_ring_dma = ring_dma;
+
if (dev->mem_start) {
option = dev->mem_start;
duplex = (dev->mem_start & 16) ? 1 : 0;
@@ -402,12 +421,10 @@
duplex = full_duplex[card_idx];
}
 
-   pdev->driver_data = dev;
 
dev->base_addr = ioaddr;
dev->irq = pdev->irq;
 
-   ep = dev->priv;
ep->pci_dev = pdev;
ep->chip_flags = ci->drv_flags;
spin_lock_init (>lock);
@@ -493,14 +510,18 @@
 
return 0;
 
-#ifndef USE_IO_OPS
-err_out_free_mmio:
-   release_mem_region (pci_resource_start (pdev, 1),
-   pci_resource_len (pdev, 1));
+err_out_unmap_tx:
+   pci_free_consistent(pdev, TX_TOTAL_SIZE, ep->tx_ring, ep->tx_ring_dma);
+err_out_iounmap:
+#ifdef USE_IO_OPS
+   iounmap(ioaddr);
 #endif
+err_out_free_mmio:
+   release_mem_region(pci_resource_start(pdev, 1),
+  pci_resource_len(pdev, 1));
 err_out_free_pio:
-   release_region (pci_resource_start (pdev, 0),
-   pci_resource_len (pdev, 0));
+   release_region(pci_resource_start(pdev, 0),
+  pci_resource_len(pdev, 0));
 err_out_free_netdev:
unregister_netdev(dev);
kfree(dev);
@@ -668,8 +689,8 @@
}
 
outl(ep->full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl);
-   outl(virt_to_bus(ep->rx_ring), ioaddr + PRxCDAR);
-   outl(virt_to_bus(ep->tx_ring), ioaddr + PTxCDAR);
+   outl(ep->rx_ring_dma, ioaddr + PRxCDAR);
+   outl(ep->tx_ring_dma, ioaddr + PTxCDAR);
 
/* Start the chip's Rx process. */
set_rx_mode(dev);
@@ -755,9 +776,10 @@
ep->tx_threshold = TX_FIFO_THRESH;
outl(ep->tx_threshold, ioaddr + TxThresh);
outl(ep->full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl);
-   outl(virt_to_bus(>rx_ring[ep->cur_rx%RX_RING_SIZE]), ioaddr + PRxCDAR);
-   outl(virt_to_bus(>tx_ring[ep->dirty_tx%TX_RING_SIZE]),
-ioaddr + PTxCDAR);
+   outl(ep->rx_ring_dma + (ep->cur_rx%RX_RING_SIZE)*
+   sizeof(struct epic_rx_desc), ioaddr + PRxCDAR);
+   outl(ep->tx_ring_dma + (ep->dirty_tx%TX_RING_SIZE)*
+sizeof(struct epic_tx_desc), ioaddr + PTxCDAR);
 
/* Start the chip's Rx process. */
set_rx_mode(dev);
@@ -852,11 +874,12 @@
for (i = 0; i < RX_RING_SIZE; i++) {
ep->rx_ring[i].rxstatus = 0;

[PATCH] 2.4.0-test11 - drivers/net/epic100.c - use of DMA mapping

2000-11-26 Thread Francois ROMIEU

Hello,

  the following updates the epic100.c driver to the DMA mapping api.
It compiles. It survives ping flood (small/big sizes), insmod/rmmod and seems
to work as it should on an intel machine. Big-endian testers welcome.

--- linux-2.4.0-test11.orig/drivers/net/epic100.c   Sun Nov 26 11:41:47 2000
+++ linux-2.4.0-test11/drivers/net/epic100.cSun Nov 26 13:57:01 2000
@@ -73,6 +73,8 @@
 #define TX_RING_SIZE   16
 #define TX_QUEUE_LEN   10  /* Limit ring entries actually used.  */
 #define RX_RING_SIZE   32
+#define TX_TOTAL_SIZE  TX_RING_SIZE*sizeof(struct epic_tx_desc)
+#define RX_TOTAL_SIZE  RX_RING_SIZE*sizeof(struct epic_rx_desc)
 
 /* Operational parameters that usually are not changed. */
 /* Time in jiffies before concluding the transmitter is hung. */
@@ -172,8 +174,6 @@
 #define EPIC_IOTYPE PCI_USES_MASTER|PCI_USES_MEM|PCI_ADDR1
 #endif
 
-#define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
-
 typedef enum {
SMSC_83C170_0,
SMSC_83C170,
@@ -276,14 +276,16 @@
 
 
 struct epic_private {
-   /* Tx and Rx rings first so that they remain paragraph aligned. */
-   struct epic_rx_desc rx_ring[RX_RING_SIZE];
-   struct epic_tx_desc tx_ring[TX_RING_SIZE];
+   struct epic_rx_desc *rx_ring;
+   struct epic_tx_desc *tx_ring;
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
struct sk_buff* tx_skbuff[TX_RING_SIZE];
/* The addresses of receive-in-place skbuffs. */
struct sk_buff* rx_skbuff[RX_RING_SIZE];
 
+   dma_addr_t tx_ring_dma;
+   dma_addr_t rx_ring_dma;
+
/* Ring pointers. */
spinlock_t lock;/* Group with Tx control cache 
line. */
unsigned int cur_tx, dirty_tx;
@@ -342,6 +344,8 @@
struct epic_chip_info *ci = epic_chip_info[ent-driver_data];
long ioaddr;
int chip_idx = (int) ent-driver_data;
+   void *ring_space;
+   dma_addr_t ring_dma;
 
card_idx++;

@@ -392,6 +396,21 @@
}
 #endif
 
+   pdev-driver_data = dev;
+   ep = dev-priv;
+
+   ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, ring_dma);
+   if (!ring_space)
+   goto err_out_iounmap;
+   ep-tx_ring = (struct epic_tx_desc *)ring_space;
+   ep-tx_ring_dma = ring_dma;
+
+   ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, ring_dma);
+   if (!ring_space)
+   goto err_out_unmap_tx;
+   ep-rx_ring = (struct epic_rx_desc *)ring_space;
+   ep-rx_ring_dma = ring_dma;
+
if (dev-mem_start) {
option = dev-mem_start;
duplex = (dev-mem_start  16) ? 1 : 0;
@@ -402,12 +421,10 @@
duplex = full_duplex[card_idx];
}
 
-   pdev-driver_data = dev;
 
dev-base_addr = ioaddr;
dev-irq = pdev-irq;
 
-   ep = dev-priv;
ep-pci_dev = pdev;
ep-chip_flags = ci-drv_flags;
spin_lock_init (ep-lock);
@@ -493,14 +510,18 @@
 
return 0;
 
-#ifndef USE_IO_OPS
-err_out_free_mmio:
-   release_mem_region (pci_resource_start (pdev, 1),
-   pci_resource_len (pdev, 1));
+err_out_unmap_tx:
+   pci_free_consistent(pdev, TX_TOTAL_SIZE, ep-tx_ring, ep-tx_ring_dma);
+err_out_iounmap:
+#ifdef USE_IO_OPS
+   iounmap(ioaddr);
 #endif
+err_out_free_mmio:
+   release_mem_region(pci_resource_start(pdev, 1),
+  pci_resource_len(pdev, 1));
 err_out_free_pio:
-   release_region (pci_resource_start (pdev, 0),
-   pci_resource_len (pdev, 0));
+   release_region(pci_resource_start(pdev, 0),
+  pci_resource_len(pdev, 0));
 err_out_free_netdev:
unregister_netdev(dev);
kfree(dev);
@@ -668,8 +689,8 @@
}
 
outl(ep-full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl);
-   outl(virt_to_bus(ep-rx_ring), ioaddr + PRxCDAR);
-   outl(virt_to_bus(ep-tx_ring), ioaddr + PTxCDAR);
+   outl(ep-rx_ring_dma, ioaddr + PRxCDAR);
+   outl(ep-tx_ring_dma, ioaddr + PTxCDAR);
 
/* Start the chip's Rx process. */
set_rx_mode(dev);
@@ -755,9 +776,10 @@
ep-tx_threshold = TX_FIFO_THRESH;
outl(ep-tx_threshold, ioaddr + TxThresh);
outl(ep-full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl);
-   outl(virt_to_bus(ep-rx_ring[ep-cur_rx%RX_RING_SIZE]), ioaddr + PRxCDAR);
-   outl(virt_to_bus(ep-tx_ring[ep-dirty_tx%TX_RING_SIZE]),
-ioaddr + PTxCDAR);
+   outl(ep-rx_ring_dma + (ep-cur_rx%RX_RING_SIZE)*
+   sizeof(struct epic_rx_desc), ioaddr + PRxCDAR);
+   outl(ep-tx_ring_dma + (ep-dirty_tx%TX_RING_SIZE)*
+sizeof(struct epic_tx_desc), ioaddr + PTxCDAR);
 
/* Start the chip's Rx process. */
set_rx_mode(dev);
@@ -852,11 +874,12 @@
for (i = 0; i  RX_RING_SIZE; i++) {
ep-rx_ring[i].rxstatus = 0;