1 /* hp-plus.c: A HP PCLAN/plus ethernet driver for linux. */
2 /*
3 	Written 1994 by Donald Becker.
4 
5 	This driver is for the Hewlett Packard PC LAN (27***) plus ethercards.
6 	These cards are sold under several model numbers, usually 2724*.
7 
8 	This software may be used and distributed according to the terms
9 	of the GNU General Public License, incorporated herein by reference.
10 
11 	The author may be reached as becker@scyld.com, or C/O
12 	Scyld Computing Corporation
13 	410 Severn Ave., Suite 210
14 	Annapolis MD 21403
15 
16 	As is often the case, a great deal of credit is owed to Russ Nelson.
17 	The Crynwr packet driver was my primary source of HP-specific
18 	programming information.
19 */
20 
21 static const char version[] =
22 "hp-plus.c:v1.10 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
23 
24 #include <linux/module.h>
25 
26 #include <linux/string.h>		/* Important -- this inlines word moves. */
27 #include <linux/kernel.h>
28 #include <linux/errno.h>
29 #include <linux/ioport.h>
30 #include <linux/netdevice.h>
31 #include <linux/etherdevice.h>
32 #include <linux/init.h>
33 #include <linux/delay.h>
34 
35 #include <asm/system.h>
36 #include <asm/io.h>
37 
38 #include "8390.h"
39 
40 #define DRV_NAME "hp-plus"
41 
42 /* A zero-terminated list of I/O addresses to be probed. */
43 static unsigned int hpplus_portlist[] __initdata =
44 {0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
45 
46 /*
47    The HP EtherTwist chip implementation is a fairly routine DP8390
48    implementation.  It allows both shared memory and programmed-I/O buffer
49    access, using a custom interface for both.  The programmed-I/O mode is
50    entirely implemented in the HP EtherTwist chip, bypassing the problem
51    ridden built-in 8390 facilities used on NE2000 designs.  The shared
52    memory mode is likewise special, with an offset register used to make
53    packets appear at the shared memory base.  Both modes use a base and bounds
54    page register to hide the Rx ring buffer wrap -- a packet that spans the
55    end of physical buffer memory appears continuous to the driver. (c.f. the
56    3c503 and Cabletron E2100)
57 
58    A special note: the internal buffer of the board is only 8 bits wide.
59    This lays several nasty traps for the unaware:
60    - the 8390 must be programmed for byte-wide operations
61    - all I/O and memory operations must work on whole words (the access
62      latches are serially preloaded and have no byte-swapping ability).
63 
64    This board is laid out in I/O space much like the earlier HP boards:
65    the first 16 locations are for the board registers, and the second 16 are
66    for the 8390.  The board is easy to identify, with both a dedicated 16 bit
67    ID register and a constant 0x530* value in the upper bits of the paging
68    register.
69 */
70 
71 #define HP_ID			0x00	/* ID register, always 0x4850. */
72 #define HP_PAGING		0x02	/* Registers visible @ 8-f, see PageName. */
73 #define HPP_OPTION		0x04	/* Bitmapped options, see HP_Option.	*/
74 #define HPP_OUT_ADDR	0x08	/* I/O output location in Perf_Page.	*/
75 #define HPP_IN_ADDR		0x0A	/* I/O input location in Perf_Page.		*/
76 #define HP_DATAPORT		0x0c	/* I/O data transfer in Perf_Page.		*/
77 #define NIC_OFFSET		0x10	/* Offset to the 8390 registers.		*/
78 #define HP_IO_EXTENT	32
79 
80 #define HP_START_PG		0x00	/* First page of TX buffer */
81 #define HP_STOP_PG		0x80	/* Last page +1 of RX ring */
82 
83 /* The register set selected in HP_PAGING. */
84 enum PageName {
85 	Perf_Page = 0,				/* Normal operation. */
86 	MAC_Page = 1,				/* The ethernet address (+checksum). */
87 	HW_Page = 2,				/* EEPROM-loaded hardware parameters. */
88 	LAN_Page = 4,				/* Transceiver selection, testing, etc. */
89 	ID_Page = 6 };
90 
91 /* The bit definitions for the HPP_OPTION register. */
92 enum HP_Option {
93 	NICReset = 1, ChipReset = 2, 	/* Active low, really UNreset. */
94 	EnableIRQ = 4, FakeIntr = 8, BootROMEnb = 0x10, IOEnb = 0x20,
95 	MemEnable = 0x40, ZeroWait = 0x80, MemDisable = 0x1000, };
96 
97 static int hpp_probe1(struct net_device *dev, int ioaddr);
98 
99 static void hpp_reset_8390(struct net_device *dev);
100 static int hpp_open(struct net_device *dev);
101 static int hpp_close(struct net_device *dev);
102 static void hpp_mem_block_input(struct net_device *dev, int count,
103 						  struct sk_buff *skb, int ring_offset);
104 static void hpp_mem_block_output(struct net_device *dev, int count,
105 							const unsigned char *buf, int start_page);
106 static void hpp_mem_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
107 						  int ring_page);
108 static void hpp_io_block_input(struct net_device *dev, int count,
109 						  struct sk_buff *skb, int ring_offset);
110 static void hpp_io_block_output(struct net_device *dev, int count,
111 							const unsigned char *buf, int start_page);
112 static void hpp_io_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
113 						  int ring_page);
114 
115 
116 /*	Probe a list of addresses for an HP LAN+ adaptor.
117 	This routine is almost boilerplate. */
118 
do_hpp_probe(struct net_device * dev)119 static int __init do_hpp_probe(struct net_device *dev)
120 {
121 	int i;
122 	int base_addr = dev->base_addr;
123 	int irq = dev->irq;
124 
125 	if (base_addr > 0x1ff)		/* Check a single specified location. */
126 		return hpp_probe1(dev, base_addr);
127 	else if (base_addr != 0)	/* Don't probe at all. */
128 		return -ENXIO;
129 
130 	for (i = 0; hpplus_portlist[i]; i++) {
131 		if (hpp_probe1(dev, hpplus_portlist[i]) == 0)
132 			return 0;
133 		dev->irq = irq;
134 	}
135 
136 	return -ENODEV;
137 }
138 
139 #ifndef MODULE
hp_plus_probe(int unit)140 struct net_device * __init hp_plus_probe(int unit)
141 {
142 	struct net_device *dev = alloc_eip_netdev();
143 	int err;
144 
145 	if (!dev)
146 		return ERR_PTR(-ENOMEM);
147 
148 	sprintf(dev->name, "eth%d", unit);
149 	netdev_boot_setup_check(dev);
150 
151 	err = do_hpp_probe(dev);
152 	if (err)
153 		goto out;
154 	return dev;
155 out:
156 	free_netdev(dev);
157 	return ERR_PTR(err);
158 }
159 #endif
160 
161 static const struct net_device_ops hpp_netdev_ops = {
162 	.ndo_open		= hpp_open,
163 	.ndo_stop		= hpp_close,
164 	.ndo_start_xmit		= eip_start_xmit,
165 	.ndo_tx_timeout		= eip_tx_timeout,
166 	.ndo_get_stats		= eip_get_stats,
167 	.ndo_set_multicast_list = eip_set_multicast_list,
168 	.ndo_validate_addr	= eth_validate_addr,
169 	.ndo_set_mac_address 	= eth_mac_addr,
170 	.ndo_change_mtu		= eth_change_mtu,
171 #ifdef CONFIG_NET_POLL_CONTROLLER
172 	.ndo_poll_controller	= eip_poll,
173 #endif
174 };
175 
176 
177 /* Do the interesting part of the probe at a single address. */
hpp_probe1(struct net_device * dev,int ioaddr)178 static int __init hpp_probe1(struct net_device *dev, int ioaddr)
179 {
180 	int i, retval;
181 	unsigned char checksum = 0;
182 	const char name[] = "HP-PC-LAN+";
183 	int mem_start;
184 	static unsigned version_printed;
185 
186 	if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME))
187 		return -EBUSY;
188 
189 	/* Check for the HP+ signature, 50 48 0x 53. */
190 	if (inw(ioaddr + HP_ID) != 0x4850 ||
191 	    (inw(ioaddr + HP_PAGING) & 0xfff0) != 0x5300) {
192 		retval = -ENODEV;
193 		goto out;
194 	}
195 
196 	if (ei_debug  &&  version_printed++ == 0)
197 		printk(version);
198 
199 	printk("%s: %s at %#3x, ", dev->name, name, ioaddr);
200 
201 	/* Retrieve and checksum the station address. */
202 	outw(MAC_Page, ioaddr + HP_PAGING);
203 
204 	for(i = 0; i < ETHER_ADDR_LEN; i++) {
205 		unsigned char inval = inb(ioaddr + 8 + i);
206 		dev->dev_addr[i] = inval;
207 		checksum += inval;
208 	}
209 	checksum += inb(ioaddr + 14);
210 
211 	printk("%pM", dev->dev_addr);
212 
213 	if (checksum != 0xff) {
214 		printk(" bad checksum %2.2x.\n", checksum);
215 		retval = -ENODEV;
216 		goto out;
217 	} else {
218 		/* Point at the Software Configuration Flags. */
219 		outw(ID_Page, ioaddr + HP_PAGING);
220 		printk(" ID %4.4x", inw(ioaddr + 12));
221 	}
222 
223 	/* Read the IRQ line. */
224 	outw(HW_Page, ioaddr + HP_PAGING);
225 	{
226 		int irq = inb(ioaddr + 13) & 0x0f;
227 		int option = inw(ioaddr + HPP_OPTION);
228 
229 		dev->irq = irq;
230 		if (option & MemEnable) {
231 			mem_start = inw(ioaddr + 9) << 8;
232 			printk(", IRQ %d, memory address %#x.\n", irq, mem_start);
233 		} else {
234 			mem_start = 0;
235 			printk(", IRQ %d, programmed-I/O mode.\n", irq);
236 		}
237 	}
238 
239 	/* Set the wrap registers for string I/O reads.   */
240 	outw((HP_START_PG + TX_PAGES/2) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
241 
242 	/* Set the base address to point to the NIC, not the "real" base! */
243 	dev->base_addr = ioaddr + NIC_OFFSET;
244 
245 	dev->netdev_ops = &hpp_netdev_ops;
246 
247 	ei_status.name = name;
248 	ei_status.word16 = 0;		/* Agggghhhhh! Debug time: 2 days! */
249 	ei_status.tx_start_page = HP_START_PG;
250 	ei_status.rx_start_page = HP_START_PG + TX_PAGES/2;
251 	ei_status.stop_page = HP_STOP_PG;
252 
253 	ei_status.reset_8390 = &hpp_reset_8390;
254 	ei_status.block_input = &hpp_io_block_input;
255 	ei_status.block_output = &hpp_io_block_output;
256 	ei_status.get_8390_hdr = &hpp_io_get_8390_hdr;
257 
258 	/* Check if the memory_enable flag is set in the option register. */
259 	if (mem_start) {
260 		ei_status.block_input = &hpp_mem_block_input;
261 		ei_status.block_output = &hpp_mem_block_output;
262 		ei_status.get_8390_hdr = &hpp_mem_get_8390_hdr;
263 		dev->mem_start = mem_start;
264 		ei_status.mem = ioremap(mem_start,
265 					(HP_STOP_PG - HP_START_PG)*256);
266 		if (!ei_status.mem) {
267 			retval = -ENOMEM;
268 			goto out;
269 		}
270 		ei_status.rmem_start = dev->mem_start + TX_PAGES/2*256;
271 		dev->mem_end = ei_status.rmem_end
272 			= dev->mem_start + (HP_STOP_PG - HP_START_PG)*256;
273 	}
274 
275 	outw(Perf_Page, ioaddr + HP_PAGING);
276 	NS8390p_init(dev, 0);
277 	/* Leave the 8390 and HP chip reset. */
278 	outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION);
279 
280 	retval = register_netdev(dev);
281 	if (retval)
282 		goto out1;
283 	return 0;
284 out1:
285 	iounmap(ei_status.mem);
286 out:
287 	release_region(ioaddr, HP_IO_EXTENT);
288 	return retval;
289 }
290 
291 static int
hpp_open(struct net_device * dev)292 hpp_open(struct net_device *dev)
293 {
294 	int ioaddr = dev->base_addr - NIC_OFFSET;
295 	int option_reg;
296 	int retval;
297 
298 	if ((retval = request_irq(dev->irq, eip_interrupt, 0, dev->name, dev))) {
299 	    return retval;
300 	}
301 
302 	/* Reset the 8390 and HP chip. */
303 	option_reg = inw(ioaddr + HPP_OPTION);
304 	outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION);
305 	udelay(5);
306 	/* Unreset the board and enable interrupts. */
307 	outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION);
308 
309 	/* Set the wrap registers for programmed-I/O operation.   */
310 	outw(HW_Page, ioaddr + HP_PAGING);
311 	outw((HP_START_PG + TX_PAGES/2) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
312 
313 	/* Select the operational page. */
314 	outw(Perf_Page, ioaddr + HP_PAGING);
315 
316 	return eip_open(dev);
317 }
318 
319 static int
hpp_close(struct net_device * dev)320 hpp_close(struct net_device *dev)
321 {
322 	int ioaddr = dev->base_addr - NIC_OFFSET;
323 	int option_reg = inw(ioaddr + HPP_OPTION);
324 
325 	free_irq(dev->irq, dev);
326 	eip_close(dev);
327 	outw((option_reg & ~EnableIRQ) | MemDisable | NICReset | ChipReset,
328 		 ioaddr + HPP_OPTION);
329 
330 	return 0;
331 }
332 
333 static void
hpp_reset_8390(struct net_device * dev)334 hpp_reset_8390(struct net_device *dev)
335 {
336 	int ioaddr = dev->base_addr - NIC_OFFSET;
337 	int option_reg = inw(ioaddr + HPP_OPTION);
338 
339 	if (ei_debug > 1) printk("resetting the 8390 time=%ld...", jiffies);
340 
341 	outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION);
342 	/* Pause a few cycles for the hardware reset to take place. */
343 	udelay(5);
344 	ei_status.txing = 0;
345 	outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION);
346 
347 	udelay(5);
348 
349 
350 	if ((inb_p(ioaddr+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0)
351 		printk("%s: hp_reset_8390() did not complete.\n", dev->name);
352 
353 	if (ei_debug > 1) printk("8390 reset done (%ld).", jiffies);
354 }
355 
356 /* The programmed-I/O version of reading the 4 byte 8390 specific header.
357    Note that transfer with the EtherTwist+ must be on word boundaries. */
358 
359 static void
hpp_io_get_8390_hdr(struct net_device * dev,struct e8390_pkt_hdr * hdr,int ring_page)360 hpp_io_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
361 {
362 	int ioaddr = dev->base_addr - NIC_OFFSET;
363 
364 	outw((ring_page<<8), ioaddr + HPP_IN_ADDR);
365 	insw(ioaddr + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
366 }
367 
368 /* Block input and output, similar to the Crynwr packet driver. */
369 
370 static void
hpp_io_block_input(struct net_device * dev,int count,struct sk_buff * skb,int ring_offset)371 hpp_io_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
372 {
373 	int ioaddr = dev->base_addr - NIC_OFFSET;
374 	char *buf = skb->data;
375 
376 	outw(ring_offset, ioaddr + HPP_IN_ADDR);
377 	insw(ioaddr + HP_DATAPORT, buf, count>>1);
378 	if (count & 0x01)
379         buf[count-1] = inw(ioaddr + HP_DATAPORT);
380 }
381 
382 /* The corresponding shared memory versions of the above 2 functions. */
383 
384 static void
hpp_mem_get_8390_hdr(struct net_device * dev,struct e8390_pkt_hdr * hdr,int ring_page)385 hpp_mem_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
386 {
387 	int ioaddr = dev->base_addr - NIC_OFFSET;
388 	int option_reg = inw(ioaddr + HPP_OPTION);
389 
390 	outw((ring_page<<8), ioaddr + HPP_IN_ADDR);
391 	outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
392 	memcpy_fromio(hdr, ei_status.mem, sizeof(struct e8390_pkt_hdr));
393 	outw(option_reg, ioaddr + HPP_OPTION);
394 	hdr->count = (le16_to_cpu(hdr->count) + 3) & ~3;	/* Round up allocation. */
395 }
396 
397 static void
hpp_mem_block_input(struct net_device * dev,int count,struct sk_buff * skb,int ring_offset)398 hpp_mem_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
399 {
400 	int ioaddr = dev->base_addr - NIC_OFFSET;
401 	int option_reg = inw(ioaddr + HPP_OPTION);
402 
403 	outw(ring_offset, ioaddr + HPP_IN_ADDR);
404 
405 	outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
406 
407 	/* Caution: this relies on get_8390_hdr() rounding up count!
408 	   Also note that we *can't* use eth_io_copy_and_sum() because
409 	   it will not always copy "count" bytes (e.g. padded IP).  */
410 
411 	memcpy_fromio(skb->data, ei_status.mem, count);
412 	outw(option_reg, ioaddr + HPP_OPTION);
413 }
414 
415 /* A special note: we *must* always transfer >=16 bit words.
416    It's always safe to round up, so we do. */
417 static void
hpp_io_block_output(struct net_device * dev,int count,const unsigned char * buf,int start_page)418 hpp_io_block_output(struct net_device *dev, int count,
419 					const unsigned char *buf, int start_page)
420 {
421 	int ioaddr = dev->base_addr - NIC_OFFSET;
422 	outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
423 	outsl(ioaddr + HP_DATAPORT, buf, (count+3)>>2);
424 }
425 
426 static void
hpp_mem_block_output(struct net_device * dev,int count,const unsigned char * buf,int start_page)427 hpp_mem_block_output(struct net_device *dev, int count,
428 				const unsigned char *buf, int start_page)
429 {
430 	int ioaddr = dev->base_addr - NIC_OFFSET;
431 	int option_reg = inw(ioaddr + HPP_OPTION);
432 
433 	outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
434 	outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
435 	memcpy_toio(ei_status.mem, buf, (count + 3) & ~3);
436 	outw(option_reg, ioaddr + HPP_OPTION);
437 }
438 
439 
440 #ifdef MODULE
441 #define MAX_HPP_CARDS	4	/* Max number of HPP cards per module */
442 static struct net_device *dev_hpp[MAX_HPP_CARDS];
443 static int io[MAX_HPP_CARDS];
444 static int irq[MAX_HPP_CARDS];
445 
446 module_param_array(io, int, NULL, 0);
447 module_param_array(irq, int, NULL, 0);
448 MODULE_PARM_DESC(io, "I/O port address(es)");
449 MODULE_PARM_DESC(irq, "IRQ number(s); ignored if properly detected");
450 MODULE_DESCRIPTION("HP PC-LAN+ ISA ethernet driver");
451 MODULE_LICENSE("GPL");
452 
453 /* This is set up so that only a single autoprobe takes place per call.
454 ISA device autoprobes on a running machine are not recommended. */
455 int __init
init_module(void)456 init_module(void)
457 {
458 	struct net_device *dev;
459 	int this_dev, found = 0;
460 
461 	for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) {
462 		if (io[this_dev] == 0)  {
463 			if (this_dev != 0) break; /* only autoprobe 1st one */
464 			printk(KERN_NOTICE "hp-plus.c: Presently autoprobing (not recommended) for a single card.\n");
465 		}
466 		dev = alloc_eip_netdev();
467 		if (!dev)
468 			break;
469 		dev->irq = irq[this_dev];
470 		dev->base_addr = io[this_dev];
471 		if (do_hpp_probe(dev) == 0) {
472 			dev_hpp[found++] = dev;
473 			continue;
474 		}
475 		free_netdev(dev);
476 		printk(KERN_WARNING "hp-plus.c: No HP-Plus card found (i/o = 0x%x).\n", io[this_dev]);
477 		break;
478 	}
479 	if (found)
480 		return 0;
481 	return -ENXIO;
482 }
483 
cleanup_card(struct net_device * dev)484 static void cleanup_card(struct net_device *dev)
485 {
486 	/* NB: hpp_close() handles free_irq */
487 	iounmap(ei_status.mem);
488 	release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
489 }
490 
491 void __exit
cleanup_module(void)492 cleanup_module(void)
493 {
494 	int this_dev;
495 
496 	for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) {
497 		struct net_device *dev = dev_hpp[this_dev];
498 		if (dev) {
499 			unregister_netdev(dev);
500 			cleanup_card(dev);
501 			free_netdev(dev);
502 		}
503 	}
504 }
505 #endif /* MODULE */
506