* [PATCH 0/9] tulip patches from parisc-linux
@ 2006-08-07 20:44 Kyle McMartin
2006-08-07 20:53 ` [PATCH 1/9] [TULIP] Fix PHY init and reset Kyle McMartin
0 siblings, 1 reply; 20+ messages in thread
From: Kyle McMartin @ 2006-08-07 20:44 UTC (permalink / raw)
To: netdev; +Cc: akpm, grundler, val_henson, varenet, jeff
[Val asked that I split this out, instead of just publishing a git tree,
so here goes nothing. I don't think I've ever used git-send-email before,
but hopefully I won't screw up too badly.]
The following patch series brings the mainline tulip driver in synch
with the modifications made in parisc-linux. Most of these patches
have been in parisc-linux cvs for the better part of several years,
so they are quite well tested.
It contains the following changes,
21142.c | 4 +-
de2104x.c | 6 +--
interrupt.c | 4 ++
media.c | 40 +++++++++++++++++++++-
timer.c | 14 ++++++-
tulip.h | 43 ++++++++++++++++++------
tulip_core.c | 102 ++++++++++++++++++++++++++++------------------------------
winbond-840.c | 68 +++++++++++++-------------------------
8 files changed, 164 insertions(+), 117 deletions(-)
Francois Romieu:
[TULIP] Defer tulip_select_media() to process context
Grant Grundler:
[TULIP] Fix PHY init and reset
[TULIP] Print physical address in tulip_init_one
[TULIP] Make tulip_stop_rxtx() failure case slightly more informative
[TULIP] Clean tulip.h so it can be used by winbond-840.c
[TULIP] Flush MMIO writes in reset sequence
[TULIP] Fix IRQ/DMA race
Helge Deller:
[TULIP] Fix section mismatch in de2104x.c
Thibaut Varene:
[TULIP] Make DS21143 printout match lspci output
Cheers!
Kyle M.
^ permalink raw reply [flat|nested] 20+ messages in thread* [PATCH 1/9] [TULIP] Fix PHY init and reset 2006-08-07 20:44 [PATCH 0/9] tulip patches from parisc-linux Kyle McMartin @ 2006-08-07 20:53 ` Kyle McMartin 2006-08-07 20:53 ` [PATCH 2/9] [TULIP] Print physical address in tulip_init_one Kyle McMartin 2006-08-09 5:29 ` [PATCH 1/9] [TULIP] Fix PHY init and reset Jeff Garzik 0 siblings, 2 replies; 20+ messages in thread From: Kyle McMartin @ 2006-08-07 20:53 UTC (permalink / raw) To: netdev; +Cc: grundler, val_henson, akpm From: Grant Grundler <grundler@parisc-linux.org> A whole slew of fixes for tulip_select_media for: - Flush posted MMIO writes as per PCI spec - Polling the reset bit (bit 15) is required to determine when the "init" sequence can be sent. This fixes tulip on HP PA-RISC systems, which use DP83840A and LXT971D PHYs. Tested for several years on a variety of HP PA-RISC systems. [Initial work done by Grant Grundler, DS21142 support added by Thibaut Varene.] Signed-off-by: Grant Grundler <grundler@parisc-linux.org> Signed-off-by: Thibaut Varene <varenet@parisc-linux.org> Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> --- drivers/net/tulip/media.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 files changed, 37 insertions(+), 3 deletions(-) diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c index e9bc2a9..5093d87 100644 --- a/drivers/net/tulip/media.c +++ b/drivers/net/tulip/media.c @@ -44,8 +44,10 @@ static const unsigned char comet_miireg2 /* MII transceiver control section. Read and write the MII registers using software-generated serial - MDIO protocol. See the MII specifications or DP83840A data sheet - for details. */ + MDIO protocol. + See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management functions") + or DP83840A data sheet for more details. + */ int tulip_mdio_read(struct net_device *dev, int phy_id, int location) { @@ -261,24 +263,56 @@ void tulip_select_media(struct net_devic u16 *reset_sequence = &((u16*)(p+3))[init_length]; int reset_length = p[2 + init_length*2]; misc_info = reset_sequence + reset_length; - if (startup) + if (startup) { + int timeout = 10; for (i = 0; i < reset_length; i++) iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); + + /* flush posted writes */ + ioread32(ioaddr + CSR15); + + /* Sect 3.10.3 in DP83840A.pdf (p39) */ + udelay(500); + + /* Section 4.2 in DP83840A.pdf (p43) */ + /* and IEEE 802.3 "22.2.4.1.1 Reset" */ + while (timeout-- && + (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET)) + udelay(100); + } for (i = 0; i < init_length; i++) iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15); + + ioread32(ioaddr + CSR15); /* flush posted writes */ } else { u8 *init_sequence = p + 2; u8 *reset_sequence = p + 3 + init_length; int reset_length = p[2 + init_length]; misc_info = (u16*)(reset_sequence + reset_length); if (startup) { + int timeout = 10; iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12); for (i = 0; i < reset_length; i++) iowrite32(reset_sequence[i], ioaddr + CSR12); + + /* flush posted writes */ + ioread32(ioaddr + CSR12); + + /* Sect 3.10.3 in DP83840A.pdf (p39) */ + udelay(500); + + /* Section 4.2 in DP83840A.pdf (p43) */ + /* and IEEE 802.3 "22.2.4.1.1 Reset" */ + while (timeout-- && + (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET)) + udelay(100); } for (i = 0; i < init_length; i++) iowrite32(init_sequence[i], ioaddr + CSR12); + + ioread32(ioaddr + CSR12); /* flush posted writes */ } + tmp_info = get_u16(&misc_info[1]); if (tmp_info) tp->advertising[phy_num] = tmp_info | 1; -- 1.4.1.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 2/9] [TULIP] Print physical address in tulip_init_one 2006-08-07 20:53 ` [PATCH 1/9] [TULIP] Fix PHY init and reset Kyle McMartin @ 2006-08-07 20:53 ` Kyle McMartin 2006-08-07 20:53 ` [PATCH 3/9] [TULIP] Make tulip_stop_rxtx() failure case slightly more informative Kyle McMartin 2006-08-09 5:29 ` [PATCH 1/9] [TULIP] Fix PHY init and reset Jeff Garzik 1 sibling, 1 reply; 20+ messages in thread From: Kyle McMartin @ 2006-08-07 20:53 UTC (permalink / raw) To: netdev; +Cc: grundler, val_henson, akpm From: Grant Grundler <grundler@parisc-linux.org> As the cookie returned by pci_iomap() is fairly useless... Signed-off-by: Grant Grundler <grundler@parisc-linux.org> Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> --- drivers/net/tulip/tulip_core.c | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 7351831..bf93679 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -1644,8 +1644,14 @@ #endif if (register_netdev(dev)) goto err_out_free_ring; - printk(KERN_INFO "%s: %s rev %d at %p,", - dev->name, chip_name, chip_rev, ioaddr); + printk(KERN_INFO "%s: %s rev %d at " +#ifdef CONFIG_TULIP_MMIO + "MMIO" +#else + "Port" +#endif + " 0x%lx,", dev->name, chip_name, chip_rev, + pci_resource_start(pdev, TULIP_BAR)); pci_set_drvdata(pdev, dev); if (eeprom_missing) -- 1.4.1.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 3/9] [TULIP] Make tulip_stop_rxtx() failure case slightly more informative 2006-08-07 20:53 ` [PATCH 2/9] [TULIP] Print physical address in tulip_init_one Kyle McMartin @ 2006-08-07 20:53 ` Kyle McMartin 2006-08-07 20:53 ` [PATCH 4/9] [TULIP] Clean tulip.h so it can be used by winbond-840.c Kyle McMartin 2006-08-09 5:30 ` [PATCH 3/9] [TULIP] Make tulip_stop_rxtx() failure case slightly more informative Jeff Garzik 0 siblings, 2 replies; 20+ messages in thread From: Kyle McMartin @ 2006-08-07 20:53 UTC (permalink / raw) To: netdev; +Cc: grundler, val_henson, akpm From: Grant Grundler <grundler@parisc-linux.org> Signed-off-by: Grant Grundler <grundler@parisc-linux.org> Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> --- drivers/net/tulip/tulip.h | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index 3bcfbf3..d79c7ae 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h @@ -473,8 +473,11 @@ static inline void tulip_stop_rxtx(struc udelay(10); if (!i) - printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed\n", - pci_name(tp->pdev)); + printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed" + " (CSR5 0x%x CSR6 0x%x)\n", + pci_name(tp->pdev), + ioread32(ioaddr + CSR5), + ioread32(ioaddr + CSR6)); } } -- 1.4.1.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 4/9] [TULIP] Clean tulip.h so it can be used by winbond-840.c 2006-08-07 20:53 ` [PATCH 3/9] [TULIP] Make tulip_stop_rxtx() failure case slightly more informative Kyle McMartin @ 2006-08-07 20:53 ` Kyle McMartin 2006-08-07 20:53 ` [PATCH 5/9] [TULIP] Flush MMIO writes in reset sequence Kyle McMartin 2006-08-09 5:33 ` [PATCH 4/9] [TULIP] Clean tulip.h so it can be used by winbond-840.c Jeff Garzik 2006-08-09 5:30 ` [PATCH 3/9] [TULIP] Make tulip_stop_rxtx() failure case slightly more informative Jeff Garzik 1 sibling, 2 replies; 20+ messages in thread From: Kyle McMartin @ 2006-08-07 20:53 UTC (permalink / raw) To: netdev; +Cc: grundler, val_henson, akpm From: Grant Grundler <grundler@parisc-linux.org> Include "tulip.h" in winbond-840.c and clean up lots of redundant definitions. Signed-off-by: Grant Grundler <grundler@parisc-linux.org> Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> --- drivers/net/tulip/tulip.h | 17 ++++++---- drivers/net/tulip/tulip_core.c | 7 +--- drivers/net/tulip/winbond-840.c | 68 ++++++++++++++------------------------- 3 files changed, 37 insertions(+), 55 deletions(-) diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index d79c7ae..951af5e 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h @@ -30,11 +30,10 @@ #include <asm/irq.h> /* undefine, or define to various debugging levels (>4 == obscene levels) */ #define TULIP_DEBUG 1 -/* undefine USE_IO_OPS for MMIO, define for PIO */ #ifdef CONFIG_TULIP_MMIO -# undef USE_IO_OPS +#define TULIP_BAR 1 /* CBMA */ #else -# define USE_IO_OPS 1 +#define TULIP_BAR 0 /* CBIO */ #endif @@ -142,6 +141,7 @@ enum status_bits { RxNoBuf = 0x80, RxIntr = 0x40, TxFIFOUnderflow = 0x20, + RxErrIntr = 0x10, TxJabber = 0x08, TxNoBuf = 0x04, TxDied = 0x02, @@ -192,9 +192,14 @@ struct tulip_tx_desc { enum desc_status_bits { - DescOwned = 0x80000000, - RxDescFatalErr = 0x8000, - RxWholePkt = 0x0300, + DescOwned = 0x80000000, + DescWholePkt = 0x60000000, + DescEndPkt = 0x40000000, + DescStartPkt = 0x20000000, + DescEndRing = 0x02000000, + DescUseLink = 0x01000000, + RxDescFatalErr = 0x008000, + RxWholePkt = 0x00000300, }; diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index bf93679..6b54572 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -1361,11 +1361,8 @@ #endif if (pci_request_regions (pdev, "tulip")) goto err_out_free_netdev; -#ifndef USE_IO_OPS - ioaddr = pci_iomap(pdev, 1, tulip_tbl[chip_idx].io_size); -#else - ioaddr = pci_iomap(pdev, 0, tulip_tbl[chip_idx].io_size); -#endif + ioaddr = pci_iomap(pdev, TULIP_BAR, tulip_tbl[chip_idx].io_size); + if (!ioaddr) goto err_out_free_res; diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 7f41481..fa3a7b3 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -90,10 +90,8 @@ static int full_duplex[MAX_UNITS] = {-1, Making the Tx ring too large decreases the effectiveness of channel bonding and packet priority. There are no ill effects from too-large receive rings. */ -#define TX_RING_SIZE 16 #define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */ #define TX_QUEUE_LEN_RESTART 5 -#define RX_RING_SIZE 32 #define TX_BUFLIMIT (1024-128) @@ -137,6 +135,8 @@ #include <asm/processor.h> /* Processor #include <asm/io.h> #include <asm/irq.h> +#include "tulip.h" + /* These identify the driver base version and may not be removed. */ static char version[] __devinitdata = KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) " DRV_RELDATE " Donald Becker <becker@scyld.com>\n" @@ -242,8 +242,8 @@ static const struct pci_id_info pci_id_t }; /* This driver was written to use PCI memory space, however some x86 systems - work only with I/O space accesses. Pass -DUSE_IO_OPS to use PCI I/O space - accesses instead of memory space. */ + work only with I/O space accesses. See CONFIG_TULIP_MMIO in .config +*/ /* Offsets to the Command and Status Registers, "CSRs". While similar to the Tulip, these registers are longword aligned. @@ -261,21 +261,11 @@ enum w840_offsets { CurTxDescAddr=0x4C, CurTxBufAddr=0x50, }; -/* Bits in the interrupt status/enable registers. */ -/* The bits in the Intr Status/Enable registers, mostly interrupt sources. */ -enum intr_status_bits { - NormalIntr=0x10000, AbnormalIntr=0x8000, - IntrPCIErr=0x2000, TimerInt=0x800, - IntrRxDied=0x100, RxNoBuf=0x80, IntrRxDone=0x40, - TxFIFOUnderflow=0x20, RxErrIntr=0x10, - TxIdle=0x04, IntrTxStopped=0x02, IntrTxDone=0x01, -}; - /* Bits in the NetworkConfig register. */ enum rx_mode_bits { - AcceptErr=0x80, AcceptRunt=0x40, - AcceptBroadcast=0x20, AcceptMulticast=0x10, - AcceptAllPhys=0x08, AcceptMyPhys=0x02, + AcceptErr=0x80, + RxAcceptBroadcast=0x20, AcceptMulticast=0x10, + RxAcceptAllPhys=0x08, AcceptMyPhys=0x02, }; enum mii_reg_bits { @@ -297,13 +287,6 @@ struct w840_tx_desc { u32 buffer1, buffer2; }; -/* Bits in network_desc.status */ -enum desc_status_bits { - DescOwn=0x80000000, DescEndRing=0x02000000, DescUseLink=0x01000000, - DescWholePkt=0x60000000, DescStartPkt=0x20000000, DescEndPkt=0x40000000, - DescIntr=0x80000000, -}; - #define MII_CNT 1 /* winbond only supports one MII */ struct netdev_private { struct w840_rx_desc *rx_ring; @@ -371,7 +354,6 @@ static int __devinit w840_probe1 (struct int irq; int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0; void __iomem *ioaddr; - int bar = 1; i = pci_enable_device(pdev); if (i) return i; @@ -393,10 +375,8 @@ static int __devinit w840_probe1 (struct if (pci_request_regions(pdev, DRV_NAME)) goto err_out_netdev; -#ifdef USE_IO_OPS - bar = 0; -#endif - ioaddr = pci_iomap(pdev, bar, netdev_res_size); + + ioaddr = pci_iomap(pdev, TULIP_BAR, netdev_res_size); if (!ioaddr) goto err_out_free_res; @@ -838,7 +818,7 @@ static void init_rxtx_rings(struct net_d np->rx_buf_sz,PCI_DMA_FROMDEVICE); np->rx_ring[i].buffer1 = np->rx_addr[i]; - np->rx_ring[i].status = DescOwn; + np->rx_ring[i].status = DescOwned; } np->cur_rx = 0; @@ -923,7 +903,7 @@ #if defined (__i386__) && !defined(MODUL } #elif defined(__powerpc__) || defined(__i386__) || defined(__alpha__) || defined(__ia64__) || defined(__x86_64__) i |= 0xE000; -#elif defined(__sparc__) +#elif defined(__sparc__) || defined (CONFIG_PARISC) i |= 0x4800; #else #warning Processor architecture undefined @@ -1043,11 +1023,11 @@ static int start_tx(struct sk_buff *skb, /* Now acquire the irq spinlock. * The difficult race is the the ordering between - * increasing np->cur_tx and setting DescOwn: + * increasing np->cur_tx and setting DescOwned: * - if np->cur_tx is increased first the interrupt * handler could consider the packet as transmitted - * since DescOwn is cleared. - * - If DescOwn is set first the NIC could report the + * since DescOwned is cleared. + * - If DescOwned is set first the NIC could report the * packet as sent, but the interrupt handler would ignore it * since the np->cur_tx was not yet increased. */ @@ -1055,7 +1035,7 @@ static int start_tx(struct sk_buff *skb, np->cur_tx++; wmb(); /* flush length, buffer1, buffer2 */ - np->tx_ring[entry].status = DescOwn; + np->tx_ring[entry].status = DescOwned; wmb(); /* flush status and kick the hardware */ iowrite32(0, np->base_addr + TxStartDemand); np->tx_q_bytes += skb->len; @@ -1155,12 +1135,12 @@ static irqreturn_t intr_handler(int irq, handled = 1; - if (intr_status & (IntrRxDone | RxNoBuf)) + if (intr_status & (RxIntr | RxNoBuf)) netdev_rx(dev); if (intr_status & RxNoBuf) iowrite32(0, ioaddr + RxStartDemand); - if (intr_status & (TxIdle | IntrTxDone) && + if (intr_status & (TxNoBuf | TxIntr) && np->cur_tx != np->dirty_tx) { spin_lock(&np->lock); netdev_tx_done(dev); @@ -1168,8 +1148,8 @@ static irqreturn_t intr_handler(int irq, } /* Abnormal error summary/uncommon events handlers. */ - if (intr_status & (AbnormalIntr | TxFIFOUnderflow | IntrPCIErr | - TimerInt | IntrTxStopped)) + if (intr_status & (AbnormalIntr | TxFIFOUnderflow | SytemError | + TimerInt | TxDied)) netdev_error(dev, intr_status); if (--work_limit < 0) { @@ -1305,7 +1285,7 @@ #endif np->rx_ring[entry].buffer1 = np->rx_addr[entry]; } wmb(); - np->rx_ring[entry].status = DescOwn; + np->rx_ring[entry].status = DescOwned; } return 0; @@ -1342,7 +1322,7 @@ #endif dev->name, new); update_csr6(dev, new); } - if (intr_status & IntrRxDied) { /* Missed a Rx frame. */ + if (intr_status & RxDied) { /* Missed a Rx frame. */ np->stats.rx_errors++; } if (intr_status & TimerInt) { @@ -1381,13 +1361,13 @@ static u32 __set_rx_mode(struct net_devi /* Unconditionally log net taps. */ printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); memset(mc_filter, 0xff, sizeof(mc_filter)); - rx_mode = AcceptBroadcast | AcceptMulticast | AcceptAllPhys + rx_mode = RxAcceptBroadcast | AcceptMulticast | RxAcceptAllPhys | AcceptMyPhys; } else if ((dev->mc_count > multicast_filter_limit) || (dev->flags & IFF_ALLMULTI)) { /* Too many to match, or accept all multicasts. */ memset(mc_filter, 0xff, sizeof(mc_filter)); - rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; + rx_mode = RxAcceptBroadcast | AcceptMulticast | AcceptMyPhys; } else { struct dev_mc_list *mclist; int i; @@ -1398,7 +1378,7 @@ static u32 __set_rx_mode(struct net_devi filterbit &= 0x3f; mc_filter[filterbit >> 5] |= 1 << (filterbit & 31); } - rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; + rx_mode = RxAcceptBroadcast | AcceptMulticast | AcceptMyPhys; } iowrite32(mc_filter[0], ioaddr + MulticastFilter0); iowrite32(mc_filter[1], ioaddr + MulticastFilter1); -- 1.4.1.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 5/9] [TULIP] Flush MMIO writes in reset sequence 2006-08-07 20:53 ` [PATCH 4/9] [TULIP] Clean tulip.h so it can be used by winbond-840.c Kyle McMartin @ 2006-08-07 20:53 ` Kyle McMartin 2006-08-07 20:53 ` [PATCH 6/9] [TULIP] Fix IRQ/DMA race Kyle McMartin 2006-08-09 5:33 ` [PATCH 5/9] [TULIP] Flush MMIO writes in reset sequence Jeff Garzik 2006-08-09 5:33 ` [PATCH 4/9] [TULIP] Clean tulip.h so it can be used by winbond-840.c Jeff Garzik 1 sibling, 2 replies; 20+ messages in thread From: Kyle McMartin @ 2006-08-07 20:53 UTC (permalink / raw) To: netdev; +Cc: grundler, val_henson, akpm From: Grant Grundler <grundler@parisc-linux.org> The obvious safe registers to read is one from PCI config space. Signed-off-by: Grant Grundler <grundler@parisc-linux.org> Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> --- drivers/net/tulip/tulip_core.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 6b54572..81905f4 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -295,12 +295,14 @@ static void tulip_up(struct net_device * /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */ iowrite32(0x00000001, ioaddr + CSR0); + pci_read_config_dword(tp->pdev, PCI_COMMAND, &i); /* flush write */ udelay(100); /* Deassert reset. Wait the specified 50 PCI cycles after a reset by initializing Tx and Rx queues and the address filter list. */ iowrite32(tp->csr0, ioaddr + CSR0); + pci_read_config_dword(tp->pdev, PCI_COMMAND, &i); /* flush write */ udelay(100); if (tulip_debug > 1) -- 1.4.1.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 6/9] [TULIP] Fix IRQ/DMA race 2006-08-07 20:53 ` [PATCH 5/9] [TULIP] Flush MMIO writes in reset sequence Kyle McMartin @ 2006-08-07 20:53 ` Kyle McMartin 2006-08-07 20:53 ` [PATCH 7/9] [TULIP] Defer tulip_select_media() to process context Kyle McMartin 2006-08-09 5:35 ` [PATCH 6/9] [TULIP] Fix IRQ/DMA race Jeff Garzik 2006-08-09 5:33 ` [PATCH 5/9] [TULIP] Flush MMIO writes in reset sequence Jeff Garzik 1 sibling, 2 replies; 20+ messages in thread From: Kyle McMartin @ 2006-08-07 20:53 UTC (permalink / raw) To: netdev; +Cc: grundler, val_henson, akpm From: Grant Grundler <grundler@parisc-linux.org> IRQs are racing with tulip_down(). DMA can be restarted by tulip_interrupt() _after_ we call tulip_stop_rxtx() and the DMA buffers are unmapped. The result is an MCA (hard crash on ia64) because of an IO TLB miss. Signed-off-by: Grant Grundler <grundler@parisc-linux.org> Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> --- drivers/net/tulip/interrupt.c | 4 ++++ drivers/net/tulip/tulip_core.c | 17 +++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c index 99ccf2e..19faa0e 100644 --- a/drivers/net/tulip/interrupt.c +++ b/drivers/net/tulip/interrupt.c @@ -87,6 +87,10 @@ int tulip_refill_rx(struct net_device *d } tp->rx_ring[entry].status = cpu_to_le32(DescOwned); } + +/* FIXME: restarting DMA breaks tulip_down() code path. + tulip_down() will unmap the RX and TX descriptors. + */ if(tp->chip_id == LC82C168) { if(((ioread32(tp->base_addr + CSR5)>>17)&0x07) == 4) { /* Rx stopped due to out of buffers, diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 81905f4..363e5f6 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -742,21 +742,20 @@ #endif /* Disable interrupts by clearing the interrupt mask. */ iowrite32 (0x00000000, ioaddr + CSR7); + ioread32 (ioaddr + CSR7); /* flush posted write */ - /* Stop the Tx and Rx processes. */ - tulip_stop_rxtx(tp); + spin_unlock_irqrestore (&tp->lock, flags); - /* prepare receive buffers */ - tulip_refill_rx(dev); + free_irq (dev->irq, dev); /* no more races after this */ + tulip_stop_rxtx(tp); /* Stop DMA */ - /* release any unconsumed transmit buffers */ - tulip_clean_tx_ring(tp); + /* Put driver back into the state we start with */ + tulip_refill_rx(dev); /* prepare RX buffers */ + tulip_clean_tx_ring(tp); /* clean up unsent TX buffers */ if (ioread32 (ioaddr + CSR6) != 0xffffffff) tp->stats.rx_missed_errors += ioread32 (ioaddr + CSR8) & 0xffff; - spin_unlock_irqrestore (&tp->lock, flags); - init_timer(&tp->timer); tp->timer.data = (unsigned long)dev; tp->timer.function = tulip_tbl[tp->chip_id].media_timer; @@ -782,7 +781,6 @@ static int tulip_close (struct net_devic printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", dev->name, ioread32 (ioaddr + CSR5)); - free_irq (dev->irq, dev); /* Free all the skbuffs in the Rx queue. */ for (i = 0; i < RX_RING_SIZE; i++) { @@ -1752,7 +1750,6 @@ static int tulip_suspend (struct pci_dev tulip_down(dev); netif_device_detach(dev); - free_irq(dev->irq, dev); pci_save_state(pdev); pci_disable_device(pdev); -- 1.4.1.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 7/9] [TULIP] Defer tulip_select_media() to process context 2006-08-07 20:53 ` [PATCH 6/9] [TULIP] Fix IRQ/DMA race Kyle McMartin @ 2006-08-07 20:53 ` Kyle McMartin 2006-08-07 20:53 ` [PATCH 8/9] [TULIP] Make DS21143 printout match lspci output Kyle McMartin 2006-08-09 5:35 ` [PATCH 6/9] [TULIP] Fix IRQ/DMA race Jeff Garzik 1 sibling, 1 reply; 20+ messages in thread From: Kyle McMartin @ 2006-08-07 20:53 UTC (permalink / raw) To: netdev; +Cc: grundler, val_henson, akpm, Francois Romieu From: Francois Romieu <romieu@fr.zoreil.com> Move tulip_select_media() processing to a workqueue, instead of delaying in interrupt context. [Edit by Kyle to use kevent thread, instead of creating its own workqueue.] Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> --- drivers/net/tulip/21142.c | 4 +-- drivers/net/tulip/timer.c | 14 ++++++++- drivers/net/tulip/tulip.h | 19 ++++++++++-- drivers/net/tulip/tulip_core.c | 64 +++++++++++++++++++--------------------- 4 files changed, 60 insertions(+), 41 deletions(-) diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c index 683f14b..ffba0c1 100644 --- a/drivers/net/tulip/21142.c +++ b/drivers/net/tulip/21142.c @@ -26,9 +26,9 @@ static u16 t21142_csr15[] = { 0x0008, 0x /* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list of available transceivers. */ -void t21142_timer(unsigned long data) +void t21142_media_task(void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct tulip_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->base_addr; int csr12 = ioread32(ioaddr + CSR12); diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c index e058a9f..272ef62 100644 --- a/drivers/net/tulip/timer.c +++ b/drivers/net/tulip/timer.c @@ -18,13 +18,14 @@ #include <linux/pci.h> #include "tulip.h" -void tulip_timer(unsigned long data) +void tulip_media_task(void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct tulip_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->base_addr; u32 csr12 = ioread32(ioaddr + CSR12); int next_tick = 2*HZ; + unsigned long flags; if (tulip_debug > 2) { printk(KERN_DEBUG "%s: Media selection tick, %s, status %8.8x mode" @@ -126,6 +127,15 @@ void tulip_timer(unsigned long data) } break; } + + + spin_lock_irqsave(&tp->lock, flags); + if (tp->timeout_recovery) { + tulip_tx_timeout_complete(tp, ioaddr); + tp->timeout_recovery = 0; + } + spin_unlock_irqrestore(&tp->lock, flags); + /* mod_timer synchronizes us with potential add_timer calls * from interrupts. */ diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index 951af5e..408fe46 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h @@ -43,7 +43,8 @@ struct tulip_chip_table { int io_size; int valid_intrs; /* CSR7 interrupt enable settings */ int flags; - void (*media_timer) (unsigned long data); + void (*media_timer) (unsigned long); + void (*media_task) (void *); }; @@ -371,6 +372,7 @@ #endif unsigned int medialock:1; /* Don't sense media type. */ unsigned int mediasense:1; /* Media sensing in progress. */ unsigned int nway:1, nwayset:1; /* 21143 internal NWay. */ + unsigned int timeout_recovery:1; unsigned int csr0; /* CSR0 setting. */ unsigned int csr6; /* Current CSR6 control settings. */ unsigned char eeprom[EEPROM_SIZE]; /* Serial EEPROM contents. */ @@ -389,6 +391,7 @@ #endif void __iomem *base_addr; int csr12_shadow; int pad0; /* Used for 8-byte alignment */ + struct work_struct media_work; }; @@ -403,7 +406,7 @@ struct eeprom_fixup { /* 21142.c */ extern u16 t21142_csr14[]; -void t21142_timer(unsigned long data); +void t21142_media_task(void *data); void t21142_start_nway(struct net_device *dev); void t21142_lnk_change(struct net_device *dev, int csr5); @@ -441,7 +444,7 @@ void pnic_lnk_change(struct net_device * void pnic_timer(unsigned long data); /* timer.c */ -void tulip_timer(unsigned long data); +void tulip_media_task(void *data); void mxic_timer(unsigned long data); void comet_timer(unsigned long data); @@ -493,4 +496,14 @@ static inline void tulip_restart_rxtx(st tulip_start_rxtx(tp); } +static inline void tulip_tx_timeout_complete(struct tulip_private *tp, void __iomem *ioaddr) +{ + /* Stop and restart the chip's Tx processes. */ + tulip_restart_rxtx(tp); + /* Trigger an immediate transmit demand. */ + iowrite32(0, ioaddr + CSR1); + + tp->stats.tx_errors++; +} + #endif /* __NET_TULIP_H__ */ diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 363e5f6..bdb6698 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -130,7 +130,14 @@ #else int tulip_debug = 1; #endif +static void tulip_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct tulip_private *tp = netdev_priv(dev); + if (netif_running(dev)) + schedule_work(&tp->media_work); +} /* * This table use during operation for capabilities and media timer. @@ -144,59 +151,60 @@ struct tulip_chip_table tulip_tbl[] = { /* DC21140 */ { "Digital DS21140 Tulip", 128, 0x0001ebef, - HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer }, + HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer, + tulip_media_task }, /* DC21142, DC21143 */ { "Digital DS21143 Tulip", 128, 0x0801fbff, HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY - | HAS_INTR_MITIGATION | HAS_PCI_MWI, t21142_timer }, + | HAS_INTR_MITIGATION | HAS_PCI_MWI, tulip_timer, t21142_media_task }, /* LC82C168 */ { "Lite-On 82c168 PNIC", 256, 0x0001fbef, - HAS_MII | HAS_PNICNWAY, pnic_timer }, + HAS_MII | HAS_PNICNWAY, pnic_timer, }, /* MX98713 */ { "Macronix 98713 PMAC", 128, 0x0001ebef, - HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer }, + HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer, }, /* MX98715 */ { "Macronix 98715 PMAC", 256, 0x0001ebef, - HAS_MEDIA_TABLE, mxic_timer }, + HAS_MEDIA_TABLE, mxic_timer, }, /* MX98725 */ { "Macronix 98725 PMAC", 256, 0x0001ebef, - HAS_MEDIA_TABLE, mxic_timer }, + HAS_MEDIA_TABLE, mxic_timer, }, /* AX88140 */ { "ASIX AX88140", 128, 0x0001fbff, HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY - | IS_ASIX, tulip_timer }, + | IS_ASIX, tulip_timer, tulip_media_task }, /* PNIC2 */ { "Lite-On PNIC-II", 256, 0x0801fbff, - HAS_MII | HAS_NWAY | HAS_8023X | HAS_PCI_MWI, pnic2_timer }, + HAS_MII | HAS_NWAY | HAS_8023X | HAS_PCI_MWI, pnic2_timer, }, /* COMET */ { "ADMtek Comet", 256, 0x0001abef, - HAS_MII | MC_HASH_ONLY | COMET_MAC_ADDR, comet_timer }, + HAS_MII | MC_HASH_ONLY | COMET_MAC_ADDR, comet_timer, }, /* COMPEX9881 */ { "Compex 9881 PMAC", 128, 0x0001ebef, - HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer }, + HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer, }, /* I21145 */ { "Intel DS21145 Tulip", 128, 0x0801fbff, HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI - | HAS_NWAY | HAS_PCI_MWI, t21142_timer }, + | HAS_NWAY | HAS_PCI_MWI, tulip_timer, tulip_media_task }, /* DM910X */ { "Davicom DM9102/DM9102A", 128, 0x0001ebef, HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI, - tulip_timer }, + tulip_timer, tulip_media_task }, /* RS7112 */ { "Conexant LANfinity", 256, 0x0001ebef, - HAS_MII | HAS_ACPI, tulip_timer }, + HAS_MII | HAS_ACPI, tulip_timer, tulip_media_task }, }; @@ -524,20 +532,9 @@ static void tulip_tx_timeout(struct net_ "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n", dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12), ioread32(ioaddr + CSR13), ioread32(ioaddr + CSR14), ioread32(ioaddr + CSR15)); - if ( ! tp->medialock && tp->mtable) { - do - --tp->cur_index; - while (tp->cur_index >= 0 - && (tulip_media_cap[tp->mtable->mleaf[tp->cur_index].media] - & MediaIsFD)); - if (--tp->cur_index < 0) { - /* We start again, but should instead look for default. */ - tp->cur_index = tp->mtable->leafcount - 1; - } - tulip_select_media(dev, 0); - printk(KERN_WARNING "%s: transmit timed out, switching to %s " - "media.\n", dev->name, medianame[dev->if_port]); - } + tp->timeout_recovery = 1; + schedule_work(&tp->media_work); + goto out_unlock; } else if (tp->chip_id == PNIC2) { printk(KERN_WARNING "%s: PNIC2 transmit timed out, status %8.8x, " "CSR6/7 %8.8x / %8.8x CSR12 %8.8x, resetting...\n", @@ -577,14 +574,9 @@ #if defined(way_too_many_messages) } #endif - /* Stop and restart the chip's Tx processes . */ - - tulip_restart_rxtx(tp); - /* Trigger an immediate transmit demand. */ - iowrite32(0, ioaddr + CSR1); - - tp->stats.tx_errors++; + tulip_tx_timeout_complete(tp, ioaddr); +out_unlock: spin_unlock_irqrestore (&tp->lock, flags); dev->trans_start = jiffies; netif_wake_queue (dev); @@ -734,6 +726,8 @@ static void tulip_down (struct net_devic void __iomem *ioaddr = tp->base_addr; unsigned long flags; + flush_scheduled_work(); + del_timer_sync (&tp->timer); #ifdef CONFIG_TULIP_NAPI del_timer_sync (&tp->oom_timer); @@ -1395,6 +1389,8 @@ #endif tp->timer.data = (unsigned long)dev; tp->timer.function = tulip_tbl[tp->chip_id].media_timer; + INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task, dev); + dev->base_addr = (unsigned long)ioaddr; #ifdef CONFIG_TULIP_MWI -- 1.4.1.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 8/9] [TULIP] Make DS21143 printout match lspci output 2006-08-07 20:53 ` [PATCH 7/9] [TULIP] Defer tulip_select_media() to process context Kyle McMartin @ 2006-08-07 20:53 ` Kyle McMartin 2006-08-07 20:53 ` [PATCH 9/9] [TULIP] Fix section mismatch in de2104x.c Kyle McMartin 2006-08-09 5:36 ` [PATCH 8/9] [TULIP] Make DS21143 printout match lspci output Jeff Garzik 0 siblings, 2 replies; 20+ messages in thread From: Kyle McMartin @ 2006-08-07 20:53 UTC (permalink / raw) To: netdev; +Cc: grundler, val_henson, akpm, Thibaut Varene From: Thibaut Varene <varenet@parisc-linux.org> Signed-off-by: Thibaut Varene <varenet@parisc-linux.org> Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> --- drivers/net/tulip/tulip_core.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index bdb6698..21eaeb2 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -155,7 +155,7 @@ struct tulip_chip_table tulip_tbl[] = { tulip_media_task }, /* DC21142, DC21143 */ - { "Digital DS21143 Tulip", 128, 0x0801fbff, + { "Digital DS21142/43 Tulip", 128, 0x0801fbff, HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY | HAS_INTR_MITIGATION | HAS_PCI_MWI, tulip_timer, t21142_media_task }, -- 1.4.1.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 9/9] [TULIP] Fix section mismatch in de2104x.c 2006-08-07 20:53 ` [PATCH 8/9] [TULIP] Make DS21143 printout match lspci output Kyle McMartin @ 2006-08-07 20:53 ` Kyle McMartin 2006-08-09 5:37 ` Jeff Garzik 2006-08-09 5:36 ` [PATCH 8/9] [TULIP] Make DS21143 printout match lspci output Jeff Garzik 1 sibling, 1 reply; 20+ messages in thread From: Kyle McMartin @ 2006-08-07 20:53 UTC (permalink / raw) To: netdev; +Cc: grundler, val_henson, akpm, Helge Deller From: Helge Deller <deller@parisc-linux.org> WARNING: drivers/net/tulip/de2104x.o - Section mismatch: reference to .init.text:de_init_one from .data.rel.local after 'de_driver' (at offset 0x20) WARNING: drivers/net/tulip/de2104x.o - Section mismatch: reference to .exit.text:de_remove_one from .data.rel.local after 'de_driver' (at offset 0x28) Signed-off-by: Helge Deller <deller@parisc-linux.org> Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> --- drivers/net/tulip/de2104x.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index d05c5aa..150a05a 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -1730,7 +1730,7 @@ static void __init de21040_get_media_inf } /* Note: this routine returns extra data bits for size detection. */ -static unsigned __init tulip_read_eeprom(void __iomem *regs, int location, int addr_len) +static unsigned __devinit tulip_read_eeprom(void __iomem *regs, int location, int addr_len) { int i; unsigned retval = 0; @@ -1926,7 +1926,7 @@ bad_srom: goto fill_defaults; } -static int __init de_init_one (struct pci_dev *pdev, +static int __devinit de_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *dev; @@ -2082,7 +2082,7 @@ err_out_free: return rc; } -static void __exit de_remove_one (struct pci_dev *pdev) +static void __devexit de_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct de_private *de = dev->priv; -- 1.4.1.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 9/9] [TULIP] Fix section mismatch in de2104x.c 2006-08-07 20:53 ` [PATCH 9/9] [TULIP] Fix section mismatch in de2104x.c Kyle McMartin @ 2006-08-09 5:37 ` Jeff Garzik 0 siblings, 0 replies; 20+ messages in thread From: Jeff Garzik @ 2006-08-09 5:37 UTC (permalink / raw) To: Kyle McMartin; +Cc: netdev, grundler, val_henson, akpm, Helge Deller Kyle McMartin wrote: > From: Helge Deller <deller@parisc-linux.org> > > WARNING: drivers/net/tulip/de2104x.o - Section mismatch: reference to .init.text:de_init_one from .data.rel.local after 'de_driver' (at offset 0x20) > WARNING: drivers/net/tulip/de2104x.o - Section mismatch: reference to .exit.text:de_remove_one from .data.rel.local after 'de_driver' (at offset 0x28) > > Signed-off-by: Helge Deller <deller@parisc-linux.org> > Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> Look deeper into the problem... Use of __init and __exit was intentional, as this card is never used in a hotplug situation AFAIK ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 8/9] [TULIP] Make DS21143 printout match lspci output 2006-08-07 20:53 ` [PATCH 8/9] [TULIP] Make DS21143 printout match lspci output Kyle McMartin 2006-08-07 20:53 ` [PATCH 9/9] [TULIP] Fix section mismatch in de2104x.c Kyle McMartin @ 2006-08-09 5:36 ` Jeff Garzik 1 sibling, 0 replies; 20+ messages in thread From: Jeff Garzik @ 2006-08-09 5:36 UTC (permalink / raw) To: Kyle McMartin; +Cc: netdev, grundler, val_henson, akpm, Thibaut Varene Kyle McMartin wrote: > From: Thibaut Varene <varenet@parisc-linux.org> > > Signed-off-by: Thibaut Varene <varenet@parisc-linux.org> > Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> > --- > drivers/net/tulip/tulip_core.c | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > > diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c > index bdb6698..21eaeb2 100644 > --- a/drivers/net/tulip/tulip_core.c > +++ b/drivers/net/tulip/tulip_core.c > @@ -155,7 +155,7 @@ struct tulip_chip_table tulip_tbl[] = { > tulip_media_task }, > > /* DC21142, DC21143 */ > - { "Digital DS21143 Tulip", 128, 0x0801fbff, > + { "Digital DS21142/43 Tulip", 128, 0x0801fbff, > HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY > | HAS_INTR_MITIGATION | HAS_PCI_MWI, tulip_timer, t21142_media_task }, ACK patches 7-8 ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 6/9] [TULIP] Fix IRQ/DMA race 2006-08-07 20:53 ` [PATCH 6/9] [TULIP] Fix IRQ/DMA race Kyle McMartin 2006-08-07 20:53 ` [PATCH 7/9] [TULIP] Defer tulip_select_media() to process context Kyle McMartin @ 2006-08-09 5:35 ` Jeff Garzik 2006-08-09 6:44 ` Valerie Henson 1 sibling, 1 reply; 20+ messages in thread From: Jeff Garzik @ 2006-08-09 5:35 UTC (permalink / raw) To: Kyle McMartin; +Cc: netdev, grundler, val_henson, akpm Kyle McMartin wrote: > From: Grant Grundler <grundler@parisc-linux.org> > > IRQs are racing with tulip_down(). > DMA can be restarted by tulip_interrupt() _after_ we call > tulip_stop_rxtx() and the DMA buffers are unmapped. The result > is an MCA (hard crash on ia64) because of an IO TLB miss. > > Signed-off-by: Grant Grundler <grundler@parisc-linux.org> > Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> > --- > drivers/net/tulip/interrupt.c | 4 ++++ > drivers/net/tulip/tulip_core.c | 17 +++++++---------- > 2 files changed, 11 insertions(+), 10 deletions(-) > > diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c > index 99ccf2e..19faa0e 100644 > --- a/drivers/net/tulip/interrupt.c > +++ b/drivers/net/tulip/interrupt.c > @@ -87,6 +87,10 @@ int tulip_refill_rx(struct net_device *d > } > tp->rx_ring[entry].status = cpu_to_le32(DescOwned); > } > + > +/* FIXME: restarting DMA breaks tulip_down() code path. > + tulip_down() will unmap the RX and TX descriptors. > + */ > if(tp->chip_id == LC82C168) { > if(((ioread32(tp->base_addr + CSR5)>>17)&0x07) == 4) { > /* Rx stopped due to out of buffers, > diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c > index 81905f4..363e5f6 100644 > --- a/drivers/net/tulip/tulip_core.c > +++ b/drivers/net/tulip/tulip_core.c > @@ -742,21 +742,20 @@ #endif > > /* Disable interrupts by clearing the interrupt mask. */ > iowrite32 (0x00000000, ioaddr + CSR7); > + ioread32 (ioaddr + CSR7); /* flush posted write */ > > - /* Stop the Tx and Rx processes. */ > - tulip_stop_rxtx(tp); > + spin_unlock_irqrestore (&tp->lock, flags); > > - /* prepare receive buffers */ > - tulip_refill_rx(dev); > + free_irq (dev->irq, dev); /* no more races after this */ > + tulip_stop_rxtx(tp); /* Stop DMA */ same old comment: need to stop DMA before releasing interrupt handler. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 6/9] [TULIP] Fix IRQ/DMA race 2006-08-09 5:35 ` [PATCH 6/9] [TULIP] Fix IRQ/DMA race Jeff Garzik @ 2006-08-09 6:44 ` Valerie Henson 0 siblings, 0 replies; 20+ messages in thread From: Valerie Henson @ 2006-08-09 6:44 UTC (permalink / raw) To: Jeff Garzik; +Cc: Kyle McMartin, netdev, grundler, akpm On Wed, Aug 09, 2006 at 01:35:05AM -0400, Jeff Garzik wrote: > Kyle McMartin wrote: > >From: Grant Grundler <grundler@parisc-linux.org> > > > >IRQs are racing with tulip_down(). > >DMA can be restarted by tulip_interrupt() _after_ we call > >tulip_stop_rxtx() and the DMA buffers are unmapped. The result > >is an MCA (hard crash on ia64) because of an IO TLB miss. > > > >Signed-off-by: Grant Grundler <grundler@parisc-linux.org> > >Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> > >--- > > drivers/net/tulip/interrupt.c | 4 ++++ > > drivers/net/tulip/tulip_core.c | 17 +++++++---------- > > 2 files changed, 11 insertions(+), 10 deletions(-) > > > >diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c > >index 99ccf2e..19faa0e 100644 > >--- a/drivers/net/tulip/interrupt.c > >+++ b/drivers/net/tulip/interrupt.c > >@@ -87,6 +87,10 @@ int tulip_refill_rx(struct net_device *d > > } > > tp->rx_ring[entry].status = cpu_to_le32(DescOwned); > > } > >+ > >+/* FIXME: restarting DMA breaks tulip_down() code path. > >+ tulip_down() will unmap the RX and TX descriptors. > >+ */ > > if(tp->chip_id == LC82C168) { > > if(((ioread32(tp->base_addr + CSR5)>>17)&0x07) == 4) { > > /* Rx stopped due to out of buffers, > >diff --git a/drivers/net/tulip/tulip_core.c > >b/drivers/net/tulip/tulip_core.c > >index 81905f4..363e5f6 100644 > >--- a/drivers/net/tulip/tulip_core.c > >+++ b/drivers/net/tulip/tulip_core.c > >@@ -742,21 +742,20 @@ #endif > > > > /* Disable interrupts by clearing the interrupt mask. */ > > iowrite32 (0x00000000, ioaddr + CSR7); > >+ ioread32 (ioaddr + CSR7); /* flush posted write */ > > > >- /* Stop the Tx and Rx processes. */ > >- tulip_stop_rxtx(tp); > >+ spin_unlock_irqrestore (&tp->lock, flags); > > > >- /* prepare receive buffers */ > >- tulip_refill_rx(dev); > >+ free_irq (dev->irq, dev); /* no more races after this */ > >+ tulip_stop_rxtx(tp); /* Stop DMA */ > > same old comment: need to stop DMA before releasing interrupt handler. I'm testing my implementation of a version that checks for in-progress shutdown in the interupt handler; unfortunately TX died in overnight testing so there's more work to do. -VAL ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 5/9] [TULIP] Flush MMIO writes in reset sequence 2006-08-07 20:53 ` [PATCH 5/9] [TULIP] Flush MMIO writes in reset sequence Kyle McMartin 2006-08-07 20:53 ` [PATCH 6/9] [TULIP] Fix IRQ/DMA race Kyle McMartin @ 2006-08-09 5:33 ` Jeff Garzik 1 sibling, 0 replies; 20+ messages in thread From: Jeff Garzik @ 2006-08-09 5:33 UTC (permalink / raw) To: Kyle McMartin; +Cc: netdev, grundler, val_henson, akpm Kyle McMartin wrote: > From: Grant Grundler <grundler@parisc-linux.org> > > The obvious safe registers to read is one from PCI config space. > > Signed-off-by: Grant Grundler <grundler@parisc-linux.org> > Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> > --- > drivers/net/tulip/tulip_core.c | 2 ++ > 1 files changed, 2 insertions(+), 0 deletions(-) > > diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c > index 6b54572..81905f4 100644 > --- a/drivers/net/tulip/tulip_core.c > +++ b/drivers/net/tulip/tulip_core.c > @@ -295,12 +295,14 @@ static void tulip_up(struct net_device * > > /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */ > iowrite32(0x00000001, ioaddr + CSR0); > + pci_read_config_dword(tp->pdev, PCI_COMMAND, &i); /* flush write */ > udelay(100); > > /* Deassert reset. > Wait the specified 50 PCI cycles after a reset by initializing > Tx and Rx queues and the address filter list. */ > iowrite32(tp->csr0, ioaddr + CSR0); > + pci_read_config_dword(tp->pdev, PCI_COMMAND, &i); /* flush write */ > udelay(100); OK ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/9] [TULIP] Clean tulip.h so it can be used by winbond-840.c 2006-08-07 20:53 ` [PATCH 4/9] [TULIP] Clean tulip.h so it can be used by winbond-840.c Kyle McMartin 2006-08-07 20:53 ` [PATCH 5/9] [TULIP] Flush MMIO writes in reset sequence Kyle McMartin @ 2006-08-09 5:33 ` Jeff Garzik 2006-08-09 15:00 ` Grant Grundler 1 sibling, 1 reply; 20+ messages in thread From: Jeff Garzik @ 2006-08-09 5:33 UTC (permalink / raw) To: Kyle McMartin; +Cc: netdev, grundler, val_henson, akpm Kyle McMartin wrote: > From: Grant Grundler <grundler@parisc-linux.org> > > Include "tulip.h" in winbond-840.c and clean up lots of redundant > definitions. > > Signed-off-by: Grant Grundler <grundler@parisc-linux.org> > Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> > --- > drivers/net/tulip/tulip.h | 17 ++++++---- > drivers/net/tulip/tulip_core.c | 7 +--- > drivers/net/tulip/winbond-840.c | 68 ++++++++++++++------------------------- > 3 files changed, 37 insertions(+), 55 deletions(-) > > diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h > index d79c7ae..951af5e 100644 > --- a/drivers/net/tulip/tulip.h > +++ b/drivers/net/tulip/tulip.h > @@ -30,11 +30,10 @@ #include <asm/irq.h> > /* undefine, or define to various debugging levels (>4 == obscene levels) */ > #define TULIP_DEBUG 1 > > -/* undefine USE_IO_OPS for MMIO, define for PIO */ > #ifdef CONFIG_TULIP_MMIO > -# undef USE_IO_OPS > +#define TULIP_BAR 1 /* CBMA */ > #else > -# define USE_IO_OPS 1 > +#define TULIP_BAR 0 /* CBIO */ > #endif OK except for two things: 1) should be split up into two patches: modify tulip, and modify winbond 2) nobody (but parisc folks?) knows what CBMA and CBIO mean. Just use "MMIO" and "PIO" ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/9] [TULIP] Clean tulip.h so it can be used by winbond-840.c 2006-08-09 5:33 ` [PATCH 4/9] [TULIP] Clean tulip.h so it can be used by winbond-840.c Jeff Garzik @ 2006-08-09 15:00 ` Grant Grundler 2006-08-10 12:26 ` Jeff Garzik 0 siblings, 1 reply; 20+ messages in thread From: Grant Grundler @ 2006-08-09 15:00 UTC (permalink / raw) To: Jeff Garzik; +Cc: Kyle McMartin, netdev, grundler, val_henson, akpm On Wed, Aug 09, 2006 at 01:33:18AM -0400, Jeff Garzik wrote: > 2) nobody (but parisc folks?) knows what CBMA and CBIO mean. Just use > "MMIO" and "PIO" "CBIO" is what's in the public documentation. I just want to make it easy for anyone who bothers to read the documentation to be sure they are reading about the right register. thanks, grant ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/9] [TULIP] Clean tulip.h so it can be used by winbond-840.c 2006-08-09 15:00 ` Grant Grundler @ 2006-08-10 12:26 ` Jeff Garzik 0 siblings, 0 replies; 20+ messages in thread From: Jeff Garzik @ 2006-08-10 12:26 UTC (permalink / raw) To: Grant Grundler; +Cc: Kyle McMartin, netdev, val_henson, akpm Grant Grundler wrote: > On Wed, Aug 09, 2006 at 01:33:18AM -0400, Jeff Garzik wrote: >> 2) nobody (but parisc folks?) knows what CBMA and CBIO mean. Just use >> "MMIO" and "PIO" > > "CBIO" is what's in the public documentation. I just want to make it > easy for anyone who bothers to read the documentation to be sure > they are reading about the right register. Thanks for clarifying. Nonetheless, I still prefer 'mmio' and 'pio' because its more universal. Jeff ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 3/9] [TULIP] Make tulip_stop_rxtx() failure case slightly more informative 2006-08-07 20:53 ` [PATCH 3/9] [TULIP] Make tulip_stop_rxtx() failure case slightly more informative Kyle McMartin 2006-08-07 20:53 ` [PATCH 4/9] [TULIP] Clean tulip.h so it can be used by winbond-840.c Kyle McMartin @ 2006-08-09 5:30 ` Jeff Garzik 1 sibling, 0 replies; 20+ messages in thread From: Jeff Garzik @ 2006-08-09 5:30 UTC (permalink / raw) To: Kyle McMartin; +Cc: netdev, grundler, val_henson, akpm Kyle McMartin wrote: > From: Grant Grundler <grundler@parisc-linux.org> > > Signed-off-by: Grant Grundler <grundler@parisc-linux.org> > Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> ACK patches 2-3 ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/9] [TULIP] Fix PHY init and reset 2006-08-07 20:53 ` [PATCH 1/9] [TULIP] Fix PHY init and reset Kyle McMartin 2006-08-07 20:53 ` [PATCH 2/9] [TULIP] Print physical address in tulip_init_one Kyle McMartin @ 2006-08-09 5:29 ` Jeff Garzik 1 sibling, 0 replies; 20+ messages in thread From: Jeff Garzik @ 2006-08-09 5:29 UTC (permalink / raw) To: Kyle McMartin; +Cc: netdev, grundler, val_henson, akpm Kyle McMartin wrote: > From: Grant Grundler <grundler@parisc-linux.org> > > A whole slew of fixes for tulip_select_media for: > - Flush posted MMIO writes as per PCI spec > - Polling the reset bit (bit 15) is required to determine when > the "init" sequence can be sent. > > This fixes tulip on HP PA-RISC systems, which use DP83840A and > LXT971D PHYs. Tested for several years on a variety of HP PA-RISC > systems. > > [Initial work done by Grant Grundler, DS21142 support added by > Thibaut Varene.] > > Signed-off-by: Grant Grundler <grundler@parisc-linux.org> > Signed-off-by: Thibaut Varene <varenet@parisc-linux.org> > Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> seems OK except for two details: * [old news] the delays should turn into sleeps, once Francois's patch is applied * seems like you should be using get_u16() etc. for possibly-unaligned data ^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2006-08-10 12:26 UTC | newest] Thread overview: 20+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-08-07 20:44 [PATCH 0/9] tulip patches from parisc-linux Kyle McMartin 2006-08-07 20:53 ` [PATCH 1/9] [TULIP] Fix PHY init and reset Kyle McMartin 2006-08-07 20:53 ` [PATCH 2/9] [TULIP] Print physical address in tulip_init_one Kyle McMartin 2006-08-07 20:53 ` [PATCH 3/9] [TULIP] Make tulip_stop_rxtx() failure case slightly more informative Kyle McMartin 2006-08-07 20:53 ` [PATCH 4/9] [TULIP] Clean tulip.h so it can be used by winbond-840.c Kyle McMartin 2006-08-07 20:53 ` [PATCH 5/9] [TULIP] Flush MMIO writes in reset sequence Kyle McMartin 2006-08-07 20:53 ` [PATCH 6/9] [TULIP] Fix IRQ/DMA race Kyle McMartin 2006-08-07 20:53 ` [PATCH 7/9] [TULIP] Defer tulip_select_media() to process context Kyle McMartin 2006-08-07 20:53 ` [PATCH 8/9] [TULIP] Make DS21143 printout match lspci output Kyle McMartin 2006-08-07 20:53 ` [PATCH 9/9] [TULIP] Fix section mismatch in de2104x.c Kyle McMartin 2006-08-09 5:37 ` Jeff Garzik 2006-08-09 5:36 ` [PATCH 8/9] [TULIP] Make DS21143 printout match lspci output Jeff Garzik 2006-08-09 5:35 ` [PATCH 6/9] [TULIP] Fix IRQ/DMA race Jeff Garzik 2006-08-09 6:44 ` Valerie Henson 2006-08-09 5:33 ` [PATCH 5/9] [TULIP] Flush MMIO writes in reset sequence Jeff Garzik 2006-08-09 5:33 ` [PATCH 4/9] [TULIP] Clean tulip.h so it can be used by winbond-840.c Jeff Garzik 2006-08-09 15:00 ` Grant Grundler 2006-08-10 12:26 ` Jeff Garzik 2006-08-09 5:30 ` [PATCH 3/9] [TULIP] Make tulip_stop_rxtx() failure case slightly more informative Jeff Garzik 2006-08-09 5:29 ` [PATCH 1/9] [TULIP] Fix PHY init and reset Jeff Garzik
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).