This forcedeth patch adds high dma support for tx/rx rings.

Signed-off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig-2.6/drivers/net/forcedeth.c    2006-01-21 23:47:55.000000000 -0500
+++ new-2.6/drivers/net/forcedeth.c     2006-01-21 23:49:35.000000000 -0500
@@ -103,6 +103,7 @@
  *     0.48: 24 Dec 2005: Disable TSO, bugfix for pci_map_single
  *     0.49: 10 Dec 2005: Fix tso for large buffers.
  *     0.50: 20 Jan 2006: Add 8021pq tagging support.
+ *     0.51: 20 Jan 2006: Add 64bit consistent memory allocation for rings.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -114,7 +115,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION              "0.50"
+#define FORCEDETH_VERSION              "0.51"
 #define DRV_NAME                       "forcedeth"
 
 #include <linux/module.h>
@@ -258,6 +259,8 @@
 #define NVREG_TXRXCTL_DESC_3   0x02200
 #define NVREG_TXRXCTL_VLANSTRIP 0x00040
 #define NVREG_TXRXCTL_VLANINS  0x00080
+       NvRegTxRingPhysAddrHigh = 0x148,
+       NvRegRxRingPhysAddrHigh = 0x14C,
        NvRegMIIStatus = 0x180,
 #define NVREG_MIISTAT_ERROR            0x0001
 #define NVREG_MIISTAT_LINKCHANGE       0x0008
@@ -627,6 +630,33 @@
        return 0;
 }
 
+#define NV_SETUP_RX_RING 0x01
+#define NV_SETUP_TX_RING 0x02
+
+static void setup_hw_rings(struct net_device *dev, int rxtx_flags)
+{
+       struct fe_priv *np = get_nvpriv(dev);
+       u8 __iomem *base = get_hwbase(dev);
+
+       if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
+               if (rxtx_flags & NV_SETUP_RX_RING) {
+                       writel((u32) cpu_to_le64(np->ring_addr), base + 
NvRegRxRingPhysAddr);
+               }
+               if (rxtx_flags & NV_SETUP_TX_RING) {
+                       writel((u32) cpu_to_le64(np->ring_addr + 
RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr);
+               }
+       } else {
+               if (rxtx_flags & NV_SETUP_RX_RING) {
+                       writel((u32) cpu_to_le64(np->ring_addr), base + 
NvRegRxRingPhysAddr);
+                       writel((u32) (cpu_to_le64(np->ring_addr) >> 32), base + 
NvRegRxRingPhysAddrHigh);
+               }
+               if (rxtx_flags & NV_SETUP_TX_RING) {
+                       writel((u32) cpu_to_le64(np->ring_addr + 
RX_RING*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr);
+                       writel((u32) (cpu_to_le64(np->ring_addr + 
RX_RING*sizeof(struct ring_desc_ex)) >> 32), base + NvRegTxRingPhysAddrHigh);
+               }
+       }
+}
+
 #define MII_READ       (-1)
 /* mii_rw: read/write a register on the PHY.
  *
@@ -1295,10 +1325,7 @@
                printk(KERN_DEBUG "%s: tx_timeout: dead entries!\n", dev->name);
                nv_drain_tx(dev);
                np->next_tx = np->nic_tx = 0;
-               if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
-                       writel((u32) (np->ring_addr + RX_RING*sizeof(struct 
ring_desc)), base + NvRegTxRingPhysAddr);
-               else
-                       writel((u32) (np->ring_addr + RX_RING*sizeof(struct 
ring_desc_ex)), base + NvRegTxRingPhysAddr);
+               setup_hw_rings(dev, NV_SETUP_TX_RING);
                netif_wake_queue(dev);
        }
 
@@ -1573,11 +1600,7 @@
                }
                /* reinit nic view of the rx queue */
                writel(np->rx_buf_sz, base + NvRegOffloadConfig);
-               writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr);
-               if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
-                       writel((u32) (np->ring_addr + RX_RING*sizeof(struct 
ring_desc)), base + NvRegTxRingPhysAddr);
-               else
-                       writel((u32) (np->ring_addr + RX_RING*sizeof(struct 
ring_desc_ex)), base + NvRegTxRingPhysAddr);
+               setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING);
                writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << 
NVREG_RINGSZ_TXSHIFT),
                        base + NvRegRingSizes);
                pci_push(base);
@@ -2310,11 +2333,7 @@
        nv_copy_mac_to_hw(dev);
 
        /* 4) give hw rings */
-       writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr);
-       if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
-               writel((u32) (np->ring_addr + RX_RING*sizeof(struct 
ring_desc)), base + NvRegTxRingPhysAddr);
-       else
-               writel((u32) (np->ring_addr + RX_RING*sizeof(struct 
ring_desc_ex)), base + NvRegTxRingPhysAddr);
+       setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING);
        writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << 
NVREG_RINGSZ_TXSHIFT),
                base + NvRegRingSizes);
 
@@ -2529,7 +2548,14 @@
                        printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 
32-bit addressing for device %s.\n",
                                        pci_name(pci_dev));
                } else {
-                       dev->features |= NETIF_F_HIGHDMA;
+                       if (pci_set_consistent_dma_mask(pci_dev, 
0x0000007fffffffffULL)) {
+                               printk(KERN_INFO "forcedeth: 64-bit DMA 
(consistent) failed for device %s.\n",
+                                       pci_name(pci_dev));
+                               goto out_relreg;
+                       } else {
+                               dev->features |= NETIF_F_HIGHDMA;
+                               printk(KERN_INFO "forcedeth: using HIGHDMA\n");
+                       }
                }
                np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
        } else if (id->driver_data & DEV_HAS_LARGEDESC) {

Reply via email to