Conversion of Tx data buffers to PCI DMA: - endianness is kept in a fscked state as it is in the original code (will be adressed in a later patch); - buf_addr of an unmapped descriptor is always set to the same value (cf rtl8169_unmap_tx_skb); - nothing fancy, really. drivers/net/r8169.c | 36 +++++++++++++++++++++++++++++------- 1 files changed, 29 insertions(+), 7 deletions(-) diff -puN drivers/net/r8169.c~r8169-dma-api-tx-buffers drivers/net/r8169.c --- linux-2.6.0-test9/drivers/net/r8169.c~r8169-dma-api-tx-buffers 2003-11-21 01:08:42.000000000 +0100 +++ linux-2.6.0-test9-fr/drivers/net/r8169.c 2003-11-21 01:08:42.000000000 +0100 @@ -871,6 +871,17 @@ err_out: return -ENOMEM; } +static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, + struct TxDesc *desc) +{ + u32 len = sk_buff[0]->len; + + pci_unmap_single(pdev, desc->buf_addr, len < ETH_ZLEN ? ETH_ZLEN : len, + PCI_DMA_TODEVICE); + desc->buf_addr = 0x00; + *sk_buff = NULL; +} + static void rtl8169_tx_clear(struct rtl8169_private *tp) { @@ -878,9 +889,12 @@ rtl8169_tx_clear(struct rtl8169_private tp->cur_tx = 0; for (i = 0; i < NUM_TX_DESC; i++) { - if (tp->Tx_skbuff[i] != NULL) { - dev_kfree_skb(tp->Tx_skbuff[i]); - tp->Tx_skbuff[i] = NULL; + struct sk_buff *skb = tp->Tx_skbuff[i]; + + if (skb) { + rtl8169_unmap_tx_skb(tp->pci_dev, tp->Tx_skbuff + i, + tp->TxDescArray + i); + dev_kfree_skb(skb); tp->stats.tx_dropped++; } } @@ -930,8 +944,13 @@ rtl8169_start_xmit(struct sk_buff *skb, spin_lock_irq(&tp->lock); if ((tp->TxDescArray[entry].status & OWNbit) == 0) { + dma_addr_t mapping; + + mapping = pci_map_single(tp->pci_dev, skb->data, len, + PCI_DMA_TODEVICE); + tp->Tx_skbuff[entry] = skb; - tp->TxDescArray[entry].buf_addr = virt_to_bus(skb->data); + tp->TxDescArray[entry].buf_addr = mapping; tp->TxDescArray[entry].status = OWNbit | FSbit | LSbit | len | (EORbit * !((entry + 1) % NUM_TX_DESC)); @@ -976,9 +995,12 @@ rtl8169_tx_interrupt(struct net_device * while (tx_left > 0) { if ((tp->TxDescArray[entry].status & OWNbit) == 0) { - dev_kfree_skb_irq(tp-> - Tx_skbuff[dirty_tx % NUM_TX_DESC]); - tp->Tx_skbuff[dirty_tx % NUM_TX_DESC] = NULL; + int cur = dirty_tx % NUM_TX_DESC; + struct sk_buff *skb = tp->Tx_skbuff[cur]; + + rtl8169_unmap_tx_skb(tp->pci_dev, tp->Tx_skbuff + cur, + tp->TxDescArray + cur); + dev_kfree_skb_irq(skb); tp->stats.tx_packets++; dirty_tx++; tx_left--; _