linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* r8169 with big-endian (patch)
@ 2003-11-05  7:46 Alexandra N. Kossovsky
  2003-11-05 18:34 ` Francois Romieu
  0 siblings, 1 reply; 3+ messages in thread
From: Alexandra N. Kossovsky @ 2003-11-05  7:46 UTC (permalink / raw)
  To: linux-kernel; +Cc: ShuChen

[-- Attachment #1: Type: text/plain, Size: 616 bytes --]

Hello!

Here is the patch to make RTL-8169 PCI Gbit ethernet card to work with
big-endian host. The patch is against 2.4.22 kernel.

It was tested with i386 and mips64-be.

I've added KERNEL_LICENSE("GPL") because I'd like to have my work under
this license. If Realtek does not want it, it is necessary to discuss this
problem.

Please, CC to me -- I'm not subscribed.

Regards,
    Alexandra.

-- 
Alexandra N. Kossovsky
OKTET Ltd.
http://www.oktet.ru/
1 Ulianovskaya st., Petergof, St.Petersburg, 198904 Russia
Phones: +7(812)428-43-84(work) +7(812)184-52-58(home) +7(812)956-42-86(mobile)
mailto:sasha@oktet.ru


[-- Attachment #2: r8169.diff --]
[-- Type: text/plain, Size: 9065 bytes --]

--- drivers/net/r8169.c.orig	Tue Nov  4 17:04:10 2003
+++ drivers/net/r8169.c	Wed Nov  5 10:32:21 2003
@@ -33,6 +33,11 @@
 	- Copy mc_filter setup code from 8139cp
 	  (includes an optimization, and avoids set_bit use)
 
+VERSION 1.3	2003/11/04
+	(C) OKTET Ltd. (www.oktet.ru)
+	Author Alexandra N. Kossovsky <Alexandra.Kossovsky@oktet.ru>
+	- Replace bus_to_virt/virt_to_bus by pci_alloc_consistent.
+	- Insert cpu_to_le/le_to_cpu where it is necessary. 
 */
 
 #include <linux/module.h>
@@ -45,7 +50,7 @@
 
 #include <asm/io.h>
 
-#define RTL8169_VERSION "1.2"
+#define RTL8169_VERSION "1.3"
 #define MODULENAME "r8169"
 #define RTL8169_DRIVER_NAME   MODULENAME " Gigabit Ethernet driver " RTL8169_VERSION
 #define PFX MODULENAME ": "
@@ -165,12 +170,6 @@
 	RxErr = 0x02,
 	RxOK = 0x01,
 
-	/*RxStatusDesc */
-	RxRES = 0x00200000,
-	RxCRC = 0x00080000,
-	RxRUNT = 0x00100000,
-	RxRWT = 0x00400000,
-
 	/*ChipCmdBits */
 	CmdReset = 0x10,
 	CmdRxEnb = 0x08,
@@ -251,10 +250,16 @@
 "RTL-8169", 0x00, 0xff7e1880,},};
 
 enum _DescStatusBit {
-	OWNbit = 0x80000000,
-	EORbit = 0x40000000,
-	FSbit = 0x20000000,
-	LSbit = 0x10000000,
+	OWNbit = __constant_cpu_to_le32(0x80000000),
+	EORbit = __constant_cpu_to_le32(0x40000000),
+	FSbit = __constant_cpu_to_le32(0x20000000),
+	LSbit = __constant_cpu_to_le32(0x10000000),
+
+	/*RxStatusDesc */
+	RxRES = __constant_cpu_to_le32(0x00200000),
+	RxCRC = __constant_cpu_to_le32(0x00080000),
+	RxRUNT = __constant_cpu_to_le32(0x00100000),
+	RxRWT = __constant_cpu_to_le32(0x00400000),
 };
 
 struct TxDesc {
@@ -284,13 +289,20 @@
 	unsigned char *RxDescArrays;	/* Index of Rx Descriptor buffer */
 	struct TxDesc *TxDescArray;	/* Index of 256-alignment Tx Descriptor buffer */
 	struct RxDesc *RxDescArray;	/* Index of 256-alignment Rx Descriptor buffer */
+	dma_addr_t     TxDescDmaAddrs;	/* DMA address of TxDescArrays */
+	dma_addr_t     RxDescDmaAddrs;	/* DMA address of RxDescArrays */
+	dma_addr_t     TxDescDmaAddr;	/* DMA address of TxDescArray */
+	dma_addr_t     RxDescDmaAddr;	/* DMA address of RxDescArray */
 	unsigned char *RxBufferRings;	/* Index of Rx Buffer  */
 	unsigned char *RxBufferRing[NUM_RX_DESC];	/* Index of Rx Buffer array */
+	dma_addr_t     RxBufferDmas;	/* DMA address of RxBufferRings */
+	dma_addr_t     RxBufferDma[NUM_RX_DESC];	/* DMA addresses of RxBufferRing */
 	struct sk_buff *Tx_skbuff[NUM_TX_DESC];	/* Index of Transmit data buffer */
 };
 
 MODULE_AUTHOR("Realtek");
 MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
+MODULE_LICENSE("GPL");
 MODULE_PARM(media, "1-" __MODULE_STRING(MAX_UNITS) "i");
 
 static int rtl8169_open(struct net_device *dev);
@@ -655,7 +667,6 @@
 	struct rtl8169_private *tp = dev->priv;
 	int retval;
 	u8 diff;
-	u32 TxPhyAddr, RxPhyAddr;
 
 	retval =
 	    request_irq(dev->irq, rtl8169_interrupt, SA_SHIRQ, dev->name, dev);
@@ -664,19 +675,21 @@
 	}
 
 	tp->TxDescArrays =
-	    kmalloc(NUM_TX_DESC * sizeof (struct TxDesc) + 256, GFP_KERNEL);
+	    pci_alloc_consistent(tp->pci_dev,
+				 NUM_TX_DESC * sizeof (struct TxDesc) + 256, 
+				 &tp->TxDescDmaAddrs);
 	// Tx Desscriptor needs 256 bytes alignment;
-	TxPhyAddr = virt_to_bus(tp->TxDescArrays);
-	diff = 256 - (TxPhyAddr - ((TxPhyAddr >> 8) << 8));
-	TxPhyAddr += diff;
+	diff = 256 - (tp->TxDescDmaAddrs - ((tp->TxDescDmaAddrs >> 8) << 8));
+	tp->TxDescDmaAddr = tp->TxDescDmaAddrs + diff;
 	tp->TxDescArray = (struct TxDesc *) (tp->TxDescArrays + diff);
 
 	tp->RxDescArrays =
-	    kmalloc(NUM_RX_DESC * sizeof (struct RxDesc) + 256, GFP_KERNEL);
+	    pci_alloc_consistent(tp->pci_dev,
+				 NUM_RX_DESC * sizeof (struct RxDesc) + 256, 
+				 &tp->RxDescDmaAddrs);
 	// Rx Desscriptor needs 256 bytes alignment;
-	RxPhyAddr = virt_to_bus(tp->RxDescArrays);
-	diff = 256 - (RxPhyAddr - ((RxPhyAddr >> 8) << 8));
-	RxPhyAddr += diff;
+	diff = 256 - (tp->RxDescDmaAddrs - ((tp->RxDescDmaAddrs >> 8) << 8));
+	tp->RxDescDmaAddr = tp->RxDescDmaAddrs + diff;
 	tp->RxDescArray = (struct RxDesc *) (tp->RxDescArrays + diff);
 
 	if (tp->TxDescArrays == NULL || tp->RxDescArrays == NULL) {
@@ -684,12 +697,18 @@
 		       "Allocate RxDescArray or TxDescArray failed\n");
 		free_irq(dev->irq, dev);
 		if (tp->TxDescArrays)
-			kfree(tp->TxDescArrays);
+			pci_free_consistent(tp->pci_dev, 
+				NUM_TX_DESC * sizeof (struct TxDesc) + 256,
+				tp->TxDescArrays, tp->TxDescDmaAddrs);
 		if (tp->RxDescArrays)
-			kfree(tp->RxDescArrays);
+			pci_free_consistent(tp->pci_dev, 
+				NUM_RX_DESC * sizeof (struct RxDesc) + 256,
+				tp->RxDescArrays, tp->RxDescDmaAddrs);
 		return -ENOMEM;
 	}
-	tp->RxBufferRings = kmalloc(RX_BUF_SIZE * NUM_RX_DESC, GFP_KERNEL);
+	tp->RxBufferRings = pci_alloc_consistent(tp->pci_dev,
+						 RX_BUF_SIZE * NUM_RX_DESC, 
+						 &tp->RxBufferDmas);
 	if (tp->RxBufferRings == NULL) {
 		printk(KERN_INFO "Allocate RxBufferRing failed\n");
 	}
@@ -733,13 +752,13 @@
 
 	/* Set DMA burst size and Interframe Gap Time */
 	RTL_W32(TxConfig,
-		(TX_DMA_BURST << TxDMAShift) | (InterFrameGap <<
-						TxInterFrameGapShift));
+		(TX_DMA_BURST << TxDMAShift) | 
+			    (InterFrameGap << TxInterFrameGapShift));
 
 	tp->cur_rx = 0;
 
-	RTL_W32(TxDescStartAddr, virt_to_bus(tp->TxDescArray));
-	RTL_W32(RxDescStartAddr, virt_to_bus(tp->RxDescArray));
+	RTL_W32(TxDescStartAddr, tp->TxDescDmaAddr);
+	RTL_W32(RxDescStartAddr, tp->RxDescDmaAddr);
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 	udelay(10);
 
@@ -775,12 +794,17 @@
 	for (i = 0; i < NUM_RX_DESC; i++) {
 		if (i == (NUM_RX_DESC - 1))
 			tp->RxDescArray[i].status =
-			    (OWNbit | EORbit) + RX_BUF_SIZE;
+			    (OWNbit | EORbit) | 
+			    __constant_cpu_to_le32(RX_BUF_SIZE);
 		else
-			tp->RxDescArray[i].status = OWNbit + RX_BUF_SIZE;
+			tp->RxDescArray[i].status = OWNbit | 
+				__constant_cpu_to_le32(RX_BUF_SIZE);
 
 		tp->RxBufferRing[i] = &(tp->RxBufferRings[i * RX_BUF_SIZE]);
-		tp->RxDescArray[i].buf_addr = virt_to_bus(tp->RxBufferRing[i]);
+		tp->RxBufferDma[i] = 
+			(dma_addr_t)((unsigned int)tp->RxBufferDmas + 
+				     i * RX_BUF_SIZE);
+		tp->RxDescArray[i].buf_addr = cpu_to_le32(tp->RxBufferDma[i]);
 	}
 }
 
@@ -842,15 +866,19 @@
 
 	if ((tp->TxDescArray[entry].status & OWNbit) == 0) {
 		tp->Tx_skbuff[entry] = skb;
-		tp->TxDescArray[entry].buf_addr = virt_to_bus(skb->data);
+		tp->TxDescArray[entry].buf_addr = 
+			cpu_to_le32(pci_map_single(tp->pci_dev, skb->data,
+						   skb->len, PCI_DMA_TODEVICE));
 		if (entry != (NUM_TX_DESC - 1))
 			tp->TxDescArray[entry].status =
-			    (OWNbit | FSbit | LSbit) | ((skb->len > ETH_ZLEN) ?
-							skb->len : ETH_ZLEN);
+			    (OWNbit | FSbit | LSbit) | 
+			    cpu_to_le32((skb->len > ETH_ZLEN) ?
+					skb->len : ETH_ZLEN);
 		else
 			tp->TxDescArray[entry].status =
 			    (OWNbit | EORbit | FSbit | LSbit) |
-			    ((skb->len > ETH_ZLEN) ? skb->len : ETH_ZLEN);
+			    cpu_to_le32(((skb->len > ETH_ZLEN) ? 
+					 skb->len : ETH_ZLEN));
 
 		RTL_W8(TxPoll, 0x40);	//set polling bit
 
@@ -884,8 +912,14 @@
 
 	while (tx_left > 0) {
 		if ((tp->TxDescArray[entry].status & OWNbit) == 0) {
-			dev_kfree_skb_irq(tp->
-					  Tx_skbuff[dirty_tx % NUM_TX_DESC]);
+			struct sk_buff *skb = 
+				tp->Tx_skbuff[dirty_tx % NUM_TX_DESC];
+
+			pci_unmap_single(tp->pci_dev, 
+					 le32_to_cpu(tp->TxDescArray[entry].
+						     buf_addr), 
+					 skb->len, PCI_DMA_TODEVICE);
+			dev_kfree_skb_irq(skb);
 			tp->Tx_skbuff[dirty_tx % NUM_TX_DESC] = NULL;
 			tp->stats.tx_packets++;
 			dirty_tx++;
@@ -926,8 +960,8 @@
 				tp->stats.rx_crc_errors++;
 		} else {
 			pkt_size =
-			    (int) (tp->RxDescArray[cur_rx].
-				   status & 0x00001FFF) - 4;
+			    (int) (le32_to_cpu(tp->RxDescArray[cur_rx].
+				   status) & 0x00001FFF) - 4;
 			skb = dev_alloc_skb(pkt_size + 2);
 			if (skb != NULL) {
 				skb->dev = dev;
@@ -940,13 +974,15 @@
 
 				if (cur_rx == (NUM_RX_DESC - 1))
 					tp->RxDescArray[cur_rx].status =
-					    (OWNbit | EORbit) + RX_BUF_SIZE;
+					    (OWNbit | EORbit) | 
+					    __constant_cpu_to_le32(RX_BUF_SIZE);
 				else
 					tp->RxDescArray[cur_rx].status =
-					    OWNbit + RX_BUF_SIZE;
+					    OWNbit | 
+					    __constant_cpu_to_le32(RX_BUF_SIZE);
 
 				tp->RxDescArray[cur_rx].buf_addr =
-				    virt_to_bus(tp->RxBufferRing[cur_rx]);
+				    cpu_to_le32(tp->RxBufferDma[cur_rx]);
 				dev->last_rx = jiffies;
 				tp->stats.rx_bytes += pkt_size;
 				tp->stats.rx_packets++;
@@ -1045,13 +1081,18 @@
 	free_irq(dev->irq, dev);
 
 	rtl8169_tx_clear(tp);
-	kfree(tp->TxDescArrays);
-	kfree(tp->RxDescArrays);
+	pci_free_consistent(tp->pci_dev, 
+		NUM_TX_DESC * sizeof (struct TxDesc) + 256,
+		tp->TxDescArrays, tp->TxDescDmaAddrs);
+	pci_free_consistent(tp->pci_dev, 
+		NUM_RX_DESC * sizeof (struct RxDesc) + 256,
+		tp->RxDescArrays, tp->RxDescDmaAddrs);
 	tp->TxDescArrays = NULL;
 	tp->RxDescArrays = NULL;
 	tp->TxDescArray = NULL;
 	tp->RxDescArray = NULL;
-	kfree(tp->RxBufferRings);
+	pci_free_consistent(tp->pci_dev, RX_BUF_SIZE * NUM_RX_DESC,
+			    tp->RxBufferRings, tp->RxBufferDmas);
 	for (i = 0; i < NUM_RX_DESC; i++) {
 		tp->RxBufferRing[i] = NULL;
 	}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: r8169 with big-endian (patch)
  2003-11-05  7:46 r8169 with big-endian (patch) Alexandra N. Kossovsky
@ 2003-11-05 18:34 ` Francois Romieu
  2003-11-06 11:55   ` Alexandra N. Kossovsky
  0 siblings, 1 reply; 3+ messages in thread
From: Francois Romieu @ 2003-11-05 18:34 UTC (permalink / raw)
  To: Alexandra N. Kossovsky; +Cc: linux-kernel, ShuChen, netdev

Greetings,

Alexandra N. Kossovsky <sasha@oktet.ru> :
[...]
> Here is the patch to make RTL-8169 PCI Gbit ethernet card to work with
> big-endian host. The patch is against 2.4.22 kernel.

Please Cc: such patches to netdev@oss.sgi.com as well as jgarzik@pobox.com.

[...]
> @@ -664,19 +675,21 @@
>  	}
>  
>  	tp->TxDescArrays =
> -	    kmalloc(NUM_TX_DESC * sizeof (struct TxDesc) + 256, GFP_KERNEL);
> +	    pci_alloc_consistent(tp->pci_dev,
> +				 NUM_TX_DESC * sizeof (struct TxDesc) + 256, 
> +				 &tp->TxDescDmaAddrs);
> -	TxPhyAddr = virt_to_bus(tp->TxDescArrays);
> -	diff = 256 - (TxPhyAddr - ((TxPhyAddr >> 8) << 8));
> -	TxPhyAddr += diff;
> +	diff = 256 - (tp->TxDescDmaAddrs - ((tp->TxDescDmaAddrs >> 8) << 8));
> +	tp->TxDescDmaAddr = tp->TxDescDmaAddrs + diff;
>  	tp->TxDescArray = (struct TxDesc *) (tp->TxDescArrays + diff);

Remove the alignment stuff. pci_alloc_consistent() does it for you,
see Documentation/DMA-mapping.txt:
[...]
The cpu return address and the DMA bus master address are both
guaranteed to be aligned to the smallest PAGE_SIZE order which
is greater than or equal to the requested size.  This invariant


@@ -684,12 +697,18 @@
[...]
-       tp->RxBufferRings = kmalloc(RX_BUF_SIZE * NUM_RX_DESC, GFP_KERNEL);
+       tp->RxBufferRings = pci_alloc_consistent(tp->pci_dev,
+                                                RX_BUF_SIZE * NUM_RX_DESC,
+                                                &tp->RxBufferDmas);

You don't want consistent mapping for the data buffer.
Either you pci_map_single() the whole kmalloced() area and you sync it
when needed or you turn this code into usual, per skb, pci_map_single()
calls and you remove the big Rx data buffer.

--
Ueimor

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: r8169 with big-endian (patch)
  2003-11-05 18:34 ` Francois Romieu
