Commit dd391066 authored by Jes Sorensen's avatar Jes Sorensen Committed by Jeff Garzik

acenic net driver update:

* PCI write posting fixes, remove pa-specific code
* support 2.5.x kernels (synchronize_irq, cli/sti cleanups)
parent 1d462e8d
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
* flushing the Jumbo ring. * flushing the Jumbo ring.
* Hans Grobler <grobh@sun.ac.za>: Memory leak fixes in the * Hans Grobler <grobh@sun.ac.za>: Memory leak fixes in the
* driver init path. * driver init path.
* Grant Grundler <grundler@cup.hp.com>: PCI write posting fixes.
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -120,6 +121,9 @@ ...@@ -120,6 +121,9 @@
#ifndef PCI_DEVICE_ID_FARALLON_PN9000SX #ifndef PCI_DEVICE_ID_FARALLON_PN9000SX
#define PCI_DEVICE_ID_FARALLON_PN9000SX 0x1a #define PCI_DEVICE_ID_FARALLON_PN9000SX 0x1a
#endif #endif
#ifndef PCI_DEVICE_ID_FARALLON_PN9100T
#define PCI_DEVICE_ID_FARALLON_PN9100T 0xfa
#endif
#ifndef PCI_VENDOR_ID_SGI #ifndef PCI_VENDOR_ID_SGI
#define PCI_VENDOR_ID_SGI 0x10a9 #define PCI_VENDOR_ID_SGI 0x10a9
#endif #endif
...@@ -140,10 +144,13 @@ static struct pci_device_id acenic_pci_tbl[] __initdata = { ...@@ -140,10 +144,13 @@ static struct pci_device_id acenic_pci_tbl[] __initdata = {
{ PCI_VENDOR_ID_NETGEAR, PCI_DEVICE_ID_NETGEAR_GA620T, { PCI_VENDOR_ID_NETGEAR, PCI_DEVICE_ID_NETGEAR_GA620T,
PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, }, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
/* /*
* Farallon used the DEC vendor ID on their cards incorrectly. * Farallon used the DEC vendor ID on their cards incorrectly,
* then later Alteon's ID.
*/ */
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_FARALLON_PN9000SX, { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_FARALLON_PN9000SX,
PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, }, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
{ PCI_VENDOR_ID_ALTEON, PCI_DEVICE_ID_FARALLON_PN9100T,
PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
{ PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_ACENIC, { PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_ACENIC,
PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, }, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
{ } { }
...@@ -173,14 +180,26 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl); ...@@ -173,14 +180,26 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);
#endif #endif
#ifndef SET_MODULE_OWNER #ifndef SET_MODULE_OWNER
#define SET_MODULE_OWNER(dev) {do{} while(0);} #define SET_MODULE_OWNER(dev) do{} while(0)
#define ACE_MOD_INC_USE_COUNT MOD_INC_USE_COUNT #define ACE_MOD_INC_USE_COUNT MOD_INC_USE_COUNT
#define ACE_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT #define ACE_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT
#else #else
#define ACE_MOD_INC_USE_COUNT {do{} while(0);} #define ACE_MOD_INC_USE_COUNT do{} while(0)
#define ACE_MOD_DEC_USE_COUNT {do{} while(0);} #define ACE_MOD_DEC_USE_COUNT do{} while(0)
#endif
#if LINUX_VERSION_CODE >= 0x2051c
#define ace_sync_irq(irq) synchronize_irq(irq)
#else
#define ace_sync_irq(irq) synchronize_irq()
#endif #endif
#if LINUX_VERSION_CODE < 0x2051e
#define local_irq_save(flags) do{__save_flags(flags) ; \
__cli();} while(0)
#define local_irq_restore(flags) __restore_flags(flags)
#endif
#if (LINUX_VERSION_CODE < 0x02030d) #if (LINUX_VERSION_CODE < 0x02030d)
#define pci_resource_start(dev, bar) dev->base_address[bar] #define pci_resource_start(dev, bar) dev->base_address[bar]
...@@ -192,6 +211,7 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl); ...@@ -192,6 +211,7 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);
#define net_device device #define net_device device
#endif #endif
#if (LINUX_VERSION_CODE < 0x02032a) #if (LINUX_VERSION_CODE < 0x02032a)
typedef u32 dma_addr_t; typedef u32 dma_addr_t;
...@@ -215,8 +235,6 @@ static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, ...@@ -215,8 +235,6 @@ static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
(((u64)(mask) & 0xffffffff00000000) == 0 ? 0 : -EIO) (((u64)(mask) & 0xffffffff00000000) == 0 ? 0 : -EIO)
#define pci_dma_supported(dev, mask) \ #define pci_dma_supported(dev, mask) \
(((u64)(mask) & 0xffffffff00000000) == 0 ? 1 : 0) (((u64)(mask) & 0xffffffff00000000) == 0 ? 1 : 0)
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
#elif (LINUX_VERSION_CODE < 0x02040d) #elif (LINUX_VERSION_CODE < 0x02040d)
...@@ -240,8 +258,15 @@ pci_map_page(struct pci_dev *cookie, struct page *page, unsigned long off, ...@@ -240,8 +258,15 @@ pci_map_page(struct pci_dev *cookie, struct page *page, unsigned long off,
} }
#define pci_unmap_page(cookie, dma_addr, size, dir) \ #define pci_unmap_page(cookie, dma_addr, size, dir) \
pci_unmap_single(cookie, dma_addr, size, dir) pci_unmap_single(cookie, dma_addr, size, dir)
#endif
#if (LINUX_VERSION_CODE < 0x020412)
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) #define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
#define pci_unmap_addr(PTR, ADDR_NAME) 0
#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do{} while(0)
#define pci_unmap_len(PTR, LEN_NAME) 0
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do{} while(0)
#endif #endif
...@@ -259,7 +284,7 @@ pci_map_page(struct pci_dev *cookie, struct page *page, unsigned long off, ...@@ -259,7 +284,7 @@ pci_map_page(struct pci_dev *cookie, struct page *page, unsigned long off,
#define dev_kfree_skb_irq(a) dev_kfree_skb(a) #define dev_kfree_skb_irq(a) dev_kfree_skb(a)
#define netif_wake_queue(dev) clear_bit(0, &dev->tbusy) #define netif_wake_queue(dev) clear_bit(0, &dev->tbusy)
#define netif_stop_queue(dev) set_bit(0, &dev->tbusy) #define netif_stop_queue(dev) set_bit(0, &dev->tbusy)
#define late_stop_netif_stop_queue(dev) {do{} while(0);} #define late_stop_netif_stop_queue(dev) do{} while(0)
#define early_stop_netif_stop_queue(dev) test_and_set_bit(0,&dev->tbusy) #define early_stop_netif_stop_queue(dev) test_and_set_bit(0,&dev->tbusy)
#define early_stop_netif_wake_queue(dev) netif_wake_queue(dev) #define early_stop_netif_wake_queue(dev) netif_wake_queue(dev)
...@@ -273,7 +298,7 @@ static inline void netif_start_queue(struct net_device *dev) ...@@ -273,7 +298,7 @@ static inline void netif_start_queue(struct net_device *dev)
#define ace_mark_net_bh() mark_bh(NET_BH) #define ace_mark_net_bh() mark_bh(NET_BH)
#define netif_queue_stopped(dev) dev->tbusy #define netif_queue_stopped(dev) dev->tbusy
#define netif_running(dev) dev->start #define netif_running(dev) dev->start
#define ace_if_down(dev) {do{dev->start = 0;} while(0);} #define ace_if_down(dev) do{dev->start = 0;} while(0)
#define tasklet_struct tq_struct #define tasklet_struct tq_struct
static inline void tasklet_schedule(struct tasklet_struct *tasklet) static inline void tasklet_schedule(struct tasklet_struct *tasklet)
...@@ -291,13 +316,13 @@ static inline void tasklet_init(struct tasklet_struct *tasklet, ...@@ -291,13 +316,13 @@ static inline void tasklet_init(struct tasklet_struct *tasklet,
tasklet->routine = (void (*)(void *))func; tasklet->routine = (void (*)(void *))func;
tasklet->data = (void *)data; tasklet->data = (void *)data;
} }
#define tasklet_kill(tasklet) {do{} while(0);} #define tasklet_kill(tasklet) do{} while(0)
#else #else
#define late_stop_netif_stop_queue(dev) netif_stop_queue(dev) #define late_stop_netif_stop_queue(dev) netif_stop_queue(dev)
#define early_stop_netif_stop_queue(dev) 0 #define early_stop_netif_stop_queue(dev) 0
#define early_stop_netif_wake_queue(dev) {do{} while(0);} #define early_stop_netif_wake_queue(dev) do{} while(0)
#define ace_mark_net_bh() {do{} while(0);} #define ace_mark_net_bh() do{} while(0)
#define ace_if_down(dev) {do{} while(0);} #define ace_if_down(dev) do{} while(0)
#endif #endif
#if (LINUX_VERSION_CODE >= 0x02031b) #if (LINUX_VERSION_CODE >= 0x02031b)
...@@ -313,7 +338,7 @@ static inline void tasklet_init(struct tasklet_struct *tasklet, ...@@ -313,7 +338,7 @@ static inline void tasklet_init(struct tasklet_struct *tasklet,
#ifndef ARCH_HAS_PREFETCHW #ifndef ARCH_HAS_PREFETCHW
#ifndef prefetchw #ifndef prefetchw
#define prefetchw(x) {do{} while(0);} #define prefetchw(x) do{} while(0)
#endif #endif
#endif #endif
...@@ -568,7 +593,7 @@ static int tx_ratio[ACE_MAX_MOD_PARMS]; ...@@ -568,7 +593,7 @@ static int tx_ratio[ACE_MAX_MOD_PARMS];
static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1}; static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1};
static char version[] __initdata = static char version[] __initdata =
"acenic.c: v0.89 03/15/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n" "acenic.c: v0.92 08/05/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n"
" http://home.cern.ch/~jes/gige/acenic.html\n"; " http://home.cern.ch/~jes/gige/acenic.html\n";
static struct net_device *root_dev; static struct net_device *root_dev;
...@@ -611,6 +636,8 @@ int __devinit acenic_probe (ACE_PROBE_ARG) ...@@ -611,6 +636,8 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
*/ */
!((pdev->vendor == PCI_VENDOR_ID_DEC) && !((pdev->vendor == PCI_VENDOR_ID_DEC) &&
(pdev->device == PCI_DEVICE_ID_FARALLON_PN9000SX)) && (pdev->device == PCI_DEVICE_ID_FARALLON_PN9000SX)) &&
!((pdev->vendor == PCI_VENDOR_ID_ALTEON) &&
(pdev->device == PCI_DEVICE_ID_FARALLON_PN9100T)) &&
!((pdev->vendor == PCI_VENDOR_ID_SGI) && !((pdev->vendor == PCI_VENDOR_ID_SGI) &&
(pdev->device == PCI_DEVICE_ID_SGI_ACENIC))) (pdev->device == PCI_DEVICE_ID_SGI_ACENIC)))
continue; continue;
...@@ -664,6 +691,11 @@ int __devinit acenic_probe (ACE_PROBE_ARG) ...@@ -664,6 +691,11 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
printk(version); printk(version);
} }
if (pci_enable_device(pdev)) {
kfree(dev);
continue;
}
/* /*
* Enable master mode before we start playing with the * Enable master mode before we start playing with the
* pci_command word since pci_set_master() will modify * pci_command word since pci_set_master() will modify
...@@ -708,9 +740,17 @@ int __devinit acenic_probe (ACE_PROBE_ARG) ...@@ -708,9 +740,17 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
switch(pdev->vendor) { switch(pdev->vendor) {
case PCI_VENDOR_ID_ALTEON: case PCI_VENDOR_ID_ALTEON:
if (pdev->device == PCI_DEVICE_ID_FARALLON_PN9100T) {
strncpy(ap->name, "Farallon PN9100-T "
"Gigabit Ethernet", sizeof (ap->name));
printk(KERN_INFO "%s: Farallon PN9100-T ",
dev->name);
} else {
strncpy(ap->name, "AceNIC Gigabit Ethernet", strncpy(ap->name, "AceNIC Gigabit Ethernet",
sizeof (ap->name)); sizeof (ap->name));
printk(KERN_INFO "%s: Alteon AceNIC ", dev->name); printk(KERN_INFO "%s: Alteon AceNIC ",
dev->name);
}
break; break;
case PCI_VENDOR_ID_3COM: case PCI_VENDOR_ID_3COM:
strncpy(ap->name, "3Com 3C985 Gigabit Ethernet", strncpy(ap->name, "3Com 3C985 Gigabit Ethernet",
...@@ -846,6 +886,7 @@ static void __exit ace_module_cleanup(void) ...@@ -846,6 +886,7 @@ static void __exit ace_module_cleanup(void)
* This clears any pending interrupts * This clears any pending interrupts
*/ */
writel(1, &regs->Mb0Lo); writel(1, &regs->Mb0Lo);
readl(&regs->CpuCtrl); /* flush */
/* /*
* Make sure no other CPUs are processing interrupts * Make sure no other CPUs are processing interrupts
...@@ -856,7 +897,7 @@ static void __exit ace_module_cleanup(void) ...@@ -856,7 +897,7 @@ static void __exit ace_module_cleanup(void)
* Then release the RX buffers - jumbo buffers were * Then release the RX buffers - jumbo buffers were
* already released in ace_close(). * already released in ace_close().
*/ */
synchronize_irq(); ace_sync_irq(root_dev->irq);
for (i = 0; i < RX_STD_RING_ENTRIES; i++) { for (i = 0; i < RX_STD_RING_ENTRIES; i++) {
struct sk_buff *skb = ap->skb->rx_std_skbuff[i].skb; struct sk_buff *skb = ap->skb->rx_std_skbuff[i].skb;
...@@ -1138,34 +1179,30 @@ static int __init ace_init(struct net_device *dev) ...@@ -1138,34 +1179,30 @@ static int __init ace_init(struct net_device *dev)
* to any crashes involving the NIC * to any crashes involving the NIC
*/ */
writel(HW_RESET | (HW_RESET << 24), &regs->HostCtrl); writel(HW_RESET | (HW_RESET << 24), &regs->HostCtrl);
wmb(); readl(&regs->HostCtrl); /* PCI write posting */
udelay(5);
/* /*
* Don't access any other registes before this point! * Don't access any other registers before this point!
*/ */
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
/* /*
* This will most likely need BYTE_SWAP once we switch * This will most likely need BYTE_SWAP once we switch
* to using __raw_writel() * to using __raw_writel()
*/ */
#ifdef __parisc__
writel((WORD_SWAP | BYTE_SWAP | CLR_INT |
((WORD_SWAP | BYTE_SWAP | CLR_INT) << 24)),
&regs->HostCtrl);
#else
writel((WORD_SWAP | CLR_INT | ((WORD_SWAP | CLR_INT) << 24)), writel((WORD_SWAP | CLR_INT | ((WORD_SWAP | CLR_INT) << 24)),
&regs->HostCtrl); &regs->HostCtrl);
#endif
#else #else
writel((CLR_INT | WORD_SWAP | ((CLR_INT | WORD_SWAP) << 24)), writel((CLR_INT | WORD_SWAP | ((CLR_INT | WORD_SWAP) << 24)),
&regs->HostCtrl); &regs->HostCtrl);
#endif #endif
mb(); readl(&regs->HostCtrl); /* PCI write posting */
/* /*
* Stop the NIC CPU and clear pending interrupts * Stop the NIC CPU and clear pending interrupts
*/ */
writel(readl(&regs->CpuCtrl) | CPU_HALT, &regs->CpuCtrl); writel(readl(&regs->CpuCtrl) | CPU_HALT, &regs->CpuCtrl);
readl(&regs->CpuCtrl); /* PCI write posting */
writel(0, &regs->Mb0Lo); writel(0, &regs->Mb0Lo);
tig_ver = readl(&regs->HostCtrl) >> 28; tig_ver = readl(&regs->HostCtrl) >> 28;
...@@ -1186,6 +1223,7 @@ static int __init ace_init(struct net_device *dev) ...@@ -1186,6 +1223,7 @@ static int __init ace_init(struct net_device *dev)
tig_ver, tigon2FwReleaseMajor, tigon2FwReleaseMinor, tig_ver, tigon2FwReleaseMajor, tigon2FwReleaseMinor,
tigon2FwReleaseFix); tigon2FwReleaseFix);
writel(readl(&regs->CpuBCtrl) | CPU_HALT, &regs->CpuBCtrl); writel(readl(&regs->CpuBCtrl) | CPU_HALT, &regs->CpuBCtrl);
readl(&regs->CpuBCtrl); /* PCI write posting */
/* /*
* The SRAM bank size does _not_ indicate the amount * The SRAM bank size does _not_ indicate the amount
* of memory on the card, it controls the _bank_ size! * of memory on the card, it controls the _bank_ size!
...@@ -1217,7 +1255,7 @@ static int __init ace_init(struct net_device *dev) ...@@ -1217,7 +1255,7 @@ static int __init ace_init(struct net_device *dev)
writel(ACE_BYTE_SWAP_DMA | ACE_WARN | ACE_FATAL | writel(ACE_BYTE_SWAP_DMA | ACE_WARN | ACE_FATAL |
ACE_WORD_SWAP_BD | ACE_NO_JUMBO_FRAG, &regs->ModeStat); ACE_WORD_SWAP_BD | ACE_NO_JUMBO_FRAG, &regs->ModeStat);
#endif #endif
mb(); readl(&regs->ModeStat); /* PCI write posting */
mac1 = 0; mac1 = 0;
for(i = 0; i < 4; i++) { for(i = 0; i < 4; i++) {
...@@ -1355,7 +1393,7 @@ static int __init ace_init(struct net_device *dev) ...@@ -1355,7 +1393,7 @@ static int __init ace_init(struct net_device *dev)
tmp &= ~DMA_READ_WRITE_MASK; tmp &= ~DMA_READ_WRITE_MASK;
tmp |= DMA_READ_MAX_128; tmp |= DMA_READ_MAX_128;
/* /*
* All the docs sy MUST NOT. Well, I did. * All the docs say MUST NOT. Well, I did.
* Nothing terrible happens, if we load wrong size. * Nothing terrible happens, if we load wrong size.
* Bit w&i still works better! * Bit w&i still works better!
*/ */
...@@ -1364,6 +1402,13 @@ static int __init ace_init(struct net_device *dev) ...@@ -1364,6 +1402,13 @@ static int __init ace_init(struct net_device *dev)
writel(tmp, &regs->PciState); writel(tmp, &regs->PciState);
#if 0 #if 0
/*
* The Host PCI bus controller driver has to set FBB.
* If all devices on that PCI bus support FBB, then the controller
* can enable FBB support in the Host PCI Bus controller (or on
* the PCI-PCI bridge if that applies).
* -ggg
*/
/* /*
* I have received reports from people having problems when this * I have received reports from people having problems when this
* bit is enabled. * bit is enabled.
...@@ -1445,9 +1490,9 @@ static int __init ace_init(struct net_device *dev) ...@@ -1445,9 +1490,9 @@ static int __init ace_init(struct net_device *dev)
set_aceaddr(&info->evt_ctrl.rngptr, ap->evt_ring_dma); set_aceaddr(&info->evt_ctrl.rngptr, ap->evt_ring_dma);
info->evt_ctrl.flags = 0; info->evt_ctrl.flags = 0;
set_aceaddr(&info->evt_prd_ptr, ap->evt_prd_dma);
*(ap->evt_prd) = 0; *(ap->evt_prd) = 0;
wmb(); wmb();
set_aceaddr(&info->evt_prd_ptr, ap->evt_prd_dma);
writel(0, &regs->EvtCsm); writel(0, &regs->EvtCsm);
set_aceaddr(&info->cmd_ctrl.rngptr, 0x100); set_aceaddr(&info->cmd_ctrl.rngptr, 0x100);
...@@ -1579,7 +1624,13 @@ static int __init ace_init(struct net_device *dev) ...@@ -1579,7 +1624,13 @@ static int __init ace_init(struct net_device *dev)
writel(0, &regs->MaskInt); writel(0, &regs->MaskInt);
writel(1, &regs->IfIdx); writel(1, &regs->IfIdx);
#if 0
/*
* McKinley boxes do not like us fiddling with AssistState
* this early
*/
writel(1, &regs->AssistState); writel(1, &regs->AssistState);
#endif
writel(DEF_STAT, &regs->TuneStatTicks); writel(DEF_STAT, &regs->TuneStatTicks);
writel(DEF_TRACE, &regs->TuneTrace); writel(DEF_TRACE, &regs->TuneTrace);
...@@ -1689,10 +1740,19 @@ static int __init ace_init(struct net_device *dev) ...@@ -1689,10 +1740,19 @@ static int __init ace_init(struct net_device *dev)
*/ */
memset(&ap->stats, 0, sizeof(ap->stats)); memset(&ap->stats, 0, sizeof(ap->stats));
/*
* Enable DMA engine now.
* If we do this sooner, Mckinley box pukes.
* I assume it's because Tigon II DMA engine wants to check
* *something* even before the CPU is started.
*/
writel(1, &regs->AssistState); /* enable DMA */
/* /*
* Start the NIC CPU * Start the NIC CPU
*/ */
writel(readl(&regs->CpuCtrl) & ~(CPU_HALT|CPU_TRACE), &regs->CpuCtrl); writel(readl(&regs->CpuCtrl) & ~(CPU_HALT|CPU_TRACE), &regs->CpuCtrl);
readl(&regs->CpuCtrl);
/* /*
* Wait for the firmware to spin up - max 3 seconds. * Wait for the firmware to spin up - max 3 seconds.
...@@ -1705,6 +1765,7 @@ static int __init ace_init(struct net_device *dev) ...@@ -1705,6 +1765,7 @@ static int __init ace_init(struct net_device *dev)
ace_dump_trace(ap); ace_dump_trace(ap);
writel(readl(&regs->CpuCtrl) | CPU_HALT, &regs->CpuCtrl); writel(readl(&regs->CpuCtrl) | CPU_HALT, &regs->CpuCtrl);
readl(&regs->CpuCtrl);
/* aman@sgi.com - account for badly behaving firmware/NIC: /* aman@sgi.com - account for badly behaving firmware/NIC:
* - have observed that the NIC may continue to generate * - have observed that the NIC may continue to generate
...@@ -1719,6 +1780,7 @@ static int __init ace_init(struct net_device *dev) ...@@ -1719,6 +1780,7 @@ static int __init ace_init(struct net_device *dev)
writel(readl(&regs->CpuBCtrl) | CPU_HALT, writel(readl(&regs->CpuBCtrl) | CPU_HALT,
&regs->CpuBCtrl); &regs->CpuBCtrl);
writel(0, &regs->Mb0Lo); writel(0, &regs->Mb0Lo);
readl(&regs->Mb0Lo);
ecode = -EBUSY; ecode = -EBUSY;
goto init_error; goto init_error;
...@@ -2393,6 +2455,7 @@ static void ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) ...@@ -2393,6 +2455,7 @@ static void ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
* threads and it is wrong even for that case. * threads and it is wrong even for that case.
*/ */
writel(0, &regs->Mb0Lo); writel(0, &regs->Mb0Lo);
readl(&regs->Mb0Lo);
/* /*
* There is no conflict between transmit handling in * There is no conflict between transmit handling in
...@@ -2496,12 +2559,13 @@ static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) ...@@ -2496,12 +2559,13 @@ static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
struct ace_private *ap = dev->priv; struct ace_private *ap = dev->priv;
unsigned long flags; unsigned long flags;
save_flags(flags); local_irq_save(flags);
cli(); ace_mask_irq(dev);
ap->vlgrp = grp; ap->vlgrp = grp;
restore_flags(flags); ace_unmask_irq(dev);
local_irq_restore(flags);
} }
...@@ -2510,13 +2574,14 @@ static void ace_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) ...@@ -2510,13 +2574,14 @@ static void ace_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
struct ace_private *ap = dev->priv; struct ace_private *ap = dev->priv;
unsigned long flags; unsigned long flags;
save_flags(flags); local_irq_save(flags);
cli(); ace_mask_irq(dev);
if (ap->vlgrp) if (ap->vlgrp)
ap->vlgrp->vlan_devices[vid] = NULL; ap->vlgrp->vlan_devices[vid] = NULL;
restore_flags(flags); ace_unmask_irq(dev);
local_irq_restore(flags);
} }
#endif /* ACENIC_DO_VLAN */ #endif /* ACENIC_DO_VLAN */
...@@ -2620,8 +2685,9 @@ static int ace_close(struct net_device *dev) ...@@ -2620,8 +2685,9 @@ static int ace_close(struct net_device *dev)
* Make sure one CPU is not processing packets while * Make sure one CPU is not processing packets while
* buffers are being released by another. * buffers are being released by another.
*/ */
save_flags(flags);
cli(); local_irq_save(flags);
ace_mask_irq(dev);
for (i = 0; i < ACE_TX_RING_ENTRIES(ap); i++) { for (i = 0; i < ACE_TX_RING_ENTRIES(ap); i++) {
struct sk_buff *skb; struct sk_buff *skb;
...@@ -2658,7 +2724,8 @@ static int ace_close(struct net_device *dev) ...@@ -2658,7 +2724,8 @@ static int ace_close(struct net_device *dev)
ace_issue_cmd(regs, &cmd); ace_issue_cmd(regs, &cmd);
} }
restore_flags(flags); ace_unmask_irq(dev);
local_irq_restore(flags);
ACE_MOD_DEC_USE_COUNT; ACE_MOD_DEC_USE_COUNT;
return 0; return 0;
...@@ -2877,7 +2944,7 @@ static int ace_change_mtu(struct net_device *dev, int new_mtu) ...@@ -2877,7 +2944,7 @@ static int ace_change_mtu(struct net_device *dev, int new_mtu)
} }
} else { } else {
while (test_and_set_bit(0, &ap->jumbo_refill_busy)); while (test_and_set_bit(0, &ap->jumbo_refill_busy));
synchronize_irq(); ace_sync_irq(dev->irq);
ace_set_rxtx_parms(dev, 0); ace_set_rxtx_parms(dev, 0);
if (ap->jumbo) { if (ap->jumbo) {
struct cmd cmd; struct cmd cmd;
...@@ -3259,22 +3326,27 @@ static void __init eeprom_start(struct ace_regs *regs) ...@@ -3259,22 +3326,27 @@ static void __init eeprom_start(struct ace_regs *regs)
{ {
u32 local; u32 local;
readl(&regs->LocalCtrl);
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
local = readl(&regs->LocalCtrl); local = readl(&regs->LocalCtrl);
local |= EEPROM_DATA_OUT | EEPROM_WRITE_ENABLE; local |= EEPROM_DATA_OUT | EEPROM_WRITE_ENABLE;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
local |= EEPROM_CLK_OUT; local |= EEPROM_CLK_OUT;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
local &= ~EEPROM_DATA_OUT; local &= ~EEPROM_DATA_OUT;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
local &= ~EEPROM_CLK_OUT; local &= ~EEPROM_CLK_OUT;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
} }
...@@ -3289,6 +3361,7 @@ static void __init eeprom_prep(struct ace_regs *regs, u8 magic) ...@@ -3289,6 +3361,7 @@ static void __init eeprom_prep(struct ace_regs *regs, u8 magic)
local &= ~EEPROM_DATA_OUT; local &= ~EEPROM_DATA_OUT;
local |= EEPROM_WRITE_ENABLE; local |= EEPROM_WRITE_ENABLE;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
for (i = 0; i < 8; i++, magic <<= 1) { for (i = 0; i < 8; i++, magic <<= 1) {
...@@ -3298,15 +3371,18 @@ static void __init eeprom_prep(struct ace_regs *regs, u8 magic) ...@@ -3298,15 +3371,18 @@ static void __init eeprom_prep(struct ace_regs *regs, u8 magic)
else else
local &= ~EEPROM_DATA_OUT; local &= ~EEPROM_DATA_OUT;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
local |= EEPROM_CLK_OUT; local |= EEPROM_CLK_OUT;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
local &= ~(EEPROM_CLK_OUT | EEPROM_DATA_OUT); local &= ~(EEPROM_CLK_OUT | EEPROM_DATA_OUT);
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
} }
} }
...@@ -3320,10 +3396,12 @@ static int __init eeprom_check_ack(struct ace_regs *regs) ...@@ -3320,10 +3396,12 @@ static int __init eeprom_check_ack(struct ace_regs *regs)
local = readl(&regs->LocalCtrl); local = readl(&regs->LocalCtrl);
local &= ~EEPROM_WRITE_ENABLE; local &= ~EEPROM_WRITE_ENABLE;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_LONG_DELAY); udelay(ACE_LONG_DELAY);
local |= EEPROM_CLK_OUT; local |= EEPROM_CLK_OUT;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
/* sample data in middle of high clk */ /* sample data in middle of high clk */
...@@ -3331,6 +3409,7 @@ static int __init eeprom_check_ack(struct ace_regs *regs) ...@@ -3331,6 +3409,7 @@ static int __init eeprom_check_ack(struct ace_regs *regs)
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
mb(); mb();
writel(readl(&regs->LocalCtrl) & ~EEPROM_CLK_OUT, &regs->LocalCtrl); writel(readl(&regs->LocalCtrl) & ~EEPROM_CLK_OUT, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
return state; return state;
...@@ -3345,18 +3424,22 @@ static void __init eeprom_stop(struct ace_regs *regs) ...@@ -3345,18 +3424,22 @@ static void __init eeprom_stop(struct ace_regs *regs)
local = readl(&regs->LocalCtrl); local = readl(&regs->LocalCtrl);
local |= EEPROM_WRITE_ENABLE; local |= EEPROM_WRITE_ENABLE;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
local &= ~EEPROM_DATA_OUT; local &= ~EEPROM_DATA_OUT;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
local |= EEPROM_CLK_OUT; local |= EEPROM_CLK_OUT;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
local |= EEPROM_DATA_OUT; local |= EEPROM_DATA_OUT;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_LONG_DELAY); udelay(ACE_LONG_DELAY);
local &= ~EEPROM_CLK_OUT; local &= ~EEPROM_CLK_OUT;
...@@ -3433,10 +3516,12 @@ static int __init read_eeprom_byte(struct net_device *dev, ...@@ -3433,10 +3516,12 @@ static int __init read_eeprom_byte(struct net_device *dev,
local = readl(&regs->LocalCtrl); local = readl(&regs->LocalCtrl);
local &= ~EEPROM_WRITE_ENABLE; local &= ~EEPROM_WRITE_ENABLE;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
udelay(ACE_LONG_DELAY); udelay(ACE_LONG_DELAY);
mb(); mb();
local |= EEPROM_CLK_OUT; local |= EEPROM_CLK_OUT;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
/* sample data mid high clk */ /* sample data mid high clk */
...@@ -3447,11 +3532,13 @@ static int __init read_eeprom_byte(struct net_device *dev, ...@@ -3447,11 +3532,13 @@ static int __init read_eeprom_byte(struct net_device *dev,
local = readl(&regs->LocalCtrl); local = readl(&regs->LocalCtrl);
local &= ~EEPROM_CLK_OUT; local &= ~EEPROM_CLK_OUT;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
mb(); mb();
if (i == 7) { if (i == 7) {
local |= EEPROM_WRITE_ENABLE; local |= EEPROM_WRITE_ENABLE;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
} }
...@@ -3459,11 +3546,14 @@ static int __init read_eeprom_byte(struct net_device *dev, ...@@ -3459,11 +3546,14 @@ static int __init read_eeprom_byte(struct net_device *dev,
local |= EEPROM_DATA_OUT; local |= EEPROM_DATA_OUT;
writel(local, &regs->LocalCtrl); writel(local, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
writel(readl(&regs->LocalCtrl) | EEPROM_CLK_OUT, &regs->LocalCtrl); writel(readl(&regs->LocalCtrl) | EEPROM_CLK_OUT, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
udelay(ACE_LONG_DELAY); udelay(ACE_LONG_DELAY);
writel(readl(&regs->LocalCtrl) & ~EEPROM_CLK_OUT, &regs->LocalCtrl); writel(readl(&regs->LocalCtrl) & ~EEPROM_CLK_OUT, &regs->LocalCtrl);
readl(&regs->LocalCtrl);
mb(); mb();
udelay(ACE_SHORT_DELAY); udelay(ACE_SHORT_DELAY);
eeprom_stop(regs); eeprom_stop(regs);
......
...@@ -748,6 +748,32 @@ static inline void ace_set_txprd(struct ace_regs *regs, ...@@ -748,6 +748,32 @@ static inline void ace_set_txprd(struct ace_regs *regs,
} }
static inline void ace_mask_irq(struct net_device *dev)
{
struct ace_private *ap = dev->priv;
struct ace_regs *regs = ap->regs;
if (ACE_IS_TIGON_I(ap))
writel(1, &regs->MaskInt);
else
writel(readl(&regs->HostCtrl) | MASK_INTS, &regs->HostCtrl);
ace_sync_irq(dev->irq);
}
static inline void ace_unmask_irq(struct net_device *dev)
{
struct ace_private *ap = dev->priv;
struct ace_regs *regs = ap->regs;
if (ACE_IS_TIGON_I(ap))
writel(0, &regs->MaskInt);
else
writel(readl(&regs->HostCtrl) &= ~MASK_INTS, &regs->HostCtrl);
}
/* /*
* Prototypes * Prototypes
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment