gold: Fix hardcoded library search path
[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 $
51 */
52
53/*
54 * Intel 82586 Ethernet chip
55 * Register, bit, and structure definitions.
56 *
57 * Written by GAW with reference to the Clarkson Packet Driver code for this
58 * chip written by Russ Nelson and others.
59 *
60 * Intel EtherExpress 16 support from if_ix.c, written by Rodney W. Grimes.
61 */
62
63/*
64 * The i82586 is a very versatile chip, found in many implementations.
65 * Programming this chip is mostly the same, but certain details differ
66 * from card to card. This driver is written so that different cards
67 * can be automatically detected at run-time.
68 */
69
70/*
71Mode of operation:
72
73We run the 82586 in a standard Ethernet mode. We keep NFRAMES received
74frame descriptors around for the receiver to use, and NRXBUFS associated
75receive buffer descriptors, both in a circular list. Whenever a frame is
76received, we rotate both lists as necessary. (The 586 treats both lists
77as a simple queue.) We also keep a transmit command around so that packets
78can be sent off quickly.
79
80We configure the adapter in AL-LOC = 1 mode, which means that the
81Ethernet/802.3 MAC header is placed at the beginning of the receive buffer
82rather than being split off into various fields in the RFD. This also
83means that we must include this header in the transmit buffer as well.
84
85By convention, all transmit commands, and only transmit commands, shall
86have the I (IE_CMD_INTR) bit set in the command. This way, when an
87interrupt arrives at ieintr(), it is immediately possible to tell
88what precisely caused it. ANY OTHER command-sending routines should
89run at splimp(), and should post an acknowledgement to every interrupt
90they generate.
91
92The 82586 has a 24-bit address space internally, and the adaptor's memory
93is located at the top of this region. However, the value we are given in
94configuration is normally the *bottom* of the adaptor RAM. So, we must go
95through a few gyrations to come up with a kernel virtual address which
96represents the actual beginning of the 586 address space. First, we
97autosize the RAM by running through several possible sizes and trying to
98initialize the adapter under the assumption that the selected size is
99correct. Then, knowing the correct RAM size, we set up our pointers in
100ie_softc[unit]. `iomem' represents the computed base of the 586 address
101space. `iomembot' represents the actual configured base of adapter RAM.
102Finally, `iosize' represents the calculated size of 586 RAM. Then, when
103laying out commands, we use the interval [iomembot, iomembot + iosize); to
104make 24-pointers, we subtract iomem, and to make 16-pointers, we subtract
105iomem and and with 0xffff.
106
107*/
108
1f2de5d4 109#include "use_ie.h"
984263bc
MD
110#include "opt_inet.h"
111#include "opt_ipx.h"
112
113#include <sys/param.h>
114#include <sys/systm.h>
115#include <sys/eventhandler.h>
116#include <sys/kernel.h>
117#include <sys/malloc.h>
118#include <sys/conf.h>
119#include <sys/mbuf.h>
120#include <sys/socket.h>
121#include <sys/sockio.h>
122#include <sys/syslog.h>
ec15e0df 123#include <sys/thread2.h>
984263bc
MD
124
125#include <net/ethernet.h>
126#include <net/if.h>
2c4ce138 127#include <net/ifq_var.h>
984263bc
MD
128#include <net/if_types.h>
129#include <net/if_dl.h>
130
131#include <netinet/in.h>
132#include <netinet/if_ether.h>
133
134#include <machine/clock.h>
664f5072 135#include <machine/inttypes.h>
984263bc
MD
136#include <machine/md_var.h>
137
21ce0dfa 138#include <bus/isa/isa_device.h>
a9295349
MD
139#include <machine_base/isa/ic/i82586.h>
140#include <machine_base/icu/icu.h>
1f2de5d4
MD
141#include "if_iereg.h"
142#include "if_ie507.h"
143#include "if_iee16.h"
144#include "../elink_layer/elink.h"
984263bc
MD
145
146#include <net/bpf.h>
147
148#ifdef DEBUG
149#define IED_RINT 0x01
150#define IED_TINT 0x02
151#define IED_RNR 0x04
152#define IED_CNA 0x08
153#define IED_READFRAME 0x10
154static int ie_debug = IED_RNR;
155
156#endif
157
32832096
MD
158DECLARE_DUMMY_MODULE(if_ie);
159
984263bc
MD
160#define IE_BUF_LEN ETHER_MAX_LEN /* length of transmit buffer */
161
162/* Forward declaration */
163struct ie_softc;
164
165static int ieprobe(struct isa_device * dvp);
166static int ieattach(struct isa_device * dvp);
7349cf53 167static void ieintr(void *);
984263bc
MD
168static int sl_probe(struct isa_device * dvp);
169static int el_probe(struct isa_device * dvp);
170static int ni_probe(struct isa_device * dvp);
171static int ee16_probe(struct isa_device * dvp);
172
173static int check_ie_present(int unit, caddr_t where, unsigned size);
174static void ieinit(void *);
175static void ie_stop(int unit);
bd4539cc
JH
176static int ieioctl(struct ifnet * ifp, u_long command, caddr_t data,
177 struct ucred *);
984263bc
MD
178static void iestart(struct ifnet * ifp);
179
180static void el_reset_586(int unit);
181static void el_chan_attn(int unit);
182
183static void sl_reset_586(int unit);
184static void sl_chan_attn(int unit);
185
186static void ee16_reset_586(int unit);
187static void ee16_chan_attn(int unit);
188static __inline void ee16_interrupt_enable(struct ie_softc * ie);
189static void ee16_eeprom_outbits(struct ie_softc * ie, int edata, int cnt);
190static void ee16_eeprom_clock(struct ie_softc * ie, int state);
191static u_short ee16_read_eeprom(struct ie_softc * ie, int location);
192static int ee16_eeprom_inbits(struct ie_softc * ie);
193static void ee16_shutdown(void *sc, int howto);
194
195static void iereset(int unit);
196static void ie_readframe(int unit, struct ie_softc * ie, int bufno);
197static void ie_drop_packet_buffer(int unit, struct ie_softc * ie);
198static void sl_read_ether(int unit, unsigned char addr[6]);
199static void find_ie_mem_size(int unit);
984263bc
MD
200static int command_and_wait(int unit, int command,
201 void volatile * pcmd, int);
202static void run_tdr(int unit, volatile struct ie_tdr_cmd * cmd);
203static int ierint(int unit, struct ie_softc * ie);
204static int ietint(int unit, struct ie_softc * ie);
205static int iernr(int unit, struct ie_softc * ie);
206static void start_receiver(int unit);
78195a76 207static __inline int ieget(int, struct ie_softc *, struct mbuf **);
984263bc
MD
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)
e3869ec7 396 kprintf("ie%d: unknown AT&T board type code %d\n", unit,
984263bc
MD
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
e3869ec7 433 kprintf("ie%d: can't map 3C507 RAM in high memory\n", unit);
984263bc
MD
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)) {
e3869ec7 451 kprintf("ie%d: kernel configured irq %d "
984263bc
MD
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)) {
664f5072 459 kprintf("ie%d: kernel configured maddr %"PRIx64" "
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) {
e3869ec7 475 kprintf("ie%d: can't find shared memory\n", unit);
984263bc
MD
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) {
e3869ec7 482 kprintf("ie%d: kernel configured msize %d "
984263bc
MD
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) {
e3869ec7 538 kprintf("ie%d: kernel configured msize %d "
984263bc
MD
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
df308fcd
MD
577 short irq_translate[] = {0, 1 << ICU_IRQ9, 1 << ICU_IRQ3,
578 1 << ICU_IRQ4, 1 << ICU_IRQ5,
579 1 << ICU_IRQ10, 1 << ICU_IRQ11, 0};
984263bc
MD
580 char irq_encode[] = {0, 0, 0, 2, 3, 4, 0, 0, 0, 1, 5, 6, 0, 0, 0, 0};
581
582 /* Need this for part of the probe. */
583 sc->ie_reset_586 = ee16_reset_586;
584 sc->ie_chan_attn = ee16_chan_attn;
585
586 /* unsure if this is necessary */
587 sc->bus_use = 0;
588
589 /* reset any ee16 at the current iobase */
590 outb(dvp->id_iobase + IEE16_ECTRL, IEE16_RESET_ASIC);
591 outb(dvp->id_iobase + IEE16_ECTRL, 0);
592 DELAY(240);
593
594 /* now look for ee16. */
595 board_id = id_var1 = id_var2 = 0;
596 for (i = 0; i < 4; i++) {
597 id_var1 = inb(dvp->id_iobase + IEE16_ID_PORT);
598 id_var2 = ((id_var1 & 0x03) << 2);
599 board_id |= ((id_var1 >> 4) << id_var2);
600 }
601
602 if (board_id != IEE16_ID) {
603 if (bootverbose)
e3869ec7 604 kprintf("ie%d: unknown board_id: %x\n", unit, board_id);
984263bc
MD
605 return (0);
606 }
607 /* need sc->port for ee16_read_eeprom */
608 sc->port = dvp->id_iobase;
609 sc->hard_type = IE_EE16;
610
611 /*
612 * The shared RAM location on the EE16 is encoded into bits 3-7 of
613 * EEPROM location 6. We zero the upper byte, and shift the 5 bits
614 * right 3. The resulting number tells us the RAM location.
615 * Because the EE16 supports either 16k or 32k of shared RAM, we
616 * only worry about the 32k locations.
617 *
618 * NOTE: if a 64k EE16 exists, it should be added to this switch. then
619 * the ia->ia_msize would need to be set per case statement.
620 *
621 * value msize location ===== ===== ======== 0x03 0x8000
622 * 0xCC000 0x06 0x8000 0xD0000 0x0C 0x8000 0xD4000 0x18
623 * 0x8000 0xD8000
624 *
625 */
626
627 bd_maddr = 0;
628 i = (ee16_read_eeprom(sc, 6) & 0x00ff) >> 3;
629 switch (i) {
630 case 0x03:
631 bd_maddr = 0xCC000;
632 break;
633 case 0x06:
634 bd_maddr = 0xD0000;
635 break;
636 case 0x0c:
637 bd_maddr = 0xD4000;
638 break;
639 case 0x18:
640 bd_maddr = 0xD8000;
641 break;
642 default:
643 bd_maddr = 0;
644 break;
645 }
646 dvp->id_msize = 0x8000;
647 if (kvtop(dvp->id_maddr) != bd_maddr) {
664f5072 648 kprintf("ie%d: kernel configured maddr %"PRIx64" "
984263bc
MD
649 "doesn't match board configured maddr %lx\n",
650 unit, kvtop(dvp->id_maddr), bd_maddr);
651 }
652 sc->iomembot = dvp->id_maddr;
653 sc->iomem = 0; /* XXX some probes set this and some don't */
654 sc->iosize = dvp->id_msize;
655
656 /* need to put the 586 in RESET while we access the eeprom. */
657 outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
658
659 /* read the eeprom and checksum it, should == IEE16_ID */
660 for (i = 0; i < 0x40; i++)
661 checksum += ee16_read_eeprom(sc, i);
662
663 if (checksum != IEE16_ID) {
e3869ec7 664 kprintf("ie%d: invalid eeprom checksum: %x\n", unit, checksum);
984263bc
MD
665 return (0);
666 }
667 /*
668 * Size and test the memory on the board. The size of the memory
669 * can be one of 16k, 32k, 48k or 64k. It can be located in the
670 * address range 0xC0000 to 0xEFFFF on 16k boundaries.
671 *
672 * If the size does not match the passed in memory allocation size
673 * issue a warning, but continue with the minimum of the two sizes.
674 */
675
676 switch (dvp->id_msize) {
677 case 65536:
678 case 32768: /* XXX Only support 32k and 64k right now */
679 break;
680 case 16384:
681 case 49512:
682 default:
e3869ec7 683 kprintf("ie%d: mapped memory size %d not supported\n", unit,
984263bc
MD
684 dvp->id_msize);
685 return (0);
686 break; /* NOTREACHED */
687 }
688
689 if ((kvtop(dvp->id_maddr) < 0xC0000) ||
690 (kvtop(dvp->id_maddr) + sc->iosize > 0xF0000)) {
e3869ec7 691 kprintf("ie%d: mapped memory location %p out of range\n", unit,
984263bc
MD
692 (void *)dvp->id_maddr);
693 return (0);
694 }
695 pg = (kvtop(dvp->id_maddr) & 0x3C000) >> 14;
696 adjust = IEE16_MCTRL_FMCS16 | (pg & 0x3) << 2;
697 decode = ((1 << (sc->iosize / 16384)) - 1) << pg;
698 edecode = ((~decode >> 4) & 0xF0) | (decode >> 8);
699
700 /* ZZZ This should be checked against eeprom location 6, low byte */
701 outb(PORT + IEE16_MEMDEC, decode & 0xFF);
702 /* ZZZ This should be checked against eeprom location 1, low byte */
703 outb(PORT + IEE16_MCTRL, adjust);
704 /* ZZZ Now if I could find this one I would have it made */
705 outb(PORT + IEE16_MPCTRL, (~decode & 0xFF));
706 /* ZZZ I think this is location 6, high byte */
707 outb(PORT + IEE16_MECTRL, edecode); /* XXX disable Exxx */
708
7b9f668c 709 kvtop(dvp->id_maddr);
984263bc
MD
710
711 /*
712 * first prime the stupid bart DRAM controller so that it works,
713 * then zero out all of memory.
714 */
715 bzero(sc->iomembot, 32);
716 bzero(sc->iomembot, sc->iosize);
717
718 /*
719 * Get the encoded interrupt number from the EEPROM, check it
720 * against the passed in IRQ. Issue a warning if they do not match.
721 * Always use the passed in IRQ, not the one in the EEPROM.
722 */
723 irq = ee16_read_eeprom(sc, IEE16_EEPROM_CONFIG1);
724 irq = (irq & IEE16_EEPROM_IRQ) >> IEE16_EEPROM_IRQ_SHIFT;
725 irq = irq_translate[irq];
726 if (dvp->id_irq > 0) {
727 if (irq != dvp->id_irq) {
e3869ec7 728 kprintf("ie%d: WARNING: board configured "
984263bc
MD
729 "at irq %u, using %u\n",
730 dvp->id_unit, dvp->id_irq, irq);
731 irq = dvp->id_unit;
732 }
733 } else {
734 dvp->id_irq = irq;
735 }
736 sc->irq_encoded = irq_encode[ffs(irq) - 1];
737
738 /*
739 * Get the hardware ethernet address from the EEPROM and save it in
740 * the softc for use by the 586 setup code.
741 */
742 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_HIGH);
743 sc->arpcom.ac_enaddr[1] = eaddrtemp & 0xFF;
744 sc->arpcom.ac_enaddr[0] = eaddrtemp >> 8;
745 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_MID);
746 sc->arpcom.ac_enaddr[3] = eaddrtemp & 0xFF;
747 sc->arpcom.ac_enaddr[2] = eaddrtemp >> 8;
748 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_LOW);
749 sc->arpcom.ac_enaddr[5] = eaddrtemp & 0xFF;
750 sc->arpcom.ac_enaddr[4] = eaddrtemp >> 8;
751
752 /* disable the board interrupts */
753 outb(PORT + IEE16_IRQ, sc->irq_encoded);
754
755 /* enable loopback to keep bad packets off the wire */
756 if (sc->hard_type == IE_EE16) {
757 bart_config = inb(PORT + IEE16_CONFIG);
758 bart_config |= IEE16_BART_LOOPBACK;
759 bart_config |= IEE16_BART_MCS16_TEST;/* inb doesn't get bit! */
760 outb(PORT + IEE16_CONFIG, bart_config);
761 bart_config = inb(PORT + IEE16_CONFIG);
762 }
763 /* take the board out of reset state */
764 outb(PORT + IEE16_ECTRL, 0);
765 DELAY(100);
766
767 if (!check_ie_present(unit, dvp->id_maddr, sc->iosize))
768 return (0);
769
770 return (16); /* return the number of I/O ports */
771}
772
773/*
774 * Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
775 */
776int
777ieattach(struct isa_device *dvp)
778{
779 int factor;
780 int unit = dvp->id_unit;
781 struct ie_softc *ie = &ie_softc[unit];
782 struct ifnet *ifp = &ie->arpcom.ac_if;
783 size_t allocsize;
784
7349cf53 785 dvp->id_intr = (inthand2_t *)ieintr;
984263bc
MD
786
787 /*
788 * based on the amount of memory we have, allocate our tx and rx
789 * resources.
790 */
791 factor = dvp->id_msize / 16384;
792 ie->nframes = factor * NFRAMES;
793 ie->nrxbufs = factor * NRXBUFS;
794 ie->ntxbufs = factor * NTXBUFS;
795
796 /*
797 * Since all of these guys are arrays of pointers, allocate as one
798 * big chunk and dole out accordingly.
799 */
800 allocsize = sizeof(void *) * (ie->nframes
801 + (ie->nrxbufs * 2)
802 + (ie->ntxbufs * 3));
efda3bd0 803 ie->rframes = kmalloc(allocsize, M_DEVBUF, M_WAITOK);
984263bc
MD
804 ie->rbuffs =
805 (volatile struct ie_recv_buf_desc **)&ie->rframes[ie->nframes];
806 ie->cbuffs = (volatile u_char **)&ie->rbuffs[ie->nrxbufs];
807 ie->xmit_cmds =
808 (volatile struct ie_xmit_cmd **)&ie->cbuffs[ie->nrxbufs];
809 ie->xmit_buffs =
810 (volatile struct ie_xmit_buf **)&ie->xmit_cmds[ie->ntxbufs];
811 ie->xmit_cbuffs = (volatile u_char **)&ie->xmit_buffs[ie->ntxbufs];
812
813 ifp->if_softc = ie;
3e4a09e7 814 if_initname(ifp, iedriver.name, unit);
984263bc 815 ifp->if_mtu = ETHERMTU;
267caeeb
JS
816 if_printf(ifp, "<%s R%d>", ie_hardware_names[ie->hard_type],
817 ie->hard_vers + 1);
984263bc
MD
818
819 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
984263bc
MD
820 ifp->if_start = iestart;
821 ifp->if_ioctl = ieioctl;
822 ifp->if_init = ieinit;
823 ifp->if_type = IFT_ETHER;
824 ifp->if_addrlen = 6;
825 ifp->if_hdrlen = 14;
2c4ce138
JS
826 ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
827 ifq_set_ready(&ifp->if_snd);
984263bc
MD
828
829 if (ie->hard_type == IE_EE16)
830 EVENTHANDLER_REGISTER(shutdown_post_sync, ee16_shutdown,
30527035 831 ie, SHUTDOWN_PRI_DRIVER);
984263bc 832
78195a76 833 ether_ifattach(ifp, ie->arpcom.ac_enaddr, NULL);
984263bc
MD
834 return (1);
835}
836
837/*
838 * What to do upon receipt of an interrupt.
839 */
840static void
477d3c1c 841ieintr(void *arg)
984263bc 842{
477d3c1c 843 int unit = (int)arg;
f96d6c88
RG
844 struct ie_softc *ie = &ie_softc[unit];
845 u_short status;
984263bc 846
78195a76
MD
847 lwkt_serialize_enter(ie->arpcom.ac_if.if_serializer);
848
984263bc
MD
849 /* Clear the interrupt latch on the 3C507. */
850 if (ie->hard_type == IE_3C507
851 && (inb(PORT + IE507_CTRL) & EL_CTRL_INTL))
852 outb(PORT + IE507_ICTRL, 1);
853
854 /* disable interrupts on the EE16. */
855 if (ie->hard_type == IE_EE16)
856 outb(PORT + IEE16_IRQ, ie->irq_encoded);
857
858 status = ie->scb->ie_status;
859
860loop:
861
862 /* Don't ack interrupts which we didn't receive */
863 ie_ack(ie->scb, IE_ST_WHENCE & status, unit, ie->ie_chan_attn);
864
865 if (status & (IE_ST_RECV | IE_ST_RNR)) {
866#ifdef DEBUG
867 in_ierint++;
868 if (ie_debug & IED_RINT)
e3869ec7 869 kprintf("ie%d: rint\n", unit);
984263bc
MD
870#endif
871 ierint(unit, ie);
872#ifdef DEBUG
873 in_ierint--;
874#endif
875 }
876 if (status & IE_ST_DONE) {
877#ifdef DEBUG
878 in_ietint++;
879 if (ie_debug & IED_TINT)
e3869ec7 880 kprintf("ie%d: tint\n", unit);
984263bc
MD
881#endif
882 ietint(unit, ie);
883#ifdef DEBUG
884 in_ietint--;
885#endif
886 }
887 if (status & IE_ST_RNR) {
888#ifdef DEBUG
889 if (ie_debug & IED_RNR)
e3869ec7 890 kprintf("ie%d: rnr\n", unit);
984263bc
MD
891#endif
892 iernr(unit, ie);
893 }
894#ifdef DEBUG
895 if ((status & IE_ST_ALLDONE)
896 && (ie_debug & IED_CNA))
e3869ec7 897 kprintf("ie%d: cna\n", unit);
984263bc
MD
898#endif
899
900 if ((status = ie->scb->ie_status) & IE_ST_WHENCE)
901 goto loop;
902
903 /* Clear the interrupt latch on the 3C507. */
904 if (ie->hard_type == IE_3C507)
905 outb(PORT + IE507_ICTRL, 1);
906
907 /* enable interrupts on the EE16. */
908 if (ie->hard_type == IE_EE16)
909 outb(PORT + IEE16_IRQ, ie->irq_encoded | IEE16_IRQ_ENABLE);
910
78195a76 911 lwkt_serialize_exit(ie->arpcom.ac_if.if_serializer);
984263bc
MD
912}
913
914/*
915 * Process a received-frame interrupt.
916 */
917static int
918ierint(int unit, struct ie_softc *ie)
919{
920 int i, status;
921 static int timesthru = 1024;
922
923 i = ie->rfhead;
924 while (1) {
925 status = ie->rframes[i]->ie_fd_status;
926
927 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
928 ie->arpcom.ac_if.if_ipackets++;
929 if (!--timesthru) {
930 ie->arpcom.ac_if.if_ierrors +=
931 ie->scb->ie_err_crc +
932 ie->scb->ie_err_align +
933 ie->scb->ie_err_resource +
934 ie->scb->ie_err_overrun;
935 ie->scb->ie_err_crc = 0;
936 ie->scb->ie_err_align = 0;
937 ie->scb->ie_err_resource = 0;
938 ie->scb->ie_err_overrun = 0;
939 timesthru = 1024;
940 }
941 ie_readframe(unit, ie, i);
942 } else {
943 if (status & IE_FD_RNR) {
944 if (!(ie->scb->ie_status & IE_RU_READY)) {
945 ie->rframes[0]->ie_fd_next =
946 MK_16(MEM, ie->rbuffs[0]);
947 ie->scb->ie_recv_list =
948 MK_16(MEM, ie->rframes[0]);
949 command_and_wait(unit, IE_RU_START,
950 0, 0);
951 }
952 }
953 break;
954 }
955 i = (i + 1) % ie->nframes;
956 }
957 return (0);
958}
959
960/*
961 * Process a command-complete interrupt. These are only generated by
962 * the transmission of frames. This routine is deceptively simple, since
963 * most of the real work is done by iestart().
964 */
965static int
966ietint(int unit, struct ie_softc *ie)
967{
968 int status;
969 int i;
970
971 ie->arpcom.ac_if.if_timer = 0;
972 ie->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
973
974 for (i = 0; i < ie->xmit_count; i++) {
975 status = ie->xmit_cmds[i]->ie_xmit_status;
976
977 if (status & IE_XS_LATECOLL) {
e3869ec7 978 kprintf("ie%d: late collision\n", unit);
984263bc
MD
979 ie->arpcom.ac_if.if_collisions++;
980 ie->arpcom.ac_if.if_oerrors++;
981 } else if (status & IE_XS_NOCARRIER) {
e3869ec7 982 kprintf("ie%d: no carrier\n", unit);
984263bc
MD
983 ie->arpcom.ac_if.if_oerrors++;
984 } else if (status & IE_XS_LOSTCTS) {
e3869ec7 985 kprintf("ie%d: lost CTS\n", unit);
984263bc
MD
986 ie->arpcom.ac_if.if_oerrors++;
987 } else if (status & IE_XS_UNDERRUN) {
e3869ec7 988 kprintf("ie%d: DMA underrun\n", unit);
984263bc
MD
989 ie->arpcom.ac_if.if_oerrors++;
990 } else if (status & IE_XS_EXCMAX) {
e3869ec7 991 kprintf("ie%d: too many collisions\n", unit);
984263bc
MD
992 ie->arpcom.ac_if.if_collisions += 16;
993 ie->arpcom.ac_if.if_oerrors++;
994 } else {
995 ie->arpcom.ac_if.if_opackets++;
996 ie->arpcom.ac_if.if_collisions += status & IE_XS_MAXCOLL;
997 }
998 }
999 ie->xmit_count = 0;
1000
1001 /*
1002 * If multicast addresses were added or deleted while we were
1003 * transmitting, ie_mc_reset() set the want_mcsetup flag indicating
1004 * that we should do it.
1005 */
1006 if (ie->want_mcsetup) {
1007 mc_setup(unit, (v_caddr_t) ie->xmit_cbuffs[0], ie->scb);
1008 ie->want_mcsetup = 0;
1009 }
1010 /* Wish I knew why this seems to be necessary... */
1011 ie->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL;
1012
9db4b353 1013 if_devstart(&ie->arpcom.ac_if);
984263bc
MD
1014 return (0); /* shouldn't be necessary */
1015}
1016
1017/*
1018 * Process a receiver-not-ready interrupt. I believe that we get these
1019 * when there aren't enough buffers to go around. For now (FIXME), we
1020 * just restart the receiver, and hope everything's ok.
1021 */
1022static int
1023iernr(int unit, struct ie_softc *ie)
1024{
1025#ifdef doesnt_work
1026 setup_rfa((v_caddr_t) ie->rframes[0], ie);
1027
1028 ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1029 command_and_wait(unit, IE_RU_START, 0, 0);
1030#else
1031 /* This doesn't work either, but it doesn't hang either. */
1032 command_and_wait(unit, IE_RU_DISABLE, 0, 0); /* just in case */
1033 setup_rfa((v_caddr_t) ie->rframes[0], ie); /* ignore cast-qual */
1034
1035 ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1036 command_and_wait(unit, IE_RU_START, 0, 0); /* was ENABLE */
1037
1038#endif
1039 ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
1040
1041 ie->arpcom.ac_if.if_ierrors++;
1042 return (0);
1043}
1044
1045/*
1046 * Compare two Ether/802 addresses for equality, inlined and
1047 * unrolled for speed. I'd love to have an inline assembler
1048 * version of this...
1049 */
1050static __inline int
1051ether_equal(u_char * one, u_char * two)
1052{
1053 if (one[0] != two[0])
1054 return (0);
1055 if (one[1] != two[1])
1056 return (0);
1057 if (one[2] != two[2])
1058 return (0);
1059 if (one[3] != two[3])
1060 return (0);
1061 if (one[4] != two[4])
1062 return (0);
1063 if (one[5] != two[5])
1064 return (0);
1065 return 1;
1066}
1067
1068/*
1069 * Determine quickly whether we should bother reading in this packet.
1070 * This depends on whether BPF and/or bridging is enabled, whether we
1071 * are receiving multicast address, and whether promiscuous mode is enabled.
1072 * We assume that if IFF_PROMISC is set, then *somebody* wants to see
1073 * all incoming packets.
1074 */
1075static __inline int
1076check_eh(struct ie_softc *ie, struct ether_header *eh)
1077{
1078 /* Optimize the common case: normal operation. We've received
1079 either a unicast with our dest or a multicast packet. */
1080 if (ie->promisc == 0) {
1081 int i;
1082
1083 /* If not multicast, it's definitely for us */
1084 if ((eh->ether_dhost[0] & 1) == 0)
1085 return (1);
1086
1087 /* Accept broadcasts (loose but fast check) */
1088 if (eh->ether_dhost[0] == 0xff)
1089 return (1);
1090
1091 /* Compare against our multicast addresses */
1092 for (i = 0; i < ie->mcast_count; i++) {
1093 if (ether_equal(eh->ether_dhost,
1094 (u_char *)&ie->mcast_addrs[i]))
1095 return (1);
1096 }
1097 return (0);
1098 }
1099
1100 /* Always accept packets when in promiscuous mode */
1101 if ((ie->promisc & IFF_PROMISC) != 0)
1102 return (1);
1103
1104 /* Always accept packets directed at us */
1105 if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
1106 return (1);
1107
1108 /* Must have IFF_ALLMULTI but not IFF_PROMISC set. The chip is
1109 actually in promiscuous mode, so discard unicast packets. */
1110 return((eh->ether_dhost[0] & 1) != 0);
1111}
1112
1113/*
1114 * We want to isolate the bits that have meaning... This assumes that
1115 * IE_RBUF_SIZE is an even power of two. If somehow the act_len exceeds
1116 * the size of the buffer, then we are screwed anyway.
1117 */
1118static __inline int
1119ie_buflen(struct ie_softc * ie, int head)
1120{
1121 return (ie->rbuffs[head]->ie_rbd_actual
1122 & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
1123}
1124
1125static __inline int
1126ie_packet_len(int unit, struct ie_softc * ie)
1127{
1128 int i;
1129 int head = ie->rbhead;
1130 int acc = 0;
1131
1132 do {
1133 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1134#ifdef DEBUG
1135 print_rbd(ie->rbuffs[ie->rbhead]);
1136#endif
1137 log(LOG_ERR,
1138 "ie%d: receive descriptors out of sync at %d\n",
1139 unit, ie->rbhead);
1140 iereset(unit);
1141 return (-1);
1142 }
1143 i = ie->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
1144
1145 acc += ie_buflen(ie, head);
1146 head = (head + 1) % ie->nrxbufs;
1147 } while (!i);
1148
1149 return (acc);
1150}
1151
1152/*
1153 * Read data off the interface, and turn it into an mbuf chain.
1154 *
1155 * This code is DRAMATICALLY different from the previous version; this
1156 * version tries to allocate the entire mbuf chain up front, given the
1157 * length of the data available. This enables us to allocate mbuf
1158 * clusters in many situations where before we would have had a long
1159 * chain of partially-full mbufs. This should help to speed up the
1160 * operation considerably. (Provided that it works, of course.)
1161 */
1162static __inline int
78195a76 1163ieget(int unit, struct ie_softc *ie, struct mbuf **mp)
984263bc
MD
1164{
1165 struct mbuf *m, *top, **mymp;
78195a76 1166 struct ether_header eh;
984263bc
MD
1167 int i;
1168 int offset;
1169 int totlen, resid;
1170 int thismboff;
1171 int head;
1172
1173 totlen = ie_packet_len(unit, ie);
1174 if (totlen <= 0)
1175 return (-1);
1176
1177 i = ie->rbhead;
1178
1179 /*
1180 * Snarf the Ethernet header.
1181 */
78195a76 1182 bcopy((v_caddr_t) ie->cbuffs[i], (caddr_t) &eh, sizeof eh);
984263bc
MD
1183 /* ignore cast-qual warning here */
1184
1185 /*
1186 * As quickly as possible, check if this packet is for us. If not,
1187 * don't waste a single cycle copying the rest of the packet in.
1188 * This is only a consideration when FILTER is defined; i.e., when
1189 * we are either running BPF or doing multicasting.
1190 */
78195a76 1191 if (!check_eh(ie, &eh)) {
984263bc
MD
1192 ie_drop_packet_buffer(unit, ie);
1193 ie->arpcom.ac_if.if_ierrors--; /* just this case, it's not an
1194 * error
1195 */
1196 return (-1);
1197 }
78195a76 1198 offset = 0;
984263bc 1199
74f1caca 1200 MGETHDR(*mp, MB_DONTWAIT, MT_DATA);
984263bc
MD
1201 if (!*mp) {
1202 ie_drop_packet_buffer(unit, ie);
1203 return (-1);
1204 }
1205 m = *mp;
984263bc
MD
1206 m->m_len = MHLEN;
1207 resid = m->m_pkthdr.len = totlen;
1208 top = 0;
1209 mymp = &top;
1210
1211 /*
1212 * This loop goes through and allocates mbufs for all the data we
1213 * will be copying in. It does not actually do the copying yet.
1214 */
1215 do { /* while(resid > 0) */
1216 /*
1217 * Try to allocate an mbuf to hold the data that we have.
1218 * If we already allocated one, just get another one and
1219 * stick it on the end (eventually). If we don't already
1220 * have one, try to allocate an mbuf cluster big enough to
1221 * hold the whole packet, if we think it's reasonable, or a
1222 * single mbuf which may or may not be big enough. Got that?
1223 */
1224 if (top) {
74f1caca 1225 MGET(m, MB_DONTWAIT, MT_DATA);
984263bc
MD
1226 if (!m) {
1227 m_freem(top);
1228 ie_drop_packet_buffer(unit, ie);
1229 return (-1);
1230 }
1231 m->m_len = MLEN;
1232 }
1233 if (resid >= MINCLSIZE) {
74f1caca 1234 MCLGET(m, MB_DONTWAIT);
984263bc
MD
1235 if (m->m_flags & M_EXT)
1236 m->m_len = min(resid, MCLBYTES);
1237 } else {
1238 if (resid < m->m_len) {
1239 if (!top && resid + max_linkhdr <= m->m_len)
1240 m->m_data += max_linkhdr;
1241 m->m_len = resid;
1242 }
1243 }
1244 resid -= m->m_len;
1245 *mymp = m;
1246 mymp = &m->m_next;
1247 } while (resid > 0);
1248
1249 resid = totlen;
1250 m = top;
1251 thismboff = 0;
1252 head = ie->rbhead;
1253
1254 /*
1255 * Now we take the mbuf chain (hopefully only one mbuf most of the
1256 * time) and stuff the data into it. There are no possible failures
1257 * at or after this point.
1258 */
1259 while (resid > 0) { /* while there's stuff left */
1260 int thislen = ie_buflen(ie, head) - offset;
1261
1262 /*
1263 * If too much data for the current mbuf, then fill the
1264 * current one up, go to the next one, and try again.
1265 */
1266 if (thislen > m->m_len - thismboff) {
1267 int newlen = m->m_len - thismboff;
1268
1269 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1270 mtod(m, v_caddr_t) +thismboff, (unsigned) newlen);
1271 /* ignore cast-qual warning */
1272 m = m->m_next;
1273 thismboff = 0; /* new mbuf, so no offset */
1274 offset += newlen; /* we are now this far into
1275 * the packet */
1276 resid -= newlen; /* so there is this much left
1277 * to get */
1278 continue;
1279 }
1280 /*
1281 * If there is more than enough space in the mbuf to hold
1282 * the contents of this buffer, copy everything in, advance
1283 * pointers, and so on.
1284 */
1285 if (thislen < m->m_len - thismboff) {
1286 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1287 mtod(m, caddr_t) +thismboff, (unsigned) thislen);
1288 thismboff += thislen; /* we are this far into the
1289 * mbuf */
1290 resid -= thislen; /* and this much is left */
1291 goto nextbuf;
1292 }
1293 /*
1294 * Otherwise, there is exactly enough space to put this
1295 * buffer's contents into the current mbuf. Do the
1296 * combination of the above actions.
1297 */
1298 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1299 mtod(m, caddr_t) + thismboff, (unsigned) thislen);
1300 m = m->m_next;
1301 thismboff = 0; /* new mbuf, start at the beginning */
1302 resid -= thislen; /* and we are this far through */
1303
1304 /*
1305 * Advance all the pointers. We can get here from either of
1306 * the last two cases, but never the first.
1307 */
1308nextbuf:
1309 offset = 0;
1310 ie->rbuffs[head]->ie_rbd_actual = 0;
1311 ie->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST;
1312 ie->rbhead = head = (head + 1) % ie->nrxbufs;
1313 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1314 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1315 }
1316
1317 /*
1318 * Unless something changed strangely while we were doing the copy,
1319 * we have now copied everything in from the shared memory. This
1320 * means that we are done.
1321 */
1322 return (0);
1323}
1324
1325/*
1326 * Read frame NUM from unit UNIT (pre-cached as IE).
1327 *
1328 * This routine reads the RFD at NUM, and copies in the buffers from
1329 * the list of RBD, then rotates the RBD and RFD lists so that the receiver
1330 * doesn't start complaining. Trailers are DROPPED---there's no point
1331 * in wasting time on confusing code to deal with them. Hopefully,
1332 * this machine will never ARP for trailers anyway.
1333 */
1334static void
1335ie_readframe(int unit, struct ie_softc *ie, int num/* frame number to read */)
1336{
1337 struct ie_recv_frame_desc rfd;
78195a76 1338 struct mbuf *m = NULL;
984263bc
MD
1339
1340 bcopy((v_caddr_t) (ie->rframes[num]), &rfd,
1341 sizeof(struct ie_recv_frame_desc));
1342
1343 /*
1344 * Immediately advance the RFD list, since we we have copied ours
1345 * now.
1346 */
1347 ie->rframes[num]->ie_fd_status = 0;
1348 ie->rframes[num]->ie_fd_last |= IE_FD_LAST;
1349 ie->rframes[ie->rftail]->ie_fd_last &= ~IE_FD_LAST;
1350 ie->rftail = (ie->rftail + 1) % ie->nframes;
1351 ie->rfhead = (ie->rfhead + 1) % ie->nframes;
1352
1353 if (rfd.ie_fd_status & IE_FD_OK) {
78195a76 1354 if (ieget(unit, ie, &m)) {
984263bc
MD
1355 ie->arpcom.ac_if.if_ierrors++; /* this counts as an
1356 * error */
1357 return;
1358 }
1359 }
984263bc
MD
1360
1361 if (!m)
1362 return;
1363
1364 /*
1365 * Finally pass this packet up to higher layers.
1366 */
78195a76 1367 ie->arpcom.ac_if.if_input(&ie->arpcom.ac_if, m);
984263bc
MD
1368}
1369
1370static void
1371ie_drop_packet_buffer(int unit, struct ie_softc * ie)
1372{
1373 int i;
1374
1375 do {
1376 /*
1377 * This means we are somehow out of sync. So, we reset the
1378 * adapter.
1379 */
1380 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1381#ifdef DEBUG
1382 print_rbd(ie->rbuffs[ie->rbhead]);
1383#endif
1384 log(LOG_ERR, "ie%d: receive descriptors out of sync at %d\n",
1385 unit, ie->rbhead);
1386 iereset(unit);
1387 return;
1388 }
1389 i = ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_LAST;
1390
1391 ie->rbuffs[ie->rbhead]->ie_rbd_length |= IE_RBD_LAST;
1392 ie->rbuffs[ie->rbhead]->ie_rbd_actual = 0;
1393 ie->rbhead = (ie->rbhead + 1) % ie->nrxbufs;
1394 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1395 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1396 } while (!i);
1397}
1398
1399
1400/*
1401 * Start transmission on an interface.
1402 */
1403static void
1404iestart(struct ifnet *ifp)
1405{
1406 struct ie_softc *ie = ifp->if_softc;
1407 struct mbuf *m0, *m;
1408 volatile unsigned char *buffer;
1409 u_short len;
1410
1411 /*
1412 * This is not really volatile, in this routine, but it makes gcc
1413 * happy.
1414 */
1415 volatile u_short *bptr = &ie->scb->ie_command_list;
1416
1417 if (!(ifp->if_flags & IFF_RUNNING))
1418 return;
1419 if (ifp->if_flags & IFF_OACTIVE)
1420 return;
1421
1422 do {
d2c71fa0 1423 m = ifq_dequeue(&ie->arpcom.ac_if.if_snd, NULL);
2c4ce138 1424 if (m == NULL)
984263bc
MD
1425 break;
1426
1427 buffer = ie->xmit_cbuffs[ie->xmit_count];
1428 len = 0;
1429
1430 for (m0 = m; m && len < IE_BUF_LEN; m = m->m_next) {
1431 bcopy(mtod(m, caddr_t), buffer, m->m_len);
1432 buffer += m->m_len;
1433 len += m->m_len;
1434 }
1435
1436 m_freem(m0);
1437 len = max(len, ETHER_MIN_LEN);
1438
1439 /*
1440 * See if bpf is listening on this interface, let it see the
1441 * packet before we commit it to the wire.
1442 */
c633dd13
JS
1443 BPF_TAP(&ie->arpcom.ac_if,
1444 __DEVOLATILE(u_char *, ie->xmit_cbuffs[ie->xmit_count]),
1445 len);
984263bc
MD
1446
1447 ie->xmit_buffs[ie->xmit_count]->ie_xmit_flags =
1448 IE_XMIT_LAST|len;
1449 ie->xmit_buffs[ie->xmit_count]->ie_xmit_next = 0xffff;
1450 ie->xmit_buffs[ie->xmit_count]->ie_xmit_buf =
1451 MK_24(ie->iomem, ie->xmit_cbuffs[ie->xmit_count]);
1452
1453 ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_cmd = IE_CMD_XMIT;
1454 ie->xmit_cmds[ie->xmit_count]->ie_xmit_status = 0;
1455 ie->xmit_cmds[ie->xmit_count]->ie_xmit_desc =
1456 MK_16(ie->iomem, ie->xmit_buffs[ie->xmit_count]);
1457
1458 *bptr = MK_16(ie->iomem, ie->xmit_cmds[ie->xmit_count]);
1459 bptr = &ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_link;
1460 ie->xmit_count++;
1461 } while (ie->xmit_count < ie->ntxbufs);
1462
1463 /*
1464 * If we queued up anything for transmission, send it.
1465 */
1466 if (ie->xmit_count) {
1467 ie->xmit_cmds[ie->xmit_count - 1]->com.ie_cmd_cmd |=
1468 IE_CMD_LAST | IE_CMD_INTR;
1469
1470 /*
1471 * By passing the command pointer as a null, we tell
1472 * command_and_wait() to pretend that this isn't an action
1473 * command. I wish I understood what was happening here.
1474 */
3e4a09e7 1475 command_and_wait(ifp->if_dunit, IE_CU_START, 0, 0);
984263bc
MD
1476 ifp->if_flags |= IFF_OACTIVE;
1477 }
1478 return;
1479}
1480
1481/*
1482 * Check to see if there's an 82586 out there.
1483 */
1484static int
1485check_ie_present(int unit, caddr_t where, unsigned size)
1486{
1487 volatile struct ie_sys_conf_ptr *scp;
1488 volatile struct ie_int_sys_conf_ptr *iscp;
1489 volatile struct ie_sys_ctl_block *scb;
1490 u_long realbase;
984263bc 1491
984263bc
MD
1492 realbase = (uintptr_t) where + size - (1 << 24);
1493
1494 scp = (volatile struct ie_sys_conf_ptr *) (uintptr_t)
1495 (realbase + IE_SCP_ADDR);
1496 bzero((volatile char *) scp, sizeof *scp);
1497
1498 /*
1499 * First we put the ISCP at the bottom of memory; this tests to make
1500 * sure that our idea of the size of memory is the same as the
1501 * controller's. This is NOT where the ISCP will be in normal
1502 * operation.
1503 */
1504 iscp = (volatile struct ie_int_sys_conf_ptr *) where;
1505 bzero((volatile char *)iscp, sizeof *iscp);
1506
1507 scb = (volatile struct ie_sys_ctl_block *) where;
1508 bzero((volatile char *)scb, sizeof *scb);
1509
1510 scp->ie_bus_use = ie_softc[unit].bus_use; /* 8-bit or 16-bit */
1511 scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1512 ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1513
1514 iscp->ie_busy = 1;
1515 iscp->ie_scb_offset = MK_16(realbase, scb) + 256;
1516
1517 (*ie_softc[unit].ie_reset_586) (unit);
1518 (*ie_softc[unit].ie_chan_attn) (unit);
1519
1520 DELAY(100); /* wait a while... */
1521
1522 if (iscp->ie_busy) {
984263bc
MD
1523 return (0);
1524 }
1525 /*
1526 * Now relocate the ISCP to its real home, and reset the controller
1527 * again.
1528 */
1529 iscp = (void *) Align((caddr_t) (uintptr_t)
1530 (realbase + IE_SCP_ADDR -
1531 sizeof(struct ie_int_sys_conf_ptr)));
1532 bzero((volatile char *) iscp, sizeof *iscp); /* ignore cast-qual */
1533
1534 scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1535 ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1536
1537 iscp->ie_busy = 1;
1538 iscp->ie_scb_offset = MK_16(realbase, scb);
1539
1540 (*ie_softc[unit].ie_reset_586) (unit);
1541 (*ie_softc[unit].ie_chan_attn) (unit);
1542
1543 DELAY(100);
1544
1545 if (iscp->ie_busy) {
984263bc
MD
1546 return (0);
1547 }
1548 ie_softc[unit].iosize = size;
1549 ie_softc[unit].iomem = (caddr_t) (uintptr_t) realbase;
1550
1551 ie_softc[unit].iscp = iscp;
1552 ie_softc[unit].scb = scb;
1553
1554 /*
1555 * Acknowledge any interrupts we may have caused...
1556 */
1557 ie_ack(scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
ec15e0df 1558
984263bc
MD
1559 return (1);
1560}
1561
1562/*
1563 * Divine the memory size of ie board UNIT.
1564 * Better hope there's nothing important hiding just below the ie card...
1565 */
1566static void
1567find_ie_mem_size(int unit)
1568{
1569 unsigned size;
1570
1571 ie_softc[unit].iosize = 0;
1572
1573 for (size = 65536; size >= 8192; size -= 8192) {
1574 if (check_ie_present(unit, ie_softc[unit].iomembot, size)) {
1575 return;
1576 }
1577 }
1578
1579 return;
1580}
1581
1582void
1583el_reset_586(int unit)
1584{
1585 outb(PORT + IE507_CTRL, EL_CTRL_RESET);
1586 DELAY(100);
1587 outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
1588 DELAY(100);
1589}
1590
1591void
1592sl_reset_586(int unit)
1593{
1594 outb(PORT + IEATT_RESET, 0);
1595}
1596
1597void
1598ee16_reset_586(int unit)
1599{
1600 outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
1601 DELAY(100);
1602 outb(PORT + IEE16_ECTRL, 0);
1603 DELAY(100);
1604}
1605
1606void
1607el_chan_attn(int unit)
1608{
1609 outb(PORT + IE507_ATTN, 1);
1610}
1611
1612void
1613sl_chan_attn(int unit)
1614{
1615 outb(PORT + IEATT_ATTN, 0);
1616}
1617
1618void
1619ee16_chan_attn(int unit)
1620{
1621 outb(PORT + IEE16_ATTN, 0);
1622}
1623
1624u_short
1625ee16_read_eeprom(struct ie_softc *sc, int location)
1626{
1627 int ectrl, edata;
1628
1629 ectrl = inb(sc->port + IEE16_ECTRL);
1630 ectrl &= IEE16_ECTRL_MASK;
1631 ectrl |= IEE16_ECTRL_EECS;
1632 outb(sc->port + IEE16_ECTRL, ectrl);
1633
1634 ee16_eeprom_outbits(sc, IEE16_EEPROM_READ, IEE16_EEPROM_OPSIZE1);
1635 ee16_eeprom_outbits(sc, location, IEE16_EEPROM_ADDR_SIZE);
1636 edata = ee16_eeprom_inbits(sc);
1637 ectrl = inb(sc->port + IEE16_ECTRL);
1638 ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EEDI | IEE16_ECTRL_EECS);
1639 outb(sc->port + IEE16_ECTRL, ectrl);
1640 ee16_eeprom_clock(sc, 1);
1641 ee16_eeprom_clock(sc, 0);
1642 return edata;
1643}
1644
1645void
1646ee16_eeprom_outbits(struct ie_softc *sc, int edata, int count)
1647{
1648 int ectrl, i;
1649
1650 ectrl = inb(sc->port + IEE16_ECTRL);
1651 ectrl &= ~IEE16_RESET_ASIC;
1652 for (i = count - 1; i >= 0; i--) {
1653 ectrl &= ~IEE16_ECTRL_EEDI;
1654 if (edata & (1 << i)) {
1655 ectrl |= IEE16_ECTRL_EEDI;
1656 }
1657 outb(sc->port + IEE16_ECTRL, ectrl);
1658 DELAY(1); /* eeprom data must be setup for 0.4 uSec */
1659 ee16_eeprom_clock(sc, 1);
1660 ee16_eeprom_clock(sc, 0);
1661 }
1662 ectrl &= ~IEE16_ECTRL_EEDI;
1663 outb(sc->port + IEE16_ECTRL, ectrl);
1664 DELAY(1); /* eeprom data must be held for 0.4 uSec */
1665}
1666
1667int
1668ee16_eeprom_inbits(struct ie_softc *sc)
1669{
1670 int ectrl, edata, i;
1671
1672 ectrl = inb(sc->port + IEE16_ECTRL);
1673 ectrl &= ~IEE16_RESET_ASIC;
1674 for (edata = 0, i = 0; i < 16; i++) {
1675 edata = edata << 1;
1676 ee16_eeprom_clock(sc, 1);
1677 ectrl = inb(sc->port + IEE16_ECTRL);
1678 if (ectrl & IEE16_ECTRL_EEDO) {
1679 edata |= 1;
1680 }
1681 ee16_eeprom_clock(sc, 0);
1682 }
1683 return (edata);
1684}
1685
1686void
1687ee16_eeprom_clock(struct ie_softc *sc, int state)
1688{
1689 int ectrl;
1690
1691 ectrl = inb(sc->port + IEE16_ECTRL);
1692 ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EESK);
1693 if (state) {
1694 ectrl |= IEE16_ECTRL_EESK;
1695 }
1696 outb(sc->port + IEE16_ECTRL, ectrl);
1697 DELAY(9); /* EESK must be stable for 8.38 uSec */
1698}
1699
1700static __inline void
1701ee16_interrupt_enable(struct ie_softc *sc)
1702{
1703 DELAY(100);
1704 outb(sc->port + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
1705 DELAY(100);
1706}
1707
1708void
1709sl_read_ether(int unit, unsigned char addr[6])
1710{
1711 int i;
1712
1713 for (i = 0; i < 6; i++)
1714 addr[i] = inb(PORT + i);
1715}
1716
1717
1718static void
1719iereset(int unit)
1720{
984263bc 1721 if (unit >= NIE) {
984263bc
MD
1722 return;
1723 }
e3869ec7 1724 kprintf("ie%d: reset\n", unit);
984263bc 1725 ie_softc[unit].arpcom.ac_if.if_flags &= ~IFF_UP;
2038fb68 1726 ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0, NULL);
984263bc
MD
1727
1728 /*
1729 * Stop i82586 dead in its tracks.
1730 */
1731 if (command_and_wait(unit, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
e3869ec7 1732 kprintf("ie%d: abort commands timed out\n", unit);
984263bc
MD
1733
1734 if (command_and_wait(unit, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
e3869ec7 1735 kprintf("ie%d: disable commands timed out\n", unit);
984263bc
MD
1736
1737#ifdef notdef
1738 if (!check_ie_present(unit, ie_softc[unit].iomembot,
1739 e_softc[unit].iosize))
1740 panic("ie disappeared!");
1741#endif
1742
1743 ie_softc[unit].arpcom.ac_if.if_flags |= IFF_UP;
2038fb68 1744 ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0, NULL);
984263bc
MD
1745}
1746
1747/*
984263bc
MD
1748 * Send a command to the controller and wait for it to either
1749 * complete or be accepted, depending on the command. If the
1750 * command pointer is null, then pretend that the command is
1751 * not an action command. If the command pointer is not null,
1752 * and the command is an action command, wait for
1753 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
1754 * to become true.
1755 */
1756static int
1757command_and_wait(int unit, int cmd, volatile void *pcmd, int mask)
1758{
1759 volatile struct ie_cmd_common *cc = pcmd;
984263bc
MD
1760
1761 ie_softc[unit].scb->ie_command = (u_short) cmd;
1762
1763 if (IE_ACTION_COMMAND(cmd) && pcmd) {
984263bc
MD
1764 /*
1765 * According to the packet driver, the minimum timeout
163f45a6 1766 * should be .369 seconds.
984263bc 1767 */
163f45a6 1768 int timer = 370;
984263bc 1769
92e62798
JS
1770 (*ie_softc[unit].ie_chan_attn) (unit);
1771
984263bc
MD
1772 /*
1773 * Now spin-lock waiting for status. This is not a very
1774 * nice thing to do, but I haven't figured out how, or
1775 * indeed if, we can put the process waiting for action to
1776 * sleep. (We may be getting called through some other
1777 * timeout running in the kernel.)
1778 */
163f45a6
JS
1779 while (--timer > 0) {
1780 if (cc->ie_cmd_status & mask)
984263bc 1781 break;
163f45a6 1782 DELAY(1000);
984263bc 1783 }
163f45a6
JS
1784 if (timer == 0)
1785 return(1);
1786 else
1787 return(0);
984263bc
MD
1788 } else {
1789
1790 /*
1791 * Otherwise, just wait for the command to be accepted.
1792 */
1793 (*ie_softc[unit].ie_chan_attn) (unit);
1794
1795 while (ie_softc[unit].scb->ie_command); /* spin lock */
1796
1797 return (0);
1798 }
1799}
1800
1801/*
1802 * Run the time-domain reflectometer...
1803 */
1804static void
1805run_tdr(int unit, volatile struct ie_tdr_cmd *cmd)
1806{
1807 int result;
1808
1809 cmd->com.ie_cmd_status = 0;
1810 cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
1811 cmd->com.ie_cmd_link = 0xffff;
1812 cmd->ie_tdr_time = 0;
1813
1814 ie_softc[unit].scb->ie_command_list = MK_16(MEM, cmd);
1815 cmd->ie_tdr_time = 0;
1816
1817 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL))
1818 result = 0x2000;
1819 else
1820 result = cmd->ie_tdr_time;
1821
1822 ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit,
1823 ie_softc[unit].ie_chan_attn);
1824
1825 if (result & IE_TDR_SUCCESS)
1826 return;
1827
1828 if (result & IE_TDR_XCVR) {
e3869ec7 1829 kprintf("ie%d: transceiver problem\n", unit);
984263bc 1830 } else if (result & IE_TDR_OPEN) {
e3869ec7 1831 kprintf("ie%d: TDR detected an open %d clocks away\n", unit,
984263bc
MD
1832 result & IE_TDR_TIME);
1833 } else if (result & IE_TDR_SHORT) {
e3869ec7 1834 kprintf("ie%d: TDR detected a short %d clocks away\n", unit,
984263bc
MD
1835 result & IE_TDR_TIME);
1836 } else {
e3869ec7 1837 kprintf("ie%d: TDR returned unknown status %x\n", unit, result);
984263bc
MD
1838 }
1839}
1840
1841static void
1842start_receiver(int unit)
1843{
984263bc
MD
1844 ie_softc[unit].scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1845 command_and_wait(unit, IE_RU_START, 0, 0);
1846
1847 ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
984263bc
MD
1848}
1849
1850/*
1851 * Here is a helper routine for iernr() and ieinit(). This sets up
1852 * the RFA.
1853 */
1854static v_caddr_t
1855setup_rfa(v_caddr_t ptr, struct ie_softc * ie)
1856{
1857 volatile struct ie_recv_frame_desc *rfd = (volatile void *)ptr;
1858 volatile struct ie_recv_buf_desc *rbd;
1859 int i;
1860 int unit = ie - &ie_softc[0];
1861
1862 /* First lay them out */
1863 for (i = 0; i < ie->nframes; i++) {
1864 ie->rframes[i] = rfd;
1865 bzero((volatile char *) rfd, sizeof *rfd); /* ignore cast-qual */
1866 rfd++;
1867 }
1868
1869 ptr = Alignvol(rfd); /* ignore cast-qual */
1870
1871 /* Now link them together */
1872 for (i = 0; i < ie->nframes; i++) {
1873 ie->rframes[i]->ie_fd_next =
1874 MK_16(MEM, ie->rframes[(i + 1) % ie->nframes]);
1875 }
1876
1877 /* Finally, set the EOL bit on the last one. */
1878 ie->rframes[ie->nframes - 1]->ie_fd_last |= IE_FD_LAST;
1879
1880 /*
1881 * Now lay out some buffers for the incoming frames. Note that we
1882 * set aside a bit of slop in each buffer, to make sure that we have
1883 * enough space to hold a single frame in every buffer.
1884 */
1885 rbd = (volatile void *) ptr;
1886
1887 for (i = 0; i < ie->nrxbufs; i++) {
1888 ie->rbuffs[i] = rbd;
1889 bzero((volatile char *)rbd, sizeof *rbd);
1890 ptr = Alignvol(ptr + sizeof *rbd);
1891 rbd->ie_rbd_length = IE_RBUF_SIZE;
1892 rbd->ie_rbd_buffer = MK_24(MEM, ptr);
1893 ie->cbuffs[i] = (volatile void *) ptr;
1894 ptr += IE_RBUF_SIZE;
1895 rbd = (volatile void *) ptr;
1896 }
1897
1898 /* Now link them together */
1899 for (i = 0; i < ie->nrxbufs; i++) {
1900 ie->rbuffs[i]->ie_rbd_next =
1901 MK_16(MEM, ie->rbuffs[(i + 1) % ie->nrxbufs]);
1902 }
1903
1904 /* Tag EOF on the last one */
1905 ie->rbuffs[ie->nrxbufs - 1]->ie_rbd_length |= IE_RBD_LAST;
1906
1907 /*
1908 * We use the head and tail pointers on receive to keep track of the
1909 * order in which RFDs and RBDs are used.
1910 */
1911 ie->rfhead = 0;
1912 ie->rftail = ie->nframes - 1;
1913 ie->rbhead = 0;
1914 ie->rbtail = ie->nrxbufs - 1;
1915
1916 ie->scb->ie_recv_list = MK_16(MEM, ie->rframes[0]);
1917 ie->rframes[0]->ie_fd_buf_desc = MK_16(MEM, ie->rbuffs[0]);
1918
1919 ptr = Alignvol(ptr);
1920 return (ptr);
1921}
1922
1923/*
1924 * Run the multicast setup command.
984263bc
MD
1925 */
1926static int
1927mc_setup(int unit, v_caddr_t ptr,
1928 volatile struct ie_sys_ctl_block * scb)
1929{
1930 struct ie_softc *ie = &ie_softc[unit];
1931 volatile struct ie_mcast_cmd *cmd = (volatile void *) ptr;
1932
1933 cmd->com.ie_cmd_status = 0;
1934 cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
1935 cmd->com.ie_cmd_link = 0xffff;
1936
1937 /* ignore cast-qual */
1938 bcopy((v_caddr_t) ie->mcast_addrs, (v_caddr_t) cmd->ie_mcast_addrs,
1939 ie->mcast_count * sizeof *ie->mcast_addrs);
1940
1941 cmd->ie_mcast_bytes = ie->mcast_count * 6; /* grrr... */
1942
1943 scb->ie_command_list = MK_16(MEM, cmd);
1944 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
1945 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
e3869ec7 1946 kprintf("ie%d: multicast address setup command failed\n", unit);
984263bc
MD
1947 return (0);
1948 }
1949 return (1);
1950}
1951
1952/*
1953 * This routine takes the environment generated by check_ie_present()
1954 * and adds to it all the other structures we need to operate the adapter.
1955 * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
1956 * starting the receiver unit, and clearing interrupts.
984263bc
MD
1957 */
1958static void
7b9f668c 1959ieinit(void *xsc)
984263bc
MD
1960{
1961 struct ie_softc *ie = xsc;
1962 volatile struct ie_sys_ctl_block *scb = ie->scb;
1963 v_caddr_t ptr;
1964 int i;
1965 int unit = ie->unit;
1966
1967 ptr = Alignvol((volatile char *) scb + sizeof *scb);
1968
1969 /*
1970 * Send the configure command first.
1971 */
1972 {
1973 volatile struct ie_config_cmd *cmd = (volatile void *) ptr;
1974
1975 ie_setup_config(cmd, ie->promisc,
1976 ie->hard_type == IE_STARLAN10);
1977 cmd->com.ie_cmd_status = 0;
1978 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
1979 cmd->com.ie_cmd_link = 0xffff;
1980
1981 scb->ie_command_list = MK_16(MEM, cmd);
1982
1983 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
1984 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
e3869ec7 1985 kprintf("ie%d: configure command failed\n", unit);
984263bc
MD
1986 return;
1987 }
1988 }
1989 /*
1990 * Now send the Individual Address Setup command.
1991 */
1992 {
1993 volatile struct ie_iasetup_cmd *cmd = (volatile void *) ptr;
1994
1995 cmd->com.ie_cmd_status = 0;
1996 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
1997 cmd->com.ie_cmd_link = 0xffff;
1998
1999 bcopy((volatile char *)ie_softc[unit].arpcom.ac_enaddr,
2000 (volatile char *)&cmd->ie_address, sizeof cmd->ie_address);
2001 scb->ie_command_list = MK_16(MEM, cmd);
2002 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2003 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
e3869ec7 2004 kprintf("ie%d: individual address "
984263bc
MD
2005 "setup command failed\n", unit);
2006 return;
2007 }
2008 }
2009
2010 /*
2011 * Now run the time-domain reflectometer.
2012 */
2013 run_tdr(unit, (volatile void *) ptr);
2014
2015 /*
2016 * Acknowledge any interrupts we have generated thus far.
2017 */
2018 ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
2019
2020 /*
2021 * Set up the RFA.
2022 */
2023 ptr = setup_rfa(ptr, ie);
2024
2025 /*
2026 * Finally, the transmit command and buffer are the last little bit
2027 * of work.
2028 */
2029
2030 /* transmit command buffers */
2031 for (i = 0; i < ie->ntxbufs; i++) {
2032 ie->xmit_cmds[i] = (volatile void *) ptr;
2033 ptr += sizeof *ie->xmit_cmds[i];
2034 ptr = Alignvol(ptr);
2035 ie->xmit_buffs[i] = (volatile void *)ptr;
2036 ptr += sizeof *ie->xmit_buffs[i];
2037 ptr = Alignvol(ptr);
2038 }
2039
2040 /* transmit buffers */
2041 for (i = 0; i < ie->ntxbufs - 1; i++) {
2042 ie->xmit_cbuffs[i] = (volatile void *)ptr;
2043 ptr += IE_BUF_LEN;
2044 ptr = Alignvol(ptr);
2045 }
2046 ie->xmit_cbuffs[ie->ntxbufs - 1] = (volatile void *) ptr;
2047
2048 for (i = 1; i < ie->ntxbufs; i++) {
2049 bzero((v_caddr_t) ie->xmit_cmds[i], sizeof *ie->xmit_cmds[i]);
2050 bzero((v_caddr_t) ie->xmit_buffs[i], sizeof *ie->xmit_buffs[i]);
2051 }
2052
2053 /*
2054 * This must be coordinated with iestart() and ietint().
2055 */
2056 ie->xmit_cmds[0]->ie_xmit_status = IE_STAT_COMPL;
2057
2058 /* take the ee16 out of loopback */
2059 if (ie->hard_type == IE_EE16) {
2060 u_int8_t bart_config;
2061
2062 bart_config = inb(PORT + IEE16_CONFIG);
2063 bart_config &= ~IEE16_BART_LOOPBACK;
2064 /* inb doesn't get bit! */
2065 bart_config |= IEE16_BART_MCS16_TEST;
2066 outb(PORT + IEE16_CONFIG, bart_config);
2067 ee16_interrupt_enable(ie);
2068 ee16_chan_attn(unit);
2069 }
2070 ie->arpcom.ac_if.if_flags |= IFF_RUNNING; /* tell higher levels
2071 * we're here */
2072 start_receiver(unit);
984263bc
MD
2073}
2074
2075static void
2076ie_stop(int unit)
2077{
2078 command_and_wait(unit, IE_RU_DISABLE, 0, 0);
2079}
2080
2081static int
bd4539cc 2082ieioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
984263bc 2083{
ec15e0df 2084 int error = 0;
984263bc 2085
984263bc 2086 switch (command) {
984263bc
MD
2087 case SIOCSIFFLAGS:
2088 /*
2089 * Note that this device doesn't have an "all multicast"
2090 * mode, so we must turn on promiscuous mode and do the
2091 * filtering manually.
2092 */
2093 if ((ifp->if_flags & IFF_UP) == 0 &&
2094 (ifp->if_flags & IFF_RUNNING)) {
2095 ifp->if_flags &= ~IFF_RUNNING;
3e4a09e7 2096 ie_stop(ifp->if_dunit);
984263bc
MD
2097 } else if ((ifp->if_flags & IFF_UP) &&
2098 (ifp->if_flags & IFF_RUNNING) == 0) {
3e4a09e7 2099 ie_softc[ifp->if_dunit].promisc =
984263bc
MD
2100 ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2101 ieinit(ifp->if_softc);
3e4a09e7 2102 } else if (ie_softc[ifp->if_dunit].promisc ^
984263bc 2103 (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI))) {
3e4a09e7 2104 ie_softc[ifp->if_dunit].promisc =
984263bc
MD
2105 ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2106 ieinit(ifp->if_softc);
2107 }
2108 break;
2109
2110 case SIOCADDMULTI:
2111 case SIOCDELMULTI:
2112 /*
2113 * Update multicast listeners
2114 */
2115 /* reset multicast filtering */
3e4a09e7 2116 ie_mc_reset(ifp->if_dunit);
984263bc
MD
2117 error = 0;
2118 break;
2119
2120 default:
4cde4dd5
JS
2121 error = ether_ioctl(ifp, command, data);
2122 break;
984263bc 2123 }
984263bc
MD
2124 return (error);
2125}
2126
2127static void
2128ie_mc_reset(int unit)
2129{
2130 struct ie_softc *ie = &ie_softc[unit];
2131 struct ifmultiaddr *ifma;
2132
2133 /*
2134 * Step through the list of addresses.
2135 */
2136 ie->mcast_count = 0;
441d34b2 2137 TAILQ_FOREACH(ifma, &ie->arpcom.ac_if.if_multiaddrs, ifma_link) {
984263bc
MD
2138 if (ifma->ifma_addr->sa_family != AF_LINK)
2139 continue;
2140
2141 /* XXX - this is broken... */
2142 if (ie->mcast_count >= MAXMCAST) {
2143 ie->arpcom.ac_if.if_flags |= IFF_ALLMULTI;
902ec341 2144 ieioctl(&ie->arpcom.ac_if, SIOCSIFFLAGS, NULL,
2038fb68 2145 NULL);
984263bc
MD
2146 goto setflag;
2147 }
2148 bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
2149 &(ie->mcast_addrs[ie->mcast_count]), 6);
2150 ie->mcast_count++;
2151 }
2152
2153setflag:
2154 ie->want_mcsetup = 1;
2155}
2156
2157
2158#ifdef DEBUG
2159static void
2160print_rbd(volatile struct ie_recv_buf_desc * rbd)
2161{
e3869ec7 2162 kprintf("RBD at %p:\n"
984263bc
MD
2163 "actual %04x, next %04x, buffer %p\n"
2164 "length %04x, mbz %04x\n",
2165 (volatile void *) rbd,
2166 rbd->ie_rbd_actual, rbd->ie_rbd_next,
2167 (void *) rbd->ie_rbd_buffer,
2168 rbd->ie_rbd_length, rbd->mbz);
2169}
2170
2171#endif /* DEBUG */