patch-2.4.7 linux/drivers/net/via-rhine.c
Next file: linux/drivers/net/wan/Config.in
Previous file: linux/drivers/net/tulip/tulip_core.c
Back to the patch index
Back to the overall index
- Lines: 112
- Date:
Tue Jul 17 18:53:55 2001
- Orig file:
v2.4.6/linux/drivers/net/via-rhine.c
- Orig date:
Tue Jul 3 17:08:20 2001
diff -u --recursive --new-file v2.4.6/linux/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c
@@ -64,6 +64,11 @@
(media selection + eeprom reload)
- David Vrabel: merges from D-Link "1.11" version
(disable WOL and PME on startup)
+
+ LK1.1.10:
+ - Manfred Spraul: use "singlecopy" for unaligned buffers
+ don't allocate bounce buffers for !ReqTxAlign cards
+
*/
@@ -118,7 +123,6 @@
/* max time out delay time */
#define W_MAX_TIMEOUT 0x0FFFU
-
#if !defined(__OPTIMIZE__) || !defined(__KERNEL__)
#warning You must compile this file with the correct options!
#warning See the last lines of the source file.
@@ -147,7 +151,7 @@
/* These identify the driver base version and may not be removed. */
static char version[] __devinitdata =
-KERN_INFO "via-rhine.c:v1.10-LK1.1.9 05/31/2001 Written by Donald Becker\n"
+KERN_INFO "via-rhine.c:v1.10-LK1.1.10 07/12/2001 Written by Donald Becker\n"
KERN_INFO " http://www.scyld.com/network/via-rhine.html\n";
static char shortname[] __devinitdata = "via-rhine";
@@ -641,6 +645,8 @@
dev->do_ioctl = mii_ioctl;
dev->tx_timeout = via_rhine_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
+ if (np->drv_flags & ReqTxAlign)
+ dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
i = register_netdev(dev);
if (i)
@@ -723,14 +729,16 @@
printk(KERN_ERR "Could not allocate DMA memory.\n");
return -ENOMEM;
}
- np->tx_bufs = pci_alloc_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE,
+ if (np->drv_flags & ReqTxAlign) {
+ np->tx_bufs = pci_alloc_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE,
&np->tx_bufs_dma);
- if (np->tx_bufs == NULL) {
- pci_free_consistent(np->pdev,
- RX_RING_SIZE * sizeof(struct rx_desc) +
- TX_RING_SIZE * sizeof(struct tx_desc),
- ring, ring_dma);
- return -ENOMEM;
+ if (np->tx_bufs == NULL) {
+ pci_free_consistent(np->pdev,
+ RX_RING_SIZE * sizeof(struct rx_desc) +
+ TX_RING_SIZE * sizeof(struct tx_desc),
+ ring, ring_dma);
+ return -ENOMEM;
+ }
}
np->rx_ring = ring;
@@ -738,7 +746,6 @@
np->rx_ring_dma = ring_dma;
np->tx_ring_dma = ring_dma + RX_RING_SIZE * sizeof(struct rx_desc);
-
return 0;
}
@@ -1100,17 +1107,23 @@
/* Caution: the write order is important here, set the field
with the "ownership" bits last. */
- /* lock eth irq */
- spin_lock_irq (&np->lock);
-
/* Calculate the next Tx descriptor entry. */
entry = np->cur_tx % TX_RING_SIZE;
np->tx_skbuff[entry] = skb;
- if ((np->drv_flags & ReqTxAlign) && ((long)skb->data & 3)) {
+ if ((np->drv_flags & ReqTxAlign) &&
+ (((long)skb->data & 3) || skb_shinfo(skb)->nr_frags != 0 || skb->ip_summed == CHECKSUM_HW)
+ ) {
/* Must use alignment buffer. */
- memcpy(np->tx_buf[entry], skb->data, skb->len);
+ if (skb->len > PKT_BUF_SZ) {
+ /* packet too long, drop it */
+ dev_kfree_skb(skb);
+ np->tx_skbuff[entry] = NULL;
+ np->stats.tx_dropped++;
+ return 0;
+ }
+ skb_copy_and_csum_dev(skb, np->tx_buf[entry]);
np->tx_skbuff_dma[entry] = 0;
np->tx_ring[entry].addr = cpu_to_le32(np->tx_bufs_dma +
(np->tx_buf[entry] - np->tx_bufs));
@@ -1122,7 +1135,12 @@
np->tx_ring[entry].desc_length =
cpu_to_le32(0x00E08000 | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
+
+ /* lock eth irq */
+ spin_lock_irq (&np->lock);
+ wmb();
np->tx_ring[entry].tx_status = cpu_to_le32(DescOwn);
+ wmb();
np->cur_tx++;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)