Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Amiga Linux/68k 8390 based PCMCIA Ethernet Driver for the Amiga 1200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * (C) Copyright 1997 Alain Malek
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *                    (Alain.Malek@cryogen.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * ----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * This program is based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * ne.c:       A general non-shared-memory NS8390 ethernet driver for linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *             Written 1992-94 by Donald Becker.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * 8390.c:     A general NS8390 ethernet driver core for linux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *             Written 1992-94 by Donald Becker.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * cnetdevice: A Sana-II ethernet driver for AmigaOS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *             Written by Bruce Abbott (bhabbott@inhb.co.nz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * ----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * License.  See the file COPYING in the main directory of the Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * distribution for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * ----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include <asm/amigaints.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include <asm/amigahw.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #include <asm/amigayle.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #include <asm/amipcmcia.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #include "8390.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) /* ---- No user-serviceable parts below ---- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define DRV_NAME "apne"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define NE_BASE	 (dev->base_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define NE_CMD	 		0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define NE_DATAPORT		0x10            /* NatSemi-defined port window offset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define NE_RESET		0x1f            /* Issue a read to reset, a write to clear. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define NE_IO_EXTENT	        0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define NE_EN0_ISR		0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define NE_EN0_DCFG		0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define NE_EN0_RSARLO	        0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define NE_EN0_RSARHI	        0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define NE_EN0_RCNTLO	        0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define NE_EN0_RXCR		0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define NE_EN0_TXCR		0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define NE_EN0_RCNTHI	        0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define NE_EN0_IMR		0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define NE1SM_START_PG	0x20	/* First page of TX buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define NE1SM_STOP_PG 	0x40	/* Last page +1 of RX ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #define NESM_START_PG	0x40	/* First page of TX buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #define NESM_STOP_PG	0x80	/* Last page +1 of RX ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) struct net_device * __init apne_probe(int unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) static int apne_probe1(struct net_device *dev, int ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) static void apne_reset_8390(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) static void apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			  int ring_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) static void apne_block_input(struct net_device *dev, int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 								struct sk_buff *skb, int ring_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) static void apne_block_output(struct net_device *dev, const int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 							const unsigned char *buf, const int start_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) static irqreturn_t apne_interrupt(int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) static int init_pcmcia(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) /* IO base address used for nic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define IOBASE 0x300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)    use MANUAL_CONFIG and MANUAL_OFFSET for enabling IO by hand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)    you can find the values to use by looking at the cnet.device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)    config file example (the default values are for the CNET40BC card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define MANUAL_CONFIG 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define MANUAL_OFFSET 0x3f8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define MANUAL_HWADDR0 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define MANUAL_HWADDR1 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define MANUAL_HWADDR2 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define MANUAL_HWADDR3 0x56
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define MANUAL_HWADDR4 0x78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define MANUAL_HWADDR5 0x9a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static const char version[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)     "apne.c:v1.1 7/10/98 Alain Malek (Alain.Malek@cryogen.ch)\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static int apne_owned;	/* signal if card already owned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static u32 apne_msg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) module_param_named(msg_enable, apne_msg_enable, uint, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct net_device * __init apne_probe(int unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	struct ei_device *ei_local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #ifndef MANUAL_CONFIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	char tuple[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	if (!MACH_IS_AMIGA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	if (apne_owned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	if ( !(AMIGAHW_PRESENT(PCMCIA)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	pr_info("Looking for PCMCIA ethernet card : ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	/* check if a card is inserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	if (!(PCMCIA_INSERTED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		pr_cont("NO PCMCIA card inserted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	dev = alloc_ei_netdev();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (unit >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		sprintf(dev->name, "eth%d", unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		netdev_boot_setup_check(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	ei_local = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	ei_local->msg_enable = apne_msg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	/* disable pcmcia irq for readtuple */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	pcmcia_disable_irq();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #ifndef MANUAL_CONFIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	if ((pcmcia_copy_tuple(CISTPL_FUNCID, tuple, 8) < 3) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		(tuple[2] != CISTPL_FUNCID_NETWORK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		pr_cont("not an ethernet card\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		/* XXX: shouldn't we re-enable irq here? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	pr_cont("ethernet PCMCIA card inserted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	if (!init_pcmcia()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		/* XXX: shouldn't we re-enable irq here? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	if (!request_region(IOBASE, 0x20, DRV_NAME)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		return ERR_PTR(-EBUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	err = apne_probe1(dev, IOBASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		release_region(IOBASE, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	err = register_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	pcmcia_disable_irq();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	free_irq(IRQ_AMIGA_PORTS, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	pcmcia_reset();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	release_region(IOBASE, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static int __init apne_probe1(struct net_device *dev, int ioaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)     int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)     unsigned char SA_prom[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)     int wordlength = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)     const char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)     int start_page, stop_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #ifndef MANUAL_HWADDR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)     int neX000, ctron;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)     static unsigned version_printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)     if ((apne_msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		netdev_info(dev, version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)     netdev_info(dev, "PCMCIA NE*000 ethercard probe");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)     /* Reset card. Who knows what dain-bramaged state it was left in. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)     {	unsigned long reset_start_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	while ((inb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			pr_cont(" not found (no reset ack).\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	outb(0xff, ioaddr + NE_EN0_ISR);		/* Ack all intr. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) #ifndef MANUAL_HWADDR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)     /* Read the 16 bytes of station address PROM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)        We must first initialize registers, similar to NS8390_init(eifdev, 0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)        We can't reliably read the SAPROM address without this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)        (I learned the hard way!). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)     {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	struct {unsigned long value, offset; } program_seq[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	    {E8390_NODMA+E8390_PAGE0+E8390_STOP, NE_CMD}, /* Select page 0*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	    {0x48,	NE_EN0_DCFG},	/* Set byte-wide (0x48) access. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	    {0x00,	NE_EN0_RCNTLO},	/* Clear the count regs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	    {0x00,	NE_EN0_RCNTHI},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	    {0x00,	NE_EN0_IMR},	/* Mask completion irq. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	    {0xFF,	NE_EN0_ISR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	    {E8390_RXOFF, NE_EN0_RXCR},	/* 0x20  Set to monitor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	    {E8390_TXOFF, NE_EN0_TXCR},	/* 0x02  and loopback mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	    {32,	NE_EN0_RCNTLO},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	    {0x00,	NE_EN0_RCNTHI},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	    {0x00,	NE_EN0_RSARLO},	/* DMA starting at 0x0000. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	    {0x00,	NE_EN0_RSARHI},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	    {E8390_RREAD+E8390_START, NE_CMD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	for (i = 0; i < ARRAY_SIZE(program_seq); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	    outb(program_seq[i].value, ioaddr + program_seq[i].offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)     for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	SA_prom[i] = inb(ioaddr + NE_DATAPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	if (SA_prom[i] != SA_prom[i+1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	    wordlength = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)     /*	At this point, wordlength *only* tells us if the SA_prom is doubled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	up or not because some broken PCI cards don't respect the byte-wide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	request in program_seq above, and hence don't have doubled up values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	These broken cards would otherwise be detected as an ne1000.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)     if (wordlength == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	for (i = 0; i < 16; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		SA_prom[i] = SA_prom[i+i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)     if (wordlength == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	/* We must set the 8390 for word mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	outb(0x49, ioaddr + NE_EN0_DCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	start_page = NESM_START_PG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	stop_page = NESM_STOP_PG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)     } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	start_page = NE1SM_START_PG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	stop_page = NE1SM_STOP_PG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)     neX000 = (SA_prom[14] == 0x57  &&  SA_prom[15] == 0x57);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)     ctron =  (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)     /* Set up the rest of the parameters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)     if (neX000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	name = (wordlength == 2) ? "NE2000" : "NE1000";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)     } else if (ctron) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	name = (wordlength == 2) ? "Ctron-8" : "Ctron-16";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	start_page = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	stop_page = (wordlength == 2) ? 0x40 : 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)     } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	pr_cont(" not found.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)     wordlength = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)     /* We must set the 8390 for word mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)     outb(0x49, ioaddr + NE_EN0_DCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)     start_page = NESM_START_PG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)     stop_page = NESM_STOP_PG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)     SA_prom[0] = MANUAL_HWADDR0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)     SA_prom[1] = MANUAL_HWADDR1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)     SA_prom[2] = MANUAL_HWADDR2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)     SA_prom[3] = MANUAL_HWADDR3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)     SA_prom[4] = MANUAL_HWADDR4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)     SA_prom[5] = MANUAL_HWADDR5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)     name = "NE2000";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)     dev->base_addr = ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)     dev->irq = IRQ_AMIGA_PORTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)     dev->netdev_ops = &ei_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)     /* Install the Interrupt handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)     i = request_irq(dev->irq, apne_interrupt, IRQF_SHARED, DRV_NAME, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)     if (i) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)     for (i = 0; i < ETH_ALEN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	dev->dev_addr[i] = SA_prom[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)     pr_cont(" %pM\n", dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)     netdev_info(dev, "%s found.\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)     ei_status.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)     ei_status.tx_start_page = start_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)     ei_status.stop_page = stop_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)     ei_status.word16 = (wordlength == 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)     ei_status.rx_start_page = start_page + TX_PAGES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)     ei_status.reset_8390 = &apne_reset_8390;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)     ei_status.block_input = &apne_block_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)     ei_status.block_output = &apne_block_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)     ei_status.get_8390_hdr = &apne_get_8390_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)     NS8390_init(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)     pcmcia_ack_int(pcmcia_get_intreq());		/* ack PCMCIA int req */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)     pcmcia_enable_irq();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)     apne_owned = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /* Hard reset the card.  This used to pause for the same period that a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)    8390 reset command required, but that shouldn't be necessary. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) apne_reset_8390(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)     unsigned long reset_start_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)     struct ei_device *ei_local = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)     init_pcmcia();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)     netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)     outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)     ei_status.txing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)     ei_status.dmaing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)     /* This check _should_not_ be necessary, omit eventually. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)     while ((inb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		netdev_err(dev, "ne_reset_8390() did not complete.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)     outb(ENISR_RESET, NE_BASE + NE_EN0_ISR);	/* Ack intr. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* Grab the 8390 specific header. Similar to the block_input routine, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)    we don't need to be concerned with ring wrap as the header will be at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)    the start of a page, so we optimize accordingly. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)     int nic_base = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)     int cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)     char *ptrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)     short *ptrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)     /* This *shouldn't* happen. If it does, it's the last thing you'll see */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)     if (ei_status.dmaing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	netdev_err(dev, "DMAing conflict in ne_get_8390_hdr "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		   "[DMAstat:%d][irqlock:%d][intr:%d].\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		   ei_status.dmaing, ei_status.irqlock, dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)     ei_status.dmaing |= 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)     outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)     outb(ENISR_RDC, nic_base + NE_EN0_ISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)     outb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)     outb(0, nic_base + NE_EN0_RCNTHI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)     outb(0, nic_base + NE_EN0_RSARLO);		/* On page boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)     outb(ring_page, nic_base + NE_EN0_RSARHI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)     outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)     if (ei_status.word16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)         ptrs = (short*)hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)         for(cnt = 0; cnt < (sizeof(struct e8390_pkt_hdr)>>1); cnt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)             *ptrs++ = inw(NE_BASE + NE_DATAPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)     } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)         ptrc = (char*)hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)         for(cnt = 0; cnt < sizeof(struct e8390_pkt_hdr); cnt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)             *ptrc++ = inb(NE_BASE + NE_DATAPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)     outb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)     ei_status.dmaing &= ~0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)     le16_to_cpus(&hdr->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /* Block input and output, similar to the Crynwr packet driver.  If you
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)    are porting to a new ethercard, look at the packet driver source for hints.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)    The NEx000 doesn't share the on-board packet memory -- you have to put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)    the packet out through the "remote DMA" dataport using outb. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)     int nic_base = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)     char *buf = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)     char *ptrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)     short *ptrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)     int cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)     /* This *shouldn't* happen. If it does, it's the last thing you'll see */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)     if (ei_status.dmaing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		netdev_err(dev, "DMAing conflict in ne_block_input "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 			   "[DMAstat:%d][irqlock:%d][intr:%d].\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 			   ei_status.dmaing, ei_status.irqlock, dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)     ei_status.dmaing |= 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)     outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)     outb(ENISR_RDC, nic_base + NE_EN0_ISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)     outb(count & 0xff, nic_base + NE_EN0_RCNTLO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)     outb(count >> 8, nic_base + NE_EN0_RCNTHI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)     outb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)     outb(ring_offset >> 8, nic_base + NE_EN0_RSARHI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)     outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)     if (ei_status.word16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)       ptrs = (short*)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)       for (cnt = 0; cnt < (count>>1); cnt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)         *ptrs++ = inw(NE_BASE + NE_DATAPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)       if (count & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	buf[count-1] = inb(NE_BASE + NE_DATAPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)       }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)     } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)       ptrc = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)       for (cnt = 0; cnt < count; cnt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)         *ptrc++ = inb(NE_BASE + NE_DATAPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)     outb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)     ei_status.dmaing &= ~0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) apne_block_output(struct net_device *dev, int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		const unsigned char *buf, const int start_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)     int nic_base = NE_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)     unsigned long dma_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)     char *ptrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)     short *ptrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)     int cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)     /* Round the count up for word writes.  Do we need to do this?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)        What effect will an odd byte count have on the 8390?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)        I should check someday. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)     if (ei_status.word16 && (count & 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)       count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)     /* This *shouldn't* happen. If it does, it's the last thing you'll see */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)     if (ei_status.dmaing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		netdev_err(dev, "DMAing conflict in ne_block_output."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 			   "[DMAstat:%d][irqlock:%d][intr:%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 			   ei_status.dmaing, ei_status.irqlock, dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)     ei_status.dmaing |= 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)     /* We should already be in page 0, but to be safe... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)     outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)     outb(ENISR_RDC, nic_base + NE_EN0_ISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)    /* Now the normal output. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)     outb(count & 0xff, nic_base + NE_EN0_RCNTLO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)     outb(count >> 8,   nic_base + NE_EN0_RCNTHI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)     outb(0x00, nic_base + NE_EN0_RSARLO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)     outb(start_page, nic_base + NE_EN0_RSARHI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)     outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)     if (ei_status.word16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)         ptrs = (short*)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)         for (cnt = 0; cnt < count>>1; cnt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)             outw(*ptrs++, NE_BASE+NE_DATAPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)     } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)         ptrc = (char*)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)         for (cnt = 0; cnt < count; cnt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	    outb(*ptrc++, NE_BASE + NE_DATAPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)     dma_start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)     while ((inb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	if (time_after(jiffies, dma_start + 2*HZ/100)) {	/* 20ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		netdev_warn(dev, "timeout waiting for Tx RDC.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		apne_reset_8390(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		NS8390_init(dev,1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)     outb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)     ei_status.dmaing &= ~0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) static irqreturn_t apne_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)     unsigned char pcmcia_intreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)     if (!(gayle.inten & GAYLE_IRQ_IRQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)         return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)     pcmcia_intreq = pcmcia_get_intreq();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)     if (!(pcmcia_intreq & GAYLE_IRQ_IRQ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)         pcmcia_ack_int(pcmcia_intreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)         return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)     if (apne_msg_enable & NETIF_MSG_INTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	pr_debug("pcmcia intreq = %x\n", pcmcia_intreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)     pcmcia_disable_irq();			/* to get rid of the sti() within ei_interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)     ei_interrupt(irq, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)     pcmcia_ack_int(pcmcia_get_intreq());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)     pcmcia_enable_irq();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)     return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) #ifdef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static struct net_device *apne_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static int __init apne_module_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	apne_dev = apne_probe(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	return PTR_ERR_OR_ZERO(apne_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static void __exit apne_module_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	unregister_netdev(apne_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	pcmcia_disable_irq();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	free_irq(IRQ_AMIGA_PORTS, apne_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	pcmcia_reset();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	release_region(IOBASE, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	free_netdev(apne_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) module_init(apne_module_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) module_exit(apne_module_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static int init_pcmcia(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	u_char config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) #ifndef MANUAL_CONFIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	u_char tuple[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	int offset_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	u_long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	pcmcia_reset();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	pcmcia_program_voltage(PCMCIA_0V);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	pcmcia_access_speed(PCMCIA_SPEED_250NS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	pcmcia_write_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) #ifdef MANUAL_CONFIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	config = MANUAL_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	/* get and write config byte to enable IO port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	if (pcmcia_copy_tuple(CISTPL_CFTABLE_ENTRY, tuple, 32) < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	config = tuple[2] & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) #ifdef MANUAL_OFFSET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	offset = MANUAL_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	if (pcmcia_copy_tuple(CISTPL_CONFIG, tuple, 32) < 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	offset_len = (tuple[2] & 0x3) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	while(offset_len--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 		offset = (offset << 8) | tuple[4+offset_len];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	out_8(GAYLE_ATTRIBUTE+offset, config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) MODULE_LICENSE("GPL");