From patchwork Sat Aug 7 14:56:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Cai,Huoqing" X-Patchwork-Id: 493582 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F3ED0C4338F for ; Sat, 7 Aug 2021 14:59:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5581F6108D for ; Sat, 7 Aug 2021 14:59:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230371AbhHGO7u (ORCPT ); Sat, 7 Aug 2021 10:59:50 -0400 Received: from mx21.baidu.com ([220.181.3.85]:42736 "EHLO baidu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S231206AbhHGO6O (ORCPT ); Sat, 7 Aug 2021 10:58:14 -0400 Received: from BC-Mail-Ex14.internal.baidu.com (unknown [172.31.51.54]) by Forcepoint Email with ESMTPS id D7DA4F505C11082B62EB; Sat, 7 Aug 2021 22:57:10 +0800 (CST) Received: from BJHW-MAIL-EX27.internal.baidu.com (10.127.64.42) by BC-Mail-Ex14.internal.baidu.com (172.31.51.54) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2242.12; Sat, 7 Aug 2021 22:57:10 +0800 Received: from LAPTOP-UKSR4ENP.internal.baidu.com (172.31.62.11) by BJHW-MAIL-EX27.internal.baidu.com (10.127.64.42) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2308.14; Sat, 7 Aug 2021 22:57:07 +0800 From: Cai Huoqing To: , , , , , CC: , , Cai Huoqing Subject: [PATCH 1/2] net: ethernet: Remove the 8390 network drivers Date: Sat, 7 Aug 2021 22:56:55 +0800 Message-ID: <20210807145655.1730-1-caihuoqing@baidu.com> X-Mailer: git-send-email 2.32.0.windows.2 MIME-Version: 1.0 X-Originating-IP: [172.31.62.11] X-ClientProxiedBy: BJHW-Mail-Ex14.internal.baidu.com (10.127.64.37) To BJHW-MAIL-EX27.internal.baidu.com (10.127.64.42) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org commit <0cf445ceaf43> ("") indicated the 8390 network drivers as orphan/obsolete in Jan 2011, updated in the MAINTAINERS file. now, after being exposed for 10 years to refactoring, and no one has become its maintainer for the past 10 years, so to remove the 8390 network drivers for good. additionally, 8390 is a kind of old ethernet chip based on ISA interface which is hard to find in the market. Signed-off-by: Cai Huoqing --- drivers/net/ethernet/8390/8390.c | 103 -- drivers/net/ethernet/8390/8390.h | 236 ---- drivers/net/ethernet/8390/8390p.c | 105 -- drivers/net/ethernet/8390/Kconfig | 212 --- drivers/net/ethernet/8390/Makefile | 20 - drivers/net/ethernet/8390/apne.c | 619 --------- drivers/net/ethernet/8390/ax88796.c | 1022 --------------- drivers/net/ethernet/8390/axnet_cs.c | 1707 ------------------------ drivers/net/ethernet/8390/etherh.c | 856 ------------- drivers/net/ethernet/8390/hydra.c | 273 ---- drivers/net/ethernet/8390/lib8390.c | 1092 ---------------- drivers/net/ethernet/8390/mac8390.c | 848 ------------ drivers/net/ethernet/8390/mcf8390.c | 475 ------- drivers/net/ethernet/8390/ne.c | 1004 --------------- drivers/net/ethernet/8390/ne2k-pci.c | 747 ----------- drivers/net/ethernet/8390/pcnet_cs.c | 1708 ------------------------- drivers/net/ethernet/8390/smc-ultra.c | 629 --------- drivers/net/ethernet/8390/stnic.c | 303 ----- drivers/net/ethernet/8390/wd.c | 574 --------- drivers/net/ethernet/8390/xsurf100.c | 377 ------ drivers/net/ethernet/8390/zorro8390.c | 452 ------- drivers/net/ethernet/Kconfig | 1 - drivers/net/ethernet/Makefile | 1 - 23 files changed, 13364 deletions(-) delete mode 100644 drivers/net/ethernet/8390/8390.c delete mode 100644 drivers/net/ethernet/8390/8390.h delete mode 100644 drivers/net/ethernet/8390/8390p.c delete mode 100644 drivers/net/ethernet/8390/Kconfig delete mode 100644 drivers/net/ethernet/8390/Makefile delete mode 100644 drivers/net/ethernet/8390/apne.c delete mode 100644 drivers/net/ethernet/8390/ax88796.c delete mode 100644 drivers/net/ethernet/8390/axnet_cs.c delete mode 100644 drivers/net/ethernet/8390/etherh.c delete mode 100644 drivers/net/ethernet/8390/hydra.c delete mode 100644 drivers/net/ethernet/8390/lib8390.c delete mode 100644 drivers/net/ethernet/8390/mac8390.c delete mode 100644 drivers/net/ethernet/8390/mcf8390.c delete mode 100644 drivers/net/ethernet/8390/ne.c delete mode 100644 drivers/net/ethernet/8390/ne2k-pci.c delete mode 100644 drivers/net/ethernet/8390/pcnet_cs.c delete mode 100644 drivers/net/ethernet/8390/smc-ultra.c delete mode 100644 drivers/net/ethernet/8390/stnic.c delete mode 100644 drivers/net/ethernet/8390/wd.c delete mode 100644 drivers/net/ethernet/8390/xsurf100.c delete mode 100644 drivers/net/ethernet/8390/zorro8390.c diff --git a/drivers/net/ethernet/8390/8390.c b/drivers/net/ethernet/8390/8390.c deleted file mode 100644 index 0e0aa4016858..000000000000 --- a/drivers/net/ethernet/8390/8390.c +++ /dev/null @@ -1,103 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* 8390 core for usual drivers */ - -static const char version[] = - "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; - -#include "lib8390.c" - -int ei_open(struct net_device *dev) -{ - return __ei_open(dev); -} -EXPORT_SYMBOL(ei_open); - -int ei_close(struct net_device *dev) -{ - return __ei_close(dev); -} -EXPORT_SYMBOL(ei_close); - -netdev_tx_t ei_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - return __ei_start_xmit(skb, dev); -} -EXPORT_SYMBOL(ei_start_xmit); - -struct net_device_stats *ei_get_stats(struct net_device *dev) -{ - return __ei_get_stats(dev); -} -EXPORT_SYMBOL(ei_get_stats); - -void ei_set_multicast_list(struct net_device *dev) -{ - __ei_set_multicast_list(dev); -} -EXPORT_SYMBOL(ei_set_multicast_list); - -void ei_tx_timeout(struct net_device *dev, unsigned int txqueue) -{ - __ei_tx_timeout(dev, txqueue); -} -EXPORT_SYMBOL(ei_tx_timeout); - -irqreturn_t ei_interrupt(int irq, void *dev_id) -{ - return __ei_interrupt(irq, dev_id); -} -EXPORT_SYMBOL(ei_interrupt); - -#ifdef CONFIG_NET_POLL_CONTROLLER -void ei_poll(struct net_device *dev) -{ - __ei_poll(dev); -} -EXPORT_SYMBOL(ei_poll); -#endif - -const struct net_device_ops ei_netdev_ops = { - .ndo_open = ei_open, - .ndo_stop = ei_close, - .ndo_start_xmit = ei_start_xmit, - .ndo_tx_timeout = ei_tx_timeout, - .ndo_get_stats = ei_get_stats, - .ndo_set_rx_mode = ei_set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = ei_poll, -#endif -}; -EXPORT_SYMBOL(ei_netdev_ops); - -struct net_device *__alloc_ei_netdev(int size) -{ - struct net_device *dev = ____alloc_ei_netdev(size); - if (dev) - dev->netdev_ops = &ei_netdev_ops; - return dev; -} -EXPORT_SYMBOL(__alloc_ei_netdev); - -void NS8390_init(struct net_device *dev, int startp) -{ - __NS8390_init(dev, startp); -} -EXPORT_SYMBOL(NS8390_init); - -#if defined(MODULE) - -static int __init ns8390_module_init(void) -{ - return 0; -} - -static void __exit ns8390_module_exit(void) -{ -} - -module_init(ns8390_module_init); -module_exit(ns8390_module_exit); -#endif /* MODULE */ -MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/8390/8390.h b/drivers/net/ethernet/8390/8390.h deleted file mode 100644 index e52264465998..000000000000 --- a/drivers/net/ethernet/8390/8390.h +++ /dev/null @@ -1,236 +0,0 @@ -/* Generic NS8390 register definitions. */ - -/* This file is part of Donald Becker's 8390 drivers, and is distributed - * under the same license. Auto-loading of 8390.o only in v2.2 - Paul G. - * Some of these names and comments originated from the Crynwr - * packet drivers, which are distributed under the GPL. - */ - -#ifndef _8390_h -#define _8390_h - -#include -#include -#include -#include - -#define TX_PAGES 12 /* Two Tx slots */ - -/* The 8390 specific per-packet-header format. */ -struct e8390_pkt_hdr { - unsigned char status; /* status */ - unsigned char next; /* pointer to next packet. */ - unsigned short count; /* header + packet length in bytes */ -}; - -#ifdef CONFIG_NET_POLL_CONTROLLER -void ei_poll(struct net_device *dev); -void eip_poll(struct net_device *dev); -#endif - - -/* Without I/O delay - non ISA or later chips */ -void NS8390_init(struct net_device *dev, int startp); -int ei_open(struct net_device *dev); -int ei_close(struct net_device *dev); -irqreturn_t ei_interrupt(int irq, void *dev_id); -void ei_tx_timeout(struct net_device *dev, unsigned int txqueue); -netdev_tx_t ei_start_xmit(struct sk_buff *skb, struct net_device *dev); -void ei_set_multicast_list(struct net_device *dev); -struct net_device_stats *ei_get_stats(struct net_device *dev); - -extern const struct net_device_ops ei_netdev_ops; - -struct net_device *__alloc_ei_netdev(int size); -static inline struct net_device *alloc_ei_netdev(void) -{ - return __alloc_ei_netdev(0); -} - -/* With I/O delay form */ -void NS8390p_init(struct net_device *dev, int startp); -int eip_open(struct net_device *dev); -int eip_close(struct net_device *dev); -irqreturn_t eip_interrupt(int irq, void *dev_id); -void eip_tx_timeout(struct net_device *dev, unsigned int txqueue); -netdev_tx_t eip_start_xmit(struct sk_buff *skb, struct net_device *dev); -void eip_set_multicast_list(struct net_device *dev); -struct net_device_stats *eip_get_stats(struct net_device *dev); - -extern const struct net_device_ops eip_netdev_ops; - -struct net_device *__alloc_eip_netdev(int size); -static inline struct net_device *alloc_eip_netdev(void) -{ - return __alloc_eip_netdev(0); -} - -/* You have one of these per-board */ -struct ei_device { - const char *name; - void (*reset_8390)(struct net_device *dev); - void (*get_8390_hdr)(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page); - void (*block_output)(struct net_device *dev, int count, - const unsigned char *buf, int start_page); - void (*block_input)(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); - unsigned long rmem_start; - unsigned long rmem_end; - void __iomem *mem; - unsigned char mcfilter[8]; - unsigned open:1; - unsigned word16:1; /* We have the 16-bit (vs 8-bit) - * version of the card. - */ - unsigned bigendian:1; /* 16-bit big endian mode. Do NOT - * set this on random 8390 clones! - */ - unsigned txing:1; /* Transmit Active */ - unsigned irqlock:1; /* 8390's intrs disabled when '1'. */ - unsigned dmaing:1; /* Remote DMA Active */ - unsigned char tx_start_page, rx_start_page, stop_page; - unsigned char current_page; /* Read pointer in buffer */ - unsigned char interface_num; /* Net port (AUI, 10bT.) to use. */ - unsigned char txqueue; /* Tx Packet buffer queue length. */ - short tx1, tx2; /* Packet lengths for ping-pong tx. */ - short lasttx; /* Alpha version consistency check. */ - unsigned char reg0; /* Register '0' in a WD8013 */ - unsigned char reg5; /* Register '5' in a WD8013 */ - unsigned char saved_irq; /* Original dev->irq value. */ - u32 *reg_offset; /* Register mapping table */ - spinlock_t page_lock; /* Page register locks */ - unsigned long priv; /* Private field to store bus IDs etc. */ - u32 msg_enable; /* debug message level */ -#ifdef AX88796_PLATFORM - unsigned char rxcr_base; /* default value for RXCR */ -#endif -}; - -/* The maximum number of 8390 interrupt service routines called per IRQ. */ -#define MAX_SERVICE 12 - -/* The maximum time waited (in jiffies) before assuming a Tx failed. (20ms) */ -#define TX_TIMEOUT (20*HZ/100) - -#define ei_status (*(struct ei_device *)netdev_priv(dev)) - -/* Some generic ethernet register configurations. */ -#define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */ -#define E8390_RX_IRQ_MASK 0x5 - -#ifdef AX88796_PLATFORM -#define E8390_RXCONFIG (ei_status.rxcr_base | 0x04) -#define E8390_RXOFF (ei_status.rxcr_base | 0x20) -#else -/* EN0_RXCR: broadcasts, no multicast,errors */ -#define E8390_RXCONFIG 0x4 -/* EN0_RXCR: Accept no packets */ -#define E8390_RXOFF 0x20 -#endif - -/* EN0_TXCR: Normal transmit mode */ -#define E8390_TXCONFIG 0x00 -/* EN0_TXCR: Transmitter off */ -#define E8390_TXOFF 0x02 - - -/* Register accessed at EN_CMD, the 8390 base addr. */ -#define E8390_STOP 0x01 /* Stop and reset the chip */ -#define E8390_START 0x02 /* Start the chip, clear reset */ -#define E8390_TRANS 0x04 /* Transmit a frame */ -#define E8390_RREAD 0x08 /* Remote read */ -#define E8390_RWRITE 0x10 /* Remote write */ -#define E8390_NODMA 0x20 /* Remote DMA */ -#define E8390_PAGE0 0x00 /* Select page chip registers */ -#define E8390_PAGE1 0x40 /* using the two high-order bits */ -#define E8390_PAGE2 0x80 /* Page 3 is invalid. */ - -/* Only generate indirect loads given a machine that needs them. - * - removed AMIGA_PCMCIA from this list, handled as ISA io now - * - the _p for generates no delay by default 8390p.c overrides this. - */ - -#ifndef ei_inb -#define ei_inb(_p) inb(_p) -#define ei_outb(_v, _p) outb(_v, _p) -#define ei_inb_p(_p) inb(_p) -#define ei_outb_p(_v, _p) outb(_v, _p) -#endif - -#ifndef EI_SHIFT -#define EI_SHIFT(x) (x) -#endif - -#define E8390_CMD EI_SHIFT(0x00) /* The command register (for all pages) */ -/* Page 0 register offsets. */ -#define EN0_CLDALO EI_SHIFT(0x01) /* Low byte of current local dma addr RD */ -#define EN0_STARTPG EI_SHIFT(0x01) /* Starting page of ring bfr WR */ -#define EN0_CLDAHI EI_SHIFT(0x02) /* High byte of current local dma addr RD */ -#define EN0_STOPPG EI_SHIFT(0x02) /* Ending page +1 of ring bfr WR */ -#define EN0_BOUNDARY EI_SHIFT(0x03) /* Boundary page of ring bfr RD WR */ -#define EN0_TSR EI_SHIFT(0x04) /* Transmit status reg RD */ -#define EN0_TPSR EI_SHIFT(0x04) /* Transmit starting page WR */ -#define EN0_NCR EI_SHIFT(0x05) /* Number of collision reg RD */ -#define EN0_TCNTLO EI_SHIFT(0x05) /* Low byte of tx byte count WR */ -#define EN0_FIFO EI_SHIFT(0x06) /* FIFO RD */ -#define EN0_TCNTHI EI_SHIFT(0x06) /* High byte of tx byte count WR */ -#define EN0_ISR EI_SHIFT(0x07) /* Interrupt status reg RD WR */ -#define EN0_CRDALO EI_SHIFT(0x08) /* low byte of current remote dma address RD */ -#define EN0_RSARLO EI_SHIFT(0x08) /* Remote start address reg 0 */ -#define EN0_CRDAHI EI_SHIFT(0x09) /* high byte, current remote dma address RD */ -#define EN0_RSARHI EI_SHIFT(0x09) /* Remote start address reg 1 */ -#define EN0_RCNTLO EI_SHIFT(0x0a) /* Remote byte count reg WR */ -#define EN0_RCNTHI EI_SHIFT(0x0b) /* Remote byte count reg WR */ -#define EN0_RSR EI_SHIFT(0x0c) /* rx status reg RD */ -#define EN0_RXCR EI_SHIFT(0x0c) /* RX configuration reg WR */ -#define EN0_TXCR EI_SHIFT(0x0d) /* TX configuration reg WR */ -#define EN0_COUNTER0 EI_SHIFT(0x0d) /* Rcv alignment error counter RD */ -#define EN0_DCFG EI_SHIFT(0x0e) /* Data configuration reg WR */ -#define EN0_COUNTER1 EI_SHIFT(0x0e) /* Rcv CRC error counter RD */ -#define EN0_IMR EI_SHIFT(0x0f) /* Interrupt mask reg WR */ -#define EN0_COUNTER2 EI_SHIFT(0x0f) /* Rcv missed frame error counter RD */ - -/* Bits in EN0_ISR - Interrupt status register */ -#define ENISR_RX 0x01 /* Receiver, no error */ -#define ENISR_TX 0x02 /* Transmitter, no error */ -#define ENISR_RX_ERR 0x04 /* Receiver, with error */ -#define ENISR_TX_ERR 0x08 /* Transmitter, with error */ -#define ENISR_OVER 0x10 /* Receiver overwrote the ring */ -#define ENISR_COUNTERS 0x20 /* Counters need emptying */ -#define ENISR_RDC 0x40 /* remote dma complete */ -#define ENISR_RESET 0x80 /* Reset completed */ -#define ENISR_ALL 0x3f /* Interrupts we will enable */ - -/* Bits in EN0_DCFG - Data config register */ -#define ENDCFG_WTS 0x01 /* word transfer mode selection */ -#define ENDCFG_BOS 0x02 /* byte order selection */ - -/* Page 1 register offsets. */ -#define EN1_PHYS EI_SHIFT(0x01) /* This board's physical enet addr RD WR */ -#define EN1_PHYS_SHIFT(i) EI_SHIFT(i+1) /* Get and set mac address */ -#define EN1_CURPAG EI_SHIFT(0x07) /* Current memory page RD WR */ -#define EN1_MULT EI_SHIFT(0x08) /* Multicast filter mask array (8 bytes) RD WR */ -#define EN1_MULT_SHIFT(i) EI_SHIFT(8+i) /* Get and set multicast filter */ - -/* Bits in received packet status byte and EN0_RSR*/ -#define ENRSR_RXOK 0x01 /* Received a good packet */ -#define ENRSR_CRC 0x02 /* CRC error */ -#define ENRSR_FAE 0x04 /* frame alignment error */ -#define ENRSR_FO 0x08 /* FIFO overrun */ -#define ENRSR_MPA 0x10 /* missed pkt */ -#define ENRSR_PHY 0x20 /* physical/multicast address */ -#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */ -#define ENRSR_DEF 0x80 /* deferring */ - -/* Transmitted packet status, EN0_TSR. */ -#define ENTSR_PTX 0x01 /* Packet transmitted without error */ -#define ENTSR_ND 0x02 /* The transmit wasn't deferred. */ -#define ENTSR_COL 0x04 /* The transmit collided at least once. */ -#define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */ -#define ENTSR_CRS 0x10 /* The carrier sense was lost. */ -#define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */ -#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */ -#define ENTSR_OWC 0x80 /* There was an out-of-window collision. */ - -#endif /* _8390_h */ diff --git a/drivers/net/ethernet/8390/8390p.c b/drivers/net/ethernet/8390/8390p.c deleted file mode 100644 index 6834742057b3..000000000000 --- a/drivers/net/ethernet/8390/8390p.c +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* 8390 core for ISA devices needing bus delays */ - -static const char version[] = - "8390p.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; - -#define ei_inb(_p) inb(_p) -#define ei_outb(_v, _p) outb(_v, _p) -#define ei_inb_p(_p) inb_p(_p) -#define ei_outb_p(_v, _p) outb_p(_v, _p) - -#include "lib8390.c" - -int eip_open(struct net_device *dev) -{ - return __ei_open(dev); -} -EXPORT_SYMBOL(eip_open); - -int eip_close(struct net_device *dev) -{ - return __ei_close(dev); -} -EXPORT_SYMBOL(eip_close); - -netdev_tx_t eip_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - return __ei_start_xmit(skb, dev); -} -EXPORT_SYMBOL(eip_start_xmit); - -struct net_device_stats *eip_get_stats(struct net_device *dev) -{ - return __ei_get_stats(dev); -} -EXPORT_SYMBOL(eip_get_stats); - -void eip_set_multicast_list(struct net_device *dev) -{ - __ei_set_multicast_list(dev); -} -EXPORT_SYMBOL(eip_set_multicast_list); - -void eip_tx_timeout(struct net_device *dev, unsigned int txqueue) -{ - __ei_tx_timeout(dev, txqueue); -} -EXPORT_SYMBOL(eip_tx_timeout); - -irqreturn_t eip_interrupt(int irq, void *dev_id) -{ - return __ei_interrupt(irq, dev_id); -} -EXPORT_SYMBOL(eip_interrupt); - -#ifdef CONFIG_NET_POLL_CONTROLLER -void eip_poll(struct net_device *dev) -{ - __ei_poll(dev); -} -EXPORT_SYMBOL(eip_poll); -#endif - -const struct net_device_ops eip_netdev_ops = { - .ndo_open = eip_open, - .ndo_stop = eip_close, - .ndo_start_xmit = eip_start_xmit, - .ndo_tx_timeout = eip_tx_timeout, - .ndo_get_stats = eip_get_stats, - .ndo_set_rx_mode = eip_set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = eip_poll, -#endif -}; -EXPORT_SYMBOL(eip_netdev_ops); - -struct net_device *__alloc_eip_netdev(int size) -{ - struct net_device *dev = ____alloc_ei_netdev(size); - if (dev) - dev->netdev_ops = &eip_netdev_ops; - return dev; -} -EXPORT_SYMBOL(__alloc_eip_netdev); - -void NS8390p_init(struct net_device *dev, int startp) -{ - __NS8390_init(dev, startp); -} -EXPORT_SYMBOL(NS8390p_init); - -static int __init NS8390p_init_module(void) -{ - return 0; -} - -static void __exit NS8390p_cleanup_module(void) -{ -} - -module_init(NS8390p_init_module); -module_exit(NS8390p_cleanup_module); -MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig deleted file mode 100644 index a4130e643342..000000000000 --- a/drivers/net/ethernet/8390/Kconfig +++ /dev/null @@ -1,212 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# 8390 device configuration -# - -config NET_VENDOR_8390 - bool "National Semiconductor 8390 devices" - default y - depends on NET_VENDOR_NATSEMI - help - If you have a network (Ethernet) card belonging to this class, say Y. - - Note that the answer to this question doesn't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about National Semiconductor 8390 cards. If you say Y, - you will be asked for your specific card in the following questions. - -if NET_VENDOR_8390 - -config PCMCIA_AXNET - tristate "Asix AX88190 PCMCIA support" - depends on PCMCIA - help - Say Y here if you intend to attach an Asix AX88190-based PCMCIA - (PC-card) Fast Ethernet card to your computer. These cards are - nearly NE2000 compatible but need a separate driver due to a few - misfeatures. - - To compile this driver as a module, choose M here: the module will be - called axnet_cs. If unsure, say N. - -config AX88796 - tristate "ASIX AX88796 NE2000 clone support" if !ZORRO - depends on (ARM || MIPS || SUPERH || ZORRO || COMPILE_TEST) - select CRC32 - select PHYLIB - select MDIO_BITBANG - help - AX88796 driver, using platform bus to provide - chip detection and resources - -config AX88796_93CX6 - bool "ASIX AX88796 external 93CX6 eeprom support" - depends on AX88796 - select EEPROM_93CX6 - help - Select this if your platform comes with an external 93CX6 eeprom. - -config XSURF100 - tristate "Amiga XSurf 100 AX88796/NE2000 clone support" - depends on ZORRO - select AX88796 - select AX88796B_PHY - help - This driver is for the Individual Computers X-Surf 100 Ethernet - card (based on the Asix AX88796 chip). If you have such a card, - say Y. Otherwise, say N. - - To compile this driver as a module, choose M here: the module - will be called xsurf100. - -config HYDRA - tristate "Hydra support" - depends on ZORRO - select CRC32 - help - If you have a Hydra Ethernet adapter, say Y. Otherwise, say N. - - To compile this driver as a module, choose M here: the module - will be called hydra. - -config ARM_ETHERH - tristate "I-cubed EtherH/ANT EtherM support" - depends on ARM && ARCH_ACORN - select CRC32 - help - If you have an Acorn system with one of these network cards, you - should say Y to this option if you wish to use it with Linux. - -config MAC8390 - tristate "Macintosh NS 8390 based ethernet cards" - depends on MAC - select CRC32 - help - If you want to include a driver to support Nubus or LC-PDS - Ethernet cards using an NS8390 chipset or its equivalent, say Y. - -config MCF8390 - tristate "ColdFire NS8390 based Ethernet support" - depends on COLDFIRE - select CRC32 - help - This driver is for Ethernet devices using an NS8390-compatible - chipset on many common ColdFire CPU based boards. Many of the older - Freescale dev boards use this, and some other common boards like - some SnapGear routers do as well. - - If you have one of these boards and want to use the network interface - on them then choose Y. To compile this driver as a module, choose M - here, the module will be called mcf8390. - -config NE2000 - tristate "NE2000/NE1000 support" - depends on (ISA || (Q40 && m) || MACH_TX49XX || ATARI_ETHERNEC) - select NETDEV_LEGACY_INIT if ISA - select CRC32 - help - If you have a network (Ethernet) card of this type, say Y here. - Many Ethernet cards without a specific driver are compatible with - the NE2000. - - If you have a PCI NE2000 card however, say N here and Y to "PCI - NE2000 and clone support" below. - - To compile this driver as a module, choose M here. The module - will be called ne. - -config NE2K_PCI - tristate "PCI NE2000 and clones support (see help)" - depends on PCI - select CRC32 - help - This driver is for NE2000 compatible PCI cards. It will not work - with ISA NE2000 cards (they have their own driver, "NE2000/NE1000 - support" below). If you have a PCI NE2000 network (Ethernet) card, - say Y here. - - This driver also works for the following NE2000 clone cards: - RealTek RTL-8029 Winbond 89C940 Compex RL2000 KTI ET32P2 - NetVin NV5000SC Via 86C926 SureCom NE34 Winbond - Holtek HT80232 Holtek HT80229 - - To compile this driver as a module, choose M here. The module - will be called ne2k-pci. - -config APNE - tristate "PCMCIA NE2000 support" - depends on AMIGA_PCMCIA - select CRC32 - help - If you have a PCMCIA NE2000 compatible adapter, say Y. Otherwise, - say N. - - To compile this driver as a module, choose M here: the module - will be called apne. - -config PCMCIA_PCNET - tristate "NE2000 compatible PCMCIA support" - depends on PCMCIA - select CRC32 - help - Say Y here if you intend to attach an NE2000 compatible PCMCIA - (PC-card) Ethernet or Fast Ethernet card to your computer. - - To compile this driver as a module, choose M here: the module will be - called pcnet_cs. If unsure, say N. - -config STNIC - tristate "National DP83902AV support" - depends on SUPERH - select CRC32 - help - Support for cards based on the National Semiconductor DP83902AV - ST-NIC Serial Network Interface Controller for Twisted Pair. This - is a 10Mbit/sec Ethernet controller. Product overview and specs at - . - - If unsure, say N. - -config ULTRA - tristate "SMC Ultra support" - depends on ISA - select NETDEV_LEGACY_INIT - select CRC32 - help - If you have a network (Ethernet) card of this type, say Y here. - - Important: There have been many reports that, with some motherboards - mixing an SMC Ultra and an Adaptec AHA154x SCSI card (or compatible, - such as some BusLogic models) causes corruption problems with many - operating systems. The Linux smc-ultra driver has a work-around for - this but keep it in mind if you have such a SCSI card and have - problems. - - To compile this driver as a module, choose M here. The module - will be called smc-ultra. - -config WD80x3 - tristate "WD80*3 support" - depends on ISA - select NETDEV_LEGACY_INIT - select CRC32 - help - If you have a network (Ethernet) card of this type, say Y here. - - To compile this driver as a module, choose M here. The module - will be called wd. - -config ZORRO8390 - tristate "Zorro NS8390-based Ethernet support" - depends on ZORRO - select CRC32 - help - This driver is for Zorro Ethernet cards using an NS8390-compatible - chipset, like the Village Tronic Ariadne II and the Individual - Computers X-Surf Ethernet cards. If you have such a card, say Y. - Otherwise, say N. - - To compile this driver as a module, choose M here: the module - will be called zorro8390. - -endif # NET_VENDOR_8390 diff --git a/drivers/net/ethernet/8390/Makefile b/drivers/net/ethernet/8390/Makefile deleted file mode 100644 index 85c83c566ec6..000000000000 --- a/drivers/net/ethernet/8390/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile for the 8390 network device drivers. -# - -obj-$(CONFIG_MAC8390) += mac8390.o -obj-$(CONFIG_APNE) += apne.o 8390.o -obj-$(CONFIG_ARM_ETHERH) += etherh.o -obj-$(CONFIG_AX88796) += ax88796.o -obj-$(CONFIG_HYDRA) += hydra.o -obj-$(CONFIG_MCF8390) += mcf8390.o -obj-$(CONFIG_NE2000) += ne.o 8390p.o -obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o -obj-$(CONFIG_PCMCIA_AXNET) += axnet_cs.o 8390.o -obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o 8390.o -obj-$(CONFIG_STNIC) += stnic.o 8390.o -obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o -obj-$(CONFIG_WD80x3) += wd.o 8390.o -obj-$(CONFIG_XSURF100) += xsurf100.o -obj-$(CONFIG_ZORRO8390) += zorro8390.o diff --git a/drivers/net/ethernet/8390/apne.c b/drivers/net/ethernet/8390/apne.c deleted file mode 100644 index da1ae37a9d73..000000000000 --- a/drivers/net/ethernet/8390/apne.c +++ /dev/null @@ -1,619 +0,0 @@ -/* - * Amiga Linux/68k 8390 based PCMCIA Ethernet Driver for the Amiga 1200 - * - * (C) Copyright 1997 Alain Malek - * (Alain.Malek@cryogen.com) - * - * ---------------------------------------------------------------------------- - * - * This program is based on - * - * ne.c: A general non-shared-memory NS8390 ethernet driver for linux - * Written 1992-94 by Donald Becker. - * - * 8390.c: A general NS8390 ethernet driver core for linux. - * Written 1992-94 by Donald Becker. - * - * cnetdevice: A Sana-II ethernet driver for AmigaOS - * Written by Bruce Abbott (bhabbott@inhb.co.nz) - * - * ---------------------------------------------------------------------------- - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - * - * ---------------------------------------------------------------------------- - * - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "8390.h" - -/* ---- No user-serviceable parts below ---- */ - -#define DRV_NAME "apne" - -#define NE_BASE (dev->base_addr) -#define NE_CMD 0x00 -#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ -#define NE_RESET 0x1f /* Issue a read to reset, a write to clear. */ -#define NE_IO_EXTENT 0x20 - -#define NE_EN0_ISR 0x07 -#define NE_EN0_DCFG 0x0e - -#define NE_EN0_RSARLO 0x08 -#define NE_EN0_RSARHI 0x09 -#define NE_EN0_RCNTLO 0x0a -#define NE_EN0_RXCR 0x0c -#define NE_EN0_TXCR 0x0d -#define NE_EN0_RCNTHI 0x0b -#define NE_EN0_IMR 0x0f - -#define NE1SM_START_PG 0x20 /* First page of TX buffer */ -#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ -#define NESM_START_PG 0x40 /* First page of TX buffer */ -#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ - - -static int apne_probe1(struct net_device *dev, int ioaddr); - -static void apne_reset_8390(struct net_device *dev); -static void apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, - int ring_page); -static void apne_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void apne_block_output(struct net_device *dev, const int count, - const unsigned char *buf, const int start_page); -static irqreturn_t apne_interrupt(int irq, void *dev_id); - -static int init_pcmcia(void); - -/* IO base address used for nic */ - -#define IOBASE 0x300 - -/* - use MANUAL_CONFIG and MANUAL_OFFSET for enabling IO by hand - you can find the values to use by looking at the cnet.device - config file example (the default values are for the CNET40BC card) -*/ - -/* -#define MANUAL_CONFIG 0x20 -#define MANUAL_OFFSET 0x3f8 - -#define MANUAL_HWADDR0 0x00 -#define MANUAL_HWADDR1 0x12 -#define MANUAL_HWADDR2 0x34 -#define MANUAL_HWADDR3 0x56 -#define MANUAL_HWADDR4 0x78 -#define MANUAL_HWADDR5 0x9a -*/ - -static const char version[] = - "apne.c:v1.1 7/10/98 Alain Malek (Alain.Malek@cryogen.ch)\n"; - -static int apne_owned; /* signal if card already owned */ - -static u32 apne_msg_enable; -module_param_named(msg_enable, apne_msg_enable, uint, 0444); -MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)"); - -static struct net_device * __init apne_probe(void) -{ - struct net_device *dev; - struct ei_device *ei_local; - -#ifndef MANUAL_CONFIG - char tuple[8]; -#endif - int err; - - if (!MACH_IS_AMIGA) - return ERR_PTR(-ENODEV); - - if (apne_owned) - return ERR_PTR(-ENODEV); - - if ( !(AMIGAHW_PRESENT(PCMCIA)) ) - return ERR_PTR(-ENODEV); - - pr_info("Looking for PCMCIA ethernet card : "); - - /* check if a card is inserted */ - if (!(PCMCIA_INSERTED)) { - pr_cont("NO PCMCIA card inserted\n"); - return ERR_PTR(-ENODEV); - } - - dev = alloc_ei_netdev(); - if (!dev) - return ERR_PTR(-ENOMEM); - ei_local = netdev_priv(dev); - ei_local->msg_enable = apne_msg_enable; - - /* disable pcmcia irq for readtuple */ - pcmcia_disable_irq(); - -#ifndef MANUAL_CONFIG - if ((pcmcia_copy_tuple(CISTPL_FUNCID, tuple, 8) < 3) || - (tuple[2] != CISTPL_FUNCID_NETWORK)) { - pr_cont("not an ethernet card\n"); - /* XXX: shouldn't we re-enable irq here? */ - free_netdev(dev); - return ERR_PTR(-ENODEV); - } -#endif - - pr_cont("ethernet PCMCIA card inserted\n"); - - if (!init_pcmcia()) { - /* XXX: shouldn't we re-enable irq here? */ - free_netdev(dev); - return ERR_PTR(-ENODEV); - } - - if (!request_region(IOBASE, 0x20, DRV_NAME)) { - free_netdev(dev); - return ERR_PTR(-EBUSY); - } - - err = apne_probe1(dev, IOBASE); - if (err) { - release_region(IOBASE, 0x20); - free_netdev(dev); - return ERR_PTR(err); - } - err = register_netdev(dev); - if (!err) - return dev; - - pcmcia_disable_irq(); - free_irq(IRQ_AMIGA_PORTS, dev); - pcmcia_reset(); - release_region(IOBASE, 0x20); - free_netdev(dev); - return ERR_PTR(err); -} - -static int __init apne_probe1(struct net_device *dev, int ioaddr) -{ - int i; - unsigned char SA_prom[32]; - int wordlength = 2; - const char *name = NULL; - int start_page, stop_page; -#ifndef MANUAL_HWADDR0 - int neX000, ctron; -#endif - static unsigned version_printed; - - if ((apne_msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0)) - netdev_info(dev, version); - - netdev_info(dev, "PCMCIA NE*000 ethercard probe"); - - /* Reset card. Who knows what dain-bramaged state it was left in. */ - { unsigned long reset_start_time = jiffies; - - outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); - - while ((inb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { - pr_cont(" not found (no reset ack).\n"); - return -ENODEV; - } - - outb(0xff, ioaddr + NE_EN0_ISR); /* Ack all intr. */ - } - -#ifndef MANUAL_HWADDR0 - - /* Read the 16 bytes of station address PROM. - We must first initialize registers, similar to NS8390_init(eifdev, 0). - We can't reliably read the SAPROM address without this. - (I learned the hard way!). */ - { - struct {unsigned long value, offset; } program_seq[] = { - {E8390_NODMA+E8390_PAGE0+E8390_STOP, NE_CMD}, /* Select page 0*/ - {0x48, NE_EN0_DCFG}, /* Set byte-wide (0x48) access. */ - {0x00, NE_EN0_RCNTLO}, /* Clear the count regs. */ - {0x00, NE_EN0_RCNTHI}, - {0x00, NE_EN0_IMR}, /* Mask completion irq. */ - {0xFF, NE_EN0_ISR}, - {E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */ - {E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode. */ - {32, NE_EN0_RCNTLO}, - {0x00, NE_EN0_RCNTHI}, - {0x00, NE_EN0_RSARLO}, /* DMA starting at 0x0000. */ - {0x00, NE_EN0_RSARHI}, - {E8390_RREAD+E8390_START, NE_CMD}, - }; - for (i = 0; i < ARRAY_SIZE(program_seq); i++) { - outb(program_seq[i].value, ioaddr + program_seq[i].offset); - } - - } - for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) { - SA_prom[i] = inb(ioaddr + NE_DATAPORT); - SA_prom[i+1] = inb(ioaddr + NE_DATAPORT); - if (SA_prom[i] != SA_prom[i+1]) - wordlength = 1; - } - - /* At this point, wordlength *only* tells us if the SA_prom is doubled - up or not because some broken PCI cards don't respect the byte-wide - request in program_seq above, and hence don't have doubled up values. - These broken cards would otherwise be detected as an ne1000. */ - - if (wordlength == 2) - for (i = 0; i < 16; i++) - SA_prom[i] = SA_prom[i+i]; - - if (wordlength == 2) { - /* We must set the 8390 for word mode. */ - outb(0x49, ioaddr + NE_EN0_DCFG); - start_page = NESM_START_PG; - stop_page = NESM_STOP_PG; - } else { - start_page = NE1SM_START_PG; - stop_page = NE1SM_STOP_PG; - } - - neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57); - ctron = (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d); - - /* Set up the rest of the parameters. */ - if (neX000) { - name = (wordlength == 2) ? "NE2000" : "NE1000"; - } else if (ctron) { - name = (wordlength == 2) ? "Ctron-8" : "Ctron-16"; - start_page = 0x01; - stop_page = (wordlength == 2) ? 0x40 : 0x20; - } else { - pr_cont(" not found.\n"); - return -ENXIO; - - } - -#else - wordlength = 2; - /* We must set the 8390 for word mode. */ - outb(0x49, ioaddr + NE_EN0_DCFG); - start_page = NESM_START_PG; - stop_page = NESM_STOP_PG; - - SA_prom[0] = MANUAL_HWADDR0; - SA_prom[1] = MANUAL_HWADDR1; - SA_prom[2] = MANUAL_HWADDR2; - SA_prom[3] = MANUAL_HWADDR3; - SA_prom[4] = MANUAL_HWADDR4; - SA_prom[5] = MANUAL_HWADDR5; - name = "NE2000"; -#endif - - dev->base_addr = ioaddr; - dev->irq = IRQ_AMIGA_PORTS; - dev->netdev_ops = &ei_netdev_ops; - - /* Install the Interrupt handler */ - i = request_irq(dev->irq, apne_interrupt, IRQF_SHARED, DRV_NAME, dev); - if (i) return i; - - for (i = 0; i < ETH_ALEN; i++) - dev->dev_addr[i] = SA_prom[i]; - - pr_cont(" %pM\n", dev->dev_addr); - - netdev_info(dev, "%s found.\n", name); - - ei_status.name = name; - ei_status.tx_start_page = start_page; - ei_status.stop_page = stop_page; - ei_status.word16 = (wordlength == 2); - - ei_status.rx_start_page = start_page + TX_PAGES; - - ei_status.reset_8390 = &apne_reset_8390; - ei_status.block_input = &apne_block_input; - ei_status.block_output = &apne_block_output; - ei_status.get_8390_hdr = &apne_get_8390_hdr; - - NS8390_init(dev, 0); - - pcmcia_ack_int(pcmcia_get_intreq()); /* ack PCMCIA int req */ - pcmcia_enable_irq(); - - apne_owned = 1; - - return 0; -} - -/* Hard reset the card. This used to pause for the same period that a - 8390 reset command required, but that shouldn't be necessary. */ -static void -apne_reset_8390(struct net_device *dev) -{ - unsigned long reset_start_time = jiffies; - struct ei_device *ei_local = netdev_priv(dev); - - init_pcmcia(); - - netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies); - - outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); - - ei_status.txing = 0; - ei_status.dmaing = 0; - - /* This check _should_not_ be necessary, omit eventually. */ - while ((inb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { - netdev_err(dev, "ne_reset_8390() did not complete.\n"); - break; - } - outb(ENISR_RESET, NE_BASE + NE_EN0_ISR); /* Ack intr. */ -} - -/* Grab the 8390 specific header. Similar to the block_input routine, but - we don't need to be concerned with ring wrap as the header will be at - the start of a page, so we optimize accordingly. */ - -static void -apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) -{ - - int nic_base = dev->base_addr; - int cnt; - char *ptrc; - short *ptrs; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) { - netdev_err(dev, "DMAing conflict in ne_get_8390_hdr " - "[DMAstat:%d][irqlock:%d][intr:%d].\n", - ei_status.dmaing, ei_status.irqlock, dev->irq); - return; - } - - ei_status.dmaing |= 0x01; - outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); - outb(ENISR_RDC, nic_base + NE_EN0_ISR); - outb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO); - outb(0, nic_base + NE_EN0_RCNTHI); - outb(0, nic_base + NE_EN0_RSARLO); /* On page boundary */ - outb(ring_page, nic_base + NE_EN0_RSARHI); - outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); - - if (ei_status.word16) { - ptrs = (short*)hdr; - for(cnt = 0; cnt < (sizeof(struct e8390_pkt_hdr)>>1); cnt++) - *ptrs++ = inw(NE_BASE + NE_DATAPORT); - } else { - ptrc = (char*)hdr; - for(cnt = 0; cnt < sizeof(struct e8390_pkt_hdr); cnt++) - *ptrc++ = inb(NE_BASE + NE_DATAPORT); - } - - outb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; - - le16_to_cpus(&hdr->count); -} - -/* Block input and output, similar to the Crynwr packet driver. If you - are porting to a new ethercard, look at the packet driver source for hints. - The NEx000 doesn't share the on-board packet memory -- you have to put - the packet out through the "remote DMA" dataport using outb. */ - -static void -apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) -{ - int nic_base = dev->base_addr; - char *buf = skb->data; - char *ptrc; - short *ptrs; - int cnt; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) { - netdev_err(dev, "DMAing conflict in ne_block_input " - "[DMAstat:%d][irqlock:%d][intr:%d].\n", - ei_status.dmaing, ei_status.irqlock, dev->irq); - return; - } - ei_status.dmaing |= 0x01; - outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); - outb(ENISR_RDC, nic_base + NE_EN0_ISR); - outb(count & 0xff, nic_base + NE_EN0_RCNTLO); - outb(count >> 8, nic_base + NE_EN0_RCNTHI); - outb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO); - outb(ring_offset >> 8, nic_base + NE_EN0_RSARHI); - outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) { - ptrs = (short*)buf; - for (cnt = 0; cnt < (count>>1); cnt++) - *ptrs++ = inw(NE_BASE + NE_DATAPORT); - if (count & 0x01) { - buf[count-1] = inb(NE_BASE + NE_DATAPORT); - } - } else { - ptrc = buf; - for (cnt = 0; cnt < count; cnt++) - *ptrc++ = inb(NE_BASE + NE_DATAPORT); - } - - outb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; -} - -static void -apne_block_output(struct net_device *dev, int count, - const unsigned char *buf, const int start_page) -{ - int nic_base = NE_BASE; - unsigned long dma_start; - char *ptrc; - short *ptrs; - int cnt; - - /* Round the count up for word writes. Do we need to do this? - What effect will an odd byte count have on the 8390? - I should check someday. */ - if (ei_status.word16 && (count & 0x01)) - count++; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) { - netdev_err(dev, "DMAing conflict in ne_block_output." - "[DMAstat:%d][irqlock:%d][intr:%d]\n", - ei_status.dmaing, ei_status.irqlock, dev->irq); - return; - } - ei_status.dmaing |= 0x01; - /* We should already be in page 0, but to be safe... */ - outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); - - outb(ENISR_RDC, nic_base + NE_EN0_ISR); - - /* Now the normal output. */ - outb(count & 0xff, nic_base + NE_EN0_RCNTLO); - outb(count >> 8, nic_base + NE_EN0_RCNTHI); - outb(0x00, nic_base + NE_EN0_RSARLO); - outb(start_page, nic_base + NE_EN0_RSARHI); - - outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) { - ptrs = (short*)buf; - for (cnt = 0; cnt < count>>1; cnt++) - outw(*ptrs++, NE_BASE+NE_DATAPORT); - } else { - ptrc = (char*)buf; - for (cnt = 0; cnt < count; cnt++) - outb(*ptrc++, NE_BASE + NE_DATAPORT); - } - - dma_start = jiffies; - - while ((inb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ - netdev_warn(dev, "timeout waiting for Tx RDC.\n"); - apne_reset_8390(dev); - NS8390_init(dev,1); - break; - } - - outb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; -} - -static irqreturn_t apne_interrupt(int irq, void *dev_id) -{ - unsigned char pcmcia_intreq; - - if (!(gayle.inten & GAYLE_IRQ_IRQ)) - return IRQ_NONE; - - pcmcia_intreq = pcmcia_get_intreq(); - - if (!(pcmcia_intreq & GAYLE_IRQ_IRQ)) { - pcmcia_ack_int(pcmcia_intreq); - return IRQ_NONE; - } - if (apne_msg_enable & NETIF_MSG_INTR) - pr_debug("pcmcia intreq = %x\n", pcmcia_intreq); - pcmcia_disable_irq(); /* to get rid of the sti() within ei_interrupt */ - ei_interrupt(irq, dev_id); - pcmcia_ack_int(pcmcia_get_intreq()); - pcmcia_enable_irq(); - return IRQ_HANDLED; -} - -static struct net_device *apne_dev; - -static int __init apne_module_init(void) -{ - apne_dev = apne_probe(); - return PTR_ERR_OR_ZERO(apne_dev); -} - -static void __exit apne_module_exit(void) -{ - unregister_netdev(apne_dev); - - pcmcia_disable_irq(); - - free_irq(IRQ_AMIGA_PORTS, apne_dev); - - pcmcia_reset(); - - release_region(IOBASE, 0x20); - - free_netdev(apne_dev); -} -module_init(apne_module_init); -module_exit(apne_module_exit); - -static int init_pcmcia(void) -{ - u_char config; -#ifndef MANUAL_CONFIG - u_char tuple[32]; - int offset_len; -#endif - u_long offset; - - pcmcia_reset(); - pcmcia_program_voltage(PCMCIA_0V); - pcmcia_access_speed(PCMCIA_SPEED_250NS); - pcmcia_write_enable(); - -#ifdef MANUAL_CONFIG - config = MANUAL_CONFIG; -#else - /* get and write config byte to enable IO port */ - - if (pcmcia_copy_tuple(CISTPL_CFTABLE_ENTRY, tuple, 32) < 3) - return 0; - - config = tuple[2] & 0x3f; -#endif -#ifdef MANUAL_OFFSET - offset = MANUAL_OFFSET; -#else - if (pcmcia_copy_tuple(CISTPL_CONFIG, tuple, 32) < 6) - return 0; - - offset_len = (tuple[2] & 0x3) + 1; - offset = 0; - while(offset_len--) { - offset = (offset << 8) | tuple[4+offset_len]; - } -#endif - - out_8(GAYLE_ATTRIBUTE+offset, config); - - return 1; -} - -MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c deleted file mode 100644 index 6c6bdd5913ec..000000000000 --- a/drivers/net/ethernet/8390/ax88796.c +++ /dev/null @@ -1,1022 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* drivers/net/ethernet/8390/ax88796.c - * - * Copyright 2005,2007 Simtec Electronics - * Ben Dooks - * - * Asix AX88796 10/100 Ethernet controller support - * Based on ne.c, by Donald Becker, et-al. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - - -/* Rename the lib8390.c functions to show that they are in this driver */ -#define __ei_open ax_ei_open -#define __ei_close ax_ei_close -#define __ei_poll ax_ei_poll -#define __ei_start_xmit ax_ei_start_xmit -#define __ei_tx_timeout ax_ei_tx_timeout -#define __ei_get_stats ax_ei_get_stats -#define __ei_set_multicast_list ax_ei_set_multicast_list -#define __ei_interrupt ax_ei_interrupt -#define ____alloc_ei_netdev ax__alloc_ei_netdev -#define __NS8390_init ax_NS8390_init - -/* force unsigned long back to 'void __iomem *' */ -#define ax_convert_addr(_a) ((void __force __iomem *)(_a)) - -#define ei_inb(_a) readb(ax_convert_addr(_a)) -#define ei_outb(_v, _a) writeb(_v, ax_convert_addr(_a)) - -#define ei_inb_p(_a) ei_inb(_a) -#define ei_outb_p(_v, _a) ei_outb(_v, _a) - -/* define EI_SHIFT() to take into account our register offsets */ -#define EI_SHIFT(x) (ei_local->reg_offset[(x)]) - -/* Ensure we have our RCR base value */ -#define AX88796_PLATFORM - -static unsigned char version[] = "ax88796.c: Copyright 2005,2007 Simtec Electronics\n"; - -#include "lib8390.c" - -#define DRV_NAME "ax88796" -#define DRV_VERSION "1.00" - -/* from ne.c */ -#define NE_CMD EI_SHIFT(0x00) -#define NE_RESET EI_SHIFT(0x1f) -#define NE_DATAPORT EI_SHIFT(0x10) - -#define NE1SM_START_PG 0x20 /* First page of TX buffer */ -#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ -#define NESM_START_PG 0x40 /* First page of TX buffer */ -#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ - -#define AX_GPOC_PPDSET BIT(6) - -/* device private data */ - -struct ax_device { - struct mii_bus *mii_bus; - struct mdiobb_ctrl bb_ctrl; - void __iomem *addr_memr; - u8 reg_memr; - int link; - int speed; - int duplex; - - void __iomem *map2; - const struct ax_plat_data *plat; - - unsigned char running; - unsigned char resume_open; - unsigned int irqflags; - - u32 reg_offsets[0x20]; -}; - -static inline struct ax_device *to_ax_dev(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - return (struct ax_device *)(ei_local + 1); -} - -void ax_NS8390_reinit(struct net_device *dev) -{ - ax_NS8390_init(dev, 1); -} - -EXPORT_SYMBOL_GPL(ax_NS8390_reinit); - -/* - * ax_initial_check - * - * do an initial probe for the card to check whether it exists - * and is functional - */ -static int ax_initial_check(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - void __iomem *ioaddr = ei_local->mem; - int reg0; - int regd; - - reg0 = ei_inb(ioaddr); - if (reg0 == 0xFF) - return -ENODEV; - - ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP, ioaddr + E8390_CMD); - regd = ei_inb(ioaddr + 0x0d); - ei_outb(0xff, ioaddr + 0x0d); - ei_outb(E8390_NODMA + E8390_PAGE0, ioaddr + E8390_CMD); - ei_inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */ - if (ei_inb(ioaddr + EN0_COUNTER0) != 0) { - ei_outb(reg0, ioaddr); - ei_outb(regd, ioaddr + 0x0d); /* Restore the old values. */ - return -ENODEV; - } - - return 0; -} - -/* - * Hard reset the card. This used to pause for the same period that a - * 8390 reset command required, but that shouldn't be necessary. - */ -static void ax_reset_8390(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - unsigned long reset_start_time = jiffies; - void __iomem *addr = (void __iomem *)dev->base_addr; - - netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies); - - ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET); - - ei_local->txing = 0; - ei_local->dmaing = 0; - - /* This check _should_not_ be necessary, omit eventually. */ - while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) { - if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) { - netdev_warn(dev, "%s: did not complete.\n", __func__); - break; - } - } - - ei_outb(ENISR_RESET, addr + EN0_ISR); /* Ack intr. */ -} - -/* Wrapper for __ei_interrupt for platforms that have a platform-specific - * way to find out whether the interrupt request might be caused by - * the ax88796 chip. - */ -static irqreturn_t ax_ei_interrupt_filtered(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct ax_device *ax = to_ax_dev(dev); - struct platform_device *pdev = to_platform_device(dev->dev.parent); - - if (!ax->plat->check_irq(pdev)) - return IRQ_NONE; - - return ax_ei_interrupt(irq, dev_id); -} - -static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, - int ring_page) -{ - struct ei_device *ei_local = netdev_priv(dev); - void __iomem *nic_base = ei_local->mem; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_local->dmaing) { - netdev_err(dev, "DMAing conflict in %s " - "[DMAstat:%d][irqlock:%d].\n", - __func__, - ei_local->dmaing, ei_local->irqlock); - return; - } - - ei_local->dmaing |= 0x01; - ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); - ei_outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); - ei_outb(0, nic_base + EN0_RCNTHI); - ei_outb(0, nic_base + EN0_RSARLO); /* On page boundary */ - ei_outb(ring_page, nic_base + EN0_RSARHI); - ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); - - if (ei_local->word16) - ioread16_rep(nic_base + NE_DATAPORT, hdr, - sizeof(struct e8390_pkt_hdr) >> 1); - else - ioread8_rep(nic_base + NE_DATAPORT, hdr, - sizeof(struct e8390_pkt_hdr)); - - ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_local->dmaing &= ~0x01; - - le16_to_cpus(&hdr->count); -} - - -/* - * Block input and output, similar to the Crynwr packet driver. If - * you are porting to a new ethercard, look at the packet driver - * source for hints. The NEx000 doesn't share the on-board packet - * memory -- you have to put the packet out through the "remote DMA" - * dataport using ei_outb. - */ -static void ax_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) -{ - struct ei_device *ei_local = netdev_priv(dev); - void __iomem *nic_base = ei_local->mem; - char *buf = skb->data; - - if (ei_local->dmaing) { - netdev_err(dev, - "DMAing conflict in %s " - "[DMAstat:%d][irqlock:%d].\n", - __func__, - ei_local->dmaing, ei_local->irqlock); - return; - } - - ei_local->dmaing |= 0x01; - - ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + NE_CMD); - ei_outb(count & 0xff, nic_base + EN0_RCNTLO); - ei_outb(count >> 8, nic_base + EN0_RCNTHI); - ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO); - ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI); - ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); - - if (ei_local->word16) { - ioread16_rep(nic_base + NE_DATAPORT, buf, count >> 1); - if (count & 0x01) - buf[count-1] = ei_inb(nic_base + NE_DATAPORT); - - } else { - ioread8_rep(nic_base + NE_DATAPORT, buf, count); - } - - ei_local->dmaing &= ~1; -} - -static void ax_block_output(struct net_device *dev, int count, - const unsigned char *buf, const int start_page) -{ - struct ei_device *ei_local = netdev_priv(dev); - void __iomem *nic_base = ei_local->mem; - unsigned long dma_start; - - /* - * Round the count up for word writes. Do we need to do this? - * What effect will an odd byte count have on the 8390? I - * should check someday. - */ - if (ei_local->word16 && (count & 0x01)) - count++; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_local->dmaing) { - netdev_err(dev, "DMAing conflict in %s." - "[DMAstat:%d][irqlock:%d]\n", - __func__, - ei_local->dmaing, ei_local->irqlock); - return; - } - - ei_local->dmaing |= 0x01; - /* We should already be in page 0, but to be safe... */ - ei_outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); - - ei_outb(ENISR_RDC, nic_base + EN0_ISR); - - /* Now the normal output. */ - ei_outb(count & 0xff, nic_base + EN0_RCNTLO); - ei_outb(count >> 8, nic_base + EN0_RCNTHI); - ei_outb(0x00, nic_base + EN0_RSARLO); - ei_outb(start_page, nic_base + EN0_RSARHI); - - ei_outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); - if (ei_local->word16) - iowrite16_rep(nic_base + NE_DATAPORT, buf, count >> 1); - else - iowrite8_rep(nic_base + NE_DATAPORT, buf, count); - - dma_start = jiffies; - - while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) { - if (time_after(jiffies, dma_start + 2 * HZ / 100)) { /* 20ms */ - netdev_warn(dev, "timeout waiting for Tx RDC.\n"); - ax_reset_8390(dev); - ax_NS8390_init(dev, 1); - break; - } - } - - ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_local->dmaing &= ~0x01; -} - -/* definitions for accessing MII/EEPROM interface */ - -#define AX_MEMR EI_SHIFT(0x14) -#define AX_MEMR_MDC BIT(0) -#define AX_MEMR_MDIR BIT(1) -#define AX_MEMR_MDI BIT(2) -#define AX_MEMR_MDO BIT(3) -#define AX_MEMR_EECS BIT(4) -#define AX_MEMR_EEI BIT(5) -#define AX_MEMR_EEO BIT(6) -#define AX_MEMR_EECLK BIT(7) - -static void ax_handle_link_change(struct net_device *dev) -{ - struct ax_device *ax = to_ax_dev(dev); - struct phy_device *phy_dev = dev->phydev; - int status_change = 0; - - if (phy_dev->link && ((ax->speed != phy_dev->speed) || - (ax->duplex != phy_dev->duplex))) { - - ax->speed = phy_dev->speed; - ax->duplex = phy_dev->duplex; - status_change = 1; - } - - if (phy_dev->link != ax->link) { - if (!phy_dev->link) { - ax->speed = 0; - ax->duplex = -1; - } - ax->link = phy_dev->link; - - status_change = 1; - } - - if (status_change) - phy_print_status(phy_dev); -} - -static int ax_mii_probe(struct net_device *dev) -{ - struct ax_device *ax = to_ax_dev(dev); - struct phy_device *phy_dev = NULL; - int ret; - - /* find the first phy */ - phy_dev = phy_find_first(ax->mii_bus); - if (!phy_dev) { - netdev_err(dev, "no PHY found\n"); - return -ENODEV; - } - - ret = phy_connect_direct(dev, phy_dev, ax_handle_link_change, - PHY_INTERFACE_MODE_MII); - if (ret) { - netdev_err(dev, "Could not attach to PHY\n"); - return ret; - } - - phy_set_max_speed(phy_dev, SPEED_100); - - netdev_info(dev, "PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", - phy_dev->drv->name, phydev_name(phy_dev), phy_dev->irq); - - return 0; -} - -static void ax_phy_switch(struct net_device *dev, int on) -{ - struct ei_device *ei_local = netdev_priv(dev); - struct ax_device *ax = to_ax_dev(dev); - - u8 reg_gpoc = ax->plat->gpoc_val; - - if (!!on) - reg_gpoc &= ~AX_GPOC_PPDSET; - else - reg_gpoc |= AX_GPOC_PPDSET; - - ei_outb(reg_gpoc, ei_local->mem + EI_SHIFT(0x17)); -} - -static void ax_bb_mdc(struct mdiobb_ctrl *ctrl, int level) -{ - struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl); - - if (level) - ax->reg_memr |= AX_MEMR_MDC; - else - ax->reg_memr &= ~AX_MEMR_MDC; - - ei_outb(ax->reg_memr, ax->addr_memr); -} - -static void ax_bb_dir(struct mdiobb_ctrl *ctrl, int output) -{ - struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl); - - if (output) - ax->reg_memr &= ~AX_MEMR_MDIR; - else - ax->reg_memr |= AX_MEMR_MDIR; - - ei_outb(ax->reg_memr, ax->addr_memr); -} - -static void ax_bb_set_data(struct mdiobb_ctrl *ctrl, int value) -{ - struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl); - - if (value) - ax->reg_memr |= AX_MEMR_MDO; - else - ax->reg_memr &= ~AX_MEMR_MDO; - - ei_outb(ax->reg_memr, ax->addr_memr); -} - -static int ax_bb_get_data(struct mdiobb_ctrl *ctrl) -{ - struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl); - int reg_memr = ei_inb(ax->addr_memr); - - return reg_memr & AX_MEMR_MDI ? 1 : 0; -} - -static const struct mdiobb_ops bb_ops = { - .owner = THIS_MODULE, - .set_mdc = ax_bb_mdc, - .set_mdio_dir = ax_bb_dir, - .set_mdio_data = ax_bb_set_data, - .get_mdio_data = ax_bb_get_data, -}; - -static int ax_mii_init(struct net_device *dev) -{ - struct platform_device *pdev = to_platform_device(dev->dev.parent); - struct ei_device *ei_local = netdev_priv(dev); - struct ax_device *ax = to_ax_dev(dev); - int err; - - ax->bb_ctrl.ops = &bb_ops; - ax->addr_memr = ei_local->mem + AX_MEMR; - ax->mii_bus = alloc_mdio_bitbang(&ax->bb_ctrl); - if (!ax->mii_bus) { - err = -ENOMEM; - goto out; - } - - ax->mii_bus->name = "ax88796_mii_bus"; - ax->mii_bus->parent = dev->dev.parent; - snprintf(ax->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", - pdev->name, pdev->id); - - err = mdiobus_register(ax->mii_bus); - if (err) - goto out_free_mdio_bitbang; - - return 0; - - out_free_mdio_bitbang: - free_mdio_bitbang(ax->mii_bus); - out: - return err; -} - -static int ax_open(struct net_device *dev) -{ - struct ax_device *ax = to_ax_dev(dev); - int ret; - - netdev_dbg(dev, "open\n"); - - ret = ax_mii_init(dev); - if (ret) - goto failed_mii; - - if (ax->plat->check_irq) - ret = request_irq(dev->irq, ax_ei_interrupt_filtered, - ax->irqflags, dev->name, dev); - else - ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags, - dev->name, dev); - if (ret) - goto failed_request_irq; - - /* turn the phy on (if turned off) */ - ax_phy_switch(dev, 1); - - ret = ax_mii_probe(dev); - if (ret) - goto failed_mii_probe; - phy_start(dev->phydev); - - ret = ax_ei_open(dev); - if (ret) - goto failed_ax_ei_open; - - ax->running = 1; - - return 0; - - failed_ax_ei_open: - phy_disconnect(dev->phydev); - failed_mii_probe: - ax_phy_switch(dev, 0); - free_irq(dev->irq, dev); - failed_request_irq: - /* unregister mdiobus */ - mdiobus_unregister(ax->mii_bus); - free_mdio_bitbang(ax->mii_bus); - failed_mii: - return ret; -} - -static int ax_close(struct net_device *dev) -{ - struct ax_device *ax = to_ax_dev(dev); - - netdev_dbg(dev, "close\n"); - - ax->running = 0; - wmb(); - - ax_ei_close(dev); - - /* turn the phy off */ - ax_phy_switch(dev, 0); - phy_disconnect(dev->phydev); - - free_irq(dev->irq, dev); - - mdiobus_unregister(ax->mii_bus); - free_mdio_bitbang(ax->mii_bus); - return 0; -} - -static int ax_ioctl(struct net_device *dev, struct ifreq *req, int cmd) -{ - struct phy_device *phy_dev = dev->phydev; - - if (!netif_running(dev)) - return -EINVAL; - - if (!phy_dev) - return -ENODEV; - - return phy_mii_ioctl(phy_dev, req, cmd); -} - -/* ethtool ops */ - -static void ax_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - struct platform_device *pdev = to_platform_device(dev->dev.parent); - - strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); - strlcpy(info->version, DRV_VERSION, sizeof(info->version)); - strlcpy(info->bus_info, pdev->name, sizeof(info->bus_info)); -} - -static u32 ax_get_msglevel(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - - return ei_local->msg_enable; -} - -static void ax_set_msglevel(struct net_device *dev, u32 v) -{ - struct ei_device *ei_local = netdev_priv(dev); - - ei_local->msg_enable = v; -} - -static const struct ethtool_ops ax_ethtool_ops = { - .get_drvinfo = ax_get_drvinfo, - .get_link = ethtool_op_get_link, - .get_ts_info = ethtool_op_get_ts_info, - .get_msglevel = ax_get_msglevel, - .set_msglevel = ax_set_msglevel, - .get_link_ksettings = phy_ethtool_get_link_ksettings, - .set_link_ksettings = phy_ethtool_set_link_ksettings, -}; - -#ifdef CONFIG_AX88796_93CX6 -static void ax_eeprom_register_read(struct eeprom_93cx6 *eeprom) -{ - struct ei_device *ei_local = eeprom->data; - u8 reg = ei_inb(ei_local->mem + AX_MEMR); - - eeprom->reg_data_in = reg & AX_MEMR_EEI; - eeprom->reg_data_out = reg & AX_MEMR_EEO; /* Input pin */ - eeprom->reg_data_clock = reg & AX_MEMR_EECLK; - eeprom->reg_chip_select = reg & AX_MEMR_EECS; -} - -static void ax_eeprom_register_write(struct eeprom_93cx6 *eeprom) -{ - struct ei_device *ei_local = eeprom->data; - u8 reg = ei_inb(ei_local->mem + AX_MEMR); - - reg &= ~(AX_MEMR_EEI | AX_MEMR_EECLK | AX_MEMR_EECS); - - if (eeprom->reg_data_in) - reg |= AX_MEMR_EEI; - if (eeprom->reg_data_clock) - reg |= AX_MEMR_EECLK; - if (eeprom->reg_chip_select) - reg |= AX_MEMR_EECS; - - ei_outb(reg, ei_local->mem + AX_MEMR); - udelay(10); -} -#endif - -static const struct net_device_ops ax_netdev_ops = { - .ndo_open = ax_open, - .ndo_stop = ax_close, - .ndo_eth_ioctl = ax_ioctl, - - .ndo_start_xmit = ax_ei_start_xmit, - .ndo_tx_timeout = ax_ei_tx_timeout, - .ndo_get_stats = ax_ei_get_stats, - .ndo_set_rx_mode = ax_ei_set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = ax_ei_poll, -#endif -}; - -/* setup code */ - -static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local) -{ - void __iomem *ioaddr = ei_local->mem; - struct ax_device *ax = to_ax_dev(dev); - - /* Select page 0 */ - ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_STOP, ioaddr + E8390_CMD); - - /* set to byte access */ - ei_outb(ax->plat->dcr_val & ~1, ioaddr + EN0_DCFG); - ei_outb(ax->plat->gpoc_val, ioaddr + EI_SHIFT(0x17)); -} - -/* - * ax_init_dev - * - * initialise the specified device, taking care to note the MAC - * address it may already have (if configured), ensure - * the device is ready to be used by lib8390.c and registerd with - * the network layer. - */ -static int ax_init_dev(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - struct ax_device *ax = to_ax_dev(dev); - void __iomem *ioaddr = ei_local->mem; - unsigned int start_page; - unsigned int stop_page; - int ret; - int i; - - ret = ax_initial_check(dev); - if (ret) - goto err_out; - - /* setup goes here */ - - ax_initial_setup(dev, ei_local); - - /* read the mac from the card prom if we need it */ - - if (ax->plat->flags & AXFLG_HAS_EEPROM) { - unsigned char SA_prom[32]; - - ei_outb(6, ioaddr + EN0_RCNTLO); - ei_outb(0, ioaddr + EN0_RCNTHI); - ei_outb(0, ioaddr + EN0_RSARLO); - ei_outb(0, ioaddr + EN0_RSARHI); - ei_outb(E8390_RREAD + E8390_START, ioaddr + NE_CMD); - for (i = 0; i < sizeof(SA_prom); i += 2) { - SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT); - SA_prom[i + 1] = ei_inb(ioaddr + NE_DATAPORT); - } - ei_outb(ENISR_RDC, ioaddr + EN0_ISR); /* Ack intr. */ - - if (ax->plat->wordlength == 2) - for (i = 0; i < 16; i++) - SA_prom[i] = SA_prom[i+i]; - - memcpy(dev->dev_addr, SA_prom, ETH_ALEN); - } - -#ifdef CONFIG_AX88796_93CX6 - if (ax->plat->flags & AXFLG_HAS_93CX6) { - unsigned char mac_addr[ETH_ALEN]; - struct eeprom_93cx6 eeprom; - - eeprom.data = ei_local; - eeprom.register_read = ax_eeprom_register_read; - eeprom.register_write = ax_eeprom_register_write; - eeprom.width = PCI_EEPROM_WIDTH_93C56; - - eeprom_93cx6_multiread(&eeprom, 0, - (__le16 __force *)mac_addr, - sizeof(mac_addr) >> 1); - - memcpy(dev->dev_addr, mac_addr, ETH_ALEN); - } -#endif - if (ax->plat->wordlength == 2) { - /* We must set the 8390 for word mode. */ - ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG); - start_page = NESM_START_PG; - stop_page = NESM_STOP_PG; - } else { - start_page = NE1SM_START_PG; - stop_page = NE1SM_STOP_PG; - } - - /* load the mac-address from the device */ - if (ax->plat->flags & AXFLG_MAC_FROMDEV) { - ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP, - ei_local->mem + E8390_CMD); /* 0x61 */ - for (i = 0; i < ETH_ALEN; i++) - dev->dev_addr[i] = - ei_inb(ioaddr + EN1_PHYS_SHIFT(i)); - } - - if ((ax->plat->flags & AXFLG_MAC_FROMPLATFORM) && - ax->plat->mac_addr) - memcpy(dev->dev_addr, ax->plat->mac_addr, ETH_ALEN); - - if (!is_valid_ether_addr(dev->dev_addr)) { - eth_hw_addr_random(dev); - dev_info(&dev->dev, "Using random MAC address: %pM\n", - dev->dev_addr); - } - - ax_reset_8390(dev); - - ei_local->name = "AX88796"; - ei_local->tx_start_page = start_page; - ei_local->stop_page = stop_page; - ei_local->word16 = (ax->plat->wordlength == 2); - ei_local->rx_start_page = start_page + TX_PAGES; - -#ifdef PACKETBUF_MEMSIZE - /* Allow the packet buffer size to be overridden by know-it-alls. */ - ei_local->stop_page = ei_local->tx_start_page + PACKETBUF_MEMSIZE; -#endif - - ei_local->reset_8390 = &ax_reset_8390; - if (ax->plat->block_input) - ei_local->block_input = ax->plat->block_input; - else - ei_local->block_input = &ax_block_input; - if (ax->plat->block_output) - ei_local->block_output = ax->plat->block_output; - else - ei_local->block_output = &ax_block_output; - ei_local->get_8390_hdr = &ax_get_8390_hdr; - ei_local->priv = 0; - - dev->netdev_ops = &ax_netdev_ops; - dev->ethtool_ops = &ax_ethtool_ops; - - ax_NS8390_init(dev, 0); - - ret = register_netdev(dev); - if (ret) - goto err_out; - - netdev_info(dev, "%dbit, irq %d, %lx, MAC: %pM\n", - ei_local->word16 ? 16 : 8, dev->irq, dev->base_addr, - dev->dev_addr); - - return 0; - - err_out: - return ret; -} - -static int ax_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - struct ei_device *ei_local = netdev_priv(dev); - struct ax_device *ax = to_ax_dev(dev); - struct resource *mem; - - unregister_netdev(dev); - - iounmap(ei_local->mem); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(mem->start, resource_size(mem)); - - if (ax->map2) { - iounmap(ax->map2); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); - release_mem_region(mem->start, resource_size(mem)); - } - - platform_set_drvdata(pdev, NULL); - free_netdev(dev); - - return 0; -} - -/* - * ax_probe - * - * This is the entry point when the platform device system uses to - * notify us of a new device to attach to. Allocate memory, find the - * resources and information passed, and map the necessary registers. - */ -static int ax_probe(struct platform_device *pdev) -{ - struct net_device *dev; - struct ei_device *ei_local; - struct ax_device *ax; - struct resource *irq, *mem, *mem2; - unsigned long mem_size, mem2_size = 0; - int ret = 0; - - dev = ax__alloc_ei_netdev(sizeof(struct ax_device)); - if (dev == NULL) - return -ENOMEM; - - /* ok, let's setup our device */ - SET_NETDEV_DEV(dev, &pdev->dev); - ei_local = netdev_priv(dev); - ax = to_ax_dev(dev); - - ax->plat = dev_get_platdata(&pdev->dev); - platform_set_drvdata(pdev, dev); - - ei_local->rxcr_base = ax->plat->rcr_val; - - /* find the platform resources */ - irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!irq) { - dev_err(&pdev->dev, "no IRQ specified\n"); - ret = -ENXIO; - goto exit_mem; - } - - dev->irq = irq->start; - ax->irqflags = irq->flags & IRQF_TRIGGER_MASK; - - if (irq->flags & IORESOURCE_IRQ_SHAREABLE) - ax->irqflags |= IRQF_SHARED; - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) { - dev_err(&pdev->dev, "no MEM specified\n"); - ret = -ENXIO; - goto exit_mem; - } - - mem_size = resource_size(mem); - - /* - * setup the register offsets from either the platform data or - * by using the size of the resource provided - */ - if (ax->plat->reg_offsets) - ei_local->reg_offset = ax->plat->reg_offsets; - else { - ei_local->reg_offset = ax->reg_offsets; - for (ret = 0; ret < 0x18; ret++) - ax->reg_offsets[ret] = (mem_size / 0x18) * ret; - } - - if (!request_mem_region(mem->start, mem_size, pdev->name)) { - dev_err(&pdev->dev, "cannot reserve registers\n"); - ret = -ENXIO; - goto exit_mem; - } - - ei_local->mem = ioremap(mem->start, mem_size); - dev->base_addr = (unsigned long)ei_local->mem; - - if (ei_local->mem == NULL) { - dev_err(&pdev->dev, "Cannot ioremap area %pR\n", mem); - - ret = -ENXIO; - goto exit_req; - } - - /* look for reset area */ - mem2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!mem2) { - if (!ax->plat->reg_offsets) { - for (ret = 0; ret < 0x20; ret++) - ax->reg_offsets[ret] = (mem_size / 0x20) * ret; - } - } else { - mem2_size = resource_size(mem2); - - if (!request_mem_region(mem2->start, mem2_size, pdev->name)) { - dev_err(&pdev->dev, "cannot reserve registers\n"); - ret = -ENXIO; - goto exit_mem1; - } - - ax->map2 = ioremap(mem2->start, mem2_size); - if (!ax->map2) { - dev_err(&pdev->dev, "cannot map reset register\n"); - ret = -ENXIO; - goto exit_mem2; - } - - ei_local->reg_offset[0x1f] = ax->map2 - ei_local->mem; - } - - /* got resources, now initialise and register device */ - ret = ax_init_dev(dev); - if (!ret) - return 0; - - if (!ax->map2) - goto exit_mem1; - - iounmap(ax->map2); - - exit_mem2: - if (mem2) - release_mem_region(mem2->start, mem2_size); - - exit_mem1: - iounmap(ei_local->mem); - - exit_req: - release_mem_region(mem->start, mem_size); - - exit_mem: - platform_set_drvdata(pdev, NULL); - free_netdev(dev); - - return ret; -} - -/* suspend and resume */ - -#ifdef CONFIG_PM -static int ax_suspend(struct platform_device *dev, pm_message_t state) -{ - struct net_device *ndev = platform_get_drvdata(dev); - struct ax_device *ax = to_ax_dev(ndev); - - ax->resume_open = ax->running; - - netif_device_detach(ndev); - ax_close(ndev); - - return 0; -} - -static int ax_resume(struct platform_device *pdev) -{ - struct net_device *ndev = platform_get_drvdata(pdev); - struct ax_device *ax = to_ax_dev(ndev); - - ax_initial_setup(ndev, netdev_priv(ndev)); - ax_NS8390_init(ndev, ax->resume_open); - netif_device_attach(ndev); - - if (ax->resume_open) - ax_open(ndev); - - return 0; -} - -#else -#define ax_suspend NULL -#define ax_resume NULL -#endif - -static struct platform_driver axdrv = { - .driver = { - .name = "ax88796", - }, - .probe = ax_probe, - .remove = ax_remove, - .suspend = ax_suspend, - .resume = ax_resume, -}; - -module_platform_driver(axdrv); - -MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver"); -MODULE_AUTHOR("Ben Dooks, "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:ax88796"); diff --git a/drivers/net/ethernet/8390/axnet_cs.c b/drivers/net/ethernet/8390/axnet_cs.c deleted file mode 100644 index 3c370e686ec3..000000000000 --- a/drivers/net/ethernet/8390/axnet_cs.c +++ /dev/null @@ -1,1707 +0,0 @@ -/*====================================================================== - - A PCMCIA ethernet driver for Asix AX88190-based cards - - The Asix AX88190 is a NS8390-derived chipset with a few nasty - idiosyncracies that make it very inconvenient to support with a - standard 8390 driver. This driver is based on pcnet_cs, with the - tweaked 8390 code grafted on the end. Much of what I did was to - clean up and update a similar driver supplied by Asix, which was - adapted by William Lee, william@asix.com.tw. - - Copyright (C) 2001 David A. Hinds -- dahinds@users.sourceforge.net - - axnet_cs.c 1.28 2002/06/29 06:27:37 - - The network driver code is based on Donald Becker's NE2000 code: - - Written 1992,1993 by Donald Becker. - Copyright 1993 United States Government as represented by the - Director, National Security Agency. This software may be used and - distributed according to the terms of the GNU General Public License, - incorporated herein by reference. - Donald Becker may be reached at becker@scyld.com - -======================================================================*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "8390.h" - -#include -#include -#include -#include - -#include -#include -#include - -#define AXNET_CMD 0x00 -#define AXNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */ -#define AXNET_RESET 0x1f /* Issue a read to reset, a write to clear. */ -#define AXNET_MII_EEP 0x14 /* Offset of MII access port */ -#define AXNET_TEST 0x15 /* Offset of TEST Register port */ -#define AXNET_GPIO 0x17 /* Offset of General Purpose Register Port */ - -#define AXNET_START_PG 0x40 /* First page of TX buffer */ -#define AXNET_STOP_PG 0x80 /* Last page +1 of RX ring */ - -#define AXNET_RDC_TIMEOUT 0x02 /* Max wait in jiffies for Tx RDC */ - -#define IS_AX88190 0x0001 -#define IS_AX88790 0x0002 - -/*====================================================================*/ - -/* Module parameters */ - -MODULE_AUTHOR("David Hinds "); -MODULE_DESCRIPTION("Asix AX88190 PCMCIA ethernet driver"); -MODULE_LICENSE("GPL"); - - -/*====================================================================*/ - -static int axnet_config(struct pcmcia_device *link); -static void axnet_release(struct pcmcia_device *link); -static int axnet_open(struct net_device *dev); -static int axnet_close(struct net_device *dev); -static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static netdev_tx_t axnet_start_xmit(struct sk_buff *skb, - struct net_device *dev); -static struct net_device_stats *get_stats(struct net_device *dev); -static void set_multicast_list(struct net_device *dev); -static void axnet_tx_timeout(struct net_device *dev, unsigned int txqueue); -static irqreturn_t ei_irq_wrapper(int irq, void *dev_id); -static void ei_watchdog(struct timer_list *t); -static void axnet_reset_8390(struct net_device *dev); - -static int mdio_read(unsigned int addr, int phy_id, int loc); -static void mdio_write(unsigned int addr, int phy_id, int loc, int value); - -static void get_8390_hdr(struct net_device *, - struct e8390_pkt_hdr *, int); -static void block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void block_output(struct net_device *dev, int count, - const u_char *buf, const int start_page); - -static void axnet_detach(struct pcmcia_device *p_dev); - -static void AX88190_init(struct net_device *dev, int startp); -static int ax_open(struct net_device *dev); -static int ax_close(struct net_device *dev); -static irqreturn_t ax_interrupt(int irq, void *dev_id); - -/*====================================================================*/ - -struct axnet_dev { - struct pcmcia_device *p_dev; - caddr_t base; - struct timer_list watchdog; - int stale, fast_poll; - u_short link_status; - u_char duplex_flag; - int phy_id; - int flags; - int active_low; -}; - -static inline struct axnet_dev *PRIV(struct net_device *dev) -{ - void *p = (char *)netdev_priv(dev) + sizeof(struct ei_device); - return p; -} - -static const struct net_device_ops axnet_netdev_ops = { - .ndo_open = axnet_open, - .ndo_stop = axnet_close, - .ndo_eth_ioctl = axnet_ioctl, - .ndo_start_xmit = axnet_start_xmit, - .ndo_tx_timeout = axnet_tx_timeout, - .ndo_get_stats = get_stats, - .ndo_set_rx_mode = set_multicast_list, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - -static int axnet_probe(struct pcmcia_device *link) -{ - struct axnet_dev *info; - struct net_device *dev; - struct ei_device *ei_local; - - dev_dbg(&link->dev, "axnet_attach()\n"); - - dev = alloc_etherdev(sizeof(struct ei_device) + sizeof(struct axnet_dev)); - if (!dev) - return -ENOMEM; - - ei_local = netdev_priv(dev); - spin_lock_init(&ei_local->page_lock); - - info = PRIV(dev); - info->p_dev = link; - link->priv = dev; - link->config_flags |= CONF_ENABLE_IRQ; - - dev->netdev_ops = &axnet_netdev_ops; - - dev->watchdog_timeo = TX_TIMEOUT; - - return axnet_config(link); -} /* axnet_attach */ - -static void axnet_detach(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - - dev_dbg(&link->dev, "axnet_detach(0x%p)\n", link); - - unregister_netdev(dev); - - axnet_release(link); - - free_netdev(dev); -} /* axnet_detach */ - -/*====================================================================== - - This probes for a card's hardware address by reading the PROM. - -======================================================================*/ - -static int get_prom(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - unsigned int ioaddr = dev->base_addr; - int i, j; - - /* This is based on drivers/net/ethernet/8390/ne.c */ - struct { - u_char value, offset; - } program_seq[] = { - {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ - {0x01, EN0_DCFG}, /* Set word-wide access. */ - {0x00, EN0_RCNTLO}, /* Clear the count regs. */ - {0x00, EN0_RCNTHI}, - {0x00, EN0_IMR}, /* Mask completion irq. */ - {0xFF, EN0_ISR}, - {E8390_RXOFF|0x40, EN0_RXCR}, /* 0x60 Set to monitor */ - {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ - {0x10, EN0_RCNTLO}, - {0x00, EN0_RCNTHI}, - {0x00, EN0_RSARLO}, /* DMA starting at 0x0400. */ - {0x04, EN0_RSARHI}, - {E8390_RREAD+E8390_START, E8390_CMD}, - }; - - /* Not much of a test, but the alternatives are messy */ - if (link->config_base != 0x03c0) - return 0; - - axnet_reset_8390(dev); - mdelay(10); - - for (i = 0; i < ARRAY_SIZE(program_seq); i++) - outb_p(program_seq[i].value, ioaddr + program_seq[i].offset); - - for (i = 0; i < 6; i += 2) { - j = inw(ioaddr + AXNET_DATAPORT); - dev->dev_addr[i] = j & 0xff; - dev->dev_addr[i+1] = j >> 8; - } - return 1; -} /* get_prom */ - -static int try_io_port(struct pcmcia_device *link) -{ - int j, ret; - link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; - link->resource[1]->flags &= ~IO_DATA_PATH_WIDTH; - if (link->resource[0]->end == 32) { - link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; - /* for master/slave multifunction cards */ - if (link->resource[1]->end > 0) - link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; - } else { - /* This should be two 16-port windows */ - link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; - link->resource[1]->flags |= IO_DATA_PATH_WIDTH_16; - } - if (link->resource[0]->start == 0) { - for (j = 0; j < 0x400; j += 0x20) { - link->resource[0]->start = j ^ 0x300; - link->resource[1]->start = (j ^ 0x300) + 0x10; - link->io_lines = 16; - ret = pcmcia_request_io(link); - if (ret == 0) - return ret; - } - return ret; - } else { - return pcmcia_request_io(link); - } -} - -static int axnet_configcheck(struct pcmcia_device *p_dev, void *priv_data) -{ - if (p_dev->config_index == 0) - return -EINVAL; - - p_dev->config_index = 0x05; - if (p_dev->resource[0]->end + p_dev->resource[1]->end < 32) - return -ENODEV; - - return try_io_port(p_dev); -} - -static int axnet_config(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - struct axnet_dev *info = PRIV(dev); - int i, j, j2, ret; - - dev_dbg(&link->dev, "axnet_config(0x%p)\n", link); - - /* don't trust the CIS on this; Linksys got it wrong */ - link->config_regs = 0x63; - link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; - ret = pcmcia_loop_config(link, axnet_configcheck, NULL); - if (ret != 0) - goto failed; - - if (!link->irq) - goto failed; - - if (resource_size(link->resource[1]) == 8) - link->config_flags |= CONF_ENABLE_SPKR; - - ret = pcmcia_enable_device(link); - if (ret) - goto failed; - - dev->irq = link->irq; - dev->base_addr = link->resource[0]->start; - - if (!get_prom(link)) { - pr_notice("this is not an AX88190 card!\n"); - pr_notice("use pcnet_cs instead.\n"); - goto failed; - } - - ei_status.name = "AX88190"; - ei_status.word16 = 1; - ei_status.tx_start_page = AXNET_START_PG; - ei_status.rx_start_page = AXNET_START_PG + TX_PAGES; - ei_status.stop_page = AXNET_STOP_PG; - ei_status.reset_8390 = axnet_reset_8390; - ei_status.get_8390_hdr = get_8390_hdr; - ei_status.block_input = block_input; - ei_status.block_output = block_output; - - if (inb(dev->base_addr + AXNET_TEST) != 0) - info->flags |= IS_AX88790; - else - info->flags |= IS_AX88190; - - if (info->flags & IS_AX88790) - outb(0x10, dev->base_addr + AXNET_GPIO); /* select Internal PHY */ - - info->active_low = 0; - - for (i = 0; i < 32; i++) { - j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1); - j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2); - if (j == j2) continue; - if ((j != 0) && (j != 0xffff)) break; - } - - if (i == 32) { - /* Maybe PHY is in power down mode. (PPD_SET = 1) - Bit 2 of CCSR is active low. */ - pcmcia_write_config_byte(link, CISREG_CCSR, 0x04); - for (i = 0; i < 32; i++) { - j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1); - j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2); - if (j == j2) continue; - if ((j != 0) && (j != 0xffff)) { - info->active_low = 1; - break; - } - } - } - - info->phy_id = (i < 32) ? i : -1; - SET_NETDEV_DEV(dev, &link->dev); - - if (register_netdev(dev) != 0) { - pr_notice("register_netdev() failed\n"); - goto failed; - } - - netdev_info(dev, "Asix AX88%d90: io %#3lx, irq %d, hw_addr %pM\n", - ((info->flags & IS_AX88790) ? 7 : 1), - dev->base_addr, dev->irq, dev->dev_addr); - if (info->phy_id != -1) { - netdev_dbg(dev, " MII transceiver at index %d, status %x\n", - info->phy_id, j); - } else { - netdev_notice(dev, " No MII transceivers found!\n"); - } - return 0; - -failed: - axnet_release(link); - return -ENODEV; -} /* axnet_config */ - -static void axnet_release(struct pcmcia_device *link) -{ - pcmcia_disable_device(link); -} - -static int axnet_suspend(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - - if (link->open) - netif_device_detach(dev); - - return 0; -} - -static int axnet_resume(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - struct axnet_dev *info = PRIV(dev); - - if (link->open) { - if (info->active_low == 1) - pcmcia_write_config_byte(link, CISREG_CCSR, 0x04); - - axnet_reset_8390(dev); - AX88190_init(dev, 1); - netif_device_attach(dev); - } - - return 0; -} - - -/*====================================================================== - - MII interface support - -======================================================================*/ - -#define MDIO_SHIFT_CLK 0x01 -#define MDIO_DATA_WRITE0 0x00 -#define MDIO_DATA_WRITE1 0x08 -#define MDIO_DATA_READ 0x04 -#define MDIO_MASK 0x0f -#define MDIO_ENB_IN 0x02 - -static void mdio_sync(unsigned int addr) -{ - int bits; - for (bits = 0; bits < 32; bits++) { - outb_p(MDIO_DATA_WRITE1, addr); - outb_p(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, addr); - } -} - -static int mdio_read(unsigned int addr, int phy_id, int loc) -{ - u_int cmd = (0xf6<<10)|(phy_id<<5)|loc; - int i, retval = 0; - - mdio_sync(addr); - for (i = 14; i >= 0; i--) { - int dat = (cmd&(1< 0; i--) { - outb_p(MDIO_ENB_IN, addr); - retval = (retval << 1) | ((inb_p(addr) & MDIO_DATA_READ) != 0); - outb_p(MDIO_ENB_IN | MDIO_SHIFT_CLK, addr); - } - return (retval>>1) & 0xffff; -} - -static void mdio_write(unsigned int addr, int phy_id, int loc, int value) -{ - u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value; - int i; - - mdio_sync(addr); - for (i = 31; i >= 0; i--) { - int dat = (cmd&(1<= 0; i--) { - outb_p(MDIO_ENB_IN, addr); - outb_p(MDIO_ENB_IN | MDIO_SHIFT_CLK, addr); - } -} - -/*====================================================================*/ - -static int axnet_open(struct net_device *dev) -{ - int ret; - struct axnet_dev *info = PRIV(dev); - struct pcmcia_device *link = info->p_dev; - unsigned int nic_base = dev->base_addr; - - dev_dbg(&link->dev, "axnet_open('%s')\n", dev->name); - - if (!pcmcia_dev_present(link)) - return -ENODEV; - - outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */ - ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev); - if (ret) - return ret; - - link->open++; - - info->link_status = 0x00; - timer_setup(&info->watchdog, ei_watchdog, 0); - mod_timer(&info->watchdog, jiffies + HZ); - - return ax_open(dev); -} /* axnet_open */ - -/*====================================================================*/ - -static int axnet_close(struct net_device *dev) -{ - struct axnet_dev *info = PRIV(dev); - struct pcmcia_device *link = info->p_dev; - - dev_dbg(&link->dev, "axnet_close('%s')\n", dev->name); - - ax_close(dev); - free_irq(dev->irq, dev); - - link->open--; - netif_stop_queue(dev); - del_timer_sync(&info->watchdog); - - return 0; -} /* axnet_close */ - -/*====================================================================== - - Hard reset the card. This used to pause for the same period that - a 8390 reset command required, but that shouldn't be necessary. - -======================================================================*/ - -static void axnet_reset_8390(struct net_device *dev) -{ - unsigned int nic_base = dev->base_addr; - int i; - - ei_status.txing = ei_status.dmaing = 0; - - outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, nic_base + E8390_CMD); - - outb(inb(nic_base + AXNET_RESET), nic_base + AXNET_RESET); - - for (i = 0; i < 100; i++) { - if ((inb_p(nic_base+EN0_ISR) & ENISR_RESET) != 0) - break; - udelay(100); - } - outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */ - - if (i == 100) - netdev_err(dev, "axnet_reset_8390() did not complete\n"); - -} /* axnet_reset_8390 */ - -/*====================================================================*/ - -static irqreturn_t ei_irq_wrapper(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - PRIV(dev)->stale = 0; - return ax_interrupt(irq, dev_id); -} - -static void ei_watchdog(struct timer_list *t) -{ - struct axnet_dev *info = from_timer(info, t, watchdog); - struct net_device *dev = info->p_dev->priv; - unsigned int nic_base = dev->base_addr; - unsigned int mii_addr = nic_base + AXNET_MII_EEP; - u_short link; - - if (!netif_device_present(dev)) goto reschedule; - - /* Check for pending interrupt with expired latency timer: with - this, we can limp along even if the interrupt is blocked */ - if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) { - if (!info->fast_poll) - netdev_info(dev, "interrupt(s) dropped!\n"); - ei_irq_wrapper(dev->irq, dev); - info->fast_poll = HZ; - } - if (info->fast_poll) { - info->fast_poll--; - info->watchdog.expires = jiffies + 1; - add_timer(&info->watchdog); - return; - } - - if (info->phy_id < 0) - goto reschedule; - link = mdio_read(mii_addr, info->phy_id, 1); - if (!link || (link == 0xffff)) { - netdev_info(dev, "MII is missing!\n"); - info->phy_id = -1; - goto reschedule; - } - - link &= 0x0004; - if (link != info->link_status) { - u_short p = mdio_read(mii_addr, info->phy_id, 5); - netdev_info(dev, "%s link beat\n", link ? "found" : "lost"); - if (link) { - info->duplex_flag = (p & 0x0140) ? 0x80 : 0x00; - if (p) - netdev_info(dev, "autonegotiation complete: %dbaseT-%cD selected\n", - (p & 0x0180) ? 100 : 10, (p & 0x0140) ? 'F' : 'H'); - else - netdev_info(dev, "link partner did not autonegotiate\n"); - AX88190_init(dev, 1); - } - info->link_status = link; - } - -reschedule: - info->watchdog.expires = jiffies + HZ; - add_timer(&info->watchdog); -} - -/*====================================================================*/ - -static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct axnet_dev *info = PRIV(dev); - struct mii_ioctl_data *data = if_mii(rq); - unsigned int mii_addr = dev->base_addr + AXNET_MII_EEP; - switch (cmd) { - case SIOCGMIIPHY: - data->phy_id = info->phy_id; - fallthrough; - case SIOCGMIIREG: /* Read MII PHY register. */ - data->val_out = mdio_read(mii_addr, data->phy_id, data->reg_num & 0x1f); - return 0; - case SIOCSMIIREG: /* Write MII PHY register. */ - mdio_write(mii_addr, data->phy_id, data->reg_num & 0x1f, data->val_in); - return 0; - } - return -EOPNOTSUPP; -} - -/*====================================================================*/ - -static void get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, - int ring_page) -{ - unsigned int nic_base = dev->base_addr; - - outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ - outb_p(ring_page, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + AXNET_CMD); - - insw(nic_base + AXNET_DATAPORT, hdr, - sizeof(struct e8390_pkt_hdr)>>1); - /* Fix for big endian systems */ - hdr->count = le16_to_cpu(hdr->count); - -} - -/*====================================================================*/ - -static void block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) -{ - unsigned int nic_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); - int xfer_count = count; - char *buf = skb->data; - - if ((netif_msg_rx_status(ei_local)) && (count != 4)) - netdev_dbg(dev, "[bi=%d]\n", count+4); - outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); - outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + AXNET_CMD); - - insw(nic_base + AXNET_DATAPORT,buf,count>>1); - if (count & 0x01) { - buf[count-1] = inb(nic_base + AXNET_DATAPORT); - xfer_count++; - } - -} - -/*====================================================================*/ - -static void block_output(struct net_device *dev, int count, - const u_char *buf, const int start_page) -{ - unsigned int nic_base = dev->base_addr; - - pr_debug("%s: [bo=%d]\n", dev->name, count); - - /* Round the count up for word writes. Do we need to do this? - What effect will an odd byte count have on the 8390? - I should check someday. */ - if (count & 0x01) - count++; - - outb_p(0x00, nic_base + EN0_RSARLO); - outb_p(start_page, nic_base + EN0_RSARHI); - outb_p(E8390_RWRITE+E8390_START, nic_base + AXNET_CMD); - outsw(nic_base + AXNET_DATAPORT, buf, count>>1); -} - -static const struct pcmcia_device_id axnet_ids[] = { - PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x016c, 0x0081), - PCMCIA_DEVICE_MANF_CARD(0x018a, 0x0301), - PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328), - PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0301), - PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0303), - PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309), - PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1106), - PCMCIA_DEVICE_MANF_CARD(0x8a01, 0xc1ab), - PCMCIA_DEVICE_MANF_CARD(0x021b, 0x0202), - PCMCIA_DEVICE_MANF_CARD(0xffff, 0x1090), - PCMCIA_DEVICE_PROD_ID12("AmbiCom,Inc.", "Fast Ethernet PC Card(AMB8110)", 0x49b020a7, 0x119cc9fc), - PCMCIA_DEVICE_PROD_ID124("Fast Ethernet", "16-bit PC Card", "AX88190", 0xb4be14e3, 0x9a12eb6a, 0xab9be5ef), - PCMCIA_DEVICE_PROD_ID12("ASIX", "AX88190", 0x0959823b, 0xab9be5ef), - PCMCIA_DEVICE_PROD_ID12("Billionton", "LNA-100B", 0x552ab682, 0xbc3b87e1), - PCMCIA_DEVICE_PROD_ID12("CHEETAH ETHERCARD", "EN2228", 0x00fa7bc8, 0x00e990cc), - PCMCIA_DEVICE_PROD_ID12("CNet", "CNF301", 0xbc477dde, 0x78c5f40b), - PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEther PCC-TXD", 0x5261440f, 0x436768c5), - PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEtherII PCC-TXD", 0x5261440f, 0x730df72e), - PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEther PCC-TXM", 0x5261440f, 0x3abbd061), - PCMCIA_DEVICE_PROD_ID12("Dynalink", "L100C16", 0x55632fd5, 0x66bc2a90), - PCMCIA_DEVICE_PROD_ID12("IO DATA", "ETXPCM", 0x547e66dc, 0x233adac2), - PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V3)", 0x0733cc81, 0x232019a8), - PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC3-TX", 0x481e0094, 0xf91af609), - PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA411", 0x9aa79dc3, 0x40fad875), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "100BASE", 0x281f1c5d, 0x7c2add04), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FastEtherCard", 0x281f1c5d, 0x7ef26116), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FEP501", 0x281f1c5d, 0x2e272058), - PCMCIA_DEVICE_PROD_ID14("Network Everywhere", "AX88190", 0x820a67b6, 0xab9be5ef), - PCMCIA_DEVICE_NULL, -}; -MODULE_DEVICE_TABLE(pcmcia, axnet_ids); - -static struct pcmcia_driver axnet_cs_driver = { - .owner = THIS_MODULE, - .name = "axnet_cs", - .probe = axnet_probe, - .remove = axnet_detach, - .id_table = axnet_ids, - .suspend = axnet_suspend, - .resume = axnet_resume, -}; -module_pcmcia_driver(axnet_cs_driver); - -/*====================================================================*/ - -/* 8390.c: A general NS8390 ethernet driver core for linux. */ -/* - Written 1992-94 by Donald Becker. - - Copyright 1993 United States Government as represented by the - Director, National Security Agency. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - The author may be reached as becker@scyld.com, or C/O - Scyld Computing Corporation - 410 Severn Ave., Suite 210 - Annapolis MD 21403 - - This is the chip-specific code for many 8390-based ethernet adaptors. - This is not a complete driver, it must be combined with board-specific - code such as ne.c, wd.c, 3c503.c, etc. - - Seeing how at least eight drivers use this code, (not counting the - PCMCIA ones either) it is easy to break some card by what seems like - a simple innocent change. Please contact me or Donald if you think - you have found something that needs changing. -- PG - - Changelog: - - Paul Gortmaker : remove set_bit lock, other cleanups. - Paul Gortmaker : add ei_get_8390_hdr() so we can pass skb's to - ei_block_input() for eth_io_copy_and_sum(). - Paul Gortmaker : exchange static int ei_pingpong for a #define, - also add better Tx error handling. - Paul Gortmaker : rewrite Rx overrun handling as per NS specs. - Alexey Kuznetsov : use the 8390's six bit hash multicast filter. - Paul Gortmaker : tweak ANK's above multicast changes a bit. - Paul Gortmaker : update packet statistics for v2.1.x - Alan Cox : support arbitrary stupid port mappings on the - 68K Macintosh. Support >16bit I/O spaces - Paul Gortmaker : add kmod support for auto-loading of the 8390 - module by all drivers that require it. - Alan Cox : Spinlocking work, added 'BUG_83C690' - Paul Gortmaker : Separate out Tx timeout code from Tx path. - - Sources: - The National Semiconductor LAN Databook, and the 3Com 3c503 databook. - - */ - -#include -#include -#include -#include -#include - -#define BUG_83C690 - -/* These are the operational function interfaces to board-specific - routines. - void reset_8390(struct net_device *dev) - Resets the board associated with DEV, including a hardware reset of - the 8390. This is only called when there is a transmit timeout, and - it is always followed by 8390_init(). - void block_output(struct net_device *dev, int count, const unsigned char *buf, - int start_page) - Write the COUNT bytes of BUF to the packet buffer at START_PAGE. The - "page" value uses the 8390's 256-byte pages. - void get_8390_hdr(struct net_device *dev, struct e8390_hdr *hdr, int ring_page) - Read the 4 byte, page aligned 8390 header. *If* there is a - subsequent read, it will be of the rest of the packet. - void block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) - Read COUNT bytes from the packet buffer into the skb data area. Start - reading from RING_OFFSET, the address as the 8390 sees it. This will always - follow the read of the 8390 header. -*/ -#define ei_reset_8390 (ei_local->reset_8390) -#define ei_block_output (ei_local->block_output) -#define ei_block_input (ei_local->block_input) -#define ei_get_8390_hdr (ei_local->get_8390_hdr) - -/* Index to functions. */ -static void ei_tx_intr(struct net_device *dev); -static void ei_tx_err(struct net_device *dev); -static void ei_receive(struct net_device *dev); -static void ei_rx_overrun(struct net_device *dev); - -/* Routines generic to NS8390-based boards. */ -static void NS8390_trigger_send(struct net_device *dev, unsigned int length, - int start_page); -static void do_set_multicast_list(struct net_device *dev); - -/* - * SMP and the 8390 setup. - * - * The 8390 isn't exactly designed to be multithreaded on RX/TX. There is - * a page register that controls bank and packet buffer access. We guard - * this with ei_local->page_lock. Nobody should assume or set the page other - * than zero when the lock is not held. Lock holders must restore page 0 - * before unlocking. Even pure readers must take the lock to protect in - * page 0. - * - * To make life difficult the chip can also be very slow. We therefore can't - * just use spinlocks. For the longer lockups we disable the irq the device - * sits on and hold the lock. We must hold the lock because there is a dual - * processor case other than interrupts (get stats/set multicast list in - * parallel with each other and transmit). - * - * Note: in theory we can just disable the irq on the card _but_ there is - * a latency on SMP irq delivery. So we can easily go "disable irq" "sync irqs" - * enter lock, take the queued irq. So we waddle instead of flying. - * - * Finally by special arrangement for the purpose of being generally - * annoying the transmit function is called bh atomic. That places - * restrictions on the user context callers as disable_irq won't save - * them. - */ - -/** - * ax_open - Open/initialize the board. - * @dev: network device to initialize - * - * This routine goes all-out, setting everything - * up anew at each open, even though many of these registers should only - * need to be set once at boot. - */ -static int ax_open(struct net_device *dev) -{ - unsigned long flags; - struct ei_device *ei_local = netdev_priv(dev); - - /* - * Grab the page lock so we own the register set, then call - * the init function. - */ - - spin_lock_irqsave(&ei_local->page_lock, flags); - AX88190_init(dev, 1); - /* Set the flag before we drop the lock, That way the IRQ arrives - after its set and we get no silly warnings */ - netif_start_queue(dev); - spin_unlock_irqrestore(&ei_local->page_lock, flags); - ei_local->irqlock = 0; - return 0; -} - -#define dev_lock(dev) (((struct ei_device *)netdev_priv(dev))->page_lock) - -/** - * ax_close - shut down network device - * @dev: network device to close - * - * Opposite of ax_open(). Only used when "ifconfig down" is done. - */ -static int ax_close(struct net_device *dev) -{ - unsigned long flags; - - /* - * Hold the page lock during close - */ - - spin_lock_irqsave(&dev_lock(dev), flags); - AX88190_init(dev, 0); - spin_unlock_irqrestore(&dev_lock(dev), flags); - netif_stop_queue(dev); - return 0; -} - -/** - * axnet_tx_timeout - handle transmit time out condition - * @dev: network device which has apparently fallen asleep - * @txqueue: unused - * - * Called by kernel when device never acknowledges a transmit has - * completed (or failed) - i.e. never posted a Tx related interrupt. - */ - -static void axnet_tx_timeout(struct net_device *dev, unsigned int txqueue) -{ - long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); - int txsr, isr, tickssofar = jiffies - dev_trans_start(dev); - unsigned long flags; - - dev->stats.tx_errors++; - - spin_lock_irqsave(&ei_local->page_lock, flags); - txsr = inb(e8390_base+EN0_TSR); - isr = inb(e8390_base+EN0_ISR); - spin_unlock_irqrestore(&ei_local->page_lock, flags); - - netdev_dbg(dev, "Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n", - (txsr & ENTSR_ABT) ? "excess collisions." : - (isr) ? "lost interrupt?" : "cable problem?", - txsr, isr, tickssofar); - - if (!isr && !dev->stats.tx_packets) - { - /* The 8390 probably hasn't gotten on the cable yet. */ - ei_local->interface_num ^= 1; /* Try a different xcvr. */ - } - - /* Ugly but a reset can be slow, yet must be protected */ - - spin_lock_irqsave(&ei_local->page_lock, flags); - - /* Try to restart the card. Perhaps the user has fixed something. */ - ei_reset_8390(dev); - AX88190_init(dev, 1); - - spin_unlock_irqrestore(&ei_local->page_lock, flags); - netif_wake_queue(dev); -} - -/** - * axnet_start_xmit - begin packet transmission - * @skb: packet to be sent - * @dev: network device to which packet is sent - * - * Sends a packet to an 8390 network device. - */ - -static netdev_tx_t axnet_start_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); - int length, send_length, output_page; - unsigned long flags; - u8 packet[ETH_ZLEN]; - - netif_stop_queue(dev); - - length = skb->len; - - /* Mask interrupts from the ethercard. - SMP: We have to grab the lock here otherwise the IRQ handler - on another CPU can flip window and race the IRQ mask set. We end - up trashing the mcast filter not disabling irqs if we don't lock */ - - spin_lock_irqsave(&ei_local->page_lock, flags); - outb_p(0x00, e8390_base + EN0_IMR); - - /* - * Slow phase with lock held. - */ - - ei_local->irqlock = 1; - - send_length = max(length, ETH_ZLEN); - - /* - * We have two Tx slots available for use. Find the first free - * slot, and then perform some sanity checks. With two Tx bufs, - * you get very close to transmitting back-to-back packets. With - * only one Tx buf, the transmitter sits idle while you reload the - * card, leaving a substantial gap between each transmitted packet. - */ - - if (ei_local->tx1 == 0) - { - output_page = ei_local->tx_start_page; - ei_local->tx1 = send_length; - if ((netif_msg_tx_queued(ei_local)) && - ei_local->tx2 > 0) - netdev_dbg(dev, - "idle transmitter tx2=%d, lasttx=%d, txing=%d\n", - ei_local->tx2, ei_local->lasttx, - ei_local->txing); - } - else if (ei_local->tx2 == 0) - { - output_page = ei_local->tx_start_page + TX_PAGES/2; - ei_local->tx2 = send_length; - if ((netif_msg_tx_queued(ei_local)) && - ei_local->tx1 > 0) - netdev_dbg(dev, - "idle transmitter, tx1=%d, lasttx=%d, txing=%d\n", - ei_local->tx1, ei_local->lasttx, - ei_local->txing); - } - else - { /* We should never get here. */ - netif_dbg(ei_local, tx_err, dev, - "No Tx buffers free! tx1=%d tx2=%d last=%d\n", - ei_local->tx1, ei_local->tx2, - ei_local->lasttx); - ei_local->irqlock = 0; - netif_stop_queue(dev); - outb_p(ENISR_ALL, e8390_base + EN0_IMR); - spin_unlock_irqrestore(&ei_local->page_lock, flags); - dev->stats.tx_errors++; - return NETDEV_TX_BUSY; - } - - /* - * Okay, now upload the packet and trigger a send if the transmitter - * isn't already sending. If it is busy, the interrupt handler will - * trigger the send later, upon receiving a Tx done interrupt. - */ - - if (length == skb->len) - ei_block_output(dev, length, skb->data, output_page); - else { - memset(packet, 0, ETH_ZLEN); - skb_copy_from_linear_data(skb, packet, skb->len); - ei_block_output(dev, length, packet, output_page); - } - - if (! ei_local->txing) - { - ei_local->txing = 1; - NS8390_trigger_send(dev, send_length, output_page); - netif_trans_update(dev); - if (output_page == ei_local->tx_start_page) - { - ei_local->tx1 = -1; - ei_local->lasttx = -1; - } - else - { - ei_local->tx2 = -1; - ei_local->lasttx = -2; - } - } - else ei_local->txqueue++; - - if (ei_local->tx1 && ei_local->tx2) - netif_stop_queue(dev); - else - netif_start_queue(dev); - - /* Turn 8390 interrupts back on. */ - ei_local->irqlock = 0; - outb_p(ENISR_ALL, e8390_base + EN0_IMR); - - spin_unlock_irqrestore(&ei_local->page_lock, flags); - - dev_kfree_skb (skb); - dev->stats.tx_bytes += send_length; - - return NETDEV_TX_OK; -} - -/** - * ax_interrupt - handle the interrupts from an 8390 - * @irq: interrupt number - * @dev_id: a pointer to the net_device - * - * Handle the ether interface interrupts. We pull packets from - * the 8390 via the card specific functions and fire them at the networking - * stack. We also handle transmit completions and wake the transmit path if - * necessary. We also update the counters and do other housekeeping as - * needed. - */ - -static irqreturn_t ax_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - long e8390_base; - int interrupts, nr_serviced = 0, i; - struct ei_device *ei_local; - int handled = 0; - unsigned long flags; - - e8390_base = dev->base_addr; - ei_local = netdev_priv(dev); - - /* - * Protect the irq test too. - */ - - spin_lock_irqsave(&ei_local->page_lock, flags); - - if (ei_local->irqlock) { -#if 1 /* This might just be an interrupt for a PCI device sharing this line */ - const char *msg; - /* The "irqlock" check is only for testing. */ - if (ei_local->irqlock) - msg = "Interrupted while interrupts are masked!"; - else - msg = "Reentering the interrupt handler!"; - netdev_info(dev, "%s, isr=%#2x imr=%#2x\n", - msg, - inb_p(e8390_base + EN0_ISR), - inb_p(e8390_base + EN0_IMR)); -#endif - spin_unlock_irqrestore(&ei_local->page_lock, flags); - return IRQ_NONE; - } - - netif_dbg(ei_local, intr, dev, "interrupt(isr=%#2.2x)\n", - inb_p(e8390_base + EN0_ISR)); - - outb_p(0x00, e8390_base + EN0_ISR); - ei_local->irqlock = 1; - - /* !!Assumption!! -- we stay in page 0. Don't break this. */ - while ((interrupts = inb_p(e8390_base + EN0_ISR)) != 0 && - ++nr_serviced < MAX_SERVICE) - { - if (!netif_running(dev) || (interrupts == 0xff)) { - netif_warn(ei_local, intr, dev, - "interrupt from stopped card\n"); - outb_p(interrupts, e8390_base + EN0_ISR); - interrupts = 0; - break; - } - handled = 1; - - /* AX88190 bug fix. */ - outb_p(interrupts, e8390_base + EN0_ISR); - for (i = 0; i < 10; i++) { - if (!(inb(e8390_base + EN0_ISR) & interrupts)) - break; - outb_p(0, e8390_base + EN0_ISR); - outb_p(interrupts, e8390_base + EN0_ISR); - } - if (interrupts & ENISR_OVER) - ei_rx_overrun(dev); - else if (interrupts & (ENISR_RX+ENISR_RX_ERR)) - { - /* Got a good (?) packet. */ - ei_receive(dev); - } - /* Push the next to-transmit packet through. */ - if (interrupts & ENISR_TX) - ei_tx_intr(dev); - else if (interrupts & ENISR_TX_ERR) - ei_tx_err(dev); - - if (interrupts & ENISR_COUNTERS) - { - dev->stats.rx_frame_errors += inb_p(e8390_base + EN0_COUNTER0); - dev->stats.rx_crc_errors += inb_p(e8390_base + EN0_COUNTER1); - dev->stats.rx_missed_errors+= inb_p(e8390_base + EN0_COUNTER2); - } - } - - if (interrupts && (netif_msg_intr(ei_local))) - { - handled = 1; - if (nr_serviced >= MAX_SERVICE) - { - /* 0xFF is valid for a card removal */ - if (interrupts != 0xFF) - netdev_warn(dev, - "Too much work at interrupt, status %#2.2x\n", - interrupts); - outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */ - } else { - netdev_warn(dev, "unknown interrupt %#2x\n", - interrupts); - outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */ - } - } - - /* Turn 8390 interrupts back on. */ - ei_local->irqlock = 0; - outb_p(ENISR_ALL, e8390_base + EN0_IMR); - - spin_unlock_irqrestore(&ei_local->page_lock, flags); - return IRQ_RETVAL(handled); -} - -/** - * ei_tx_err - handle transmitter error - * @dev: network device which threw the exception - * - * A transmitter error has happened. Most likely excess collisions (which - * is a fairly normal condition). If the error is one where the Tx will - * have been aborted, we try and send another one right away, instead of - * letting the failed packet sit and collect dust in the Tx buffer. This - * is a much better solution as it avoids kernel based Tx timeouts, and - * an unnecessary card reset. - * - * Called with lock held. - */ - -static void ei_tx_err(struct net_device *dev) -{ - long e8390_base = dev->base_addr; - unsigned char txsr = inb_p(e8390_base+EN0_TSR); - unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU); - -#ifdef VERBOSE_ERROR_DUMP - netdev_dbg(dev, "transmitter error (%#2x):", txsr); - if (txsr & ENTSR_ABT) - pr_cont(" excess-collisions"); - if (txsr & ENTSR_ND) - pr_cont(" non-deferral"); - if (txsr & ENTSR_CRS) - pr_cont(" lost-carrier"); - if (txsr & ENTSR_FU) - pr_cont(" FIFO-underrun"); - if (txsr & ENTSR_CDH) - pr_cont(" lost-heartbeat"); - pr_cont("\n"); -#endif - - if (tx_was_aborted) - ei_tx_intr(dev); - else - { - dev->stats.tx_errors++; - if (txsr & ENTSR_CRS) dev->stats.tx_carrier_errors++; - if (txsr & ENTSR_CDH) dev->stats.tx_heartbeat_errors++; - if (txsr & ENTSR_OWC) dev->stats.tx_window_errors++; - } -} - -/** - * ei_tx_intr - transmit interrupt handler - * @dev: network device for which tx intr is handled - * - * We have finished a transmit: check for errors and then trigger the next - * packet to be sent. Called with lock held. - */ - -static void ei_tx_intr(struct net_device *dev) -{ - long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); - int status = inb(e8390_base + EN0_TSR); - - /* - * There are two Tx buffers, see which one finished, and trigger - * the send of another one if it exists. - */ - ei_local->txqueue--; - - if (ei_local->tx1 < 0) - { - if (ei_local->lasttx != 1 && ei_local->lasttx != -1) - netdev_err(dev, "%s: bogus last_tx_buffer %d, tx1=%d\n", - ei_local->name, ei_local->lasttx, - ei_local->tx1); - ei_local->tx1 = 0; - if (ei_local->tx2 > 0) - { - ei_local->txing = 1; - NS8390_trigger_send(dev, ei_local->tx2, ei_local->tx_start_page + 6); - netif_trans_update(dev); - ei_local->tx2 = -1; - ei_local->lasttx = 2; - } else { - ei_local->lasttx = 20; - ei_local->txing = 0; - } - } - else if (ei_local->tx2 < 0) - { - if (ei_local->lasttx != 2 && ei_local->lasttx != -2) - netdev_err(dev, "%s: bogus last_tx_buffer %d, tx2=%d\n", - ei_local->name, ei_local->lasttx, - ei_local->tx2); - ei_local->tx2 = 0; - if (ei_local->tx1 > 0) - { - ei_local->txing = 1; - NS8390_trigger_send(dev, ei_local->tx1, ei_local->tx_start_page); - netif_trans_update(dev); - ei_local->tx1 = -1; - ei_local->lasttx = 1; - } else { - ei_local->lasttx = 10; - ei_local->txing = 0; - } - } -// else -// netdev_warn(dev, "unexpected TX-done interrupt, lasttx=%d\n", -// ei_local->lasttx); - - /* Minimize Tx latency: update the statistics after we restart TXing. */ - if (status & ENTSR_COL) - dev->stats.collisions++; - if (status & ENTSR_PTX) - dev->stats.tx_packets++; - else - { - dev->stats.tx_errors++; - if (status & ENTSR_ABT) - { - dev->stats.tx_aborted_errors++; - dev->stats.collisions += 16; - } - if (status & ENTSR_CRS) - dev->stats.tx_carrier_errors++; - if (status & ENTSR_FU) - dev->stats.tx_fifo_errors++; - if (status & ENTSR_CDH) - dev->stats.tx_heartbeat_errors++; - if (status & ENTSR_OWC) - dev->stats.tx_window_errors++; - } - netif_wake_queue(dev); -} - -/** - * ei_receive - receive some packets - * @dev: network device with which receive will be run - * - * We have a good packet(s), get it/them out of the buffers. - * Called with lock held. - */ - -static void ei_receive(struct net_device *dev) -{ - long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); - unsigned char rxing_page, this_frame, next_frame; - unsigned short current_offset; - int rx_pkt_count = 0; - struct e8390_pkt_hdr rx_frame; - - while (++rx_pkt_count < 10) - { - int pkt_len, pkt_stat; - - /* Get the rx page (incoming packet pointer). */ - rxing_page = inb_p(e8390_base + EN1_CURPAG -1); - - /* Remove one frame from the ring. Boundary is always a page behind. */ - this_frame = inb_p(e8390_base + EN0_BOUNDARY) + 1; - if (this_frame >= ei_local->stop_page) - this_frame = ei_local->rx_start_page; - - /* Someday we'll omit the previous, iff we never get this message. - (There is at least one clone claimed to have a problem.) - - Keep quiet if it looks like a card removal. One problem here - is that some clones crash in roughly the same way. - */ - if ((netif_msg_rx_err(ei_local)) && - this_frame != ei_local->current_page && - (this_frame != 0x0 || rxing_page != 0xFF)) - netdev_err(dev, "mismatched read page pointers %2x vs %2x\n", - this_frame, ei_local->current_page); - - if (this_frame == rxing_page) /* Read all the frames? */ - break; /* Done for now */ - - current_offset = this_frame << 8; - ei_get_8390_hdr(dev, &rx_frame, this_frame); - - pkt_len = rx_frame.count - sizeof(struct e8390_pkt_hdr); - pkt_stat = rx_frame.status; - - next_frame = this_frame + 1 + ((pkt_len+4)>>8); - - if (pkt_len < 60 || pkt_len > 1518) - { - netif_err(ei_local, rx_err, dev, - "bogus packet size: %d, status=%#2x nxpg=%#2x\n", - rx_frame.count, rx_frame.status, - rx_frame.next); - dev->stats.rx_errors++; - dev->stats.rx_length_errors++; - } - else if ((pkt_stat & 0x0F) == ENRSR_RXOK) - { - struct sk_buff *skb; - - skb = netdev_alloc_skb(dev, pkt_len + 2); - if (skb == NULL) - { - netif_err(ei_local, rx_err, dev, - "Couldn't allocate a sk_buff of size %d\n", - pkt_len); - dev->stats.rx_dropped++; - break; - } - else - { - skb_reserve(skb,2); /* IP headers on 16 byte boundaries */ - skb_put(skb, pkt_len); /* Make room */ - ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame)); - skb->protocol=eth_type_trans(skb,dev); - netif_rx(skb); - dev->stats.rx_packets++; - dev->stats.rx_bytes += pkt_len; - if (pkt_stat & ENRSR_PHY) - dev->stats.multicast++; - } - } - else - { - netif_err(ei_local, rx_err, dev, - "bogus packet: status=%#2x nxpg=%#2x size=%d\n", - rx_frame.status, rx_frame.next, - rx_frame.count); - dev->stats.rx_errors++; - /* NB: The NIC counts CRC, frame and missed errors. */ - if (pkt_stat & ENRSR_FO) - dev->stats.rx_fifo_errors++; - } - next_frame = rx_frame.next; - - /* This _should_ never happen: it's here for avoiding bad clones. */ - if (next_frame >= ei_local->stop_page) { - netdev_info(dev, "next frame inconsistency, %#2x\n", - next_frame); - next_frame = ei_local->rx_start_page; - } - ei_local->current_page = next_frame; - outb_p(next_frame-1, e8390_base+EN0_BOUNDARY); - } -} - -/** - * ei_rx_overrun - handle receiver overrun - * @dev: network device which threw exception - * - * We have a receiver overrun: we have to kick the 8390 to get it started - * again. Problem is that you have to kick it exactly as NS prescribes in - * the updated datasheets, or "the NIC may act in an unpredictable manner." - * This includes causing "the NIC to defer indefinitely when it is stopped - * on a busy network." Ugh. - * Called with lock held. Don't call this with the interrupts off or your - * computer will hate you - it takes 10ms or so. - */ - -static void ei_rx_overrun(struct net_device *dev) -{ - struct axnet_dev *info = PRIV(dev); - long e8390_base = dev->base_addr; - unsigned char was_txing, must_resend = 0; - struct ei_device *ei_local = netdev_priv(dev); - - /* - * Record whether a Tx was in progress and then issue the - * stop command. - */ - was_txing = inb_p(e8390_base+E8390_CMD) & E8390_TRANS; - outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); - - netif_dbg(ei_local, rx_err, dev, "Receiver overrun\n"); - dev->stats.rx_over_errors++; - - /* - * Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total. - * We wait at least 2ms. - */ - - mdelay(2); - - /* - * Reset RBCR[01] back to zero as per magic incantation. - */ - outb_p(0x00, e8390_base+EN0_RCNTLO); - outb_p(0x00, e8390_base+EN0_RCNTHI); - - /* - * See if any Tx was interrupted or not. According to NS, this - * step is vital, and skipping it will cause no end of havoc. - */ - - if (was_txing) - { - unsigned char tx_completed = inb_p(e8390_base+EN0_ISR) & (ENISR_TX+ENISR_TX_ERR); - if (!tx_completed) - must_resend = 1; - } - - /* - * Have to enter loopback mode and then restart the NIC before - * you are allowed to slurp packets up off the ring. - */ - outb_p(E8390_TXOFF, e8390_base + EN0_TXCR); - outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, e8390_base + E8390_CMD); - - /* - * Clear the Rx ring of all the debris, and ack the interrupt. - */ - ei_receive(dev); - - /* - * Leave loopback mode, and resend any packet that got stopped. - */ - outb_p(E8390_TXCONFIG | info->duplex_flag, e8390_base + EN0_TXCR); - if (must_resend) - outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START + E8390_TRANS, e8390_base + E8390_CMD); -} - -/* - * Collect the stats. This is called unlocked and from several contexts. - */ - -static struct net_device_stats *get_stats(struct net_device *dev) -{ - long ioaddr = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); - unsigned long flags; - - /* If the card is stopped, just return the present stats. */ - if (!netif_running(dev)) - return &dev->stats; - - spin_lock_irqsave(&ei_local->page_lock,flags); - /* Read the counter registers, assuming we are in page 0. */ - dev->stats.rx_frame_errors += inb_p(ioaddr + EN0_COUNTER0); - dev->stats.rx_crc_errors += inb_p(ioaddr + EN0_COUNTER1); - dev->stats.rx_missed_errors+= inb_p(ioaddr + EN0_COUNTER2); - spin_unlock_irqrestore(&ei_local->page_lock, flags); - - return &dev->stats; -} - -/* - * Form the 64 bit 8390 multicast table from the linked list of addresses - * associated with this dev structure. - */ - -static inline void make_mc_bits(u8 *bits, struct net_device *dev) -{ - struct netdev_hw_addr *ha; - u32 crc; - - netdev_for_each_mc_addr(ha, dev) { - crc = ether_crc(ETH_ALEN, ha->addr); - /* - * The 8390 uses the 6 most significant bits of the - * CRC to index the multicast table. - */ - bits[crc>>29] |= (1<<((crc>>26)&7)); - } -} - -/** - * do_set_multicast_list - set/clear multicast filter - * @dev: net device for which multicast filter is adjusted - * - * Set or clear the multicast filter for this adaptor. - * Must be called with lock held. - */ - -static void do_set_multicast_list(struct net_device *dev) -{ - long e8390_base = dev->base_addr; - int i; - struct ei_device *ei_local = netdev_priv(dev); - - if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) { - memset(ei_local->mcfilter, 0, 8); - if (!netdev_mc_empty(dev)) - make_mc_bits(ei_local->mcfilter, dev); - } else { - /* set to accept-all */ - memset(ei_local->mcfilter, 0xFF, 8); - } - - outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD); - for(i = 0; i < 8; i++) - { - outb_p(ei_local->mcfilter[i], e8390_base + EN1_MULT_SHIFT(i)); - } - outb_p(E8390_NODMA + E8390_PAGE0, e8390_base + E8390_CMD); - - if(dev->flags&IFF_PROMISC) - outb_p(E8390_RXCONFIG | 0x58, e8390_base + EN0_RXCR); - else if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev)) - outb_p(E8390_RXCONFIG | 0x48, e8390_base + EN0_RXCR); - else - outb_p(E8390_RXCONFIG | 0x40, e8390_base + EN0_RXCR); - - outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base+E8390_CMD); -} - -/* - * Called without lock held. This is invoked from user context and may - * be parallel to just about everything else. Its also fairly quick and - * not called too often. Must protect against both bh and irq users - */ - -static void set_multicast_list(struct net_device *dev) -{ - unsigned long flags; - - spin_lock_irqsave(&dev_lock(dev), flags); - do_set_multicast_list(dev); - spin_unlock_irqrestore(&dev_lock(dev), flags); -} - -/* This page of functions should be 8390 generic */ -/* Follow National Semi's recommendations for initializing the "NIC". */ - -/** - * AX88190_init - initialize 8390 hardware - * @dev: network device to initialize - * @startp: boolean. non-zero value to initiate chip processing - * - * Must be called with lock held. - */ - -static void AX88190_init(struct net_device *dev, int startp) -{ - struct axnet_dev *info = PRIV(dev); - long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); - int i; - int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48; - - if(sizeof(struct e8390_pkt_hdr)!=4) - panic("8390.c: header struct mispacked\n"); - /* Follow National Semi's recommendations for initing the DP83902. */ - outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); /* 0x21 */ - outb_p(endcfg, e8390_base + EN0_DCFG); /* 0x48 or 0x49 */ - /* Clear the remote byte count registers. */ - outb_p(0x00, e8390_base + EN0_RCNTLO); - outb_p(0x00, e8390_base + EN0_RCNTHI); - /* Set to monitor and loopback mode -- this is vital!. */ - outb_p(E8390_RXOFF|0x40, e8390_base + EN0_RXCR); /* 0x60 */ - outb_p(E8390_TXOFF, e8390_base + EN0_TXCR); /* 0x02 */ - /* Set the transmit page and receive ring. */ - outb_p(ei_local->tx_start_page, e8390_base + EN0_TPSR); - ei_local->tx1 = ei_local->tx2 = 0; - outb_p(ei_local->rx_start_page, e8390_base + EN0_STARTPG); - outb_p(ei_local->stop_page-1, e8390_base + EN0_BOUNDARY); /* 3c503 says 0x3f,NS0x26*/ - ei_local->current_page = ei_local->rx_start_page; /* assert boundary+1 */ - outb_p(ei_local->stop_page, e8390_base + EN0_STOPPG); - /* Clear the pending interrupts and mask. */ - outb_p(0xFF, e8390_base + EN0_ISR); - outb_p(0x00, e8390_base + EN0_IMR); - - /* Copy the station address into the DS8390 registers. */ - - outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, e8390_base+E8390_CMD); /* 0x61 */ - for(i = 0; i < 6; i++) - { - outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i)); - if(inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i]) - netdev_err(dev, "Hw. address read/write mismap %d\n", i); - } - - outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG); - outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); - - netif_start_queue(dev); - ei_local->tx1 = ei_local->tx2 = 0; - ei_local->txing = 0; - - if (info->flags & IS_AX88790) /* select Internal PHY */ - outb(0x10, e8390_base + AXNET_GPIO); - - if (startp) - { - outb_p(0xff, e8390_base + EN0_ISR); - outb_p(ENISR_ALL, e8390_base + EN0_IMR); - outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base+E8390_CMD); - outb_p(E8390_TXCONFIG | info->duplex_flag, - e8390_base + EN0_TXCR); /* xmit on. */ - /* 3c503 TechMan says rxconfig only after the NIC is started. */ - outb_p(E8390_RXCONFIG | 0x40, e8390_base + EN0_RXCR); /* rx on, */ - do_set_multicast_list(dev); /* (re)load the mcast table */ - } -} - -/* Trigger a transmit start, assuming the length is valid. - Always called with the page lock held */ - -static void NS8390_trigger_send(struct net_device *dev, unsigned int length, - int start_page) -{ - long e8390_base = dev->base_addr; - struct ei_device *ei_local __attribute((unused)) = netdev_priv(dev); - - if (inb_p(e8390_base) & E8390_TRANS) - { - netdev_warn(dev, "trigger_send() called with the transmitter busy\n"); - return; - } - outb_p(length & 0xff, e8390_base + EN0_TCNTLO); - outb_p(length >> 8, e8390_base + EN0_TCNTHI); - outb_p(start_page, e8390_base + EN0_TPSR); - outb_p(E8390_NODMA+E8390_TRANS+E8390_START, e8390_base+E8390_CMD); -} diff --git a/drivers/net/ethernet/8390/etherh.c b/drivers/net/ethernet/8390/etherh.c deleted file mode 100644 index bd22a534b1c0..000000000000 --- a/drivers/net/ethernet/8390/etherh.c +++ /dev/null @@ -1,856 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * linux/drivers/acorn/net/etherh.c - * - * Copyright (C) 2000-2002 Russell King - * - * NS8390 I-cubed EtherH and ANT EtherM specific driver - * Thanks to I-Cubed for information on their cards. - * EtherM conversion (C) 1999 Chris Kemp and Tim Watterton - * EtherM integration (C) 2000 Aleph One Ltd (Tak-Shing Chan) - * EtherM integration re-engineered by Russell King. - * - * Changelog: - * 08-12-1996 RMK 1.00 Created - * RMK 1.03 Added support for EtherLan500 cards - * 23-11-1997 RMK 1.04 Added media autodetection - * 16-04-1998 RMK 1.05 Improved media autodetection - * 10-02-2000 RMK 1.06 Updated for 2.3.43 - * 13-05-2000 RMK 1.07 Updated for 2.3.99-pre8 - * 12-10-1999 CK/TEW EtherM driver first release - * 21-12-2000 TTC EtherH/EtherM integration - * 25-12-2000 RMK 1.08 Clean integration of EtherM into this driver. - * 03-01-2002 RMK 1.09 Always enable IRQs if we're in the nic slot. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define EI_SHIFT(x) (ei_local->reg_offset[x]) - -#define ei_inb(_p) readb((void __iomem *)_p) -#define ei_outb(_v,_p) writeb(_v,(void __iomem *)_p) -#define ei_inb_p(_p) readb((void __iomem *)_p) -#define ei_outb_p(_v,_p) writeb(_v,(void __iomem *)_p) - -#define DRV_NAME "etherh" -#define DRV_VERSION "1.11" - -static char version[] = - "EtherH/EtherM Driver (c) 2002-2004 Russell King " DRV_VERSION "\n"; - -#include "lib8390.c" - -struct etherh_priv { - void __iomem *ioc_fast; - void __iomem *memc; - void __iomem *dma_base; - unsigned int id; - void __iomem *ctrl_port; - unsigned char ctrl; - u32 supported; -}; - -struct etherh_data { - unsigned long ns8390_offset; - unsigned long dataport_offset; - unsigned long ctrlport_offset; - int ctrl_ioc; - const char name[16]; - u32 supported; - unsigned char tx_start_page; - unsigned char stop_page; -}; - -MODULE_AUTHOR("Russell King"); -MODULE_DESCRIPTION("EtherH/EtherM driver"); -MODULE_LICENSE("GPL"); - -#define ETHERH500_DATAPORT 0x800 /* MEMC */ -#define ETHERH500_NS8390 0x000 /* MEMC */ -#define ETHERH500_CTRLPORT 0x800 /* IOC */ - -#define ETHERH600_DATAPORT 0x040 /* MEMC */ -#define ETHERH600_NS8390 0x800 /* MEMC */ -#define ETHERH600_CTRLPORT 0x200 /* MEMC */ - -#define ETHERH_CP_IE 1 -#define ETHERH_CP_IF 2 -#define ETHERH_CP_HEARTBEAT 2 - -#define ETHERH_TX_START_PAGE 1 -#define ETHERH_STOP_PAGE 127 - -/* - * These came from CK/TEW - */ -#define ETHERM_DATAPORT 0x200 /* MEMC */ -#define ETHERM_NS8390 0x800 /* MEMC */ -#define ETHERM_CTRLPORT 0x23c /* MEMC */ - -#define ETHERM_TX_START_PAGE 64 -#define ETHERM_STOP_PAGE 127 - -/* ------------------------------------------------------------------------ */ - -#define etherh_priv(dev) \ - ((struct etherh_priv *)(((char *)netdev_priv(dev)) + sizeof(struct ei_device))) - -static inline void etherh_set_ctrl(struct etherh_priv *eh, unsigned char mask) -{ - unsigned char ctrl = eh->ctrl | mask; - eh->ctrl = ctrl; - writeb(ctrl, eh->ctrl_port); -} - -static inline void etherh_clr_ctrl(struct etherh_priv *eh, unsigned char mask) -{ - unsigned char ctrl = eh->ctrl & ~mask; - eh->ctrl = ctrl; - writeb(ctrl, eh->ctrl_port); -} - -static inline unsigned int etherh_get_stat(struct etherh_priv *eh) -{ - return readb(eh->ctrl_port); -} - - - - -static void etherh_irq_enable(ecard_t *ec, int irqnr) -{ - struct etherh_priv *eh = ec->irq_data; - - etherh_set_ctrl(eh, ETHERH_CP_IE); -} - -static void etherh_irq_disable(ecard_t *ec, int irqnr) -{ - struct etherh_priv *eh = ec->irq_data; - - etherh_clr_ctrl(eh, ETHERH_CP_IE); -} - -static expansioncard_ops_t etherh_ops = { - .irqenable = etherh_irq_enable, - .irqdisable = etherh_irq_disable, -}; - - - - -static void -etherh_setif(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - unsigned long flags; - void __iomem *addr; - - local_irq_save(flags); - - /* set the interface type */ - switch (etherh_priv(dev)->id) { - case PROD_I3_ETHERLAN600: - case PROD_I3_ETHERLAN600A: - addr = (void __iomem *)dev->base_addr + EN0_RCNTHI; - - switch (dev->if_port) { - case IF_PORT_10BASE2: - writeb((readb(addr) & 0xf8) | 1, addr); - break; - case IF_PORT_10BASET: - writeb((readb(addr) & 0xf8), addr); - break; - } - break; - - case PROD_I3_ETHERLAN500: - switch (dev->if_port) { - case IF_PORT_10BASE2: - etherh_clr_ctrl(etherh_priv(dev), ETHERH_CP_IF); - break; - - case IF_PORT_10BASET: - etherh_set_ctrl(etherh_priv(dev), ETHERH_CP_IF); - break; - } - break; - - default: - break; - } - - local_irq_restore(flags); -} - -static int -etherh_getifstat(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - void __iomem *addr; - int stat = 0; - - switch (etherh_priv(dev)->id) { - case PROD_I3_ETHERLAN600: - case PROD_I3_ETHERLAN600A: - addr = (void __iomem *)dev->base_addr + EN0_RCNTHI; - switch (dev->if_port) { - case IF_PORT_10BASE2: - stat = 1; - break; - case IF_PORT_10BASET: - stat = readb(addr) & 4; - break; - } - break; - - case PROD_I3_ETHERLAN500: - switch (dev->if_port) { - case IF_PORT_10BASE2: - stat = 1; - break; - case IF_PORT_10BASET: - stat = etherh_get_stat(etherh_priv(dev)) & ETHERH_CP_HEARTBEAT; - break; - } - break; - - default: - stat = 0; - break; - } - - return stat != 0; -} - -/* - * Configure the interface. Note that we ignore the other - * parts of ifmap, since its mostly meaningless for this driver. - */ -static int etherh_set_config(struct net_device *dev, struct ifmap *map) -{ - switch (map->port) { - case IF_PORT_10BASE2: - case IF_PORT_10BASET: - /* - * If the user explicitly sets the interface - * media type, turn off automedia detection. - */ - dev->flags &= ~IFF_AUTOMEDIA; - dev->if_port = map->port; - break; - - default: - return -EINVAL; - } - - etherh_setif(dev); - - return 0; -} - -/* - * Reset the 8390 (hard reset). Note that we can't actually do this. - */ -static void -etherh_reset(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - void __iomem *addr = (void __iomem *)dev->base_addr; - - writeb(E8390_NODMA+E8390_PAGE0+E8390_STOP, addr); - - /* - * See if we need to change the interface type. - * Note that we use 'interface_num' as a flag - * to indicate that we need to change the media. - */ - if (dev->flags & IFF_AUTOMEDIA && ei_local->interface_num) { - ei_local->interface_num = 0; - - if (dev->if_port == IF_PORT_10BASET) - dev->if_port = IF_PORT_10BASE2; - else - dev->if_port = IF_PORT_10BASET; - - etherh_setif(dev); - } -} - -/* - * Write a block of data out to the 8390 - */ -static void -etherh_block_output (struct net_device *dev, int count, const unsigned char *buf, int start_page) -{ - struct ei_device *ei_local = netdev_priv(dev); - unsigned long dma_start; - void __iomem *dma_base, *addr; - - if (ei_local->dmaing) { - netdev_err(dev, "DMAing conflict in etherh_block_input: " - " DMAstat %d irqlock %d\n", - ei_local->dmaing, ei_local->irqlock); - return; - } - - /* - * Make sure we have a round number of bytes if we're in word mode. - */ - if (count & 1 && ei_local->word16) - count++; - - ei_local->dmaing = 1; - - addr = (void __iomem *)dev->base_addr; - dma_base = etherh_priv(dev)->dma_base; - - count = (count + 1) & ~1; - writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); - - writeb (0x42, addr + EN0_RCNTLO); - writeb (0x00, addr + EN0_RCNTHI); - writeb (0x42, addr + EN0_RSARLO); - writeb (0x00, addr + EN0_RSARHI); - writeb (E8390_RREAD | E8390_START, addr + E8390_CMD); - - udelay (1); - - writeb (ENISR_RDC, addr + EN0_ISR); - writeb (count, addr + EN0_RCNTLO); - writeb (count >> 8, addr + EN0_RCNTHI); - writeb (0, addr + EN0_RSARLO); - writeb (start_page, addr + EN0_RSARHI); - writeb (E8390_RWRITE | E8390_START, addr + E8390_CMD); - - if (ei_local->word16) - writesw (dma_base, buf, count >> 1); - else - writesb (dma_base, buf, count); - - dma_start = jiffies; - - while ((readb (addr + EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ - netdev_warn(dev, "timeout waiting for TX RDC\n"); - etherh_reset (dev); - __NS8390_init (dev, 1); - break; - } - - writeb (ENISR_RDC, addr + EN0_ISR); - ei_local->dmaing = 0; -} - -/* - * Read a block of data from the 8390 - */ -static void -etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) -{ - struct ei_device *ei_local = netdev_priv(dev); - unsigned char *buf; - void __iomem *dma_base, *addr; - - if (ei_local->dmaing) { - netdev_err(dev, "DMAing conflict in etherh_block_input: " - " DMAstat %d irqlock %d\n", - ei_local->dmaing, ei_local->irqlock); - return; - } - - ei_local->dmaing = 1; - - addr = (void __iomem *)dev->base_addr; - dma_base = etherh_priv(dev)->dma_base; - - buf = skb->data; - writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); - writeb (count, addr + EN0_RCNTLO); - writeb (count >> 8, addr + EN0_RCNTHI); - writeb (ring_offset, addr + EN0_RSARLO); - writeb (ring_offset >> 8, addr + EN0_RSARHI); - writeb (E8390_RREAD | E8390_START, addr + E8390_CMD); - - if (ei_local->word16) { - readsw (dma_base, buf, count >> 1); - if (count & 1) - buf[count - 1] = readb (dma_base); - } else - readsb (dma_base, buf, count); - - writeb (ENISR_RDC, addr + EN0_ISR); - ei_local->dmaing = 0; -} - -/* - * Read a header from the 8390 - */ -static void -etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) -{ - struct ei_device *ei_local = netdev_priv(dev); - void __iomem *dma_base, *addr; - - if (ei_local->dmaing) { - netdev_err(dev, "DMAing conflict in etherh_get_header: " - " DMAstat %d irqlock %d\n", - ei_local->dmaing, ei_local->irqlock); - return; - } - - ei_local->dmaing = 1; - - addr = (void __iomem *)dev->base_addr; - dma_base = etherh_priv(dev)->dma_base; - - writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); - writeb (sizeof (*hdr), addr + EN0_RCNTLO); - writeb (0, addr + EN0_RCNTHI); - writeb (0, addr + EN0_RSARLO); - writeb (ring_page, addr + EN0_RSARHI); - writeb (E8390_RREAD | E8390_START, addr + E8390_CMD); - - if (ei_local->word16) - readsw (dma_base, hdr, sizeof (*hdr) >> 1); - else - readsb (dma_base, hdr, sizeof (*hdr)); - - writeb (ENISR_RDC, addr + EN0_ISR); - ei_local->dmaing = 0; -} - -/* - * Open/initialize the board. This is called (in the current kernel) - * sometime after booting when the 'ifconfig' program is run. - * - * This routine should set everything up anew at each open, even - * registers that "should" only need to be set once at boot, so that - * there is non-reboot way to recover if something goes wrong. - */ -static int -etherh_open(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - - if (request_irq(dev->irq, __ei_interrupt, 0, dev->name, dev)) - return -EAGAIN; - - /* - * Make sure that we aren't going to change the - * media type on the next reset - we are about to - * do automedia manually now. - */ - ei_local->interface_num = 0; - - /* - * If we are doing automedia detection, do it now. - * This is more reliable than the 8390's detection. - */ - if (dev->flags & IFF_AUTOMEDIA) { - dev->if_port = IF_PORT_10BASET; - etherh_setif(dev); - mdelay(1); - if (!etherh_getifstat(dev)) { - dev->if_port = IF_PORT_10BASE2; - etherh_setif(dev); - } - } else - etherh_setif(dev); - - etherh_reset(dev); - __ei_open(dev); - - return 0; -} - -/* - * The inverse routine to etherh_open(). - */ -static int -etherh_close(struct net_device *dev) -{ - __ei_close (dev); - free_irq (dev->irq, dev); - return 0; -} - -/* - * Read the ethernet address string from the on board rom. - * This is an ascii string... - */ -static int etherh_addr(char *addr, struct expansion_card *ec) -{ - struct in_chunk_dir cd; - char *s; - - if (!ecard_readchunk(&cd, ec, 0xf5, 0)) { - printk(KERN_ERR "%s: unable to read module description string\n", - dev_name(&ec->dev)); - goto no_addr; - } - - s = strchr(cd.d.string, '('); - if (s) { - int i; - - for (i = 0; i < 6; i++) { - addr[i] = simple_strtoul(s + 1, &s, 0x10); - if (*s != (i == 5? ')' : ':')) - break; - } - - if (i == 6) - return 0; - } - - printk(KERN_ERR "%s: unable to parse MAC address: %s\n", - dev_name(&ec->dev), cd.d.string); - - no_addr: - return -ENODEV; -} - -/* - * Create an ethernet address from the system serial number. - */ -static int __init etherm_addr(char *addr) -{ - unsigned int serial; - - if (system_serial_low == 0 && system_serial_high == 0) - return -ENODEV; - - serial = system_serial_low | system_serial_high; - - addr[0] = 0; - addr[1] = 0; - addr[2] = 0xa4; - addr[3] = 0x10 + (serial >> 24); - addr[4] = serial >> 16; - addr[5] = serial >> 8; - return 0; -} - -static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) -{ - strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); - strlcpy(info->version, DRV_VERSION, sizeof(info->version)); - strlcpy(info->bus_info, dev_name(dev->dev.parent), - sizeof(info->bus_info)); -} - -static int etherh_get_link_ksettings(struct net_device *dev, - struct ethtool_link_ksettings *cmd) -{ - ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, - etherh_priv(dev)->supported); - cmd->base.speed = SPEED_10; - cmd->base.duplex = DUPLEX_HALF; - cmd->base.port = dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC; - cmd->base.autoneg = (dev->flags & IFF_AUTOMEDIA ? AUTONEG_ENABLE : - AUTONEG_DISABLE); - return 0; -} - -static int etherh_set_link_ksettings(struct net_device *dev, - const struct ethtool_link_ksettings *cmd) -{ - switch (cmd->base.autoneg) { - case AUTONEG_ENABLE: - dev->flags |= IFF_AUTOMEDIA; - break; - - case AUTONEG_DISABLE: - switch (cmd->base.port) { - case PORT_TP: - dev->if_port = IF_PORT_10BASET; - break; - - case PORT_BNC: - dev->if_port = IF_PORT_10BASE2; - break; - - default: - return -EINVAL; - } - dev->flags &= ~IFF_AUTOMEDIA; - break; - - default: - return -EINVAL; - } - - etherh_setif(dev); - - return 0; -} - -static u32 etherh_get_msglevel(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - - return ei_local->msg_enable; -} - -static void etherh_set_msglevel(struct net_device *dev, u32 v) -{ - struct ei_device *ei_local = netdev_priv(dev); - - ei_local->msg_enable = v; -} - -static const struct ethtool_ops etherh_ethtool_ops = { - .get_drvinfo = etherh_get_drvinfo, - .get_ts_info = ethtool_op_get_ts_info, - .get_msglevel = etherh_get_msglevel, - .set_msglevel = etherh_set_msglevel, - .get_link_ksettings = etherh_get_link_ksettings, - .set_link_ksettings = etherh_set_link_ksettings, -}; - -static const struct net_device_ops etherh_netdev_ops = { - .ndo_open = etherh_open, - .ndo_stop = etherh_close, - .ndo_set_config = etherh_set_config, - .ndo_start_xmit = __ei_start_xmit, - .ndo_tx_timeout = __ei_tx_timeout, - .ndo_get_stats = __ei_get_stats, - .ndo_set_rx_mode = __ei_set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = __ei_poll, -#endif -}; - -static u32 etherh_regoffsets[16]; -static u32 etherm_regoffsets[16]; - -static int -etherh_probe(struct expansion_card *ec, const struct ecard_id *id) -{ - const struct etherh_data *data = id->data; - struct ei_device *ei_local; - struct net_device *dev; - struct etherh_priv *eh; - int ret; - - ret = ecard_request_resources(ec); - if (ret) - goto out; - - dev = ____alloc_ei_netdev(sizeof(struct etherh_priv)); - if (!dev) { - ret = -ENOMEM; - goto release; - } - - SET_NETDEV_DEV(dev, &ec->dev); - - dev->netdev_ops = ðerh_netdev_ops; - dev->irq = ec->irq; - dev->ethtool_ops = ðerh_ethtool_ops; - - if (data->supported & SUPPORTED_Autoneg) - dev->flags |= IFF_AUTOMEDIA; - if (data->supported & SUPPORTED_TP) { - dev->flags |= IFF_PORTSEL; - dev->if_port = IF_PORT_10BASET; - } else if (data->supported & SUPPORTED_BNC) { - dev->flags |= IFF_PORTSEL; - dev->if_port = IF_PORT_10BASE2; - } else - dev->if_port = IF_PORT_UNKNOWN; - - eh = etherh_priv(dev); - eh->supported = data->supported; - eh->ctrl = 0; - eh->id = ec->cid.product; - eh->memc = ecardm_iomap(ec, ECARD_RES_MEMC, 0, PAGE_SIZE); - if (!eh->memc) { - ret = -ENOMEM; - goto free; - } - - eh->ctrl_port = eh->memc; - if (data->ctrl_ioc) { - eh->ioc_fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, PAGE_SIZE); - if (!eh->ioc_fast) { - ret = -ENOMEM; - goto free; - } - eh->ctrl_port = eh->ioc_fast; - } - - dev->base_addr = (unsigned long)eh->memc + data->ns8390_offset; - eh->dma_base = eh->memc + data->dataport_offset; - eh->ctrl_port += data->ctrlport_offset; - - /* - * IRQ and control port handling - only for non-NIC slot cards. - */ - if (ec->slot_no != 8) { - ecard_setirq(ec, ðerh_ops, eh); - } else { - /* - * If we're in the NIC slot, make sure the IRQ is enabled - */ - etherh_set_ctrl(eh, ETHERH_CP_IE); - } - - ei_local = netdev_priv(dev); - spin_lock_init(&ei_local->page_lock); - - if (ec->cid.product == PROD_ANT_ETHERM) { - etherm_addr(dev->dev_addr); - ei_local->reg_offset = etherm_regoffsets; - } else { - etherh_addr(dev->dev_addr, ec); - ei_local->reg_offset = etherh_regoffsets; - } - - ei_local->name = dev->name; - ei_local->word16 = 1; - ei_local->tx_start_page = data->tx_start_page; - ei_local->rx_start_page = ei_local->tx_start_page + TX_PAGES; - ei_local->stop_page = data->stop_page; - ei_local->reset_8390 = etherh_reset; - ei_local->block_input = etherh_block_input; - ei_local->block_output = etherh_block_output; - ei_local->get_8390_hdr = etherh_get_header; - ei_local->interface_num = 0; - - etherh_reset(dev); - __NS8390_init(dev, 0); - - ret = register_netdev(dev); - if (ret) - goto free; - - netdev_info(dev, "%s in slot %d, %pM\n", - data->name, ec->slot_no, dev->dev_addr); - - ecard_set_drvdata(ec, dev); - - return 0; - - free: - free_netdev(dev); - release: - ecard_release_resources(ec); - out: - return ret; -} - -static void etherh_remove(struct expansion_card *ec) -{ - struct net_device *dev = ecard_get_drvdata(ec); - - ecard_set_drvdata(ec, NULL); - - unregister_netdev(dev); - - free_netdev(dev); - - ecard_release_resources(ec); -} - -static struct etherh_data etherm_data = { - .ns8390_offset = ETHERM_NS8390, - .dataport_offset = ETHERM_NS8390 + ETHERM_DATAPORT, - .ctrlport_offset = ETHERM_NS8390 + ETHERM_CTRLPORT, - .name = "ANT EtherM", - .supported = SUPPORTED_10baseT_Half, - .tx_start_page = ETHERM_TX_START_PAGE, - .stop_page = ETHERM_STOP_PAGE, -}; - -static struct etherh_data etherlan500_data = { - .ns8390_offset = ETHERH500_NS8390, - .dataport_offset = ETHERH500_NS8390 + ETHERH500_DATAPORT, - .ctrlport_offset = ETHERH500_CTRLPORT, - .ctrl_ioc = 1, - .name = "i3 EtherH 500", - .supported = SUPPORTED_10baseT_Half, - .tx_start_page = ETHERH_TX_START_PAGE, - .stop_page = ETHERH_STOP_PAGE, -}; - -static struct etherh_data etherlan600_data = { - .ns8390_offset = ETHERH600_NS8390, - .dataport_offset = ETHERH600_NS8390 + ETHERH600_DATAPORT, - .ctrlport_offset = ETHERH600_NS8390 + ETHERH600_CTRLPORT, - .name = "i3 EtherH 600", - .supported = SUPPORTED_10baseT_Half | SUPPORTED_TP | SUPPORTED_BNC | SUPPORTED_Autoneg, - .tx_start_page = ETHERH_TX_START_PAGE, - .stop_page = ETHERH_STOP_PAGE, -}; - -static struct etherh_data etherlan600a_data = { - .ns8390_offset = ETHERH600_NS8390, - .dataport_offset = ETHERH600_NS8390 + ETHERH600_DATAPORT, - .ctrlport_offset = ETHERH600_NS8390 + ETHERH600_CTRLPORT, - .name = "i3 EtherH 600A", - .supported = SUPPORTED_10baseT_Half | SUPPORTED_TP | SUPPORTED_BNC | SUPPORTED_Autoneg, - .tx_start_page = ETHERH_TX_START_PAGE, - .stop_page = ETHERH_STOP_PAGE, -}; - -static const struct ecard_id etherh_ids[] = { - { MANU_ANT, PROD_ANT_ETHERM, ðerm_data }, - { MANU_I3, PROD_I3_ETHERLAN500, ðerlan500_data }, - { MANU_I3, PROD_I3_ETHERLAN600, ðerlan600_data }, - { MANU_I3, PROD_I3_ETHERLAN600A, ðerlan600a_data }, - { 0xffff, 0xffff } -}; - -static struct ecard_driver etherh_driver = { - .probe = etherh_probe, - .remove = etherh_remove, - .id_table = etherh_ids, - .drv = { - .name = DRV_NAME, - }, -}; - -static int __init etherh_init(void) -{ - int i; - - for (i = 0; i < 16; i++) { - etherh_regoffsets[i] = i << 2; - etherm_regoffsets[i] = i << 5; - } - - return ecard_register_driver(ðerh_driver); -} - -static void __exit etherh_exit(void) -{ - ecard_remove_driver(ðerh_driver); -} - -module_init(etherh_init); -module_exit(etherh_exit); diff --git a/drivers/net/ethernet/8390/hydra.c b/drivers/net/ethernet/8390/hydra.c deleted file mode 100644 index 941754ea78ec..000000000000 --- a/drivers/net/ethernet/8390/hydra.c +++ /dev/null @@ -1,273 +0,0 @@ -/* New Hydra driver using generic 8390 core */ -/* Based on old hydra driver by Topi Kanerva (topi@susanna.oulu.fi) */ - -/* This file is subject to the terms and conditions of the GNU General */ -/* Public License. See the file COPYING in the main directory of the */ -/* Linux distribution for more details. */ - -/* Peter De Schrijver (p2@mind.be) */ -/* Oldenburg 2000 */ - -/* The Amiganet is a Zorro-II board made by Hydra Systems. It contains a */ -/* NS8390 NIC (network interface controller) clone, 16 or 64K on-board RAM */ -/* and 10BASE-2 (thin coax) and AUI connectors. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define EI_SHIFT(x) (ei_local->reg_offset[x]) -#define ei_inb(port) in_8(port) -#define ei_outb(val,port) out_8(port,val) -#define ei_inb_p(port) in_8(port) -#define ei_outb_p(val,port) out_8(port,val) - -static const char version[] = - "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; - -#include "lib8390.c" - -#define NE_EN0_DCFG (0x0e*2) - -#define NESM_START_PG 0x0 /* First page of TX buffer */ -#define NESM_STOP_PG 0x40 /* Last page +1 of RX ring */ - -#define HYDRA_NIC_BASE 0xffe1 -#define HYDRA_ADDRPROM 0xffc0 -#define HYDRA_VERSION "v3.0alpha" - -#define WORDSWAP(a) ((((a)>>8)&0xff) | ((a)<<8)) - - -static int hydra_init_one(struct zorro_dev *z, - const struct zorro_device_id *ent); -static int hydra_init(struct zorro_dev *z); -static int hydra_open(struct net_device *dev); -static int hydra_close(struct net_device *dev); -static void hydra_reset_8390(struct net_device *dev); -static void hydra_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page); -static void hydra_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void hydra_block_output(struct net_device *dev, int count, - const unsigned char *buf, int start_page); -static void hydra_remove_one(struct zorro_dev *z); - -static struct zorro_device_id hydra_zorro_tbl[] = { - { ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET }, - { 0 } -}; -MODULE_DEVICE_TABLE(zorro, hydra_zorro_tbl); - -static struct zorro_driver hydra_driver = { - .name = "hydra", - .id_table = hydra_zorro_tbl, - .probe = hydra_init_one, - .remove = hydra_remove_one, -}; - -static int hydra_init_one(struct zorro_dev *z, - const struct zorro_device_id *ent) -{ - int err; - - if (!request_mem_region(z->resource.start, 0x10000, "Hydra")) - return -EBUSY; - if ((err = hydra_init(z))) { - release_mem_region(z->resource.start, 0x10000); - return -EBUSY; - } - return 0; -} - -static const struct net_device_ops hydra_netdev_ops = { - .ndo_open = hydra_open, - .ndo_stop = hydra_close, - - .ndo_start_xmit = __ei_start_xmit, - .ndo_tx_timeout = __ei_tx_timeout, - .ndo_get_stats = __ei_get_stats, - .ndo_set_rx_mode = __ei_set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = __ei_poll, -#endif -}; - -static int hydra_init(struct zorro_dev *z) -{ - struct net_device *dev; - unsigned long board = (unsigned long)ZTWO_VADDR(z->resource.start); - unsigned long ioaddr = board+HYDRA_NIC_BASE; - const char name[] = "NE2000"; - int start_page, stop_page; - int j; - int err; - - static u32 hydra_offsets[16] = { - 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, - 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, - }; - - dev = ____alloc_ei_netdev(0); - if (!dev) - return -ENOMEM; - - for (j = 0; j < ETH_ALEN; j++) - dev->dev_addr[j] = *((u8 *)(board + HYDRA_ADDRPROM + 2*j)); - - /* We must set the 8390 for word mode. */ - z_writeb(0x4b, ioaddr + NE_EN0_DCFG); - start_page = NESM_START_PG; - stop_page = NESM_STOP_PG; - - dev->base_addr = ioaddr; - dev->irq = IRQ_AMIGA_PORTS; - - /* Install the Interrupt handler */ - if (request_irq(IRQ_AMIGA_PORTS, __ei_interrupt, IRQF_SHARED, "Hydra Ethernet", - dev)) { - free_netdev(dev); - return -EAGAIN; - } - - ei_status.name = name; - ei_status.tx_start_page = start_page; - ei_status.stop_page = stop_page; - ei_status.word16 = 1; - ei_status.bigendian = 1; - - ei_status.rx_start_page = start_page + TX_PAGES; - - ei_status.reset_8390 = hydra_reset_8390; - ei_status.block_input = hydra_block_input; - ei_status.block_output = hydra_block_output; - ei_status.get_8390_hdr = hydra_get_8390_hdr; - ei_status.reg_offset = hydra_offsets; - - dev->netdev_ops = &hydra_netdev_ops; - __NS8390_init(dev, 0); - - err = register_netdev(dev); - if (err) { - free_irq(IRQ_AMIGA_PORTS, dev); - free_netdev(dev); - return err; - } - - zorro_set_drvdata(z, dev); - - pr_info("%s: Hydra at %pR, address %pM (hydra.c " HYDRA_VERSION ")\n", - dev->name, &z->resource, dev->dev_addr); - - return 0; -} - -static int hydra_open(struct net_device *dev) -{ - __ei_open(dev); - return 0; -} - -static int hydra_close(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - - netif_dbg(ei_local, ifdown, dev, "Shutting down ethercard.\n"); - __ei_close(dev); - return 0; -} - -static void hydra_reset_8390(struct net_device *dev) -{ - netdev_info(dev, "Hydra hw reset not there\n"); -} - -static void hydra_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page) -{ - int nic_base = dev->base_addr; - short *ptrs; - unsigned long hdr_start= (nic_base-HYDRA_NIC_BASE) + - ((ring_page - NESM_START_PG)<<8); - ptrs = (short *)hdr; - - *(ptrs++) = z_readw(hdr_start); - *((short *)hdr) = WORDSWAP(*((short *)hdr)); - hdr_start += 2; - *(ptrs++) = z_readw(hdr_start); - *((short *)hdr+1) = WORDSWAP(*((short *)hdr+1)); -} - -static void hydra_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) -{ - unsigned long nic_base = dev->base_addr; - unsigned long mem_base = nic_base - HYDRA_NIC_BASE; - unsigned long xfer_start = mem_base + ring_offset - (NESM_START_PG<<8); - - if (count&1) - count++; - - if (xfer_start+count > mem_base + (NESM_STOP_PG<<8)) { - int semi_count = (mem_base + (NESM_STOP_PG<<8)) - xfer_start; - - z_memcpy_fromio(skb->data,xfer_start,semi_count); - count -= semi_count; - z_memcpy_fromio(skb->data+semi_count, mem_base, count); - } else - z_memcpy_fromio(skb->data, xfer_start,count); - -} - -static void hydra_block_output(struct net_device *dev, int count, - const unsigned char *buf, int start_page) -{ - unsigned long nic_base = dev->base_addr; - unsigned long mem_base = nic_base - HYDRA_NIC_BASE; - - if (count&1) - count++; - - z_memcpy_toio(mem_base+((start_page - NESM_START_PG)<<8), buf, count); -} - -static void hydra_remove_one(struct zorro_dev *z) -{ - struct net_device *dev = zorro_get_drvdata(z); - - unregister_netdev(dev); - free_irq(IRQ_AMIGA_PORTS, dev); - release_mem_region(ZTWO_PADDR(dev->base_addr)-HYDRA_NIC_BASE, 0x10000); - free_netdev(dev); -} - -static int __init hydra_init_module(void) -{ - return zorro_register_driver(&hydra_driver); -} - -static void __exit hydra_cleanup_module(void) -{ - zorro_unregister_driver(&hydra_driver); -} - -module_init(hydra_init_module); -module_exit(hydra_cleanup_module); - -MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/8390/lib8390.c b/drivers/net/ethernet/8390/lib8390.c deleted file mode 100644 index e84021282edf..000000000000 --- a/drivers/net/ethernet/8390/lib8390.c +++ /dev/null @@ -1,1092 +0,0 @@ -/* 8390.c: A general NS8390 ethernet driver core for linux. */ -/* - Written 1992-94 by Donald Becker. - - Copyright 1993 United States Government as represented by the - Director, National Security Agency. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - The author may be reached as becker@scyld.com, or C/O - Scyld Computing Corporation - 410 Severn Ave., Suite 210 - Annapolis MD 21403 - - - This is the chip-specific code for many 8390-based ethernet adaptors. - This is not a complete driver, it must be combined with board-specific - code such as ne.c, wd.c, 3c503.c, etc. - - Seeing how at least eight drivers use this code, (not counting the - PCMCIA ones either) it is easy to break some card by what seems like - a simple innocent change. Please contact me or Donald if you think - you have found something that needs changing. -- PG - - - Changelog: - - Paul Gortmaker : remove set_bit lock, other cleanups. - Paul Gortmaker : add ei_get_8390_hdr() so we can pass skb's to - ei_block_input() for eth_io_copy_and_sum(). - Paul Gortmaker : exchange static int ei_pingpong for a #define, - also add better Tx error handling. - Paul Gortmaker : rewrite Rx overrun handling as per NS specs. - Alexey Kuznetsov : use the 8390's six bit hash multicast filter. - Paul Gortmaker : tweak ANK's above multicast changes a bit. - Paul Gortmaker : update packet statistics for v2.1.x - Alan Cox : support arbitrary stupid port mappings on the - 68K Macintosh. Support >16bit I/O spaces - Paul Gortmaker : add kmod support for auto-loading of the 8390 - module by all drivers that require it. - Alan Cox : Spinlocking work, added 'BUG_83C690' - Paul Gortmaker : Separate out Tx timeout code from Tx path. - Paul Gortmaker : Remove old unused single Tx buffer code. - Hayato Fujiwara : Add m32r support. - Paul Gortmaker : use skb_padto() instead of stack scratch area - - Sources: - The National Semiconductor LAN Databook, and the 3Com 3c503 databook. - - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define NS8390_CORE -#include "8390.h" - -#define BUG_83C690 - -/* These are the operational function interfaces to board-specific - routines. - void reset_8390(struct net_device *dev) - Resets the board associated with DEV, including a hardware reset of - the 8390. This is only called when there is a transmit timeout, and - it is always followed by 8390_init(). - void block_output(struct net_device *dev, int count, const unsigned char *buf, - int start_page) - Write the COUNT bytes of BUF to the packet buffer at START_PAGE. The - "page" value uses the 8390's 256-byte pages. - void get_8390_hdr(struct net_device *dev, struct e8390_hdr *hdr, int ring_page) - Read the 4 byte, page aligned 8390 header. *If* there is a - subsequent read, it will be of the rest of the packet. - void block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) - Read COUNT bytes from the packet buffer into the skb data area. Start - reading from RING_OFFSET, the address as the 8390 sees it. This will always - follow the read of the 8390 header. -*/ -#define ei_reset_8390 (ei_local->reset_8390) -#define ei_block_output (ei_local->block_output) -#define ei_block_input (ei_local->block_input) -#define ei_get_8390_hdr (ei_local->get_8390_hdr) - -/* Index to functions. */ -static void ei_tx_intr(struct net_device *dev); -static void ei_tx_err(struct net_device *dev); -static void ei_receive(struct net_device *dev); -static void ei_rx_overrun(struct net_device *dev); - -/* Routines generic to NS8390-based boards. */ -static void NS8390_trigger_send(struct net_device *dev, unsigned int length, - int start_page); -static void do_set_multicast_list(struct net_device *dev); -static void __NS8390_init(struct net_device *dev, int startp); - -static unsigned version_printed; -static int msg_enable; -static const int default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_RX_ERR | - NETIF_MSG_TX_ERR); -module_param(msg_enable, int, 0444); -MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)"); - -/* - * SMP and the 8390 setup. - * - * The 8390 isn't exactly designed to be multithreaded on RX/TX. There is - * a page register that controls bank and packet buffer access. We guard - * this with ei_local->page_lock. Nobody should assume or set the page other - * than zero when the lock is not held. Lock holders must restore page 0 - * before unlocking. Even pure readers must take the lock to protect in - * page 0. - * - * To make life difficult the chip can also be very slow. We therefore can't - * just use spinlocks. For the longer lockups we disable the irq the device - * sits on and hold the lock. We must hold the lock because there is a dual - * processor case other than interrupts (get stats/set multicast list in - * parallel with each other and transmit). - * - * Note: in theory we can just disable the irq on the card _but_ there is - * a latency on SMP irq delivery. So we can easily go "disable irq" "sync irqs" - * enter lock, take the queued irq. So we waddle instead of flying. - * - * Finally by special arrangement for the purpose of being generally - * annoying the transmit function is called bh atomic. That places - * restrictions on the user context callers as disable_irq won't save - * them. - * - * Additional explanation of problems with locking by Alan Cox: - * - * "The author (me) didn't use spin_lock_irqsave because the slowness of the - * card means that approach caused horrible problems like losing serial data - * at 38400 baud on some chips. Remember many 8390 nics on PCI were ISA - * chips with FPGA front ends. - * - * Ok the logic behind the 8390 is very simple: - * - * Things to know - * - IRQ delivery is asynchronous to the PCI bus - * - Blocking the local CPU IRQ via spin locks was too slow - * - The chip has register windows needing locking work - * - * So the path was once (I say once as people appear to have changed it - * in the mean time and it now looks rather bogus if the changes to use - * disable_irq_nosync_irqsave are disabling the local IRQ) - * - * - * Take the page lock - * Mask the IRQ on chip - * Disable the IRQ (but not mask locally- someone seems to have - * broken this with the lock validator stuff) - * [This must be _nosync as the page lock may otherwise - * deadlock us] - * Drop the page lock and turn IRQs back on - * - * At this point an existing IRQ may still be running but we can't - * get a new one - * - * Take the lock (so we know the IRQ has terminated) but don't mask - * the IRQs on the processor - * Set irqlock [for debug] - * - * Transmit (slow as ****) - * - * re-enable the IRQ - * - * - * We have to use disable_irq because otherwise you will get delayed - * interrupts on the APIC bus deadlocking the transmit path. - * - * Quite hairy but the chip simply wasn't designed for SMP and you can't - * even ACK an interrupt without risking corrupting other parallel - * activities on the chip." [lkml, 25 Jul 2007] - */ - - - -/** - * ei_open - Open/initialize the board. - * @dev: network device to initialize - * - * This routine goes all-out, setting everything - * up anew at each open, even though many of these registers should only - * need to be set once at boot. - */ -static int __ei_open(struct net_device *dev) -{ - unsigned long flags; - struct ei_device *ei_local = netdev_priv(dev); - - if (dev->watchdog_timeo <= 0) - dev->watchdog_timeo = TX_TIMEOUT; - - /* - * Grab the page lock so we own the register set, then call - * the init function. - */ - - spin_lock_irqsave(&ei_local->page_lock, flags); - __NS8390_init(dev, 1); - /* Set the flag before we drop the lock, That way the IRQ arrives - after its set and we get no silly warnings */ - netif_start_queue(dev); - spin_unlock_irqrestore(&ei_local->page_lock, flags); - ei_local->irqlock = 0; - return 0; -} - -/** - * ei_close - shut down network device - * @dev: network device to close - * - * Opposite of ei_open(). Only used when "ifconfig down" is done. - */ -static int __ei_close(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - unsigned long flags; - - /* - * Hold the page lock during close - */ - - spin_lock_irqsave(&ei_local->page_lock, flags); - __NS8390_init(dev, 0); - spin_unlock_irqrestore(&ei_local->page_lock, flags); - netif_stop_queue(dev); - return 0; -} - -/** - * ei_tx_timeout - handle transmit time out condition - * @dev: network device which has apparently fallen asleep - * - * Called by kernel when device never acknowledges a transmit has - * completed (or failed) - i.e. never posted a Tx related interrupt. - */ - -static void __ei_tx_timeout(struct net_device *dev, unsigned int txqueue) -{ - unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); - int txsr, isr, tickssofar = jiffies - dev_trans_start(dev); - unsigned long flags; - - dev->stats.tx_errors++; - - spin_lock_irqsave(&ei_local->page_lock, flags); - txsr = ei_inb(e8390_base+EN0_TSR); - isr = ei_inb(e8390_base+EN0_ISR); - spin_unlock_irqrestore(&ei_local->page_lock, flags); - - netdev_dbg(dev, "Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d\n", - (txsr & ENTSR_ABT) ? "excess collisions." : - (isr) ? "lost interrupt?" : "cable problem?", - txsr, isr, tickssofar); - - if (!isr && !dev->stats.tx_packets) { - /* The 8390 probably hasn't gotten on the cable yet. */ - ei_local->interface_num ^= 1; /* Try a different xcvr. */ - } - - /* Ugly but a reset can be slow, yet must be protected */ - - disable_irq_nosync_lockdep(dev->irq); - spin_lock(&ei_local->page_lock); - - /* Try to restart the card. Perhaps the user has fixed something. */ - ei_reset_8390(dev); - __NS8390_init(dev, 1); - - spin_unlock(&ei_local->page_lock); - enable_irq_lockdep(dev->irq); - netif_wake_queue(dev); -} - -/** - * ei_start_xmit - begin packet transmission - * @skb: packet to be sent - * @dev: network device to which packet is sent - * - * Sends a packet to an 8390 network device. - */ - -static netdev_tx_t __ei_start_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); - int send_length = skb->len, output_page; - unsigned long flags; - char buf[ETH_ZLEN]; - char *data = skb->data; - - if (skb->len < ETH_ZLEN) { - memset(buf, 0, ETH_ZLEN); /* more efficient than doing just the needed bits */ - memcpy(buf, data, skb->len); - send_length = ETH_ZLEN; - data = buf; - } - - /* Mask interrupts from the ethercard. - SMP: We have to grab the lock here otherwise the IRQ handler - on another CPU can flip window and race the IRQ mask set. We end - up trashing the mcast filter not disabling irqs if we don't lock */ - - spin_lock_irqsave(&ei_local->page_lock, flags); - ei_outb_p(0x00, e8390_base + EN0_IMR); - spin_unlock_irqrestore(&ei_local->page_lock, flags); - - - /* - * Slow phase with lock held. - */ - - disable_irq_nosync_lockdep_irqsave(dev->irq, &flags); - - spin_lock(&ei_local->page_lock); - - ei_local->irqlock = 1; - - /* - * We have two Tx slots available for use. Find the first free - * slot, and then perform some sanity checks. With two Tx bufs, - * you get very close to transmitting back-to-back packets. With - * only one Tx buf, the transmitter sits idle while you reload the - * card, leaving a substantial gap between each transmitted packet. - */ - - if (ei_local->tx1 == 0) { - output_page = ei_local->tx_start_page; - ei_local->tx1 = send_length; - if ((netif_msg_tx_queued(ei_local)) && - ei_local->tx2 > 0) - netdev_dbg(dev, - "idle transmitter tx2=%d, lasttx=%d, txing=%d\n", - ei_local->tx2, ei_local->lasttx, ei_local->txing); - } else if (ei_local->tx2 == 0) { - output_page = ei_local->tx_start_page + TX_PAGES/2; - ei_local->tx2 = send_length; - if ((netif_msg_tx_queued(ei_local)) && - ei_local->tx1 > 0) - netdev_dbg(dev, - "idle transmitter, tx1=%d, lasttx=%d, txing=%d\n", - ei_local->tx1, ei_local->lasttx, ei_local->txing); - } else { /* We should never get here. */ - netif_dbg(ei_local, tx_err, dev, - "No Tx buffers free! tx1=%d tx2=%d last=%d\n", - ei_local->tx1, ei_local->tx2, ei_local->lasttx); - ei_local->irqlock = 0; - netif_stop_queue(dev); - ei_outb_p(ENISR_ALL, e8390_base + EN0_IMR); - spin_unlock(&ei_local->page_lock); - enable_irq_lockdep_irqrestore(dev->irq, &flags); - dev->stats.tx_errors++; - return NETDEV_TX_BUSY; - } - - /* - * Okay, now upload the packet and trigger a send if the transmitter - * isn't already sending. If it is busy, the interrupt handler will - * trigger the send later, upon receiving a Tx done interrupt. - */ - - ei_block_output(dev, send_length, data, output_page); - - if (!ei_local->txing) { - ei_local->txing = 1; - NS8390_trigger_send(dev, send_length, output_page); - if (output_page == ei_local->tx_start_page) { - ei_local->tx1 = -1; - ei_local->lasttx = -1; - } else { - ei_local->tx2 = -1; - ei_local->lasttx = -2; - } - } else - ei_local->txqueue++; - - if (ei_local->tx1 && ei_local->tx2) - netif_stop_queue(dev); - else - netif_start_queue(dev); - - /* Turn 8390 interrupts back on. */ - ei_local->irqlock = 0; - ei_outb_p(ENISR_ALL, e8390_base + EN0_IMR); - - spin_unlock(&ei_local->page_lock); - enable_irq_lockdep_irqrestore(dev->irq, &flags); - skb_tx_timestamp(skb); - dev_consume_skb_any(skb); - dev->stats.tx_bytes += send_length; - - return NETDEV_TX_OK; -} - -/** - * ei_interrupt - handle the interrupts from an 8390 - * @irq: interrupt number - * @dev_id: a pointer to the net_device - * - * Handle the ether interface interrupts. We pull packets from - * the 8390 via the card specific functions and fire them at the networking - * stack. We also handle transmit completions and wake the transmit path if - * necessary. We also update the counters and do other housekeeping as - * needed. - */ - -static irqreturn_t __ei_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - unsigned long e8390_base = dev->base_addr; - int interrupts, nr_serviced = 0; - struct ei_device *ei_local = netdev_priv(dev); - - /* - * Protect the irq test too. - */ - - spin_lock(&ei_local->page_lock); - - if (ei_local->irqlock) { - /* - * This might just be an interrupt for a PCI device sharing - * this line - */ - netdev_err(dev, "Interrupted while interrupts are masked! isr=%#2x imr=%#2x\n", - ei_inb_p(e8390_base + EN0_ISR), - ei_inb_p(e8390_base + EN0_IMR)); - spin_unlock(&ei_local->page_lock); - return IRQ_NONE; - } - - /* Change to page 0 and read the intr status reg. */ - ei_outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD); - netif_dbg(ei_local, intr, dev, "interrupt(isr=%#2.2x)\n", - ei_inb_p(e8390_base + EN0_ISR)); - - /* !!Assumption!! -- we stay in page 0. Don't break this. */ - while ((interrupts = ei_inb_p(e8390_base + EN0_ISR)) != 0 && - ++nr_serviced < MAX_SERVICE) { - if (!netif_running(dev)) { - netdev_warn(dev, "interrupt from stopped card\n"); - /* rmk - acknowledge the interrupts */ - ei_outb_p(interrupts, e8390_base + EN0_ISR); - interrupts = 0; - break; - } - if (interrupts & ENISR_OVER) - ei_rx_overrun(dev); - else if (interrupts & (ENISR_RX+ENISR_RX_ERR)) { - /* Got a good (?) packet. */ - ei_receive(dev); - } - /* Push the next to-transmit packet through. */ - if (interrupts & ENISR_TX) - ei_tx_intr(dev); - else if (interrupts & ENISR_TX_ERR) - ei_tx_err(dev); - - if (interrupts & ENISR_COUNTERS) { - dev->stats.rx_frame_errors += ei_inb_p(e8390_base + EN0_COUNTER0); - dev->stats.rx_crc_errors += ei_inb_p(e8390_base + EN0_COUNTER1); - dev->stats.rx_missed_errors += ei_inb_p(e8390_base + EN0_COUNTER2); - ei_outb_p(ENISR_COUNTERS, e8390_base + EN0_ISR); /* Ack intr. */ - } - - /* Ignore any RDC interrupts that make it back to here. */ - if (interrupts & ENISR_RDC) - ei_outb_p(ENISR_RDC, e8390_base + EN0_ISR); - - ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD); - } - - if (interrupts && (netif_msg_intr(ei_local))) { - ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD); - if (nr_serviced >= MAX_SERVICE) { - /* 0xFF is valid for a card removal */ - if (interrupts != 0xFF) - netdev_warn(dev, "Too much work at interrupt, status %#2.2x\n", - interrupts); - ei_outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */ - } else { - netdev_warn(dev, "unknown interrupt %#2x\n", interrupts); - ei_outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */ - } - } - spin_unlock(&ei_local->page_lock); - return IRQ_RETVAL(nr_serviced > 0); -} - -#ifdef CONFIG_NET_POLL_CONTROLLER -static void __ei_poll(struct net_device *dev) -{ - disable_irq(dev->irq); - __ei_interrupt(dev->irq, dev); - enable_irq(dev->irq); -} -#endif - -/** - * ei_tx_err - handle transmitter error - * @dev: network device which threw the exception - * - * A transmitter error has happened. Most likely excess collisions (which - * is a fairly normal condition). If the error is one where the Tx will - * have been aborted, we try and send another one right away, instead of - * letting the failed packet sit and collect dust in the Tx buffer. This - * is a much better solution as it avoids kernel based Tx timeouts, and - * an unnecessary card reset. - * - * Called with lock held. - */ - -static void ei_tx_err(struct net_device *dev) -{ - unsigned long e8390_base = dev->base_addr; - /* ei_local is used on some platforms via the EI_SHIFT macro */ - struct ei_device *ei_local __maybe_unused = netdev_priv(dev); - unsigned char txsr = ei_inb_p(e8390_base+EN0_TSR); - unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU); - -#ifdef VERBOSE_ERROR_DUMP - netdev_dbg(dev, "transmitter error (%#2x):", txsr); - if (txsr & ENTSR_ABT) - pr_cont(" excess-collisions "); - if (txsr & ENTSR_ND) - pr_cont(" non-deferral "); - if (txsr & ENTSR_CRS) - pr_cont(" lost-carrier "); - if (txsr & ENTSR_FU) - pr_cont(" FIFO-underrun "); - if (txsr & ENTSR_CDH) - pr_cont(" lost-heartbeat "); - pr_cont("\n"); -#endif - - ei_outb_p(ENISR_TX_ERR, e8390_base + EN0_ISR); /* Ack intr. */ - - if (tx_was_aborted) - ei_tx_intr(dev); - else { - dev->stats.tx_errors++; - if (txsr & ENTSR_CRS) - dev->stats.tx_carrier_errors++; - if (txsr & ENTSR_CDH) - dev->stats.tx_heartbeat_errors++; - if (txsr & ENTSR_OWC) - dev->stats.tx_window_errors++; - } -} - -/** - * ei_tx_intr - transmit interrupt handler - * @dev: network device for which tx intr is handled - * - * We have finished a transmit: check for errors and then trigger the next - * packet to be sent. Called with lock held. - */ - -static void ei_tx_intr(struct net_device *dev) -{ - unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); - int status = ei_inb(e8390_base + EN0_TSR); - - ei_outb_p(ENISR_TX, e8390_base + EN0_ISR); /* Ack intr. */ - - /* - * There are two Tx buffers, see which one finished, and trigger - * the send of another one if it exists. - */ - ei_local->txqueue--; - - if (ei_local->tx1 < 0) { - if (ei_local->lasttx != 1 && ei_local->lasttx != -1) - pr_err("%s: bogus last_tx_buffer %d, tx1=%d\n", - ei_local->name, ei_local->lasttx, ei_local->tx1); - ei_local->tx1 = 0; - if (ei_local->tx2 > 0) { - ei_local->txing = 1; - NS8390_trigger_send(dev, ei_local->tx2, ei_local->tx_start_page + 6); - netif_trans_update(dev); - ei_local->tx2 = -1; - ei_local->lasttx = 2; - } else { - ei_local->lasttx = 20; - ei_local->txing = 0; - } - } else if (ei_local->tx2 < 0) { - if (ei_local->lasttx != 2 && ei_local->lasttx != -2) - pr_err("%s: bogus last_tx_buffer %d, tx2=%d\n", - ei_local->name, ei_local->lasttx, ei_local->tx2); - ei_local->tx2 = 0; - if (ei_local->tx1 > 0) { - ei_local->txing = 1; - NS8390_trigger_send(dev, ei_local->tx1, ei_local->tx_start_page); - netif_trans_update(dev); - ei_local->tx1 = -1; - ei_local->lasttx = 1; - } else { - ei_local->lasttx = 10; - ei_local->txing = 0; - } - } /* else - netdev_warn(dev, "unexpected TX-done interrupt, lasttx=%d\n", - ei_local->lasttx); -*/ - - /* Minimize Tx latency: update the statistics after we restart TXing. */ - if (status & ENTSR_COL) - dev->stats.collisions++; - if (status & ENTSR_PTX) - dev->stats.tx_packets++; - else { - dev->stats.tx_errors++; - if (status & ENTSR_ABT) { - dev->stats.tx_aborted_errors++; - dev->stats.collisions += 16; - } - if (status & ENTSR_CRS) - dev->stats.tx_carrier_errors++; - if (status & ENTSR_FU) - dev->stats.tx_fifo_errors++; - if (status & ENTSR_CDH) - dev->stats.tx_heartbeat_errors++; - if (status & ENTSR_OWC) - dev->stats.tx_window_errors++; - } - netif_wake_queue(dev); -} - -/** - * ei_receive - receive some packets - * @dev: network device with which receive will be run - * - * We have a good packet(s), get it/them out of the buffers. - * Called with lock held. - */ - -static void ei_receive(struct net_device *dev) -{ - unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); - unsigned char rxing_page, this_frame, next_frame; - unsigned short current_offset; - int rx_pkt_count = 0; - struct e8390_pkt_hdr rx_frame; - int num_rx_pages = ei_local->stop_page-ei_local->rx_start_page; - - while (++rx_pkt_count < 10) { - int pkt_len, pkt_stat; - - /* Get the rx page (incoming packet pointer). */ - ei_outb_p(E8390_NODMA+E8390_PAGE1, e8390_base + E8390_CMD); - rxing_page = ei_inb_p(e8390_base + EN1_CURPAG); - ei_outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD); - - /* Remove one frame from the ring. Boundary is always a page behind. */ - this_frame = ei_inb_p(e8390_base + EN0_BOUNDARY) + 1; - if (this_frame >= ei_local->stop_page) - this_frame = ei_local->rx_start_page; - - /* Someday we'll omit the previous, iff we never get this message. - (There is at least one clone claimed to have a problem.) - - Keep quiet if it looks like a card removal. One problem here - is that some clones crash in roughly the same way. - */ - if ((netif_msg_rx_status(ei_local)) && - this_frame != ei_local->current_page && - (this_frame != 0x0 || rxing_page != 0xFF)) - netdev_err(dev, - "mismatched read page pointers %2x vs %2x\n", - this_frame, ei_local->current_page); - - if (this_frame == rxing_page) /* Read all the frames? */ - break; /* Done for now */ - - current_offset = this_frame << 8; - ei_get_8390_hdr(dev, &rx_frame, this_frame); - - pkt_len = rx_frame.count - sizeof(struct e8390_pkt_hdr); - pkt_stat = rx_frame.status; - - next_frame = this_frame + 1 + ((pkt_len+4)>>8); - - /* Check for bogosity warned by 3c503 book: the status byte is never - written. This happened a lot during testing! This code should be - cleaned up someday. */ - if (rx_frame.next != next_frame && - rx_frame.next != next_frame + 1 && - rx_frame.next != next_frame - num_rx_pages && - rx_frame.next != next_frame + 1 - num_rx_pages) { - ei_local->current_page = rxing_page; - ei_outb(ei_local->current_page-1, e8390_base+EN0_BOUNDARY); - dev->stats.rx_errors++; - continue; - } - - if (pkt_len < 60 || pkt_len > 1518) { - netif_dbg(ei_local, rx_status, dev, - "bogus packet size: %d, status=%#2x nxpg=%#2x\n", - rx_frame.count, rx_frame.status, - rx_frame.next); - dev->stats.rx_errors++; - dev->stats.rx_length_errors++; - } else if ((pkt_stat & 0x0F) == ENRSR_RXOK) { - struct sk_buff *skb; - - skb = netdev_alloc_skb(dev, pkt_len + 2); - if (skb == NULL) { - netif_err(ei_local, rx_err, dev, - "Couldn't allocate a sk_buff of size %d\n", - pkt_len); - dev->stats.rx_dropped++; - break; - } else { - skb_reserve(skb, 2); /* IP headers on 16 byte boundaries */ - skb_put(skb, pkt_len); /* Make room */ - ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame)); - skb->protocol = eth_type_trans(skb, dev); - if (!skb_defer_rx_timestamp(skb)) - netif_rx(skb); - dev->stats.rx_packets++; - dev->stats.rx_bytes += pkt_len; - if (pkt_stat & ENRSR_PHY) - dev->stats.multicast++; - } - } else { - netif_err(ei_local, rx_err, dev, - "bogus packet: status=%#2x nxpg=%#2x size=%d\n", - rx_frame.status, rx_frame.next, - rx_frame.count); - dev->stats.rx_errors++; - /* NB: The NIC counts CRC, frame and missed errors. */ - if (pkt_stat & ENRSR_FO) - dev->stats.rx_fifo_errors++; - } - next_frame = rx_frame.next; - - /* This _should_ never happen: it's here for avoiding bad clones. */ - if (next_frame >= ei_local->stop_page) { - netdev_notice(dev, "next frame inconsistency, %#2x\n", - next_frame); - next_frame = ei_local->rx_start_page; - } - ei_local->current_page = next_frame; - ei_outb_p(next_frame-1, e8390_base+EN0_BOUNDARY); - } - - /* We used to also ack ENISR_OVER here, but that would sometimes mask - a real overrun, leaving the 8390 in a stopped state with rec'vr off. */ - ei_outb_p(ENISR_RX+ENISR_RX_ERR, e8390_base+EN0_ISR); -} - -/** - * ei_rx_overrun - handle receiver overrun - * @dev: network device which threw exception - * - * We have a receiver overrun: we have to kick the 8390 to get it started - * again. Problem is that you have to kick it exactly as NS prescribes in - * the updated datasheets, or "the NIC may act in an unpredictable manner." - * This includes causing "the NIC to defer indefinitely when it is stopped - * on a busy network." Ugh. - * Called with lock held. Don't call this with the interrupts off or your - * computer will hate you - it takes 10ms or so. - */ - -static void ei_rx_overrun(struct net_device *dev) -{ - unsigned long e8390_base = dev->base_addr; - unsigned char was_txing, must_resend = 0; - /* ei_local is used on some platforms via the EI_SHIFT macro */ - struct ei_device *ei_local __maybe_unused = netdev_priv(dev); - - /* - * Record whether a Tx was in progress and then issue the - * stop command. - */ - was_txing = ei_inb_p(e8390_base+E8390_CMD) & E8390_TRANS; - ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); - - netif_dbg(ei_local, rx_err, dev, "Receiver overrun\n"); - dev->stats.rx_over_errors++; - - /* - * Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total. - * Early datasheets said to poll the reset bit, but now they say that - * it "is not a reliable indicator and subsequently should be ignored." - * We wait at least 10ms. - */ - - mdelay(10); - - /* - * Reset RBCR[01] back to zero as per magic incantation. - */ - ei_outb_p(0x00, e8390_base+EN0_RCNTLO); - ei_outb_p(0x00, e8390_base+EN0_RCNTHI); - - /* - * See if any Tx was interrupted or not. According to NS, this - * step is vital, and skipping it will cause no end of havoc. - */ - - if (was_txing) { - unsigned char tx_completed = ei_inb_p(e8390_base+EN0_ISR) & (ENISR_TX+ENISR_TX_ERR); - if (!tx_completed) - must_resend = 1; - } - - /* - * Have to enter loopback mode and then restart the NIC before - * you are allowed to slurp packets up off the ring. - */ - ei_outb_p(E8390_TXOFF, e8390_base + EN0_TXCR); - ei_outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, e8390_base + E8390_CMD); - - /* - * Clear the Rx ring of all the debris, and ack the interrupt. - */ - ei_receive(dev); - ei_outb_p(ENISR_OVER, e8390_base+EN0_ISR); - - /* - * Leave loopback mode, and resend any packet that got stopped. - */ - ei_outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); - if (must_resend) - ei_outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START + E8390_TRANS, e8390_base + E8390_CMD); -} - -/* - * Collect the stats. This is called unlocked and from several contexts. - */ - -static struct net_device_stats *__ei_get_stats(struct net_device *dev) -{ - unsigned long ioaddr = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); - unsigned long flags; - - /* If the card is stopped, just return the present stats. */ - if (!netif_running(dev)) - return &dev->stats; - - spin_lock_irqsave(&ei_local->page_lock, flags); - /* Read the counter registers, assuming we are in page 0. */ - dev->stats.rx_frame_errors += ei_inb_p(ioaddr + EN0_COUNTER0); - dev->stats.rx_crc_errors += ei_inb_p(ioaddr + EN0_COUNTER1); - dev->stats.rx_missed_errors += ei_inb_p(ioaddr + EN0_COUNTER2); - spin_unlock_irqrestore(&ei_local->page_lock, flags); - - return &dev->stats; -} - -/* - * Form the 64 bit 8390 multicast table from the linked list of addresses - * associated with this dev structure. - */ - -static inline void make_mc_bits(u8 *bits, struct net_device *dev) -{ - struct netdev_hw_addr *ha; - - netdev_for_each_mc_addr(ha, dev) { - u32 crc = ether_crc(ETH_ALEN, ha->addr); - /* - * The 8390 uses the 6 most significant bits of the - * CRC to index the multicast table. - */ - bits[crc>>29] |= (1<<((crc>>26)&7)); - } -} - -/** - * do_set_multicast_list - set/clear multicast filter - * @dev: net device for which multicast filter is adjusted - * - * Set or clear the multicast filter for this adaptor. May be called - * from a BH in 2.1.x. Must be called with lock held. - */ - -static void do_set_multicast_list(struct net_device *dev) -{ - unsigned long e8390_base = dev->base_addr; - int i; - struct ei_device *ei_local = netdev_priv(dev); - - if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) { - memset(ei_local->mcfilter, 0, 8); - if (!netdev_mc_empty(dev)) - make_mc_bits(ei_local->mcfilter, dev); - } else - memset(ei_local->mcfilter, 0xFF, 8); /* mcast set to accept-all */ - - /* - * DP8390 manuals don't specify any magic sequence for altering - * the multicast regs on an already running card. To be safe, we - * ensure multicast mode is off prior to loading up the new hash - * table. If this proves to be not enough, we can always resort - * to stopping the NIC, loading the table and then restarting. - * - * Bug Alert! The MC regs on the SMC 83C690 (SMC Elite and SMC - * Elite16) appear to be write-only. The NS 8390 data sheet lists - * them as r/w so this is a bug. The SMC 83C790 (SMC Ultra and - * Ultra32 EISA) appears to have this bug fixed. - */ - - if (netif_running(dev)) - ei_outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); - ei_outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD); - for (i = 0; i < 8; i++) { - ei_outb_p(ei_local->mcfilter[i], e8390_base + EN1_MULT_SHIFT(i)); -#ifndef BUG_83C690 - if (ei_inb_p(e8390_base + EN1_MULT_SHIFT(i)) != ei_local->mcfilter[i]) - netdev_err(dev, "Multicast filter read/write mismap %d\n", - i); -#endif - } - ei_outb_p(E8390_NODMA + E8390_PAGE0, e8390_base + E8390_CMD); - - if (dev->flags&IFF_PROMISC) - ei_outb_p(E8390_RXCONFIG | 0x18, e8390_base + EN0_RXCR); - else if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev)) - ei_outb_p(E8390_RXCONFIG | 0x08, e8390_base + EN0_RXCR); - else - ei_outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); -} - -/* - * Called without lock held. This is invoked from user context and may - * be parallel to just about everything else. Its also fairly quick and - * not called too often. Must protect against both bh and irq users - */ - -static void __ei_set_multicast_list(struct net_device *dev) -{ - unsigned long flags; - struct ei_device *ei_local = netdev_priv(dev); - - spin_lock_irqsave(&ei_local->page_lock, flags); - do_set_multicast_list(dev); - spin_unlock_irqrestore(&ei_local->page_lock, flags); -} - -/** - * ethdev_setup - init rest of 8390 device struct - * @dev: network device structure to init - * - * Initialize the rest of the 8390 device structure. Do NOT __init - * this, as it is used by 8390 based modular drivers too. - */ - -static void ethdev_setup(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - - ether_setup(dev); - - spin_lock_init(&ei_local->page_lock); - - ei_local->msg_enable = netif_msg_init(msg_enable, default_msg_level); - - if (netif_msg_drv(ei_local) && (version_printed++ == 0)) - pr_info("%s", version); -} - -/** - * alloc_ei_netdev - alloc_etherdev counterpart for 8390 - * @size: extra bytes to allocate - * - * Allocate 8390-specific net_device. - */ -static struct net_device *____alloc_ei_netdev(int size) -{ - return alloc_netdev(sizeof(struct ei_device) + size, "eth%d", - NET_NAME_UNKNOWN, ethdev_setup); -} - - - - -/* This page of functions should be 8390 generic */ -/* Follow National Semi's recommendations for initializing the "NIC". */ - -/** - * NS8390_init - initialize 8390 hardware - * @dev: network device to initialize - * @startp: boolean. non-zero value to initiate chip processing - * - * Must be called with lock held. - */ - -static void __NS8390_init(struct net_device *dev, int startp) -{ - unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); - int i; - int endcfg = ei_local->word16 - ? (0x48 | ENDCFG_WTS | (ei_local->bigendian ? ENDCFG_BOS : 0)) - : 0x48; - - BUILD_BUG_ON(sizeof(struct e8390_pkt_hdr) != 4); - /* Follow National Semi's recommendations for initing the DP83902. */ - ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); /* 0x21 */ - ei_outb_p(endcfg, e8390_base + EN0_DCFG); /* 0x48 or 0x49 */ - /* Clear the remote byte count registers. */ - ei_outb_p(0x00, e8390_base + EN0_RCNTLO); - ei_outb_p(0x00, e8390_base + EN0_RCNTHI); - /* Set to monitor and loopback mode -- this is vital!. */ - ei_outb_p(E8390_RXOFF, e8390_base + EN0_RXCR); /* 0x20 */ - ei_outb_p(E8390_TXOFF, e8390_base + EN0_TXCR); /* 0x02 */ - /* Set the transmit page and receive ring. */ - ei_outb_p(ei_local->tx_start_page, e8390_base + EN0_TPSR); - ei_local->tx1 = ei_local->tx2 = 0; - ei_outb_p(ei_local->rx_start_page, e8390_base + EN0_STARTPG); - ei_outb_p(ei_local->stop_page-1, e8390_base + EN0_BOUNDARY); /* 3c503 says 0x3f,NS0x26*/ - ei_local->current_page = ei_local->rx_start_page; /* assert boundary+1 */ - ei_outb_p(ei_local->stop_page, e8390_base + EN0_STOPPG); - /* Clear the pending interrupts and mask. */ - ei_outb_p(0xFF, e8390_base + EN0_ISR); - ei_outb_p(0x00, e8390_base + EN0_IMR); - - /* Copy the station address into the DS8390 registers. */ - - ei_outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, e8390_base+E8390_CMD); /* 0x61 */ - for (i = 0; i < 6; i++) { - ei_outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i)); - if ((netif_msg_probe(ei_local)) && - ei_inb_p(e8390_base + EN1_PHYS_SHIFT(i)) != dev->dev_addr[i]) - netdev_err(dev, - "Hw. address read/write mismap %d\n", i); - } - - ei_outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG); - ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); - - ei_local->tx1 = ei_local->tx2 = 0; - ei_local->txing = 0; - - if (startp) { - ei_outb_p(0xff, e8390_base + EN0_ISR); - ei_outb_p(ENISR_ALL, e8390_base + EN0_IMR); - ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base+E8390_CMD); - ei_outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); /* xmit on. */ - /* 3c503 TechMan says rxconfig only after the NIC is started. */ - ei_outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); /* rx on, */ - do_set_multicast_list(dev); /* (re)load the mcast table */ - } -} - -/* Trigger a transmit start, assuming the length is valid. - Always called with the page lock held */ - -static void NS8390_trigger_send(struct net_device *dev, unsigned int length, - int start_page) -{ - unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local __attribute((unused)) = netdev_priv(dev); - - ei_outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD); - - if (ei_inb_p(e8390_base + E8390_CMD) & E8390_TRANS) { - netdev_warn(dev, "trigger_send() called with the transmitter busy\n"); - return; - } - ei_outb_p(length & 0xff, e8390_base + EN0_TCNTLO); - ei_outb_p(length >> 8, e8390_base + EN0_TCNTHI); - ei_outb_p(start_page, e8390_base + EN0_TPSR); - ei_outb_p(E8390_NODMA+E8390_TRANS+E8390_START, e8390_base+E8390_CMD); -} diff --git a/drivers/net/ethernet/8390/mac8390.c b/drivers/net/ethernet/8390/mac8390.c deleted file mode 100644 index 91b04abfd687..000000000000 --- a/drivers/net/ethernet/8390/mac8390.c +++ /dev/null @@ -1,848 +0,0 @@ -/* mac8390.c: New driver for 8390-based Nubus (or Nubus-alike) - Ethernet cards on Linux */ -/* Based on the former daynaport.c driver, by Alan Cox. Some code - taken from or inspired by skeleton.c by Donald Becker, acenic.c by - Jes Sorensen, and ne2k-pci.c by Donald Becker and Paul Gortmaker. - - This software may be used and distributed according to the terms of - the GNU Public License, incorporated herein by reference. */ - -/* 2000-02-28: support added for Dayna and Kinetics cards by - A.G.deWijn@phys.uu.nl */ -/* 2000-04-04: support added for Dayna2 by bart@etpmod.phys.tue.nl */ -/* 2001-04-18: support for DaynaPort E/LC-M by rayk@knightsmanor.org */ -/* 2001-05-15: support for Cabletron ported from old daynaport driver - * and fixed access to Sonic Sys card which masquerades as a Farallon - * by rayk@knightsmanor.org */ -/* 2002-12-30: Try to support more cards, some clues from NetBSD driver */ -/* 2003-12-26: Make sure Asante cards always work. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static char version[] = - "v0.4 2001-05-15 David Huggins-Daines and others\n"; - -#define EI_SHIFT(x) (ei_local->reg_offset[x]) -#define ei_inb(port) in_8(port) -#define ei_outb(val, port) out_8(port, val) -#define ei_inb_p(port) in_8(port) -#define ei_outb_p(val, port) out_8(port, val) - -#include "lib8390.c" - -#define WD_START_PG 0x00 /* First page of TX buffer */ -#define CABLETRON_RX_START_PG 0x00 /* First page of RX buffer */ -#define CABLETRON_RX_STOP_PG 0x30 /* Last page +1 of RX ring */ -#define CABLETRON_TX_START_PG CABLETRON_RX_STOP_PG - /* First page of TX buffer */ - -/* - * Unfortunately it seems we have to hardcode these for the moment - * Shouldn't the card know about this? - * Does anyone know where to read it off the card? - * Do we trust the data provided by the card? - */ - -#define DAYNA_8390_BASE 0x80000 -#define DAYNA_8390_MEM 0x00000 - -#define CABLETRON_8390_BASE 0x90000 -#define CABLETRON_8390_MEM 0x00000 - -#define INTERLAN_8390_BASE 0xE0000 -#define INTERLAN_8390_MEM 0xD0000 - -enum mac8390_type { - MAC8390_NONE = -1, - MAC8390_APPLE, - MAC8390_ASANTE, - MAC8390_FARALLON, - MAC8390_CABLETRON, - MAC8390_DAYNA, - MAC8390_INTERLAN, - MAC8390_KINETICS, -}; - -static const char *cardname[] = { - "apple", - "asante", - "farallon", - "cabletron", - "dayna", - "interlan", - "kinetics", -}; - -static const int word16[] = { - 1, /* apple */ - 1, /* asante */ - 1, /* farallon */ - 1, /* cabletron */ - 0, /* dayna */ - 1, /* interlan */ - 0, /* kinetics */ -}; - -/* on which cards do we use NuBus resources? */ -static const int useresources[] = { - 1, /* apple */ - 1, /* asante */ - 1, /* farallon */ - 0, /* cabletron */ - 0, /* dayna */ - 0, /* interlan */ - 0, /* kinetics */ -}; - -enum mac8390_access { - ACCESS_UNKNOWN = 0, - ACCESS_32, - ACCESS_16, -}; - -extern int mac8390_memtest(struct net_device *dev); -static int mac8390_initdev(struct net_device *dev, struct nubus_board *board, - enum mac8390_type type); - -static int mac8390_open(struct net_device *dev); -static int mac8390_close(struct net_device *dev); -static void mac8390_no_reset(struct net_device *dev); -static void interlan_reset(struct net_device *dev); - -/* Sane (32-bit chunk memory read/write) - Some Farallon and Apple do this*/ -static void sane_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page); -static void sane_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void sane_block_output(struct net_device *dev, int count, - const unsigned char *buf, const int start_page); - -/* dayna_memcpy to and from card */ -static void dayna_memcpy_fromcard(struct net_device *dev, void *to, - int from, int count); -static void dayna_memcpy_tocard(struct net_device *dev, int to, - const void *from, int count); - -/* Dayna - Dayna/Kinetics use this */ -static void dayna_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page); -static void dayna_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void dayna_block_output(struct net_device *dev, int count, - const unsigned char *buf, int start_page); - -/* Slow Sane (16-bit chunk memory read/write) Cabletron uses this */ -static void slow_sane_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page); -static void slow_sane_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void slow_sane_block_output(struct net_device *dev, int count, - const unsigned char *buf, int start_page); -static void word_memcpy_tocard(unsigned long tp, const void *fp, int count); -static void word_memcpy_fromcard(void *tp, unsigned long fp, int count); - -static enum mac8390_type mac8390_ident(struct nubus_rsrc *fres) -{ - switch (fres->dr_sw) { - case NUBUS_DRSW_3COM: - switch (fres->dr_hw) { - case NUBUS_DRHW_APPLE_SONIC_NB: - case NUBUS_DRHW_APPLE_SONIC_LC: - case NUBUS_DRHW_SONNET: - return MAC8390_NONE; - default: - return MAC8390_APPLE; - } - - case NUBUS_DRSW_APPLE: - switch (fres->dr_hw) { - case NUBUS_DRHW_ASANTE_LC: - return MAC8390_NONE; - case NUBUS_DRHW_CABLETRON: - return MAC8390_CABLETRON; - default: - return MAC8390_APPLE; - } - - case NUBUS_DRSW_ASANTE: - return MAC8390_ASANTE; - - case NUBUS_DRSW_TECHWORKS: - case NUBUS_DRSW_DAYNA2: - case NUBUS_DRSW_DAYNA_LC: - if (fres->dr_hw == NUBUS_DRHW_CABLETRON) - return MAC8390_CABLETRON; - else - return MAC8390_APPLE; - - case NUBUS_DRSW_FARALLON: - return MAC8390_FARALLON; - - case NUBUS_DRSW_KINETICS: - switch (fres->dr_hw) { - case NUBUS_DRHW_INTERLAN: - return MAC8390_INTERLAN; - default: - return MAC8390_KINETICS; - } - - case NUBUS_DRSW_DAYNA: - /* - * These correspond to Dayna Sonic cards - * which use the macsonic driver - */ - if (fres->dr_hw == NUBUS_DRHW_SMC9194 || - fres->dr_hw == NUBUS_DRHW_INTERLAN) - return MAC8390_NONE; - else - return MAC8390_DAYNA; - } - return MAC8390_NONE; -} - -static enum mac8390_access mac8390_testio(unsigned long membase) -{ - u32 outdata = 0xA5A0B5B0; - u32 indata = 0; - - /* Try writing 32 bits */ - nubus_writel(outdata, membase); - /* Now read it back */ - indata = nubus_readl(membase); - if (outdata == indata) - return ACCESS_32; - - outdata = 0xC5C0D5D0; - indata = 0; - - /* Write 16 bit output */ - word_memcpy_tocard(membase, &outdata, 4); - /* Now read it back */ - word_memcpy_fromcard(&indata, membase, 4); - if (outdata == indata) - return ACCESS_16; - - return ACCESS_UNKNOWN; -} - -static int mac8390_memsize(unsigned long membase) -{ - unsigned long flags; - int i, j; - - local_irq_save(flags); - /* Check up to 32K in 4K increments */ - for (i = 0; i < 8; i++) { - volatile unsigned short *m = (unsigned short *)(membase + (i * 0x1000)); - - /* Unwriteable - we have a fully decoded card and the - RAM end located */ - if (hwreg_present(m) == 0) - break; - - /* write a distinctive byte */ - *m = 0xA5A0 | i; - /* check that we read back what we wrote */ - if (*m != (0xA5A0 | i)) - break; - - /* check for partial decode and wrap */ - for (j = 0; j < i; j++) { - volatile unsigned short *p = (unsigned short *)(membase + (j * 0x1000)); - if (*p != (0xA5A0 | j)) - break; - } - } - local_irq_restore(flags); - /* - * in any case, we stopped once we tried one block too many, - * or once we reached 32K - */ - return i * 0x1000; -} - -static bool mac8390_rsrc_init(struct net_device *dev, - struct nubus_rsrc *fres, - enum mac8390_type cardtype) -{ - struct nubus_board *board = fres->board; - struct nubus_dir dir; - struct nubus_dirent ent; - int offset; - volatile unsigned short *i; - - dev->irq = SLOT2IRQ(board->slot); - /* This is getting to be a habit */ - dev->base_addr = board->slot_addr | ((board->slot & 0xf) << 20); - - /* - * Get some Nubus info - we will trust the card's idea - * of where its memory and registers are. - */ - - if (nubus_get_func_dir(fres, &dir) == -1) { - dev_err(&board->dev, - "Unable to get Nubus functional directory\n"); - return false; - } - - /* Get the MAC address */ - if (nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent) == -1) { - dev_info(&board->dev, "MAC address resource not found\n"); - return false; - } - - nubus_get_rsrc_mem(dev->dev_addr, &ent, 6); - - if (useresources[cardtype] == 1) { - nubus_rewinddir(&dir); - if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_BASEOS, - &ent) == -1) { - dev_err(&board->dev, - "Memory offset resource not found\n"); - return false; - } - nubus_get_rsrc_mem(&offset, &ent, 4); - dev->mem_start = dev->base_addr + offset; - /* yes, this is how the Apple driver does it */ - dev->base_addr = dev->mem_start + 0x10000; - nubus_rewinddir(&dir); - if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_LENGTH, - &ent) == -1) { - dev_info(&board->dev, - "Memory length resource not found, probing\n"); - offset = mac8390_memsize(dev->mem_start); - } else { - nubus_get_rsrc_mem(&offset, &ent, 4); - } - dev->mem_end = dev->mem_start + offset; - } else { - switch (cardtype) { - case MAC8390_KINETICS: - case MAC8390_DAYNA: /* it's the same */ - dev->base_addr = (int)(board->slot_addr + - DAYNA_8390_BASE); - dev->mem_start = (int)(board->slot_addr + - DAYNA_8390_MEM); - dev->mem_end = dev->mem_start + - mac8390_memsize(dev->mem_start); - break; - case MAC8390_INTERLAN: - dev->base_addr = (int)(board->slot_addr + - INTERLAN_8390_BASE); - dev->mem_start = (int)(board->slot_addr + - INTERLAN_8390_MEM); - dev->mem_end = dev->mem_start + - mac8390_memsize(dev->mem_start); - break; - case MAC8390_CABLETRON: - dev->base_addr = (int)(board->slot_addr + - CABLETRON_8390_BASE); - dev->mem_start = (int)(board->slot_addr + - CABLETRON_8390_MEM); - /* The base address is unreadable if 0x00 - * has been written to the command register - * Reset the chip by writing E8390_NODMA + - * E8390_PAGE0 + E8390_STOP just to be - * sure - */ - i = (void *)dev->base_addr; - *i = 0x21; - dev->mem_end = dev->mem_start + - mac8390_memsize(dev->mem_start); - break; - - default: - dev_err(&board->dev, - "No known base address for card type\n"); - return false; - } - } - - return true; -} - -static int mac8390_device_probe(struct nubus_board *board) -{ - struct net_device *dev; - int err = -ENODEV; - struct nubus_rsrc *fres; - enum mac8390_type cardtype = MAC8390_NONE; - - dev = ____alloc_ei_netdev(0); - if (!dev) - return -ENOMEM; - - SET_NETDEV_DEV(dev, &board->dev); - - for_each_board_func_rsrc(board, fres) { - if (fres->category != NUBUS_CAT_NETWORK || - fres->type != NUBUS_TYPE_ETHERNET) - continue; - - cardtype = mac8390_ident(fres); - if (cardtype == MAC8390_NONE) - continue; - - if (mac8390_rsrc_init(dev, fres, cardtype)) - break; - } - if (!fres) - goto out; - - err = mac8390_initdev(dev, board, cardtype); - if (err) - goto out; - - err = register_netdev(dev); - if (err) - goto out; - - nubus_set_drvdata(board, dev); - return 0; - -out: - free_netdev(dev); - return err; -} - -static void mac8390_device_remove(struct nubus_board *board) -{ - struct net_device *dev = nubus_get_drvdata(board); - - unregister_netdev(dev); - free_netdev(dev); -} - -static struct nubus_driver mac8390_driver = { - .probe = mac8390_device_probe, - .remove = mac8390_device_remove, - .driver = { - .name = KBUILD_MODNAME, - .owner = THIS_MODULE, - } -}; - -MODULE_AUTHOR("David Huggins-Daines and others"); -MODULE_DESCRIPTION("Macintosh NS8390-based Nubus Ethernet driver"); -MODULE_LICENSE("GPL"); - -static int __init mac8390_init(void) -{ - return nubus_driver_register(&mac8390_driver); -} -module_init(mac8390_init); - -static void __exit mac8390_exit(void) -{ - nubus_driver_unregister(&mac8390_driver); -} -module_exit(mac8390_exit); - -static const struct net_device_ops mac8390_netdev_ops = { - .ndo_open = mac8390_open, - .ndo_stop = mac8390_close, - .ndo_start_xmit = __ei_start_xmit, - .ndo_tx_timeout = __ei_tx_timeout, - .ndo_get_stats = __ei_get_stats, - .ndo_set_rx_mode = __ei_set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = __ei_poll, -#endif -}; - -static int mac8390_initdev(struct net_device *dev, struct nubus_board *board, - enum mac8390_type type) -{ - static u32 fwrd4_offsets[16] = { - 0, 4, 8, 12, - 16, 20, 24, 28, - 32, 36, 40, 44, - 48, 52, 56, 60 - }; - static u32 back4_offsets[16] = { - 60, 56, 52, 48, - 44, 40, 36, 32, - 28, 24, 20, 16, - 12, 8, 4, 0 - }; - static u32 fwrd2_offsets[16] = { - 0, 2, 4, 6, - 8, 10, 12, 14, - 16, 18, 20, 22, - 24, 26, 28, 30 - }; - - int access_bitmode = 0; - - /* Now fill in our stuff */ - dev->netdev_ops = &mac8390_netdev_ops; - - /* GAR, ei_status is actually a macro even though it looks global */ - ei_status.name = cardname[type]; - ei_status.word16 = word16[type]; - - /* Cabletron's TX/RX buffers are backwards */ - if (type == MAC8390_CABLETRON) { - ei_status.tx_start_page = CABLETRON_TX_START_PG; - ei_status.rx_start_page = CABLETRON_RX_START_PG; - ei_status.stop_page = CABLETRON_RX_STOP_PG; - ei_status.rmem_start = dev->mem_start; - ei_status.rmem_end = dev->mem_start + CABLETRON_RX_STOP_PG*256; - } else { - ei_status.tx_start_page = WD_START_PG; - ei_status.rx_start_page = WD_START_PG + TX_PAGES; - ei_status.stop_page = (dev->mem_end - dev->mem_start)/256; - ei_status.rmem_start = dev->mem_start + TX_PAGES*256; - ei_status.rmem_end = dev->mem_end; - } - - /* Fill in model-specific information and functions */ - switch (type) { - case MAC8390_FARALLON: - case MAC8390_APPLE: - switch (mac8390_testio(dev->mem_start)) { - case ACCESS_UNKNOWN: - dev_err(&board->dev, - "Don't know how to access card memory\n"); - return -ENODEV; - - case ACCESS_16: - /* 16 bit card, register map is reversed */ - ei_status.reset_8390 = mac8390_no_reset; - ei_status.block_input = slow_sane_block_input; - ei_status.block_output = slow_sane_block_output; - ei_status.get_8390_hdr = slow_sane_get_8390_hdr; - ei_status.reg_offset = back4_offsets; - break; - - case ACCESS_32: - /* 32 bit card, register map is reversed */ - ei_status.reset_8390 = mac8390_no_reset; - ei_status.block_input = sane_block_input; - ei_status.block_output = sane_block_output; - ei_status.get_8390_hdr = sane_get_8390_hdr; - ei_status.reg_offset = back4_offsets; - access_bitmode = 1; - break; - } - break; - - case MAC8390_ASANTE: - /* Some Asante cards pass the 32 bit test - * but overwrite system memory when run at 32 bit. - * so we run them all at 16 bit. - */ - ei_status.reset_8390 = mac8390_no_reset; - ei_status.block_input = slow_sane_block_input; - ei_status.block_output = slow_sane_block_output; - ei_status.get_8390_hdr = slow_sane_get_8390_hdr; - ei_status.reg_offset = back4_offsets; - break; - - case MAC8390_CABLETRON: - /* 16 bit card, register map is short forward */ - ei_status.reset_8390 = mac8390_no_reset; - ei_status.block_input = slow_sane_block_input; - ei_status.block_output = slow_sane_block_output; - ei_status.get_8390_hdr = slow_sane_get_8390_hdr; - ei_status.reg_offset = fwrd2_offsets; - break; - - case MAC8390_DAYNA: - case MAC8390_KINETICS: - /* 16 bit memory, register map is forward */ - /* dayna and similar */ - ei_status.reset_8390 = mac8390_no_reset; - ei_status.block_input = dayna_block_input; - ei_status.block_output = dayna_block_output; - ei_status.get_8390_hdr = dayna_get_8390_hdr; - ei_status.reg_offset = fwrd4_offsets; - break; - - case MAC8390_INTERLAN: - /* 16 bit memory, register map is forward */ - ei_status.reset_8390 = interlan_reset; - ei_status.block_input = slow_sane_block_input; - ei_status.block_output = slow_sane_block_output; - ei_status.get_8390_hdr = slow_sane_get_8390_hdr; - ei_status.reg_offset = fwrd4_offsets; - break; - - default: - dev_err(&board->dev, "Unsupported card type\n"); - return -ENODEV; - } - - __NS8390_init(dev, 0); - - /* Good, done, now spit out some messages */ - dev_info(&board->dev, "%s (type %s)\n", board->name, cardname[type]); - dev_info(&board->dev, "MAC %pM, IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n", - dev->dev_addr, dev->irq, - (unsigned int)(dev->mem_end - dev->mem_start) >> 10, - dev->mem_start, access_bitmode ? 32 : 16); - return 0; -} - -static int mac8390_open(struct net_device *dev) -{ - int err; - - __ei_open(dev); - err = request_irq(dev->irq, __ei_interrupt, 0, "8390 Ethernet", dev); - if (err) - pr_err("%s: unable to get IRQ %d\n", dev->name, dev->irq); - return err; -} - -static int mac8390_close(struct net_device *dev) -{ - free_irq(dev->irq, dev); - __ei_close(dev); - return 0; -} - -static void mac8390_no_reset(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - - ei_status.txing = 0; - netif_info(ei_local, hw, dev, "reset not supported\n"); -} - -static void interlan_reset(struct net_device *dev) -{ - unsigned char *target = nubus_slot_addr(IRQ2SLOT(dev->irq)); - struct ei_device *ei_local = netdev_priv(dev); - - netif_info(ei_local, hw, dev, "Need to reset the NS8390 t=%lu...", - jiffies); - ei_status.txing = 0; - target[0xC0000] = 0; - if (netif_msg_hw(ei_local)) - pr_cont("reset complete\n"); -} - -/* dayna_memcpy_fromio/dayna_memcpy_toio */ -/* directly from daynaport.c by Alan Cox */ -static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, - int count) -{ - volatile unsigned char *ptr; - unsigned char *target = to; - from <<= 1; /* word, skip overhead */ - ptr = (unsigned char *)(dev->mem_start+from); - /* Leading byte? */ - if (from & 2) { - *target++ = ptr[-1]; - ptr += 2; - count--; - } - while (count >= 2) { - *(unsigned short *)target = *(unsigned short volatile *)ptr; - ptr += 4; /* skip cruft */ - target += 2; - count -= 2; - } - /* Trailing byte? */ - if (count) - *target = *ptr; -} - -static void dayna_memcpy_tocard(struct net_device *dev, int to, - const void *from, int count) -{ - volatile unsigned short *ptr; - const unsigned char *src = from; - to <<= 1; /* word, skip overhead */ - ptr = (unsigned short *)(dev->mem_start+to); - /* Leading byte? */ - if (to & 2) { /* avoid a byte write (stomps on other data) */ - ptr[-1] = (ptr[-1]&0xFF00)|*src++; - ptr++; - count--; - } - while (count >= 2) { - *ptr++ = *(unsigned short *)src; /* Copy and */ - ptr++; /* skip cruft */ - src += 2; - count -= 2; - } - /* Trailing byte? */ - if (count) { - /* card doesn't like byte writes */ - *ptr = (*ptr & 0x00FF) | (*src << 8); - } -} - -/* sane block input/output */ -static void sane_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page) -{ - unsigned long hdr_start = (ring_page - WD_START_PG)<<8; - memcpy_fromio(hdr, (void __iomem *)dev->mem_start + hdr_start, 4); - /* Fix endianness */ - hdr->count = swab16(hdr->count); -} - -static void sane_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) -{ - unsigned long xfer_base = ring_offset - (WD_START_PG<<8); - unsigned long xfer_start = xfer_base + dev->mem_start; - - if (xfer_start + count > ei_status.rmem_end) { - /* We must wrap the input move. */ - int semi_count = ei_status.rmem_end - xfer_start; - memcpy_fromio(skb->data, - (void __iomem *)dev->mem_start + xfer_base, - semi_count); - count -= semi_count; - memcpy_fromio(skb->data + semi_count, - (void __iomem *)ei_status.rmem_start, count); - } else { - memcpy_fromio(skb->data, - (void __iomem *)dev->mem_start + xfer_base, - count); - } -} - -static void sane_block_output(struct net_device *dev, int count, - const unsigned char *buf, int start_page) -{ - long shmem = (start_page - WD_START_PG)<<8; - - memcpy_toio((void __iomem *)dev->mem_start + shmem, buf, count); -} - -/* dayna block input/output */ -static void dayna_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page) -{ - unsigned long hdr_start = (ring_page - WD_START_PG)<<8; - - dayna_memcpy_fromcard(dev, hdr, hdr_start, 4); - /* Fix endianness */ - hdr->count = (hdr->count & 0xFF) << 8 | (hdr->count >> 8); -} - -static void dayna_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) -{ - unsigned long xfer_base = ring_offset - (WD_START_PG<<8); - unsigned long xfer_start = xfer_base+dev->mem_start; - - /* Note the offset math is done in card memory space which is word - per long onto our space. */ - - if (xfer_start + count > ei_status.rmem_end) { - /* We must wrap the input move. */ - int semi_count = ei_status.rmem_end - xfer_start; - dayna_memcpy_fromcard(dev, skb->data, xfer_base, semi_count); - count -= semi_count; - dayna_memcpy_fromcard(dev, skb->data + semi_count, - ei_status.rmem_start - dev->mem_start, - count); - } else { - dayna_memcpy_fromcard(dev, skb->data, xfer_base, count); - } -} - -static void dayna_block_output(struct net_device *dev, int count, - const unsigned char *buf, - int start_page) -{ - long shmem = (start_page - WD_START_PG)<<8; - - dayna_memcpy_tocard(dev, shmem, buf, count); -} - -/* Cabletron block I/O */ -static void slow_sane_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, - int ring_page) -{ - unsigned long hdr_start = (ring_page - WD_START_PG)<<8; - word_memcpy_fromcard(hdr, dev->mem_start + hdr_start, 4); - /* Register endianism - fix here rather than 8390.c */ - hdr->count = (hdr->count&0xFF)<<8|(hdr->count>>8); -} - -static void slow_sane_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) -{ - unsigned long xfer_base = ring_offset - (WD_START_PG<<8); - unsigned long xfer_start = xfer_base+dev->mem_start; - - if (xfer_start + count > ei_status.rmem_end) { - /* We must wrap the input move. */ - int semi_count = ei_status.rmem_end - xfer_start; - word_memcpy_fromcard(skb->data, dev->mem_start + xfer_base, - semi_count); - count -= semi_count; - word_memcpy_fromcard(skb->data + semi_count, - ei_status.rmem_start, count); - } else { - word_memcpy_fromcard(skb->data, dev->mem_start + xfer_base, - count); - } -} - -static void slow_sane_block_output(struct net_device *dev, int count, - const unsigned char *buf, int start_page) -{ - long shmem = (start_page - WD_START_PG)<<8; - - word_memcpy_tocard(dev->mem_start + shmem, buf, count); -} - -static void word_memcpy_tocard(unsigned long tp, const void *fp, int count) -{ - volatile unsigned short *to = (void *)tp; - const unsigned short *from = fp; - - count++; - count /= 2; - - while (count--) - *to++ = *from++; -} - -static void word_memcpy_fromcard(void *tp, unsigned long fp, int count) -{ - unsigned short *to = tp; - const volatile unsigned short *from = (const void *)fp; - - count++; - count /= 2; - - while (count--) - *to++ = *from++; -} - - diff --git a/drivers/net/ethernet/8390/mcf8390.c b/drivers/net/ethernet/8390/mcf8390.c deleted file mode 100644 index 4ad8031ab669..000000000000 --- a/drivers/net/ethernet/8390/mcf8390.c +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Support for ColdFire CPU based boards using a NS8390 Ethernet device. - * - * Derived from the many other 8390 drivers. - * - * (C) Copyright 2012, Greg Ungerer - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const char version[] = - "mcf8390.c: (15-06-2012) Greg Ungerer "; - -#define NE_CMD 0x00 -#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset */ -#define NE_RESET 0x1f /* Issue a read to reset ,a write to clear */ -#define NE_EN0_ISR 0x07 -#define NE_EN0_DCFG 0x0e -#define NE_EN0_RSARLO 0x08 -#define NE_EN0_RSARHI 0x09 -#define NE_EN0_RCNTLO 0x0a -#define NE_EN0_RXCR 0x0c -#define NE_EN0_TXCR 0x0d -#define NE_EN0_RCNTHI 0x0b -#define NE_EN0_IMR 0x0f - -#define NESM_START_PG 0x40 /* First page of TX buffer */ -#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ - -#ifdef NE2000_ODDOFFSET -/* - * A lot of the ColdFire boards use a separate address region for odd offset - * register addresses. The following functions convert and map as required. - * Note that the data port accesses are treated a little differently, and - * always accessed via the insX/outsX functions. - */ -static inline u32 NE_PTR(u32 addr) -{ - if (addr & 1) - return addr - 1 + NE2000_ODDOFFSET; - return addr; -} - -static inline u32 NE_DATA_PTR(u32 addr) -{ - return addr; -} - -void ei_outb(u32 val, u32 addr) -{ - NE2000_BYTE *rp; - - rp = (NE2000_BYTE *) NE_PTR(addr); - *rp = RSWAP(val); -} - -#define ei_inb ei_inb -u8 ei_inb(u32 addr) -{ - NE2000_BYTE *rp, val; - - rp = (NE2000_BYTE *) NE_PTR(addr); - val = *rp; - return (u8) (RSWAP(val) & 0xff); -} - -void ei_insb(u32 addr, void *vbuf, int len) -{ - NE2000_BYTE *rp, val; - u8 *buf; - - buf = (u8 *) vbuf; - rp = (NE2000_BYTE *) NE_DATA_PTR(addr); - for (; (len > 0); len--) { - val = *rp; - *buf++ = RSWAP(val); - } -} - -void ei_insw(u32 addr, void *vbuf, int len) -{ - volatile u16 *rp; - u16 w, *buf; - - buf = (u16 *) vbuf; - rp = (volatile u16 *) NE_DATA_PTR(addr); - for (; (len > 0); len--) { - w = *rp; - *buf++ = BSWAP(w); - } -} - -void ei_outsb(u32 addr, const void *vbuf, int len) -{ - NE2000_BYTE *rp, val; - u8 *buf; - - buf = (u8 *) vbuf; - rp = (NE2000_BYTE *) NE_DATA_PTR(addr); - for (; (len > 0); len--) { - val = *buf++; - *rp = RSWAP(val); - } -} - -void ei_outsw(u32 addr, const void *vbuf, int len) -{ - volatile u16 *rp; - u16 w, *buf; - - buf = (u16 *) vbuf; - rp = (volatile u16 *) NE_DATA_PTR(addr); - for (; (len > 0); len--) { - w = *buf++; - *rp = BSWAP(w); - } -} - -#else /* !NE2000_ODDOFFSET */ - -#define ei_inb inb -#define ei_outb outb -#define ei_insb insb -#define ei_insw insw -#define ei_outsb outsb -#define ei_outsw outsw - -#endif /* !NE2000_ODDOFFSET */ - -#define ei_inb_p ei_inb -#define ei_outb_p ei_outb - -#include "lib8390.c" - -/* - * Hard reset the card. This used to pause for the same period that a - * 8390 reset command required, but that shouldn't be necessary. - */ -static void mcf8390_reset_8390(struct net_device *dev) -{ - unsigned long reset_start_time = jiffies; - u32 addr = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); - - netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies); - - ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET); - - ei_status.txing = 0; - ei_status.dmaing = 0; - - /* This check _should_not_ be necessary, omit eventually. */ - while ((ei_inb(addr + NE_EN0_ISR) & ENISR_RESET) == 0) { - if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) { - netdev_warn(dev, "%s: did not complete\n", __func__); - break; - } - } - - ei_outb(ENISR_RESET, addr + NE_EN0_ISR); -} - -/* - * This *shouldn't* happen. - * If it does, it's the last thing you'll see - */ -static void mcf8390_dmaing_err(const char *func, struct net_device *dev, - struct ei_device *ei_local) -{ - netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n", - func, ei_local->dmaing, ei_local->irqlock); -} - -/* - * Grab the 8390 specific header. Similar to the block_input routine, but - * we don't need to be concerned with ring wrap as the header will be at - * the start of a page, so we optimize accordingly. - */ -static void mcf8390_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page) -{ - struct ei_device *ei_local = netdev_priv(dev); - u32 addr = dev->base_addr; - - if (ei_local->dmaing) { - mcf8390_dmaing_err(__func__, dev, ei_local); - return; - } - - ei_local->dmaing |= 0x01; - ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, addr + NE_CMD); - ei_outb(ENISR_RDC, addr + NE_EN0_ISR); - ei_outb(sizeof(struct e8390_pkt_hdr), addr + NE_EN0_RCNTLO); - ei_outb(0, addr + NE_EN0_RCNTHI); - ei_outb(0, addr + NE_EN0_RSARLO); /* On page boundary */ - ei_outb(ring_page, addr + NE_EN0_RSARHI); - ei_outb(E8390_RREAD + E8390_START, addr + NE_CMD); - - ei_insw(addr + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr) >> 1); - - outb(ENISR_RDC, addr + NE_EN0_ISR); /* Ack intr */ - ei_local->dmaing &= ~0x01; - - hdr->count = cpu_to_le16(hdr->count); -} - -/* - * Block input and output, similar to the Crynwr packet driver. - * If you are porting to a new ethercard, look at the packet driver source - * for hints. The NEx000 doesn't share the on-board packet memory -- - * you have to put the packet out through the "remote DMA" dataport - * using z_writeb. - */ -static void mcf8390_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) -{ - struct ei_device *ei_local = netdev_priv(dev); - u32 addr = dev->base_addr; - char *buf = skb->data; - - if (ei_local->dmaing) { - mcf8390_dmaing_err(__func__, dev, ei_local); - return; - } - - ei_local->dmaing |= 0x01; - ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, addr + NE_CMD); - ei_outb(ENISR_RDC, addr + NE_EN0_ISR); - ei_outb(count & 0xff, addr + NE_EN0_RCNTLO); - ei_outb(count >> 8, addr + NE_EN0_RCNTHI); - ei_outb(ring_offset & 0xff, addr + NE_EN0_RSARLO); - ei_outb(ring_offset >> 8, addr + NE_EN0_RSARHI); - ei_outb(E8390_RREAD + E8390_START, addr + NE_CMD); - - ei_insw(addr + NE_DATAPORT, buf, count >> 1); - if (count & 1) - buf[count - 1] = ei_inb(addr + NE_DATAPORT); - - ei_outb(ENISR_RDC, addr + NE_EN0_ISR); /* Ack intr */ - ei_local->dmaing &= ~0x01; -} - -static void mcf8390_block_output(struct net_device *dev, int count, - const unsigned char *buf, - const int start_page) -{ - struct ei_device *ei_local = netdev_priv(dev); - u32 addr = dev->base_addr; - unsigned long dma_start; - - /* Make sure we transfer all bytes if 16bit IO writes */ - if (count & 0x1) - count++; - - if (ei_local->dmaing) { - mcf8390_dmaing_err(__func__, dev, ei_local); - return; - } - - ei_local->dmaing |= 0x01; - /* We should already be in page 0, but to be safe... */ - ei_outb(E8390_PAGE0 + E8390_START + E8390_NODMA, addr + NE_CMD); - - ei_outb(ENISR_RDC, addr + NE_EN0_ISR); - - /* Now the normal output. */ - ei_outb(count & 0xff, addr + NE_EN0_RCNTLO); - ei_outb(count >> 8, addr + NE_EN0_RCNTHI); - ei_outb(0x00, addr + NE_EN0_RSARLO); - ei_outb(start_page, addr + NE_EN0_RSARHI); - ei_outb(E8390_RWRITE + E8390_START, addr + NE_CMD); - - ei_outsw(addr + NE_DATAPORT, buf, count >> 1); - - dma_start = jiffies; - while ((ei_inb(addr + NE_EN0_ISR) & ENISR_RDC) == 0) { - if (time_after(jiffies, dma_start + 2 * HZ / 100)) { /* 20ms */ - netdev_warn(dev, "timeout waiting for Tx RDC\n"); - mcf8390_reset_8390(dev); - __NS8390_init(dev, 1); - break; - } - } - - ei_outb(ENISR_RDC, addr + NE_EN0_ISR); /* Ack intr */ - ei_local->dmaing &= ~0x01; -} - -static const struct net_device_ops mcf8390_netdev_ops = { - .ndo_open = __ei_open, - .ndo_stop = __ei_close, - .ndo_start_xmit = __ei_start_xmit, - .ndo_tx_timeout = __ei_tx_timeout, - .ndo_get_stats = __ei_get_stats, - .ndo_set_rx_mode = __ei_set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = __ei_poll, -#endif -}; - -static int mcf8390_init(struct net_device *dev) -{ - static u32 offsets[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - }; - struct ei_device *ei_local = netdev_priv(dev); - unsigned char SA_prom[32]; - u32 addr = dev->base_addr; - int start_page, stop_page; - int i, ret; - - mcf8390_reset_8390(dev); - - /* - * Read the 16 bytes of station address PROM. - * We must first initialize registers, - * similar to NS8390_init(eifdev, 0). - * We can't reliably read the SAPROM address without this. - * (I learned the hard way!). - */ - { - static const struct { - u32 value; - u32 offset; - } program_seq[] = { - {E8390_NODMA + E8390_PAGE0 + E8390_STOP, NE_CMD}, - /* Select page 0 */ - {0x48, NE_EN0_DCFG}, /* 0x48: Set byte-wide access */ - {0x00, NE_EN0_RCNTLO}, /* Clear the count regs */ - {0x00, NE_EN0_RCNTHI}, - {0x00, NE_EN0_IMR}, /* Mask completion irq */ - {0xFF, NE_EN0_ISR}, - {E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */ - {E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode */ - {32, NE_EN0_RCNTLO}, - {0x00, NE_EN0_RCNTHI}, - {0x00, NE_EN0_RSARLO}, /* DMA starting at 0x0000 */ - {0x00, NE_EN0_RSARHI}, - {E8390_RREAD + E8390_START, NE_CMD}, - }; - for (i = 0; i < ARRAY_SIZE(program_seq); i++) { - ei_outb(program_seq[i].value, - addr + program_seq[i].offset); - } - } - - for (i = 0; i < 16; i++) { - SA_prom[i] = ei_inb(addr + NE_DATAPORT); - ei_inb(addr + NE_DATAPORT); - } - - /* We must set the 8390 for word mode. */ - ei_outb(0x49, addr + NE_EN0_DCFG); - start_page = NESM_START_PG; - stop_page = NESM_STOP_PG; - - /* Install the Interrupt handler */ - ret = request_irq(dev->irq, __ei_interrupt, 0, dev->name, dev); - if (ret) - return ret; - - for (i = 0; i < ETH_ALEN; i++) - dev->dev_addr[i] = SA_prom[i]; - - netdev_dbg(dev, "Found ethernet address: %pM\n", dev->dev_addr); - - ei_local->name = "mcf8390"; - ei_local->tx_start_page = start_page; - ei_local->stop_page = stop_page; - ei_local->word16 = 1; - ei_local->rx_start_page = start_page + TX_PAGES; - ei_local->reset_8390 = mcf8390_reset_8390; - ei_local->block_input = mcf8390_block_input; - ei_local->block_output = mcf8390_block_output; - ei_local->get_8390_hdr = mcf8390_get_8390_hdr; - ei_local->reg_offset = offsets; - - dev->netdev_ops = &mcf8390_netdev_ops; - __NS8390_init(dev, 0); - ret = register_netdev(dev); - if (ret) { - free_irq(dev->irq, dev); - return ret; - } - - netdev_info(dev, "addr=0x%08x irq=%d, Ethernet Address %pM\n", - addr, dev->irq, dev->dev_addr); - return 0; -} - -static int mcf8390_probe(struct platform_device *pdev) -{ - struct net_device *dev; - struct resource *mem, *irq; - resource_size_t msize; - int ret; - - irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (irq == NULL) { - dev_err(&pdev->dev, "no IRQ specified?\n"); - return -ENXIO; - } - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (mem == NULL) { - dev_err(&pdev->dev, "no memory address specified?\n"); - return -ENXIO; - } - msize = resource_size(mem); - if (!request_mem_region(mem->start, msize, pdev->name)) - return -EBUSY; - - dev = ____alloc_ei_netdev(0); - if (dev == NULL) { - release_mem_region(mem->start, msize); - return -ENOMEM; - } - - SET_NETDEV_DEV(dev, &pdev->dev); - platform_set_drvdata(pdev, dev); - - dev->irq = irq->start; - dev->base_addr = mem->start; - - ret = mcf8390_init(dev); - if (ret) { - release_mem_region(mem->start, msize); - free_netdev(dev); - return ret; - } - return 0; -} - -static int mcf8390_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - struct resource *mem; - - unregister_netdev(dev); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (mem) - release_mem_region(mem->start, resource_size(mem)); - free_netdev(dev); - return 0; -} - -static struct platform_driver mcf8390_drv = { - .driver = { - .name = "mcf8390", - }, - .probe = mcf8390_probe, - .remove = mcf8390_remove, -}; - -module_platform_driver(mcf8390_drv); - -MODULE_DESCRIPTION("MCF8390 ColdFire NS8390 driver"); -MODULE_AUTHOR("Greg Ungerer "); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:mcf8390"); diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c deleted file mode 100644 index 53660bc8d6ff..000000000000 --- a/drivers/net/ethernet/8390/ne.c +++ /dev/null @@ -1,1004 +0,0 @@ -/* ne.c: A general non-shared-memory NS8390 ethernet driver for linux. */ -/* - Written 1992-94 by Donald Becker. - - Copyright 1993 United States Government as represented by the - Director, National Security Agency. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - The author may be reached as becker@scyld.com, or C/O - Scyld Computing Corporation, 410 Severn Ave., Suite 210, Annapolis MD 21403 - - This driver should work with many programmed-I/O 8390-based ethernet - boards. Currently it supports the NE1000, NE2000, many clones, - and some Cabletron products. - - Changelog: - - Paul Gortmaker : use ENISR_RDC to monitor Tx PIO uploads, made - sanity checks and bad clone support optional. - Paul Gortmaker : new reset code, reset card after probe at boot. - Paul Gortmaker : multiple card support for module users. - Paul Gortmaker : Support for PCI ne2k clones, similar to lance.c - Paul Gortmaker : Allow users with bad cards to avoid full probe. - Paul Gortmaker : PCI probe changes, more PCI cards supported. - rjohnson@analogic.com : Changed init order so an interrupt will only - occur after memory is allocated for dev->priv. Deallocated memory - last in cleanup_modue() - Richard Guenther : Added support for ISAPnP cards - Paul Gortmaker : Discontinued PCI support - use ne2k-pci.c instead. - Hayato Fujiwara : Add m32r support. - -*/ - -/* Routines for the NatSemi-based designs (NE[12]000). */ - -static const char version1[] = -"ne.c:v1.10 9/23/94 Donald Becker (becker@scyld.com)\n"; -static const char version2[] = -"Last modified Nov 1, 2000 by Paul Gortmaker\n"; - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "8390.h" - -#define DRV_NAME "ne" - -/* Some defines that people can play with if so inclined. */ - -/* Do we support clones that don't adhere to 14,15 of the SAprom ? */ -#define SUPPORT_NE_BAD_CLONES -/* 0xbad = bad sig or no reset ack */ -#define BAD 0xbad - -#define MAX_NE_CARDS 4 /* Max number of NE cards per module */ -static struct platform_device *pdev_ne[MAX_NE_CARDS]; -static int io[MAX_NE_CARDS]; -static int irq[MAX_NE_CARDS]; -static int bad[MAX_NE_CARDS]; -static u32 ne_msg_enable; - -#ifdef MODULE -module_param_hw_array(io, int, ioport, NULL, 0); -module_param_hw_array(irq, int, irq, NULL, 0); -module_param_array(bad, int, NULL, 0); -module_param_named(msg_enable, ne_msg_enable, uint, 0444); -MODULE_PARM_DESC(io, "I/O base address(es),required"); -MODULE_PARM_DESC(irq, "IRQ number(s)"); -MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures"); -MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)"); -MODULE_DESCRIPTION("NE1000/NE2000 ISA/PnP Ethernet driver"); -MODULE_LICENSE("GPL"); -#endif /* MODULE */ - -/* Do we perform extra sanity checks on stuff ? */ -/* #define NE_SANITY_CHECK */ - -/* Do we implement the read before write bugfix ? */ -/* #define NE_RW_BUGFIX */ - -/* Do we have a non std. amount of memory? (in units of 256 byte pages) */ -/* #define PACKETBUF_MEMSIZE 0x40 */ - -/* This is set up so that no ISA autoprobe takes place. We can't guarantee -that the ne2k probe is the last 8390 based probe to take place (as it -is at boot) and so the probe will get confused by any other 8390 cards. -ISA device autoprobes on a running machine are not recommended anyway. */ -#if !defined(MODULE) && defined(CONFIG_ISA) -/* Do we need a portlist for the ISA auto-probe ? */ -#define NEEDS_PORTLIST -#endif - -/* A zero-terminated list of I/O addresses to be probed at boot. */ -#ifdef NEEDS_PORTLIST -static unsigned int netcard_portlist[] __initdata = { - 0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0 -}; -#endif - -static struct isapnp_device_id isapnp_clone_list[] __initdata = { - { ISAPNP_CARD_ID('A','X','E',0x2011), - ISAPNP_VENDOR('A','X','E'), ISAPNP_FUNCTION(0x2011), - (long) "NetGear EA201" }, - { ISAPNP_ANY_ID, ISAPNP_ANY_ID, - ISAPNP_VENDOR('E','D','I'), ISAPNP_FUNCTION(0x0216), - (long) "NN NE2000" }, - { ISAPNP_ANY_ID, ISAPNP_ANY_ID, - ISAPNP_VENDOR('P','N','P'), ISAPNP_FUNCTION(0x80d6), - (long) "Generic PNP" }, - { } /* terminate list */ -}; - -MODULE_DEVICE_TABLE(isapnp, isapnp_clone_list); - -#ifdef SUPPORT_NE_BAD_CLONES -/* A list of bad clones that we none-the-less recognize. */ -static struct { const char *name8, *name16; unsigned char SAprefix[4];} -bad_clone_list[] __initdata = { - {"DE100", "DE200", {0x00, 0xDE, 0x01,}}, - {"DE120", "DE220", {0x00, 0x80, 0xc8,}}, - {"DFI1000", "DFI2000", {'D', 'F', 'I',}}, /* Original, eh? */ - {"EtherNext UTP8", "EtherNext UTP16", {0x00, 0x00, 0x79}}, - {"NE1000","NE2000-invalid", {0x00, 0x00, 0xd8}}, /* Ancient real NE1000. */ - {"NN1000", "NN2000", {0x08, 0x03, 0x08}}, /* Outlaw no-name clone. */ - {"4-DIM8","4-DIM16", {0x00,0x00,0x4d,}}, /* Outlaw 4-Dimension cards. */ - {"Con-Intl_8", "Con-Intl_16", {0x00, 0x00, 0x24}}, /* Connect Int'nl */ - {"ET-100","ET-200", {0x00, 0x45, 0x54}}, /* YANG and YA clone */ - {"COMPEX","COMPEX16",{0x00,0x80,0x48}}, /* Broken ISA Compex cards */ - {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */ - {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */ - {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */ -#ifdef CONFIG_MACH_TX49XX - {"RBHMA4X00-RTL8019", "RBHMA4X00-RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */ -#endif - {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */ - {NULL,} -}; -#endif - -/* ---- No user-serviceable parts below ---- */ - -#define NE_BASE (dev->base_addr) -#define NE_CMD 0x00 -#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ -#define NE_RESET 0x1f /* Issue a read to reset, a write to clear. */ -#define NE_IO_EXTENT 0x20 - -#define NE1SM_START_PG 0x20 /* First page of TX buffer */ -#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ -#define NESM_START_PG 0x40 /* First page of TX buffer */ -#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ - -#if defined(CONFIG_MACH_TX49XX) -# define DCR_VAL 0x48 /* 8-bit mode */ -#elif defined(CONFIG_ATARI) /* 8-bit mode on Atari, normal on Q40 */ -# define DCR_VAL (MACH_IS_ATARI ? 0x48 : 0x49) -#else -# define DCR_VAL 0x49 -#endif - -static int ne_probe1(struct net_device *dev, unsigned long ioaddr); -static int ne_probe_isapnp(struct net_device *dev); - -static void ne_reset_8390(struct net_device *dev); -static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, - int ring_page); -static void ne_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void ne_block_output(struct net_device *dev, const int count, - const unsigned char *buf, const int start_page); - - -/* Probe for various non-shared-memory ethercards. - - NEx000-clone boards have a Station Address PROM (SAPROM) in the packet - buffer memory space. NE2000 clones have 0x57,0x57 in bytes 0x0e,0x0f of - the SAPROM, while other supposed NE2000 clones must be detected by their - SA prefix. - - Reading the SAPROM from a word-wide card with the 8390 set in byte-wide - mode results in doubled values, which can be detected and compensated for. - - The probe is also responsible for initializing the card and filling - in the 'dev' and 'ei_status' structures. - - We use the minimum memory size for some ethercard product lines, iff we can't - distinguish models. You can increase the packet buffer size by setting - PACKETBUF_MEMSIZE. Reported Cabletron packet buffer locations are: - E1010 starts at 0x100 and ends at 0x2000. - E1010-x starts at 0x100 and ends at 0x8000. ("-x" means "more memory") - E2010 starts at 0x100 and ends at 0x4000. - E2010-x starts at 0x100 and ends at 0xffff. */ - -static int __init do_ne_probe(struct net_device *dev) -{ - unsigned long base_addr = dev->base_addr; -#ifdef NEEDS_PORTLIST - int orig_irq = dev->irq; -#endif - - /* First check any supplied i/o locations. User knows best. */ - if (base_addr > 0x1ff) { /* Check a single specified location. */ - int ret = ne_probe1(dev, base_addr); - if (ret) - netdev_warn(dev, "ne.c: No NE*000 card found at " - "i/o = %#lx\n", base_addr); - return ret; - } - else if (base_addr != 0) /* Don't probe at all. */ - return -ENXIO; - - /* Then look for any installed ISAPnP clones */ - if (isapnp_present() && (ne_probe_isapnp(dev) == 0)) - return 0; - -#ifdef NEEDS_PORTLIST - /* Last resort. The semi-risky ISA auto-probe. */ - for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) { - int ioaddr = netcard_portlist[base_addr]; - dev->irq = orig_irq; - if (ne_probe1(dev, ioaddr) == 0) - return 0; - } -#endif - - return -ENODEV; -} - -static int __init ne_probe_isapnp(struct net_device *dev) -{ - int i; - - for (i = 0; isapnp_clone_list[i].vendor != 0; i++) { - struct pnp_dev *idev = NULL; - - while ((idev = pnp_find_dev(NULL, - isapnp_clone_list[i].vendor, - isapnp_clone_list[i].function, - idev))) { - /* Avoid already found cards from previous calls */ - if (pnp_device_attach(idev) < 0) - continue; - if (pnp_activate_dev(idev) < 0) { - pnp_device_detach(idev); - continue; - } - /* if no io and irq, search for next */ - if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0)) { - pnp_device_detach(idev); - continue; - } - /* found it */ - dev->base_addr = pnp_port_start(idev, 0); - dev->irq = pnp_irq(idev, 0); - netdev_info(dev, - "ne.c: ISAPnP reports %s at i/o %#lx, irq %d.\n", - (char *) isapnp_clone_list[i].driver_data, - dev->base_addr, dev->irq); - if (ne_probe1(dev, dev->base_addr) != 0) { /* Shouldn't happen. */ - netdev_err(dev, - "ne.c: Probe of ISAPnP card at %#lx failed.\n", - dev->base_addr); - pnp_device_detach(idev); - return -ENXIO; - } - ei_status.priv = (unsigned long)idev; - break; - } - if (!idev) - continue; - return 0; - } - - return -ENODEV; -} - -static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) -{ - int i; - unsigned char SA_prom[32]; - int wordlength = 2; - const char *name = NULL; - int start_page, stop_page; - int neX000, ctron, copam, bad_card; - int reg0, ret; - static unsigned version_printed; - struct ei_device *ei_local = netdev_priv(dev); - - if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME)) - return -EBUSY; - - reg0 = inb_p(ioaddr); - if (reg0 == 0xFF) { - ret = -ENODEV; - goto err_out; - } - - /* Do a preliminary verification that we have a 8390. */ - { - int regd; - outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); - regd = inb_p(ioaddr + 0x0d); - outb_p(0xff, ioaddr + 0x0d); - outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD); - inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */ - if (inb_p(ioaddr + EN0_COUNTER0) != 0) { - outb_p(reg0, ioaddr); - outb_p(regd, ioaddr + 0x0d); /* Restore the old values. */ - ret = -ENODEV; - goto err_out; - } - } - - if ((ne_msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0)) - netdev_info(dev, "%s%s", version1, version2); - - netdev_info(dev, "NE*000 ethercard probe at %#3lx:", ioaddr); - - /* A user with a poor card that fails to ack the reset, or that - does not have a valid 0x57,0x57 signature can still use this - without having to recompile. Specifying an i/o address along - with an otherwise unused dev->mem_end value of "0xBAD" will - cause the driver to skip these parts of the probe. */ - - bad_card = ((dev->base_addr != 0) && (dev->mem_end == BAD)); - - /* Reset card. Who knows what dain-bramaged state it was left in. */ - - { - unsigned long reset_start_time = jiffies; - - /* DON'T change these to inb_p/outb_p or reset will fail on clones. */ - outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); - - while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { - if (bad_card) { - pr_cont(" (warning: no reset ack)"); - break; - } else { - pr_cont(" not found (no reset ack).\n"); - ret = -ENODEV; - goto err_out; - } - } - - outb_p(0xff, ioaddr + EN0_ISR); /* Ack all intr. */ - } - - /* Read the 16 bytes of station address PROM. - We must first initialize registers, similar to NS8390p_init(eifdev, 0). - We can't reliably read the SAPROM address without this. - (I learned the hard way!). */ - { - struct {unsigned char value, offset; } program_seq[] = - { - {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ - {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ - {0x00, EN0_RCNTLO}, /* Clear the count regs. */ - {0x00, EN0_RCNTHI}, - {0x00, EN0_IMR}, /* Mask completion irq. */ - {0xFF, EN0_ISR}, - {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ - {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ - {32, EN0_RCNTLO}, - {0x00, EN0_RCNTHI}, - {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ - {0x00, EN0_RSARHI}, - {E8390_RREAD+E8390_START, E8390_CMD}, - }; - - for (i = 0; i < ARRAY_SIZE(program_seq); i++) - outb_p(program_seq[i].value, ioaddr + program_seq[i].offset); - - } - for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) { - SA_prom[i] = inb(ioaddr + NE_DATAPORT); - SA_prom[i+1] = inb(ioaddr + NE_DATAPORT); - if (SA_prom[i] != SA_prom[i+1]) - wordlength = 1; - } - - if (wordlength == 2) - { - for (i = 0; i < 16; i++) - SA_prom[i] = SA_prom[i+i]; - /* We must set the 8390 for word mode. */ - outb_p(DCR_VAL, ioaddr + EN0_DCFG); - start_page = NESM_START_PG; - - /* - * Realtek RTL8019AS datasheet says that the PSTOP register - * shouldn't exceed 0x60 in 8-bit mode. - * This chip can be identified by reading the signature from - * the remote byte count registers (otherwise write-only)... - */ - if ((DCR_VAL & 0x01) == 0 && /* 8-bit mode */ - inb(ioaddr + EN0_RCNTLO) == 0x50 && - inb(ioaddr + EN0_RCNTHI) == 0x70) - stop_page = 0x60; - else - stop_page = NESM_STOP_PG; - } else { - start_page = NE1SM_START_PG; - stop_page = NE1SM_STOP_PG; - } - - neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57); - ctron = (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d); - copam = (SA_prom[14] == 0x49 && SA_prom[15] == 0x00); - - /* Set up the rest of the parameters. */ - if (neX000 || bad_card || copam) { - name = (wordlength == 2) ? "NE2000" : "NE1000"; - } - else if (ctron) - { - name = (wordlength == 2) ? "Ctron-8" : "Ctron-16"; - start_page = 0x01; - stop_page = (wordlength == 2) ? 0x40 : 0x20; - } - else - { -#ifdef SUPPORT_NE_BAD_CLONES - /* Ack! Well, there might be a *bad* NE*000 clone there. - Check for total bogus addresses. */ - for (i = 0; bad_clone_list[i].name8; i++) - { - if (SA_prom[0] == bad_clone_list[i].SAprefix[0] && - SA_prom[1] == bad_clone_list[i].SAprefix[1] && - SA_prom[2] == bad_clone_list[i].SAprefix[2]) - { - if (wordlength == 2) - { - name = bad_clone_list[i].name16; - } else { - name = bad_clone_list[i].name8; - } - break; - } - } - if (bad_clone_list[i].name8 == NULL) - { - pr_cont(" not found (invalid signature %2.2x %2.2x).\n", - SA_prom[14], SA_prom[15]); - ret = -ENXIO; - goto err_out; - } -#else - pr_cont(" not found.\n"); - ret = -ENXIO; - goto err_out; -#endif - } - - if (dev->irq < 2) - { - unsigned long cookie = probe_irq_on(); - outb_p(0x50, ioaddr + EN0_IMR); /* Enable one interrupt. */ - outb_p(0x00, ioaddr + EN0_RCNTLO); - outb_p(0x00, ioaddr + EN0_RCNTHI); - outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */ - mdelay(10); /* wait 10ms for interrupt to propagate */ - outb_p(0x00, ioaddr + EN0_IMR); /* Mask it again. */ - dev->irq = probe_irq_off(cookie); - if (ne_msg_enable & NETIF_MSG_PROBE) - pr_cont(" autoirq is %d", dev->irq); - } else if (dev->irq == 2) - /* Fixup for users that don't know that IRQ 2 is really IRQ 9, - or don't know which one to set. */ - dev->irq = 9; - - if (! dev->irq) { - pr_cont(" failed to detect IRQ line.\n"); - ret = -EAGAIN; - goto err_out; - } - - /* Snarf the interrupt now. There's no point in waiting since we cannot - share and the board will usually be enabled. */ - ret = request_irq(dev->irq, eip_interrupt, 0, name, dev); - if (ret) { - pr_cont(" unable to get IRQ %d (errno=%d).\n", dev->irq, ret); - goto err_out; - } - - dev->base_addr = ioaddr; - - for (i = 0; i < ETH_ALEN; i++) { - dev->dev_addr[i] = SA_prom[i]; - } - - pr_cont("%pM\n", dev->dev_addr); - - ei_status.name = name; - ei_status.tx_start_page = start_page; - ei_status.stop_page = stop_page; - - /* Use 16-bit mode only if this wasn't overridden by DCR_VAL */ - ei_status.word16 = (wordlength == 2 && (DCR_VAL & 0x01)); - - ei_status.rx_start_page = start_page + TX_PAGES; -#ifdef PACKETBUF_MEMSIZE - /* Allow the packet buffer size to be overridden by know-it-alls. */ - ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; -#endif - - ei_status.reset_8390 = &ne_reset_8390; - ei_status.block_input = &ne_block_input; - ei_status.block_output = &ne_block_output; - ei_status.get_8390_hdr = &ne_get_8390_hdr; - ei_status.priv = 0; - - dev->netdev_ops = &eip_netdev_ops; - NS8390p_init(dev, 0); - - ei_local->msg_enable = ne_msg_enable; - ret = register_netdev(dev); - if (ret) - goto out_irq; - netdev_info(dev, "%s found at %#lx, using IRQ %d.\n", - name, ioaddr, dev->irq); - return 0; - -out_irq: - free_irq(dev->irq, dev); -err_out: - release_region(ioaddr, NE_IO_EXTENT); - return ret; -} - -/* Hard reset the card. This used to pause for the same period that a - 8390 reset command required, but that shouldn't be necessary. */ - -static void ne_reset_8390(struct net_device *dev) -{ - unsigned long reset_start_time = jiffies; - struct ei_device *ei_local = netdev_priv(dev); - - netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies); - - /* DON'T change these to inb_p/outb_p or reset will fail on clones. */ - outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); - - ei_status.txing = 0; - ei_status.dmaing = 0; - - /* This check _should_not_ be necessary, omit eventually. */ - while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { - netdev_err(dev, "ne_reset_8390() did not complete.\n"); - break; - } - outb_p(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */ -} - -/* Grab the 8390 specific header. Similar to the block_input routine, but - we don't need to be concerned with ring wrap as the header will be at - the start of a page, so we optimize accordingly. */ - -static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) -{ - int nic_base = dev->base_addr; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - - if (ei_status.dmaing) - { - netdev_err(dev, "DMAing conflict in ne_get_8390_hdr " - "[DMAstat:%d][irqlock:%d].\n", - ei_status.dmaing, ei_status.irqlock); - return; - } - - ei_status.dmaing |= 0x01; - outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); - outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); - outb_p(0, nic_base + EN0_RCNTHI); - outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ - outb_p(ring_page, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); - - if (ei_status.word16) - insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1); - else - insb(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)); - - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; - - le16_to_cpus(&hdr->count); -} - -/* Block input and output, similar to the Crynwr packet driver. If you - are porting to a new ethercard, look at the packet driver source for hints. - The NEx000 doesn't share the on-board packet memory -- you have to put - the packet out through the "remote DMA" dataport using outb. */ - -static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) -{ -#ifdef NE_SANITY_CHECK - int xfer_count = count; - struct ei_device *ei_local = netdev_priv(dev); -#endif - int nic_base = dev->base_addr; - char *buf = skb->data; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) - { - netdev_err(dev, "DMAing conflict in ne_block_input " - "[DMAstat:%d][irqlock:%d].\n", - ei_status.dmaing, ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); - outb_p(count & 0xff, nic_base + EN0_RCNTLO); - outb_p(count >> 8, nic_base + EN0_RCNTHI); - outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); - outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) - { - insw(NE_BASE + NE_DATAPORT,buf,count>>1); - if (count & 0x01) - { - buf[count-1] = inb(NE_BASE + NE_DATAPORT); -#ifdef NE_SANITY_CHECK - xfer_count++; -#endif - } - } else { - insb(NE_BASE + NE_DATAPORT, buf, count); - } - -#ifdef NE_SANITY_CHECK - /* This was for the ALPHA version only, but enough people have - been encountering problems so it is still here. If you see - this message you either 1) have a slightly incompatible clone - or 2) have noise/speed problems with your bus. */ - - if (netif_msg_rx_status(ei_local)) - { - /* DMA termination address check... */ - int addr, tries = 20; - do { - /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here - -- it's broken for Rx on some cards! */ - int high = inb_p(nic_base + EN0_RSARHI); - int low = inb_p(nic_base + EN0_RSARLO); - addr = (high << 8) + low; - if (((ring_offset + xfer_count) & 0xff) == low) - break; - } while (--tries > 0); - if (tries <= 0) - netdev_warn(dev, "RX transfer address mismatch," - "%#4.4x (expected) vs. %#4.4x (actual).\n", - ring_offset + xfer_count, addr); - } -#endif - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; -} - -static void ne_block_output(struct net_device *dev, int count, - const unsigned char *buf, const int start_page) -{ - int nic_base = NE_BASE; - unsigned long dma_start; -#ifdef NE_SANITY_CHECK - int retries = 0; - struct ei_device *ei_local = netdev_priv(dev); -#endif - - /* Round the count up for word writes. Do we need to do this? - What effect will an odd byte count have on the 8390? - I should check someday. */ - - if (ei_status.word16 && (count & 0x01)) - count++; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) - { - netdev_err(dev, "DMAing conflict in ne_block_output." - "[DMAstat:%d][irqlock:%d]\n", - ei_status.dmaing, ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - /* We should already be in page 0, but to be safe... */ - outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); - -#ifdef NE_SANITY_CHECK -retry: -#endif - -#ifdef NE_RW_BUGFIX - /* Handle the read-before-write bug the same way as the - Crynwr packet driver -- the NatSemi method doesn't work. - Actually this doesn't always work either, but if you have - problems with your NEx000 this is better than nothing! */ - - outb_p(0x42, nic_base + EN0_RCNTLO); - outb_p(0x00, nic_base + EN0_RCNTHI); - outb_p(0x42, nic_base + EN0_RSARLO); - outb_p(0x00, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); - /* Make certain that the dummy read has occurred. */ - udelay(6); -#endif - - outb_p(ENISR_RDC, nic_base + EN0_ISR); - - /* Now the normal output. */ - outb_p(count & 0xff, nic_base + EN0_RCNTLO); - outb_p(count >> 8, nic_base + EN0_RCNTHI); - outb_p(0x00, nic_base + EN0_RSARLO); - outb_p(start_page, nic_base + EN0_RSARHI); - - outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) { - outsw(NE_BASE + NE_DATAPORT, buf, count>>1); - } else { - outsb(NE_BASE + NE_DATAPORT, buf, count); - } - - dma_start = jiffies; - -#ifdef NE_SANITY_CHECK - /* This was for the ALPHA version only, but enough people have - been encountering problems so it is still here. */ - - if (netif_msg_tx_queued(ei_local)) - { - /* DMA termination address check... */ - int addr, tries = 20; - do { - int high = inb_p(nic_base + EN0_RSARHI); - int low = inb_p(nic_base + EN0_RSARLO); - addr = (high << 8) + low; - if ((start_page << 8) + count == addr) - break; - } while (--tries > 0); - - if (tries <= 0) - { - netdev_warn(dev, "Tx packet transfer address mismatch," - "%#4.4x (expected) vs. %#4.4x (actual).\n", - (start_page << 8) + count, addr); - if (retries++ == 0) - goto retry; - } - } -#endif - - while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ - netdev_warn(dev, "timeout waiting for Tx RDC.\n"); - ne_reset_8390(dev); - NS8390p_init(dev, 1); - break; - } - - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; -} - -static int __init ne_drv_probe(struct platform_device *pdev) -{ - struct net_device *dev; - int err, this_dev = pdev->id; - struct resource *res; - - dev = alloc_eip_netdev(); - if (!dev) - return -ENOMEM; - - /* ne.c doesn't populate resources in platform_device, but - * rbtx4927_ne_init and rbtx4938_ne_init do register devices - * with resources. - */ - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (res) { - dev->base_addr = res->start; - dev->irq = platform_get_irq(pdev, 0); - } else { - if (this_dev < 0 || this_dev >= MAX_NE_CARDS) { - free_netdev(dev); - return -EINVAL; - } - dev->base_addr = io[this_dev]; - dev->irq = irq[this_dev]; - dev->mem_end = bad[this_dev]; - } - SET_NETDEV_DEV(dev, &pdev->dev); - err = do_ne_probe(dev); - if (err) { - free_netdev(dev); - return err; - } - platform_set_drvdata(pdev, dev); - - /* Update with any values found by probing, don't update if - * resources were specified. - */ - if (!res) { - io[this_dev] = dev->base_addr; - irq[this_dev] = dev->irq; - } - return 0; -} - -static int ne_drv_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - - if (dev) { - struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; - netif_device_detach(dev); - unregister_netdev(dev); - if (idev) - pnp_device_detach(idev); - /* Careful ne_drv_remove can be called twice, once from - * the platform_driver.remove and again when the - * platform_device is being removed. - */ - ei_status.priv = 0; - free_irq(dev->irq, dev); - release_region(dev->base_addr, NE_IO_EXTENT); - free_netdev(dev); - } - return 0; -} - -/* Remove unused devices or all if true. */ -static void ne_loop_rm_unreg(int all) -{ - int this_dev; - struct platform_device *pdev; - for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - pdev = pdev_ne[this_dev]; - /* No network device == unused */ - if (pdev && (!platform_get_drvdata(pdev) || all)) { - ne_drv_remove(pdev); - platform_device_unregister(pdev); - pdev_ne[this_dev] = NULL; - } - } -} - -#ifdef CONFIG_PM -static int ne_drv_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct net_device *dev = platform_get_drvdata(pdev); - - if (netif_running(dev)) { - struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; - netif_device_detach(dev); - if (idev) - pnp_stop_dev(idev); - } - return 0; -} - -static int ne_drv_resume(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - - if (netif_running(dev)) { - struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; - if (idev) - pnp_start_dev(idev); - ne_reset_8390(dev); - NS8390p_init(dev, 1); - netif_device_attach(dev); - } - return 0; -} -#else -#define ne_drv_suspend NULL -#define ne_drv_resume NULL -#endif - -static struct platform_driver ne_driver = { - .remove = ne_drv_remove, - .suspend = ne_drv_suspend, - .resume = ne_drv_resume, - .driver = { - .name = DRV_NAME, - }, -}; - -static void __init ne_add_devices(void) -{ - int this_dev; - struct platform_device *pdev; - - for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - if (pdev_ne[this_dev]) - continue; - pdev = platform_device_register_simple( - DRV_NAME, this_dev, NULL, 0); - if (IS_ERR(pdev)) - continue; - pdev_ne[this_dev] = pdev; - } -} - -#ifdef MODULE -static int __init ne_init(void) -{ - int retval; - ne_add_devices(); - retval = platform_driver_probe(&ne_driver, ne_drv_probe); - if (retval) { - if (io[0] == 0) - pr_notice("ne.c: You must supply \"io=0xNNN\"" - " value(s) for ISA cards.\n"); - ne_loop_rm_unreg(1); - return retval; - } - - /* Unregister unused platform_devices. */ - ne_loop_rm_unreg(0); - return retval; -} -module_init(ne_init); -#else /* MODULE */ -static int __init ne_init(void) -{ - int retval = platform_driver_probe(&ne_driver, ne_drv_probe); - - /* Unregister unused platform_devices. */ - ne_loop_rm_unreg(0); - return retval; -} -module_init(ne_init); - -#ifdef CONFIG_NETDEV_LEGACY_INIT -struct net_device * __init ne_probe(int unit) -{ - int this_dev; - struct net_device *dev; - - /* Find an empty slot, that is no net_device and zero io port. */ - this_dev = 0; - while ((pdev_ne[this_dev] && platform_get_drvdata(pdev_ne[this_dev])) || - io[this_dev]) { - if (++this_dev == MAX_NE_CARDS) - return ERR_PTR(-ENOMEM); - } - - /* Get irq, io from kernel command line */ - dev = alloc_eip_netdev(); - if (!dev) - return ERR_PTR(-ENOMEM); - - sprintf(dev->name, "eth%d", unit); - netdev_boot_setup_check(dev); - - io[this_dev] = dev->base_addr; - irq[this_dev] = dev->irq; - bad[this_dev] = dev->mem_end; - - free_netdev(dev); - - ne_add_devices(); - - /* return the first device found */ - for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - if (pdev_ne[this_dev]) { - dev = platform_get_drvdata(pdev_ne[this_dev]); - if (dev) - return dev; - } - } - - return ERR_PTR(-ENODEV); -} -#endif -#endif /* MODULE */ - -static void __exit ne_exit(void) -{ - platform_driver_unregister(&ne_driver); - ne_loop_rm_unreg(1); -} -module_exit(ne_exit); diff --git a/drivers/net/ethernet/8390/ne2k-pci.c b/drivers/net/ethernet/8390/ne2k-pci.c deleted file mode 100644 index d6715008e04d..000000000000 --- a/drivers/net/ethernet/8390/ne2k-pci.c +++ /dev/null @@ -1,747 +0,0 @@ -/* A Linux device driver for PCI NE2000 clones. - * - * Authors and other copyright holders: - * 1992-2000 by Donald Becker, NE2000 core and various modifications. - * 1995-1998 by Paul Gortmaker, core modifications and PCI support. - * Copyright 1993 assigned to the United States Government as represented - * by the Director, National Security Agency. - * - * This software may be used and distributed according to the terms of - * the GNU General Public License (GPL), incorporated herein by reference. - * Drivers based on or derived from this code fall under the GPL and must - * retain the authorship, copyright and license notice. This file is not - * a complete program and may only be used when the entire operating - * system is licensed under the GPL. - * - * The author may be reached as becker@scyld.com, or C/O - * Scyld Computing Corporation - * 410 Severn Ave., Suite 210 - * Annapolis MD 21403 - * - * Issues remaining: - * People are making PCI NE2000 clones! Oh the horror, the horror... - * Limited full-duplex support. - */ - -#define DRV_NAME "ne2k-pci" -#define DRV_DESCRIPTION "PCI NE2000 clone driver" -#define DRV_AUTHOR "Donald Becker / Paul Gortmaker" -#define DRV_VERSION "1.03" -#define DRV_RELDATE "9/22/2003" - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -/* The user-configurable values. - * These may be modified when a driver module is loaded. - */ - -/* More are supported, limit only on options */ -#define MAX_UNITS 8 - -/* Used to pass the full-duplex flag, etc. */ -static int full_duplex[MAX_UNITS]; -static int options[MAX_UNITS]; - -/* Force a non std. amount of memory. Units are 256 byte pages. */ -/* #define PACKETBUF_MEMSIZE 0x40 */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "8390.h" - -static int ne2k_msg_enable; - -static const int default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | - NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR); - -#if defined(__powerpc__) -#define inl_le(addr) le32_to_cpu(inl(addr)) -#define inw_le(addr) le16_to_cpu(inw(addr)) -#endif - -MODULE_AUTHOR(DRV_AUTHOR); -MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_VERSION(DRV_VERSION); -MODULE_LICENSE("GPL"); - -module_param_named(msg_enable, ne2k_msg_enable, int, 0444); -module_param_array(options, int, NULL, 0); -module_param_array(full_duplex, int, NULL, 0); -MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)"); -MODULE_PARM_DESC(options, "Bit 5: full duplex"); -MODULE_PARM_DESC(full_duplex, "full duplex setting(s) (1)"); - -/* Some defines that people can play with if so inclined. - */ - -/* Use 32 bit data-movement operations instead of 16 bit. */ -#define USE_LONGIO - -/* Do we implement the read before write bugfix ? */ -/* #define NE_RW_BUGFIX */ - -/* Flags. We rename an existing ei_status field to store flags! - * Thus only the low 8 bits are usable for non-init-time flags. - */ -#define ne2k_flags reg0 - -enum { - /* Chip can do only 16/32-bit xfers. */ - ONLY_16BIT_IO = 8, ONLY_32BIT_IO = 4, - /* User override. */ - FORCE_FDX = 0x20, - REALTEK_FDX = 0x40, HOLTEK_FDX = 0x80, - STOP_PG_0x60 = 0x100, -}; - -enum ne2k_pci_chipsets { - CH_RealTek_RTL_8029 = 0, - CH_Winbond_89C940, - CH_Compex_RL2000, - CH_KTI_ET32P2, - CH_NetVin_NV5000SC, - CH_Via_86C926, - CH_SureCom_NE34, - CH_Winbond_W89C940F, - CH_Holtek_HT80232, - CH_Holtek_HT80229, - CH_Winbond_89C940_8c4a, -}; - - -static struct { - char *name; - int flags; -} pci_clone_list[] = { - {"RealTek RTL-8029(AS)", REALTEK_FDX}, - {"Winbond 89C940", 0}, - {"Compex RL2000", 0}, - {"KTI ET32P2", 0}, - {"NetVin NV5000SC", 0}, - {"Via 86C926", ONLY_16BIT_IO}, - {"SureCom NE34", 0}, - {"Winbond W89C940F", 0}, - {"Holtek HT80232", ONLY_16BIT_IO | HOLTEK_FDX}, - {"Holtek HT80229", ONLY_32BIT_IO | HOLTEK_FDX | STOP_PG_0x60 }, - {"Winbond W89C940(misprogrammed)", 0}, - {NULL,} -}; - - -static const struct pci_device_id ne2k_pci_tbl[] = { - { 0x10ec, 0x8029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RealTek_RTL_8029 }, - { 0x1050, 0x0940, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_89C940 }, - { 0x11f6, 0x1401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Compex_RL2000 }, - { 0x8e2e, 0x3000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_KTI_ET32P2 }, - { 0x4a14, 0x5000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_NetVin_NV5000SC }, - { 0x1106, 0x0926, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Via_86C926 }, - { 0x10bd, 0x0e34, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_SureCom_NE34 }, - { 0x1050, 0x5a5a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_W89C940F }, - { 0x12c3, 0x0058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Holtek_HT80232 }, - { 0x12c3, 0x5598, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Holtek_HT80229 }, - { 0x8c4a, 0x1980, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_89C940_8c4a }, - { 0, } -}; - -MODULE_DEVICE_TABLE(pci, ne2k_pci_tbl); - - -/* ---- No user-serviceable parts below ---- */ - -#define NE_BASE (dev->base_addr) -#define NE_CMD 0x00 -#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ -#define NE_RESET 0x1f /* Issue a read to reset, a write to clear. */ -#define NE_IO_EXTENT 0x20 - -#define NESM_START_PG 0x40 /* First page of TX buffer */ -#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ - - -static int ne2k_pci_open(struct net_device *dev); -static int ne2k_pci_close(struct net_device *dev); - -static void ne2k_pci_reset_8390(struct net_device *dev); -static void ne2k_pci_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page); -static void ne2k_pci_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void ne2k_pci_block_output(struct net_device *dev, const int count, - const unsigned char *buf, - const int start_page); -static const struct ethtool_ops ne2k_pci_ethtool_ops; - - - -/* There is no room in the standard 8390 structure for extra info we need, - * so we build a meta/outer-wrapper structure.. - */ -struct ne2k_pci_card { - struct net_device *dev; - struct pci_dev *pci_dev; -}; - - - -/* NEx000-clone boards have a Station Address (SA) PROM (SAPROM) in the packet - * buffer memory space. By-the-spec NE2000 clones have 0x57,0x57 in bytes - * 0x0e,0x0f of the SAPROM, while other supposed NE2000 clones must be - * detected by their SA prefix. - * - * Reading the SAPROM from a word-wide card with the 8390 set in byte-wide - * mode results in doubled values, which can be detected and compensated for. - * - * The probe is also responsible for initializing the card and filling - * in the 'dev' and 'ei_status' structures. - */ - -static const struct net_device_ops ne2k_netdev_ops = { - .ndo_open = ne2k_pci_open, - .ndo_stop = ne2k_pci_close, - .ndo_start_xmit = ei_start_xmit, - .ndo_tx_timeout = ei_tx_timeout, - .ndo_get_stats = ei_get_stats, - .ndo_set_rx_mode = ei_set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = ei_poll, -#endif -}; - -static int ne2k_pci_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct net_device *dev; - int i; - unsigned char SA_prom[32]; - int start_page, stop_page; - int irq, reg0, chip_idx = ent->driver_data; - static unsigned int fnd_cnt; - long ioaddr; - int flags = pci_clone_list[chip_idx].flags; - struct ei_device *ei_local; - - fnd_cnt++; - - i = pci_enable_device(pdev); - if (i) - return i; - - ioaddr = pci_resource_start(pdev, 0); - irq = pdev->irq; - - if (!ioaddr || ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) == 0)) { - dev_err(&pdev->dev, "no I/O resource at PCI BAR #0\n"); - goto err_out; - } - - if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME)) { - dev_err(&pdev->dev, "I/O resource 0x%x @ 0x%lx busy\n", - NE_IO_EXTENT, ioaddr); - goto err_out; - } - - reg0 = inb(ioaddr); - if (reg0 == 0xFF) - goto err_out_free_res; - - /* Do a preliminary verification that we have a 8390. */ - { - int regd; - - outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP, ioaddr + E8390_CMD); - regd = inb(ioaddr + 0x0d); - outb(0xff, ioaddr + 0x0d); - outb(E8390_NODMA + E8390_PAGE0, ioaddr + E8390_CMD); - /* Clear the counter by reading. */ - inb(ioaddr + EN0_COUNTER0); - if (inb(ioaddr + EN0_COUNTER0) != 0) { - outb(reg0, ioaddr); - /* Restore the old values. */ - outb(regd, ioaddr + 0x0d); - goto err_out_free_res; - } - } - - /* Allocate net_device, dev->priv; fill in 8390 specific dev fields. */ - dev = alloc_ei_netdev(); - if (!dev) { - dev_err(&pdev->dev, "cannot allocate ethernet device\n"); - goto err_out_free_res; - } - dev->netdev_ops = &ne2k_netdev_ops; - ei_local = netdev_priv(dev); - ei_local->msg_enable = netif_msg_init(ne2k_msg_enable, default_msg_level); - - SET_NETDEV_DEV(dev, &pdev->dev); - - /* Reset card. Who knows what dain-bramaged state it was left in. */ - { - unsigned long reset_start_time = jiffies; - - outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); - - /* This looks like a horrible timing loop, but it should never - * take more than a few cycles. - */ - while ((inb(ioaddr + EN0_ISR) & ENISR_RESET) == 0) - /* Limit wait: '2' avoids jiffy roll-over. */ - if (jiffies - reset_start_time > 2) { - dev_err(&pdev->dev, - "Card failure (no reset ack).\n"); - goto err_out_free_netdev; - } - /* Ack all intr. */ - outb(0xff, ioaddr + EN0_ISR); - } - - /* Read the 16 bytes of station address PROM. - * We must first initialize registers, similar - * to NS8390_init(eifdev, 0). - * We can't reliably read the SAPROM address without this. - * (I learned the hard way!). - */ - { - struct {unsigned char value, offset; } program_seq[] = { - /* Select page 0 */ - {E8390_NODMA + E8390_PAGE0 + E8390_STOP, E8390_CMD}, - /* Set word-wide access */ - {0x49, EN0_DCFG}, - /* Clear the count regs. */ - {0x00, EN0_RCNTLO}, - /* Mask completion IRQ */ - {0x00, EN0_RCNTHI}, - {0x00, EN0_IMR}, - {0xFF, EN0_ISR}, - /* 0x20 Set to monitor */ - {E8390_RXOFF, EN0_RXCR}, - /* 0x02 and loopback mode */ - {E8390_TXOFF, EN0_TXCR}, - {32, EN0_RCNTLO}, - {0x00, EN0_RCNTHI}, - /* DMA starting at 0x0000 */ - {0x00, EN0_RSARLO}, - {0x00, EN0_RSARHI}, - {E8390_RREAD+E8390_START, E8390_CMD}, - }; - for (i = 0; i < ARRAY_SIZE(program_seq); i++) - outb(program_seq[i].value, - ioaddr + program_seq[i].offset); - - } - - /* Note: all PCI cards have at least 16 bit access, so we don't have - * to check for 8 bit cards. Most cards permit 32 bit access. - */ - if (flags & ONLY_32BIT_IO) { - for (i = 0; i < 4 ; i++) - ((u32 *)SA_prom)[i] = le32_to_cpu(inl(ioaddr + NE_DATAPORT)); - } else - for (i = 0; i < 32 /* sizeof(SA_prom )*/; i++) - SA_prom[i] = inb(ioaddr + NE_DATAPORT); - - /* We always set the 8390 registers for word mode. */ - outb(0x49, ioaddr + EN0_DCFG); - start_page = NESM_START_PG; - - stop_page = flags & STOP_PG_0x60 ? 0x60 : NESM_STOP_PG; - - /* Set up the rest of the parameters. */ - dev->irq = irq; - dev->base_addr = ioaddr; - pci_set_drvdata(pdev, dev); - - ei_status.name = pci_clone_list[chip_idx].name; - ei_status.tx_start_page = start_page; - ei_status.stop_page = stop_page; - ei_status.word16 = 1; - ei_status.ne2k_flags = flags; - if (fnd_cnt < MAX_UNITS) { - if (full_duplex[fnd_cnt] > 0 || (options[fnd_cnt] & FORCE_FDX)) - ei_status.ne2k_flags |= FORCE_FDX; - } - - ei_status.rx_start_page = start_page + TX_PAGES; -#ifdef PACKETBUF_MEMSIZE - /* Allow the packet buffer size to be overridden by know-it-alls. */ - ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; -#endif - - ei_status.reset_8390 = &ne2k_pci_reset_8390; - ei_status.block_input = &ne2k_pci_block_input; - ei_status.block_output = &ne2k_pci_block_output; - ei_status.get_8390_hdr = &ne2k_pci_get_8390_hdr; - ei_status.priv = (unsigned long) pdev; - - dev->ethtool_ops = &ne2k_pci_ethtool_ops; - NS8390_init(dev, 0); - - memcpy(dev->dev_addr, SA_prom, dev->addr_len); - - i = register_netdev(dev); - if (i) - goto err_out_free_netdev; - - netdev_info(dev, "%s found at %#lx, IRQ %d, %pM.\n", - pci_clone_list[chip_idx].name, ioaddr, dev->irq, - dev->dev_addr); - - return 0; - -err_out_free_netdev: - free_netdev(dev); -err_out_free_res: - release_region(ioaddr, NE_IO_EXTENT); -err_out: - pci_disable_device(pdev); - return -ENODEV; -} - -/* Magic incantation sequence for full duplex on the supported cards. - */ -static inline int set_realtek_fdx(struct net_device *dev) -{ - long ioaddr = dev->base_addr; - - outb(0xC0 + E8390_NODMA, ioaddr + NE_CMD); /* Page 3 */ - outb(0xC0, ioaddr + 0x01); /* Enable writes to CONFIG3 */ - outb(0x40, ioaddr + 0x06); /* Enable full duplex */ - outb(0x00, ioaddr + 0x01); /* Disable writes to CONFIG3 */ - outb(E8390_PAGE0 + E8390_NODMA, ioaddr + NE_CMD); /* Page 0 */ - return 0; -} - -static inline int set_holtek_fdx(struct net_device *dev) -{ - long ioaddr = dev->base_addr; - - outb(inb(ioaddr + 0x20) | 0x80, ioaddr + 0x20); - return 0; -} - -static int ne2k_pci_set_fdx(struct net_device *dev) -{ - if (ei_status.ne2k_flags & REALTEK_FDX) - return set_realtek_fdx(dev); - else if (ei_status.ne2k_flags & HOLTEK_FDX) - return set_holtek_fdx(dev); - - return -EOPNOTSUPP; -} - -static int ne2k_pci_open(struct net_device *dev) -{ - int ret = request_irq(dev->irq, ei_interrupt, IRQF_SHARED, - dev->name, dev); - - if (ret) - return ret; - - if (ei_status.ne2k_flags & FORCE_FDX) - ne2k_pci_set_fdx(dev); - - ei_open(dev); - return 0; -} - -static int ne2k_pci_close(struct net_device *dev) -{ - ei_close(dev); - free_irq(dev->irq, dev); - return 0; -} - -/* Hard reset the card. This used to pause for the same period that a - * 8390 reset command required, but that shouldn't be necessary. - */ -static void ne2k_pci_reset_8390(struct net_device *dev) -{ - unsigned long reset_start_time = jiffies; - struct ei_device *ei_local = netdev_priv(dev); - - netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", - jiffies); - - outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); - - ei_status.txing = 0; - ei_status.dmaing = 0; - - /* This check _should_not_ be necessary, omit eventually. */ - while ((inb(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) - if (jiffies - reset_start_time > 2) { - netdev_err(dev, "%s did not complete.\n", __func__); - break; - } - /* Ack intr. */ - outb(ENISR_RESET, NE_BASE + EN0_ISR); -} - -/* Grab the 8390 specific header. Similar to the block_input routine, but - * we don't need to be concerned with ring wrap as the header will be at - * the start of a page, so we optimize accordingly. - */ - -static void ne2k_pci_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page) -{ - - long nic_base = dev->base_addr; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see - */ - if (ei_status.dmaing) { - netdev_err(dev, "DMAing conflict in %s [DMAstat:%d][irqlock:%d].\n", - __func__, ei_status.dmaing, ei_status.irqlock); - return; - } - - ei_status.dmaing |= 0x01; - outb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); - outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); - outb(0, nic_base + EN0_RCNTHI); - outb(0, nic_base + EN0_RSARLO); /* On page boundary */ - outb(ring_page, nic_base + EN0_RSARHI); - outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); - - if (ei_status.ne2k_flags & ONLY_16BIT_IO) { - insw(NE_BASE + NE_DATAPORT, hdr, - sizeof(struct e8390_pkt_hdr) >> 1); - } else { - *(u32 *)hdr = le32_to_cpu(inl(NE_BASE + NE_DATAPORT)); - le16_to_cpus(&hdr->count); - } - /* Ack intr. */ - outb(ENISR_RDC, nic_base + EN0_ISR); - ei_status.dmaing &= ~0x01; -} - -/* Block input and output, similar to the Crynwr packet driver. If you - *are porting to a new ethercard, look at the packet driver source for hints. - *The NEx000 doesn't share the on-board packet memory -- you have to put - *the packet out through the "remote DMA" dataport using outb. - */ - -static void ne2k_pci_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) -{ - long nic_base = dev->base_addr; - char *buf = skb->data; - - /* This *shouldn't* happen. - * If it does, it's the last thing you'll see. - */ - if (ei_status.dmaing) { - netdev_err(dev, "DMAing conflict in %s [DMAstat:%d][irqlock:%d]\n", - __func__, ei_status.dmaing, ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - if (ei_status.ne2k_flags & ONLY_32BIT_IO) - count = (count + 3) & 0xFFFC; - outb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); - outb(count & 0xff, nic_base + EN0_RCNTLO); - outb(count >> 8, nic_base + EN0_RCNTHI); - outb(ring_offset & 0xff, nic_base + EN0_RSARLO); - outb(ring_offset >> 8, nic_base + EN0_RSARHI); - outb(E8390_RREAD + E8390_START, nic_base + NE_CMD); - - if (ei_status.ne2k_flags & ONLY_16BIT_IO) { - insw(NE_BASE + NE_DATAPORT, buf, count >> 1); - if (count & 0x01) - buf[count-1] = inb(NE_BASE + NE_DATAPORT); - } else { - insl(NE_BASE + NE_DATAPORT, buf, count >> 2); - if (count & 3) { - buf += count & ~3; - if (count & 2) { - __le16 *b = (__le16 *)buf; - - *b++ = cpu_to_le16(inw(NE_BASE + NE_DATAPORT)); - buf = (char *)b; - } - if (count & 1) - *buf = inb(NE_BASE + NE_DATAPORT); - } - } - /* Ack intr. */ - outb(ENISR_RDC, nic_base + EN0_ISR); - ei_status.dmaing &= ~0x01; -} - -static void ne2k_pci_block_output(struct net_device *dev, int count, - const unsigned char *buf, const int start_page) -{ - long nic_base = NE_BASE; - unsigned long dma_start; - - /* On little-endian it's always safe to round the count up for - * word writes. - */ - if (ei_status.ne2k_flags & ONLY_32BIT_IO) - count = (count + 3) & 0xFFFC; - else - if (count & 0x01) - count++; - - /* This *shouldn't* happen. - * If it does, it's the last thing you'll see. - */ - if (ei_status.dmaing) { - netdev_err(dev, "DMAing conflict in %s [DMAstat:%d][irqlock:%d]\n", - __func__, ei_status.dmaing, ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - /* We should already be in page 0, but to be safe... */ - outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); - -#ifdef NE_RW_BUGFIX - /* Handle the read-before-write bug the same way as the - * Crynwr packet driver -- the NatSemi method doesn't work. - * Actually this doesn't always work either, but if you have - * problems with your NEx000 this is better than nothing! - */ - outb(0x42, nic_base + EN0_RCNTLO); - outb(0x00, nic_base + EN0_RCNTHI); - outb(0x42, nic_base + EN0_RSARLO); - outb(0x00, nic_base + EN0_RSARHI); - outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); -#endif - outb(ENISR_RDC, nic_base + EN0_ISR); - - /* Now the normal output. */ - outb(count & 0xff, nic_base + EN0_RCNTLO); - outb(count >> 8, nic_base + EN0_RCNTHI); - outb(0x00, nic_base + EN0_RSARLO); - outb(start_page, nic_base + EN0_RSARHI); - outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); - if (ei_status.ne2k_flags & ONLY_16BIT_IO) { - outsw(NE_BASE + NE_DATAPORT, buf, count >> 1); - } else { - outsl(NE_BASE + NE_DATAPORT, buf, count >> 2); - if (count & 3) { - buf += count & ~3; - if (count & 2) { - __le16 *b = (__le16 *)buf; - - outw(le16_to_cpu(*b++), NE_BASE + NE_DATAPORT); - buf = (char *)b; - } - } - } - - dma_start = jiffies; - - while ((inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) - /* Avoid clock roll-over. */ - if (jiffies - dma_start > 2) { - netdev_warn(dev, "timeout waiting for Tx RDC.\n"); - ne2k_pci_reset_8390(dev); - NS8390_init(dev, 1); - break; - } - /* Ack intr. */ - outb(ENISR_RDC, nic_base + EN0_ISR); - ei_status.dmaing &= ~0x01; -} - -static void ne2k_pci_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - struct ei_device *ei = netdev_priv(dev); - struct pci_dev *pci_dev = (struct pci_dev *) ei->priv; - - strscpy(info->driver, DRV_NAME, sizeof(info->driver)); - strscpy(info->version, DRV_VERSION, sizeof(info->version)); - strscpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info)); -} - -static u32 ne2k_pci_get_msglevel(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - - return ei_local->msg_enable; -} - -static void ne2k_pci_set_msglevel(struct net_device *dev, u32 v) -{ - struct ei_device *ei_local = netdev_priv(dev); - - ei_local->msg_enable = v; -} - -static const struct ethtool_ops ne2k_pci_ethtool_ops = { - .get_drvinfo = ne2k_pci_get_drvinfo, - .get_msglevel = ne2k_pci_get_msglevel, - .set_msglevel = ne2k_pci_set_msglevel, -}; - -static void ne2k_pci_remove_one(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - BUG_ON(!dev); - unregister_netdev(dev); - release_region(dev->base_addr, NE_IO_EXTENT); - free_netdev(dev); - pci_disable_device(pdev); -} - -static int __maybe_unused ne2k_pci_suspend(struct device *dev_d) -{ - struct net_device *dev = dev_get_drvdata(dev_d); - - netif_device_detach(dev); - - return 0; -} - -static int __maybe_unused ne2k_pci_resume(struct device *dev_d) -{ - struct net_device *dev = dev_get_drvdata(dev_d); - - NS8390_init(dev, 1); - netif_device_attach(dev); - - return 0; -} - -static SIMPLE_DEV_PM_OPS(ne2k_pci_pm_ops, ne2k_pci_suspend, ne2k_pci_resume); - -static struct pci_driver ne2k_driver = { - .name = DRV_NAME, - .probe = ne2k_pci_init_one, - .remove = ne2k_pci_remove_one, - .id_table = ne2k_pci_tbl, - .driver.pm = &ne2k_pci_pm_ops, -}; - - -static int __init ne2k_pci_init(void) -{ - return pci_register_driver(&ne2k_driver); -} - - -static void __exit ne2k_pci_cleanup(void) -{ - pci_unregister_driver(&ne2k_driver); -} - -module_init(ne2k_pci_init); -module_exit(ne2k_pci_cleanup); diff --git a/drivers/net/ethernet/8390/pcnet_cs.c b/drivers/net/ethernet/8390/pcnet_cs.c deleted file mode 100644 index 96ad72abd373..000000000000 --- a/drivers/net/ethernet/8390/pcnet_cs.c +++ /dev/null @@ -1,1708 +0,0 @@ -/*====================================================================== - - A PCMCIA ethernet driver for NS8390-based cards - - This driver supports the D-Link DE-650 and Linksys EthernetCard - cards, the newer D-Link and Linksys combo cards, Accton EN2212 - cards, the RPTI EP400, and the PreMax PE-200 in non-shared-memory - mode, and the IBM Credit Card Adapter, the NE4100, the Thomas - Conrad ethernet card, and the Kingston KNE-PCM/x in shared-memory - mode. It will also handle the Socket EA card in either mode. - - Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net - - pcnet_cs.c 1.153 2003/11/09 18:53:09 - - The network driver code is based on Donald Becker's NE2000 code: - - Written 1992,1993 by Donald Becker. - Copyright 1993 United States Government as represented by the - Director, National Security Agency. This software may be used and - distributed according to the terms of the GNU General Public License, - incorporated herein by reference. - Donald Becker may be reached at becker@scyld.com - - Based also on Keith Moore's changes to Don Becker's code, for IBM - CCAE support. Drivers merged back together, and shared-memory - Socket EA support added, by Ken Raeburn, September 1995. - -======================================================================*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "8390.h" - -#include -#include -#include -#include - -#include -#include -#include - -#define PCNET_CMD 0x00 -#define PCNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */ -#define PCNET_RESET 0x1f /* Issue a read to reset, a write to clear. */ -#define PCNET_MISC 0x18 /* For IBM CCAE and Socket EA cards */ - -#define PCNET_START_PG 0x40 /* First page of TX buffer */ -#define PCNET_STOP_PG 0x80 /* Last page +1 of RX ring */ - -/* Socket EA cards have a larger packet buffer */ -#define SOCKET_START_PG 0x01 -#define SOCKET_STOP_PG 0xff - -#define PCNET_RDC_TIMEOUT (2*HZ/100) /* Max wait in jiffies for Tx RDC */ - -static const char *if_names[] = { "auto", "10baseT", "10base2"}; - -/*====================================================================*/ - -/* Module parameters */ - -MODULE_AUTHOR("David Hinds "); -MODULE_DESCRIPTION("NE2000 compatible PCMCIA ethernet driver"); -MODULE_LICENSE("GPL"); - -#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0) - -INT_MODULE_PARM(if_port, 1); /* Transceiver type */ -INT_MODULE_PARM(use_big_buf, 1); /* use 64K packet buffer? */ -INT_MODULE_PARM(mem_speed, 0); /* shared mem speed, in ns */ -INT_MODULE_PARM(delay_output, 0); /* pause after xmit? */ -INT_MODULE_PARM(delay_time, 4); /* in usec */ -INT_MODULE_PARM(use_shmem, -1); /* use shared memory? */ -INT_MODULE_PARM(full_duplex, 0); /* full duplex? */ - -/* Ugh! Let the user hardwire the hardware address for queer cards */ -static int hw_addr[6] = { 0, /* ... */ }; -module_param_array(hw_addr, int, NULL, 0); - -/*====================================================================*/ - -static void mii_phy_probe(struct net_device *dev); -static int pcnet_config(struct pcmcia_device *link); -static void pcnet_release(struct pcmcia_device *link); -static int pcnet_open(struct net_device *dev); -static int pcnet_close(struct net_device *dev); -static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static irqreturn_t ei_irq_wrapper(int irq, void *dev_id); -static void ei_watchdog(struct timer_list *t); -static void pcnet_reset_8390(struct net_device *dev); -static int set_config(struct net_device *dev, struct ifmap *map); -static int setup_shmem_window(struct pcmcia_device *link, int start_pg, - int stop_pg, int cm_offset); -static int setup_dma_config(struct pcmcia_device *link, int start_pg, - int stop_pg); - -static void pcnet_detach(struct pcmcia_device *p_dev); - -/*====================================================================*/ - -struct hw_info { - u_int offset; - u_char a0, a1, a2; - u_int flags; -}; - -#define DELAY_OUTPUT 0x01 -#define HAS_MISC_REG 0x02 -#define USE_BIG_BUF 0x04 -#define HAS_IBM_MISC 0x08 -#define IS_DL10019 0x10 -#define IS_DL10022 0x20 -#define HAS_MII 0x40 -#define USE_SHMEM 0x80 /* autodetected */ - -#define AM79C9XX_HOME_PHY 0x00006B90 /* HomePNA PHY */ -#define AM79C9XX_ETH_PHY 0x00006B70 /* 10baseT PHY */ -#define MII_PHYID_REV_MASK 0xfffffff0 -#define MII_PHYID_REG1 0x02 -#define MII_PHYID_REG2 0x03 - -static struct hw_info hw_info[] = { - { /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT }, - { /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 }, - { /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 }, - { /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94, - DELAY_OUTPUT | HAS_IBM_MISC }, - { /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 }, - { /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 }, - { /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 }, - { /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 }, - { /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 }, - { /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 }, - { /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 }, - { /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 }, - { /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* IBM FME */ 0x0374, 0x00, 0x04, 0xac, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 }, - { /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 }, - { /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 }, - { /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 }, - { /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 }, - { /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 }, - { /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 }, - { /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 }, - { /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 }, - { /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b, - DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF }, - { /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 }, - { /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 }, - { /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 }, - { /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 }, - { /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 } -}; - -#define NR_INFO ARRAY_SIZE(hw_info) - -static struct hw_info default_info = { 0, 0, 0, 0, 0 }; -static struct hw_info dl10019_info = { 0, 0, 0, 0, IS_DL10019|HAS_MII }; -static struct hw_info dl10022_info = { 0, 0, 0, 0, IS_DL10022|HAS_MII }; - -struct pcnet_dev { - struct pcmcia_device *p_dev; - u_int flags; - void __iomem *base; - struct timer_list watchdog; - int stale, fast_poll; - u_char phy_id; - u_char eth_phy, pna_phy; - u_short link_status; - u_long mii_reset; -}; - -static inline struct pcnet_dev *PRIV(struct net_device *dev) -{ - char *p = netdev_priv(dev); - return (struct pcnet_dev *)(p + sizeof(struct ei_device)); -} - -static const struct net_device_ops pcnet_netdev_ops = { - .ndo_open = pcnet_open, - .ndo_stop = pcnet_close, - .ndo_set_config = set_config, - .ndo_start_xmit = ei_start_xmit, - .ndo_get_stats = ei_get_stats, - .ndo_eth_ioctl = ei_ioctl, - .ndo_set_rx_mode = ei_set_multicast_list, - .ndo_tx_timeout = ei_tx_timeout, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = ei_poll, -#endif -}; - -static int pcnet_probe(struct pcmcia_device *link) -{ - struct pcnet_dev *info; - struct net_device *dev; - - dev_dbg(&link->dev, "pcnet_attach()\n"); - - /* Create new ethernet device */ - dev = __alloc_ei_netdev(sizeof(struct pcnet_dev)); - if (!dev) return -ENOMEM; - info = PRIV(dev); - info->p_dev = link; - link->priv = dev; - - link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; - - dev->netdev_ops = &pcnet_netdev_ops; - - return pcnet_config(link); -} /* pcnet_attach */ - -static void pcnet_detach(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - - dev_dbg(&link->dev, "pcnet_detach\n"); - - unregister_netdev(dev); - - pcnet_release(link); - - free_netdev(dev); -} /* pcnet_detach */ - -/*====================================================================== - - This probes for a card's hardware address, for card types that - encode this information in their CIS. - -======================================================================*/ - -static struct hw_info *get_hwinfo(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - u_char __iomem *base, *virt; - int i, j; - - /* Allocate a small memory window */ - link->resource[2]->flags |= WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; - link->resource[2]->start = 0; link->resource[2]->end = 0; - i = pcmcia_request_window(link, link->resource[2], 0); - if (i != 0) - return NULL; - - virt = ioremap(link->resource[2]->start, - resource_size(link->resource[2])); - if (unlikely(!virt)) { - pcmcia_release_window(link, link->resource[2]); - return NULL; - } - - for (i = 0; i < NR_INFO; i++) { - pcmcia_map_mem_page(link, link->resource[2], - hw_info[i].offset & ~(resource_size(link->resource[2])-1)); - base = &virt[hw_info[i].offset & (resource_size(link->resource[2])-1)]; - if ((readb(base+0) == hw_info[i].a0) && - (readb(base+2) == hw_info[i].a1) && - (readb(base+4) == hw_info[i].a2)) { - for (j = 0; j < 6; j++) - dev->dev_addr[j] = readb(base + (j<<1)); - break; - } - } - - iounmap(virt); - j = pcmcia_release_window(link, link->resource[2]); - return (i < NR_INFO) ? hw_info+i : NULL; -} /* get_hwinfo */ - -/*====================================================================== - - This probes for a card's hardware address by reading the PROM. - It checks the address against a list of known types, then falls - back to a simple NE2000 clone signature check. - -======================================================================*/ - -static struct hw_info *get_prom(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - unsigned int ioaddr = dev->base_addr; - u_char prom[32]; - int i, j; - - /* This is lifted straight from drivers/net/ethernet/8390/ne.c */ - struct { - u_char value, offset; - } program_seq[] = { - {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ - {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ - {0x00, EN0_RCNTLO}, /* Clear the count regs. */ - {0x00, EN0_RCNTHI}, - {0x00, EN0_IMR}, /* Mask completion irq. */ - {0xFF, EN0_ISR}, - {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ - {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ - {32, EN0_RCNTLO}, - {0x00, EN0_RCNTHI}, - {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ - {0x00, EN0_RSARHI}, - {E8390_RREAD+E8390_START, E8390_CMD}, - }; - - pcnet_reset_8390(dev); - mdelay(10); - - for (i = 0; i < ARRAY_SIZE(program_seq); i++) - outb_p(program_seq[i].value, ioaddr + program_seq[i].offset); - - for (i = 0; i < 32; i++) - prom[i] = inb(ioaddr + PCNET_DATAPORT); - for (i = 0; i < NR_INFO; i++) { - if ((prom[0] == hw_info[i].a0) && - (prom[2] == hw_info[i].a1) && - (prom[4] == hw_info[i].a2)) - break; - } - if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) { - for (j = 0; j < 6; j++) - dev->dev_addr[j] = prom[j<<1]; - return (i < NR_INFO) ? hw_info+i : &default_info; - } - return NULL; -} /* get_prom */ - -/*====================================================================== - - For DL10019 based cards, like the Linksys EtherFast - -======================================================================*/ - -static struct hw_info *get_dl10019(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - int i; - u_char sum; - - for (sum = 0, i = 0x14; i < 0x1c; i++) - sum += inb_p(dev->base_addr + i); - if (sum != 0xff) - return NULL; - for (i = 0; i < 6; i++) - dev->dev_addr[i] = inb_p(dev->base_addr + 0x14 + i); - i = inb(dev->base_addr + 0x1f); - return ((i == 0x91)||(i == 0x99)) ? &dl10022_info : &dl10019_info; -} - -/*====================================================================== - - For Asix AX88190 based cards - -======================================================================*/ - -static struct hw_info *get_ax88190(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - unsigned int ioaddr = dev->base_addr; - int i, j; - - /* Not much of a test, but the alternatives are messy */ - if (link->config_base != 0x03c0) - return NULL; - - outb_p(0x01, ioaddr + EN0_DCFG); /* Set word-wide access. */ - outb_p(0x00, ioaddr + EN0_RSARLO); /* DMA starting at 0x0400. */ - outb_p(0x04, ioaddr + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, ioaddr + E8390_CMD); - - for (i = 0; i < 6; i += 2) { - j = inw(ioaddr + PCNET_DATAPORT); - dev->dev_addr[i] = j & 0xff; - dev->dev_addr[i+1] = j >> 8; - } - return NULL; -} - -/*====================================================================== - - This should be totally unnecessary... but when we can't figure - out the hardware address any other way, we'll let the user hard - wire it when the module is initialized. - -======================================================================*/ - -static struct hw_info *get_hwired(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - int i; - - for (i = 0; i < 6; i++) - if (hw_addr[i] != 0) break; - if (i == 6) - return NULL; - - for (i = 0; i < 6; i++) - dev->dev_addr[i] = hw_addr[i]; - - return &default_info; -} /* get_hwired */ - -static int try_io_port(struct pcmcia_device *link) -{ - int j, ret; - link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; - link->resource[1]->flags &= ~IO_DATA_PATH_WIDTH; - if (link->resource[0]->end == 32) { - link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; - if (link->resource[1]->end > 0) { - /* for master/slave multifunction cards */ - link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; - } - } else { - /* This should be two 16-port windows */ - link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; - link->resource[1]->flags |= IO_DATA_PATH_WIDTH_16; - } - if (link->resource[0]->start == 0) { - for (j = 0; j < 0x400; j += 0x20) { - link->resource[0]->start = j ^ 0x300; - link->resource[1]->start = (j ^ 0x300) + 0x10; - link->io_lines = 16; - ret = pcmcia_request_io(link); - if (ret == 0) - return ret; - } - return ret; - } else { - return pcmcia_request_io(link); - } -} - -static int pcnet_confcheck(struct pcmcia_device *p_dev, void *priv_data) -{ - int *priv = priv_data; - int try = (*priv & 0x1); - - *priv &= (p_dev->resource[2]->end >= 0x4000) ? 0x10 : ~0x10; - - if (p_dev->config_index == 0) - return -EINVAL; - - if (p_dev->resource[0]->end + p_dev->resource[1]->end < 32) - return -EINVAL; - - if (try) - p_dev->io_lines = 16; - return try_io_port(p_dev); -} - -static struct hw_info *pcnet_try_config(struct pcmcia_device *link, - int *has_shmem, int try) -{ - struct net_device *dev = link->priv; - struct hw_info *local_hw_info; - struct pcnet_dev *info = PRIV(dev); - int priv = try; - int ret; - - ret = pcmcia_loop_config(link, pcnet_confcheck, &priv); - if (ret) { - dev_warn(&link->dev, "no useable port range found\n"); - return NULL; - } - *has_shmem = (priv & 0x10); - - if (!link->irq) - return NULL; - - if (resource_size(link->resource[1]) == 8) - link->config_flags |= CONF_ENABLE_SPKR; - - if ((link->manf_id == MANFID_IBM) && - (link->card_id == PRODID_IBM_HOME_AND_AWAY)) - link->config_index |= 0x10; - - ret = pcmcia_enable_device(link); - if (ret) - return NULL; - - dev->irq = link->irq; - dev->base_addr = link->resource[0]->start; - - if (info->flags & HAS_MISC_REG) { - if ((if_port == 1) || (if_port == 2)) - dev->if_port = if_port; - else - dev_notice(&link->dev, "invalid if_port requested\n"); - } else - dev->if_port = 0; - - if ((link->config_base == 0x03c0) && - (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) { - dev_info(&link->dev, - "this is an AX88190 card - use axnet_cs instead.\n"); - return NULL; - } - - local_hw_info = get_hwinfo(link); - if (!local_hw_info) - local_hw_info = get_prom(link); - if (!local_hw_info) - local_hw_info = get_dl10019(link); - if (!local_hw_info) - local_hw_info = get_ax88190(link); - if (!local_hw_info) - local_hw_info = get_hwired(link); - - return local_hw_info; -} - -static int pcnet_config(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - struct pcnet_dev *info = PRIV(dev); - int start_pg, stop_pg, cm_offset; - int has_shmem = 0; - struct hw_info *local_hw_info; - - dev_dbg(&link->dev, "pcnet_config\n"); - - local_hw_info = pcnet_try_config(link, &has_shmem, 0); - if (!local_hw_info) { - /* check whether forcing io_lines to 16 helps... */ - pcmcia_disable_device(link); - local_hw_info = pcnet_try_config(link, &has_shmem, 1); - if (local_hw_info == NULL) { - dev_notice(&link->dev, "unable to read hardware net" - " address for io base %#3lx\n", dev->base_addr); - goto failed; - } - } - - info->flags = local_hw_info->flags; - /* Check for user overrides */ - info->flags |= (delay_output) ? DELAY_OUTPUT : 0; - if ((link->manf_id == MANFID_SOCKET) && - ((link->card_id == PRODID_SOCKET_LPE) || - (link->card_id == PRODID_SOCKET_LPE_CF) || - (link->card_id == PRODID_SOCKET_EIO))) - info->flags &= ~USE_BIG_BUF; - if (!use_big_buf) - info->flags &= ~USE_BIG_BUF; - - if (info->flags & USE_BIG_BUF) { - start_pg = SOCKET_START_PG; - stop_pg = SOCKET_STOP_PG; - cm_offset = 0x10000; - } else { - start_pg = PCNET_START_PG; - stop_pg = PCNET_STOP_PG; - cm_offset = 0; - } - - /* has_shmem is ignored if use_shmem != -1 */ - if ((use_shmem == 0) || (!has_shmem && (use_shmem == -1)) || - (setup_shmem_window(link, start_pg, stop_pg, cm_offset) != 0)) - setup_dma_config(link, start_pg, stop_pg); - - ei_status.name = "NE2000"; - ei_status.word16 = 1; - ei_status.reset_8390 = pcnet_reset_8390; - - if (info->flags & (IS_DL10019|IS_DL10022)) - mii_phy_probe(dev); - - SET_NETDEV_DEV(dev, &link->dev); - - if (register_netdev(dev) != 0) { - pr_notice("register_netdev() failed\n"); - goto failed; - } - - if (info->flags & (IS_DL10019|IS_DL10022)) { - u_char id = inb(dev->base_addr + 0x1a); - netdev_info(dev, "NE2000 (DL100%d rev %02x): ", - (info->flags & IS_DL10022) ? 22 : 19, id); - if (info->pna_phy) - pr_cont("PNA, "); - } else { - netdev_info(dev, "NE2000 Compatible: "); - } - pr_cont("io %#3lx, irq %d,", dev->base_addr, dev->irq); - if (info->flags & USE_SHMEM) - pr_cont(" mem %#5lx,", dev->mem_start); - if (info->flags & HAS_MISC_REG) - pr_cont(" %s xcvr,", if_names[dev->if_port]); - pr_cont(" hw_addr %pM\n", dev->dev_addr); - return 0; - -failed: - pcnet_release(link); - return -ENODEV; -} /* pcnet_config */ - -static void pcnet_release(struct pcmcia_device *link) -{ - struct pcnet_dev *info = PRIV(link->priv); - - dev_dbg(&link->dev, "pcnet_release\n"); - - if (info->flags & USE_SHMEM) - iounmap(info->base); - - pcmcia_disable_device(link); -} - -static int pcnet_suspend(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - - if (link->open) - netif_device_detach(dev); - - return 0; -} - -static int pcnet_resume(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - - if (link->open) { - pcnet_reset_8390(dev); - NS8390_init(dev, 1); - netif_device_attach(dev); - } - - return 0; -} - - -/*====================================================================== - - MII interface support for DL10019 and DL10022 based cards - - On the DL10019, the MII IO direction bit is 0x10; on the DL10022 - it is 0x20. Setting both bits seems to work on both card types. - -======================================================================*/ - -#define DLINK_GPIO 0x1c -#define DLINK_DIAG 0x1d -#define DLINK_EEPROM 0x1e - -#define MDIO_SHIFT_CLK 0x80 -#define MDIO_DATA_OUT 0x40 -#define MDIO_DIR_WRITE 0x30 -#define MDIO_DATA_WRITE0 (MDIO_DIR_WRITE) -#define MDIO_DATA_WRITE1 (MDIO_DIR_WRITE | MDIO_DATA_OUT) -#define MDIO_DATA_READ 0x10 -#define MDIO_MASK 0x0f - -static void mdio_sync(unsigned int addr) -{ - int bits, mask = inb(addr) & MDIO_MASK; - for (bits = 0; bits < 32; bits++) { - outb(mask | MDIO_DATA_WRITE1, addr); - outb(mask | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, addr); - } -} - -static int mdio_read(unsigned int addr, int phy_id, int loc) -{ - u_int cmd = (0x06<<10)|(phy_id<<5)|loc; - int i, retval = 0, mask = inb(addr) & MDIO_MASK; - - mdio_sync(addr); - for (i = 13; i >= 0; i--) { - int dat = (cmd&(1< 0; i--) { - outb(mask, addr); - retval = (retval << 1) | ((inb(addr) & MDIO_DATA_READ) != 0); - outb(mask | MDIO_SHIFT_CLK, addr); - } - return (retval>>1) & 0xffff; -} - -static void mdio_write(unsigned int addr, int phy_id, int loc, int value) -{ - u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value; - int i, mask = inb(addr) & MDIO_MASK; - - mdio_sync(addr); - for (i = 31; i >= 0; i--) { - int dat = (cmd&(1<= 0; i--) { - outb(mask, addr); - outb(mask | MDIO_SHIFT_CLK, addr); - } -} - -/*====================================================================== - - EEPROM access routines for DL10019 and DL10022 based cards - -======================================================================*/ - -#define EE_EEP 0x40 -#define EE_ASIC 0x10 -#define EE_CS 0x08 -#define EE_CK 0x04 -#define EE_DO 0x02 -#define EE_DI 0x01 -#define EE_ADOT 0x01 /* DataOut for ASIC */ -#define EE_READ_CMD 0x06 - -#define DL19FDUPLX 0x0400 /* DL10019 Full duplex mode */ - -static int read_eeprom(unsigned int ioaddr, int location) -{ - int i, retval = 0; - unsigned int ee_addr = ioaddr + DLINK_EEPROM; - int read_cmd = location | (EE_READ_CMD << 8); - - outb(0, ee_addr); - outb(EE_EEP|EE_CS, ee_addr); - - /* Shift the read command bits out. */ - for (i = 10; i >= 0; i--) { - short dataval = (read_cmd & (1 << i)) ? EE_DO : 0; - outb_p(EE_EEP|EE_CS|dataval, ee_addr); - outb_p(EE_EEP|EE_CS|dataval|EE_CK, ee_addr); - } - outb(EE_EEP|EE_CS, ee_addr); - - for (i = 16; i > 0; i--) { - outb_p(EE_EEP|EE_CS | EE_CK, ee_addr); - retval = (retval << 1) | ((inb(ee_addr) & EE_DI) ? 1 : 0); - outb_p(EE_EEP|EE_CS, ee_addr); - } - - /* Terminate the EEPROM access. */ - outb(0, ee_addr); - return retval; -} - -/* - The internal ASIC registers can be changed by EEPROM READ access - with EE_ASIC bit set. - In ASIC mode, EE_ADOT is used to output the data to the ASIC. -*/ - -static void write_asic(unsigned int ioaddr, int location, short asic_data) -{ - int i; - unsigned int ee_addr = ioaddr + DLINK_EEPROM; - short dataval; - int read_cmd = location | (EE_READ_CMD << 8); - - asic_data |= read_eeprom(ioaddr, location); - - outb(0, ee_addr); - outb(EE_ASIC|EE_CS|EE_DI, ee_addr); - - read_cmd = read_cmd >> 1; - - /* Shift the read command bits out. */ - for (i = 9; i >= 0; i--) { - dataval = (read_cmd & (1 << i)) ? EE_DO : 0; - outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr); - outb_p(EE_ASIC|EE_CS|EE_DI|dataval|EE_CK, ee_addr); - outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr); - } - // sync - outb(EE_ASIC|EE_CS, ee_addr); - outb(EE_ASIC|EE_CS|EE_CK, ee_addr); - outb(EE_ASIC|EE_CS, ee_addr); - - for (i = 15; i >= 0; i--) { - dataval = (asic_data & (1 << i)) ? EE_ADOT : 0; - outb_p(EE_ASIC|EE_CS|dataval, ee_addr); - outb_p(EE_ASIC|EE_CS|dataval|EE_CK, ee_addr); - outb_p(EE_ASIC|EE_CS|dataval, ee_addr); - } - - /* Terminate the ASIC access. */ - outb(EE_ASIC|EE_DI, ee_addr); - outb(EE_ASIC|EE_DI| EE_CK, ee_addr); - outb(EE_ASIC|EE_DI, ee_addr); - - outb(0, ee_addr); -} - -/*====================================================================*/ - -static void set_misc_reg(struct net_device *dev) -{ - unsigned int nic_base = dev->base_addr; - struct pcnet_dev *info = PRIV(dev); - u_char tmp; - - if (info->flags & HAS_MISC_REG) { - tmp = inb_p(nic_base + PCNET_MISC) & ~3; - if (dev->if_port == 2) - tmp |= 1; - if (info->flags & USE_BIG_BUF) - tmp |= 2; - if (info->flags & HAS_IBM_MISC) - tmp |= 8; - outb_p(tmp, nic_base + PCNET_MISC); - } - if (info->flags & IS_DL10022) { - if (info->flags & HAS_MII) { - /* Advertise 100F, 100H, 10F, 10H */ - mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 4, 0x01e1); - /* Restart MII autonegotiation */ - mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x0000); - mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x1200); - info->mii_reset = jiffies; - } else { - outb(full_duplex ? 4 : 0, nic_base + DLINK_DIAG); - } - } else if (info->flags & IS_DL10019) { - /* Advertise 100F, 100H, 10F, 10H */ - mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 4, 0x01e1); - /* Restart MII autonegotiation */ - mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x0000); - mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x1200); - } -} - -/*====================================================================*/ - -static void mii_phy_probe(struct net_device *dev) -{ - struct pcnet_dev *info = PRIV(dev); - unsigned int mii_addr = dev->base_addr + DLINK_GPIO; - int i; - u_int tmp, phyid; - - for (i = 31; i >= 0; i--) { - tmp = mdio_read(mii_addr, i, 1); - if ((tmp == 0) || (tmp == 0xffff)) - continue; - tmp = mdio_read(mii_addr, i, MII_PHYID_REG1); - phyid = tmp << 16; - phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2); - phyid &= MII_PHYID_REV_MASK; - netdev_dbg(dev, "MII at %d is 0x%08x\n", i, phyid); - if (phyid == AM79C9XX_HOME_PHY) { - info->pna_phy = i; - } else if (phyid != AM79C9XX_ETH_PHY) { - info->eth_phy = i; - } - } -} - -static int pcnet_open(struct net_device *dev) -{ - int ret; - struct pcnet_dev *info = PRIV(dev); - struct pcmcia_device *link = info->p_dev; - unsigned int nic_base = dev->base_addr; - - dev_dbg(&link->dev, "pcnet_open('%s')\n", dev->name); - - if (!pcmcia_dev_present(link)) - return -ENODEV; - - set_misc_reg(dev); - - outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */ - ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev->name, dev); - if (ret) - return ret; - - link->open++; - - info->phy_id = info->eth_phy; - info->link_status = 0x00; - timer_setup(&info->watchdog, ei_watchdog, 0); - mod_timer(&info->watchdog, jiffies + HZ); - - return ei_open(dev); -} /* pcnet_open */ - -/*====================================================================*/ - -static int pcnet_close(struct net_device *dev) -{ - struct pcnet_dev *info = PRIV(dev); - struct pcmcia_device *link = info->p_dev; - - dev_dbg(&link->dev, "pcnet_close('%s')\n", dev->name); - - ei_close(dev); - free_irq(dev->irq, dev); - - link->open--; - netif_stop_queue(dev); - del_timer_sync(&info->watchdog); - - return 0; -} /* pcnet_close */ - -/*====================================================================== - - Hard reset the card. This used to pause for the same period that - a 8390 reset command required, but that shouldn't be necessary. - -======================================================================*/ - -static void pcnet_reset_8390(struct net_device *dev) -{ - unsigned int nic_base = dev->base_addr; - int i; - - ei_status.txing = ei_status.dmaing = 0; - - outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, nic_base + E8390_CMD); - - outb(inb(nic_base + PCNET_RESET), nic_base + PCNET_RESET); - - for (i = 0; i < 100; i++) { - if ((inb_p(nic_base+EN0_ISR) & ENISR_RESET) != 0) - break; - udelay(100); - } - outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */ - - if (i == 100) - netdev_err(dev, "pcnet_reset_8390() did not complete.\n"); - - set_misc_reg(dev); - -} /* pcnet_reset_8390 */ - -/*====================================================================*/ - -static int set_config(struct net_device *dev, struct ifmap *map) -{ - struct pcnet_dev *info = PRIV(dev); - if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { - if (!(info->flags & HAS_MISC_REG)) - return -EOPNOTSUPP; - else if ((map->port < 1) || (map->port > 2)) - return -EINVAL; - dev->if_port = map->port; - netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]); - NS8390_init(dev, 1); - } - return 0; -} - -/*====================================================================*/ - -static irqreturn_t ei_irq_wrapper(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct pcnet_dev *info; - irqreturn_t ret = ei_interrupt(irq, dev_id); - - if (ret == IRQ_HANDLED) { - info = PRIV(dev); - info->stale = 0; - } - return ret; -} - -static void ei_watchdog(struct timer_list *t) -{ - struct pcnet_dev *info = from_timer(info, t, watchdog); - struct net_device *dev = info->p_dev->priv; - unsigned int nic_base = dev->base_addr; - unsigned int mii_addr = nic_base + DLINK_GPIO; - u_short link; - - if (!netif_device_present(dev)) goto reschedule; - - /* Check for pending interrupt with expired latency timer: with - this, we can limp along even if the interrupt is blocked */ - if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) { - if (!info->fast_poll) - netdev_info(dev, "interrupt(s) dropped!\n"); - ei_irq_wrapper(dev->irq, dev); - info->fast_poll = HZ; - } - if (info->fast_poll) { - info->fast_poll--; - info->watchdog.expires = jiffies + 1; - add_timer(&info->watchdog); - return; - } - - if (!(info->flags & HAS_MII)) - goto reschedule; - - mdio_read(mii_addr, info->phy_id, 1); - link = mdio_read(mii_addr, info->phy_id, 1); - if (!link || (link == 0xffff)) { - if (info->eth_phy) { - info->phy_id = info->eth_phy = 0; - } else { - netdev_info(dev, "MII is missing!\n"); - info->flags &= ~HAS_MII; - } - goto reschedule; - } - - link &= 0x0004; - if (link != info->link_status) { - u_short p = mdio_read(mii_addr, info->phy_id, 5); - netdev_info(dev, "%s link beat\n", link ? "found" : "lost"); - if (link && (info->flags & IS_DL10022)) { - /* Disable collision detection on full duplex links */ - outb((p & 0x0140) ? 4 : 0, nic_base + DLINK_DIAG); - } else if (link && (info->flags & IS_DL10019)) { - /* Disable collision detection on full duplex links */ - write_asic(dev->base_addr, 4, (p & 0x140) ? DL19FDUPLX : 0); - } - if (link) { - if (info->phy_id == info->eth_phy) { - if (p) - netdev_info(dev, "autonegotiation complete: " - "%sbaseT-%cD selected\n", - ((p & 0x0180) ? "100" : "10"), - ((p & 0x0140) ? 'F' : 'H')); - else - netdev_info(dev, "link partner did not autonegotiate\n"); - } - NS8390_init(dev, 1); - } - info->link_status = link; - } - if (info->pna_phy && time_after(jiffies, info->mii_reset + 6*HZ)) { - link = mdio_read(mii_addr, info->eth_phy, 1) & 0x0004; - if (((info->phy_id == info->pna_phy) && link) || - ((info->phy_id != info->pna_phy) && !link)) { - /* isolate this MII and try flipping to the other one */ - mdio_write(mii_addr, info->phy_id, 0, 0x0400); - info->phy_id ^= info->pna_phy ^ info->eth_phy; - netdev_info(dev, "switched to %s transceiver\n", - (info->phy_id == info->eth_phy) ? "ethernet" : "PNA"); - mdio_write(mii_addr, info->phy_id, 0, - (info->phy_id == info->eth_phy) ? 0x1000 : 0); - info->link_status = 0; - info->mii_reset = jiffies; - } - } - -reschedule: - info->watchdog.expires = jiffies + HZ; - add_timer(&info->watchdog); -} - -/*====================================================================*/ - - -static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct pcnet_dev *info = PRIV(dev); - struct mii_ioctl_data *data = if_mii(rq); - unsigned int mii_addr = dev->base_addr + DLINK_GPIO; - - if (!(info->flags & (IS_DL10019|IS_DL10022))) - return -EINVAL; - - switch (cmd) { - case SIOCGMIIPHY: - data->phy_id = info->phy_id; - fallthrough; - case SIOCGMIIREG: /* Read MII PHY register. */ - data->val_out = mdio_read(mii_addr, data->phy_id, data->reg_num & 0x1f); - return 0; - case SIOCSMIIREG: /* Write MII PHY register. */ - mdio_write(mii_addr, data->phy_id, data->reg_num & 0x1f, data->val_in); - return 0; - } - return -EOPNOTSUPP; -} - -/*====================================================================*/ - -static void dma_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, - int ring_page) -{ - unsigned int nic_base = dev->base_addr; - - if (ei_status.dmaing) { - netdev_err(dev, "DMAing conflict in dma_block_input." - "[DMAstat:%1x][irqlock:%1x]\n", - ei_status.dmaing, ei_status.irqlock); - return; - } - - ei_status.dmaing |= 0x01; - outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + PCNET_CMD); - outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); - outb_p(0, nic_base + EN0_RCNTHI); - outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ - outb_p(ring_page, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + PCNET_CMD); - - insw(nic_base + PCNET_DATAPORT, hdr, - sizeof(struct e8390_pkt_hdr)>>1); - /* Fix for big endian systems */ - hdr->count = le16_to_cpu(hdr->count); - - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; -} - -/*====================================================================*/ - -static void dma_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) -{ - unsigned int nic_base = dev->base_addr; - int xfer_count = count; - char *buf = skb->data; - struct ei_device *ei_local = netdev_priv(dev); - - if ((netif_msg_rx_status(ei_local)) && (count != 4)) - netdev_dbg(dev, "[bi=%d]\n", count+4); - if (ei_status.dmaing) { - netdev_err(dev, "DMAing conflict in dma_block_input." - "[DMAstat:%1x][irqlock:%1x]\n", - ei_status.dmaing, ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + PCNET_CMD); - outb_p(count & 0xff, nic_base + EN0_RCNTLO); - outb_p(count >> 8, nic_base + EN0_RCNTHI); - outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); - outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + PCNET_CMD); - - insw(nic_base + PCNET_DATAPORT,buf,count>>1); - if (count & 0x01) { - buf[count-1] = inb(nic_base + PCNET_DATAPORT); - xfer_count++; - } - - /* This was for the ALPHA version only, but enough people have been - encountering problems that it is still here. */ -#ifdef PCMCIA_DEBUG - /* DMA termination address check... */ - if (netif_msg_rx_status(ei_local)) { - int addr, tries = 20; - do { - /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here - -- it's broken for Rx on some cards! */ - int high = inb_p(nic_base + EN0_RSARHI); - int low = inb_p(nic_base + EN0_RSARLO); - addr = (high << 8) + low; - if (((ring_offset + xfer_count) & 0xff) == (addr & 0xff)) - break; - } while (--tries > 0); - if (tries <= 0) - netdev_notice(dev, "RX transfer address mismatch," - "%#4.4x (expected) vs. %#4.4x (actual).\n", - ring_offset + xfer_count, addr); - } -#endif - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; -} /* dma_block_input */ - -/*====================================================================*/ - -static void dma_block_output(struct net_device *dev, int count, - const u_char *buf, const int start_page) -{ - unsigned int nic_base = dev->base_addr; - struct pcnet_dev *info = PRIV(dev); -#ifdef PCMCIA_DEBUG - int retries = 0; - struct ei_device *ei_local = netdev_priv(dev); -#endif - u_long dma_start; - -#ifdef PCMCIA_DEBUG - netif_dbg(ei_local, tx_queued, dev, "[bo=%d]\n", count); -#endif - - /* Round the count up for word writes. Do we need to do this? - What effect will an odd byte count have on the 8390? - I should check someday. */ - if (count & 0x01) - count++; - if (ei_status.dmaing) { - netdev_err(dev, "DMAing conflict in dma_block_output." - "[DMAstat:%1x][irqlock:%1x]\n", - ei_status.dmaing, ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - /* We should already be in page 0, but to be safe... */ - outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base+PCNET_CMD); - -#ifdef PCMCIA_DEBUG - retry: -#endif - - outb_p(ENISR_RDC, nic_base + EN0_ISR); - - /* Now the normal output. */ - outb_p(count & 0xff, nic_base + EN0_RCNTLO); - outb_p(count >> 8, nic_base + EN0_RCNTHI); - outb_p(0x00, nic_base + EN0_RSARLO); - outb_p(start_page, nic_base + EN0_RSARHI); - - outb_p(E8390_RWRITE+E8390_START, nic_base + PCNET_CMD); - outsw(nic_base + PCNET_DATAPORT, buf, count>>1); - - dma_start = jiffies; - -#ifdef PCMCIA_DEBUG - /* This was for the ALPHA version only, but enough people have been - encountering problems that it is still here. */ - /* DMA termination address check... */ - if (netif_msg_tx_queued(ei_local)) { - int addr, tries = 20; - do { - int high = inb_p(nic_base + EN0_RSARHI); - int low = inb_p(nic_base + EN0_RSARLO); - addr = (high << 8) + low; - if ((start_page << 8) + count == addr) - break; - } while (--tries > 0); - if (tries <= 0) { - netdev_notice(dev, "Tx packet transfer address mismatch," - "%#4.4x (expected) vs. %#4.4x (actual).\n", - (start_page << 8) + count, addr); - if (retries++ == 0) - goto retry; - } - } -#endif - - while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + PCNET_RDC_TIMEOUT)) { - netdev_warn(dev, "timeout waiting for Tx RDC.\n"); - pcnet_reset_8390(dev); - NS8390_init(dev, 1); - break; - } - - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - if (info->flags & DELAY_OUTPUT) - udelay((long)delay_time); - ei_status.dmaing &= ~0x01; -} - -/*====================================================================*/ - -static int setup_dma_config(struct pcmcia_device *link, int start_pg, - int stop_pg) -{ - struct net_device *dev = link->priv; - - ei_status.tx_start_page = start_pg; - ei_status.rx_start_page = start_pg + TX_PAGES; - ei_status.stop_page = stop_pg; - - /* set up block i/o functions */ - ei_status.get_8390_hdr = dma_get_8390_hdr; - ei_status.block_input = dma_block_input; - ei_status.block_output = dma_block_output; - - return 0; -} - -/*====================================================================*/ - -static void copyin(void *dest, void __iomem *src, int c) -{ - u_short *d = dest; - u_short __iomem *s = src; - int odd; - - if (c <= 0) - return; - odd = (c & 1); c >>= 1; - - if (c) { - do { *d++ = __raw_readw(s++); } while (--c); - } - /* get last byte by fetching a word and masking */ - if (odd) - *((u_char *)d) = readw(s) & 0xff; -} - -static void copyout(void __iomem *dest, const void *src, int c) -{ - u_short __iomem *d = dest; - const u_short *s = src; - int odd; - - if (c <= 0) - return; - odd = (c & 1); c >>= 1; - - if (c) { - do { __raw_writew(*s++, d++); } while (--c); - } - /* copy last byte doing a read-modify-write */ - if (odd) - writew((readw(d) & 0xff00) | *(u_char *)s, d); -} - -/*====================================================================*/ - -static void shmem_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, - int ring_page) -{ - void __iomem *xfer_start = ei_status.mem + (TX_PAGES<<8) - + (ring_page << 8) - - (ei_status.rx_start_page << 8); - - copyin(hdr, xfer_start, sizeof(struct e8390_pkt_hdr)); - /* Fix for big endian systems */ - hdr->count = le16_to_cpu(hdr->count); -} - -/*====================================================================*/ - -static void shmem_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) -{ - void __iomem *base = ei_status.mem; - unsigned long offset = (TX_PAGES<<8) + ring_offset - - (ei_status.rx_start_page << 8); - char *buf = skb->data; - - if (offset + count > ei_status.priv) { - /* We must wrap the input move. */ - int semi_count = ei_status.priv - offset; - copyin(buf, base + offset, semi_count); - buf += semi_count; - offset = TX_PAGES<<8; - count -= semi_count; - } - copyin(buf, base + offset, count); -} - -/*====================================================================*/ - -static void shmem_block_output(struct net_device *dev, int count, - const u_char *buf, const int start_page) -{ - void __iomem *shmem = ei_status.mem + (start_page << 8); - shmem -= ei_status.tx_start_page << 8; - copyout(shmem, buf, count); -} - -/*====================================================================*/ - -static int setup_shmem_window(struct pcmcia_device *link, int start_pg, - int stop_pg, int cm_offset) -{ - struct net_device *dev = link->priv; - struct pcnet_dev *info = PRIV(dev); - int i, window_size, offset, ret; - - window_size = (stop_pg - start_pg) << 8; - if (window_size > 32 * 1024) - window_size = 32 * 1024; - - /* Make sure it's a power of two. */ - window_size = roundup_pow_of_two(window_size); - - /* Allocate a memory window */ - link->resource[3]->flags |= WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE; - link->resource[3]->flags |= WIN_USE_WAIT; - link->resource[3]->start = 0; link->resource[3]->end = window_size; - ret = pcmcia_request_window(link, link->resource[3], mem_speed); - if (ret) - goto failed; - - offset = (start_pg << 8) + cm_offset; - offset -= offset % window_size; - ret = pcmcia_map_mem_page(link, link->resource[3], offset); - if (ret) - goto failed; - - /* Try scribbling on the buffer */ - info->base = ioremap(link->resource[3]->start, - resource_size(link->resource[3])); - if (unlikely(!info->base)) { - ret = -ENOMEM; - goto failed; - } - - for (i = 0; i < (TX_PAGES<<8); i += 2) - __raw_writew((i>>1), info->base+offset+i); - udelay(100); - for (i = 0; i < (TX_PAGES<<8); i += 2) - if (__raw_readw(info->base+offset+i) != (i>>1)) break; - pcnet_reset_8390(dev); - if (i != (TX_PAGES<<8)) { - iounmap(info->base); - pcmcia_release_window(link, link->resource[3]); - info->base = NULL; - goto failed; - } - - ei_status.mem = info->base + offset; - ei_status.priv = resource_size(link->resource[3]); - dev->mem_start = (u_long)ei_status.mem; - dev->mem_end = dev->mem_start + resource_size(link->resource[3]); - - ei_status.tx_start_page = start_pg; - ei_status.rx_start_page = start_pg + TX_PAGES; - ei_status.stop_page = start_pg + ( - (resource_size(link->resource[3]) - offset) >> 8); - - /* set up block i/o functions */ - ei_status.get_8390_hdr = shmem_get_8390_hdr; - ei_status.block_input = shmem_block_input; - ei_status.block_output = shmem_block_output; - - info->flags |= USE_SHMEM; - return 0; - -failed: - return 1; -} - -/*====================================================================*/ - -static const struct pcmcia_device_id pcnet_ids[] = { - PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0057, 0x0021), - PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0104, 0x000a), - PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0xea15), - PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0143, 0x3341), - PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0143, 0xc0ab), - PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101), - PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), - PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "Home and Away 28.8 PC Card ", 0xb569a6e5, 0x5bd4ff2c), - PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3), - PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15), - PCMCIA_MFC_DEVICE_PROD_ID123(0, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f), - PCMCIA_MFC_DEVICE_PROD_ID2(0, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302), - PCMCIA_DEVICE_MANF_CARD(0x0057, 0x1004), - PCMCIA_DEVICE_MANF_CARD(0x0104, 0x000d), - PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0075), - PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0145), - PCMCIA_DEVICE_MANF_CARD(0x0149, 0x0230), - PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530), - PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), - PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110), - PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041), - PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452), - PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300), - PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0307), - PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030a), - PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1103), - PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1121), - PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0009), - PCMCIA_DEVICE_PROD_ID12("2408LAN", "Ethernet", 0x352fff7f, 0x00b2e941), - PCMCIA_DEVICE_PROD_ID1234("Socket", "CF 10/100 Ethernet Card", "Revision B", "05/11/06", 0xb38bcc2e, 0x4de88352, 0xeaca6c8d, 0x7e57c22e), - PCMCIA_DEVICE_PROD_ID123("Cardwell", "PCMCIA", "ETHERNET", 0x9533672e, 0x281f1c5d, 0x3ff7175b), - PCMCIA_DEVICE_PROD_ID123("CNet ", "CN30BC", "ETHERNET", 0x9fe55d3d, 0x85601198, 0x3ff7175b), - PCMCIA_DEVICE_PROD_ID123("Digital", "Ethernet", "Adapter", 0x9999ab35, 0x00b2e941, 0x4b0d829e), - PCMCIA_DEVICE_PROD_ID123("Edimax Technology Inc.", "PCMCIA", "Ethernet Card", 0x738a0019, 0x281f1c5d, 0x5e9d92c0), - PCMCIA_DEVICE_PROD_ID123("EFA ", "EFA207", "ETHERNET", 0x3d294be4, 0xeb9aab6c, 0x3ff7175b), - PCMCIA_DEVICE_PROD_ID123("I-O DATA", "PCLA", "ETHERNET", 0x1d55d7ec, 0xe4c64d34, 0x3ff7175b), - PCMCIA_DEVICE_PROD_ID123("IO DATA", "PCLATE", "ETHERNET", 0x547e66dc, 0x6b260753, 0x3ff7175b), - PCMCIA_DEVICE_PROD_ID123("KingMax Technology Inc.", "EN10-T2", "PCMCIA Ethernet Card", 0x932b7189, 0x699e4436, 0x6f6652e0), - PCMCIA_DEVICE_PROD_ID123("PCMCIA", "PCMCIA-ETHERNET-CARD", "UE2216", 0x281f1c5d, 0xd4cd2f20, 0xb87add82), - PCMCIA_DEVICE_PROD_ID123("PCMCIA", "PCMCIA-ETHERNET-CARD", "UE2620", 0x281f1c5d, 0xd4cd2f20, 0x7d3d83a8), - PCMCIA_DEVICE_PROD_ID1("2412LAN", 0x67f236ab), - PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2212", 0xdfc6b5b2, 0xcb112a11), - PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2216-PCMCIA-ETHERNET", 0xdfc6b5b2, 0x5542bfff), - PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA100-PCM-T V2 100/10M LAN PC Card", 0xbb7fbdd7, 0xcd91cc68), - PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA100-PCM V2", 0x36634a66, 0xc6d05997), - PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA-PCM_V2", 0xbb7fBdd7, 0x28e299f8), - PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA-PCM V3", 0x36634a66, 0x62241d96), - PCMCIA_DEVICE_PROD_ID12("AmbiCom", "AMB8010", 0x5070a7f9, 0x82f96e96), - PCMCIA_DEVICE_PROD_ID12("AmbiCom", "AMB8610", 0x5070a7f9, 0x86741224), - PCMCIA_DEVICE_PROD_ID12("AmbiCom Inc", "AMB8002", 0x93b15570, 0x75ec3efb), - PCMCIA_DEVICE_PROD_ID12("AmbiCom Inc", "AMB8002T", 0x93b15570, 0x461c5247), - PCMCIA_DEVICE_PROD_ID12("AmbiCom Inc", "AMB8010", 0x93b15570, 0x82f96e96), - PCMCIA_DEVICE_PROD_ID12("AnyCom", "ECO Ethernet", 0x578ba6e7, 0x0a9888c1), - PCMCIA_DEVICE_PROD_ID12("AnyCom", "ECO Ethernet 10/100", 0x578ba6e7, 0x939fedbd), - PCMCIA_DEVICE_PROD_ID12("AROWANA", "PCMCIA Ethernet LAN Card", 0x313adbc8, 0x08d9f190), - PCMCIA_DEVICE_PROD_ID12("ASANTE", "FriendlyNet PC Card", 0x3a7ade0f, 0x41c64504), - PCMCIA_DEVICE_PROD_ID12("Billionton", "LNT-10TB", 0x552ab682, 0xeeb1ba6a), - PCMCIA_DEVICE_PROD_ID12("CF", "10Base-Ethernet", 0x44ebf863, 0x93ae4d79), - PCMCIA_DEVICE_PROD_ID12("CNet", "CN40BC Ethernet", 0xbc477dde, 0xfba775a7), - PCMCIA_DEVICE_PROD_ID12("COMPU-SHACK", "BASEline PCMCIA 10 MBit Ethernetadapter", 0xfa2e424d, 0xe9190d8a), - PCMCIA_DEVICE_PROD_ID12("COMPU-SHACK", "FASTline PCMCIA 10/100 Fast-Ethernet", 0xfa2e424d, 0x3953d9b9), - PCMCIA_DEVICE_PROD_ID12("CONTEC", "C-NET(PC)C-10L", 0x21cab552, 0xf6f90722), - PCMCIA_DEVICE_PROD_ID12("corega", "FEther PCC-TXF", 0x0a21501a, 0xa51564a2), - PCMCIA_DEVICE_PROD_ID12("corega", "Ether CF-TD", 0x0a21501a, 0x6589340a), - PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether CF-TD LAN Card", 0x5261440f, 0x8797663b), - PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-T", 0x5261440f, 0xfa9d85bd), - PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-TD", 0x5261440f, 0xc49bd73d), - PCMCIA_DEVICE_PROD_ID12("Corega K.K.", "corega EtherII PCC-TD", 0xd4fdcbd8, 0xc49bd73d), - PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether PCC-T", 0x5261440f, 0x6705fcaa), - PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether PCC-TD", 0x5261440f, 0x47d5ca83), - PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FastEther PCC-TX", 0x5261440f, 0x485e85d9), - PCMCIA_DEVICE_PROD_ID12("Corega,K.K.", "Ethernet LAN Card", 0x110d26d9, 0x9fd2f0a2), - PCMCIA_DEVICE_PROD_ID12("corega,K.K.", "Ethernet LAN Card", 0x9791a90e, 0x9fd2f0a2), - PCMCIA_DEVICE_PROD_ID12("corega K.K.", "(CG-LAPCCTXD)", 0x5261440f, 0x73ec0d88), - PCMCIA_DEVICE_PROD_ID12("CouplerlessPCMCIA", "100BASE", 0xee5af0ad, 0x7c2add04), - PCMCIA_DEVICE_PROD_ID12("CyQ've", "ELA-010", 0x77008979, 0x9d8d445d), - PCMCIA_DEVICE_PROD_ID12("CyQ've", "ELA-110E 10/100M LAN Card", 0x77008979, 0xfd184814), - PCMCIA_DEVICE_PROD_ID12("DataTrek.", "NetCard ", 0x5cd66d9d, 0x84697ce0), - PCMCIA_DEVICE_PROD_ID12("Dayna Communications, Inc.", "CommuniCard E", 0x0c629325, 0xb4e7dbaf), - PCMCIA_DEVICE_PROD_ID12("Digicom", "Palladio LAN 10/100", 0x697403d8, 0xe160b995), - PCMCIA_DEVICE_PROD_ID12("Digicom", "Palladio LAN 10/100 Dongless", 0x697403d8, 0xa6d3b233), - PCMCIA_DEVICE_PROD_ID12("DIGITAL", "DEPCM-XX", 0x69616cb3, 0xe600e76e), - PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-650", 0x1a424a1c, 0xf28c8398), - PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660", 0x1a424a1c, 0xd9a1d05b), - PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660+", 0x1a424a1c, 0x50dcd0ec), - PCMCIA_DEVICE_PROD_ID12("D-Link", "DFE-650", 0x1a424a1c, 0x0f0073f9), - PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 PC Card", 0x725b842d, 0xf1efee84), - PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 Port Attached PC Card", 0x725b842d, 0x2db1f8e9), - PCMCIA_DEVICE_PROD_ID12("Dynalink", "L10BC", 0x55632fd5, 0xdc65f2b1), - PCMCIA_DEVICE_PROD_ID12("DYNALINK", "L10BC", 0x6a26d1cf, 0xdc65f2b1), - PCMCIA_DEVICE_PROD_ID12("DYNALINK", "L10C", 0x6a26d1cf, 0xc4f84efb), - PCMCIA_DEVICE_PROD_ID12("E-CARD", "E-CARD", 0x6701da11, 0x6701da11), - PCMCIA_DEVICE_PROD_ID12("EIGER Labs Inc.", "Ethernet 10BaseT card", 0x53c864c6, 0xedd059f6), - PCMCIA_DEVICE_PROD_ID12("EIGER Labs Inc.", "Ethernet Combo card", 0x53c864c6, 0x929c486c), - PCMCIA_DEVICE_PROD_ID12("Ethernet", "Adapter", 0x00b2e941, 0x4b0d829e), - PCMCIA_DEVICE_PROD_ID12("Ethernet Adapter", "E2000 PCMCIA Ethernet", 0x96767301, 0x71fbbc61), - PCMCIA_DEVICE_PROD_ID12("Ethernet PCMCIA adapter", "EP-210", 0x8dd86181, 0xf2b52517), - PCMCIA_DEVICE_PROD_ID12("Fast Ethernet", "Adapter", 0xb4be14e3, 0x4b0d829e), - PCMCIA_DEVICE_PROD_ID12("Grey Cell", "GCS2000", 0x2a151fac, 0xf00555cb), - PCMCIA_DEVICE_PROD_ID12("Grey Cell", "GCS2220", 0x2a151fac, 0xc1b7e327), - PCMCIA_DEVICE_PROD_ID12("GVC", "NIC-2000p", 0x76e171bd, 0x6eb1c947), - PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "Ethernet", 0xe3736c88, 0x00b2e941), - PCMCIA_DEVICE_PROD_ID12("IC-CARD", "IC-CARD", 0x60cb09a6, 0x60cb09a6), - PCMCIA_DEVICE_PROD_ID12("IC-CARD+", "IC-CARD+", 0x93693494, 0x93693494), - PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b), - PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0), - PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956), - PCMCIA_DEVICE_PROD_ID12("KENTRONICS", "KEP-230", 0xaf8144c9, 0x868f6616), - PCMCIA_DEVICE_PROD_ID12("KCI", "PE520 PCMCIA Ethernet Adapter", 0xa89b87d3, 0x1eb88e64), - PCMCIA_DEVICE_PROD_ID12("KINGMAX", "EN10T2T", 0x7bcb459a, 0xa5c81fa5), - PCMCIA_DEVICE_PROD_ID12("Kingston", "KNE-PC2", 0x1128e633, 0xce2a89b3), - PCMCIA_DEVICE_PROD_ID12("Kingston Technology Corp.", "EtheRx PC Card Ethernet Adapter", 0x313c7be3, 0x0afb54a2), - PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-10/100CD", 0x1b7827b2, 0xcda71d1c), - PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDF", 0x1b7827b2, 0xfec71e40), - PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDL/T", 0x1b7827b2, 0x79fba4f7), - PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDS", 0x1b7827b2, 0x931afaab), - PCMCIA_DEVICE_PROD_ID12("LEMEL", "LM-N89TX PRO", 0xbbefb52f, 0xd2897a97), - PCMCIA_DEVICE_PROD_ID12("Linksys", "Combo PCMCIA EthernetCard (EC2T)", 0x0733cc81, 0x32ee8c78), - PCMCIA_DEVICE_PROD_ID12("LINKSYS", "E-CARD", 0xf7cb0b07, 0x6701da11), - PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 Integrated PC Card (PCM100)", 0x0733cc81, 0x453c3f9d), - PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100)", 0x0733cc81, 0x66c5a389), - PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V2)", 0x0733cc81, 0x3a3b28e9), - PCMCIA_DEVICE_PROD_ID12("Linksys", "HomeLink Phoneline + 10/100 Network PC Card (PCM100H1)", 0x733cc81, 0x7a3e5c3a), - PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN100TX", 0x88fcdeda, 0x6d772737), - PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN100TE", 0x88fcdeda, 0x0e714bee), - PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN20T", 0x88fcdeda, 0x81090922), - PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN10TE", 0x88fcdeda, 0xc1e2521c), - PCMCIA_DEVICE_PROD_ID12("LONGSHINE", "PCMCIA Ethernet Card", 0xf866b0b0, 0x6f6652e0), - PCMCIA_DEVICE_PROD_ID12("MACNICA", "ME1-JEIDA", 0x20841b68, 0xaf8a3578), - PCMCIA_DEVICE_PROD_ID12("Macsense", "MPC-10", 0xd830297f, 0xd265c307), - PCMCIA_DEVICE_PROD_ID12("Matsushita Electric Industrial Co.,LTD.", "CF-VEL211", 0x44445376, 0x8ded41d4), - PCMCIA_DEVICE_PROD_ID12("MAXTECH", "PCN2000", 0x78d64bc0, 0xca0ca4b8), - PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC2-T", 0x481e0094, 0xa2eb0cf3), - PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC2-TX", 0x481e0094, 0x41a6916c), - PCMCIA_DEVICE_PROD_ID12("Microcom C.E.", "Travel Card LAN 10/100", 0x4b91cec7, 0xe70220d6), - PCMCIA_DEVICE_PROD_ID12("Microdyne", "NE4200", 0x2e6da59b, 0x0478e472), - PCMCIA_DEVICE_PROD_ID12("MIDORI ELEC.", "LT-PCMT", 0x648d55c1, 0xbde526c7), - PCMCIA_DEVICE_PROD_ID12("National Semiconductor", "InfoMover 4100", 0x36e1191f, 0x60c229b9), - PCMCIA_DEVICE_PROD_ID12("National Semiconductor", "InfoMover NE4100", 0x36e1191f, 0xa6617ec8), - PCMCIA_DEVICE_PROD_ID12("NEC", "PC-9801N-J12", 0x18df0ba0, 0xbc912d76), - PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA410TX", 0x9aa79dc3, 0x60e5bc0e), - PCMCIA_DEVICE_PROD_ID12("Network Everywhere", "Fast Ethernet 10/100 PC Card", 0x820a67b6, 0x31ed1a5f), - PCMCIA_DEVICE_PROD_ID12("NextCom K.K.", "Next Hawk", 0xaedaec74, 0xad050ef1), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100Mbps Ethernet Card", 0x281f1c5d, 0x6e41773b), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet", 0x281f1c5d, 0x00b2e941), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "ETHERNET", 0x281f1c5d, 0x3ff7175b), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet 10BaseT Card", 0x281f1c5d, 0x4de2f6c8), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet Card", 0x281f1c5d, 0x5e9d92c0), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet Combo card", 0x281f1c5d, 0x929c486c), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "ETHERNET V1.0", 0x281f1c5d, 0x4d8817c8), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FastEthernet", 0x281f1c5d, 0xfe871eeb), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Fast-Ethernet", 0x281f1c5d, 0x45f1f3b4), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FAST ETHERNET CARD", 0x281f1c5d, 0xec5dbca7), - PCMCIA_DEVICE_PROD_ID12("PCMCIA LAN", "Ethernet", 0x7500e246, 0x00b2e941), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "LNT-10TN", 0x281f1c5d, 0xe707f641), - PCMCIA_DEVICE_PROD_ID12("PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", "UE2212", 0x281f1c5d, 0xbf17199b), - PCMCIA_DEVICE_PROD_ID12("PCMCIA", " Ethernet NE2000 Compatible", 0x281f1c5d, 0x42d5d7e1), - PCMCIA_DEVICE_PROD_ID12("PRETEC", "Ethernet CompactLAN 10baseT 3.3V", 0xebf91155, 0x30074c80), - PCMCIA_DEVICE_PROD_ID12("PRETEC", "Ethernet CompactLAN 10BaseT 3.3V", 0xebf91155, 0x7f5a4f50), - PCMCIA_DEVICE_PROD_ID12("Psion Dacom", "Gold Card Ethernet", 0xf5f025c2, 0x3a30e110), - PCMCIA_DEVICE_PROD_ID12("=RELIA==", "Ethernet", 0xcdd0644a, 0x00b2e941), - PCMCIA_DEVICE_PROD_ID12("RIOS Systems Co.", "PC CARD3 ETHERNET", 0x7dd33481, 0x10b41826), - PCMCIA_DEVICE_PROD_ID12("RP", "1625B Ethernet NE2000 Compatible", 0xe3e66e22, 0xb96150df), - PCMCIA_DEVICE_PROD_ID12("RPTI", "EP400 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4a7e2ae0), - PCMCIA_DEVICE_PROD_ID12("RPTI", "EP401 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4bcbd7fd), - PCMCIA_DEVICE_PROD_ID12("RPTI LTD.", "EP400", 0xc53ac515, 0x81e39388), - PCMCIA_DEVICE_PROD_ID12("SCM", "Ethernet Combo card", 0xbdc3b102, 0x929c486c), - PCMCIA_DEVICE_PROD_ID12("Seiko Epson Corp.", "Ethernet", 0x09928730, 0x00b2e941), - PCMCIA_DEVICE_PROD_ID12("SMC", "EZCard-10-PCMCIA", 0xc4f8b18b, 0xfb21d265), - PCMCIA_DEVICE_PROD_ID12("Socket Communications Inc", "Socket EA PCMCIA LAN Adapter Revision D", 0xc70a4760, 0x2ade483e), - PCMCIA_DEVICE_PROD_ID12("Socket Communications Inc", "Socket EA PCMCIA LAN Adapter Revision E", 0xc70a4760, 0x5dd978a8), - PCMCIA_DEVICE_PROD_ID12("TDK", "LAK-CD031 for PCMCIA", 0x1eae9475, 0x0ed386fa), - PCMCIA_DEVICE_PROD_ID12("Telecom Device K.K.", "SuperSocket RE450T", 0x466b05f0, 0x8b74bc4f), - PCMCIA_DEVICE_PROD_ID12("Telecom Device K.K.", "SuperSocket RE550T", 0x466b05f0, 0x33c8db2a), - PCMCIA_DEVICE_PROD_ID13("Hypertec", "EP401", 0x8787bec7, 0xf6e4a31e), - PCMCIA_DEVICE_PROD_ID13("KingMax Technology Inc.", "Ethernet Card", 0x932b7189, 0x5e9d92c0), - PCMCIA_DEVICE_PROD_ID13("LONGSHINE", "EP401", 0xf866b0b0, 0xf6e4a31e), - PCMCIA_DEVICE_PROD_ID13("Xircom", "CFE-10", 0x2e3ee845, 0x22a49f89), - PCMCIA_DEVICE_PROD_ID1("CyQ've 10 Base-T LAN CARD", 0x94faf360), - PCMCIA_DEVICE_PROD_ID1("EP-210 PCMCIA LAN CARD.", 0x8850b4de), - PCMCIA_DEVICE_PROD_ID1("ETHER-C16", 0x06a8514f), - PCMCIA_DEVICE_PROD_ID1("NE2000 Compatible", 0x75b8ad5a), - PCMCIA_DEVICE_PROD_ID2("EN-6200P2", 0xa996d078), - /* too generic! */ - /* PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100 Ethernet Card", 0x281f1c5d, 0x11b0ffc0), */ - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"), - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"), - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"), - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"), - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"), - PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "TOSHIBA", "Modem/LAN Card", 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis"), - PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"), - PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"), - PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"), - PCMCIA_DEVICE_CIS_PROD_ID12("Allied Telesis,K.K", "Ethernet LAN Card", 0x2ad62f3c, 0x9fd2f0a2, "cis/LA-PCM.cis"), - PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "cis/PE520.cis"), - PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"), - PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"), - PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"), - PCMCIA_DEVICE_PROD_ID12("Ethernet", "CF Size PC Card", 0x00b2e941, 0x43ac239b), - PCMCIA_DEVICE_PROD_ID123("Fast Ethernet", "CF Size PC Card", "1.0", - 0xb4be14e3, 0x43ac239b, 0x0877b627), - PCMCIA_DEVICE_NULL -}; -MODULE_DEVICE_TABLE(pcmcia, pcnet_ids); -MODULE_FIRMWARE("cis/PCMLM28.cis"); -MODULE_FIRMWARE("cis/DP83903.cis"); -MODULE_FIRMWARE("cis/LA-PCM.cis"); -MODULE_FIRMWARE("cis/PE520.cis"); -MODULE_FIRMWARE("cis/NE2K.cis"); -MODULE_FIRMWARE("cis/PE-200.cis"); -MODULE_FIRMWARE("cis/tamarack.cis"); - -static struct pcmcia_driver pcnet_driver = { - .name = "pcnet_cs", - .probe = pcnet_probe, - .remove = pcnet_detach, - .owner = THIS_MODULE, - .id_table = pcnet_ids, - .suspend = pcnet_suspend, - .resume = pcnet_resume, -}; -module_pcmcia_driver(pcnet_driver); diff --git a/drivers/net/ethernet/8390/smc-ultra.c b/drivers/net/ethernet/8390/smc-ultra.c deleted file mode 100644 index 0890fa493f70..000000000000 --- a/drivers/net/ethernet/8390/smc-ultra.c +++ /dev/null @@ -1,629 +0,0 @@ -/* smc-ultra.c: A SMC Ultra ethernet driver for linux. */ -/* - This is a driver for the SMC Ultra and SMC EtherEZ ISA ethercards. - - Written 1993-1998 by Donald Becker. - - Copyright 1993 United States Government as represented by the - Director, National Security Agency. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - The author may be reached as becker@scyld.com, or C/O - Scyld Computing Corporation - 410 Severn Ave., Suite 210 - Annapolis MD 21403 - - This driver uses the cards in the 8390-compatible mode. - Most of the run-time complexity is handled by the generic code in - 8390.c. The code in this file is responsible for - - ultra_probe() Detecting and initializing the card. - ultra_probe1() - ultra_probe_isapnp() - - ultra_open() The card-specific details of starting, stopping - ultra_reset_8390() and resetting the 8390 NIC core. - ultra_close() - - ultra_block_input() Routines for reading and writing blocks of - ultra_block_output() packet buffer memory. - ultra_pio_input() - ultra_pio_output() - - This driver enables the shared memory only when doing the actual data - transfers to avoid a bug in early version of the card that corrupted - data transferred by a AHA1542. - - This driver now supports the programmed-I/O (PIO) data transfer mode of - the EtherEZ. It does not use the non-8390-compatible "Altego" mode. - That support (if available) is in smc-ez.c. - - Changelog: - - Paul Gortmaker : multiple card support for module users. - Donald Becker : 4/17/96 PIO support, minor potential problems avoided. - Donald Becker : 6/6/96 correctly set auto-wrap bit. - Alexander Sotirov : 1/20/01 Added support for ISAPnP cards - - Note about the ISA PnP support: - - This driver can not autoprobe for more than one SMC EtherEZ PnP card. - You have to configure the second card manually through the /proc/isapnp - interface and then load the module with an explicit io=0x___ option. -*/ - -static const char version[] = - "smc-ultra.c:v2.02 2/3/98 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "8390.h" - -#define DRV_NAME "smc-ultra" - -/* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int ultra_portlist[] __initdata = -{0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0}; - -static int ultra_probe1(struct net_device *dev, int ioaddr); - -#ifdef __ISAPNP__ -static int ultra_probe_isapnp(struct net_device *dev); -#endif - -static int ultra_open(struct net_device *dev); -static void ultra_reset_8390(struct net_device *dev); -static void ultra_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, - int ring_page); -static void ultra_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void ultra_block_output(struct net_device *dev, int count, - const unsigned char *buf, const int start_page); -static void ultra_pio_get_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, - int ring_page); -static void ultra_pio_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void ultra_pio_output(struct net_device *dev, int count, - const unsigned char *buf, const int start_page); -static int ultra_close_card(struct net_device *dev); - -#ifdef __ISAPNP__ -static struct isapnp_device_id ultra_device_ids[] __initdata = { - { ISAPNP_VENDOR('S','M','C'), ISAPNP_FUNCTION(0x8416), - ISAPNP_VENDOR('S','M','C'), ISAPNP_FUNCTION(0x8416), - (long) "SMC EtherEZ (8416)" }, - { } /* terminate list */ -}; - -MODULE_DEVICE_TABLE(isapnp, ultra_device_ids); -#endif - -static u32 ultra_msg_enable; - -#define START_PG 0x00 /* First page of TX buffer */ - -#define ULTRA_CMDREG 0 /* Offset to ASIC command register. */ -#define ULTRA_RESET 0x80 /* Board reset, in ULTRA_CMDREG. */ -#define ULTRA_MEMENB 0x40 /* Enable the shared memory. */ -#define IOPD 0x02 /* I/O Pipe Data (16 bits), PIO operation. */ -#define IOPA 0x07 /* I/O Pipe Address for PIO operation. */ -#define ULTRA_NIC_OFFSET 16 /* NIC register offset from the base_addr. */ -#define ULTRA_IO_EXTENT 32 -#define EN0_ERWCNT 0x08 /* Early receive warning count. */ - -#ifdef CONFIG_NET_POLL_CONTROLLER -static void ultra_poll(struct net_device *dev) -{ - disable_irq(dev->irq); - ei_interrupt(dev->irq, dev); - enable_irq(dev->irq); -} -#endif -/* Probe for the Ultra. This looks like a 8013 with the station - address PROM at I/O ports +8 to +13, with a checksum - following. -*/ - -static int __init do_ultra_probe(struct net_device *dev) -{ - int i; - int base_addr = dev->base_addr; - int irq = dev->irq; - - if (base_addr > 0x1ff) /* Check a single specified location. */ - return ultra_probe1(dev, base_addr); - else if (base_addr != 0) /* Don't probe at all. */ - return -ENXIO; - -#ifdef __ISAPNP__ - /* Look for any installed ISAPnP cards */ - if (isapnp_present() && (ultra_probe_isapnp(dev) == 0)) - return 0; -#endif - - for (i = 0; ultra_portlist[i]; i++) { - dev->irq = irq; - if (ultra_probe1(dev, ultra_portlist[i]) == 0) - return 0; - } - - return -ENODEV; -} - -#ifndef MODULE -struct net_device * __init ultra_probe(int unit) -{ - struct net_device *dev = alloc_ei_netdev(); - int err; - - if (!dev) - return ERR_PTR(-ENOMEM); - - sprintf(dev->name, "eth%d", unit); - netdev_boot_setup_check(dev); - - err = do_ultra_probe(dev); - if (err) - goto out; - return dev; -out: - free_netdev(dev); - return ERR_PTR(err); -} -#endif - -static const struct net_device_ops ultra_netdev_ops = { - .ndo_open = ultra_open, - .ndo_stop = ultra_close_card, - - .ndo_start_xmit = ei_start_xmit, - .ndo_tx_timeout = ei_tx_timeout, - .ndo_get_stats = ei_get_stats, - .ndo_set_rx_mode = ei_set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = ultra_poll, -#endif -}; - -static int __init ultra_probe1(struct net_device *dev, int ioaddr) -{ - int i, retval; - int checksum = 0; - const char *model_name; - unsigned char eeprom_irq = 0; - static unsigned version_printed; - /* Values from various config regs. */ - unsigned char num_pages, irqreg, addr, piomode; - unsigned char idreg = inb(ioaddr + 7); - unsigned char reg4 = inb(ioaddr + 4) & 0x7f; - struct ei_device *ei_local = netdev_priv(dev); - - if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME)) - return -EBUSY; - - /* Check the ID nibble. */ - if ((idreg & 0xF0) != 0x20 /* SMC Ultra */ - && (idreg & 0xF0) != 0x40) { /* SMC EtherEZ */ - retval = -ENODEV; - goto out; - } - - /* Select the station address register set. */ - outb(reg4, ioaddr + 4); - - for (i = 0; i < 8; i++) - checksum += inb(ioaddr + 8 + i); - if ((checksum & 0xff) != 0xFF) { - retval = -ENODEV; - goto out; - } - - if ((ultra_msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0)) - netdev_info(dev, version); - - model_name = (idreg & 0xF0) == 0x20 ? "SMC Ultra" : "SMC EtherEZ"; - - for (i = 0; i < 6; i++) - dev->dev_addr[i] = inb(ioaddr + 8 + i); - - netdev_info(dev, "%s at %#3x, %pM", model_name, - ioaddr, dev->dev_addr); - - /* Switch from the station address to the alternate register set and - read the useful registers there. */ - outb(0x80 | reg4, ioaddr + 4); - - /* Enabled FINE16 mode to avoid BIOS ROM width mismatches @ reboot. */ - outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c); - piomode = inb(ioaddr + 0x8); - addr = inb(ioaddr + 0xb); - irqreg = inb(ioaddr + 0xd); - - /* Switch back to the station address register set so that the MS-DOS driver - can find the card after a warm boot. */ - outb(reg4, ioaddr + 4); - - if (dev->irq < 2) { - unsigned char irqmap[] = {0, 9, 3, 5, 7, 10, 11, 15}; - int irq; - - /* The IRQ bits are split. */ - irq = irqmap[((irqreg & 0x40) >> 4) + ((irqreg & 0x0c) >> 2)]; - - if (irq == 0) { - pr_cont(", failed to detect IRQ line.\n"); - retval = -EAGAIN; - goto out; - } - dev->irq = irq; - eeprom_irq = 1; - } - - /* The 8390 isn't at the base address, so fake the offset */ - dev->base_addr = ioaddr+ULTRA_NIC_OFFSET; - - { - static const int addr_tbl[4] = { - 0x0C0000, 0x0E0000, 0xFC0000, 0xFE0000 - }; - static const short num_pages_tbl[4] = { - 0x20, 0x40, 0x80, 0xff - }; - - dev->mem_start = ((addr & 0x0f) << 13) + addr_tbl[(addr >> 6) & 3] ; - num_pages = num_pages_tbl[(addr >> 4) & 3]; - } - - ei_status.name = model_name; - ei_status.word16 = 1; - ei_status.tx_start_page = START_PG; - ei_status.rx_start_page = START_PG + TX_PAGES; - ei_status.stop_page = num_pages; - - ei_status.mem = ioremap(dev->mem_start, (ei_status.stop_page - START_PG)*256); - if (!ei_status.mem) { - pr_cont(", failed to ioremap.\n"); - retval = -ENOMEM; - goto out; - } - - dev->mem_end = dev->mem_start + (ei_status.stop_page - START_PG)*256; - - if (piomode) { - pr_cont(", %s IRQ %d programmed-I/O mode.\n", - eeprom_irq ? "EEPROM" : "assigned ", dev->irq); - ei_status.block_input = &ultra_pio_input; - ei_status.block_output = &ultra_pio_output; - ei_status.get_8390_hdr = &ultra_pio_get_hdr; - } else { - pr_cont(", %s IRQ %d memory %#lx-%#lx.\n", - eeprom_irq ? "" : "assigned ", dev->irq, dev->mem_start, - dev->mem_end-1); - ei_status.block_input = &ultra_block_input; - ei_status.block_output = &ultra_block_output; - ei_status.get_8390_hdr = &ultra_get_8390_hdr; - } - ei_status.reset_8390 = &ultra_reset_8390; - - dev->netdev_ops = &ultra_netdev_ops; - NS8390_init(dev, 0); - ei_local->msg_enable = ultra_msg_enable; - - retval = register_netdev(dev); - if (retval) - goto out; - return 0; -out: - release_region(ioaddr, ULTRA_IO_EXTENT); - return retval; -} - -#ifdef __ISAPNP__ -static int __init ultra_probe_isapnp(struct net_device *dev) -{ - int i; - - for (i = 0; ultra_device_ids[i].vendor != 0; i++) { - struct pnp_dev *idev = NULL; - - while ((idev = pnp_find_dev(NULL, - ultra_device_ids[i].vendor, - ultra_device_ids[i].function, - idev))) { - /* Avoid already found cards from previous calls */ - if (pnp_device_attach(idev) < 0) - continue; - if (pnp_activate_dev(idev) < 0) { - __again: - pnp_device_detach(idev); - continue; - } - /* if no io and irq, search for next */ - if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0)) - goto __again; - /* found it */ - dev->base_addr = pnp_port_start(idev, 0); - dev->irq = pnp_irq(idev, 0); - netdev_info(dev, - "smc-ultra.c: ISAPnP reports %s at i/o %#lx, irq %d.\n", - (char *) ultra_device_ids[i].driver_data, - dev->base_addr, dev->irq); - if (ultra_probe1(dev, dev->base_addr) != 0) { /* Shouldn't happen. */ - netdev_err(dev, - "smc-ultra.c: Probe of ISAPnP card at %#lx failed.\n", - dev->base_addr); - pnp_device_detach(idev); - return -ENXIO; - } - ei_status.priv = (unsigned long)idev; - break; - } - if (!idev) - continue; - return 0; - } - - return -ENODEV; -} -#endif - -static int -ultra_open(struct net_device *dev) -{ - int retval; - int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ - unsigned char irq2reg[] = {0, 0, 0x04, 0x08, 0, 0x0C, 0, 0x40, - 0, 0x04, 0x44, 0x48, 0, 0, 0, 0x4C, }; - - retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev); - if (retval) - return retval; - - outb(0x00, ioaddr); /* Disable shared memory for safety. */ - outb(0x80, ioaddr + 5); - /* Set the IRQ line. */ - outb(inb(ioaddr + 4) | 0x80, ioaddr + 4); - outb((inb(ioaddr + 13) & ~0x4C) | irq2reg[dev->irq], ioaddr + 13); - outb(inb(ioaddr + 4) & 0x7f, ioaddr + 4); - - if (ei_status.block_input == &ultra_pio_input) { - outb(0x11, ioaddr + 6); /* Enable interrupts and PIO. */ - outb(0x01, ioaddr + 0x19); /* Enable ring read auto-wrap. */ - } else - outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */ - /* Set the early receive warning level in window 0 high enough not - to receive ERW interrupts. */ - outb_p(E8390_NODMA+E8390_PAGE0, dev->base_addr); - outb(0xff, dev->base_addr + EN0_ERWCNT); - ei_open(dev); - return 0; -} - -static void -ultra_reset_8390(struct net_device *dev) -{ - int cmd_port = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC base addr */ - struct ei_device *ei_local = netdev_priv(dev); - - outb(ULTRA_RESET, cmd_port); - netif_dbg(ei_local, hw, dev, "resetting Ultra, t=%ld...\n", jiffies); - ei_status.txing = 0; - - outb(0x00, cmd_port); /* Disable shared memory for safety. */ - outb(0x80, cmd_port + 5); - if (ei_status.block_input == &ultra_pio_input) - outb(0x11, cmd_port + 6); /* Enable interrupts and PIO. */ - else - outb(0x01, cmd_port + 6); /* Enable interrupts and memory. */ - - netif_dbg(ei_local, hw, dev, "reset done\n"); -} - -/* Grab the 8390 specific header. Similar to the block_input routine, but - we don't need to be concerned with ring wrap as the header will be at - the start of a page, so we optimize accordingly. */ - -static void -ultra_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) -{ - void __iomem *hdr_start = ei_status.mem + ((ring_page - START_PG)<<8); - - outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem on */ -#ifdef __BIG_ENDIAN - /* Officially this is what we are doing, but the readl() is faster */ - /* unfortunately it isn't endian aware of the struct */ - memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); - hdr->count = le16_to_cpu(hdr->count); -#else - ((unsigned int*)hdr)[0] = readl(hdr_start); -#endif - outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem off */ -} - -/* Block input and output are easy on shared memory ethercards, the only - complication is when the ring buffer wraps. */ - -static void -ultra_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) -{ - void __iomem *xfer_start = ei_status.mem + ring_offset - (START_PG<<8); - - /* Enable shared memory. */ - outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); - - if (ring_offset + count > ei_status.stop_page*256) { - /* We must wrap the input move. */ - int semi_count = ei_status.stop_page*256 - ring_offset; - memcpy_fromio(skb->data, xfer_start, semi_count); - count -= semi_count; - memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); - } else { - memcpy_fromio(skb->data, xfer_start, count); - } - - outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */ -} - -static void -ultra_block_output(struct net_device *dev, int count, const unsigned char *buf, - int start_page) -{ - void __iomem *shmem = ei_status.mem + ((start_page - START_PG)<<8); - - /* Enable shared memory. */ - outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); - - memcpy_toio(shmem, buf, count); - - outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */ -} - -/* The identical operations for programmed I/O cards. - The PIO model is trivial to use: the 16 bit start address is written - byte-sequentially to IOPA, with no intervening I/O operations, and the - data is read or written to the IOPD data port. - The only potential complication is that the address register is shared - and must be always be rewritten between each read/write direction change. - This is no problem for us, as the 8390 code ensures that we are single - threaded. */ -static void ultra_pio_get_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, - int ring_page) -{ - int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ - outb(0x00, ioaddr + IOPA); /* Set the address, LSB first. */ - outb(ring_page, ioaddr + IOPA); - insw(ioaddr + IOPD, hdr, sizeof(struct e8390_pkt_hdr)>>1); -} - -static void ultra_pio_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) -{ - int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ - char *buf = skb->data; - - /* For now set the address again, although it should already be correct. */ - outb(ring_offset, ioaddr + IOPA); /* Set the address, LSB first. */ - outb(ring_offset >> 8, ioaddr + IOPA); - /* We know skbuffs are padded to at least word alignment. */ - insw(ioaddr + IOPD, buf, (count+1)>>1); -} -static void ultra_pio_output(struct net_device *dev, int count, - const unsigned char *buf, const int start_page) -{ - int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ - outb(0x00, ioaddr + IOPA); /* Set the address, LSB first. */ - outb(start_page, ioaddr + IOPA); - /* An extra odd byte is OK here as well. */ - outsw(ioaddr + IOPD, buf, (count+1)>>1); -} - -static int -ultra_close_card(struct net_device *dev) -{ - int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* CMDREG */ - struct ei_device *ei_local = netdev_priv(dev); - - netif_stop_queue(dev); - - netif_dbg(ei_local, ifdown, dev, "Shutting down ethercard.\n"); - - outb(0x00, ioaddr + 6); /* Disable interrupts. */ - free_irq(dev->irq, dev); - - NS8390_init(dev, 0); - - /* We should someday disable shared memory and change to 8-bit mode - "just in case"... */ - - return 0; -} - - -#ifdef MODULE -#define MAX_ULTRA_CARDS 4 /* Max number of Ultra cards per module */ -static struct net_device *dev_ultra[MAX_ULTRA_CARDS]; -static int io[MAX_ULTRA_CARDS]; -static int irq[MAX_ULTRA_CARDS]; - -module_param_hw_array(io, int, ioport, NULL, 0); -module_param_hw_array(irq, int, irq, NULL, 0); -module_param_named(msg_enable, ultra_msg_enable, uint, 0444); -MODULE_PARM_DESC(io, "I/O base address(es)"); -MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); -MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)"); -MODULE_DESCRIPTION("SMC Ultra/EtherEZ ISA/PnP Ethernet driver"); -MODULE_LICENSE("GPL"); - -/* This is set up so that only a single autoprobe takes place per call. -ISA device autoprobes on a running machine are not recommended. */ -static int __init ultra_init_module(void) -{ - struct net_device *dev; - int this_dev, found = 0; - - for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) { - if (io[this_dev] == 0) { - if (this_dev != 0) break; /* only autoprobe 1st one */ - printk(KERN_NOTICE "smc-ultra.c: Presently autoprobing (not recommended) for a single card.\n"); - } - dev = alloc_ei_netdev(); - if (!dev) - break; - dev->irq = irq[this_dev]; - dev->base_addr = io[this_dev]; - if (do_ultra_probe(dev) == 0) { - dev_ultra[found++] = dev; - continue; - } - free_netdev(dev); - printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]); - break; - } - if (found) - return 0; - return -ENXIO; -} -module_init(ultra_init_module); - -static void cleanup_card(struct net_device *dev) -{ - /* NB: ultra_close_card() does free_irq */ -#ifdef __ISAPNP__ - struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; - if (idev) - pnp_device_detach(idev); -#endif - release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT); - iounmap(ei_status.mem); -} - -static void __exit ultra_cleanup_module(void) -{ - int this_dev; - - for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) { - struct net_device *dev = dev_ultra[this_dev]; - if (dev) { - unregister_netdev(dev); - cleanup_card(dev); - free_netdev(dev); - } - } -} -module_exit(ultra_cleanup_module); -#endif /* MODULE */ diff --git a/drivers/net/ethernet/8390/stnic.c b/drivers/net/ethernet/8390/stnic.c deleted file mode 100644 index fbbd7f22c142..000000000000 --- a/drivers/net/ethernet/8390/stnic.c +++ /dev/null @@ -1,303 +0,0 @@ -/* stnic.c : A SH7750 specific part of driver for NS DP83902A ST-NIC. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999 kaz Kojima - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#ifdef CONFIG_SH_STANDARD_BIOS -#include -#endif - -#include "8390.h" - -#define DRV_NAME "stnic" - -#define byte unsigned char -#define half unsigned short -#define word unsigned int -#define vbyte volatile unsigned char -#define vhalf volatile unsigned short -#define vword volatile unsigned int - -#define STNIC_RUN 0x01 /* 1 == Run, 0 == reset. */ - -#define START_PG 0 /* First page of TX buffer */ -#define STOP_PG 128 /* Last page +1 of RX ring */ - -/* Alias */ -#define STNIC_CR E8390_CMD -#define PG0_RSAR0 EN0_RSARLO -#define PG0_RSAR1 EN0_RSARHI -#define PG0_RBCR0 EN0_RCNTLO -#define PG0_RBCR1 EN0_RCNTHI - -#define CR_RRD E8390_RREAD -#define CR_RWR E8390_RWRITE -#define CR_PG0 E8390_PAGE0 -#define CR_STA E8390_START -#define CR_RDMA E8390_NODMA - -/* FIXME! YOU MUST SET YOUR OWN ETHER ADDRESS. */ -static byte stnic_eadr[6] = -{0x00, 0xc0, 0x6e, 0x00, 0x00, 0x07}; - -static struct net_device *stnic_dev; - -static void stnic_reset (struct net_device *dev); -static void stnic_get_hdr (struct net_device *dev, struct e8390_pkt_hdr *hdr, - int ring_page); -static void stnic_block_input (struct net_device *dev, int count, - struct sk_buff *skb , int ring_offset); -static void stnic_block_output (struct net_device *dev, int count, - const unsigned char *buf, int start_page); - -static void stnic_init (struct net_device *dev); - -static u32 stnic_msg_enable; - -module_param_named(msg_enable, stnic_msg_enable, uint, 0444); -MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)"); - -/* SH7750 specific read/write io. */ -static inline void -STNIC_DELAY (void) -{ - vword trash; - trash = *(vword *) 0xa0000000; - trash = *(vword *) 0xa0000000; - trash = *(vword *) 0xa0000000; -} - -static inline byte -STNIC_READ (int reg) -{ - byte val; - - val = (*(vhalf *) (PA_83902 + ((reg) << 1)) >> 8) & 0xff; - STNIC_DELAY (); - return val; -} - -static inline void -STNIC_WRITE (int reg, byte val) -{ - *(vhalf *) (PA_83902 + ((reg) << 1)) = ((half) (val) << 8); - STNIC_DELAY (); -} - -static int __init stnic_probe(void) -{ - struct net_device *dev; - int i, err; - struct ei_device *ei_local; - - /* If we are not running on a SolutionEngine, give up now */ - if (! MACH_SE) - return -ENODEV; - - /* New style probing API */ - dev = alloc_ei_netdev(); - if (!dev) - return -ENOMEM; - -#ifdef CONFIG_SH_STANDARD_BIOS - sh_bios_get_node_addr (stnic_eadr); -#endif - for (i = 0; i < ETH_ALEN; i++) - dev->dev_addr[i] = stnic_eadr[i]; - - /* Set the base address to point to the NIC, not the "real" base! */ - dev->base_addr = 0x1000; - dev->irq = IRQ_STNIC; - dev->netdev_ops = &ei_netdev_ops; - - /* Snarf the interrupt now. There's no point in waiting since we cannot - share and the board will usually be enabled. */ - err = request_irq (dev->irq, ei_interrupt, 0, DRV_NAME, dev); - if (err) { - netdev_emerg(dev, " unable to get IRQ %d.\n", dev->irq); - free_netdev(dev); - return err; - } - - ei_status.name = dev->name; - ei_status.word16 = 1; -#ifdef __LITTLE_ENDIAN__ - ei_status.bigendian = 0; -#else - ei_status.bigendian = 1; -#endif - ei_status.tx_start_page = START_PG; - ei_status.rx_start_page = START_PG + TX_PAGES; - ei_status.stop_page = STOP_PG; - - ei_status.reset_8390 = &stnic_reset; - ei_status.get_8390_hdr = &stnic_get_hdr; - ei_status.block_input = &stnic_block_input; - ei_status.block_output = &stnic_block_output; - - stnic_init (dev); - ei_local = netdev_priv(dev); - ei_local->msg_enable = stnic_msg_enable; - - err = register_netdev(dev); - if (err) { - free_irq(dev->irq, dev); - free_netdev(dev); - return err; - } - stnic_dev = dev; - - netdev_info(dev, "NS ST-NIC 83902A\n"); - - return 0; -} - -static void -stnic_reset (struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - - *(vhalf *) PA_83902_RST = 0; - udelay (5); - netif_warn(ei_local, hw, dev, "8390 reset done (%ld).\n", jiffies); - *(vhalf *) PA_83902_RST = ~0; - udelay (5); -} - -static void -stnic_get_hdr (struct net_device *dev, struct e8390_pkt_hdr *hdr, - int ring_page) -{ - struct ei_device *ei_local = netdev_priv(dev); - - half buf[2]; - - STNIC_WRITE (PG0_RSAR0, 0); - STNIC_WRITE (PG0_RSAR1, ring_page); - STNIC_WRITE (PG0_RBCR0, 4); - STNIC_WRITE (PG0_RBCR1, 0); - STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA); - - buf[0] = *(vhalf *) PA_83902_IF; - STNIC_DELAY (); - buf[1] = *(vhalf *) PA_83902_IF; - STNIC_DELAY (); - hdr->next = buf[0] >> 8; - hdr->status = buf[0] & 0xff; -#ifdef __LITTLE_ENDIAN__ - hdr->count = buf[1]; -#else - hdr->count = ((buf[1] >> 8) & 0xff) | (buf[1] << 8); -#endif - - netif_dbg(ei_local, probe, dev, "ring %x status %02x next %02x count %04x.\n", - ring_page, hdr->status, hdr->next, hdr->count); - - STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA); -} - -/* Block input and output, similar to the Crynwr packet driver. If you are - porting to a new ethercard look at the packet driver source for hints. - The HP LAN doesn't use shared memory -- we put the packet - out through the "remote DMA" dataport. */ - -static void -stnic_block_input (struct net_device *dev, int length, struct sk_buff *skb, - int offset) -{ - char *buf = skb->data; - half val; - - STNIC_WRITE (PG0_RSAR0, offset & 0xff); - STNIC_WRITE (PG0_RSAR1, offset >> 8); - STNIC_WRITE (PG0_RBCR0, length & 0xff); - STNIC_WRITE (PG0_RBCR1, length >> 8); - STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA); - - if (length & 1) - length++; - - while (length > 0) - { - val = *(vhalf *) PA_83902_IF; -#ifdef __LITTLE_ENDIAN__ - *buf++ = val & 0xff; - *buf++ = val >> 8; -#else - *buf++ = val >> 8; - *buf++ = val & 0xff; -#endif - STNIC_DELAY (); - length -= sizeof (half); - } - - STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA); -} - -static void -stnic_block_output (struct net_device *dev, int length, - const unsigned char *buf, int output_page) -{ - STNIC_WRITE (PG0_RBCR0, 1); /* Write non-zero value */ - STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA); - STNIC_DELAY (); - - STNIC_WRITE (PG0_RBCR0, length & 0xff); - STNIC_WRITE (PG0_RBCR1, length >> 8); - STNIC_WRITE (PG0_RSAR0, 0); - STNIC_WRITE (PG0_RSAR1, output_page); - STNIC_WRITE (STNIC_CR, CR_RWR | CR_PG0 | CR_STA); - - if (length & 1) - length++; - - while (length > 0) - { -#ifdef __LITTLE_ENDIAN__ - *(vhalf *) PA_83902_IF = ((half) buf[1] << 8) | buf[0]; -#else - *(vhalf *) PA_83902_IF = ((half) buf[0] << 8) | buf[1]; -#endif - STNIC_DELAY (); - buf += sizeof (half); - length -= sizeof (half); - } - - STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA); -} - -/* This function resets the STNIC if something screws up. */ -static void -stnic_init (struct net_device *dev) -{ - stnic_reset (dev); - NS8390_init (dev, 0); -} - -static void __exit stnic_cleanup(void) -{ - unregister_netdev(stnic_dev); - free_irq(stnic_dev->irq, stnic_dev); - free_netdev(stnic_dev); -} - -module_init(stnic_probe); -module_exit(stnic_cleanup); -MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/8390/wd.c b/drivers/net/ethernet/8390/wd.c deleted file mode 100644 index 263a942d81fa..000000000000 --- a/drivers/net/ethernet/8390/wd.c +++ /dev/null @@ -1,574 +0,0 @@ -/* wd.c: A WD80x3 ethernet driver for linux. */ -/* - Written 1993-94 by Donald Becker. - - Copyright 1993 United States Government as represented by the - Director, National Security Agency. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - The author may be reached as becker@scyld.com, or C/O - Scyld Computing Corporation - 410 Severn Ave., Suite 210 - Annapolis MD 21403 - - This is a driver for WD8003 and WD8013 "compatible" ethercards. - - Thanks to Russ Nelson (nelson@crnwyr.com) for loaning me a WD8013. - - Changelog: - - Paul Gortmaker : multiple card support for module users, support - for non-standard memory sizes. - - -*/ - -static const char version[] = - "wd.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "8390.h" - -#define DRV_NAME "wd" - -/* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int wd_portlist[] __initdata = -{0x300, 0x280, 0x380, 0x240, 0}; - -static int wd_probe1(struct net_device *dev, int ioaddr); - -static int wd_open(struct net_device *dev); -static void wd_reset_8390(struct net_device *dev); -static void wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, - int ring_page); -static void wd_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void wd_block_output(struct net_device *dev, int count, - const unsigned char *buf, int start_page); -static int wd_close(struct net_device *dev); - -static u32 wd_msg_enable; - -#define WD_START_PG 0x00 /* First page of TX buffer */ -#define WD03_STOP_PG 0x20 /* Last page +1 of RX ring */ -#define WD13_STOP_PG 0x40 /* Last page +1 of RX ring */ - -#define WD_CMDREG 0 /* Offset to ASIC command register. */ -#define WD_RESET 0x80 /* Board reset, in WD_CMDREG. */ -#define WD_MEMENB 0x40 /* Enable the shared memory. */ -#define WD_CMDREG5 5 /* Offset to 16-bit-only ASIC register 5. */ -#define ISA16 0x80 /* Enable 16 bit access from the ISA bus. */ -#define NIC16 0x40 /* Enable 16 bit access from the 8390. */ -#define WD_NIC_OFFSET 16 /* Offset to the 8390 from the base_addr. */ -#define WD_IO_EXTENT 32 - - -/* Probe for the WD8003 and WD8013. These cards have the station - address PROM at I/O ports +8 to +13, with a checksum - following. A Soundblaster can have the same checksum as an WDethercard, - so we have an extra exclusionary check for it. - - The wd_probe1() routine initializes the card and fills the - station address field. */ - -static int __init do_wd_probe(struct net_device *dev) -{ - int i; - struct resource *r; - int base_addr = dev->base_addr; - int irq = dev->irq; - int mem_start = dev->mem_start; - int mem_end = dev->mem_end; - - if (base_addr > 0x1ff) { /* Check a user specified location. */ - r = request_region(base_addr, WD_IO_EXTENT, "wd-probe"); - if ( r == NULL) - return -EBUSY; - i = wd_probe1(dev, base_addr); - if (i != 0) - release_region(base_addr, WD_IO_EXTENT); - else - r->name = dev->name; - return i; - } - else if (base_addr != 0) /* Don't probe at all. */ - return -ENXIO; - - for (i = 0; wd_portlist[i]; i++) { - int ioaddr = wd_portlist[i]; - r = request_region(ioaddr, WD_IO_EXTENT, "wd-probe"); - if (r == NULL) - continue; - if (wd_probe1(dev, ioaddr) == 0) { - r->name = dev->name; - return 0; - } - release_region(ioaddr, WD_IO_EXTENT); - dev->irq = irq; - dev->mem_start = mem_start; - dev->mem_end = mem_end; - } - - return -ENODEV; -} - -#ifndef MODULE -struct net_device * __init wd_probe(int unit) -{ - struct net_device *dev = alloc_ei_netdev(); - int err; - - if (!dev) - return ERR_PTR(-ENOMEM); - - sprintf(dev->name, "eth%d", unit); - netdev_boot_setup_check(dev); - - err = do_wd_probe(dev); - if (err) - goto out; - return dev; -out: - free_netdev(dev); - return ERR_PTR(err); -} -#endif - -static const struct net_device_ops wd_netdev_ops = { - .ndo_open = wd_open, - .ndo_stop = wd_close, - .ndo_start_xmit = ei_start_xmit, - .ndo_tx_timeout = ei_tx_timeout, - .ndo_get_stats = ei_get_stats, - .ndo_set_rx_mode = ei_set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = ei_poll, -#endif -}; - -static int __init wd_probe1(struct net_device *dev, int ioaddr) -{ - int i; - int err; - int checksum = 0; - int ancient = 0; /* An old card without config registers. */ - int word16 = 0; /* 0 = 8 bit, 1 = 16 bit */ - const char *model_name; - static unsigned version_printed; - struct ei_device *ei_local = netdev_priv(dev); - - for (i = 0; i < 8; i++) - checksum += inb(ioaddr + 8 + i); - if (inb(ioaddr + 8) == 0xff /* Extra check to avoid soundcard. */ - || inb(ioaddr + 9) == 0xff - || (checksum & 0xff) != 0xFF) - return -ENODEV; - - /* Check for semi-valid mem_start/end values if supplied. */ - if ((dev->mem_start % 0x2000) || (dev->mem_end % 0x2000)) { - netdev_warn(dev, - "wd.c: user supplied mem_start or mem_end not on 8kB boundary - ignored.\n"); - dev->mem_start = 0; - dev->mem_end = 0; - } - - if ((wd_msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0)) - netdev_info(dev, version); - - for (i = 0; i < 6; i++) - dev->dev_addr[i] = inb(ioaddr + 8 + i); - - netdev_info(dev, "WD80x3 at %#3x, %pM", ioaddr, dev->dev_addr); - - /* The following PureData probe code was contributed by - Mike Jagdis . Puredata does software - configuration differently from others so we have to check for them. - This detects an 8 bit, 16 bit or dumb (Toshiba, jumpered) card. - */ - if (inb(ioaddr+0) == 'P' && inb(ioaddr+1) == 'D') { - unsigned char reg5 = inb(ioaddr+5); - - switch (inb(ioaddr+2)) { - case 0x03: word16 = 0; model_name = "PDI8023-8"; break; - case 0x05: word16 = 0; model_name = "PDUC8023"; break; - case 0x0a: word16 = 1; model_name = "PDI8023-16"; break; - /* Either 0x01 (dumb) or they've released a new version. */ - default: word16 = 0; model_name = "PDI8023"; break; - } - dev->mem_start = ((reg5 & 0x1c) + 0xc0) << 12; - dev->irq = (reg5 & 0xe0) == 0xe0 ? 10 : (reg5 >> 5) + 1; - } else { /* End of PureData probe */ - /* This method of checking for a 16-bit board is borrowed from the - we.c driver. A simpler method is just to look in ASIC reg. 0x03. - I'm comparing the two method in alpha test to make certain they - return the same result. */ - /* Check for the old 8 bit board - it has register 0/8 aliasing. - Do NOT check i>=6 here -- it hangs the old 8003 boards! */ - for (i = 0; i < 6; i++) - if (inb(ioaddr+i) != inb(ioaddr+8+i)) - break; - if (i >= 6) { - ancient = 1; - model_name = "WD8003-old"; - word16 = 0; - } else { - int tmp = inb(ioaddr+1); /* fiddle with 16bit bit */ - outb( tmp ^ 0x01, ioaddr+1 ); /* attempt to clear 16bit bit */ - if (((inb( ioaddr+1) & 0x01) == 0x01) /* A 16 bit card */ - && (tmp & 0x01) == 0x01 ) { /* In a 16 slot. */ - int asic_reg5 = inb(ioaddr+WD_CMDREG5); - /* Magic to set ASIC to word-wide mode. */ - outb( NIC16 | (asic_reg5&0x1f), ioaddr+WD_CMDREG5); - outb(tmp, ioaddr+1); - model_name = "WD8013"; - word16 = 1; /* We have a 16bit board here! */ - } else { - model_name = "WD8003"; - word16 = 0; - } - outb(tmp, ioaddr+1); /* Restore original reg1 value. */ - } -#ifndef final_version - if ( !ancient && (inb(ioaddr+1) & 0x01) != (word16 & 0x01)) - pr_cont("\nWD80?3: Bus width conflict, %d (probe) != %d (reg report).", - word16 ? 16 : 8, - (inb(ioaddr+1) & 0x01) ? 16 : 8); -#endif - } - -#if defined(WD_SHMEM) && WD_SHMEM > 0x80000 - /* Allow a compile-time override. */ - dev->mem_start = WD_SHMEM; -#else - if (dev->mem_start == 0) { - /* Sanity and old 8003 check */ - int reg0 = inb(ioaddr); - if (reg0 == 0xff || reg0 == 0) { - /* Future plan: this could check a few likely locations first. */ - dev->mem_start = 0xd0000; - pr_cont(" assigning address %#lx", dev->mem_start); - } else { - int high_addr_bits = inb(ioaddr+WD_CMDREG5) & 0x1f; - /* Some boards don't have the register 5 -- it returns 0xff. */ - if (high_addr_bits == 0x1f || word16 == 0) - high_addr_bits = 0x01; - dev->mem_start = ((reg0&0x3f) << 13) + (high_addr_bits << 19); - } - } -#endif - - /* The 8390 isn't at the base address -- the ASIC regs are there! */ - dev->base_addr = ioaddr+WD_NIC_OFFSET; - - if (dev->irq < 2) { - static const int irqmap[] = {9, 3, 5, 7, 10, 11, 15, 4}; - int reg1 = inb(ioaddr+1); - int reg4 = inb(ioaddr+4); - if (ancient || reg1 == 0xff) { /* Ack!! No way to read the IRQ! */ - short nic_addr = ioaddr+WD_NIC_OFFSET; - unsigned long irq_mask; - - /* We have an old-style ethercard that doesn't report its IRQ - line. Do autoirq to find the IRQ line. Note that this IS NOT - a reliable way to trigger an interrupt. */ - outb_p(E8390_NODMA + E8390_STOP, nic_addr); - outb(0x00, nic_addr+EN0_IMR); /* Disable all intrs. */ - - irq_mask = probe_irq_on(); - outb_p(0xff, nic_addr + EN0_IMR); /* Enable all interrupts. */ - outb_p(0x00, nic_addr + EN0_RCNTLO); - outb_p(0x00, nic_addr + EN0_RCNTHI); - outb(E8390_RREAD+E8390_START, nic_addr); /* Trigger it... */ - mdelay(20); - dev->irq = probe_irq_off(irq_mask); - - outb_p(0x00, nic_addr+EN0_IMR); /* Mask all intrs. again. */ - - if (wd_msg_enable & NETIF_MSG_PROBE) - pr_cont(" autoirq is %d", dev->irq); - if (dev->irq < 2) - dev->irq = word16 ? 10 : 5; - } else - dev->irq = irqmap[((reg4 >> 5) & 0x03) + (reg1 & 0x04)]; - } else if (dev->irq == 2) /* Fixup bogosity: IRQ2 is really IRQ9 */ - dev->irq = 9; - - /* Snarf the interrupt now. There's no point in waiting since we cannot - share and the board will usually be enabled. */ - i = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev); - if (i) { - pr_cont(" unable to get IRQ %d.\n", dev->irq); - return i; - } - - /* OK, were are certain this is going to work. Setup the device. */ - ei_status.name = model_name; - ei_status.word16 = word16; - ei_status.tx_start_page = WD_START_PG; - ei_status.rx_start_page = WD_START_PG + TX_PAGES; - - /* Don't map in the shared memory until the board is actually opened. */ - - /* Some cards (eg WD8003EBT) can be jumpered for more (32k!) memory. */ - if (dev->mem_end != 0) { - ei_status.stop_page = (dev->mem_end - dev->mem_start)/256; - ei_status.priv = dev->mem_end - dev->mem_start; - } else { - ei_status.stop_page = word16 ? WD13_STOP_PG : WD03_STOP_PG; - dev->mem_end = dev->mem_start + (ei_status.stop_page - WD_START_PG)*256; - ei_status.priv = (ei_status.stop_page - WD_START_PG)*256; - } - - ei_status.mem = ioremap(dev->mem_start, ei_status.priv); - if (!ei_status.mem) { - free_irq(dev->irq, dev); - return -ENOMEM; - } - - pr_cont(" %s, IRQ %d, shared memory at %#lx-%#lx.\n", - model_name, dev->irq, dev->mem_start, dev->mem_end-1); - - ei_status.reset_8390 = wd_reset_8390; - ei_status.block_input = wd_block_input; - ei_status.block_output = wd_block_output; - ei_status.get_8390_hdr = wd_get_8390_hdr; - - dev->netdev_ops = &wd_netdev_ops; - NS8390_init(dev, 0); - ei_local->msg_enable = wd_msg_enable; - -#if 1 - /* Enable interrupt generation on softconfig cards -- M.U */ - /* .. but possibly potentially unsafe - Donald */ - if (inb(ioaddr+14) & 0x20) - outb(inb(ioaddr+4)|0x80, ioaddr+4); -#endif - - err = register_netdev(dev); - if (err) { - free_irq(dev->irq, dev); - iounmap(ei_status.mem); - } - return err; -} - -static int -wd_open(struct net_device *dev) -{ - int ioaddr = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ - - /* Map in the shared memory. Always set register 0 last to remain - compatible with very old boards. */ - ei_status.reg0 = ((dev->mem_start>>13) & 0x3f) | WD_MEMENB; - ei_status.reg5 = ((dev->mem_start>>19) & 0x1f) | NIC16; - - if (ei_status.word16) - outb(ei_status.reg5, ioaddr+WD_CMDREG5); - outb(ei_status.reg0, ioaddr); /* WD_CMDREG */ - - return ei_open(dev); -} - -static void -wd_reset_8390(struct net_device *dev) -{ - int wd_cmd_port = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ - struct ei_device *ei_local = netdev_priv(dev); - - outb(WD_RESET, wd_cmd_port); - netif_dbg(ei_local, hw, dev, "resetting the WD80x3 t=%lu...\n", - jiffies); - ei_status.txing = 0; - - /* Set up the ASIC registers, just in case something changed them. */ - outb((((dev->mem_start>>13) & 0x3f)|WD_MEMENB), wd_cmd_port); - if (ei_status.word16) - outb(NIC16 | ((dev->mem_start>>19) & 0x1f), wd_cmd_port+WD_CMDREG5); - - netif_dbg(ei_local, hw, dev, "reset done\n"); -} - -/* Grab the 8390 specific header. Similar to the block_input routine, but - we don't need to be concerned with ring wrap as the header will be at - the start of a page, so we optimize accordingly. */ - -static void -wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) -{ - - int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ - void __iomem *hdr_start = ei_status.mem + ((ring_page - WD_START_PG)<<8); - - /* We'll always get a 4 byte header read followed by a packet read, so - we enable 16 bit mode before the header, and disable after the body. */ - if (ei_status.word16) - outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5); - -#ifdef __BIG_ENDIAN - /* Officially this is what we are doing, but the readl() is faster */ - /* unfortunately it isn't endian aware of the struct */ - memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); - hdr->count = le16_to_cpu(hdr->count); -#else - ((unsigned int*)hdr)[0] = readl(hdr_start); -#endif -} - -/* Block input and output are easy on shared memory ethercards, and trivial - on the Western digital card where there is no choice of how to do it. - The only complications are that the ring buffer wraps, and need to map - switch between 8- and 16-bit modes. */ - -static void -wd_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) -{ - int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ - unsigned long offset = ring_offset - (WD_START_PG<<8); - void __iomem *xfer_start = ei_status.mem + offset; - - if (offset + count > ei_status.priv) { - /* We must wrap the input move. */ - int semi_count = ei_status.priv - offset; - memcpy_fromio(skb->data, xfer_start, semi_count); - count -= semi_count; - memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); - } else { - /* Packet is in one chunk -- we can copy + cksum. */ - memcpy_fromio(skb->data, xfer_start, count); - } - - /* Turn off 16 bit access so that reboot works. ISA brain-damage */ - if (ei_status.word16) - outb(ei_status.reg5, wd_cmdreg+WD_CMDREG5); -} - -static void -wd_block_output(struct net_device *dev, int count, const unsigned char *buf, - int start_page) -{ - int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ - void __iomem *shmem = ei_status.mem + ((start_page - WD_START_PG)<<8); - - - if (ei_status.word16) { - /* Turn on and off 16 bit access so that reboot works. */ - outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5); - memcpy_toio(shmem, buf, count); - outb(ei_status.reg5, wd_cmdreg+WD_CMDREG5); - } else - memcpy_toio(shmem, buf, count); -} - - -static int -wd_close(struct net_device *dev) -{ - int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ - struct ei_device *ei_local = netdev_priv(dev); - - netif_dbg(ei_local, ifdown, dev, "Shutting down ethercard.\n"); - ei_close(dev); - - /* Change from 16-bit to 8-bit shared memory so reboot works. */ - if (ei_status.word16) - outb(ei_status.reg5, wd_cmdreg + WD_CMDREG5 ); - - /* And disable the shared memory. */ - outb(ei_status.reg0 & ~WD_MEMENB, wd_cmdreg); - - return 0; -} - - -#ifdef MODULE -#define MAX_WD_CARDS 4 /* Max number of wd cards per module */ -static struct net_device *dev_wd[MAX_WD_CARDS]; -static int io[MAX_WD_CARDS]; -static int irq[MAX_WD_CARDS]; -static int mem[MAX_WD_CARDS]; -static int mem_end[MAX_WD_CARDS]; /* for non std. mem size */ - -module_param_hw_array(io, int, ioport, NULL, 0); -module_param_hw_array(irq, int, irq, NULL, 0); -module_param_hw_array(mem, int, iomem, NULL, 0); -module_param_hw_array(mem_end, int, iomem, NULL, 0); -module_param_named(msg_enable, wd_msg_enable, uint, 0444); -MODULE_PARM_DESC(io, "I/O base address(es)"); -MODULE_PARM_DESC(irq, "IRQ number(s) (ignored for PureData boards)"); -MODULE_PARM_DESC(mem, "memory base address(es)(ignored for PureData boards)"); -MODULE_PARM_DESC(mem_end, "memory end address(es)"); -MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)"); -MODULE_DESCRIPTION("ISA Western Digital wd8003/wd8013 ; SMC Elite, Elite16 ethernet driver"); -MODULE_LICENSE("GPL"); - -/* This is set up so that only a single autoprobe takes place per call. -ISA device autoprobes on a running machine are not recommended. */ - -static int __init wd_init_module(void) -{ - struct net_device *dev; - int this_dev, found = 0; - - for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) { - if (io[this_dev] == 0) { - if (this_dev != 0) break; /* only autoprobe 1st one */ - printk(KERN_NOTICE "wd.c: Presently autoprobing (not recommended) for a single card.\n"); - } - dev = alloc_ei_netdev(); - if (!dev) - break; - dev->irq = irq[this_dev]; - dev->base_addr = io[this_dev]; - dev->mem_start = mem[this_dev]; - dev->mem_end = mem_end[this_dev]; - if (do_wd_probe(dev) == 0) { - dev_wd[found++] = dev; - continue; - } - free_netdev(dev); - printk(KERN_WARNING "wd.c: No wd80x3 card found (i/o = 0x%x).\n", io[this_dev]); - break; - } - if (found) - return 0; - return -ENXIO; -} -module_init(wd_init_module); - -static void cleanup_card(struct net_device *dev) -{ - free_irq(dev->irq, dev); - release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT); - iounmap(ei_status.mem); -} - -static void __exit wd_cleanup_module(void) -{ - int this_dev; - - for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) { - struct net_device *dev = dev_wd[this_dev]; - if (dev) { - unregister_netdev(dev); - cleanup_card(dev); - free_netdev(dev); - } - } -} -module_exit(wd_cleanup_module); -#endif /* MODULE */ diff --git a/drivers/net/ethernet/8390/xsurf100.c b/drivers/net/ethernet/8390/xsurf100.c deleted file mode 100644 index fe7a74707aa4..000000000000 --- a/drivers/net/ethernet/8390/xsurf100.c +++ /dev/null @@ -1,377 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include -#include -#include - -#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF100 \ - ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x64, 0) - -#define XS100_IRQSTATUS_BASE 0x40 -#define XS100_8390_BASE 0x800 - -/* Longword-access area. Translated to 2 16-bit access cycles by the - * X-Surf 100 FPGA - */ -#define XS100_8390_DATA32_BASE 0x8000 -#define XS100_8390_DATA32_SIZE 0x2000 -/* Sub-Areas for fast data register access; addresses relative to area begin */ -#define XS100_8390_DATA_READ32_BASE 0x0880 -#define XS100_8390_DATA_WRITE32_BASE 0x0C80 -#define XS100_8390_DATA_AREA_SIZE 0x80 - -/* force unsigned long back to 'void __iomem *' */ -#define ax_convert_addr(_a) ((void __force __iomem *)(_a)) - -#define ei_inb(_a) z_readb(ax_convert_addr(_a)) -#define ei_outb(_v, _a) z_writeb(_v, ax_convert_addr(_a)) - -#define ei_inw(_a) z_readw(ax_convert_addr(_a)) -#define ei_outw(_v, _a) z_writew(_v, ax_convert_addr(_a)) - -#define ei_inb_p(_a) ei_inb(_a) -#define ei_outb_p(_v, _a) ei_outb(_v, _a) - -/* define EI_SHIFT() to take into account our register offsets */ -#define EI_SHIFT(x) (ei_local->reg_offset[(x)]) - -/* Ensure we have our RCR base value */ -#define AX88796_PLATFORM - -#include "8390.h" - -/* from ne.c */ -#define NE_CMD EI_SHIFT(0x00) -#define NE_RESET EI_SHIFT(0x1f) -#define NE_DATAPORT EI_SHIFT(0x10) - -struct xsurf100_ax_plat_data { - struct ax_plat_data ax; - void __iomem *base_regs; - void __iomem *data_area; -}; - -static int is_xsurf100_network_irq(struct platform_device *pdev) -{ - struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev); - - return (readw(xs100->base_regs + XS100_IRQSTATUS_BASE) & 0xaaaa) != 0; -} - -/* These functions guarantee that the iomem is accessed with 32 bit - * cycles only. z_memcpy_fromio / z_memcpy_toio don't - */ -static void z_memcpy_fromio32(void *dst, const void __iomem *src, size_t bytes) -{ - while (bytes > 32) { - asm __volatile__ - ("movem.l (%0)+,%%d0-%%d7\n" - "movem.l %%d0-%%d7,(%1)\n" - "adda.l #32,%1" : "=a"(src), "=a"(dst) - : "0"(src), "1"(dst) : "d0", "d1", "d2", "d3", "d4", - "d5", "d6", "d7", "memory"); - bytes -= 32; - } - while (bytes) { - *(uint32_t *)dst = z_readl(src); - src += 4; - dst += 4; - bytes -= 4; - } -} - -static void z_memcpy_toio32(void __iomem *dst, const void *src, size_t bytes) -{ - while (bytes) { - z_writel(*(const uint32_t *)src, dst); - src += 4; - dst += 4; - bytes -= 4; - } -} - -static void xs100_write(struct net_device *dev, const void *src, - unsigned int count) -{ - struct ei_device *ei_local = netdev_priv(dev); - struct platform_device *pdev = to_platform_device(dev->dev.parent); - struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev); - - /* copy whole blocks */ - while (count > XS100_8390_DATA_AREA_SIZE) { - z_memcpy_toio32(xs100->data_area + - XS100_8390_DATA_WRITE32_BASE, src, - XS100_8390_DATA_AREA_SIZE); - src += XS100_8390_DATA_AREA_SIZE; - count -= XS100_8390_DATA_AREA_SIZE; - } - /* copy whole dwords */ - z_memcpy_toio32(xs100->data_area + XS100_8390_DATA_WRITE32_BASE, - src, count & ~3); - src += count & ~3; - if (count & 2) { - ei_outw(*(uint16_t *)src, ei_local->mem + NE_DATAPORT); - src += 2; - } - if (count & 1) - ei_outb(*(uint8_t *)src, ei_local->mem + NE_DATAPORT); -} - -static void xs100_read(struct net_device *dev, void *dst, unsigned int count) -{ - struct ei_device *ei_local = netdev_priv(dev); - struct platform_device *pdev = to_platform_device(dev->dev.parent); - struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev); - - /* copy whole blocks */ - while (count > XS100_8390_DATA_AREA_SIZE) { - z_memcpy_fromio32(dst, xs100->data_area + - XS100_8390_DATA_READ32_BASE, - XS100_8390_DATA_AREA_SIZE); - dst += XS100_8390_DATA_AREA_SIZE; - count -= XS100_8390_DATA_AREA_SIZE; - } - /* copy whole dwords */ - z_memcpy_fromio32(dst, xs100->data_area + XS100_8390_DATA_READ32_BASE, - count & ~3); - dst += count & ~3; - if (count & 2) { - *(uint16_t *)dst = ei_inw(ei_local->mem + NE_DATAPORT); - dst += 2; - } - if (count & 1) - *(uint8_t *)dst = ei_inb(ei_local->mem + NE_DATAPORT); -} - -/* Block input and output, similar to the Crynwr packet driver. If - * you are porting to a new ethercard, look at the packet driver - * source for hints. The NEx000 doesn't share the on-board packet - * memory -- you have to put the packet out through the "remote DMA" - * dataport using ei_outb. - */ -static void xs100_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) -{ - struct ei_device *ei_local = netdev_priv(dev); - void __iomem *nic_base = ei_local->mem; - char *buf = skb->data; - - if (ei_local->dmaing) { - netdev_err(dev, - "DMAing conflict in %s [DMAstat:%d][irqlock:%d]\n", - __func__, - ei_local->dmaing, ei_local->irqlock); - return; - } - - ei_local->dmaing |= 0x01; - - ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); - ei_outb(count & 0xff, nic_base + EN0_RCNTLO); - ei_outb(count >> 8, nic_base + EN0_RCNTHI); - ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO); - ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI); - ei_outb(E8390_RREAD + E8390_START, nic_base + NE_CMD); - - xs100_read(dev, buf, count); - - ei_local->dmaing &= ~1; -} - -static void xs100_block_output(struct net_device *dev, int count, - const unsigned char *buf, const int start_page) -{ - struct ei_device *ei_local = netdev_priv(dev); - void __iomem *nic_base = ei_local->mem; - unsigned long dma_start; - - /* Round the count up for word writes. Do we need to do this? - * What effect will an odd byte count have on the 8390? I - * should check someday. - */ - if (ei_local->word16 && (count & 0x01)) - count++; - - /* This *shouldn't* happen. If it does, it's the last thing - * you'll see - */ - if (ei_local->dmaing) { - netdev_err(dev, - "DMAing conflict in %s [DMAstat:%d][irqlock:%d]\n", - __func__, - ei_local->dmaing, ei_local->irqlock); - return; - } - - ei_local->dmaing |= 0x01; - /* We should already be in page 0, but to be safe... */ - ei_outb(E8390_PAGE0 + E8390_START + E8390_NODMA, nic_base + NE_CMD); - - ei_outb(ENISR_RDC, nic_base + EN0_ISR); - - /* Now the normal output. */ - ei_outb(count & 0xff, nic_base + EN0_RCNTLO); - ei_outb(count >> 8, nic_base + EN0_RCNTHI); - ei_outb(0x00, nic_base + EN0_RSARLO); - ei_outb(start_page, nic_base + EN0_RSARHI); - - ei_outb(E8390_RWRITE + E8390_START, nic_base + NE_CMD); - - xs100_write(dev, buf, count); - - dma_start = jiffies; - - while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) { - if (jiffies - dma_start > 2 * HZ / 100) { /* 20ms */ - netdev_warn(dev, "timeout waiting for Tx RDC.\n"); - ei_local->reset_8390(dev); - ax_NS8390_reinit(dev); - break; - } - } - - ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_local->dmaing &= ~0x01; -} - -static int xsurf100_probe(struct zorro_dev *zdev, - const struct zorro_device_id *ent) -{ - struct platform_device *pdev; - struct xsurf100_ax_plat_data ax88796_data; - struct resource res[2] = { - DEFINE_RES_NAMED(IRQ_AMIGA_PORTS, 1, NULL, - IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE), - DEFINE_RES_MEM(zdev->resource.start + XS100_8390_BASE, - 4 * 0x20) - }; - int reg; - /* This table is referenced in the device structure, so it must - * outlive the scope of xsurf100_probe. - */ - static u32 reg_offsets[32]; - int ret = 0; - - /* X-Surf 100 control and 32 bit ring buffer data access areas. - * These resources are not used by the ax88796 driver, so must - * be requested here and passed via platform data. - */ - - if (!request_mem_region(zdev->resource.start, 0x100, zdev->name)) { - dev_err(&zdev->dev, "cannot reserve X-Surf 100 control registers\n"); - return -ENXIO; - } - - if (!request_mem_region(zdev->resource.start + - XS100_8390_DATA32_BASE, - XS100_8390_DATA32_SIZE, - "X-Surf 100 32-bit data access")) { - dev_err(&zdev->dev, "cannot reserve 32-bit area\n"); - ret = -ENXIO; - goto exit_req; - } - - for (reg = 0; reg < 0x20; reg++) - reg_offsets[reg] = 4 * reg; - - memset(&ax88796_data, 0, sizeof(ax88796_data)); - ax88796_data.ax.flags = AXFLG_HAS_EEPROM; - ax88796_data.ax.wordlength = 2; - ax88796_data.ax.dcr_val = 0x48; - ax88796_data.ax.rcr_val = 0x40; - ax88796_data.ax.reg_offsets = reg_offsets; - ax88796_data.ax.check_irq = is_xsurf100_network_irq; - ax88796_data.base_regs = ioremap(zdev->resource.start, 0x100); - - /* error handling for ioremap regs */ - if (!ax88796_data.base_regs) { - dev_err(&zdev->dev, "Cannot ioremap area %pR (registers)\n", - &zdev->resource); - - ret = -ENXIO; - goto exit_req2; - } - - ax88796_data.data_area = ioremap(zdev->resource.start + - XS100_8390_DATA32_BASE, XS100_8390_DATA32_SIZE); - - /* error handling for ioremap data */ - if (!ax88796_data.data_area) { - dev_err(&zdev->dev, - "Cannot ioremap area %pR offset %x (32-bit access)\n", - &zdev->resource, XS100_8390_DATA32_BASE); - - ret = -ENXIO; - goto exit_mem; - } - - ax88796_data.ax.block_output = xs100_block_output; - ax88796_data.ax.block_input = xs100_block_input; - - pdev = platform_device_register_resndata(&zdev->dev, "ax88796", - zdev->slotaddr, res, 2, - &ax88796_data, - sizeof(ax88796_data)); - - if (IS_ERR(pdev)) { - dev_err(&zdev->dev, "cannot register platform device\n"); - ret = -ENXIO; - goto exit_mem2; - } - - zorro_set_drvdata(zdev, pdev); - - if (!ret) - return 0; - - exit_mem2: - iounmap(ax88796_data.data_area); - - exit_mem: - iounmap(ax88796_data.base_regs); - - exit_req2: - release_mem_region(zdev->resource.start + XS100_8390_DATA32_BASE, - XS100_8390_DATA32_SIZE); - - exit_req: - release_mem_region(zdev->resource.start, 0x100); - - return ret; -} - -static void xsurf100_remove(struct zorro_dev *zdev) -{ - struct platform_device *pdev = zorro_get_drvdata(zdev); - struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev); - - platform_device_unregister(pdev); - - iounmap(xs100->base_regs); - release_mem_region(zdev->resource.start, 0x100); - iounmap(xs100->data_area); - release_mem_region(zdev->resource.start + XS100_8390_DATA32_BASE, - XS100_8390_DATA32_SIZE); -} - -static const struct zorro_device_id xsurf100_zorro_tbl[] = { - { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF100, }, - { 0 } -}; - -MODULE_DEVICE_TABLE(zorro, xsurf100_zorro_tbl); - -static struct zorro_driver xsurf100_driver = { - .name = "xsurf100", - .id_table = xsurf100_zorro_tbl, - .probe = xsurf100_probe, - .remove = xsurf100_remove, -}; - -module_driver(xsurf100_driver, zorro_register_driver, zorro_unregister_driver); - -MODULE_DESCRIPTION("X-Surf 100 driver"); -MODULE_AUTHOR("Michael Karcher "); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/net/ethernet/8390/zorro8390.c b/drivers/net/ethernet/8390/zorro8390.c deleted file mode 100644 index 35a500a21521..000000000000 --- a/drivers/net/ethernet/8390/zorro8390.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Amiga Linux/m68k and Linux/PPC Zorro NS8390 Ethernet Driver - * - * (C) Copyright 1998-2000 by some Elitist 680x0 Users(TM) - * - * --------------------------------------------------------------------------- - * - * This program is based on all the other NE2000 drivers for Linux - * - * --------------------------------------------------------------------------- - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - * - * --------------------------------------------------------------------------- - * - * The Ariadne II and X-Surf are Zorro-II boards containing Realtek RTL8019AS - * Ethernet Controllers. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define EI_SHIFT(x) (ei_local->reg_offset[x]) -#define ei_inb(port) in_8(port) -#define ei_outb(val, port) out_8(port, val) -#define ei_inb_p(port) in_8(port) -#define ei_outb_p(val, port) out_8(port, val) - -static const char version[] = - "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; - -#include "lib8390.c" - -#define DRV_NAME "zorro8390" - -#define NE_BASE (dev->base_addr) -#define NE_CMD (0x00 * 2) -#define NE_DATAPORT (0x10 * 2) /* NatSemi-defined port window offset */ -#define NE_RESET (0x1f * 2) /* Issue a read to reset, - * a write to clear. */ -#define NE_IO_EXTENT (0x20 * 2) - -#define NE_EN0_ISR (0x07 * 2) -#define NE_EN0_DCFG (0x0e * 2) - -#define NE_EN0_RSARLO (0x08 * 2) -#define NE_EN0_RSARHI (0x09 * 2) -#define NE_EN0_RCNTLO (0x0a * 2) -#define NE_EN0_RXCR (0x0c * 2) -#define NE_EN0_TXCR (0x0d * 2) -#define NE_EN0_RCNTHI (0x0b * 2) -#define NE_EN0_IMR (0x0f * 2) - -#define NESM_START_PG 0x40 /* First page of TX buffer */ -#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ - -#define WORDSWAP(a) ((((a) >> 8) & 0xff) | ((a) << 8)) - -static struct card_info { - zorro_id id; - const char *name; - unsigned int offset; -} cards[] = { - { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, "Ariadne II", 0x0600 }, - { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, "X-Surf", 0x8600 }, -}; - -/* Hard reset the card. This used to pause for the same period that a - * 8390 reset command required, but that shouldn't be necessary. - */ -static void zorro8390_reset_8390(struct net_device *dev) -{ - unsigned long reset_start_time = jiffies; - struct ei_device *ei_local = netdev_priv(dev); - - netif_dbg(ei_local, hw, dev, "resetting - t=%ld...\n", jiffies); - - z_writeb(z_readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); - - ei_status.txing = 0; - ei_status.dmaing = 0; - - /* This check _should_not_ be necessary, omit eventually. */ - while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) { - netdev_warn(dev, "%s: did not complete\n", __func__); - break; - } - z_writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR); /* Ack intr */ -} - -/* Grab the 8390 specific header. Similar to the block_input routine, but - * we don't need to be concerned with ring wrap as the header will be at - * the start of a page, so we optimize accordingly. - */ -static void zorro8390_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page) -{ - int nic_base = dev->base_addr; - int cnt; - short *ptrs; - - /* This *shouldn't* happen. - * If it does, it's the last thing you'll see - */ - if (ei_status.dmaing) { - netdev_warn(dev, - "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n", - __func__, ei_status.dmaing, ei_status.irqlock); - return; - } - - ei_status.dmaing |= 0x01; - z_writeb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); - z_writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO); - z_writeb(0, nic_base + NE_EN0_RCNTHI); - z_writeb(0, nic_base + NE_EN0_RSARLO); /* On page boundary */ - z_writeb(ring_page, nic_base + NE_EN0_RSARHI); - z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); - - ptrs = (short *)hdr; - for (cnt = 0; cnt < sizeof(struct e8390_pkt_hdr) >> 1; cnt++) - *ptrs++ = z_readw(NE_BASE + NE_DATAPORT); - - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */ - - hdr->count = WORDSWAP(hdr->count); - - ei_status.dmaing &= ~0x01; -} - -/* Block input and output, similar to the Crynwr packet driver. - * If you are porting to a new ethercard, look at the packet driver source - * for hints. The NEx000 doesn't share the on-board packet memory -- - * you have to put the packet out through the "remote DMA" dataport - * using z_writeb. - */ -static void zorro8390_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) -{ - int nic_base = dev->base_addr; - char *buf = skb->data; - short *ptrs; - int cnt; - - /* This *shouldn't* happen. - * If it does, it's the last thing you'll see - */ - if (ei_status.dmaing) { - netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n", - __func__, ei_status.dmaing, ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - z_writeb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); - z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO); - z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI); - z_writeb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO); - z_writeb(ring_offset >> 8, nic_base + NE_EN0_RSARHI); - z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); - ptrs = (short *)buf; - for (cnt = 0; cnt < count >> 1; cnt++) - *ptrs++ = z_readw(NE_BASE + NE_DATAPORT); - if (count & 0x01) - buf[count - 1] = z_readb(NE_BASE + NE_DATAPORT); - - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */ - ei_status.dmaing &= ~0x01; -} - -static void zorro8390_block_output(struct net_device *dev, int count, - const unsigned char *buf, - const int start_page) -{ - int nic_base = NE_BASE; - unsigned long dma_start; - short *ptrs; - int cnt; - - /* Round the count up for word writes. Do we need to do this? - * What effect will an odd byte count have on the 8390? - * I should check someday. - */ - if (count & 0x01) - count++; - - /* This *shouldn't* happen. - * If it does, it's the last thing you'll see - */ - if (ei_status.dmaing) { - netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n", - __func__, ei_status.dmaing, ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - /* We should already be in page 0, but to be safe... */ - z_writeb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); - - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); - - /* Now the normal output. */ - z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO); - z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI); - z_writeb(0x00, nic_base + NE_EN0_RSARLO); - z_writeb(start_page, nic_base + NE_EN0_RSARHI); - - z_writeb(E8390_RWRITE + E8390_START, nic_base + NE_CMD); - ptrs = (short *)buf; - for (cnt = 0; cnt < count >> 1; cnt++) - z_writew(*ptrs++, NE_BASE + NE_DATAPORT); - - dma_start = jiffies; - - while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2 * HZ / 100)) { - /* 20ms */ - netdev_warn(dev, "timeout waiting for Tx RDC\n"); - zorro8390_reset_8390(dev); - __NS8390_init(dev, 1); - break; - } - - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */ - ei_status.dmaing &= ~0x01; -} - -static int zorro8390_open(struct net_device *dev) -{ - __ei_open(dev); - return 0; -} - -static int zorro8390_close(struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - - netif_dbg(ei_local, ifdown, dev, "Shutting down ethercard\n"); - __ei_close(dev); - return 0; -} - -static void zorro8390_remove_one(struct zorro_dev *z) -{ - struct net_device *dev = zorro_get_drvdata(z); - - unregister_netdev(dev); - free_irq(IRQ_AMIGA_PORTS, dev); - release_mem_region(ZTWO_PADDR(dev->base_addr), NE_IO_EXTENT * 2); - free_netdev(dev); -} - -static struct zorro_device_id zorro8390_zorro_tbl[] = { - { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, }, - { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, }, - { 0 } -}; -MODULE_DEVICE_TABLE(zorro, zorro8390_zorro_tbl); - -static const struct net_device_ops zorro8390_netdev_ops = { - .ndo_open = zorro8390_open, - .ndo_stop = zorro8390_close, - .ndo_start_xmit = __ei_start_xmit, - .ndo_tx_timeout = __ei_tx_timeout, - .ndo_get_stats = __ei_get_stats, - .ndo_set_rx_mode = __ei_set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = __ei_poll, -#endif -}; - -static int zorro8390_init(struct net_device *dev, unsigned long board, - const char *name, void __iomem *ioaddr) -{ - int i; - int err; - unsigned char SA_prom[32]; - int start_page, stop_page; - static u32 zorro8390_offsets[16] = { - 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, - 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, - }; - - /* Reset card. Who knows what dain-bramaged state it was left in. */ - { - unsigned long reset_start_time = jiffies; - - z_writeb(z_readb(ioaddr + NE_RESET), ioaddr + NE_RESET); - - while ((z_readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, - reset_start_time + 2 * HZ / 100)) { - netdev_warn(dev, "not found (no reset ack)\n"); - return -ENODEV; - } - - z_writeb(0xff, ioaddr + NE_EN0_ISR); /* Ack all intr. */ - } - - /* Read the 16 bytes of station address PROM. - * We must first initialize registers, - * similar to NS8390_init(eifdev, 0). - * We can't reliably read the SAPROM address without this. - * (I learned the hard way!). - */ - { - static const struct { - u32 value; - u32 offset; - } program_seq[] = { - {E8390_NODMA + E8390_PAGE0 + E8390_STOP, NE_CMD}, - /* Select page 0 */ - {0x48, NE_EN0_DCFG}, /* 0x48: Set byte-wide access */ - {0x00, NE_EN0_RCNTLO}, /* Clear the count regs */ - {0x00, NE_EN0_RCNTHI}, - {0x00, NE_EN0_IMR}, /* Mask completion irq */ - {0xFF, NE_EN0_ISR}, - {E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */ - {E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode */ - {32, NE_EN0_RCNTLO}, - {0x00, NE_EN0_RCNTHI}, - {0x00, NE_EN0_RSARLO}, /* DMA starting at 0x0000 */ - {0x00, NE_EN0_RSARHI}, - {E8390_RREAD + E8390_START, NE_CMD}, - }; - for (i = 0; i < ARRAY_SIZE(program_seq); i++) - z_writeb(program_seq[i].value, - ioaddr + program_seq[i].offset); - } - for (i = 0; i < 16; i++) { - SA_prom[i] = z_readb(ioaddr + NE_DATAPORT); - (void)z_readb(ioaddr + NE_DATAPORT); - } - - /* We must set the 8390 for word mode. */ - z_writeb(0x49, ioaddr + NE_EN0_DCFG); - start_page = NESM_START_PG; - stop_page = NESM_STOP_PG; - - dev->base_addr = (unsigned long)ioaddr; - dev->irq = IRQ_AMIGA_PORTS; - - /* Install the Interrupt handler */ - i = request_irq(IRQ_AMIGA_PORTS, __ei_interrupt, - IRQF_SHARED, DRV_NAME, dev); - if (i) - return i; - - for (i = 0; i < ETH_ALEN; i++) - dev->dev_addr[i] = SA_prom[i]; - - pr_debug("Found ethernet address: %pM\n", dev->dev_addr); - - ei_status.name = name; - ei_status.tx_start_page = start_page; - ei_status.stop_page = stop_page; - ei_status.word16 = 1; - - ei_status.rx_start_page = start_page + TX_PAGES; - - ei_status.reset_8390 = zorro8390_reset_8390; - ei_status.block_input = zorro8390_block_input; - ei_status.block_output = zorro8390_block_output; - ei_status.get_8390_hdr = zorro8390_get_8390_hdr; - ei_status.reg_offset = zorro8390_offsets; - - dev->netdev_ops = &zorro8390_netdev_ops; - __NS8390_init(dev, 0); - - err = register_netdev(dev); - if (err) { - free_irq(IRQ_AMIGA_PORTS, dev); - return err; - } - - netdev_info(dev, "%s at 0x%08lx, Ethernet Address %pM\n", - name, board, dev->dev_addr); - - return 0; -} - -static int zorro8390_init_one(struct zorro_dev *z, - const struct zorro_device_id *ent) -{ - struct net_device *dev; - unsigned long board, ioaddr; - int err, i; - - for (i = ARRAY_SIZE(cards) - 1; i >= 0; i--) - if (z->id == cards[i].id) - break; - if (i < 0) - return -ENODEV; - - board = z->resource.start; - ioaddr = board + cards[i].offset; - dev = ____alloc_ei_netdev(0); - if (!dev) - return -ENOMEM; - if (!request_mem_region(ioaddr, NE_IO_EXTENT * 2, DRV_NAME)) { - free_netdev(dev); - return -EBUSY; - } - err = zorro8390_init(dev, board, cards[i].name, ZTWO_VADDR(ioaddr)); - if (err) { - release_mem_region(ioaddr, NE_IO_EXTENT * 2); - free_netdev(dev); - return err; - } - zorro_set_drvdata(z, dev); - return 0; -} - -static struct zorro_driver zorro8390_driver = { - .name = "zorro8390", - .id_table = zorro8390_zorro_tbl, - .probe = zorro8390_init_one, - .remove = zorro8390_remove_one, -}; - -static int __init zorro8390_init_module(void) -{ - return zorro_register_driver(&zorro8390_driver); -} - -static void __exit zorro8390_cleanup_module(void) -{ - zorro_unregister_driver(&zorro8390_driver); -} - -module_init(zorro8390_init_module); -module_exit(zorro8390_cleanup_module); - -MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig index 1cdff1dca790..da11cc2e122f 100644 --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig @@ -140,7 +140,6 @@ source "drivers/net/ethernet/natsemi/Kconfig" source "drivers/net/ethernet/neterion/Kconfig" source "drivers/net/ethernet/netronome/Kconfig" source "drivers/net/ethernet/ni/Kconfig" -source "drivers/net/ethernet/8390/Kconfig" source "drivers/net/ethernet/nvidia/Kconfig" source "drivers/net/ethernet/nxp/Kconfig" source "drivers/net/ethernet/oki-semi/Kconfig" diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile index cb3f9084a21b..f96a174db8e9 100644 --- a/drivers/net/ethernet/Makefile +++ b/drivers/net/ethernet/Makefile @@ -4,7 +4,6 @@ # obj-$(CONFIG_NET_VENDOR_3COM) += 3com/ -obj-$(CONFIG_NET_VENDOR_8390) += 8390/ obj-$(CONFIG_NET_VENDOR_ACTIONS) += actions/ obj-$(CONFIG_NET_VENDOR_ADAPTEC) += adaptec/ obj-$(CONFIG_GRETH) += aeroflex/