Commit cacde53e authored by François Romieu's avatar François Romieu Committed by Jeff Garzik

[netdrvr sis190] use PCI DMA API for RX buffers

Missing pieces for DMA-API on the Rx side:
- SiS190_init_ring: the global area for the received data is mapped.
  This area is persistent during the whole driver's life.
  It only needs to be unmapped in SiS190_close() as no other exit/error
  path exists.
- SiS190_rx_interrupt: no map/unmap for received data buffer. A single
  sync operation is done. Btw, there is no need to store the same value
  in RxDescArray[cur_rx].buf_addr over and over again.
- Remove driver dependancy on CONFIG_BROKEN.
parent dfb4fdc9
...@@ -2044,7 +2044,7 @@ config R8169 ...@@ -2044,7 +2044,7 @@ config R8169
config SIS190 config SIS190
tristate "SiS190 gigabit ethernet support (EXPERIMENTAL)" tristate "SiS190 gigabit ethernet support (EXPERIMENTAL)"
depends on PCI && EXPERIMENTAL && BROKEN depends on PCI && EXPERIMENTAL
---help--- ---help---
Say Y here if you have a SiS 190 PCI Gigabit Ethernet adapter. Say Y here if you have a SiS 190 PCI Gigabit Ethernet adapter.
......
...@@ -828,19 +828,19 @@ SiS190_init_ring(struct net_device *dev) ...@@ -828,19 +828,19 @@ SiS190_init_ring(struct net_device *dev)
tp->Tx_skbuff[i] = NULL; tp->Tx_skbuff[i] = NULL;
} }
for (i = 0; i < NUM_RX_DESC; i++) { for (i = 0; i < NUM_RX_DESC; i++) {
struct RxDesc *desc = tp->RxDescArray + i;
tp->RxDescArray[i].PSize = 0x0; desc->PSize = 0x0;
if (i == (NUM_RX_DESC - 1)) if (i == (NUM_RX_DESC - 1))
tp->RxDescArray[i].buf_Len = BIT_31 + RX_BUF_SIZE; //bit 31 is End bit desc->buf_Len = BIT_31 + RX_BUF_SIZE; //bit 31 is End bit
else else
tp->RxDescArray[i].buf_Len = RX_BUF_SIZE; desc->buf_Len = RX_BUF_SIZE;
#warning Replace virt_to_bus with DMA mapping
tp->RxBufferRing[i] = &(tp->RxBufferRings[i * RX_BUF_SIZE]);
tp->RxDescArray[i].buf_addr = virt_to_bus(tp->RxBufferRing[i]);
tp->RxDescArray[i].status = OWNbit | INTbit;
tp->RxBufferRing[i] = tp->RxBufferRings + i * RX_BUF_SIZE;
desc->buf_addr = pci_map_single(tp->pci_dev,
tp->RxBufferRing[i], RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
desc->status = OWNbit | INTbit;
} }
} }
...@@ -998,29 +998,30 @@ static void ...@@ -998,29 +998,30 @@ static void
SiS190_rx_interrupt(struct net_device *dev, struct sis190_private *tp, SiS190_rx_interrupt(struct net_device *dev, struct sis190_private *tp,
void *ioaddr) void *ioaddr)
{ {
int cur_rx; int cur_rx = tp->cur_rx;
struct sk_buff *skb; struct RxDesc *desc = tp->RxDescArray + cur_rx;
int pkt_size = 0;
assert(dev != NULL); assert(dev != NULL);
assert(tp != NULL); assert(tp != NULL);
assert(ioaddr != NULL); assert(ioaddr != NULL);
cur_rx = tp->cur_rx; while ((desc->status & OWNbit) == 0) {
while ((tp->RxDescArray[cur_rx].status & OWNbit) == 0) {
if (tp->RxDescArray[cur_rx].PSize & 0x0080000) { if (desc->PSize & 0x0080000) {
printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name); printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name);
tp->stats.rx_errors++; tp->stats.rx_errors++;
tp->stats.rx_length_errors++; tp->stats.rx_length_errors++;
} else if (!(tp->RxDescArray[cur_rx].PSize & 0x0010000)) { } else if (!(desc->PSize & 0x0010000)) {
printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name); printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name);
tp->stats.rx_errors++; tp->stats.rx_errors++;
tp->stats.rx_crc_errors++; tp->stats.rx_crc_errors++;
} else { } else {
pkt_size = struct sk_buff *skb;
(int) (tp->RxDescArray[cur_rx]. int pkt_size;
PSize & 0x0000FFFF) - 4;
pkt_size = (int) (desc->PSize & 0x0000FFFF) - 4;
pci_dma_sync_single(tp->pci_dev, desc->buf_addr,
RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
skb = dev_alloc_skb(pkt_size + 2); skb = dev_alloc_skb(pkt_size + 2);
if (skb != NULL) { if (skb != NULL) {
skb->dev = dev; skb->dev = dev;
...@@ -1031,24 +1032,18 @@ SiS190_rx_interrupt(struct net_device *dev, struct sis190_private *tp, ...@@ -1031,24 +1032,18 @@ SiS190_rx_interrupt(struct net_device *dev, struct sis190_private *tp,
skb->protocol = eth_type_trans(skb, dev); skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb); netif_rx(skb);
tp->RxDescArray[cur_rx].PSize = 0x0; desc->PSize = 0x0;
if (cur_rx == (NUM_RX_DESC - 1)) if (cur_rx == (NUM_RX_DESC - 1))
tp->RxDescArray[cur_rx].buf_Len = desc->buf_Len = ENDbit + RX_BUF_SIZE;
ENDbit + RX_BUF_SIZE;
else else
tp->RxDescArray[cur_rx].buf_Len = desc->buf_Len = RX_BUF_SIZE;
RX_BUF_SIZE;
#warning Replace virt_to_bus with DMA mapping
tp->RxDescArray[cur_rx].buf_addr =
virt_to_bus(tp->RxBufferRing[cur_rx]);
dev->last_rx = jiffies; dev->last_rx = jiffies;
tp->stats.rx_bytes += pkt_size; tp->stats.rx_bytes += pkt_size;
tp->stats.rx_packets++; tp->stats.rx_packets++;
tp->RxDescArray[cur_rx].status = desc->status = OWNbit | INTbit;
OWNbit | INTbit;
} else { } else {
printk(KERN_WARNING printk(KERN_WARNING
"%s: Memory squeeze, deferring packet.\n", "%s: Memory squeeze, deferring packet.\n",
...@@ -1060,7 +1055,7 @@ SiS190_rx_interrupt(struct net_device *dev, struct sis190_private *tp, ...@@ -1060,7 +1055,7 @@ SiS190_rx_interrupt(struct net_device *dev, struct sis190_private *tp,
} }
cur_rx = (cur_rx + 1) % NUM_RX_DESC; cur_rx = (cur_rx + 1) % NUM_RX_DESC;
desc = tp->RxDescArray + cur_rx;
} }
tp->cur_rx = cur_rx; tp->cur_rx = cur_rx;
...@@ -1144,11 +1139,13 @@ SiS190_close(struct net_device *dev) ...@@ -1144,11 +1139,13 @@ SiS190_close(struct net_device *dev)
pci_free_consistent(tp->pci_dev, RX_DESC_TOTAL_SIZE, tp->RxDescArray, pci_free_consistent(tp->pci_dev, RX_DESC_TOTAL_SIZE, tp->RxDescArray,
tp->rx_dma); tp->rx_dma);
tp->TxDescArray = NULL; tp->TxDescArray = NULL;
tp->RxDescArray = NULL;
kfree(tp->RxBufferRings);
for (i = 0; i < NUM_RX_DESC; i++) { for (i = 0; i < NUM_RX_DESC; i++) {
pci_unmap_single(tp->pci_dev, tp->RxDescArray[i].buf_addr,
RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
tp->RxBufferRing[i] = NULL; tp->RxBufferRing[i] = NULL;
} }
tp->RxDescArray = NULL;
kfree(tp->RxBufferRings);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment