patch-2.4.7 linux/drivers/net/sis900.c
Next file: linux/drivers/net/sis900.h
Previous file: linux/drivers/net/setup.c
Back to the patch index
Back to the overall index
- Lines: 269
- Date:
Tue Jul 17 18:53:55 2001
- Orig file:
v2.4.6/linux/drivers/net/sis900.c
- Orig date:
Tue Jul 3 17:08:20 2001
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sis900.c linux/drivers/net/sis900.c
@@ -150,8 +150,11 @@
/* The saved address of a sent/receive-in-place packet buffer */
struct sk_buff *tx_skbuff[NUM_TX_DESC];
struct sk_buff *rx_skbuff[NUM_RX_DESC];
- BufferDesc tx_ring[NUM_TX_DESC];
- BufferDesc rx_ring[NUM_RX_DESC];
+ BufferDesc *tx_ring;
+ BufferDesc *rx_ring;
+
+ dma_addr_t tx_ring_dma;
+ dma_addr_t rx_ring_dma;
unsigned int tx_full; /* The Tx queue is full. */
};
@@ -309,6 +312,8 @@
{
struct sis900_private *sis_priv;
struct net_device *net_dev;
+ dma_addr_t ring_dma;
+ void *ring_space;
long ioaddr;
int i, ret;
u8 revision;
@@ -353,6 +358,22 @@
pci_set_drvdata(pci_dev, net_dev);
+ ring_space = pci_alloc_consistent(pci_dev, TX_TOTAL_SIZE, &ring_dma);
+ if (!ring_space) {
+ ret = -ENOMEM;
+ goto err_out_cleardev;
+ }
+ sis_priv->tx_ring = (BufferDesc *)ring_space;
+ sis_priv->tx_ring_dma = ring_dma;
+
+ ring_space = pci_alloc_consistent(pci_dev, RX_TOTAL_SIZE, &ring_dma);
+ if (!ring_space) {
+ ret = -ENOMEM;
+ goto err_unmap_tx;
+ }
+ sis_priv->rx_ring = (BufferDesc *)ring_space;
+ sis_priv->rx_ring_dma = ring_dma;
+
/* The SiS900-specific entries in the device structure. */
net_dev->open = &sis900_open;
net_dev->hard_start_xmit = &sis900_start_xmit;
@@ -366,7 +387,7 @@
ret = register_netdev(net_dev);
if (ret)
- goto err_out_cleardev;
+ goto err_unmap_rx;
/* Get Mac address according to the chip revision */
pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
@@ -401,6 +422,12 @@
err_out_unregister:
unregister_netdev(net_dev);
+ err_unmap_rx:
+ pci_free_consistent(pci_dev, RX_TOTAL_SIZE, sis_priv->rx_ring,
+ sis_priv->rx_ring_dma);
+ err_unmap_tx:
+ pci_free_consistent(pci_dev, TX_TOTAL_SIZE, sis_priv->tx_ring,
+ sis_priv->tx_ring_dma);
err_out_cleardev:
pci_set_drvdata(pci_dev, NULL);
pci_release_regions(pci_dev);
@@ -808,7 +835,7 @@
{
struct sis900_private *sis_priv = net_dev->priv;
long ioaddr = net_dev->base_addr;
- u8 revision;
+ u8 revision;
int ret;
/* Soft reset the chip. */
@@ -907,14 +934,14 @@
for (i = 0; i < NUM_TX_DESC; i++) {
sis_priv->tx_skbuff[i] = NULL;
- sis_priv->tx_ring[i].link = (u32) virt_to_bus(&sis_priv->tx_ring[i+1]);
+ sis_priv->tx_ring[i].link = sis_priv->tx_ring_dma +
+ ((i+1)%NUM_TX_DESC)*sizeof(BufferDesc);
sis_priv->tx_ring[i].cmdsts = 0;
sis_priv->tx_ring[i].bufptr = 0;
}
- sis_priv->tx_ring[i-1].link = (u32) virt_to_bus(&sis_priv->tx_ring[0]);
/* load Transmit Descriptor Register */
- outl(virt_to_bus(&sis_priv->tx_ring[0]), ioaddr + txdp);
+ outl(sis_priv->tx_ring_dma, ioaddr + txdp);
if (sis900_debug > 2)
printk(KERN_INFO "%s: TX descriptor register loaded with: %8.8x\n",
net_dev->name, inl(ioaddr + txdp));
@@ -942,11 +969,11 @@
for (i = 0; i < NUM_RX_DESC; i++) {
sis_priv->rx_skbuff[i] = NULL;
- sis_priv->rx_ring[i].link = (u32) virt_to_bus(&sis_priv->rx_ring[i+1]);
+ sis_priv->rx_ring[i].link = sis_priv->rx_ring_dma +
+ ((i+1)%NUM_RX_DESC)*sizeof(BufferDesc);
sis_priv->rx_ring[i].cmdsts = 0;
sis_priv->rx_ring[i].bufptr = 0;
}
- sis_priv->rx_ring[i-1].link = (u32) virt_to_bus(&sis_priv->rx_ring[0]);
/* allocate sock buffers */
for (i = 0; i < NUM_RX_DESC; i++) {
@@ -962,12 +989,13 @@
skb->dev = net_dev;
sis_priv->rx_skbuff[i] = skb;
sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE;
- sis_priv->rx_ring[i].bufptr = virt_to_bus(skb->tail);
+ sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev,
+ skb->tail, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
}
sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC);
/* load Receive Descriptor Register */
- outl(virt_to_bus(&sis_priv->rx_ring[0]), ioaddr + rxdp);
+ outl(sis_priv->rx_ring_dma, ioaddr + rxdp);
if (sis900_debug > 2)
printk(KERN_INFO "%s: RX descriptor register loaded with: %8.8x\n",
net_dev->name, inl(ioaddr + rxdp));
@@ -1012,7 +1040,8 @@
revision == SIS630A_900_REV) )
return;
- if ((dev = pci_find_device(SIS630_VENDOR_ID, SIS630_DEVICE_ID, dev)))
+ dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, dev);
+ if (dev)
pci_read_config_byte(dev, PCI_CLASS_REVISION, &host_bridge_rev);
if (netif_carrier_ok(net_dev)) {
@@ -1320,8 +1349,13 @@
/* discard unsent packets */
sis_priv->dirty_tx = sis_priv->cur_tx = 0;
for (i = 0; i < NUM_TX_DESC; i++) {
- if (sis_priv->tx_skbuff[i] != NULL) {
- dev_kfree_skb(sis_priv->tx_skbuff[i]);
+ struct sk_buff *skb = sis_priv->tx_skbuff[i];
+
+ if (skb) {
+ pci_unmap_single(sis_priv->pci_dev,
+ sis_priv->tx_ring[i].bufptr, skb->len,
+ PCI_DMA_TODEVICE);
+ dev_kfree_skb(skb);
sis_priv->tx_skbuff[i] = 0;
sis_priv->tx_ring[i].cmdsts = 0;
sis_priv->tx_ring[i].bufptr = 0;
@@ -1368,7 +1402,8 @@
sis_priv->tx_skbuff[entry] = skb;
/* set the transmit buffer descriptor and enable Transmit State Machine */
- sis_priv->tx_ring[entry].bufptr = virt_to_bus(skb->data);
+ sis_priv->tx_ring[entry].bufptr = pci_map_single(sis_priv->pci_dev,
+ skb->data, skb->len, PCI_DMA_TODEVICE);
sis_priv->tx_ring[entry].cmdsts = (OWN | skb->len);
outl(TxENA, ioaddr + cr);
@@ -1509,7 +1544,13 @@
break;
}
- /* gvie the socket buffer to upper layers */
+ pci_dma_sync_single(sis_priv->pci_dev,
+ sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE,
+ PCI_DMA_FROMDEVICE);
+ pci_unmap_single(sis_priv->pci_dev,
+ sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE,
+ PCI_DMA_FROMDEVICE);
+ /* give the socket buffer to upper layers */
skb = sis_priv->rx_skbuff[entry];
skb_put(skb, rx_size);
skb->protocol = eth_type_trans(skb, net_dev);
@@ -1542,7 +1583,9 @@
skb->dev = net_dev;
sis_priv->rx_skbuff[entry] = skb;
sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
- sis_priv->rx_ring[entry].bufptr = virt_to_bus(skb->tail);
+ sis_priv->rx_ring[entry].bufptr =
+ pci_map_single(sis_priv->pci_dev, skb->tail,
+ RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
sis_priv->dirty_rx++;
}
sis_priv->cur_rx++;
@@ -1572,7 +1615,9 @@
skb->dev = net_dev;
sis_priv->rx_skbuff[entry] = skb;
sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
- sis_priv->rx_ring[entry].bufptr = virt_to_bus(skb->tail);
+ sis_priv->rx_ring[entry].bufptr =
+ pci_map_single(sis_priv->pci_dev, skb->tail,
+ RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
}
}
/* re-enable the potentially idle receive state matchine */
@@ -1596,6 +1641,7 @@
struct sis900_private *sis_priv = net_dev->priv;
for (; sis_priv->dirty_tx < sis_priv->cur_tx; sis_priv->dirty_tx++) {
+ struct sk_buff *skb;
unsigned int entry;
u32 tx_status;
@@ -1631,7 +1677,11 @@
sis_priv->stats.tx_packets++;
}
/* Free the original skb. */
- dev_kfree_skb_irq(sis_priv->tx_skbuff[entry]);
+ skb = sis_priv->tx_skbuff[entry];
+ pci_unmap_single(sis_priv->pci_dev,
+ sis_priv->tx_ring[entry].bufptr, skb->len,
+ PCI_DMA_TODEVICE);
+ dev_kfree_skb_irq(skb);
sis_priv->tx_skbuff[entry] = NULL;
sis_priv->tx_ring[entry].bufptr = 0;
sis_priv->tx_ring[entry].cmdsts = 0;
@@ -1659,6 +1709,7 @@
{
long ioaddr = net_dev->base_addr;
struct sis900_private *sis_priv = net_dev->priv;
+ struct sk_buff *skb;
int i;
netif_stop_queue(net_dev);
@@ -1676,14 +1727,24 @@
/* Free Tx and RX skbuff */
for (i = 0; i < NUM_RX_DESC; i++) {
- if (sis_priv->rx_skbuff[i] != NULL)
- dev_kfree_skb(sis_priv->rx_skbuff[i]);
- sis_priv->rx_skbuff[i] = 0;
+ skb = sis_priv->rx_skbuff[i];
+ if (skb) {
+ pci_unmap_single(sis_priv->pci_dev,
+ sis_priv->rx_ring[i].bufptr,
+ RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ dev_kfree_skb(skb);
+ sis_priv->rx_skbuff[i] = 0;
+ }
}
for (i = 0; i < NUM_TX_DESC; i++) {
- if (sis_priv->tx_skbuff[i] != NULL)
- dev_kfree_skb(sis_priv->tx_skbuff[i]);
- sis_priv->tx_skbuff[i] = 0;
+ skb = sis_priv->tx_skbuff[i];
+ if (skb) {
+ pci_unmap_single(sis_priv->pci_dev,
+ sis_priv->tx_ring[i].bufptr, skb->len,
+ PCI_DMA_TODEVICE);
+ dev_kfree_skb(skb);
+ sis_priv->tx_skbuff[i] = 0;
+ }
}
/* Green! Put the chip in low-power mode. */
@@ -2007,6 +2068,10 @@
kfree(phy);
}
+ pci_free_consistent(pci_dev, RX_TOTAL_SIZE, sis_priv->rx_ring,
+ sis_priv->rx_ring_dma);
+ pci_free_consistent(pci_dev, TX_TOTAL_SIZE, sis_priv->tx_ring,
+ sis_priv->tx_ring_dma);
unregister_netdev(net_dev);
kfree(net_dev);
pci_release_regions(pci_dev);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)