@ 2003-11-06 11:55   ` Alexandra N. Kossovsky
  0 siblings, 0 replies; 3+ messages in thread
From: Alexandra N. Kossovsky @ 2003-11-06 11:55 UTC (permalink / raw)
  To: Francois Romieu; +Cc: linux-kernel, ShuChen, netdev, jgarzik

[-- Attachment #1: Type: text/plain, Size: 320 bytes --]

Hello.

Here is next version of the patch, thanks to Francois Romieu.

Best regards,
    Alexandra.
-- 
Alexandra N. Kossovsky
OKTET Ltd.
http://www.oktet.ru/
1 Ulianovskaya st., Petergof, St.Petersburg, 198904 Russia
Phones: +7(812)428-43-84(work) +7(812)184-52-58(home) +7(812)956-42-86(mobile)
mailto:sasha@oktet.ru


[-- Attachment #2: r8169.diff --]
[-- Type: text/plain, Size: 9761 bytes --]

--- drivers/net/r8169.c.orig	2003-11-06 14:53:18.000000000 +0300
+++ drivers/net/r8169.c	2003-11-06 14:54:17.000000000 +0300
@@ -33,6 +33,11 @@
 	- Copy mc_filter setup code from 8139cp
 	  (includes an optimization, and avoids set_bit use)
 
+VERSION 1.2.1	2003/11/04
+	(C) OKTET Ltd. (www.oktet.ru)
+	Author Alexandra N. Kossovsky <Alexandra.Kossovsky@oktet.ru>
+	- Replace bus_to_virt/virt_to_bus by pci_alloc_consistent.
+	- Insert cpu_to_le/le_to_cpu where it is necessary. 
 */
 
 #include <linux/module.h>
@@ -45,7 +50,7 @@
 
 #include <asm/io.h>
 
-#define RTL8169_VERSION "1.2"
+#define RTL8169_VERSION "1.2.1"
 #define MODULENAME "r8169"
 #define RTL8169_DRIVER_NAME   MODULENAME " Gigabit Ethernet driver " RTL8169_VERSION
 #define PFX MODULENAME ": "
@@ -165,12 +170,6 @@
 	RxErr = 0x02,
 	RxOK = 0x01,
 
-	/*RxStatusDesc */
-	RxRES = 0x00200000,
-	RxCRC = 0x00080000,
-	RxRUNT = 0x00100000,
-	RxRWT = 0x00400000,
-
 	/*ChipCmdBits */
 	CmdReset = 0x10,
 	CmdRxEnb = 0x08,
@@ -251,10 +250,16 @@
 "RTL-8169", 0x00, 0xff7e1880,},};
 
 enum _DescStatusBit {
-	OWNbit = 0x80000000,
-	EORbit = 0x40000000,
-	FSbit = 0x20000000,
-	LSbit = 0x10000000,
+	OWNbit = __constant_cpu_to_le32(0x80000000),
+	EORbit = __constant_cpu_to_le32(0x40000000),
+	FSbit = __constant_cpu_to_le32(0x20000000),
+	LSbit = __constant_cpu_to_le32(0x10000000),
+
+	/*RxStatusDesc */
+	RxRES = __constant_cpu_to_le32(0x00200000),
+	RxCRC = __constant_cpu_to_le32(0x00080000),
+	RxRUNT = __constant_cpu_to_le32(0x00100000),
+	RxRWT = __constant_cpu_to_le32(0x00400000),
 };
 
 struct TxDesc {
@@ -280,17 +285,20 @@
 	unsigned long cur_rx;	/* Index into the Rx descriptor buffer of next Rx pkt. */
 	unsigned long cur_tx;	/* Index into the Tx descriptor buffer of next Rx pkt. */
 	unsigned long dirty_tx;
-	unsigned char *TxDescArrays;	/* Index of Tx Descriptor buffer */
-	unsigned char *RxDescArrays;	/* Index of Rx Descriptor buffer */
 	struct TxDesc *TxDescArray;	/* Index of 256-alignment Tx Descriptor buffer */
 	struct RxDesc *RxDescArray;	/* Index of 256-alignment Rx Descriptor buffer */
+	dma_addr_t     TxDescDmaAddr;	/* DMA address of TxDescArray */
+	dma_addr_t     RxDescDmaAddr;	/* DMA address of RxDescArray */
 	unsigned char *RxBufferRings;	/* Index of Rx Buffer  */
 	unsigned char *RxBufferRing[NUM_RX_DESC];	/* Index of Rx Buffer array */
+	dma_addr_t     RxBufferDmas;	/* DMA address of RxBufferRings */
+	dma_addr_t     RxBufferDma[NUM_RX_DESC];	/* DMA addresses of RxBufferRing */
 	struct sk_buff *Tx_skbuff[NUM_TX_DESC];	/* Index of Transmit data buffer */
 };
 
 MODULE_AUTHOR("Realtek");
 MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
+MODULE_LICENSE("GPL");
 MODULE_PARM(media, "1-" __MODULE_STRING(MAX_UNITS) "i");
 
 static int rtl8169_open(struct net_device *dev);
@@ -654,8 +662,6 @@
 {
 	struct rtl8169_private *tp = dev->priv;
 	int retval;
-	u8 diff;
-	u32 TxPhyAddr, RxPhyAddr;
 
 	retval =
 	    request_irq(dev->irq, rtl8169_interrupt, SA_SHIRQ, dev->name, dev);
@@ -663,36 +669,37 @@
 		return retval;
 	}
 
-	tp->TxDescArrays =
-	    kmalloc(NUM_TX_DESC * sizeof (struct TxDesc) + 256, GFP_KERNEL);
-	// Tx Desscriptor needs 256 bytes alignment;
-	TxPhyAddr = virt_to_bus(tp->TxDescArrays);
-	diff = 256 - (TxPhyAddr - ((TxPhyAddr >> 8) << 8));
-	TxPhyAddr += diff;
-	tp->TxDescArray = (struct TxDesc *) (tp->TxDescArrays + diff);
-
-	tp->RxDescArrays =
-	    kmalloc(NUM_RX_DESC * sizeof (struct RxDesc) + 256, GFP_KERNEL);
-	// Rx Desscriptor needs 256 bytes alignment;
-	RxPhyAddr = virt_to_bus(tp->RxDescArrays);
-	diff = 256 - (RxPhyAddr - ((RxPhyAddr >> 8) << 8));
-	RxPhyAddr += diff;
-	tp->RxDescArray = (struct RxDesc *) (tp->RxDescArrays + diff);
+	tp->TxDescArray = (struct TxDesc *)
+	    pci_alloc_consistent(tp->pci_dev,
+				 NUM_TX_DESC * sizeof (struct TxDesc) + 256, 
+				 &tp->TxDescDmaAddr);
+
+	tp->RxDescArray = (struct RxDesc *)
+	    pci_alloc_consistent(tp->pci_dev,
+				 NUM_RX_DESC * sizeof (struct RxDesc) + 256, 
+				 &tp->RxDescDmaAddr);
 
-	if (tp->TxDescArrays == NULL || tp->RxDescArrays == NULL) {
+	if (tp->TxDescArray == NULL || tp->RxDescArray == NULL) {
 		printk(KERN_INFO
 		       "Allocate RxDescArray or TxDescArray failed\n");
 		free_irq(dev->irq, dev);
-		if (tp->TxDescArrays)
-			kfree(tp->TxDescArrays);
-		if (tp->RxDescArrays)
-			kfree(tp->RxDescArrays);
+		if (tp->TxDescArray)
+			pci_free_consistent(tp->pci_dev, 
+				NUM_TX_DESC * sizeof (struct TxDesc) + 256,
+				tp->TxDescArray, tp->TxDescDmaAddr);
+		if (tp->RxDescArray)
+			pci_free_consistent(tp->pci_dev, 
+				NUM_RX_DESC * sizeof (struct RxDesc) + 256,
+				tp->RxDescArray, tp->RxDescDmaAddr);
 		return -ENOMEM;
 	}
-	tp->RxBufferRings = kmalloc(RX_BUF_SIZE * NUM_RX_DESC, GFP_KERNEL);
+        tp->RxBufferRings = kmalloc(RX_BUF_SIZE * NUM_RX_DESC, GFP_KERNEL);
 	if (tp->RxBufferRings == NULL) {
 		printk(KERN_INFO "Allocate RxBufferRing failed\n");
 	}
+	tp->RxBufferDmas = pci_map_single(tp->pci_dev, tp->RxBufferRings,
+					  RX_BUF_SIZE * NUM_RX_DESC, 
+					  PCI_DMA_FROMDEVICE);
 
 	rtl8169_init_ring(dev);
 	rtl8169_hw_start(dev);
@@ -733,13 +740,13 @@
 
 	/* Set DMA burst size and Interframe Gap Time */
 	RTL_W32(TxConfig,
-		(TX_DMA_BURST << TxDMAShift) | (InterFrameGap <<
-						TxInterFrameGapShift));
+		(TX_DMA_BURST << TxDMAShift) | 
+			    (InterFrameGap << TxInterFrameGapShift));
 
 	tp->cur_rx = 0;
 
-	RTL_W32(TxDescStartAddr, virt_to_bus(tp->TxDescArray));
-	RTL_W32(RxDescStartAddr, virt_to_bus(tp->RxDescArray));
+	RTL_W32(TxDescStartAddr, tp->TxDescDmaAddr);
+	RTL_W32(RxDescStartAddr, tp->RxDescDmaAddr);
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 	udelay(10);
 
@@ -775,12 +782,17 @@
 	for (i = 0; i < NUM_RX_DESC; i++) {
 		if (i == (NUM_RX_DESC - 1))
 			tp->RxDescArray[i].status =
-			    (OWNbit | EORbit) + RX_BUF_SIZE;
+			    (OWNbit | EORbit) | 
+			    __constant_cpu_to_le32(RX_BUF_SIZE);
 		else
-			tp->RxDescArray[i].status = OWNbit + RX_BUF_SIZE;
+			tp->RxDescArray[i].status = OWNbit | 
+				__constant_cpu_to_le32(RX_BUF_SIZE);
 
 		tp->RxBufferRing[i] = &(tp->RxBufferRings[i * RX_BUF_SIZE]);
-		tp->RxDescArray[i].buf_addr = virt_to_bus(tp->RxBufferRing[i]);
+		tp->RxBufferDma[i] = 
+			(dma_addr_t)((unsigned int)tp->RxBufferDmas + 
+				     i * RX_BUF_SIZE);
+		tp->RxDescArray[i].buf_addr = cpu_to_le32(tp->RxBufferDma[i]);
 	}
 }
 
@@ -842,15 +854,19 @@
 
 	if ((tp->TxDescArray[entry].status & OWNbit) == 0) {
 		tp->Tx_skbuff[entry] = skb;
-		tp->TxDescArray[entry].buf_addr = virt_to_bus(skb->data);
+		tp->TxDescArray[entry].buf_addr = 
+			cpu_to_le32(pci_map_single(tp->pci_dev, skb->data,
+						   skb->len, PCI_DMA_TODEVICE));
 		if (entry != (NUM_TX_DESC - 1))
 			tp->TxDescArray[entry].status =
-			    (OWNbit | FSbit | LSbit) | ((skb->len > ETH_ZLEN) ?
-							skb->len : ETH_ZLEN);
+			    (OWNbit | FSbit | LSbit) | 
+			    cpu_to_le32((skb->len > ETH_ZLEN) ?
+					skb->len : ETH_ZLEN);
 		else
 			tp->TxDescArray[entry].status =
 			    (OWNbit | EORbit | FSbit | LSbit) |
-			    ((skb->len > ETH_ZLEN) ? skb->len : ETH_ZLEN);
+			    cpu_to_le32(((skb->len > ETH_ZLEN) ? 
+					 skb->len : ETH_ZLEN));
 
 		RTL_W8(TxPoll, 0x40);	//set polling bit
 
@@ -884,8 +900,14 @@
 
 	while (tx_left > 0) {
 		if ((tp->TxDescArray[entry].status & OWNbit) == 0) {
-			dev_kfree_skb_irq(tp->
-					  Tx_skbuff[dirty_tx % NUM_TX_DESC]);
+			struct sk_buff *skb = 
+				tp->Tx_skbuff[dirty_tx % NUM_TX_DESC];
+
+			pci_unmap_single(tp->pci_dev, 
+					 le32_to_cpu(tp->TxDescArray[entry].
+						     buf_addr), 
+					 skb->len, PCI_DMA_TODEVICE);
+			dev_kfree_skb_irq(skb);
 			tp->Tx_skbuff[dirty_tx % NUM_TX_DESC] = NULL;
 			tp->stats.tx_packets++;
 			dirty_tx++;
@@ -926,12 +948,16 @@
 				tp->stats.rx_crc_errors++;
 		} else {
 			pkt_size =
-			    (int) (tp->RxDescArray[cur_rx].
-				   status & 0x00001FFF) - 4;
+			    (int) (le32_to_cpu(tp->RxDescArray[cur_rx].
+				   status) & 0x00001FFF) - 4;
 			skb = dev_alloc_skb(pkt_size + 2);
 			if (skb != NULL) {
 				skb->dev = dev;
 				skb_reserve(skb, 2);	// 16 byte align the IP fields. //
+                                pci_dma_sync_single(tp->pci_dev, 
+                                                    tp->RxBufferDmas,
+                                                    RX_BUF_SIZE * NUM_RX_DESC,
+                                                    PCI_DMA_FROMDEVICE);
 				eth_copy_and_sum(skb, tp->RxBufferRing[cur_rx],
 						 pkt_size, 0);
 				skb_put(skb, pkt_size);
@@ -940,13 +966,15 @@
 
 				if (cur_rx == (NUM_RX_DESC - 1))
 					tp->RxDescArray[cur_rx].status =
-					    (OWNbit | EORbit) + RX_BUF_SIZE;
+					    (OWNbit | EORbit) | 
+					    __constant_cpu_to_le32(RX_BUF_SIZE);
 				else
 					tp->RxDescArray[cur_rx].status =
-					    OWNbit + RX_BUF_SIZE;
+					    OWNbit | 
+					    __constant_cpu_to_le32(RX_BUF_SIZE);
 
 				tp->RxDescArray[cur_rx].buf_addr =
-				    virt_to_bus(tp->RxBufferRing[cur_rx]);
+				    cpu_to_le32(tp->RxBufferDma[cur_rx]);
 				dev->last_rx = jiffies;
 				tp->stats.rx_bytes += pkt_size;
 				tp->stats.rx_packets++;
@@ -1045,12 +1073,16 @@
 	free_irq(dev->irq, dev);
 
 	rtl8169_tx_clear(tp);
-	kfree(tp->TxDescArrays);
-	kfree(tp->RxDescArrays);
-	tp->TxDescArrays = NULL;
-	tp->RxDescArrays = NULL;
+	pci_free_consistent(tp->pci_dev, 
+		NUM_TX_DESC * sizeof (struct TxDesc) + 256,
+		tp->TxDescArray, tp->TxDescDmaAddr);
+	pci_free_consistent(tp->pci_dev, 
+		NUM_RX_DESC * sizeof (struct RxDesc) + 256,
+		tp->RxDescArray, tp->RxDescDmaAddr);
 	tp->TxDescArray = NULL;
 	tp->RxDescArray = NULL;
+	pci_unmap_single(tp->pci_dev, tp->RxBufferDmas, 
+			 RX_BUF_SIZE * NUM_RX_DESC, PCI_DMA_FROMDEVICE);
 	kfree(tp->RxBufferRings);
 	for (i = 0; i < NUM_RX_DESC; i++) {
 		tp->RxBufferRing[i] = NULL;

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2003-11-06 11:56 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-11-05  7:46 r8169 with big-endian (patch) Alexandra N. Kossovsky
2003-11-05 18:34 ` Francois Romieu
2003-11-06 11:55   ` Alexandra N. Kossovsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).