[PATCH] 2.4.0-test11 - drivers/net/epic100.c - use of DMA mapping
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
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;