patch-2.3.99-pre2 linux/drivers/net/tulip/interrupt.c
Next file: linux/drivers/net/tulip/tulip.h
Previous file: linux/drivers/net/tokenring/olympic.h
Back to the patch index
Back to the overall index
- Lines: 130
- Date:
Sat Mar 18 11:18:05 2000
- Orig file:
v2.3.99-pre1/linux/drivers/net/tulip/interrupt.c
- Orig date:
Sat Feb 26 22:31:47 2000
diff -u --recursive --new-file v2.3.99-pre1/linux/drivers/net/tulip/interrupt.c linux/drivers/net/tulip/interrupt.c
@@ -16,6 +16,7 @@
#include "tulip.h"
#include <asm/io.h>
#include <linux/etherdevice.h>
+#include <linux/pci.h>
int tulip_rx_copybreak;
@@ -32,13 +33,20 @@
/* Refill the Rx ring buffers. */
for (; tp->cur_rx - tp->dirty_rx > 0; tp->dirty_rx++) {
entry = tp->dirty_rx % RX_RING_SIZE;
- if (tp->rx_skbuff[entry] == NULL) {
+ if (tp->rx_buffers[entry].skb == NULL) {
struct sk_buff *skb;
- skb = tp->rx_skbuff[entry] = dev_alloc_skb(PKT_BUF_SZ);
+ dma_addr_t mapping;
+
+ skb = tp->rx_buffers[entry].skb = dev_alloc_skb(PKT_BUF_SZ);
if (skb == NULL)
break;
+
+ mapping = pci_map_single(tp->pdev, skb->tail, PKT_BUF_SZ,
+ PCI_DMA_FROMDEVICE);
+ tp->rx_buffers[entry].mapping = mapping;
+
skb->dev = dev; /* Mark as being used by this device. */
- tp->rx_ring[entry].buffer1 = virt_to_le32desc(skb->tail);
+ tp->rx_ring[entry].buffer1 = cpu_to_le32(mapping);
refilled++;
}
tp->rx_ring[entry].status = cpu_to_le32(DescOwned);
@@ -106,24 +114,39 @@
&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
skb->dev = dev;
skb_reserve(skb, 2); /* 16 byte align the IP header */
+ pci_dma_sync_single(tp->pdev,
+ tp->rx_buffers[entry].mapping,
+ pkt_len, PCI_DMA_FROMDEVICE);
#if ! defined(__alpha__)
- eth_copy_and_sum(skb, tp->rx_skbuff[entry]->tail, pkt_len, 0);
+ eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail,
+ pkt_len, 0);
skb_put(skb, pkt_len);
#else
- memcpy(skb_put(skb, pkt_len), tp->rx_skbuff[entry]->tail,
- pkt_len);
+ memcpy(skb_put(skb, pkt_len),
+ tp->rx_buffers[entry].skb->tail,
+ pkt_len);
#endif
} else { /* Pass up the skb already on the Rx ring. */
- char *temp = skb_put(skb = tp->rx_skbuff[entry], pkt_len);
- tp->rx_skbuff[entry] = NULL;
+ char *temp = skb_put(skb = tp->rx_buffers[entry].skb,
+ pkt_len);
+
#ifndef final_version
- if (le32desc_to_virt(tp->rx_ring[entry].buffer1) != temp)
+ if (tp->rx_buffers[entry].mapping !=
+ le32_to_cpu(tp->rx_ring[entry].buffer1)) {
printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
- "do not match in tulip_rx: %p vs. %p / %p.\n",
- dev->name,
- le32desc_to_virt(tp->rx_ring[entry].buffer1),
- skb->head, temp);
+ "do not match in tulip_rx: %08x vs. %08x %p / %p.\n",
+ dev->name,
+ le32_to_cpu(tp->rx_ring[entry].buffer1),
+ tp->rx_buffers[entry].mapping,
+ skb->head, temp);
+ }
#endif
+
+ pci_unmap_single(tp->pdev, tp->rx_buffers[entry].mapping,
+ PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+
+ tp->rx_buffers[entry].skb = NULL;
+ tp->rx_buffers[entry].mapping = 0;
}
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
@@ -189,8 +212,13 @@
if (status < 0)
break; /* It still has not been Txed */
/* Check for Rx filter setup frames. */
- if (tp->tx_skbuff[entry] == NULL)
+ if (tp->tx_buffers[entry].skb == NULL) {
+ pci_unmap_single(tp->pdev,
+ tp->tx_buffers[entry].mapping,
+ sizeof(tp->setup_frame),
+ PCI_DMA_TODEVICE);
continue;
+ }
if (status & 0x8000) {
/* There was an major error, log it. */
@@ -213,14 +241,20 @@
#ifdef ETHER_STATS
if (status & 0x0001) tp->stats.tx_deferred++;
#endif
- tp->stats.tx_bytes += tp->tx_skbuff[entry]->len;
+ tp->stats.tx_bytes +=
+ tp->tx_buffers[entry].skb->len;
tp->stats.collisions += (status >> 3) & 15;
tp->stats.tx_packets++;
}
+ pci_unmap_single(tp->pdev, tp->tx_buffers[entry].mapping,
+ tp->tx_buffers[entry].skb->len,
+ PCI_DMA_TODEVICE);
+
/* Free the original skb. */
- dev_kfree_skb_irq(tp->tx_skbuff[entry]);
- tp->tx_skbuff[entry] = 0;
+ dev_kfree_skb_irq(tp->tx_buffers[entry].skb);
+ tp->tx_buffers[entry].skb = NULL;
+ tp->tx_buffers[entry].mapping = 0;
tx++;
}
@@ -311,7 +345,7 @@
/* check if we card is in suspend mode */
entry = tp->dirty_rx % RX_RING_SIZE;
- if (tp->rx_skbuff[entry] == NULL) {
+ if (tp->rx_buffers[entry].skb == NULL) {
if (tulip_debug > 1)
printk(KERN_WARNING "%s: in rx suspend mode: (%lu) (tp->cur_rx = %u, ttimer = %d, rx = %d) go/stay in suspend mode\n", dev->name, tp->nir, tp->cur_rx, tp->ttimer, rx);
if (tp->ttimer == 0 || (inl(ioaddr + CSR11) & 0xffff) == 0) {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)