Change mbug allocation flags from M_ to MB_ to avoid confusion with malloc
[dragonfly.git] / sys / dev / netif / ie / if_ie.c
CommitLineData
984263bc
MD
1/*-
2 * Copyright (c) 1992, 1993, University of Vermont and State
3 * Agricultural College.
4 * Copyright (c) 1992, 1993, Garrett A. Wollman.
5 *
6 * Portions:
7 * Copyright (c) 1990, 1991, William F. Jolitz
8 * Copyright (c) 1990, The Regents of the University of California
9 *
10 * 3Com 3C507 support:
11 * Copyright (c) 1993, 1994, Charles M. Hannum
12 *
13 * EtherExpress 16 support:
14 * Copyright (c) 1993, 1994, 1995, Rodney W. Grimes
15 * Copyright (c) 1997, Aaron C. Smith
16 *
17 * All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
27 * 3. All advertising materials mentioning features or use of this software
28 * must display the following acknowledgement:
29 * This product includes software developed by the University of
30 * Vermont and State Agricultural College and Garrett A. Wollman, by
31 * William F. Jolitz, by the University of California, Berkeley,
32 * Lawrence Berkeley Laboratory, and their contributors, by
33 * Charles M. Hannum, by Rodney W. Grimes, and by Aaron C. Smith.
34 * 4. Neither the names of the Universities nor the names of the authors
35 * may be used to endorse or promote products derived from this software
36 * without specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 *
50 * $FreeBSD: src/sys/dev/ie/if_ie.c,v 1.72.2.4 2003/03/27 21:01:49 mdodd Exp $
74f1caca 51 * $DragonFly: src/sys/dev/netif/ie/if_ie.c,v 1.12 2004/06/02 14:42:52 eirikn Exp $
984263bc
MD
52 */
53
54/*
55 * Intel 82586 Ethernet chip
56 * Register, bit, and structure definitions.
57 *
58 * Written by GAW with reference to the Clarkson Packet Driver code for this
59 * chip written by Russ Nelson and others.
60 *
61 * Intel EtherExpress 16 support from if_ix.c, written by Rodney W. Grimes.
62 */
63
64/*
65 * The i82586 is a very versatile chip, found in many implementations.
66 * Programming this chip is mostly the same, but certain details differ
67 * from card to card. This driver is written so that different cards
68 * can be automatically detected at run-time.
69 */
70
71/*
72Mode of operation:
73
74We run the 82586 in a standard Ethernet mode. We keep NFRAMES received
75frame descriptors around for the receiver to use, and NRXBUFS associated
76receive buffer descriptors, both in a circular list. Whenever a frame is
77received, we rotate both lists as necessary. (The 586 treats both lists
78as a simple queue.) We also keep a transmit command around so that packets
79can be sent off quickly.
80
81We configure the adapter in AL-LOC = 1 mode, which means that the
82Ethernet/802.3 MAC header is placed at the beginning of the receive buffer
83rather than being split off into various fields in the RFD. This also
84means that we must include this header in the transmit buffer as well.
85
86By convention, all transmit commands, and only transmit commands, shall
87have the I (IE_CMD_INTR) bit set in the command. This way, when an
88interrupt arrives at ieintr(), it is immediately possible to tell
89what precisely caused it. ANY OTHER command-sending routines should
90run at splimp(), and should post an acknowledgement to every interrupt
91they generate.
92
93The 82586 has a 24-bit address space internally, and the adaptor's memory
94is located at the top of this region. However, the value we are given in
95configuration is normally the *bottom* of the adaptor RAM. So, we must go
96through a few gyrations to come up with a kernel virtual address which
97represents the actual beginning of the 586 address space. First, we
98autosize the RAM by running through several possible sizes and trying to
99initialize the adapter under the assumption that the selected size is
100correct. Then, knowing the correct RAM size, we set up our pointers in
101ie_softc[unit]. `iomem' represents the computed base of the 586 address
102space. `iomembot' represents the actual configured base of adapter RAM.
103Finally, `iosize' represents the calculated size of 586 RAM. Then, when
104laying out commands, we use the interval [iomembot, iomembot + iosize); to
105make 24-pointers, we subtract iomem, and to make 16-pointers, we subtract
106iomem and and with 0xffff.
107
108*/
109
1f2de5d4 110#include "use_ie.h"
984263bc
MD
111#include "opt_inet.h"
112#include "opt_ipx.h"
113
114#include <sys/param.h>
115#include <sys/systm.h>
116#include <sys/eventhandler.h>
117#include <sys/kernel.h>
118#include <sys/malloc.h>
119#include <sys/conf.h>
120#include <sys/mbuf.h>
121#include <sys/socket.h>
122#include <sys/sockio.h>
123#include <sys/syslog.h>
124
125#include <net/ethernet.h>
126#include <net/if.h>
127#include <net/if_types.h>
128#include <net/if_dl.h>
129
130#include <netinet/in.h>
131#include <netinet/if_ether.h>
132
133#include <machine/clock.h>
134#include <machine/md_var.h>
135
1f2de5d4 136#include <bus/isa/i386/isa_device.h>
984263bc
MD
137#include <i386/isa/ic/i82586.h>
138#include <i386/isa/icu.h>
1f2de5d4
MD
139#include "if_iereg.h"
140#include "if_ie507.h"
141#include "if_iee16.h"
142#include "../elink_layer/elink.h"
984263bc
MD
143
144#include <net/bpf.h>
145
146#ifdef DEBUG
147#define IED_RINT 0x01
148#define IED_TINT 0x02
149#define IED_RNR 0x04
150#define IED_CNA 0x08
151#define IED_READFRAME 0x10
152static int ie_debug = IED_RNR;
153
154#endif
155
32832096
MD
156DECLARE_DUMMY_MODULE(if_ie);
157
984263bc
MD
158#define IE_BUF_LEN ETHER_MAX_LEN /* length of transmit buffer */
159
160/* Forward declaration */
161struct ie_softc;
162
163static int ieprobe(struct isa_device * dvp);
164static int ieattach(struct isa_device * dvp);
165static ointhand2_t ieintr;
166static int sl_probe(struct isa_device * dvp);
167static int el_probe(struct isa_device * dvp);
168static int ni_probe(struct isa_device * dvp);
169static int ee16_probe(struct isa_device * dvp);
170
171static int check_ie_present(int unit, caddr_t where, unsigned size);
172static void ieinit(void *);
173static void ie_stop(int unit);
bd4539cc
JH
174static int ieioctl(struct ifnet * ifp, u_long command, caddr_t data,
175 struct ucred *);
984263bc
MD
176static void iestart(struct ifnet * ifp);
177
178static void el_reset_586(int unit);
179static void el_chan_attn(int unit);
180
181static void sl_reset_586(int unit);
182static void sl_chan_attn(int unit);
183
184static void ee16_reset_586(int unit);
185static void ee16_chan_attn(int unit);
186static __inline void ee16_interrupt_enable(struct ie_softc * ie);
187static void ee16_eeprom_outbits(struct ie_softc * ie, int edata, int cnt);
188static void ee16_eeprom_clock(struct ie_softc * ie, int state);
189static u_short ee16_read_eeprom(struct ie_softc * ie, int location);
190static int ee16_eeprom_inbits(struct ie_softc * ie);
191static void ee16_shutdown(void *sc, int howto);
192
193static void iereset(int unit);
194static void ie_readframe(int unit, struct ie_softc * ie, int bufno);
195static void ie_drop_packet_buffer(int unit, struct ie_softc * ie);
196static void sl_read_ether(int unit, unsigned char addr[6]);
197static void find_ie_mem_size(int unit);
198static void chan_attn_timeout(void *rock);
199static int command_and_wait(int unit, int command,
200 void volatile * pcmd, int);
201static void run_tdr(int unit, volatile struct ie_tdr_cmd * cmd);
202static int ierint(int unit, struct ie_softc * ie);
203static int ietint(int unit, struct ie_softc * ie);
204static int iernr(int unit, struct ie_softc * ie);
205static void start_receiver(int unit);
206static __inline int ieget(int, struct ie_softc *, struct mbuf **,
207 struct ether_header *);
208static v_caddr_t setup_rfa(v_caddr_t ptr, struct ie_softc * ie);
209static int mc_setup(int, v_caddr_t, volatile struct ie_sys_ctl_block *);
210static void ie_mc_reset(int unit);
211
212#ifdef DEBUG
213static void print_rbd(volatile struct ie_recv_buf_desc * rbd);
214
215static int in_ierint = 0;
216static int in_ietint = 0;
217
218#endif
219
220/*
221 * This tells the autoconf code how to set us up.
222 */
223struct isa_driver iedriver = {
224 ieprobe, ieattach, "ie",
225};
226
227enum ie_hardware {
228 IE_STARLAN10,
229 IE_EN100,
230 IE_SLFIBER,
231 IE_3C507,
232 IE_NI5210,
233 IE_EE16,
234 IE_UNKNOWN
235};
236
237static const char *ie_hardware_names[] = {
238 "StarLAN 10",
239 "EN100",
240 "StarLAN Fiber",
241 "3C507",
242 "NI5210",
243 "EtherExpress 16",
244 "Unknown"
245};
246
247/*
248sizeof(iscp) == 1+1+2+4 == 8
249sizeof(scb) == 2+2+2+2+2+2+2+2 == 16
250NFRAMES * sizeof(rfd) == NFRAMES*(2+2+2+2+6+6+2+2) == NFRAMES*24 == 384
251sizeof(xmit_cmd) == 2+2+2+2+6+2 == 18
252sizeof(transmit buffer) == 1512
253sizeof(transmit buffer desc) == 8
254-----
2551946
256
257NRXBUFS * sizeof(rbd) == NRXBUFS*(2+2+4+2+2) == NRXBUFS*12
258NRXBUFS * IE_RBUF_SIZE == NRXBUFS*256
259
260NRXBUFS should be (16384 - 1946) / (256 + 12) == 14438 / 268 == 53
261
262With NRXBUFS == 48, this leaves us 1574 bytes for another command or
263more buffers. Another transmit command would be 18+8+1512 == 1538
264---just barely fits!
265
266Obviously all these would have to be reduced for smaller memory sizes.
267With a larger memory, it would be possible to roughly double the number of
268both transmit and receive buffers.
269*/
270
271#define NFRAMES 8 /* number of receive frames */
272#define NRXBUFS 48 /* number of buffers to allocate */
273#define IE_RBUF_SIZE 256 /* size of each buffer, MUST BE POWER OF TWO */
274#define NTXBUFS 2 /* number of transmit commands */
275#define IE_TBUF_SIZE ETHER_MAX_LEN /* size of transmit buffer */
276
277/*
278 * Ethernet status, per interface.
279 */
280static struct ie_softc {
281 struct arpcom arpcom;
282 void (*ie_reset_586) (int);
283 void (*ie_chan_attn) (int);
284 enum ie_hardware hard_type;
285 int hard_vers;
286 int unit;
287
288 u_short port; /* i/o base address for this interface */
289 caddr_t iomem; /* memory size */
290 caddr_t iomembot; /* memory base address */
291 unsigned iosize;
292 int bus_use; /* 0 means 16bit, 1 means 8 bit adapter */
293
294 int want_mcsetup;
295 int promisc;
296 int nframes;
297 int nrxbufs;
298 int ntxbufs;
299 volatile struct ie_int_sys_conf_ptr *iscp;
300 volatile struct ie_sys_ctl_block *scb;
301 volatile struct ie_recv_frame_desc **rframes; /* nframes worth */
302 volatile struct ie_recv_buf_desc **rbuffs; /* nrxbufs worth */
303 volatile u_char **cbuffs; /* nrxbufs worth */
304 int rfhead, rftail, rbhead, rbtail;
305
306 volatile struct ie_xmit_cmd **xmit_cmds; /* ntxbufs worth */
307 volatile struct ie_xmit_buf **xmit_buffs; /* ntxbufs worth */
308 volatile u_char **xmit_cbuffs; /* ntxbufs worth */
309 int xmit_count;
310
311 struct ie_en_addr mcast_addrs[MAXMCAST + 1];
312 int mcast_count;
313
314 u_short irq_encoded; /* encoded interrupt on IEE16 */
315} ie_softc[NIE];
316
317#define MK_24(base, ptr) ((caddr_t)((uintptr_t)ptr - (uintptr_t)base))
318#define MK_16(base, ptr) ((u_short)(uintptr_t)MK_24(base, ptr))
319
320#define PORT ie_softc[unit].port
321#define MEM ie_softc[unit].iomem
322
323int
324ieprobe(struct isa_device *dvp)
325{
326 int ret;
327
328 ret = sl_probe(dvp);
329 if (!ret)
330 ret = el_probe(dvp);
331 if (!ret)
332 ret = ni_probe(dvp);
333 if (!ret)
334 ret = ee16_probe(dvp);
335
336 return (ret);
337}
338
339static int
340sl_probe(struct isa_device *dvp)
341{
342 int unit = dvp->id_unit;
343 u_char c;
344
345 ie_softc[unit].port = dvp->id_iobase;
346 ie_softc[unit].iomembot = dvp->id_maddr;
347 ie_softc[unit].iomem = 0;
348 ie_softc[unit].bus_use = 0;
349
350 c = inb(PORT + IEATT_REVISION);
351 switch (SL_BOARD(c)) {
352 case SL10_BOARD:
353 ie_softc[unit].hard_type = IE_STARLAN10;
354 ie_softc[unit].ie_reset_586 = sl_reset_586;
355 ie_softc[unit].ie_chan_attn = sl_chan_attn;
356 break;
357 case EN100_BOARD:
358 ie_softc[unit].hard_type = IE_EN100;
359 ie_softc[unit].ie_reset_586 = sl_reset_586;
360 ie_softc[unit].ie_chan_attn = sl_chan_attn;
361 break;
362 case SLFIBER_BOARD:
363 ie_softc[unit].hard_type = IE_SLFIBER;
364 ie_softc[unit].ie_reset_586 = sl_reset_586;
365 ie_softc[unit].ie_chan_attn = sl_chan_attn;
366 break;
367
368 /*
369 * Anything else is not recognized or cannot be used.
370 */
371 default:
372 return (0);
373 }
374
375 ie_softc[unit].hard_vers = SL_REV(c);
376
377 /*
378 * Divine memory size on-board the card. Ususally 16k.
379 */
380 find_ie_mem_size(unit);
381
382 if (!ie_softc[unit].iosize) {
383 return (0);
384 }
385 dvp->id_msize = ie_softc[unit].iosize;
386
387 switch (ie_softc[unit].hard_type) {
388 case IE_EN100:
389 case IE_STARLAN10:
390 case IE_SLFIBER:
391 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
392 break;
393
394 default:
395 if (bootverbose)
396 printf("ie%d: unknown AT&T board type code %d\n", unit,
397 ie_softc[unit].hard_type);
398 return (0);
399 }
400
401 return (1);
402}
403
404
405static int
406el_probe(struct isa_device *dvp)
407{
408 struct ie_softc *sc = &ie_softc[dvp->id_unit];
409 u_char c;
410 int i;
411 u_char signature[] = "*3COM*";
412 int unit = dvp->id_unit;
413
414 sc->unit = unit;
415 sc->port = dvp->id_iobase;
416 sc->iomembot = dvp->id_maddr;
417 sc->bus_use = 0;
418
419 /* Need this for part of the probe. */
420 sc->ie_reset_586 = el_reset_586;
421 sc->ie_chan_attn = el_chan_attn;
422
423 /* Reset and put card in CONFIG state without changing address. */
424 elink_reset();
425 outb(ELINK_ID_PORT, 0x00);
426 elink_idseq(ELINK_507_POLY);
427 elink_idseq(ELINK_507_POLY);
428 outb(ELINK_ID_PORT, 0xff);
429
430 c = inb(PORT + IE507_MADDR);
431 if (c & 0x20) {
432#ifdef DEBUG
433 printf("ie%d: can't map 3C507 RAM in high memory\n", unit);
434#endif
435 return (0);
436 }
437 /* go to RUN state */
438 outb(ELINK_ID_PORT, 0x00);
439 elink_idseq(ELINK_507_POLY);
440 outb(ELINK_ID_PORT, 0x00);
441
442 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
443
444 for (i = 0; i < 6; i++)
445 if (inb(PORT + i) != signature[i])
446 return (0);
447
448 c = inb(PORT + IE507_IRQ) & 0x0f;
449
450 if (dvp->id_irq != (1 << c)) {
451 printf("ie%d: kernel configured irq %d "
452 "doesn't match board configured irq %d\n",
453 unit, ffs(dvp->id_irq) - 1, c);
454 return (0);
455 }
456 c = (inb(PORT + IE507_MADDR) & 0x1c) + 0xc0;
457
458 if (kvtop(dvp->id_maddr) != ((int) c << 12)) {
416148ae 459 printf("ie%d: kernel configured maddr %llx "
984263bc
MD
460 "doesn't match board configured maddr %x\n",
461 unit, kvtop(dvp->id_maddr), (int) c << 12);
462 return (0);
463 }
464 outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
465
466 sc->hard_type = IE_3C507;
467 sc->hard_vers = 0; /* 3C507 has no version number. */
468
469 /*
470 * Divine memory size on-board the card.
471 */
472 find_ie_mem_size(unit);
473
474 if (!sc->iosize) {
475 printf("ie%d: can't find shared memory\n", unit);
476 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
477 return (0);
478 }
479 if (!dvp->id_msize)
480 dvp->id_msize = sc->iosize;
481 else if (dvp->id_msize != sc->iosize) {
482 printf("ie%d: kernel configured msize %d "
483 "doesn't match board configured msize %d\n",
484 unit, dvp->id_msize, sc->iosize);
485 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
486 return (0);
487 }
488 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
489
490 /* Clear the interrupt latch just in case. */
491 outb(PORT + IE507_ICTRL, 1);
492
493 return (16);
494}
495
496
497static int
498ni_probe(struct isa_device *dvp)
499{
500 int unit = dvp->id_unit;
501 int boardtype, c;
502
503 ie_softc[unit].port = dvp->id_iobase;
504 ie_softc[unit].iomembot = dvp->id_maddr;
505 ie_softc[unit].iomem = 0;
506 ie_softc[unit].bus_use = 1;
507
508 boardtype = inb(PORT + IEATT_REVISION);
509 c = inb(PORT + IEATT_REVISION + 1);
510 boardtype = boardtype + (c << 8);
511 switch (boardtype) {
512 case 0x5500: /* This is the magic cookie for the NI5210 */
513 ie_softc[unit].hard_type = IE_NI5210;
514 ie_softc[unit].ie_reset_586 = sl_reset_586;
515 ie_softc[unit].ie_chan_attn = sl_chan_attn;
516 break;
517
518 /*
519 * Anything else is not recognized or cannot be used.
520 */
521 default:
522 return (0);
523 }
524
525 ie_softc[unit].hard_vers = 0;
526
527 /*
528 * Divine memory size on-board the card. Either 8 or 16k.
529 */
530 find_ie_mem_size(unit);
531
532 if (!ie_softc[unit].iosize) {
533 return (0);
534 }
535 if (!dvp->id_msize)
536 dvp->id_msize = ie_softc[unit].iosize;
537 else if (dvp->id_msize != ie_softc[unit].iosize) {
538 printf("ie%d: kernel configured msize %d "
539 "doesn't match board configured msize %d\n",
540 unit, dvp->id_msize, ie_softc[unit].iosize);
541 return (0);
542 }
543 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
544
545 return (8);
546
547}
548
549
550static void
551ee16_shutdown(void *sc, int howto)
552{
553 struct ie_softc *ie = (struct ie_softc *)sc;
554 int unit = ie - &ie_softc[0];
555
556 ee16_reset_586(unit);
557 outb(PORT + IEE16_ECTRL, IEE16_RESET_ASIC);
558 outb(PORT + IEE16_ECTRL, 0);
559}
560
561
562/* Taken almost exactly from Rod's if_ix.c. */
563
564int
565ee16_probe(struct isa_device *dvp)
566{
567 struct ie_softc *sc = &ie_softc[dvp->id_unit];
568
569 int i;
570 int unit = dvp->id_unit;
571 u_short board_id, id_var1, id_var2, checksum = 0;
572 u_short eaddrtemp, irq;
573 u_short pg, adjust, decode, edecode;
574 u_char bart_config;
575 u_long bd_maddr;
576
577 short irq_translate[] = {0, IRQ9, IRQ3, IRQ4, IRQ5, IRQ10, IRQ11, 0};
578 char irq_encode[] = {0, 0, 0, 2, 3, 4, 0, 0, 0, 1, 5, 6, 0, 0, 0, 0};
579
580 /* Need this for part of the probe. */
581 sc->ie_reset_586 = ee16_reset_586;
582 sc->ie_chan_attn = ee16_chan_attn;
583
584 /* unsure if this is necessary */
585 sc->bus_use = 0;
586
587 /* reset any ee16 at the current iobase */
588 outb(dvp->id_iobase + IEE16_ECTRL, IEE16_RESET_ASIC);
589 outb(dvp->id_iobase + IEE16_ECTRL, 0);
590 DELAY(240);
591
592 /* now look for ee16. */
593 board_id = id_var1 = id_var2 = 0;
594 for (i = 0; i < 4; i++) {
595 id_var1 = inb(dvp->id_iobase + IEE16_ID_PORT);
596 id_var2 = ((id_var1 & 0x03) << 2);
597 board_id |= ((id_var1 >> 4) << id_var2);
598 }
599
600 if (board_id != IEE16_ID) {
601 if (bootverbose)
602 printf("ie%d: unknown board_id: %x\n", unit, board_id);
603 return (0);
604 }
605 /* need sc->port for ee16_read_eeprom */
606 sc->port = dvp->id_iobase;
607 sc->hard_type = IE_EE16;
608
609 /*
610 * The shared RAM location on the EE16 is encoded into bits 3-7 of
611 * EEPROM location 6. We zero the upper byte, and shift the 5 bits
612 * right 3. The resulting number tells us the RAM location.
613 * Because the EE16 supports either 16k or 32k of shared RAM, we
614 * only worry about the 32k locations.
615 *
616 * NOTE: if a 64k EE16 exists, it should be added to this switch. then
617 * the ia->ia_msize would need to be set per case statement.
618 *
619 * value msize location ===== ===== ======== 0x03 0x8000
620 * 0xCC000 0x06 0x8000 0xD0000 0x0C 0x8000 0xD4000 0x18
621 * 0x8000 0xD8000
622 *
623 */
624
625 bd_maddr = 0;
626 i = (ee16_read_eeprom(sc, 6) & 0x00ff) >> 3;
627 switch (i) {
628 case 0x03:
629 bd_maddr = 0xCC000;
630 break;
631 case 0x06:
632 bd_maddr = 0xD0000;
633 break;
634 case 0x0c:
635 bd_maddr = 0xD4000;
636 break;
637 case 0x18:
638 bd_maddr = 0xD8000;
639 break;
640 default:
641 bd_maddr = 0;
642 break;
643 }
644 dvp->id_msize = 0x8000;
645 if (kvtop(dvp->id_maddr) != bd_maddr) {
416148ae 646 printf("ie%d: kernel configured maddr %llx "
984263bc
MD
647 "doesn't match board configured maddr %lx\n",
648 unit, kvtop(dvp->id_maddr), bd_maddr);
649 }
650 sc->iomembot = dvp->id_maddr;
651 sc->iomem = 0; /* XXX some probes set this and some don't */
652 sc->iosize = dvp->id_msize;
653
654 /* need to put the 586 in RESET while we access the eeprom. */
655 outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
656
657 /* read the eeprom and checksum it, should == IEE16_ID */
658 for (i = 0; i < 0x40; i++)
659 checksum += ee16_read_eeprom(sc, i);
660
661 if (checksum != IEE16_ID) {
662 printf("ie%d: invalid eeprom checksum: %x\n", unit, checksum);
663 return (0);
664 }
665 /*
666 * Size and test the memory on the board. The size of the memory
667 * can be one of 16k, 32k, 48k or 64k. It can be located in the
668 * address range 0xC0000 to 0xEFFFF on 16k boundaries.
669 *
670 * If the size does not match the passed in memory allocation size
671 * issue a warning, but continue with the minimum of the two sizes.
672 */
673
674 switch (dvp->id_msize) {
675 case 65536:
676 case 32768: /* XXX Only support 32k and 64k right now */
677 break;
678 case 16384:
679 case 49512:
680 default:
681 printf("ie%d: mapped memory size %d not supported\n", unit,
682 dvp->id_msize);
683 return (0);
684 break; /* NOTREACHED */
685 }
686
687 if ((kvtop(dvp->id_maddr) < 0xC0000) ||
688 (kvtop(dvp->id_maddr) + sc->iosize > 0xF0000)) {
689 printf("ie%d: mapped memory location %p out of range\n", unit,
690 (void *)dvp->id_maddr);
691 return (0);
692 }
693 pg = (kvtop(dvp->id_maddr) & 0x3C000) >> 14;
694 adjust = IEE16_MCTRL_FMCS16 | (pg & 0x3) << 2;
695 decode = ((1 << (sc->iosize / 16384)) - 1) << pg;
696 edecode = ((~decode >> 4) & 0xF0) | (decode >> 8);
697
698 /* ZZZ This should be checked against eeprom location 6, low byte */
699 outb(PORT + IEE16_MEMDEC, decode & 0xFF);
700 /* ZZZ This should be checked against eeprom location 1, low byte */
701 outb(PORT + IEE16_MCTRL, adjust);
702 /* ZZZ Now if I could find this one I would have it made */
703 outb(PORT + IEE16_MPCTRL, (~decode & 0xFF));
704 /* ZZZ I think this is location 6, high byte */
705 outb(PORT + IEE16_MECTRL, edecode); /* XXX disable Exxx */
706
707 (void) kvtop(dvp->id_maddr);
708
709 /*
710 * first prime the stupid bart DRAM controller so that it works,
711 * then zero out all of memory.
712 */
713 bzero(sc->iomembot, 32);
714 bzero(sc->iomembot, sc->iosize);
715
716 /*
717 * Get the encoded interrupt number from the EEPROM, check it
718 * against the passed in IRQ. Issue a warning if they do not match.
719 * Always use the passed in IRQ, not the one in the EEPROM.
720 */
721 irq = ee16_read_eeprom(sc, IEE16_EEPROM_CONFIG1);
722 irq = (irq & IEE16_EEPROM_IRQ) >> IEE16_EEPROM_IRQ_SHIFT;
723 irq = irq_translate[irq];
724 if (dvp->id_irq > 0) {
725 if (irq != dvp->id_irq) {
726 printf("ie%d: WARNING: board configured "
727 "at irq %u, using %u\n",
728 dvp->id_unit, dvp->id_irq, irq);
729 irq = dvp->id_unit;
730 }
731 } else {
732 dvp->id_irq = irq;
733 }
734 sc->irq_encoded = irq_encode[ffs(irq) - 1];
735
736 /*
737 * Get the hardware ethernet address from the EEPROM and save it in
738 * the softc for use by the 586 setup code.
739 */
740 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_HIGH);
741 sc->arpcom.ac_enaddr[1] = eaddrtemp & 0xFF;
742 sc->arpcom.ac_enaddr[0] = eaddrtemp >> 8;
743 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_MID);
744 sc->arpcom.ac_enaddr[3] = eaddrtemp & 0xFF;
745 sc->arpcom.ac_enaddr[2] = eaddrtemp >> 8;
746 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_LOW);
747 sc->arpcom.ac_enaddr[5] = eaddrtemp & 0xFF;
748 sc->arpcom.ac_enaddr[4] = eaddrtemp >> 8;
749
750 /* disable the board interrupts */
751 outb(PORT + IEE16_IRQ, sc->irq_encoded);
752
753 /* enable loopback to keep bad packets off the wire */
754 if (sc->hard_type == IE_EE16) {
755 bart_config = inb(PORT + IEE16_CONFIG);
756 bart_config |= IEE16_BART_LOOPBACK;
757 bart_config |= IEE16_BART_MCS16_TEST;/* inb doesn't get bit! */
758 outb(PORT + IEE16_CONFIG, bart_config);
759 bart_config = inb(PORT + IEE16_CONFIG);
760 }
761 /* take the board out of reset state */
762 outb(PORT + IEE16_ECTRL, 0);
763 DELAY(100);
764
765 if (!check_ie_present(unit, dvp->id_maddr, sc->iosize))
766 return (0);
767
768 return (16); /* return the number of I/O ports */
769}
770
771/*
772 * Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
773 */
774int
775ieattach(struct isa_device *dvp)
776{
777 int factor;
778 int unit = dvp->id_unit;
779 struct ie_softc *ie = &ie_softc[unit];
780 struct ifnet *ifp = &ie->arpcom.ac_if;
781 size_t allocsize;
782
783 dvp->id_ointr = ieintr;
784
785 /*
786 * based on the amount of memory we have, allocate our tx and rx
787 * resources.
788 */
789 factor = dvp->id_msize / 16384;
790 ie->nframes = factor * NFRAMES;
791 ie->nrxbufs = factor * NRXBUFS;
792 ie->ntxbufs = factor * NTXBUFS;
793
794 /*
795 * Since all of these guys are arrays of pointers, allocate as one
796 * big chunk and dole out accordingly.
797 */
798 allocsize = sizeof(void *) * (ie->nframes
799 + (ie->nrxbufs * 2)
800 + (ie->ntxbufs * 3));
c5541aee 801 ie->rframes = malloc(allocsize, M_DEVBUF, M_WAITOK);
984263bc
MD
802 ie->rbuffs =
803 (volatile struct ie_recv_buf_desc **)&ie->rframes[ie->nframes];
804 ie->cbuffs = (volatile u_char **)&ie->rbuffs[ie->nrxbufs];
805 ie->xmit_cmds =
806 (volatile struct ie_xmit_cmd **)&ie->cbuffs[ie->nrxbufs];
807 ie->xmit_buffs =
808 (volatile struct ie_xmit_buf **)&ie->xmit_cmds[ie->ntxbufs];
809 ie->xmit_cbuffs = (volatile u_char **)&ie->xmit_buffs[ie->ntxbufs];
810
811 ifp->if_softc = ie;
3e4a09e7 812 if_initname(ifp, iedriver.name, unit);
984263bc
MD
813 ifp->if_mtu = ETHERMTU;
814 printf("ie%d: <%s R%d> address %6D\n", unit,
815 ie_hardware_names[ie->hard_type],
816 ie->hard_vers + 1,
817 ie->arpcom.ac_enaddr, ":");
818
819 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
820 ifp->if_output = ether_output;
821 ifp->if_start = iestart;
822 ifp->if_ioctl = ieioctl;
823 ifp->if_init = ieinit;
824 ifp->if_type = IFT_ETHER;
825 ifp->if_addrlen = 6;
826 ifp->if_hdrlen = 14;
827 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
828
829 if (ie->hard_type == IE_EE16)
830 EVENTHANDLER_REGISTER(shutdown_post_sync, ee16_shutdown,
831 ie, SHUTDOWN_PRI_DEFAULT);
832
0a8b5977 833 ether_ifattach(ifp, ie->arpcom.ac_enaddr);
984263bc
MD
834 return (1);
835}
836
837/*
838 * What to do upon receipt of an interrupt.
839 */
840static void
841ieintr(int unit)
842{
f96d6c88
RG
843 struct ie_softc *ie = &ie_softc[unit];
844 u_short status;
984263bc
MD
845
846 /* Clear the interrupt latch on the 3C507. */
847 if (ie->hard_type == IE_3C507
848 && (inb(PORT + IE507_CTRL) & EL_CTRL_INTL))
849 outb(PORT + IE507_ICTRL, 1);
850
851 /* disable interrupts on the EE16. */
852 if (ie->hard_type == IE_EE16)
853 outb(PORT + IEE16_IRQ, ie->irq_encoded);
854
855 status = ie->scb->ie_status;
856
857loop:
858
859 /* Don't ack interrupts which we didn't receive */
860 ie_ack(ie->scb, IE_ST_WHENCE & status, unit, ie->ie_chan_attn);
861
862 if (status & (IE_ST_RECV | IE_ST_RNR)) {
863#ifdef DEBUG
864 in_ierint++;
865 if (ie_debug & IED_RINT)
866 printf("ie%d: rint\n", unit);
867#endif
868 ierint(unit, ie);
869#ifdef DEBUG
870 in_ierint--;
871#endif
872 }
873 if (status & IE_ST_DONE) {
874#ifdef DEBUG
875 in_ietint++;
876 if (ie_debug & IED_TINT)
877 printf("ie%d: tint\n", unit);
878#endif
879 ietint(unit, ie);
880#ifdef DEBUG
881 in_ietint--;
882#endif
883 }
884 if (status & IE_ST_RNR) {
885#ifdef DEBUG
886 if (ie_debug & IED_RNR)
887 printf("ie%d: rnr\n", unit);
888#endif
889 iernr(unit, ie);
890 }
891#ifdef DEBUG
892 if ((status & IE_ST_ALLDONE)
893 && (ie_debug & IED_CNA))
894 printf("ie%d: cna\n", unit);
895#endif
896
897 if ((status = ie->scb->ie_status) & IE_ST_WHENCE)
898 goto loop;
899
900 /* Clear the interrupt latch on the 3C507. */
901 if (ie->hard_type == IE_3C507)
902 outb(PORT + IE507_ICTRL, 1);
903
904 /* enable interrupts on the EE16. */
905 if (ie->hard_type == IE_EE16)
906 outb(PORT + IEE16_IRQ, ie->irq_encoded | IEE16_IRQ_ENABLE);
907
908}
909
910/*
911 * Process a received-frame interrupt.
912 */
913static int
914ierint(int unit, struct ie_softc *ie)
915{
916 int i, status;
917 static int timesthru = 1024;
918
919 i = ie->rfhead;
920 while (1) {
921 status = ie->rframes[i]->ie_fd_status;
922
923 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
924 ie->arpcom.ac_if.if_ipackets++;
925 if (!--timesthru) {
926 ie->arpcom.ac_if.if_ierrors +=
927 ie->scb->ie_err_crc +
928 ie->scb->ie_err_align +
929 ie->scb->ie_err_resource +
930 ie->scb->ie_err_overrun;
931 ie->scb->ie_err_crc = 0;
932 ie->scb->ie_err_align = 0;
933 ie->scb->ie_err_resource = 0;
934 ie->scb->ie_err_overrun = 0;
935 timesthru = 1024;
936 }
937 ie_readframe(unit, ie, i);
938 } else {
939 if (status & IE_FD_RNR) {
940 if (!(ie->scb->ie_status & IE_RU_READY)) {
941 ie->rframes[0]->ie_fd_next =
942 MK_16(MEM, ie->rbuffs[0]);
943 ie->scb->ie_recv_list =
944 MK_16(MEM, ie->rframes[0]);
945 command_and_wait(unit, IE_RU_START,
946 0, 0);
947 }
948 }
949 break;
950 }
951 i = (i + 1) % ie->nframes;
952 }
953 return (0);
954}
955
956/*
957 * Process a command-complete interrupt. These are only generated by
958 * the transmission of frames. This routine is deceptively simple, since
959 * most of the real work is done by iestart().
960 */
961static int
962ietint(int unit, struct ie_softc *ie)
963{
964 int status;
965 int i;
966
967 ie->arpcom.ac_if.if_timer = 0;
968 ie->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
969
970 for (i = 0; i < ie->xmit_count; i++) {
971 status = ie->xmit_cmds[i]->ie_xmit_status;
972
973 if (status & IE_XS_LATECOLL) {
974 printf("ie%d: late collision\n", unit);
975 ie->arpcom.ac_if.if_collisions++;
976 ie->arpcom.ac_if.if_oerrors++;
977 } else if (status & IE_XS_NOCARRIER) {
978 printf("ie%d: no carrier\n", unit);
979 ie->arpcom.ac_if.if_oerrors++;
980 } else if (status & IE_XS_LOSTCTS) {
981 printf("ie%d: lost CTS\n", unit);
982 ie->arpcom.ac_if.if_oerrors++;
983 } else if (status & IE_XS_UNDERRUN) {
984 printf("ie%d: DMA underrun\n", unit);
985 ie->arpcom.ac_if.if_oerrors++;
986 } else if (status & IE_XS_EXCMAX) {
987 printf("ie%d: too many collisions\n", unit);
988 ie->arpcom.ac_if.if_collisions += 16;
989 ie->arpcom.ac_if.if_oerrors++;
990 } else {
991 ie->arpcom.ac_if.if_opackets++;
992 ie->arpcom.ac_if.if_collisions += status & IE_XS_MAXCOLL;
993 }
994 }
995 ie->xmit_count = 0;
996
997 /*
998 * If multicast addresses were added or deleted while we were
999 * transmitting, ie_mc_reset() set the want_mcsetup flag indicating
1000 * that we should do it.
1001 */
1002 if (ie->want_mcsetup) {
1003 mc_setup(unit, (v_caddr_t) ie->xmit_cbuffs[0], ie->scb);
1004 ie->want_mcsetup = 0;
1005 }
1006 /* Wish I knew why this seems to be necessary... */
1007 ie->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL;
1008
1009 iestart(&ie->arpcom.ac_if);
1010 return (0); /* shouldn't be necessary */
1011}
1012
1013/*
1014 * Process a receiver-not-ready interrupt. I believe that we get these
1015 * when there aren't enough buffers to go around. For now (FIXME), we
1016 * just restart the receiver, and hope everything's ok.
1017 */
1018static int
1019iernr(int unit, struct ie_softc *ie)
1020{
1021#ifdef doesnt_work
1022 setup_rfa((v_caddr_t) ie->rframes[0], ie);
1023
1024 ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1025 command_and_wait(unit, IE_RU_START, 0, 0);
1026#else
1027 /* This doesn't work either, but it doesn't hang either. */
1028 command_and_wait(unit, IE_RU_DISABLE, 0, 0); /* just in case */
1029 setup_rfa((v_caddr_t) ie->rframes[0], ie); /* ignore cast-qual */
1030
1031 ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1032 command_and_wait(unit, IE_RU_START, 0, 0); /* was ENABLE */
1033
1034#endif
1035 ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
1036
1037 ie->arpcom.ac_if.if_ierrors++;
1038 return (0);
1039}
1040
1041/*
1042 * Compare two Ether/802 addresses for equality, inlined and
1043 * unrolled for speed. I'd love to have an inline assembler
1044 * version of this...
1045 */
1046static __inline int
1047ether_equal(u_char * one, u_char * two)
1048{
1049 if (one[0] != two[0])
1050 return (0);
1051 if (one[1] != two[1])
1052 return (0);
1053 if (one[2] != two[2])
1054 return (0);
1055 if (one[3] != two[3])
1056 return (0);
1057 if (one[4] != two[4])
1058 return (0);
1059 if (one[5] != two[5])
1060 return (0);
1061 return 1;
1062}
1063
1064/*
1065 * Determine quickly whether we should bother reading in this packet.
1066 * This depends on whether BPF and/or bridging is enabled, whether we
1067 * are receiving multicast address, and whether promiscuous mode is enabled.
1068 * We assume that if IFF_PROMISC is set, then *somebody* wants to see
1069 * all incoming packets.
1070 */
1071static __inline int
1072check_eh(struct ie_softc *ie, struct ether_header *eh)
1073{
1074 /* Optimize the common case: normal operation. We've received
1075 either a unicast with our dest or a multicast packet. */
1076 if (ie->promisc == 0) {
1077 int i;
1078
1079 /* If not multicast, it's definitely for us */
1080 if ((eh->ether_dhost[0] & 1) == 0)
1081 return (1);
1082
1083 /* Accept broadcasts (loose but fast check) */
1084 if (eh->ether_dhost[0] == 0xff)
1085 return (1);
1086
1087 /* Compare against our multicast addresses */
1088 for (i = 0; i < ie->mcast_count; i++) {
1089 if (ether_equal(eh->ether_dhost,
1090 (u_char *)&ie->mcast_addrs[i]))
1091 return (1);
1092 }
1093 return (0);
1094 }
1095
1096 /* Always accept packets when in promiscuous mode */
1097 if ((ie->promisc & IFF_PROMISC) != 0)
1098 return (1);
1099
1100 /* Always accept packets directed at us */
1101 if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
1102 return (1);
1103
1104 /* Must have IFF_ALLMULTI but not IFF_PROMISC set. The chip is
1105 actually in promiscuous mode, so discard unicast packets. */
1106 return((eh->ether_dhost[0] & 1) != 0);
1107}
1108
1109/*
1110 * We want to isolate the bits that have meaning... This assumes that
1111 * IE_RBUF_SIZE is an even power of two. If somehow the act_len exceeds
1112 * the size of the buffer, then we are screwed anyway.
1113 */
1114static __inline int
1115ie_buflen(struct ie_softc * ie, int head)
1116{
1117 return (ie->rbuffs[head]->ie_rbd_actual
1118 & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
1119}
1120
1121static __inline int
1122ie_packet_len(int unit, struct ie_softc * ie)
1123{
1124 int i;
1125 int head = ie->rbhead;
1126 int acc = 0;
1127
1128 do {
1129 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1130#ifdef DEBUG
1131 print_rbd(ie->rbuffs[ie->rbhead]);
1132#endif
1133 log(LOG_ERR,
1134 "ie%d: receive descriptors out of sync at %d\n",
1135 unit, ie->rbhead);
1136 iereset(unit);
1137 return (-1);
1138 }
1139 i = ie->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
1140
1141 acc += ie_buflen(ie, head);
1142 head = (head + 1) % ie->nrxbufs;
1143 } while (!i);
1144
1145 return (acc);
1146}
1147
1148/*
1149 * Read data off the interface, and turn it into an mbuf chain.
1150 *
1151 * This code is DRAMATICALLY different from the previous version; this
1152 * version tries to allocate the entire mbuf chain up front, given the
1153 * length of the data available. This enables us to allocate mbuf
1154 * clusters in many situations where before we would have had a long
1155 * chain of partially-full mbufs. This should help to speed up the
1156 * operation considerably. (Provided that it works, of course.)
1157 */
1158static __inline int
1159ieget(int unit, struct ie_softc *ie, struct mbuf **mp, struct ether_header *ehp)
1160{
1161 struct mbuf *m, *top, **mymp;
1162 int i;
1163 int offset;
1164 int totlen, resid;
1165 int thismboff;
1166 int head;
1167
1168 totlen = ie_packet_len(unit, ie);
1169 if (totlen <= 0)
1170 return (-1);
1171
1172 i = ie->rbhead;
1173
1174 /*
1175 * Snarf the Ethernet header.
1176 */
1177 bcopy((v_caddr_t) ie->cbuffs[i], (caddr_t) ehp, sizeof *ehp);
1178 /* ignore cast-qual warning here */
1179
1180 /*
1181 * As quickly as possible, check if this packet is for us. If not,
1182 * don't waste a single cycle copying the rest of the packet in.
1183 * This is only a consideration when FILTER is defined; i.e., when
1184 * we are either running BPF or doing multicasting.
1185 */
1186 if (!check_eh(ie, ehp)) {
1187 ie_drop_packet_buffer(unit, ie);
1188 ie->arpcom.ac_if.if_ierrors--; /* just this case, it's not an
1189 * error
1190 */
1191 return (-1);
1192 }
1193 totlen -= (offset = sizeof *ehp);
1194
74f1caca 1195 MGETHDR(*mp, MB_DONTWAIT, MT_DATA);
984263bc
MD
1196 if (!*mp) {
1197 ie_drop_packet_buffer(unit, ie);
1198 return (-1);
1199 }
1200 m = *mp;
1201 m->m_pkthdr.rcvif = &ie->arpcom.ac_if;
1202 m->m_len = MHLEN;
1203 resid = m->m_pkthdr.len = totlen;
1204 top = 0;
1205 mymp = &top;
1206
1207 /*
1208 * This loop goes through and allocates mbufs for all the data we
1209 * will be copying in. It does not actually do the copying yet.
1210 */
1211 do { /* while(resid > 0) */
1212 /*
1213 * Try to allocate an mbuf to hold the data that we have.
1214 * If we already allocated one, just get another one and
1215 * stick it on the end (eventually). If we don't already
1216 * have one, try to allocate an mbuf cluster big enough to
1217 * hold the whole packet, if we think it's reasonable, or a
1218 * single mbuf which may or may not be big enough. Got that?
1219 */
1220 if (top) {
74f1caca 1221 MGET(m, MB_DONTWAIT, MT_DATA);
984263bc
MD
1222 if (!m) {
1223 m_freem(top);
1224 ie_drop_packet_buffer(unit, ie);
1225 return (-1);
1226 }
1227 m->m_len = MLEN;
1228 }
1229 if (resid >= MINCLSIZE) {
74f1caca 1230 MCLGET(m, MB_DONTWAIT);
984263bc
MD
1231 if (m->m_flags & M_EXT)
1232 m->m_len = min(resid, MCLBYTES);
1233 } else {
1234 if (resid < m->m_len) {
1235 if (!top && resid + max_linkhdr <= m->m_len)
1236 m->m_data += max_linkhdr;
1237 m->m_len = resid;
1238 }
1239 }
1240 resid -= m->m_len;
1241 *mymp = m;
1242 mymp = &m->m_next;
1243 } while (resid > 0);
1244
1245 resid = totlen;
1246 m = top;
1247 thismboff = 0;
1248 head = ie->rbhead;
1249
1250 /*
1251 * Now we take the mbuf chain (hopefully only one mbuf most of the
1252 * time) and stuff the data into it. There are no possible failures
1253 * at or after this point.
1254 */
1255 while (resid > 0) { /* while there's stuff left */
1256 int thislen = ie_buflen(ie, head) - offset;
1257
1258 /*
1259 * If too much data for the current mbuf, then fill the
1260 * current one up, go to the next one, and try again.
1261 */
1262 if (thislen > m->m_len - thismboff) {
1263 int newlen = m->m_len - thismboff;
1264
1265 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1266 mtod(m, v_caddr_t) +thismboff, (unsigned) newlen);
1267 /* ignore cast-qual warning */
1268 m = m->m_next;
1269 thismboff = 0; /* new mbuf, so no offset */
1270 offset += newlen; /* we are now this far into
1271 * the packet */
1272 resid -= newlen; /* so there is this much left
1273 * to get */
1274 continue;
1275 }
1276 /*
1277 * If there is more than enough space in the mbuf to hold
1278 * the contents of this buffer, copy everything in, advance
1279 * pointers, and so on.
1280 */
1281 if (thislen < m->m_len - thismboff) {
1282 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1283 mtod(m, caddr_t) +thismboff, (unsigned) thislen);
1284 thismboff += thislen; /* we are this far into the
1285 * mbuf */
1286 resid -= thislen; /* and this much is left */
1287 goto nextbuf;
1288 }
1289 /*
1290 * Otherwise, there is exactly enough space to put this
1291 * buffer's contents into the current mbuf. Do the
1292 * combination of the above actions.
1293 */
1294 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1295 mtod(m, caddr_t) + thismboff, (unsigned) thislen);
1296 m = m->m_next;
1297 thismboff = 0; /* new mbuf, start at the beginning */
1298 resid -= thislen; /* and we are this far through */
1299
1300 /*
1301 * Advance all the pointers. We can get here from either of
1302 * the last two cases, but never the first.
1303 */
1304nextbuf:
1305 offset = 0;
1306 ie->rbuffs[head]->ie_rbd_actual = 0;
1307 ie->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST;
1308 ie->rbhead = head = (head + 1) % ie->nrxbufs;
1309 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1310 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1311 }
1312
1313 /*
1314 * Unless something changed strangely while we were doing the copy,
1315 * we have now copied everything in from the shared memory. This
1316 * means that we are done.
1317 */
1318 return (0);
1319}
1320
1321/*
1322 * Read frame NUM from unit UNIT (pre-cached as IE).
1323 *
1324 * This routine reads the RFD at NUM, and copies in the buffers from
1325 * the list of RBD, then rotates the RBD and RFD lists so that the receiver
1326 * doesn't start complaining. Trailers are DROPPED---there's no point
1327 * in wasting time on confusing code to deal with them. Hopefully,
1328 * this machine will never ARP for trailers anyway.
1329 */
1330static void
1331ie_readframe(int unit, struct ie_softc *ie, int num/* frame number to read */)
1332{
1333 struct ie_recv_frame_desc rfd;
1334 struct mbuf *m = 0;
1335 struct ether_header eh;
1336
1337 bcopy((v_caddr_t) (ie->rframes[num]), &rfd,
1338 sizeof(struct ie_recv_frame_desc));
1339
1340 /*
1341 * Immediately advance the RFD list, since we we have copied ours
1342 * now.
1343 */
1344 ie->rframes[num]->ie_fd_status = 0;
1345 ie->rframes[num]->ie_fd_last |= IE_FD_LAST;
1346 ie->rframes[ie->rftail]->ie_fd_last &= ~IE_FD_LAST;
1347 ie->rftail = (ie->rftail + 1) % ie->nframes;
1348 ie->rfhead = (ie->rfhead + 1) % ie->nframes;
1349
1350 if (rfd.ie_fd_status & IE_FD_OK) {
1351 if (ieget(unit, ie, &m, &eh)) {
1352 ie->arpcom.ac_if.if_ierrors++; /* this counts as an
1353 * error */
1354 return;
1355 }
1356 }
1357#ifdef DEBUG
1358 if (ie_debug & IED_READFRAME) {
1359 printf("ie%d: frame from ether %6D type %x\n", unit,
1360 eh.ether_shost, ":", (unsigned) eh.ether_type);
1361 }
1362 if (ntohs(eh.ether_type) > ETHERTYPE_TRAIL
1363 && ntohs(eh.ether_type) < (ETHERTYPE_TRAIL + ETHERTYPE_NTRAILER))
1364 printf("received trailer!\n");
1365#endif
1366
1367 if (!m)
1368 return;
1369
1370 /*
1371 * Finally pass this packet up to higher layers.
1372 */
1373 ether_input(&ie->arpcom.ac_if, &eh, m);
1374}
1375
1376static void
1377ie_drop_packet_buffer(int unit, struct ie_softc * ie)
1378{
1379 int i;
1380
1381 do {
1382 /*
1383 * This means we are somehow out of sync. So, we reset the
1384 * adapter.
1385 */
1386 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1387#ifdef DEBUG
1388 print_rbd(ie->rbuffs[ie->rbhead]);
1389#endif
1390 log(LOG_ERR, "ie%d: receive descriptors out of sync at %d\n",
1391 unit, ie->rbhead);
1392 iereset(unit);
1393 return;
1394 }
1395 i = ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_LAST;
1396
1397 ie->rbuffs[ie->rbhead]->ie_rbd_length |= IE_RBD_LAST;
1398 ie->rbuffs[ie->rbhead]->ie_rbd_actual = 0;
1399 ie->rbhead = (ie->rbhead + 1) % ie->nrxbufs;
1400 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1401 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1402 } while (!i);
1403}
1404
1405
1406/*
1407 * Start transmission on an interface.
1408 */
1409static void
1410iestart(struct ifnet *ifp)
1411{
1412 struct ie_softc *ie = ifp->if_softc;
1413 struct mbuf *m0, *m;
1414 volatile unsigned char *buffer;
1415 u_short len;
1416
1417 /*
1418 * This is not really volatile, in this routine, but it makes gcc
1419 * happy.
1420 */
1421 volatile u_short *bptr = &ie->scb->ie_command_list;
1422
1423 if (!(ifp->if_flags & IFF_RUNNING))
1424 return;
1425 if (ifp->if_flags & IFF_OACTIVE)
1426 return;
1427
1428 do {
1429 IF_DEQUEUE(&ie->arpcom.ac_if.if_snd, m);
1430 if (!m)
1431 break;
1432
1433 buffer = ie->xmit_cbuffs[ie->xmit_count];
1434 len = 0;
1435
1436 for (m0 = m; m && len < IE_BUF_LEN; m = m->m_next) {
1437 bcopy(mtod(m, caddr_t), buffer, m->m_len);
1438 buffer += m->m_len;
1439 len += m->m_len;
1440 }
1441
1442 m_freem(m0);
1443 len = max(len, ETHER_MIN_LEN);
1444
1445 /*
1446 * See if bpf is listening on this interface, let it see the
1447 * packet before we commit it to the wire.
1448 */
c633dd13
JS
1449 BPF_TAP(&ie->arpcom.ac_if,
1450 __DEVOLATILE(u_char *, ie->xmit_cbuffs[ie->xmit_count]),
1451 len);
984263bc
MD
1452
1453 ie->xmit_buffs[ie->xmit_count]->ie_xmit_flags =
1454 IE_XMIT_LAST|len;
1455 ie->xmit_buffs[ie->xmit_count]->ie_xmit_next = 0xffff;
1456 ie->xmit_buffs[ie->xmit_count]->ie_xmit_buf =
1457 MK_24(ie->iomem, ie->xmit_cbuffs[ie->xmit_count]);
1458
1459 ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_cmd = IE_CMD_XMIT;
1460 ie->xmit_cmds[ie->xmit_count]->ie_xmit_status = 0;
1461 ie->xmit_cmds[ie->xmit_count]->ie_xmit_desc =
1462 MK_16(ie->iomem, ie->xmit_buffs[ie->xmit_count]);
1463
1464 *bptr = MK_16(ie->iomem, ie->xmit_cmds[ie->xmit_count]);
1465 bptr = &ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_link;
1466 ie->xmit_count++;
1467 } while (ie->xmit_count < ie->ntxbufs);
1468
1469 /*
1470 * If we queued up anything for transmission, send it.
1471 */
1472 if (ie->xmit_count) {
1473 ie->xmit_cmds[ie->xmit_count - 1]->com.ie_cmd_cmd |=
1474 IE_CMD_LAST | IE_CMD_INTR;
1475
1476 /*
1477 * By passing the command pointer as a null, we tell
1478 * command_and_wait() to pretend that this isn't an action
1479 * command. I wish I understood what was happening here.
1480 */
3e4a09e7 1481 command_and_wait(ifp->if_dunit, IE_CU_START, 0, 0);
984263bc
MD
1482 ifp->if_flags |= IFF_OACTIVE;
1483 }
1484 return;
1485}
1486
1487/*
1488 * Check to see if there's an 82586 out there.
1489 */
1490static int
1491check_ie_present(int unit, caddr_t where, unsigned size)
1492{
1493 volatile struct ie_sys_conf_ptr *scp;
1494 volatile struct ie_int_sys_conf_ptr *iscp;
1495 volatile struct ie_sys_ctl_block *scb;
1496 u_long realbase;
1497 int s;
1498
1499 s = splimp();
1500
1501 realbase = (uintptr_t) where + size - (1 << 24);
1502
1503 scp = (volatile struct ie_sys_conf_ptr *) (uintptr_t)
1504 (realbase + IE_SCP_ADDR);
1505 bzero((volatile char *) scp, sizeof *scp);
1506
1507 /*
1508 * First we put the ISCP at the bottom of memory; this tests to make
1509 * sure that our idea of the size of memory is the same as the
1510 * controller's. This is NOT where the ISCP will be in normal
1511 * operation.
1512 */
1513 iscp = (volatile struct ie_int_sys_conf_ptr *) where;
1514 bzero((volatile char *)iscp, sizeof *iscp);
1515
1516 scb = (volatile struct ie_sys_ctl_block *) where;
1517 bzero((volatile char *)scb, sizeof *scb);
1518
1519 scp->ie_bus_use = ie_softc[unit].bus_use; /* 8-bit or 16-bit */
1520 scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1521 ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1522
1523 iscp->ie_busy = 1;
1524 iscp->ie_scb_offset = MK_16(realbase, scb) + 256;
1525
1526 (*ie_softc[unit].ie_reset_586) (unit);
1527 (*ie_softc[unit].ie_chan_attn) (unit);
1528
1529 DELAY(100); /* wait a while... */
1530
1531 if (iscp->ie_busy) {
1532 splx(s);
1533 return (0);
1534 }
1535 /*
1536 * Now relocate the ISCP to its real home, and reset the controller
1537 * again.
1538 */
1539 iscp = (void *) Align((caddr_t) (uintptr_t)
1540 (realbase + IE_SCP_ADDR -
1541 sizeof(struct ie_int_sys_conf_ptr)));
1542 bzero((volatile char *) iscp, sizeof *iscp); /* ignore cast-qual */
1543
1544 scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1545 ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1546
1547 iscp->ie_busy = 1;
1548 iscp->ie_scb_offset = MK_16(realbase, scb);
1549
1550 (*ie_softc[unit].ie_reset_586) (unit);
1551 (*ie_softc[unit].ie_chan_attn) (unit);
1552
1553 DELAY(100);
1554
1555 if (iscp->ie_busy) {
1556 splx(s);
1557 return (0);
1558 }
1559 ie_softc[unit].iosize = size;
1560 ie_softc[unit].iomem = (caddr_t) (uintptr_t) realbase;
1561
1562 ie_softc[unit].iscp = iscp;
1563 ie_softc[unit].scb = scb;
1564
1565 /*
1566 * Acknowledge any interrupts we may have caused...
1567 */
1568 ie_ack(scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
1569 splx(s);
1570
1571 return (1);
1572}
1573
1574/*
1575 * Divine the memory size of ie board UNIT.
1576 * Better hope there's nothing important hiding just below the ie card...
1577 */
1578static void
1579find_ie_mem_size(int unit)
1580{
1581 unsigned size;
1582
1583 ie_softc[unit].iosize = 0;
1584
1585 for (size = 65536; size >= 8192; size -= 8192) {
1586 if (check_ie_present(unit, ie_softc[unit].iomembot, size)) {
1587 return;
1588 }
1589 }
1590
1591 return;
1592}
1593
1594void
1595el_reset_586(int unit)
1596{
1597 outb(PORT + IE507_CTRL, EL_CTRL_RESET);
1598 DELAY(100);
1599 outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
1600 DELAY(100);
1601}
1602
1603void
1604sl_reset_586(int unit)
1605{
1606 outb(PORT + IEATT_RESET, 0);
1607}
1608
1609void
1610ee16_reset_586(int unit)
1611{
1612 outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
1613 DELAY(100);
1614 outb(PORT + IEE16_ECTRL, 0);
1615 DELAY(100);
1616}
1617
1618void
1619el_chan_attn(int unit)
1620{
1621 outb(PORT + IE507_ATTN, 1);
1622}
1623
1624void
1625sl_chan_attn(int unit)
1626{
1627 outb(PORT + IEATT_ATTN, 0);
1628}
1629
1630void
1631ee16_chan_attn(int unit)
1632{
1633 outb(PORT + IEE16_ATTN, 0);
1634}
1635
1636u_short
1637ee16_read_eeprom(struct ie_softc *sc, int location)
1638{
1639 int ectrl, edata;
1640
1641 ectrl = inb(sc->port + IEE16_ECTRL);
1642 ectrl &= IEE16_ECTRL_MASK;
1643 ectrl |= IEE16_ECTRL_EECS;
1644 outb(sc->port + IEE16_ECTRL, ectrl);
1645
1646 ee16_eeprom_outbits(sc, IEE16_EEPROM_READ, IEE16_EEPROM_OPSIZE1);
1647 ee16_eeprom_outbits(sc, location, IEE16_EEPROM_ADDR_SIZE);
1648 edata = ee16_eeprom_inbits(sc);
1649 ectrl = inb(sc->port + IEE16_ECTRL);
1650 ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EEDI | IEE16_ECTRL_EECS);
1651 outb(sc->port + IEE16_ECTRL, ectrl);
1652 ee16_eeprom_clock(sc, 1);
1653 ee16_eeprom_clock(sc, 0);
1654 return edata;
1655}
1656
1657void
1658ee16_eeprom_outbits(struct ie_softc *sc, int edata, int count)
1659{
1660 int ectrl, i;
1661
1662 ectrl = inb(sc->port + IEE16_ECTRL);
1663 ectrl &= ~IEE16_RESET_ASIC;
1664 for (i = count - 1; i >= 0; i--) {
1665 ectrl &= ~IEE16_ECTRL_EEDI;
1666 if (edata & (1 << i)) {
1667 ectrl |= IEE16_ECTRL_EEDI;
1668 }
1669 outb(sc->port + IEE16_ECTRL, ectrl);
1670 DELAY(1); /* eeprom data must be setup for 0.4 uSec */
1671 ee16_eeprom_clock(sc, 1);
1672 ee16_eeprom_clock(sc, 0);
1673 }
1674 ectrl &= ~IEE16_ECTRL_EEDI;
1675 outb(sc->port + IEE16_ECTRL, ectrl);
1676 DELAY(1); /* eeprom data must be held for 0.4 uSec */
1677}
1678
1679int
1680ee16_eeprom_inbits(struct ie_softc *sc)
1681{
1682 int ectrl, edata, i;
1683
1684 ectrl = inb(sc->port + IEE16_ECTRL);
1685 ectrl &= ~IEE16_RESET_ASIC;
1686 for (edata = 0, i = 0; i < 16; i++) {
1687 edata = edata << 1;
1688 ee16_eeprom_clock(sc, 1);
1689 ectrl = inb(sc->port + IEE16_ECTRL);
1690 if (ectrl & IEE16_ECTRL_EEDO) {
1691 edata |= 1;
1692 }
1693 ee16_eeprom_clock(sc, 0);
1694 }
1695 return (edata);
1696}
1697
1698void
1699ee16_eeprom_clock(struct ie_softc *sc, int state)
1700{
1701 int ectrl;
1702
1703 ectrl = inb(sc->port + IEE16_ECTRL);
1704 ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EESK);
1705 if (state) {
1706 ectrl |= IEE16_ECTRL_EESK;
1707 }
1708 outb(sc->port + IEE16_ECTRL, ectrl);
1709 DELAY(9); /* EESK must be stable for 8.38 uSec */
1710}
1711
1712static __inline void
1713ee16_interrupt_enable(struct ie_softc *sc)
1714{
1715 DELAY(100);
1716 outb(sc->port + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
1717 DELAY(100);
1718}
1719
1720void
1721sl_read_ether(int unit, unsigned char addr[6])
1722{
1723 int i;
1724
1725 for (i = 0; i < 6; i++)
1726 addr[i] = inb(PORT + i);
1727}
1728
1729
1730static void
1731iereset(int unit)
1732{
1733 int s = splimp();
1734
1735 if (unit >= NIE) {
1736 splx(s);
1737 return;
1738 }
1739 printf("ie%d: reset\n", unit);
1740 ie_softc[unit].arpcom.ac_if.if_flags &= ~IFF_UP;
bd4539cc 1741 ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0, (struct ucred *)NULL);
984263bc
MD
1742
1743 /*
1744 * Stop i82586 dead in its tracks.
1745 */
1746 if (command_and_wait(unit, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
1747 printf("ie%d: abort commands timed out\n", unit);
1748
1749 if (command_and_wait(unit, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1750 printf("ie%d: disable commands timed out\n", unit);
1751
1752#ifdef notdef
1753 if (!check_ie_present(unit, ie_softc[unit].iomembot,
1754 e_softc[unit].iosize))
1755 panic("ie disappeared!");
1756#endif
1757
1758 ie_softc[unit].arpcom.ac_if.if_flags |= IFF_UP;
bd4539cc 1759 ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0, (struct ucred *)NULL);
984263bc
MD
1760
1761 splx(s);
1762 return;
1763}
1764
1765/*
1766 * This is called if we time out.
1767 */
1768static void
1769chan_attn_timeout(void *rock)
1770{
1771 *(int *) rock = 1;
1772}
1773
1774/*
1775 * Send a command to the controller and wait for it to either
1776 * complete or be accepted, depending on the command. If the
1777 * command pointer is null, then pretend that the command is
1778 * not an action command. If the command pointer is not null,
1779 * and the command is an action command, wait for
1780 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
1781 * to become true.
1782 */
1783static int
1784command_and_wait(int unit, int cmd, volatile void *pcmd, int mask)
1785{
1786 volatile struct ie_cmd_common *cc = pcmd;
1787 volatile int timedout = 0;
1788 struct callout_handle ch;
1789
1790 ie_softc[unit].scb->ie_command = (u_short) cmd;
1791
1792 if (IE_ACTION_COMMAND(cmd) && pcmd) {
1793 (*ie_softc[unit].ie_chan_attn) (unit);
1794
1795 /*
1796 * According to the packet driver, the minimum timeout
1797 * should be .369 seconds, which we round up to .37.
1798 */
c633dd13 1799 ch = timeout(chan_attn_timeout, __DEVOLATILE(int *, &timedout),
984263bc
MD
1800 37 * hz / 100);
1801 /* ignore cast-qual */
1802
1803 /*
1804 * Now spin-lock waiting for status. This is not a very
1805 * nice thing to do, but I haven't figured out how, or
1806 * indeed if, we can put the process waiting for action to
1807 * sleep. (We may be getting called through some other
1808 * timeout running in the kernel.)
1809 */
1810 while (1) {
1811 if ((cc->ie_cmd_status & mask) || timedout)
1812 break;
1813 }
1814
c633dd13 1815 untimeout(chan_attn_timeout, __DEVOLATILE(int *, &timedout), ch);
984263bc
MD
1816 /* ignore cast-qual */
1817
1818 return (timedout);
1819 } else {
1820
1821 /*
1822 * Otherwise, just wait for the command to be accepted.
1823 */
1824 (*ie_softc[unit].ie_chan_attn) (unit);
1825
1826 while (ie_softc[unit].scb->ie_command); /* spin lock */
1827
1828 return (0);
1829 }
1830}
1831
1832/*
1833 * Run the time-domain reflectometer...
1834 */
1835static void
1836run_tdr(int unit, volatile struct ie_tdr_cmd *cmd)
1837{
1838 int result;
1839
1840 cmd->com.ie_cmd_status = 0;
1841 cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
1842 cmd->com.ie_cmd_link = 0xffff;
1843 cmd->ie_tdr_time = 0;
1844
1845 ie_softc[unit].scb->ie_command_list = MK_16(MEM, cmd);
1846 cmd->ie_tdr_time = 0;
1847
1848 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL))
1849 result = 0x2000;
1850 else
1851 result = cmd->ie_tdr_time;
1852
1853 ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit,
1854 ie_softc[unit].ie_chan_attn);
1855
1856 if (result & IE_TDR_SUCCESS)
1857 return;
1858
1859 if (result & IE_TDR_XCVR) {
1860 printf("ie%d: transceiver problem\n", unit);
1861 } else if (result & IE_TDR_OPEN) {
1862 printf("ie%d: TDR detected an open %d clocks away\n", unit,
1863 result & IE_TDR_TIME);
1864 } else if (result & IE_TDR_SHORT) {
1865 printf("ie%d: TDR detected a short %d clocks away\n", unit,
1866 result & IE_TDR_TIME);
1867 } else {
1868 printf("ie%d: TDR returned unknown status %x\n", unit, result);
1869 }
1870}
1871
1872static void
1873start_receiver(int unit)
1874{
1875 int s = splimp();
1876
1877 ie_softc[unit].scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1878 command_and_wait(unit, IE_RU_START, 0, 0);
1879
1880 ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
1881
1882 splx(s);
1883}
1884
1885/*
1886 * Here is a helper routine for iernr() and ieinit(). This sets up
1887 * the RFA.
1888 */
1889static v_caddr_t
1890setup_rfa(v_caddr_t ptr, struct ie_softc * ie)
1891{
1892 volatile struct ie_recv_frame_desc *rfd = (volatile void *)ptr;
1893 volatile struct ie_recv_buf_desc *rbd;
1894 int i;
1895 int unit = ie - &ie_softc[0];
1896
1897 /* First lay them out */
1898 for (i = 0; i < ie->nframes; i++) {
1899 ie->rframes[i] = rfd;
1900 bzero((volatile char *) rfd, sizeof *rfd); /* ignore cast-qual */
1901 rfd++;
1902 }
1903
1904 ptr = Alignvol(rfd); /* ignore cast-qual */
1905
1906 /* Now link them together */
1907 for (i = 0; i < ie->nframes; i++) {
1908 ie->rframes[i]->ie_fd_next =
1909 MK_16(MEM, ie->rframes[(i + 1) % ie->nframes]);
1910 }
1911
1912 /* Finally, set the EOL bit on the last one. */
1913 ie->rframes[ie->nframes - 1]->ie_fd_last |= IE_FD_LAST;
1914
1915 /*
1916 * Now lay out some buffers for the incoming frames. Note that we
1917 * set aside a bit of slop in each buffer, to make sure that we have
1918 * enough space to hold a single frame in every buffer.
1919 */
1920 rbd = (volatile void *) ptr;
1921
1922 for (i = 0; i < ie->nrxbufs; i++) {
1923 ie->rbuffs[i] = rbd;
1924 bzero((volatile char *)rbd, sizeof *rbd);
1925 ptr = Alignvol(ptr + sizeof *rbd);
1926 rbd->ie_rbd_length = IE_RBUF_SIZE;
1927 rbd->ie_rbd_buffer = MK_24(MEM, ptr);
1928 ie->cbuffs[i] = (volatile void *) ptr;
1929 ptr += IE_RBUF_SIZE;
1930 rbd = (volatile void *) ptr;
1931 }
1932
1933 /* Now link them together */
1934 for (i = 0; i < ie->nrxbufs; i++) {
1935 ie->rbuffs[i]->ie_rbd_next =
1936 MK_16(MEM, ie->rbuffs[(i + 1) % ie->nrxbufs]);
1937 }
1938
1939 /* Tag EOF on the last one */
1940 ie->rbuffs[ie->nrxbufs - 1]->ie_rbd_length |= IE_RBD_LAST;
1941
1942 /*
1943 * We use the head and tail pointers on receive to keep track of the
1944 * order in which RFDs and RBDs are used.
1945 */
1946 ie->rfhead = 0;
1947 ie->rftail = ie->nframes - 1;
1948 ie->rbhead = 0;
1949 ie->rbtail = ie->nrxbufs - 1;
1950
1951 ie->scb->ie_recv_list = MK_16(MEM, ie->rframes[0]);
1952 ie->rframes[0]->ie_fd_buf_desc = MK_16(MEM, ie->rbuffs[0]);
1953
1954 ptr = Alignvol(ptr);
1955 return (ptr);
1956}
1957
1958/*
1959 * Run the multicast setup command.
1960 * Call at splimp().
1961 */
1962static int
1963mc_setup(int unit, v_caddr_t ptr,
1964 volatile struct ie_sys_ctl_block * scb)
1965{
1966 struct ie_softc *ie = &ie_softc[unit];
1967 volatile struct ie_mcast_cmd *cmd = (volatile void *) ptr;
1968
1969 cmd->com.ie_cmd_status = 0;
1970 cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
1971 cmd->com.ie_cmd_link = 0xffff;
1972
1973 /* ignore cast-qual */
1974 bcopy((v_caddr_t) ie->mcast_addrs, (v_caddr_t) cmd->ie_mcast_addrs,
1975 ie->mcast_count * sizeof *ie->mcast_addrs);
1976
1977 cmd->ie_mcast_bytes = ie->mcast_count * 6; /* grrr... */
1978
1979 scb->ie_command_list = MK_16(MEM, cmd);
1980 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
1981 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1982 printf("ie%d: multicast address setup command failed\n", unit);
1983 return (0);
1984 }
1985 return (1);
1986}
1987
1988/*
1989 * This routine takes the environment generated by check_ie_present()
1990 * and adds to it all the other structures we need to operate the adapter.
1991 * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
1992 * starting the receiver unit, and clearing interrupts.
1993 *
1994 * THIS ROUTINE MUST BE CALLED AT splimp() OR HIGHER.
1995 */
1996static void
1997ieinit(xsc)
1998 void *xsc;
1999{
2000 struct ie_softc *ie = xsc;
2001 volatile struct ie_sys_ctl_block *scb = ie->scb;
2002 v_caddr_t ptr;
2003 int i;
2004 int unit = ie->unit;
2005
2006 ptr = Alignvol((volatile char *) scb + sizeof *scb);
2007
2008 /*
2009 * Send the configure command first.
2010 */
2011 {
2012 volatile struct ie_config_cmd *cmd = (volatile void *) ptr;
2013
2014 ie_setup_config(cmd, ie->promisc,
2015 ie->hard_type == IE_STARLAN10);
2016 cmd->com.ie_cmd_status = 0;
2017 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
2018 cmd->com.ie_cmd_link = 0xffff;
2019
2020 scb->ie_command_list = MK_16(MEM, cmd);
2021
2022 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2023 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2024 printf("ie%d: configure command failed\n", unit);
2025 return;
2026 }
2027 }
2028 /*
2029 * Now send the Individual Address Setup command.
2030 */
2031 {
2032 volatile struct ie_iasetup_cmd *cmd = (volatile void *) ptr;
2033
2034 cmd->com.ie_cmd_status = 0;
2035 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
2036 cmd->com.ie_cmd_link = 0xffff;
2037
2038 bcopy((volatile char *)ie_softc[unit].arpcom.ac_enaddr,
2039 (volatile char *)&cmd->ie_address, sizeof cmd->ie_address);
2040 scb->ie_command_list = MK_16(MEM, cmd);
2041 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2042 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2043 printf("ie%d: individual address "
2044 "setup command failed\n", unit);
2045 return;
2046 }
2047 }
2048
2049 /*
2050 * Now run the time-domain reflectometer.
2051 */
2052 run_tdr(unit, (volatile void *) ptr);
2053
2054 /*
2055 * Acknowledge any interrupts we have generated thus far.
2056 */
2057 ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
2058
2059 /*
2060 * Set up the RFA.
2061 */
2062 ptr = setup_rfa(ptr, ie);
2063
2064 /*
2065 * Finally, the transmit command and buffer are the last little bit
2066 * of work.
2067 */
2068
2069 /* transmit command buffers */
2070 for (i = 0; i < ie->ntxbufs; i++) {
2071 ie->xmit_cmds[i] = (volatile void *) ptr;
2072 ptr += sizeof *ie->xmit_cmds[i];
2073 ptr = Alignvol(ptr);
2074 ie->xmit_buffs[i] = (volatile void *)ptr;
2075 ptr += sizeof *ie->xmit_buffs[i];
2076 ptr = Alignvol(ptr);
2077 }
2078
2079 /* transmit buffers */
2080 for (i = 0; i < ie->ntxbufs - 1; i++) {
2081 ie->xmit_cbuffs[i] = (volatile void *)ptr;
2082 ptr += IE_BUF_LEN;
2083 ptr = Alignvol(ptr);
2084 }
2085 ie->xmit_cbuffs[ie->ntxbufs - 1] = (volatile void *) ptr;
2086
2087 for (i = 1; i < ie->ntxbufs; i++) {
2088 bzero((v_caddr_t) ie->xmit_cmds[i], sizeof *ie->xmit_cmds[i]);
2089 bzero((v_caddr_t) ie->xmit_buffs[i], sizeof *ie->xmit_buffs[i]);
2090 }
2091
2092 /*
2093 * This must be coordinated with iestart() and ietint().
2094 */
2095 ie->xmit_cmds[0]->ie_xmit_status = IE_STAT_COMPL;
2096
2097 /* take the ee16 out of loopback */
2098 if (ie->hard_type == IE_EE16) {
2099 u_int8_t bart_config;
2100
2101 bart_config = inb(PORT + IEE16_CONFIG);
2102 bart_config &= ~IEE16_BART_LOOPBACK;
2103 /* inb doesn't get bit! */
2104 bart_config |= IEE16_BART_MCS16_TEST;
2105 outb(PORT + IEE16_CONFIG, bart_config);
2106 ee16_interrupt_enable(ie);
2107 ee16_chan_attn(unit);
2108 }
2109 ie->arpcom.ac_if.if_flags |= IFF_RUNNING; /* tell higher levels
2110 * we're here */
2111 start_receiver(unit);
2112
2113 return;
2114}
2115
2116static void
2117ie_stop(int unit)
2118{
2119 command_and_wait(unit, IE_RU_DISABLE, 0, 0);
2120}
2121
2122static int
bd4539cc 2123ieioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
984263bc
MD
2124{
2125 int s, error = 0;
2126
2127 s = splimp();
2128
2129 switch (command) {
2130 case SIOCSIFADDR:
2131 case SIOCGIFADDR:
2132 case SIOCSIFMTU:
2133 error = ether_ioctl(ifp, command, data);
2134 break;
2135
2136 case SIOCSIFFLAGS:
2137 /*
2138 * Note that this device doesn't have an "all multicast"
2139 * mode, so we must turn on promiscuous mode and do the
2140 * filtering manually.
2141 */
2142 if ((ifp->if_flags & IFF_UP) == 0 &&
2143 (ifp->if_flags & IFF_RUNNING)) {
2144 ifp->if_flags &= ~IFF_RUNNING;
3e4a09e7 2145 ie_stop(ifp->if_dunit);
984263bc
MD
2146 } else if ((ifp->if_flags & IFF_UP) &&
2147 (ifp->if_flags & IFF_RUNNING) == 0) {
3e4a09e7 2148 ie_softc[ifp->if_dunit].promisc =
984263bc
MD
2149 ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2150 ieinit(ifp->if_softc);
3e4a09e7 2151 } else if (ie_softc[ifp->if_dunit].promisc ^
984263bc 2152 (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI))) {
3e4a09e7 2153 ie_softc[ifp->if_dunit].promisc =
984263bc
MD
2154 ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2155 ieinit(ifp->if_softc);
2156 }
2157 break;
2158
2159 case SIOCADDMULTI:
2160 case SIOCDELMULTI:
2161 /*
2162 * Update multicast listeners
2163 */
2164 /* reset multicast filtering */
3e4a09e7 2165 ie_mc_reset(ifp->if_dunit);
984263bc
MD
2166 error = 0;
2167 break;
2168
2169 default:
2170 error = EINVAL;
2171 }
2172
2173 splx(s);
2174 return (error);
2175}
2176
2177static void
2178ie_mc_reset(int unit)
2179{
2180 struct ie_softc *ie = &ie_softc[unit];
2181 struct ifmultiaddr *ifma;
2182
2183 /*
2184 * Step through the list of addresses.
2185 */
2186 ie->mcast_count = 0;
2187 for (ifma = ie->arpcom.ac_if.if_multiaddrs.lh_first; ifma;
2188 ifma = ifma->ifma_link.le_next) {
2189 if (ifma->ifma_addr->sa_family != AF_LINK)
2190 continue;
2191
2192 /* XXX - this is broken... */
2193 if (ie->mcast_count >= MAXMCAST) {
2194 ie->arpcom.ac_if.if_flags |= IFF_ALLMULTI;
bd4539cc
JH
2195 ieioctl(&ie->arpcom.ac_if, SIOCSIFFLAGS, (void *) 0,
2196 (struct ucred *)NULL);
984263bc
MD
2197 goto setflag;
2198 }
2199 bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
2200 &(ie->mcast_addrs[ie->mcast_count]), 6);
2201 ie->mcast_count++;
2202 }
2203
2204setflag:
2205 ie->want_mcsetup = 1;
2206}
2207
2208
2209#ifdef DEBUG
2210static void
2211print_rbd(volatile struct ie_recv_buf_desc * rbd)
2212{
2213 printf("RBD at %p:\n"
2214 "actual %04x, next %04x, buffer %p\n"
2215 "length %04x, mbz %04x\n",
2216 (volatile void *) rbd,
2217 rbd->ie_rbd_actual, rbd->ie_rbd_next,
2218 (void *) rbd->ie_rbd_buffer,
2219 rbd->ie_rbd_length, rbd->mbz);
2220}
2221
2222#endif /* DEBUG */