From: Benjamin LaHaise <bcrl@redhat.com>
To: Marcelo Tosatti <marcelo@conectiva.com.br>,
Linux Kernel <linux-kernel@vger.kernel.org>
Subject: [patch] ns83820 v0.18 update
Date: Mon, 10 Jun 2002 21:53:24 -0400 [thread overview]
Message-ID: <20020610215324.D13225@redhat.com> (raw)
This patch fixes a bug in ns83820.c in conjunction with the pci
dma fix and allows zero copy tx from highmem to function again.
It also removes the cruft from the pre-pci highmem days to bring
the driver into compliance with the pci dma mapping api.
-ben
--
"You will be reincarnated as a toad; and you will be much happier."
:r ~/patches/v2.4/v2.4.19-pre10-ns83820-0.18.diff
diff -urN v2.4.19-pre10/drivers/net/ns83820.c ns83820-v2.4.19-pre10/drivers/net/ns83820.c
--- v2.4.19-pre10/drivers/net/ns83820.c Thu Jun 6 20:10:02 2002
+++ ns83820-v2.4.19-pre10/drivers/net/ns83820.c Mon Jun 10 21:50:27 2002
@@ -1,10 +1,12 @@
-#define _VERSION "0.17"
-/* ns83820.c by Benjamin LaHaise <bcrl@redhat.com> with contributions.
+#define _VERSION "0.18"
+/* ns83820.c by Benjamin LaHaise with contributions.
*
- * $Revision: 1.34.2.14 $
+ * Questions/comments/discussion to linux-ns83820@kvack.org.
+ *
+ * $Revision: 1.34.2.16 $
*
* Copyright 2001 Benjamin LaHaise.
- * Copyright 2001 Red Hat.
+ * Copyright 2001, 2002 Red Hat.
*
* Mmmm, chocolate vanilla mocha...
*
@@ -53,6 +55,8 @@
* 20011204 0.15 get ppc (big endian) working
* 20011218 0.16 various cleanups
* 20020310 0.17 speedups
+ * 20020610 0.18 - actually use the pci dma api for highmem
+ * - remove pci latency register fiddling
*
* Driver Overview
* ===============
@@ -105,54 +109,16 @@
#undef Dprintk
#define Dprintk dprintk
-#ifdef CONFIG_HIGHMEM64G
-#define USE_64BIT_ADDR "+"
-#elif defined(__ia64__)
+#if defined(CONFIG_HIGHMEM64G) || defined(__ia64__)
#define USE_64BIT_ADDR "+"
#endif
-/* Tell davem to fix the pci dma api. Grrr. */
-/* stolen from acenic.c */
-#if 0 //def CONFIG_HIGHMEM
-#if defined(CONFIG_X86)
-#define DMAADDR_OFFSET 0
-#if defined(CONFIG_HIGHMEM64G)
-typedef u64 dmaaddr_high_t;
-#else
-typedef u32 dmaaddr_high_t;
-#endif
-#elif defined(CONFIG_PPC)
-#define DMAADDR_OFFSET PCI_DRAM_OFFSET
-typedef unsigned long dmaaddr_high_t;
-#endif
-
-static inline dmaaddr_high_t
-pci_map_single_high(struct pci_dev *hwdev, struct page *page,
- int offset, size_t size, int dir)
-{
- u64 phys;
- phys = page - mem_map;
- phys <<= PAGE_SHIFT;
- phys += offset;
- phys += DMAADDR_OFFSET;
- return phys;
-}
-#else
-
-typedef unsigned long dmaaddr_high_t;
-
-static inline dmaaddr_high_t
-pci_map_single_high(struct pci_dev *hwdev, struct page *page,
- int offset, size_t size, int dir)
-{
- return pci_map_single(hwdev, page_address(page) + offset, size, dir);
-}
-#endif
-
#if defined(USE_64BIT_ADDR)
#define VERSION _VERSION USE_64BIT_ADDR
+#define TRY_DAC 1
#else
#define VERSION _VERSION
+#define TRY_DAC 0
#endif
/* tunables */
@@ -384,13 +350,22 @@
} while(0)
#ifdef USE_64BIT_ADDR
-typedef u64 hw_addr_t;
+#define HW_ADDR_LEN 8
+#define desc_addr_set(desc, addr) \
+ do { \
+ u64 __addr = (addr); \
+ desc[BUFPTR] = cpu_to_le32(__addr); \
+ desc[BUFPTR+1] = cpu_to_le32(__addr >> 32); \
+ } while(0)
+#define desc_addr_get(desc) \
+ (((u64)le32_to_cpu(desc[BUFPTR+1]) << 32) \
+ | le32_to_cpu(desc[BUFPTR]))
#else
-typedef u32 hw_addr_t;
+#define HW_ADDR_LEN 4
+#define desc_addr_set(desc, addr) (desc[BUFPTR] = cpu_to_le32(addr))
+#define desc_addr_get(desc) (le32_to_cpu(desc[BUFPTR]))
#endif
-#define HW_ADDR_LEN (sizeof(hw_addr_t))
-
#define LINK 0
#define BUFPTR (LINK + HW_ADDR_LEN/4)
#define CMDSTS (BUFPTR + HW_ADDR_LEN/4)
@@ -402,6 +377,7 @@
#define CMDSTS_INTR 0x20000000
#define CMDSTS_ERR 0x10000000
#define CMDSTS_OK 0x08000000
+#define CMDSTS_LEN_MASK 0x0000ffff
#define CMDSTS_DEST_MASK 0x01800000
#define CMDSTS_DEST_SELF 0x00800000
@@ -515,7 +491,7 @@
unsigned next_empty;
u32 cmdsts;
u32 *sg;
- hw_addr_t buf;
+ dma_addr_t buf;
next_empty = dev->rx_info.next_empty;
@@ -848,7 +824,7 @@
(cmdsts != CMDSTS_OWN)) {
struct sk_buff *skb;
u32 extsts = le32_to_cpu(desc[EXTSTS]);
- dmaaddr_high_t bufptr = le32_to_cpu(desc[BUFPTR]);
+ dma_addr_t bufptr = desc_addr_get(desc);
dprintk("cmdsts: %08x\n", cmdsts);
dprintk("link: %08x\n", cpu_to_le32(desc[LINK]));
@@ -936,6 +912,8 @@
while ((tx_done_idx != dev->tx_free_idx) &&
!(CMDSTS_OWN & (cmdsts = le32_to_cpu(desc[CMDSTS]))) ) {
struct sk_buff *skb;
+ unsigned len;
+ dma_addr_t addr;
if (cmdsts & CMDSTS_ERR)
dev->stats.tx_errors ++;
@@ -949,13 +927,20 @@
skb = dev->tx_skbs[tx_done_idx];
dev->tx_skbs[tx_done_idx] = NULL;
dprintk("done(%p)\n", skb);
+
+ len = cmdsts & CMDSTS_LEN_MASK;
+ addr = desc_addr_get(desc);
if (skb) {
pci_unmap_single(dev->pci_dev,
- le32_to_cpu(desc[BUFPTR]),
- skb->len,
+ addr,
+ len,
PCI_DMA_TODEVICE);
dev_kfree_skb_irq(skb);
- }
+ } else
+ pci_unmap_page(dev->pci_dev,
+ addr,
+ len,
+ PCI_DMA_TODEVICE);
tx_done_idx = (tx_done_idx + 1) % NR_TX_DESC;
dev->tx_done_idx = tx_done_idx;
@@ -1001,7 +986,7 @@
u32 free_idx, cmdsts, extsts;
int nr_free, nr_frags;
unsigned tx_done_idx;
- dmaaddr_high_t buf;
+ dma_addr_t buf;
unsigned len;
skb_frag_t *frag;
int stopped = 0;
@@ -1075,7 +1060,7 @@
(unsigned long long)buf);
free_idx = (free_idx + 1) % NR_TX_DESC;
desc[LINK] = cpu_to_le32(dev->tx_phy_descs + (free_idx * DESC_SIZE * 4));
- desc[BUFPTR] = cpu_to_le32(buf);
+ desc_addr_set(desc, buf);
desc[EXTSTS] = cpu_to_le32(extsts);
cmdsts = ((nr_frags|residue) ? CMDSTS_MORE : do_intr ? CMDSTS_INTR : 0);
@@ -1092,11 +1077,12 @@
if (!nr_frags)
break;
- buf = pci_map_single_high(dev->pci_dev, frag->page,
- frag->page_offset,
- frag->size, PCI_DMA_TODEVICE);
- dprintk("frag: buf=%08Lx page=%08lx\n",
- (long long)buf, (long)(frag->page - mem_map));
+ buf = pci_map_page(dev->pci_dev, frag->page,
+ frag->page_offset,
+ frag->size, PCI_DMA_TODEVICE);
+ printk("frag: buf=%08Lx page=%08lx offset=%08lx\n",
+ (long long)buf, (long)(frag->page - mem_map),
+ frag->page_offset);
len = frag->size;
frag++;
nr_frags--;
@@ -1427,6 +1413,16 @@
struct ns83820 *dev;
long addr;
int err;
+ int using_dac = 0;
+
+ if (TRY_DAC && !pci_set_dma_mask(pci_dev, 0xffffffffffffffff)) {
+ using_dac = 1;
+ } else if (!pci_set_dma_mask(pci_dev, 0xffffffff)) {
+ using_dac = 0;
+ } else {
+ printk(KERN_WARNING "ns83820.c: pci_set_dma_mask failed!\n");
+ return -ENODEV;
+ }
dev = (struct ns83820 *)alloc_etherdev((sizeof *dev) - (sizeof dev->net_dev));
err = -ENOMEM;
@@ -1536,6 +1532,9 @@
#ifdef USE_64BIT_ADDR
dev->CFG_cache |= CFG_M64ADDR;
#endif
+ if (using_dac)
+ dev->CFG_cache |= CFG_T64ADDR;
+
/* Big endian mode does not seem to do what the docs suggest */
dev->CFG_cache &= ~CFG_BEM;
@@ -1561,7 +1560,7 @@
writel(dev->CFG_cache, dev->base + CFG);
dprintk("CFG: %08x\n", dev->CFG_cache);
-#if 1 /* Huh? This sets the PCI latency register. Should be done via
+#if 0 /* Huh? This sets the PCI latency register. Should be done via
* the PCI layer. FIXME.
*/
if (readl(dev->base + SRR))
@@ -1614,13 +1613,12 @@
/* Yes, we support dumb IP checksum on transmit */
dev->net_dev.features |= NETIF_F_SG;
dev->net_dev.features |= NETIF_F_IP_CSUM;
-#if defined(USE_64BIT_ADDR) || defined(CONFIG_HIGHMEM4G)
- if ((dev->CFG_cache & CFG_T64ADDR)) {
+
+ if (using_dac) {
printk(KERN_INFO "%s: using 64 bit addressing.\n",
dev->net_dev.name);
dev->net_dev.features |= NETIF_F_HIGHDMA;
}
-#endif
printk(KERN_INFO "%s: ns83820 v" VERSION ": DP83820 v%u.%u: %02x:%02x:%02x:%02x:%02x:%02x io=0x%08lx irq=%d f=%s\n",
dev->net_dev.name,
reply other threads:[~2002-06-11 1:53 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20020610215324.D13225@redhat.com \
--to=bcrl@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=marcelo@conectiva.com.br \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.