patch-2.3.99-pre2 linux/drivers/net/tulip/tulip_core.c
Next file: linux/drivers/net/via-rhine.c
Previous file: linux/drivers/net/tulip/tulip.h
Back to the patch index
Back to the overall index
- Lines: 195
- Date:
Sat Mar 18 11:18:05 2000
- Orig file:
v2.3.99-pre1/linux/drivers/net/tulip/tulip_core.c
- Orig date:
Fri Mar 10 16:40:43 2000
diff -u --recursive --new-file v2.3.99-pre1/linux/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c
@@ -51,7 +51,7 @@
};
/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
-#if defined(__alpha__) || defined(__arm__)
+#if defined(__alpha__) || defined(__arm__) || defined(__sparc__)
static int rx_copybreak = 1518;
#else
static int rx_copybreak = 100;
@@ -72,8 +72,14 @@
#if defined(__alpha__)
static int csr0 = 0x01A00000 | 0xE000;
-#elif defined(__i386__) || defined(__powerpc__) || defined(__sparc__)
+#elif defined(__i386__) || defined(__powerpc__)
static int csr0 = 0x01A00000 | 0x8000;
+#elif defined(__sparc__)
+/* The UltraSparc PCI controllers will disconnect at every 64-byte
+ * crossing anyways so it makes no sense to tell Tulip to burst
+ * any more than that.
+ */
+static int csr0 = 0x01A00000 | 0x9000;
#elif defined(__arm__)
static int csr0 = 0x01A00000 | 0x4800;
#else
@@ -285,6 +291,7 @@
/* This is set_rx_mode(), but without starting the transmitter. */
u16 *eaddrs = (u16 *)dev->dev_addr;
u16 *setup_frm = &tp->setup_frame[15*6];
+ dma_addr_t mapping;
/* 21140 bug: you must add the broadcast address. */
memset(tp->setup_frame, 0xff, sizeof(tp->setup_frame));
@@ -292,9 +299,16 @@
*setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
*setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
*setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
+
+ mapping = pci_map_single(tp->pdev, tp->setup_frame,
+ sizeof(tp->setup_frame),
+ PCI_DMA_TODEVICE);
+ tp->tx_buffers[0].skb = NULL;
+ tp->tx_buffers[0].mapping = mapping;
+
/* Put the setup frame on the Tx list. */
tp->tx_ring[0].length = cpu_to_le32(0x08000000 | 192);
- tp->tx_ring[0].buffer1 = virt_to_le32desc(tp->setup_frame);
+ tp->tx_ring[0].buffer1 = cpu_to_le32(mapping);
tp->tx_ring[0].status = cpu_to_le32(DescOwned);
tp->cur_tx++;
@@ -569,30 +583,37 @@
tp->rx_ring[i].status = 0x00000000;
tp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ);
tp->rx_ring[i].buffer2 = cpu_to_le32(tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * (i + 1));
- tp->rx_skbuff[i] = NULL;
+ tp->rx_buffers[i].skb = NULL;
+ tp->rx_buffers[i].mapping = 0;
}
/* Mark the last entry as wrapping the ring. */
tp->rx_ring[i-1].length = cpu_to_le32(PKT_BUF_SZ | DESC_RING_WRAP);
tp->rx_ring[i-1].buffer2 = cpu_to_le32(tp->rx_ring_dma);
for (i = 0; i < RX_RING_SIZE; i++) {
+ dma_addr_t mapping;
+
/* Note the receive buffer must be longword aligned.
dev_alloc_skb() provides 16 byte alignment. But do *not*
use skb_reserve() to align the IP header! */
struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ);
- tp->rx_skbuff[i] = skb;
+ tp->rx_buffers[i].skb = skb;
if (skb == NULL)
break;
+ mapping = pci_map_single(tp->pdev, skb->tail,
+ PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+ tp->rx_buffers[i].mapping = mapping;
skb->dev = dev; /* Mark as being used by this device. */
tp->rx_ring[i].status = cpu_to_le32(DescOwned); /* Owned by Tulip chip */
- tp->rx_ring[i].buffer1 = virt_to_le32desc(skb->tail);
+ tp->rx_ring[i].buffer1 = cpu_to_le32(mapping);
}
tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
/* The Tx buffer descriptor is filled in as needed, but we
do need to clear the ownership bit. */
for (i = 0; i < TX_RING_SIZE; i++) {
- tp->tx_skbuff[i] = 0;
+ tp->tx_buffers[i].skb = NULL;
+ tp->tx_buffers[i].mapping = 0;
tp->tx_ring[i].status = 0x00000000;
tp->tx_ring[i].buffer2 = cpu_to_le32(tp->tx_ring_dma + sizeof(struct tulip_tx_desc) * (i + 1));
}
@@ -605,6 +626,7 @@
struct tulip_private *tp = (struct tulip_private *)dev->priv;
int entry;
u32 flag;
+ dma_addr_t mapping;
unsigned long cpuflags;
/* Caution: the write order is important here, set the field
@@ -615,8 +637,11 @@
/* Calculate the next Tx descriptor entry. */
entry = tp->cur_tx % TX_RING_SIZE;
- tp->tx_skbuff[entry] = skb;
- tp->tx_ring[entry].buffer1 = virt_to_le32desc(skb->data);
+ tp->tx_buffers[entry].skb = skb;
+ mapping = pci_map_single(tp->pdev, skb->data,
+ skb->len, PCI_DMA_TODEVICE);
+ tp->tx_buffers[entry].mapping = mapping;
+ tp->tx_ring[entry].buffer1 = cpu_to_le32(mapping);
if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE/2) {/* Typical path */
flag = 0x60000000; /* No interrupt */
@@ -697,19 +722,31 @@
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
- struct sk_buff *skb = tp->rx_skbuff[i];
- tp->rx_skbuff[i] = 0;
+ struct sk_buff *skb = tp->rx_buffers[i].skb;
+ dma_addr_t mapping = tp->rx_buffers[i].mapping;
+
+ tp->rx_buffers[i].skb = NULL;
+ tp->rx_buffers[i].mapping = 0;
+
tp->rx_ring[i].status = 0; /* Not owned by Tulip chip. */
tp->rx_ring[i].length = 0;
tp->rx_ring[i].buffer1 = 0xBADF00D0; /* An invalid address. */
if (skb) {
+ pci_unmap_single(tp->pdev, mapping, PKT_BUF_SZ,
+ PCI_DMA_FROMDEVICE);
dev_kfree_skb (skb);
}
}
for (i = 0; i < TX_RING_SIZE; i++) {
- if (tp->tx_skbuff[i])
- dev_kfree_skb (tp->tx_skbuff[i]);
- tp->tx_skbuff[i] = 0;
+ struct sk_buff *skb = tp->tx_buffers[i].skb;
+
+ if (skb != NULL) {
+ pci_unmap_single(tp->pdev, tp->tx_buffers[i].mapping,
+ skb->len, PCI_DMA_TODEVICE);
+ dev_kfree_skb (skb);
+ }
+ tp->tx_buffers[i].skb = NULL;
+ tp->tx_buffers[i].mapping = 0;
}
MOD_DEC_USE_COUNT;
@@ -937,7 +974,8 @@
if (entry != 0) {
/* Avoid a chip errata by prefixing a dummy entry. */
- tp->tx_skbuff[entry] = 0;
+ tp->tx_buffers[entry].skb = NULL;
+ tp->tx_buffers[entry].mapping = 0;
tp->tx_ring[entry].length =
(entry == TX_RING_SIZE-1) ? cpu_to_le32(DESC_RING_WRAP) : 0;
tp->tx_ring[entry].buffer1 = 0;
@@ -945,12 +983,17 @@
entry = tp->cur_tx++ % TX_RING_SIZE;
}
- tp->tx_skbuff[entry] = 0;
+ tp->tx_buffers[entry].skb = NULL;
+ tp->tx_buffers[entry].mapping =
+ pci_map_single(tp->pdev, tp->setup_frame,
+ sizeof(tp->setup_frame),
+ PCI_DMA_TODEVICE);
/* Put the setup frame on the Tx list. */
if (entry == TX_RING_SIZE-1)
tx_flags |= DESC_RING_WRAP; /* Wrap ring. */
tp->tx_ring[entry].length = cpu_to_le32(tx_flags);
- tp->tx_ring[entry].buffer1 = virt_to_le32desc(tp->setup_frame);
+ tp->tx_ring[entry].buffer1 =
+ cpu_to_le32(tp->tx_buffers[entry].mapping);
tp->tx_ring[entry].status = cpu_to_le32(DescOwned);
if (tp->cur_tx - tp->dirty_tx >= TX_RING_SIZE - 2) {
netif_stop_queue(dev);
@@ -1163,8 +1206,10 @@
And the ASIX must have a burst limit or horrible things happen. */
if (chip_idx == DC21143 && chip_rev == 65)
tp->csr0 &= ~0x01000000;
- else if (chip_idx == AX88140)
- tp->csr0 |= 0x2000;
+ else if (chip_idx == AX88140) {
+ if ((tp->csr0 & 0x3f00) == 0)
+ tp->csr0 |= 0x2000;
+ }
/* The lower four bits are the media type. */
if (board_idx >= 0 && board_idx < MAX_UNITS) {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)