| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  *	Digi RightSwitch SE-X loadable device driver for Linux | 
 | 3 |  * | 
 | 4 |  *	The RightSwitch is a 4 (EISA) or 6 (PCI) port etherswitch and | 
 | 5 |  *	a NIC on an internal board. | 
 | 6 |  * | 
 | 7 |  *	Author: Rick Richardson, rick@remotepoint.com | 
 | 8 |  *	Derived from the SVR4.2 (UnixWare) driver for the same card. | 
 | 9 |  * | 
 | 10 |  *	Copyright 1995-1996 Digi International Inc. | 
 | 11 |  * | 
 | 12 |  *	This software may be used and distributed according to the terms | 
 | 13 |  *	of the GNU General Public License, incorporated herein by reference. | 
 | 14 |  * | 
 | 15 |  *	For information on purchasing a RightSwitch SE-4 or SE-6 | 
 | 16 |  *	board, please contact Digi's sales department at 1-612-912-3444 | 
 | 17 |  *	or 1-800-DIGIBRD.  Outside the U.S., please check our Web page | 
 | 18 |  *	at http://www.dgii.com for sales offices worldwide. | 
 | 19 |  * | 
 | 20 |  *	OPERATION: | 
 | 21 |  *	When compiled as a loadable module, this driver can operate | 
 | 22 |  *	the board as either a 4/6 port switch with a 5th or 7th port | 
 | 23 |  *	that is a conventional NIC interface as far as the host is | 
 | 24 |  *	concerned, OR as 4/6 independent NICs.  To select multi-NIC | 
 | 25 |  *	mode, add "nicmode=1" on the insmod load line for the driver. | 
 | 26 |  * | 
 | 27 |  *	This driver uses the "dev" common ethernet device structure | 
 | 28 |  *	and a private "priv" (dev->priv) structure that contains | 
 | 29 |  *	mostly DGRS-specific information and statistics.  To keep | 
 | 30 |  *	the code for both the switch mode and the multi-NIC mode | 
 | 31 |  *	as similar as possible, I have introduced the concept of | 
 | 32 |  *	"dev0"/"priv0" and "devN"/"privN"  pointer pairs in subroutines | 
 | 33 |  *	where needed.  The first pair of pointers points to the | 
 | 34 |  *	"dev" and "priv" structures of the zeroth (0th) device | 
 | 35 |  *	interface associated with a board.  The second pair of | 
 | 36 |  *	pointers points to the current (Nth) device interface | 
 | 37 |  *	for the board: the one for which we are processing data. | 
 | 38 |  * | 
 | 39 |  *	In switch mode, the pairs of pointers are always the same, | 
 | 40 |  *	that is, dev0 == devN and priv0 == privN.  This is just | 
 | 41 |  *	like previous releases of this driver which did not support | 
 | 42 |  *	NIC mode. | 
 | 43 |  * | 
 | 44 |  *	In multi-NIC mode, the pairs of pointers may be different. | 
 | 45 |  *	We use the devN and privN pointers to reference just the | 
 | 46 |  *	name, port number, and statistics for the current interface. | 
 | 47 |  *	We use the dev0 and priv0 pointers to access the variables | 
 | 48 |  *	that control access to the board, such as board address | 
 | 49 |  *	and simulated 82596 variables.  This is because there is | 
 | 50 |  *	only one "fake" 82596 that serves as the interface to | 
 | 51 |  *	the board.  We do not want to try to keep the variables | 
 | 52 |  *	associated with this 82596 in sync across all devices. | 
 | 53 |  * | 
 | 54 |  *	This scheme works well.  As you will see, except for | 
 | 55 |  *	initialization, there is very little difference between | 
 | 56 |  *	the two modes as far as this driver is concerned.  On the | 
 | 57 |  *	receive side in NIC mode, the interrupt *always* comes in on | 
 | 58 |  *	the 0th interface (dev0/priv0).  We then figure out which | 
 | 59 |  *	real 82596 port it came in on from looking at the "chan" | 
 | 60 |  *	member that the board firmware adds at the end of each | 
 | 61 |  *	RBD (a.k.a. TBD). We get the channel number like this: | 
 | 62 |  *		int chan = ((I596_RBD *) S2H(cbp->xmit.tbdp))->chan; | 
 | 63 |  * | 
 | 64 |  *	On the transmit side in multi-NIC mode, we specify the | 
 | 65 |  *	output 82596 port by setting the new "dstchan" structure | 
 | 66 |  *	member that is at the end of the RFD, like this: | 
 | 67 |  *		priv0->rfdp->dstchan = privN->chan; | 
 | 68 |  * | 
 | 69 |  *	TODO: | 
 | 70 |  *	- Multi-NIC mode is not yet supported when the driver is linked | 
 | 71 |  *	  into the kernel. | 
 | 72 |  *	- Better handling of multicast addresses. | 
 | 73 |  * | 
 | 74 |  *	Fixes: | 
 | 75 |  *	Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 11/01/2001 | 
 | 76 |  *	- fix dgrs_found_device wrt checking kmalloc return and | 
 | 77 |  *	rollbacking the partial steps of the whole process when | 
 | 78 |  *	one of the devices can't be allocated. Fix SET_MODULE_OWNER | 
 | 79 |  *	on the loop to use devN instead of repeated calls to dev. | 
 | 80 |  * | 
 | 81 |  *	davej <davej@suse.de> - 9/2/2001 | 
 | 82 |  *	- Enable PCI device before reading ioaddr/irq | 
 | 83 |  * | 
 | 84 |  */ | 
 | 85 |  | 
 | 86 | #include <linux/module.h> | 
 | 87 | #include <linux/eisa.h> | 
 | 88 | #include <linux/kernel.h> | 
 | 89 | #include <linux/string.h> | 
 | 90 | #include <linux/delay.h> | 
 | 91 | #include <linux/errno.h> | 
 | 92 | #include <linux/ioport.h> | 
 | 93 | #include <linux/slab.h> | 
 | 94 | #include <linux/interrupt.h> | 
 | 95 | #include <linux/pci.h> | 
 | 96 | #include <linux/init.h> | 
 | 97 | #include <linux/netdevice.h> | 
 | 98 | #include <linux/etherdevice.h> | 
 | 99 | #include <linux/skbuff.h> | 
 | 100 | #include <linux/bitops.h> | 
 | 101 |  | 
 | 102 | #include <asm/io.h> | 
 | 103 | #include <asm/byteorder.h> | 
 | 104 | #include <asm/uaccess.h> | 
 | 105 |  | 
 | 106 | static char version[] __initdata = | 
 | 107 | 	"$Id: dgrs.c,v 1.13 2000/06/06 04:07:00 rick Exp $"; | 
 | 108 |  | 
 | 109 | /* | 
 | 110 |  *	DGRS include files | 
 | 111 |  */ | 
 | 112 | typedef unsigned char uchar; | 
 | 113 | typedef unsigned int bool; | 
 | 114 | #define vol volatile | 
 | 115 |  | 
 | 116 | #include "dgrs.h" | 
 | 117 | #include "dgrs_es4h.h" | 
 | 118 | #include "dgrs_plx9060.h" | 
 | 119 | #include "dgrs_i82596.h" | 
 | 120 | #include "dgrs_ether.h" | 
 | 121 | #include "dgrs_asstruct.h" | 
 | 122 | #include "dgrs_bcomm.h" | 
 | 123 |  | 
 | 124 | #ifdef CONFIG_PCI | 
 | 125 | static struct pci_device_id dgrs_pci_tbl[] = { | 
 | 126 | 	{ SE6_PCI_VENDOR_ID, SE6_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, }, | 
 | 127 | 	{ }			/* Terminating entry */ | 
 | 128 | }; | 
 | 129 | MODULE_DEVICE_TABLE(pci, dgrs_pci_tbl); | 
 | 130 | #endif | 
 | 131 |  | 
 | 132 | #ifdef CONFIG_EISA | 
 | 133 | static struct eisa_device_id dgrs_eisa_tbl[] = { | 
 | 134 | 	{ "DBI0A01" }, | 
 | 135 | 	{ } | 
 | 136 | }; | 
 | 137 | MODULE_DEVICE_TABLE(eisa, dgrs_eisa_tbl); | 
 | 138 | #endif | 
 | 139 |  | 
 | 140 | MODULE_LICENSE("GPL"); | 
 | 141 |  | 
 | 142 |  | 
 | 143 | /* | 
 | 144 |  *	Firmware.  Compiled separately for local compilation, | 
 | 145 |  *	but #included for Linux distribution. | 
 | 146 |  */ | 
 | 147 | #ifndef NOFW | 
 | 148 | 	#include "dgrs_firmware.c" | 
 | 149 | #else | 
 | 150 | 	extern int	dgrs_firmnum; | 
 | 151 | 	extern char	dgrs_firmver[]; | 
 | 152 | 	extern char	dgrs_firmdate[]; | 
 | 153 | 	extern uchar	dgrs_code[]; | 
 | 154 | 	extern int	dgrs_ncode; | 
 | 155 | #endif | 
 | 156 |  | 
 | 157 | /* | 
 | 158 |  *	Linux out*() is backwards from all other operating systems | 
 | 159 |  */ | 
 | 160 | #define	OUTB(ADDR, VAL)	outb(VAL, ADDR) | 
 | 161 | #define	OUTW(ADDR, VAL)	outw(VAL, ADDR) | 
 | 162 | #define	OUTL(ADDR, VAL)	outl(VAL, ADDR) | 
 | 163 |  | 
 | 164 | /* | 
 | 165 |  *	Macros to convert switch to host and host to switch addresses | 
 | 166 |  *	(assumes a local variable priv points to board dependent struct) | 
 | 167 |  */ | 
 | 168 | #define	S2H(A)	( ((unsigned long)(A)&0x00ffffff) + priv0->vmem ) | 
 | 169 | #define	S2HN(A)	( ((unsigned long)(A)&0x00ffffff) + privN->vmem ) | 
 | 170 | #define	H2S(A)	( ((char *) (A) - priv0->vmem) + 0xA3000000 ) | 
 | 171 |  | 
 | 172 | /* | 
 | 173 |  *	Convert a switch address to a "safe" address for use with the | 
 | 174 |  *	PLX 9060 DMA registers and the associated HW kludge that allows | 
 | 175 |  *	for host access of the DMA registers. | 
 | 176 |  */ | 
 | 177 | #define	S2DMA(A)	( (unsigned long)(A) & 0x00ffffff) | 
 | 178 |  | 
 | 179 | /* | 
 | 180 |  *	"Space.c" variables, now settable from module interface | 
 | 181 |  *	Use the name below, minus the "dgrs_" prefix.  See init_module(). | 
 | 182 |  */ | 
 | 183 | static int	dgrs_debug = 1; | 
 | 184 | static int	dgrs_dma = 1; | 
 | 185 | static int	dgrs_spantree = -1; | 
 | 186 | static int	dgrs_hashexpire = -1; | 
 | 187 | static uchar	dgrs_ipaddr[4] = { 0xff, 0xff, 0xff, 0xff}; | 
 | 188 | static uchar	dgrs_iptrap[4] = { 0xff, 0xff, 0xff, 0xff}; | 
 | 189 | static __u32	dgrs_ipxnet = -1; | 
 | 190 | static int	dgrs_nicmode; | 
 | 191 |  | 
 | 192 | /* | 
 | 193 |  *	Private per-board data structure (dev->priv) | 
 | 194 |  */ | 
 | 195 | typedef struct | 
 | 196 | { | 
 | 197 | 	/* | 
 | 198 | 	 *	Stuff for generic ethercard I/F | 
 | 199 | 	 */ | 
 | 200 | 	struct net_device_stats	stats; | 
 | 201 |  | 
 | 202 | 	/* | 
 | 203 | 	 *	DGRS specific data | 
 | 204 | 	 */ | 
 | 205 | 	char		*vmem; | 
 | 206 |  | 
 | 207 |         struct bios_comm *bcomm;        /* Firmware BIOS comm structure */ | 
 | 208 |         PORT            *port;          /* Ptr to PORT[0] struct in VM */ | 
 | 209 |         I596_SCB        *scbp;          /* Ptr to SCB struct in VM */ | 
 | 210 |         I596_RFD        *rfdp;          /* Current RFD list */ | 
 | 211 |         I596_RBD        *rbdp;          /* Current RBD list */ | 
 | 212 |  | 
 | 213 |         volatile int    intrcnt;        /* Count of interrupts */ | 
 | 214 |  | 
 | 215 |         /* | 
 | 216 |          *      SE-4 (EISA) board variables | 
 | 217 |          */ | 
 | 218 |         uchar		is_reg;		/* EISA: Value for ES4H_IS reg */ | 
 | 219 |  | 
 | 220 |         /* | 
 | 221 |          *      SE-6 (PCI) board variables | 
 | 222 |          * | 
 | 223 |          *      The PLX "expansion rom" space is used for DMA register | 
 | 224 |          *      access from the host on the SE-6.  These are the physical | 
 | 225 |          *      and virtual addresses of that space. | 
 | 226 |          */ | 
 | 227 |         ulong		plxreg;		/* Phys address of PLX chip */ | 
 | 228 |         char            *vplxreg;	/* Virtual address of PLX chip */ | 
 | 229 |         ulong		plxdma;		/* Phys addr of PLX "expansion rom" */ | 
 | 230 |         ulong volatile  *vplxdma;	/* Virtual addr of "expansion rom" */ | 
 | 231 |         int             use_dma;        /* Flag: use DMA */ | 
 | 232 | 	DMACHAIN	*dmadesc_s;	/* area for DMA chains (SW addr.) */ | 
 | 233 | 	DMACHAIN	*dmadesc_h;	/* area for DMA chains (Host Virtual) */ | 
 | 234 |  | 
 | 235 | 	/* | 
 | 236 | 	 *	Multi-NIC mode variables | 
 | 237 | 	 * | 
 | 238 | 	 *	All entries of the devtbl[] array are valid for the 0th | 
 | 239 | 	 *	device (i.e. eth0, but not eth1...eth5).  devtbl[0] is | 
 | 240 | 	 *	valid for all devices (i.e. eth0, eth1, ..., eth5). | 
 | 241 | 	 */ | 
 | 242 | 	int		nports;		/* Number of physical ports (4 or 6) */ | 
 | 243 | 	int		chan;		/* Channel # (1-6) for this device */ | 
 | 244 | 	struct net_device	*devtbl[6];	/* Ptrs to N device structs */ | 
 | 245 |  | 
 | 246 | } DGRS_PRIV; | 
 | 247 |  | 
 | 248 |  | 
 | 249 | /* | 
 | 250 |  *	reset or un-reset the IDT processor | 
 | 251 |  */ | 
 | 252 | static void | 
 | 253 | proc_reset(struct net_device *dev0, int reset) | 
 | 254 | { | 
 | 255 | 	DGRS_PRIV	*priv0 = (DGRS_PRIV *) dev0->priv; | 
 | 256 |  | 
 | 257 | 	if (priv0->plxreg) | 
 | 258 | 	{ | 
 | 259 | 		ulong		val; | 
 | 260 | 		val = inl(dev0->base_addr + PLX_MISC_CSR); | 
 | 261 | 		if (reset) | 
 | 262 | 			val |= SE6_RESET; | 
 | 263 | 		else | 
 | 264 | 			val &= ~SE6_RESET; | 
 | 265 | 		OUTL(dev0->base_addr + PLX_MISC_CSR, val); | 
 | 266 | 	} | 
 | 267 | 	else | 
 | 268 | 	{ | 
 | 269 | 		OUTB(dev0->base_addr + ES4H_PC, reset ? ES4H_PC_RESET : 0); | 
 | 270 | 	} | 
 | 271 | } | 
 | 272 |  | 
 | 273 | /* | 
 | 274 |  *	See if the board supports bus master DMA | 
 | 275 |  */ | 
 | 276 | static int | 
 | 277 | check_board_dma(struct net_device *dev0) | 
 | 278 | { | 
 | 279 | 	DGRS_PRIV	*priv0 = (DGRS_PRIV *) dev0->priv; | 
 | 280 | 	ulong	x; | 
 | 281 |  | 
 | 282 | 	/* | 
 | 283 | 	 *	If Space.c says not to use DMA, or if it's not a PLX based | 
 | 284 | 	 *	PCI board, or if the expansion ROM space is not PCI | 
 | 285 | 	 *	configured, then return false. | 
 | 286 | 	 */ | 
 | 287 | 	if (!dgrs_dma || !priv0->plxreg || !priv0->plxdma) | 
 | 288 | 		return (0); | 
 | 289 |  | 
 | 290 | 	/* | 
 | 291 | 	 *	Set the local address remap register of the "expansion rom" | 
 | 292 | 	 *	area to 0x80000000 so that we can use it to access the DMA | 
 | 293 | 	 *	registers from the host side. | 
 | 294 | 	 */ | 
 | 295 | 	OUTL(dev0->base_addr + PLX_ROM_BASE_ADDR, 0x80000000); | 
 | 296 |  | 
 | 297 | 	/* | 
 | 298 | 	 * Set the PCI region descriptor to: | 
 | 299 | 	 *      Space 0: | 
 | 300 | 	 *              disable read-prefetch | 
 | 301 | 	 *              enable READY | 
 | 302 | 	 *              enable BURST | 
 | 303 | 	 *              0 internal wait states | 
 | 304 | 	 *      Expansion ROM: (used for host DMA register access) | 
 | 305 | 	 *              disable read-prefetch | 
 | 306 | 	 *              enable READY | 
 | 307 | 	 *              disable BURST | 
 | 308 | 	 *              0 internal wait states | 
 | 309 | 	 */ | 
 | 310 | 	OUTL(dev0->base_addr + PLX_BUS_REGION, 0x49430343); | 
 | 311 |  | 
 | 312 | 	/* | 
 | 313 | 	 *	Now map the DMA registers into our virtual space | 
 | 314 | 	 */ | 
 | 315 | 	priv0->vplxdma = (ulong *) ioremap (priv0->plxdma, 256); | 
 | 316 | 	if (!priv0->vplxdma) | 
 | 317 | 	{ | 
 | 318 | 		printk("%s: can't *remap() the DMA regs\n", dev0->name); | 
 | 319 | 		return (0); | 
 | 320 | 	} | 
 | 321 |  | 
 | 322 | 	/* | 
 | 323 | 	 *	Now test to see if we can access the DMA registers | 
 | 324 | 	 *	If we write -1 and get back 1FFF, then we accessed the | 
 | 325 | 	 *	DMA register.  Otherwise, we probably have an old board | 
 | 326 | 	 *	and wrote into regular RAM. | 
 | 327 | 	 */ | 
 | 328 | 	priv0->vplxdma[PLX_DMA0_MODE/4] = 0xFFFFFFFF; | 
 | 329 | 	x = priv0->vplxdma[PLX_DMA0_MODE/4]; | 
 | 330 | 	if (x != 0x00001FFF) { | 
 | 331 | 		iounmap((void *)priv0->vplxdma); | 
 | 332 | 		return (0); | 
 | 333 | 	} | 
 | 334 |  | 
 | 335 | 	return (1); | 
 | 336 | } | 
 | 337 |  | 
 | 338 | /* | 
 | 339 |  *	Initiate DMA using PLX part on PCI board.  Spin the | 
 | 340 |  *	processor until completed.  All addresses are physical! | 
 | 341 |  * | 
 | 342 |  *	If pciaddr is NULL, then it's a chaining DMA, and lcladdr is | 
 | 343 |  *	the address of the first DMA descriptor in the chain. | 
 | 344 |  * | 
 | 345 |  *	If pciaddr is not NULL, then it's a single DMA. | 
 | 346 |  * | 
 | 347 |  *	In either case, "lcladdr" must have been fixed up to make | 
 | 348 |  *	sure the MSB isn't set using the S2DMA macro before passing | 
 | 349 |  *	the address to this routine. | 
 | 350 |  */ | 
 | 351 | static int | 
 | 352 | do_plx_dma( | 
 | 353 | 	struct net_device *dev, | 
 | 354 | 	ulong pciaddr, | 
 | 355 | 	ulong lcladdr, | 
 | 356 | 	int len, | 
 | 357 | 	int to_host | 
 | 358 | ) | 
 | 359 | { | 
 | 360 |         int     	i; | 
 | 361 |         ulong   	csr = 0; | 
 | 362 | 	DGRS_PRIV	*priv = (DGRS_PRIV *) dev->priv; | 
 | 363 |  | 
 | 364 | 	if (pciaddr) | 
 | 365 | 	{ | 
 | 366 | 		/* | 
 | 367 | 		 *	Do a single, non-chain DMA | 
 | 368 | 		 */ | 
 | 369 | 		priv->vplxdma[PLX_DMA0_PCI_ADDR/4] = pciaddr; | 
 | 370 | 		priv->vplxdma[PLX_DMA0_LCL_ADDR/4] = lcladdr; | 
 | 371 | 		priv->vplxdma[PLX_DMA0_SIZE/4] = len; | 
 | 372 | 		priv->vplxdma[PLX_DMA0_DESCRIPTOR/4] = to_host | 
 | 373 | 					? PLX_DMA_DESC_TO_HOST | 
 | 374 | 					: PLX_DMA_DESC_TO_BOARD; | 
 | 375 | 		priv->vplxdma[PLX_DMA0_MODE/4] = | 
 | 376 | 					  PLX_DMA_MODE_WIDTH32 | 
 | 377 | 					| PLX_DMA_MODE_WAITSTATES(0) | 
 | 378 | 					| PLX_DMA_MODE_READY | 
 | 379 | 					| PLX_DMA_MODE_NOBTERM | 
 | 380 | 					| PLX_DMA_MODE_BURST | 
 | 381 | 					| PLX_DMA_MODE_NOCHAIN; | 
 | 382 | 	} | 
 | 383 | 	else | 
 | 384 | 	{ | 
 | 385 | 		/* | 
 | 386 | 		 *	Do a chaining DMA | 
 | 387 | 		 */ | 
 | 388 | 		priv->vplxdma[PLX_DMA0_MODE/4] = | 
 | 389 | 					  PLX_DMA_MODE_WIDTH32 | 
 | 390 | 					| PLX_DMA_MODE_WAITSTATES(0) | 
 | 391 | 					| PLX_DMA_MODE_READY | 
 | 392 | 					| PLX_DMA_MODE_NOBTERM | 
 | 393 | 					| PLX_DMA_MODE_BURST | 
 | 394 | 					| PLX_DMA_MODE_CHAIN; | 
 | 395 | 		priv->vplxdma[PLX_DMA0_DESCRIPTOR/4] = lcladdr; | 
 | 396 | 	} | 
 | 397 |  | 
 | 398 | 	priv->vplxdma[PLX_DMA_CSR/4] = | 
 | 399 | 				PLX_DMA_CSR_0_ENABLE | PLX_DMA_CSR_0_START; | 
 | 400 |  | 
 | 401 |         /* | 
 | 402 | 	 *	Wait for DMA to complete | 
 | 403 | 	 */ | 
 | 404 |         for (i = 0; i < 1000000; ++i) | 
 | 405 |         { | 
 | 406 | 		/* | 
 | 407 | 		 *	Spin the host CPU for 1 usec, so we don't thrash | 
 | 408 | 		 *	the PCI bus while the PLX 9060 is doing DMA. | 
 | 409 | 		 */ | 
 | 410 | 		udelay(1); | 
 | 411 |  | 
 | 412 | 		csr = (volatile unsigned long) priv->vplxdma[PLX_DMA_CSR/4]; | 
 | 413 |  | 
 | 414 |                 if (csr & PLX_DMA_CSR_0_DONE) | 
 | 415 |                         break; | 
 | 416 |         } | 
 | 417 |  | 
 | 418 |         if ( ! (csr & PLX_DMA_CSR_0_DONE) ) | 
 | 419 |         { | 
 | 420 | 		printk("%s: DMA done never occurred. DMA disabled.\n", | 
 | 421 | 			dev->name); | 
 | 422 | 		priv->use_dma = 0; | 
 | 423 |                 return 1; | 
 | 424 |         } | 
 | 425 |         return 0; | 
 | 426 | } | 
 | 427 |  | 
 | 428 | /* | 
 | 429 |  *	dgrs_rcv_frame() | 
 | 430 |  * | 
 | 431 |  *	Process a received frame.  This is called from the interrupt | 
 | 432 |  *	routine, and works for both switch mode and multi-NIC mode. | 
 | 433 |  * | 
 | 434 |  *	Note that when in multi-NIC mode, we want to always access the | 
 | 435 |  *	hardware using the dev and priv structures of the first port, | 
 | 436 |  *	so that we are using only one set of variables to maintain | 
 | 437 |  *	the board interface status, but we want to use the Nth port | 
 | 438 |  *	dev and priv structures to maintain statistics and to pass | 
 | 439 |  *	the packet up. | 
 | 440 |  * | 
 | 441 |  *	Only the first device structure is attached to the interrupt. | 
 | 442 |  *	We use the special "chan" variable at the end of the first RBD | 
 | 443 |  *	to select the Nth device in multi-NIC mode. | 
 | 444 |  * | 
 | 445 |  *	We currently do chained DMA on a per-packet basis when the | 
 | 446 |  *	packet is "long", and we spin the CPU a short time polling | 
 | 447 |  *	for DMA completion.  This avoids a second interrupt overhead, | 
 | 448 |  *	and gives the best performance for light traffic to the host. | 
 | 449 |  * | 
 | 450 |  *	However, a better scheme that could be implemented would be | 
 | 451 |  *	to see how many packets are outstanding for the host, and if | 
 | 452 |  *	the number is "large", create a long chain to DMA several | 
 | 453 |  *	packets into the host in one go.  In this case, we would set | 
 | 454 |  *	up some state variables to let the host CPU continue doing | 
 | 455 |  *	other things until a DMA completion interrupt comes along. | 
 | 456 |  */ | 
 | 457 | static void | 
 | 458 | dgrs_rcv_frame( | 
 | 459 | 	struct net_device	*dev0, | 
 | 460 | 	DGRS_PRIV	*priv0, | 
 | 461 | 	I596_CB		*cbp | 
 | 462 | ) | 
 | 463 | { | 
 | 464 | 	int		len; | 
 | 465 | 	I596_TBD	*tbdp; | 
 | 466 | 	struct sk_buff	*skb; | 
 | 467 | 	uchar		*putp; | 
 | 468 | 	uchar		*p; | 
 | 469 | 	struct net_device	*devN; | 
 | 470 | 	DGRS_PRIV	*privN; | 
 | 471 |  | 
 | 472 | 	/* | 
 | 473 | 	 *	Determine Nth priv and dev structure pointers | 
 | 474 | 	 */ | 
 | 475 | 	if (dgrs_nicmode) | 
 | 476 | 	{	/* Multi-NIC mode */ | 
 | 477 | 		int chan = ((I596_RBD *) S2H(cbp->xmit.tbdp))->chan; | 
 | 478 |  | 
 | 479 | 		devN = priv0->devtbl[chan-1]; | 
 | 480 | 		/* | 
 | 481 | 		 * If devN is null, we got an interrupt before the I/F | 
 | 482 | 		 * has been initialized.  Pitch the packet. | 
 | 483 | 		 */ | 
 | 484 | 		if (devN == NULL) | 
 | 485 | 			goto out; | 
 | 486 | 		privN = (DGRS_PRIV *) devN->priv; | 
 | 487 | 	} | 
 | 488 | 	else | 
 | 489 | 	{	/* Switch mode */ | 
 | 490 | 		devN = dev0; | 
 | 491 | 		privN = priv0; | 
 | 492 | 	} | 
 | 493 |  | 
 | 494 | 	if (0) printk("%s: rcv len=%ld\n", devN->name, cbp->xmit.count); | 
 | 495 |  | 
 | 496 | 	/* | 
 | 497 | 	 *	Allocate a message block big enough to hold the whole frame | 
 | 498 | 	 */ | 
 | 499 | 	len = cbp->xmit.count; | 
 | 500 | 	if ((skb = dev_alloc_skb(len+5)) == NULL) | 
 | 501 | 	{ | 
 | 502 | 		printk("%s: dev_alloc_skb failed for rcv buffer\n", devN->name); | 
 | 503 | 		++privN->stats.rx_dropped; | 
 | 504 | 		/* discarding the frame */ | 
 | 505 | 		goto out; | 
 | 506 | 	} | 
 | 507 | 	skb->dev = devN; | 
 | 508 | 	skb_reserve(skb, 2);	/* Align IP header */ | 
 | 509 |  | 
 | 510 | again: | 
 | 511 | 	putp = p = skb_put(skb, len); | 
 | 512 |  | 
 | 513 | 	/* | 
 | 514 | 	 *	There are three modes here for doing the packet copy. | 
 | 515 | 	 *	If we have DMA, and the packet is "long", we use the | 
 | 516 | 	 *	chaining mode of DMA.  If it's shorter, we use single | 
 | 517 | 	 *	DMA's.  Otherwise, we use memcpy(). | 
 | 518 | 	 */ | 
 | 519 | 	if (priv0->use_dma && priv0->dmadesc_h && len > 64) | 
 | 520 | 	{ | 
 | 521 | 		/* | 
 | 522 | 		 *	If we can use DMA and it's a long frame, copy it using | 
 | 523 | 		 *	DMA chaining. | 
 | 524 | 		 */ | 
 | 525 | 		DMACHAIN	*ddp_h;	/* Host virtual DMA desc. pointer */ | 
 | 526 | 		DMACHAIN	*ddp_s;	/* Switch physical DMA desc. pointer */ | 
 | 527 | 		uchar		*phys_p; | 
 | 528 |  | 
 | 529 | 		/* | 
 | 530 | 		 *	Get the physical address of the STREAMS buffer. | 
 | 531 | 		 *	NOTE: allocb() guarantees that the whole buffer | 
 | 532 | 		 *	is in a single page if the length < 4096. | 
 | 533 | 		 */ | 
 | 534 | 		phys_p = (uchar *) virt_to_phys(putp); | 
 | 535 |  | 
 | 536 | 		ddp_h = priv0->dmadesc_h; | 
 | 537 | 		ddp_s = priv0->dmadesc_s; | 
 | 538 | 		tbdp = (I596_TBD *) S2H(cbp->xmit.tbdp); | 
 | 539 | 		for (;;) | 
 | 540 | 		{ | 
 | 541 | 			int	count; | 
 | 542 | 			int	amt; | 
 | 543 |  | 
 | 544 | 			count = tbdp->count; | 
 | 545 | 			amt = count & 0x3fff; | 
 | 546 | 			if (amt == 0) | 
 | 547 | 				break; /* For safety */ | 
 | 548 | 			if ( (p-putp) >= len) | 
 | 549 | 			{ | 
 | 550 | 				printk("%s: cbp = %lx\n", devN->name, (long) H2S(cbp)); | 
 | 551 | 				proc_reset(dev0, 1);	/* Freeze IDT */ | 
 | 552 | 				break; /* For Safety */ | 
 | 553 | 			} | 
 | 554 |  | 
 | 555 | 			ddp_h->pciaddr = (ulong) phys_p; | 
 | 556 | 			ddp_h->lcladdr = S2DMA(tbdp->buf); | 
 | 557 | 			ddp_h->len = amt; | 
 | 558 |  | 
 | 559 | 			phys_p += amt; | 
 | 560 | 			p += amt; | 
 | 561 |  | 
 | 562 | 			if (count & I596_TBD_EOF) | 
 | 563 | 			{ | 
 | 564 | 				ddp_h->next = PLX_DMA_DESC_TO_HOST | 
 | 565 | 						| PLX_DMA_DESC_EOC; | 
 | 566 | 				++ddp_h; | 
 | 567 | 				break; | 
 | 568 | 			} | 
 | 569 | 			else | 
 | 570 | 			{ | 
 | 571 | 				++ddp_s; | 
 | 572 | 				ddp_h->next = PLX_DMA_DESC_TO_HOST | 
 | 573 | 						| (ulong) ddp_s; | 
 | 574 | 				tbdp = (I596_TBD *) S2H(tbdp->next); | 
 | 575 | 				++ddp_h; | 
 | 576 | 			} | 
 | 577 | 		} | 
 | 578 | 		if (ddp_h - priv0->dmadesc_h) | 
 | 579 | 		{ | 
 | 580 | 			int	rc; | 
 | 581 |  | 
 | 582 | 			rc = do_plx_dma(dev0, | 
 | 583 | 				0, (ulong) priv0->dmadesc_s, len, 0); | 
 | 584 | 			if (rc) | 
 | 585 | 			{ | 
 | 586 | 				printk("%s: Chained DMA failure\n", devN->name); | 
 | 587 | 				goto again; | 
 | 588 | 			} | 
 | 589 | 		} | 
 | 590 | 	} | 
 | 591 | 	else if (priv0->use_dma) | 
 | 592 | 	{ | 
 | 593 | 		/* | 
 | 594 | 		 *	If we can use DMA and it's a shorter frame, copy it | 
 | 595 | 		 *	using single DMA transfers. | 
 | 596 | 		 */ | 
 | 597 | 		uchar		*phys_p; | 
 | 598 |  | 
 | 599 | 		/* | 
 | 600 | 		 *	Get the physical address of the STREAMS buffer. | 
 | 601 | 		 *	NOTE: allocb() guarantees that the whole buffer | 
 | 602 | 		 *	is in a single page if the length < 4096. | 
 | 603 | 		 */ | 
 | 604 | 		phys_p = (uchar *) virt_to_phys(putp); | 
 | 605 |  | 
 | 606 | 		tbdp = (I596_TBD *) S2H(cbp->xmit.tbdp); | 
 | 607 | 		for (;;) | 
 | 608 | 		{ | 
 | 609 | 			int	count; | 
 | 610 | 			int	amt; | 
 | 611 | 			int	rc; | 
 | 612 |  | 
 | 613 | 			count = tbdp->count; | 
 | 614 | 			amt = count & 0x3fff; | 
 | 615 | 			if (amt == 0) | 
 | 616 | 				break; /* For safety */ | 
 | 617 | 			if ( (p-putp) >= len) | 
 | 618 | 			{ | 
 | 619 | 				printk("%s: cbp = %lx\n", devN->name, (long) H2S(cbp)); | 
 | 620 | 				proc_reset(dev0, 1);	/* Freeze IDT */ | 
 | 621 | 				break; /* For Safety */ | 
 | 622 | 			} | 
 | 623 | 			rc = do_plx_dma(dev0, (ulong) phys_p, | 
 | 624 | 						S2DMA(tbdp->buf), amt, 1); | 
 | 625 | 			if (rc) | 
 | 626 | 			{ | 
 | 627 | 				memcpy(p, S2H(tbdp->buf), amt); | 
 | 628 | 				printk("%s: Single DMA failed\n", devN->name); | 
 | 629 | 			} | 
 | 630 | 			phys_p += amt; | 
 | 631 | 			p += amt; | 
 | 632 | 			if (count & I596_TBD_EOF) | 
 | 633 | 				break; | 
 | 634 | 			tbdp = (I596_TBD *) S2H(tbdp->next); | 
 | 635 | 		} | 
 | 636 | 	} | 
 | 637 | 	else | 
 | 638 | 	{ | 
 | 639 | 		/* | 
 | 640 | 		 *	Otherwise, copy it piece by piece using memcpy() | 
 | 641 | 		 */ | 
 | 642 | 		tbdp = (I596_TBD *) S2H(cbp->xmit.tbdp); | 
 | 643 | 		for (;;) | 
 | 644 | 		{ | 
 | 645 | 			int	count; | 
 | 646 | 			int	amt; | 
 | 647 |  | 
 | 648 | 			count = tbdp->count; | 
 | 649 | 			amt = count & 0x3fff; | 
 | 650 | 			if (amt == 0) | 
 | 651 | 				break; /* For safety */ | 
 | 652 | 			if ( (p-putp) >= len) | 
 | 653 | 			{ | 
 | 654 | 				printk("%s: cbp = %lx\n", devN->name, (long) H2S(cbp)); | 
 | 655 | 				proc_reset(dev0, 1);	/* Freeze IDT */ | 
 | 656 | 				break; /* For Safety */ | 
 | 657 | 			} | 
 | 658 | 			memcpy(p, S2H(tbdp->buf), amt); | 
 | 659 | 			p += amt; | 
 | 660 | 			if (count & I596_TBD_EOF) | 
 | 661 | 				break; | 
 | 662 | 			tbdp = (I596_TBD *) S2H(tbdp->next); | 
 | 663 | 		} | 
 | 664 | 	} | 
 | 665 |  | 
 | 666 | 	/* | 
 | 667 | 	 *	Pass the frame to upper half | 
 | 668 | 	 */ | 
 | 669 | 	skb->protocol = eth_type_trans(skb, devN); | 
 | 670 | 	netif_rx(skb); | 
 | 671 | 	devN->last_rx = jiffies; | 
 | 672 | 	++privN->stats.rx_packets; | 
 | 673 | 	privN->stats.rx_bytes += len; | 
 | 674 |  | 
 | 675 | out: | 
 | 676 | 	cbp->xmit.status = I596_CB_STATUS_C | I596_CB_STATUS_OK; | 
 | 677 | } | 
 | 678 |  | 
 | 679 | /* | 
 | 680 |  *	Start transmission of a frame | 
 | 681 |  * | 
 | 682 |  *	The interface to the board is simple: we pretend that we are | 
 | 683 |  *	a fifth 82596 ethernet controller 'receiving' data, and copy the | 
 | 684 |  *	data into the same structures that a real 82596 would.  This way, | 
 | 685 |  *	the board firmware handles the host 'port' the same as any other. | 
 | 686 |  * | 
 | 687 |  *	NOTE: we do not use Bus master DMA for this routine.  Turns out | 
 | 688 |  *	that it is not needed.  Slave writes over the PCI bus are about | 
 | 689 |  *	as fast as DMA, due to the fact that the PLX part can do burst | 
 | 690 |  *	writes.  The same is not true for data being read from the board. | 
 | 691 |  * | 
 | 692 |  *	For multi-NIC mode, we tell the firmware the desired 82596 | 
 | 693 |  *	output port by setting the special "dstchan" member at the | 
 | 694 |  *	end of the traditional 82596 RFD structure. | 
 | 695 |  */ | 
 | 696 |  | 
 | 697 | static int dgrs_start_xmit(struct sk_buff *skb, struct net_device *devN) | 
 | 698 | { | 
 | 699 | 	DGRS_PRIV	*privN = (DGRS_PRIV *) devN->priv; | 
 | 700 | 	struct net_device	*dev0; | 
 | 701 | 	DGRS_PRIV	*priv0; | 
 | 702 | 	I596_RBD	*rbdp; | 
 | 703 | 	int		count; | 
 | 704 | 	int		i, len, amt; | 
 | 705 |  | 
 | 706 | 	/* | 
 | 707 | 	 *	Determine 0th priv and dev structure pointers | 
 | 708 | 	 */ | 
 | 709 | 	if (dgrs_nicmode) | 
 | 710 | 	{ | 
 | 711 | 		dev0 = privN->devtbl[0]; | 
 | 712 | 		priv0 = (DGRS_PRIV *) dev0->priv; | 
 | 713 | 	} | 
 | 714 | 	else | 
 | 715 | 	{ | 
 | 716 | 		dev0 = devN; | 
 | 717 | 		priv0 = privN; | 
 | 718 | 	} | 
 | 719 |  | 
 | 720 | 	if (dgrs_debug > 1) | 
 | 721 | 		printk("%s: xmit len=%d\n", devN->name, (int) skb->len); | 
 | 722 |  | 
 | 723 | 	devN->trans_start = jiffies; | 
 | 724 | 	netif_start_queue(devN); | 
 | 725 |  | 
 | 726 | 	if (priv0->rfdp->cmd & I596_RFD_EL) | 
 | 727 | 	{	/* Out of RFD's */ | 
 | 728 | 		if (0) printk("%s: NO RFD's\n", devN->name); | 
 | 729 | 		goto no_resources; | 
 | 730 | 	} | 
 | 731 |  | 
 | 732 | 	rbdp = priv0->rbdp; | 
 | 733 | 	count = 0; | 
 | 734 | 	priv0->rfdp->rbdp = (I596_RBD *) H2S(rbdp); | 
 | 735 |  | 
 | 736 | 	i = 0; len = skb->len; | 
 | 737 | 	for (;;) | 
 | 738 | 	{ | 
 | 739 | 		if (rbdp->size & I596_RBD_EL) | 
 | 740 | 		{	/* Out of RBD's */ | 
 | 741 | 			if (0) printk("%s: NO RBD's\n", devN->name); | 
 | 742 | 			goto no_resources; | 
 | 743 | 		} | 
 | 744 |  | 
 | 745 | 		amt = min_t(unsigned int, len, rbdp->size - count); | 
 | 746 | 		memcpy( (char *) S2H(rbdp->buf) + count, skb->data + i, amt); | 
 | 747 | 		i += amt; | 
 | 748 | 		count += amt; | 
 | 749 | 		len -= amt; | 
 | 750 | 		if (len == 0) | 
 | 751 | 		{ | 
 | 752 | 			if (skb->len < 60) | 
 | 753 | 				rbdp->count = 60 | I596_RBD_EOF; | 
 | 754 | 			else | 
 | 755 | 				rbdp->count = count | I596_RBD_EOF; | 
 | 756 | 			rbdp = (I596_RBD *) S2H(rbdp->next); | 
 | 757 | 			goto frame_done; | 
 | 758 | 		} | 
 | 759 | 		else if (count < 32) | 
 | 760 | 		{ | 
 | 761 | 			/* More data to come, but we used less than 32 | 
 | 762 | 			 * bytes of this RBD.  Keep filling this RBD. | 
 | 763 | 			 */ | 
 | 764 | 			{}	/* Yes, we do nothing here */ | 
 | 765 | 		} | 
 | 766 | 		else | 
 | 767 | 		{ | 
 | 768 | 			rbdp->count = count; | 
 | 769 | 			rbdp = (I596_RBD *) S2H(rbdp->next); | 
 | 770 | 			count = 0; | 
 | 771 | 		} | 
 | 772 | 	} | 
 | 773 |  | 
 | 774 | frame_done: | 
 | 775 | 	priv0->rbdp = rbdp; | 
 | 776 | 	if (dgrs_nicmode) | 
 | 777 | 		priv0->rfdp->dstchan = privN->chan; | 
 | 778 | 	priv0->rfdp->status = I596_RFD_C | I596_RFD_OK; | 
 | 779 | 	priv0->rfdp = (I596_RFD *) S2H(priv0->rfdp->next); | 
 | 780 |  | 
 | 781 | 	++privN->stats.tx_packets; | 
 | 782 |  | 
 | 783 | 	dev_kfree_skb (skb); | 
 | 784 | 	return (0); | 
 | 785 |  | 
 | 786 | no_resources: | 
 | 787 | 	priv0->scbp->status |= I596_SCB_RNR;	/* simulate I82596 */ | 
 | 788 | 	return (-EAGAIN); | 
 | 789 | } | 
 | 790 |  | 
 | 791 | /* | 
 | 792 |  *	Open the interface | 
 | 793 |  */ | 
 | 794 | static int | 
 | 795 | dgrs_open( struct net_device *dev ) | 
 | 796 | { | 
 | 797 | 	netif_start_queue(dev); | 
 | 798 | 	return (0); | 
 | 799 | } | 
 | 800 |  | 
 | 801 | /* | 
 | 802 |  *	Close the interface | 
 | 803 |  */ | 
 | 804 | static int dgrs_close( struct net_device *dev ) | 
 | 805 | { | 
 | 806 | 	netif_stop_queue(dev); | 
 | 807 | 	return (0); | 
 | 808 | } | 
 | 809 |  | 
 | 810 | /* | 
 | 811 |  *	Get statistics | 
 | 812 |  */ | 
 | 813 | static struct net_device_stats *dgrs_get_stats( struct net_device *dev ) | 
 | 814 | { | 
 | 815 | 	DGRS_PRIV	*priv = (DGRS_PRIV *) dev->priv; | 
 | 816 |  | 
 | 817 | 	return (&priv->stats); | 
 | 818 | } | 
 | 819 |  | 
 | 820 | /* | 
 | 821 |  *	Set multicast list and/or promiscuous mode | 
 | 822 |  */ | 
 | 823 |  | 
 | 824 | static void dgrs_set_multicast_list( struct net_device *dev) | 
 | 825 | { | 
 | 826 | 	DGRS_PRIV	*priv = (DGRS_PRIV *) dev->priv; | 
 | 827 |  | 
 | 828 | 	priv->port->is_promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; | 
 | 829 | } | 
 | 830 |  | 
 | 831 | /* | 
 | 832 |  *	Unique ioctl's | 
 | 833 |  */ | 
 | 834 | static int dgrs_ioctl(struct net_device *devN, struct ifreq *ifr, int cmd) | 
 | 835 | { | 
 | 836 | 	DGRS_PRIV	*privN = (DGRS_PRIV *) devN->priv; | 
 | 837 | 	DGRS_IOCTL	ioc; | 
 | 838 | 	int		i; | 
 | 839 |  | 
 | 840 | 	if (cmd != DGRSIOCTL) | 
 | 841 | 		return -EINVAL; | 
 | 842 |  | 
 | 843 | 	if(copy_from_user(&ioc, ifr->ifr_data, sizeof(DGRS_IOCTL))) | 
 | 844 | 		return -EFAULT; | 
 | 845 |  | 
 | 846 | 	switch (ioc.cmd) | 
 | 847 | 	{ | 
 | 848 | 		case DGRS_GETMEM: | 
 | 849 | 			if (ioc.len != sizeof(ulong)) | 
 | 850 | 				return -EINVAL; | 
 | 851 | 			if(copy_to_user(ioc.data, &devN->mem_start, ioc.len)) | 
 | 852 | 				return -EFAULT; | 
 | 853 | 			return (0); | 
 | 854 | 		case DGRS_SETFILTER: | 
 | 855 | 			if (!capable(CAP_NET_ADMIN)) | 
 | 856 | 				return -EPERM; | 
 | 857 | 			if (ioc.port > privN->bcomm->bc_nports) | 
 | 858 | 				return -EINVAL; | 
 | 859 | 			if (ioc.filter >= NFILTERS) | 
 | 860 | 				return -EINVAL; | 
 | 861 | 			if (ioc.len > privN->bcomm->bc_filter_area_len) | 
 | 862 | 				return -EINVAL; | 
 | 863 |  | 
 | 864 | 			/* Wait for old command to finish */ | 
 | 865 | 			for (i = 0; i < 1000; ++i) | 
 | 866 | 			{ | 
 | 867 | 				if ( (volatile long) privN->bcomm->bc_filter_cmd <= 0 ) | 
 | 868 | 					break; | 
 | 869 | 				udelay(1); | 
 | 870 | 			} | 
 | 871 | 			if (i >= 1000) | 
 | 872 | 				return -EIO; | 
 | 873 |  | 
 | 874 | 			privN->bcomm->bc_filter_port = ioc.port; | 
 | 875 | 			privN->bcomm->bc_filter_num = ioc.filter; | 
 | 876 | 			privN->bcomm->bc_filter_len = ioc.len; | 
 | 877 | 	 | 
 | 878 | 			if (ioc.len) | 
 | 879 | 			{ | 
 | 880 | 				if(copy_from_user(S2HN(privN->bcomm->bc_filter_area), | 
 | 881 | 					ioc.data, ioc.len)) | 
 | 882 | 					return -EFAULT; | 
 | 883 | 				privN->bcomm->bc_filter_cmd = BC_FILTER_SET; | 
 | 884 | 			} | 
 | 885 | 			else | 
 | 886 | 				privN->bcomm->bc_filter_cmd = BC_FILTER_CLR; | 
 | 887 | 			return(0); | 
 | 888 | 		default: | 
 | 889 | 			return -EOPNOTSUPP; | 
 | 890 | 	} | 
 | 891 | } | 
 | 892 |  | 
 | 893 | /* | 
 | 894 |  *	Process interrupts | 
 | 895 |  * | 
 | 896 |  *	dev, priv will always refer to the 0th device in Multi-NIC mode. | 
 | 897 |  */ | 
 | 898 |  | 
 | 899 | static irqreturn_t dgrs_intr(int irq, void *dev_id, struct pt_regs *regs) | 
 | 900 | { | 
 | 901 | 	struct net_device	*dev0 = (struct net_device *) dev_id; | 
 | 902 | 	DGRS_PRIV	*priv0 = (DGRS_PRIV *) dev0->priv; | 
 | 903 | 	I596_CB		*cbp; | 
 | 904 | 	int		cmd; | 
 | 905 | 	int		i; | 
 | 906 |  | 
 | 907 | 	++priv0->intrcnt; | 
 | 908 | 	if (1) ++priv0->bcomm->bc_cnt[4]; | 
 | 909 | 	if (0) | 
 | 910 | 	{ | 
 | 911 | 		static int cnt = 100; | 
 | 912 | 		if (--cnt > 0) | 
 | 913 | 		printk("%s: interrupt: irq %d\n", dev0->name, irq); | 
 | 914 | 	} | 
 | 915 |  | 
 | 916 | 	/* | 
 | 917 | 	 *	Get 596 command | 
 | 918 | 	 */ | 
 | 919 | 	cmd = priv0->scbp->cmd; | 
 | 920 |  | 
 | 921 | 	/* | 
 | 922 | 	 *	See if RU has been restarted | 
 | 923 | 	 */ | 
 | 924 | 	if ( (cmd & I596_SCB_RUC) == I596_SCB_RUC_START) | 
 | 925 | 	{ | 
 | 926 | 		if (0) printk("%s: RUC start\n", dev0->name); | 
 | 927 | 		priv0->rfdp = (I596_RFD *) S2H(priv0->scbp->rfdp); | 
 | 928 | 		priv0->rbdp = (I596_RBD *) S2H(priv0->rfdp->rbdp); | 
 | 929 | 		priv0->scbp->status &= ~(I596_SCB_RNR|I596_SCB_RUS); | 
 | 930 | 		/* | 
 | 931 | 		 * Tell upper half (halves) | 
 | 932 | 		 */ | 
 | 933 | 		if (dgrs_nicmode) | 
 | 934 | 		{ | 
 | 935 | 			for (i = 0; i < priv0->nports; ++i) | 
 | 936 | 				netif_wake_queue (priv0->devtbl[i]); | 
 | 937 | 		} | 
 | 938 | 		else | 
 | 939 | 			netif_wake_queue (dev0); | 
 | 940 | 		/* if (bd->flags & TX_QUEUED) | 
 | 941 | 			DL_sched(bd, bdd); */ | 
 | 942 | 	} | 
 | 943 |  | 
 | 944 | 	/* | 
 | 945 | 	 *	See if any CU commands to process | 
 | 946 | 	 */ | 
 | 947 | 	if ( (cmd & I596_SCB_CUC) != I596_SCB_CUC_START) | 
 | 948 | 	{ | 
 | 949 | 		priv0->scbp->cmd = 0;	/* Ignore all other commands */ | 
 | 950 | 		goto ack_intr; | 
 | 951 | 	} | 
 | 952 | 	priv0->scbp->status &= ~(I596_SCB_CNA|I596_SCB_CUS); | 
 | 953 |  | 
 | 954 | 	/* | 
 | 955 | 	 *	Process a command | 
 | 956 | 	 */ | 
 | 957 | 	cbp = (I596_CB *) S2H(priv0->scbp->cbp); | 
 | 958 | 	priv0->scbp->cmd = 0;	/* Safe to clear the command */ | 
 | 959 | 	for (;;) | 
 | 960 | 	{ | 
 | 961 | 		switch (cbp->nop.cmd & I596_CB_CMD) | 
 | 962 | 		{ | 
 | 963 | 		case I596_CB_CMD_XMIT: | 
 | 964 | 			dgrs_rcv_frame(dev0, priv0, cbp); | 
 | 965 | 			break; | 
 | 966 | 		default: | 
 | 967 | 			cbp->nop.status = I596_CB_STATUS_C | I596_CB_STATUS_OK; | 
 | 968 | 			break; | 
 | 969 | 		} | 
 | 970 | 		if (cbp->nop.cmd & I596_CB_CMD_EL) | 
 | 971 | 			break; | 
 | 972 | 		cbp = (I596_CB *) S2H(cbp->nop.next); | 
 | 973 | 	} | 
 | 974 | 	priv0->scbp->status |= I596_SCB_CNA; | 
 | 975 |  | 
 | 976 | 	/* | 
 | 977 | 	 * Ack the interrupt | 
 | 978 | 	 */ | 
 | 979 | ack_intr: | 
 | 980 | 	if (priv0->plxreg) | 
 | 981 | 		OUTL(dev0->base_addr + PLX_LCL2PCI_DOORBELL, 1); | 
 | 982 |  | 
 | 983 | 	return IRQ_HANDLED; | 
 | 984 | } | 
 | 985 |  | 
 | 986 | /* | 
 | 987 |  *	Download the board firmware | 
 | 988 |  */ | 
 | 989 | static int __init  | 
 | 990 | dgrs_download(struct net_device *dev0) | 
 | 991 | { | 
 | 992 | 	DGRS_PRIV	*priv0 = (DGRS_PRIV *) dev0->priv; | 
 | 993 | 	int		is; | 
 | 994 | 	unsigned long	i; | 
 | 995 |  | 
 | 996 | 	static int	iv2is[16] = { | 
 | 997 | 				0, 0, 0, ES4H_IS_INT3, | 
 | 998 | 				0, ES4H_IS_INT5, 0, ES4H_IS_INT7, | 
 | 999 | 				0, 0, ES4H_IS_INT10, ES4H_IS_INT11, | 
 | 1000 | 				ES4H_IS_INT12, 0, 0, ES4H_IS_INT15 }; | 
 | 1001 |  | 
 | 1002 | 	/* | 
 | 1003 | 	 * Map in the dual port memory | 
 | 1004 | 	 */ | 
 | 1005 | 	priv0->vmem = ioremap(dev0->mem_start, 2048*1024); | 
 | 1006 | 	if (!priv0->vmem) | 
 | 1007 | 	{ | 
 | 1008 | 		printk("%s: cannot map in board memory\n", dev0->name); | 
 | 1009 | 		return -ENXIO; | 
 | 1010 | 	} | 
 | 1011 |  | 
 | 1012 | 	/* | 
 | 1013 | 	 *	Hold the processor and configure the board addresses | 
 | 1014 | 	 */ | 
 | 1015 | 	if (priv0->plxreg) | 
 | 1016 | 	{	/* PCI bus */ | 
 | 1017 | 		proc_reset(dev0, 1); | 
 | 1018 | 	} | 
 | 1019 | 	else | 
 | 1020 | 	{	/* EISA bus */ | 
 | 1021 | 		is = iv2is[dev0->irq & 0x0f]; | 
 | 1022 | 		if (!is) | 
 | 1023 | 		{ | 
 | 1024 | 			printk("%s: Illegal IRQ %d\n", dev0->name, dev0->irq); | 
 | 1025 | 			iounmap(priv0->vmem); | 
 | 1026 | 			priv0->vmem = NULL; | 
 | 1027 | 			return -ENXIO; | 
 | 1028 | 		} | 
 | 1029 | 		OUTB(dev0->base_addr + ES4H_AS_31_24, | 
 | 1030 | 			(uchar) (dev0->mem_start >> 24) ); | 
 | 1031 | 		OUTB(dev0->base_addr + ES4H_AS_23_16, | 
 | 1032 | 			(uchar) (dev0->mem_start >> 16) ); | 
 | 1033 | 		priv0->is_reg = ES4H_IS_LINEAR | is | | 
 | 1034 | 			((uchar) (dev0->mem_start >> 8) & ES4H_IS_AS15); | 
 | 1035 | 		OUTB(dev0->base_addr + ES4H_IS, priv0->is_reg); | 
 | 1036 | 		OUTB(dev0->base_addr + ES4H_EC, ES4H_EC_ENABLE); | 
 | 1037 | 		OUTB(dev0->base_addr + ES4H_PC, ES4H_PC_RESET); | 
 | 1038 | 		OUTB(dev0->base_addr + ES4H_MW, ES4H_MW_ENABLE | 0x00); | 
 | 1039 | 	} | 
 | 1040 |  | 
 | 1041 | 	/* | 
 | 1042 | 	 *	See if we can do DMA on the SE-6 | 
 | 1043 | 	 */ | 
 | 1044 | 	priv0->use_dma = check_board_dma(dev0); | 
 | 1045 | 	if (priv0->use_dma) | 
 | 1046 | 		printk("%s: Bus Master DMA is enabled.\n", dev0->name); | 
 | 1047 |  | 
 | 1048 | 	/* | 
 | 1049 | 	 * Load and verify the code at the desired address | 
 | 1050 | 	 */ | 
 | 1051 | 	memcpy(priv0->vmem, dgrs_code, dgrs_ncode);	/* Load code */ | 
 | 1052 | 	if (memcmp(priv0->vmem, dgrs_code, dgrs_ncode)) | 
 | 1053 | 	{ | 
 | 1054 | 		iounmap(priv0->vmem); | 
 | 1055 | 		priv0->vmem = NULL; | 
 | 1056 | 		printk("%s: download compare failed\n", dev0->name); | 
 | 1057 | 		return -ENXIO; | 
 | 1058 | 	} | 
 | 1059 |  | 
 | 1060 | 	/* | 
 | 1061 | 	 * Configurables | 
 | 1062 | 	 */ | 
 | 1063 | 	priv0->bcomm = (struct bios_comm *) (priv0->vmem + 0x0100); | 
 | 1064 | 	priv0->bcomm->bc_nowait = 1;	/* Tell board to make printf not wait */ | 
 | 1065 | 	priv0->bcomm->bc_squelch = 0;	/* Flag from Space.c */ | 
 | 1066 | 	priv0->bcomm->bc_150ohm = 0;	/* Flag from Space.c */ | 
 | 1067 |  | 
 | 1068 | 	priv0->bcomm->bc_spew = 0;	/* Debug flag from Space.c */ | 
 | 1069 | 	priv0->bcomm->bc_maxrfd = 0;	/* Debug flag from Space.c */ | 
 | 1070 | 	priv0->bcomm->bc_maxrbd = 0;	/* Debug flag from Space.c */ | 
 | 1071 |  | 
 | 1072 | 	/* | 
 | 1073 | 	 * Tell board we are operating in switch mode (1) or in | 
 | 1074 | 	 * multi-NIC mode (2). | 
 | 1075 | 	 */ | 
 | 1076 | 	priv0->bcomm->bc_host = dgrs_nicmode ? BC_MULTINIC : BC_SWITCH; | 
 | 1077 |  | 
 | 1078 | 	/* | 
 | 1079 | 	 * Request memory space on board for DMA chains | 
 | 1080 | 	 */ | 
 | 1081 | 	if (priv0->use_dma) | 
 | 1082 | 		priv0->bcomm->bc_hostarea_len = (2048/64) * 16; | 
 | 1083 |  | 
 | 1084 | 	/* | 
 | 1085 | 	 * NVRAM configurables from Space.c | 
 | 1086 | 	 */ | 
 | 1087 | 	priv0->bcomm->bc_spantree = dgrs_spantree; | 
 | 1088 | 	priv0->bcomm->bc_hashexpire = dgrs_hashexpire; | 
 | 1089 | 	memcpy(priv0->bcomm->bc_ipaddr, dgrs_ipaddr, 4); | 
 | 1090 | 	memcpy(priv0->bcomm->bc_iptrap, dgrs_iptrap, 4); | 
 | 1091 | 	memcpy(priv0->bcomm->bc_ipxnet, &dgrs_ipxnet, 4); | 
 | 1092 |  | 
 | 1093 | 	/* | 
 | 1094 | 	 * Release processor, wait 8 seconds for board to initialize | 
 | 1095 | 	 */ | 
 | 1096 | 	proc_reset(dev0, 0); | 
 | 1097 |  | 
 | 1098 | 	for (i = jiffies + 8 * HZ; time_after(i, jiffies); ) | 
 | 1099 | 	{ | 
 | 1100 | 		barrier();		/* Gcc 2.95 needs this */ | 
 | 1101 | 		if (priv0->bcomm->bc_status >= BC_RUN) | 
 | 1102 | 			break; | 
 | 1103 | 	} | 
 | 1104 |  | 
 | 1105 | 	if (priv0->bcomm->bc_status < BC_RUN) | 
 | 1106 | 	{ | 
 | 1107 | 		printk("%s: board not operating\n", dev0->name); | 
 | 1108 | 		iounmap(priv0->vmem); | 
 | 1109 | 		priv0->vmem = NULL; | 
 | 1110 | 		return -ENXIO; | 
 | 1111 | 	} | 
 | 1112 |  | 
 | 1113 | 	priv0->port = (PORT *) S2H(priv0->bcomm->bc_port); | 
 | 1114 | 	priv0->scbp = (I596_SCB *) S2H(priv0->port->scbp); | 
 | 1115 | 	priv0->rfdp = (I596_RFD *) S2H(priv0->scbp->rfdp); | 
 | 1116 | 	priv0->rbdp = (I596_RBD *) S2H(priv0->rfdp->rbdp); | 
 | 1117 |  | 
 | 1118 | 	priv0->scbp->status = I596_SCB_CNA;	/* CU is idle */ | 
 | 1119 |  | 
 | 1120 | 	/* | 
 | 1121 | 	 *	Get switch physical and host virtual pointers to DMA | 
 | 1122 | 	 *	chaining area.  NOTE: the MSB of the switch physical | 
 | 1123 | 	 *	address *must* be turned off.  Otherwise, the HW kludge | 
 | 1124 | 	 *	that allows host access of the PLX DMA registers will | 
 | 1125 | 	 *	erroneously select the PLX registers. | 
 | 1126 | 	 */ | 
 | 1127 | 	priv0->dmadesc_s = (DMACHAIN *) S2DMA(priv0->bcomm->bc_hostarea); | 
 | 1128 | 	if (priv0->dmadesc_s) | 
 | 1129 | 		priv0->dmadesc_h = (DMACHAIN *) S2H(priv0->dmadesc_s); | 
 | 1130 | 	else | 
 | 1131 | 		priv0->dmadesc_h = NULL; | 
 | 1132 |  | 
 | 1133 | 	/* | 
 | 1134 | 	 *	Enable board interrupts | 
 | 1135 | 	 */ | 
 | 1136 | 	if (priv0->plxreg) | 
 | 1137 | 	{	/* PCI bus */ | 
 | 1138 | 		OUTL(dev0->base_addr + PLX_INT_CSR, | 
 | 1139 | 			inl(dev0->base_addr + PLX_INT_CSR) | 
 | 1140 | 			| PLX_PCI_DOORBELL_IE);	/* Enable intr to host */ | 
 | 1141 | 		OUTL(dev0->base_addr + PLX_LCL2PCI_DOORBELL, 1); | 
 | 1142 | 	} | 
 | 1143 | 	else | 
 | 1144 | 	{	/* EISA bus */ | 
 | 1145 | 	} | 
 | 1146 |  | 
 | 1147 | 	return (0); | 
 | 1148 | } | 
 | 1149 |  | 
 | 1150 | /* | 
 | 1151 |  *	Probe (init) a board | 
 | 1152 |  */ | 
 | 1153 | static int __init  | 
 | 1154 | dgrs_probe1(struct net_device *dev) | 
 | 1155 | { | 
 | 1156 | 	DGRS_PRIV	*priv = (DGRS_PRIV *) dev->priv; | 
 | 1157 | 	unsigned long	i; | 
 | 1158 | 	int		rc; | 
 | 1159 |  | 
 | 1160 | 	printk("%s: Digi RightSwitch io=%lx mem=%lx irq=%d plx=%lx dma=%lx\n", | 
 | 1161 | 		dev->name, dev->base_addr, dev->mem_start, dev->irq, | 
 | 1162 | 		priv->plxreg, priv->plxdma); | 
 | 1163 |  | 
 | 1164 | 	/* | 
 | 1165 | 	 *	Download the firmware and light the processor | 
 | 1166 | 	 */ | 
 | 1167 | 	rc = dgrs_download(dev); | 
 | 1168 | 	if (rc) | 
 | 1169 | 		goto err_out; | 
 | 1170 |  | 
 | 1171 | 	/* | 
 | 1172 | 	 * Get ether address of board | 
 | 1173 | 	 */ | 
 | 1174 | 	printk("%s: Ethernet address", dev->name); | 
 | 1175 | 	memcpy(dev->dev_addr, priv->port->ethaddr, 6); | 
 | 1176 | 	for (i = 0; i < 6; ++i) | 
 | 1177 | 		printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]); | 
 | 1178 | 	printk("\n"); | 
 | 1179 |  | 
 | 1180 | 	if (dev->dev_addr[0] & 1) | 
 | 1181 | 	{ | 
 | 1182 | 		printk("%s: Illegal Ethernet Address\n", dev->name); | 
 | 1183 | 		rc = -ENXIO; | 
 | 1184 | 		goto err_out; | 
 | 1185 | 	} | 
 | 1186 |  | 
 | 1187 | 	/* | 
 | 1188 | 	 *	ACK outstanding interrupts, hook the interrupt, | 
 | 1189 | 	 *	and verify that we are getting interrupts from the board. | 
 | 1190 | 	 */ | 
 | 1191 | 	if (priv->plxreg) | 
 | 1192 | 		OUTL(dev->base_addr + PLX_LCL2PCI_DOORBELL, 1); | 
 | 1193 | 	 | 
 | 1194 | 	rc = request_irq(dev->irq, &dgrs_intr, SA_SHIRQ, "RightSwitch", dev); | 
 | 1195 | 	if (rc) | 
 | 1196 | 		goto err_out; | 
 | 1197 |  | 
 | 1198 | 	priv->intrcnt = 0; | 
 | 1199 | 	for (i = jiffies + 2*HZ + HZ/2; time_after(i, jiffies); ) | 
 | 1200 | 	{ | 
 | 1201 | 		cpu_relax(); | 
 | 1202 | 		if (priv->intrcnt >= 2) | 
 | 1203 | 			break; | 
 | 1204 | 	} | 
 | 1205 | 	if (priv->intrcnt < 2) | 
 | 1206 | 	{ | 
 | 1207 | 		printk(KERN_ERR "%s: Not interrupting on IRQ %d (%d)\n", | 
 | 1208 | 				dev->name, dev->irq, priv->intrcnt); | 
 | 1209 | 		rc = -ENXIO; | 
 | 1210 | 		goto err_free_irq; | 
 | 1211 | 	} | 
 | 1212 |  | 
 | 1213 | 	/* | 
 | 1214 | 	 *	Entry points... | 
 | 1215 | 	 */ | 
 | 1216 | 	dev->open = &dgrs_open; | 
 | 1217 | 	dev->stop = &dgrs_close; | 
 | 1218 | 	dev->get_stats = &dgrs_get_stats; | 
 | 1219 | 	dev->hard_start_xmit = &dgrs_start_xmit; | 
 | 1220 | 	dev->set_multicast_list = &dgrs_set_multicast_list; | 
 | 1221 | 	dev->do_ioctl = &dgrs_ioctl; | 
 | 1222 |  | 
 | 1223 | 	return rc; | 
 | 1224 |  | 
 | 1225 | err_free_irq: | 
 | 1226 | 	free_irq(dev->irq, dev); | 
 | 1227 | err_out: | 
 | 1228 |        	return rc; | 
 | 1229 | } | 
 | 1230 |  | 
 | 1231 | static int __init  | 
 | 1232 | dgrs_initclone(struct net_device *dev) | 
 | 1233 | { | 
 | 1234 | 	DGRS_PRIV	*priv = (DGRS_PRIV *) dev->priv; | 
 | 1235 | 	int		i; | 
 | 1236 |  | 
 | 1237 | 	printk("%s: Digi RightSwitch port %d ", | 
 | 1238 | 		dev->name, priv->chan); | 
 | 1239 | 	for (i = 0; i < 6; ++i) | 
 | 1240 | 		printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]); | 
 | 1241 | 	printk("\n"); | 
 | 1242 |  | 
 | 1243 | 	return (0); | 
 | 1244 | } | 
 | 1245 |  | 
 | 1246 | static struct net_device * __init  | 
 | 1247 | dgrs_found_device( | 
 | 1248 | 	int		io, | 
 | 1249 | 	ulong		mem, | 
 | 1250 | 	int		irq, | 
 | 1251 | 	ulong		plxreg, | 
 | 1252 | 	ulong		plxdma, | 
 | 1253 | 	struct device   *pdev | 
 | 1254 | ) | 
 | 1255 | { | 
 | 1256 | 	DGRS_PRIV *priv; | 
 | 1257 | 	struct net_device *dev; | 
 | 1258 | 	int i, ret = -ENOMEM; | 
 | 1259 |  | 
 | 1260 | 	dev = alloc_etherdev(sizeof(DGRS_PRIV)); | 
 | 1261 | 	if (!dev) | 
 | 1262 | 		goto err0; | 
 | 1263 |  | 
 | 1264 | 	priv = (DGRS_PRIV *)dev->priv; | 
 | 1265 |  | 
 | 1266 | 	dev->base_addr = io; | 
 | 1267 | 	dev->mem_start = mem; | 
 | 1268 | 	dev->mem_end = mem + 2048 * 1024 - 1; | 
 | 1269 | 	dev->irq = irq; | 
 | 1270 | 	priv->plxreg = plxreg; | 
 | 1271 | 	priv->plxdma = plxdma; | 
 | 1272 | 	priv->vplxdma = NULL; | 
 | 1273 |  | 
 | 1274 | 	priv->chan = 1; | 
 | 1275 | 	priv->devtbl[0] = dev; | 
 | 1276 |  | 
 | 1277 | 	SET_MODULE_OWNER(dev); | 
 | 1278 | 	SET_NETDEV_DEV(dev, pdev); | 
 | 1279 | 	 | 
 | 1280 | 	ret = dgrs_probe1(dev); | 
 | 1281 | 	if (ret)  | 
 | 1282 | 		goto err1; | 
 | 1283 |  | 
 | 1284 | 	ret = register_netdev(dev); | 
 | 1285 | 	if (ret) | 
 | 1286 | 		goto err2; | 
 | 1287 |  | 
 | 1288 | 	if ( !dgrs_nicmode ) | 
 | 1289 | 		return dev;	/* Switch mode, we are done */ | 
 | 1290 |  | 
 | 1291 | 	/* | 
 | 1292 | 	 * Operating card as N separate NICs | 
 | 1293 | 	 */ | 
 | 1294 |  | 
 | 1295 | 	priv->nports = priv->bcomm->bc_nports; | 
 | 1296 |  | 
 | 1297 | 	for (i = 1; i < priv->nports; ++i) | 
 | 1298 | 	{ | 
 | 1299 | 		struct net_device	*devN; | 
 | 1300 | 		DGRS_PRIV	*privN; | 
 | 1301 | 			/* Allocate new dev and priv structures */ | 
 | 1302 | 		devN = alloc_etherdev(sizeof(DGRS_PRIV)); | 
 | 1303 | 		ret = -ENOMEM; | 
 | 1304 | 		if (!devN)  | 
 | 1305 | 			goto fail; | 
 | 1306 |  | 
 | 1307 | 		/* Don't copy the network device structure! */ | 
 | 1308 |  | 
 | 1309 | 		/* copy the priv structure of dev[0] */ | 
 | 1310 | 		privN = (DGRS_PRIV *)devN->priv; | 
 | 1311 | 		*privN = *priv; | 
 | 1312 |  | 
 | 1313 | 			/* ... and zero out VM areas */ | 
 | 1314 | 		privN->vmem = NULL; | 
 | 1315 | 		privN->vplxdma = NULL; | 
 | 1316 | 			/* ... and zero out IRQ */ | 
 | 1317 | 		devN->irq = 0; | 
 | 1318 | 			/* ... and base MAC address off address of 1st port */ | 
 | 1319 | 		devN->dev_addr[5] += i; | 
 | 1320 |  | 
 | 1321 | 		ret = dgrs_initclone(devN); | 
 | 1322 | 		if (ret) | 
 | 1323 | 			goto fail; | 
 | 1324 |  | 
 | 1325 | 		SET_MODULE_OWNER(devN); | 
 | 1326 | 		SET_NETDEV_DEV(dev, pdev); | 
 | 1327 |  | 
 | 1328 | 		ret = register_netdev(devN); | 
 | 1329 | 		if (ret) { | 
 | 1330 | 			free_netdev(devN); | 
 | 1331 | 			goto fail; | 
 | 1332 | 		} | 
 | 1333 | 		privN->chan = i+1; | 
 | 1334 | 		priv->devtbl[i] = devN; | 
 | 1335 | 	} | 
 | 1336 | 	return dev; | 
 | 1337 |  | 
 | 1338 |  fail:	 | 
 | 1339 | 	while (i >= 0) { | 
 | 1340 | 		struct net_device *d = priv->devtbl[i--]; | 
 | 1341 | 		unregister_netdev(d); | 
 | 1342 | 		free_netdev(d); | 
 | 1343 | 	} | 
 | 1344 |  | 
 | 1345 |  err2: | 
 | 1346 | 	free_irq(dev->irq, dev); | 
 | 1347 |  err1: | 
 | 1348 | 	free_netdev(dev); | 
 | 1349 |  err0: | 
 | 1350 | 	return ERR_PTR(ret); | 
 | 1351 | } | 
 | 1352 |  | 
 | 1353 | static void __devexit dgrs_remove(struct net_device *dev) | 
 | 1354 | { | 
 | 1355 | 	DGRS_PRIV *priv = dev->priv; | 
 | 1356 | 	int i; | 
 | 1357 |  | 
 | 1358 | 	unregister_netdev(dev); | 
 | 1359 |  | 
 | 1360 | 	for (i = 1; i < priv->nports; ++i) { | 
 | 1361 | 		struct net_device *d = priv->devtbl[i]; | 
 | 1362 | 		if (d) { | 
 | 1363 | 			unregister_netdev(d); | 
 | 1364 | 			free_netdev(d); | 
 | 1365 | 		} | 
 | 1366 | 	} | 
 | 1367 |  | 
 | 1368 | 	proc_reset(priv->devtbl[0], 1); | 
 | 1369 |  | 
 | 1370 | 	if (priv->vmem) | 
 | 1371 | 		iounmap(priv->vmem); | 
 | 1372 | 	if (priv->vplxdma) | 
 | 1373 | 		iounmap((uchar *) priv->vplxdma); | 
 | 1374 |  | 
 | 1375 | 	if (dev->irq) | 
 | 1376 | 		free_irq(dev->irq, dev); | 
 | 1377 |  | 
 | 1378 | 	for (i = 1; i < priv->nports; ++i) { | 
 | 1379 | 		if (priv->devtbl[i]) | 
 | 1380 | 			unregister_netdev(priv->devtbl[i]); | 
 | 1381 | 	} | 
 | 1382 | } | 
 | 1383 |  | 
 | 1384 | #ifdef CONFIG_PCI | 
 | 1385 | static int __init dgrs_pci_probe(struct pci_dev *pdev, | 
 | 1386 | 				 const struct pci_device_id *ent) | 
 | 1387 | { | 
 | 1388 | 	struct net_device *dev; | 
 | 1389 | 	int err; | 
 | 1390 | 	uint	io; | 
 | 1391 | 	uint	mem; | 
 | 1392 | 	uint	irq; | 
 | 1393 | 	uint	plxreg; | 
 | 1394 | 	uint	plxdma; | 
 | 1395 |  | 
 | 1396 | 	/* | 
 | 1397 | 	 * Get and check the bus-master and latency values. | 
 | 1398 | 	 * Some PCI BIOSes fail to set the master-enable bit, | 
 | 1399 | 	 * and the latency timer must be set to the maximum | 
 | 1400 | 	 * value to avoid data corruption that occurs when the | 
 | 1401 | 	 * timer expires during a transfer.  Yes, it's a bug. | 
 | 1402 | 	 */ | 
 | 1403 | 	err = pci_enable_device(pdev); | 
 | 1404 | 	if (err) | 
 | 1405 | 		return err; | 
 | 1406 | 	err = pci_request_regions(pdev, "RightSwitch"); | 
 | 1407 | 	if (err) | 
 | 1408 | 		return err; | 
 | 1409 |  | 
 | 1410 | 	pci_set_master(pdev); | 
 | 1411 |  | 
 | 1412 | 	plxreg = pci_resource_start (pdev, 0); | 
 | 1413 | 	io = pci_resource_start (pdev, 1); | 
 | 1414 | 	mem = pci_resource_start (pdev, 2); | 
 | 1415 | 	pci_read_config_dword(pdev, 0x30, &plxdma); | 
 | 1416 | 	irq = pdev->irq; | 
 | 1417 | 	plxdma &= ~15; | 
 | 1418 |  | 
 | 1419 | 	/* | 
 | 1420 | 	 * On some BIOSES, the PLX "expansion rom" (used for DMA) | 
 | 1421 | 	 * address comes up as "0".  This is probably because | 
 | 1422 | 	 * the BIOS doesn't see a valid 55 AA ROM signature at | 
 | 1423 | 	 * the "ROM" start and zeroes the address.  To get | 
 | 1424 | 	 * around this problem the SE-6 is configured to ask | 
 | 1425 | 	 * for 4 MB of space for the dual port memory.  We then | 
 | 1426 | 	 * must set its range back to 2 MB, and use the upper | 
 | 1427 | 	 * half for DMA register access | 
 | 1428 | 	 */ | 
 | 1429 | 	OUTL(io + PLX_SPACE0_RANGE, 0xFFE00000L); | 
 | 1430 | 	if (plxdma == 0) | 
 | 1431 | 		plxdma = mem + (2048L * 1024L); | 
 | 1432 | 	pci_write_config_dword(pdev, 0x30, plxdma + 1); | 
 | 1433 | 	pci_read_config_dword(pdev, 0x30, &plxdma); | 
 | 1434 | 	plxdma &= ~15; | 
 | 1435 |  | 
 | 1436 | 	dev = dgrs_found_device(io, mem, irq, plxreg, plxdma, &pdev->dev); | 
 | 1437 | 	if (IS_ERR(dev)) { | 
 | 1438 | 		pci_release_regions(pdev); | 
 | 1439 | 		return PTR_ERR(dev); | 
 | 1440 | 	} | 
 | 1441 |  | 
 | 1442 | 	pci_set_drvdata(pdev, dev); | 
 | 1443 | 	return 0; | 
 | 1444 | } | 
 | 1445 |  | 
 | 1446 | static void __devexit dgrs_pci_remove(struct pci_dev *pdev) | 
 | 1447 | { | 
 | 1448 | 	struct net_device *dev = pci_get_drvdata(pdev); | 
 | 1449 |  | 
 | 1450 | 	dgrs_remove(dev); | 
 | 1451 | 	pci_release_regions(pdev); | 
 | 1452 | 	free_netdev(dev); | 
 | 1453 | } | 
 | 1454 |  | 
 | 1455 | static struct pci_driver dgrs_pci_driver = { | 
 | 1456 | 	.name = "dgrs", | 
 | 1457 | 	.id_table = dgrs_pci_tbl, | 
 | 1458 | 	.probe = dgrs_pci_probe, | 
 | 1459 | 	.remove = __devexit_p(dgrs_pci_remove), | 
 | 1460 | }; | 
 | 1461 | #endif | 
 | 1462 |  | 
 | 1463 |  | 
 | 1464 | #ifdef CONFIG_EISA | 
 | 1465 | static int is2iv[8] __initdata = { 0, 3, 5, 7, 10, 11, 12, 15 }; | 
 | 1466 |  | 
 | 1467 | static int __init dgrs_eisa_probe (struct device *gendev) | 
 | 1468 | { | 
 | 1469 | 	struct net_device *dev; | 
 | 1470 | 	struct eisa_device *edev = to_eisa_device(gendev); | 
 | 1471 | 	uint	io = edev->base_addr; | 
 | 1472 | 	uint	mem; | 
 | 1473 | 	uint	irq; | 
 | 1474 | 	int 	rc = -ENODEV; /* Not EISA configured */ | 
 | 1475 |  | 
 | 1476 | 	if (!request_region(io, 256, "RightSwitch")) { | 
 | 1477 | 		printk(KERN_ERR "dgrs: eisa io 0x%x, which is busy.\n", io); | 
 | 1478 | 		return -EBUSY; | 
 | 1479 | 	} | 
 | 1480 |  | 
 | 1481 | 	if ( ! (inb(io+ES4H_EC) & ES4H_EC_ENABLE) )  | 
 | 1482 | 		goto err_out; | 
 | 1483 |  | 
 | 1484 | 	mem = (inb(io+ES4H_AS_31_24) << 24) | 
 | 1485 | 		+ (inb(io+ES4H_AS_23_16) << 16); | 
 | 1486 |  | 
 | 1487 | 	irq = is2iv[ inb(io+ES4H_IS) & ES4H_IS_INTMASK ]; | 
 | 1488 |  | 
 | 1489 | 	dev = dgrs_found_device(io, mem, irq, 0L, 0L, gendev); | 
 | 1490 | 	if (IS_ERR(dev)) { | 
 | 1491 | 		rc = PTR_ERR(dev); | 
 | 1492 | 		goto err_out; | 
 | 1493 | 	} | 
 | 1494 |  | 
 | 1495 | 	gendev->driver_data = dev; | 
 | 1496 | 	return 0; | 
 | 1497 |  err_out: | 
 | 1498 | 	release_region(io, 256); | 
 | 1499 | 	return rc; | 
 | 1500 | } | 
 | 1501 |  | 
 | 1502 | static int __devexit dgrs_eisa_remove(struct device *gendev) | 
 | 1503 | { | 
 | 1504 | 	struct net_device *dev = gendev->driver_data; | 
 | 1505 | 	 | 
 | 1506 | 	dgrs_remove(dev); | 
 | 1507 |  | 
 | 1508 | 	release_region(dev->base_addr, 256); | 
 | 1509 | 		 | 
 | 1510 | 	free_netdev(dev); | 
 | 1511 | 	return 0; | 
 | 1512 | } | 
 | 1513 |  | 
 | 1514 |  | 
 | 1515 | static struct eisa_driver dgrs_eisa_driver = { | 
 | 1516 | 	.id_table = dgrs_eisa_tbl, | 
 | 1517 | 	.driver = { | 
 | 1518 | 		.name = "dgrs", | 
 | 1519 | 		.probe = dgrs_eisa_probe, | 
 | 1520 | 		.remove = __devexit_p(dgrs_eisa_remove), | 
 | 1521 | 	} | 
 | 1522 | }; | 
 | 1523 | #endif | 
 | 1524 |  | 
 | 1525 | /* | 
 | 1526 |  *	Variables that can be overriden from module command line | 
 | 1527 |  */ | 
 | 1528 | static int	debug = -1; | 
 | 1529 | static int	dma = -1; | 
 | 1530 | static int	hashexpire = -1; | 
 | 1531 | static int	spantree = -1; | 
 | 1532 | static int	ipaddr[4] = { -1 }; | 
 | 1533 | static int	iptrap[4] = { -1 }; | 
 | 1534 | static __u32	ipxnet = -1; | 
 | 1535 | static int	nicmode = -1; | 
 | 1536 |  | 
 | 1537 | module_param(debug, int, 0); | 
 | 1538 | module_param(dma, int, 0); | 
 | 1539 | module_param(hashexpire, int, 0); | 
 | 1540 | module_param(spantree, int, 0); | 
 | 1541 | module_param_array(ipaddr, int, NULL, 0); | 
 | 1542 | module_param_array(iptrap, int, NULL, 0); | 
 | 1543 | module_param(ipxnet, int, 0); | 
 | 1544 | module_param(nicmode, int, 0); | 
 | 1545 | MODULE_PARM_DESC(debug, "Digi RightSwitch enable debugging (0-1)"); | 
 | 1546 | MODULE_PARM_DESC(dma, "Digi RightSwitch enable BM DMA (0-1)"); | 
 | 1547 | MODULE_PARM_DESC(nicmode, "Digi RightSwitch operating mode (1: switch, 2: multi-NIC)"); | 
 | 1548 |  | 
 | 1549 | static int __init dgrs_init_module (void) | 
 | 1550 | { | 
 | 1551 | 	int	i; | 
 | 1552 | 	int eisacount = 0, pcicount = 0; | 
 | 1553 |  | 
 | 1554 | 	/* | 
 | 1555 | 	 *	Command line variable overrides | 
 | 1556 | 	 *		debug=NNN | 
 | 1557 | 	 *		dma=0/1 | 
 | 1558 | 	 *		spantree=0/1 | 
 | 1559 | 	 *		hashexpire=NNN | 
 | 1560 | 	 *		ipaddr=A,B,C,D | 
 | 1561 | 	 *		iptrap=A,B,C,D | 
 | 1562 | 	 *		ipxnet=NNN | 
 | 1563 | 	 *		nicmode=NNN | 
 | 1564 | 	 */ | 
 | 1565 | 	if (debug >= 0) | 
 | 1566 | 		dgrs_debug = debug; | 
 | 1567 | 	if (dma >= 0) | 
 | 1568 | 		dgrs_dma = dma; | 
 | 1569 | 	if (nicmode >= 0) | 
 | 1570 | 		dgrs_nicmode = nicmode; | 
 | 1571 | 	if (hashexpire >= 0) | 
 | 1572 | 		dgrs_hashexpire = hashexpire; | 
 | 1573 | 	if (spantree >= 0) | 
 | 1574 | 		dgrs_spantree = spantree; | 
 | 1575 | 	if (ipaddr[0] != -1) | 
 | 1576 | 		for (i = 0; i < 4; ++i) | 
 | 1577 | 			dgrs_ipaddr[i] = ipaddr[i]; | 
 | 1578 | 	if (iptrap[0] != -1) | 
 | 1579 | 		for (i = 0; i < 4; ++i) | 
 | 1580 | 			dgrs_iptrap[i] = iptrap[i]; | 
 | 1581 | 	if (ipxnet != -1) | 
 | 1582 | 		dgrs_ipxnet = htonl( ipxnet ); | 
 | 1583 |  | 
 | 1584 | 	if (dgrs_debug) | 
 | 1585 | 	{ | 
 | 1586 | 		printk(KERN_INFO "dgrs: SW=%s FW=Build %d %s\nFW Version=%s\n", | 
 | 1587 | 		       version, dgrs_firmnum, dgrs_firmdate, dgrs_firmver); | 
 | 1588 | 	} | 
 | 1589 |  | 
 | 1590 | 	/* | 
 | 1591 | 	 *	Find and configure all the cards | 
 | 1592 | 	 */ | 
 | 1593 | #ifdef CONFIG_EISA | 
 | 1594 | 	eisacount = eisa_driver_register(&dgrs_eisa_driver); | 
 | 1595 | 	if (eisacount < 0) | 
 | 1596 | 		return eisacount; | 
 | 1597 | #endif | 
 | 1598 | #ifdef CONFIG_PCI | 
 | 1599 | 	pcicount = pci_register_driver(&dgrs_pci_driver); | 
 | 1600 | 	if (pcicount) | 
 | 1601 | 		return pcicount; | 
 | 1602 | #endif | 
 | 1603 | 	return 0; | 
 | 1604 | } | 
 | 1605 |  | 
 | 1606 | static void __exit dgrs_cleanup_module (void) | 
 | 1607 | { | 
 | 1608 | #ifdef CONFIG_EISA | 
 | 1609 | 	eisa_driver_unregister (&dgrs_eisa_driver); | 
 | 1610 | #endif | 
 | 1611 | #ifdef CONFIG_PCI | 
 | 1612 | 	pci_unregister_driver (&dgrs_pci_driver); | 
 | 1613 | #endif | 
 | 1614 | } | 
 | 1615 |  | 
 | 1616 | module_init(dgrs_init_module); | 
 | 1617 | module_exit(dgrs_cleanup_module); |