1 /*
2 * Copyright (c) 1982, 1986 Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 *
7 * @(#)if_il.c 7.8 (Berkeley) 12/16/90
8 */
9
10 #include "il.h"
11 #if NIL > 0
12
13 /*
14 * Interlan Ethernet Communications Controller interface
15 */
16 #include "../include/pte.h"
17
18 #include "sys/param.h"
19 #include "sys/systm.h"
20 #include "sys/mbuf.h"
21 #include "sys/buf.h"
22 #include "sys/protosw.h"
23 #include "sys/socket.h"
24 #include "sys/vmmac.h"
25 #include "sys/ioctl.h"
26 #include "sys/errno.h"
27 #include "sys/syslog.h"
28
29 #include "net/if.h"
30 #include "net/netisr.h"
31 #include "net/route.h"
32
33 #ifdef INET
34 #include "netinet/in.h"
35 #include "netinet/in_systm.h"
36 #include "netinet/in_var.h"
37 #include "netinet/ip.h"
38 #include "netinet/if_ether.h"
39 #endif
40
41 #ifdef NS
42 #include "netns/ns.h"
43 #include "netns/ns_if.h"
44 #endif
45
46 #include "../include/cpu.h"
47 #include "../include/mtpr.h"
48 #include "if_il.h"
49 #include "if_ilreg.h"
50 #include "if_uba.h"
51 #include "../uba/ubareg.h"
52 #include "../uba/ubavar.h"
53
54 int ilprobe(), ilattach(), ilrint(), ilcint();
55 struct uba_device *ilinfo[NIL];
56 u_short ilstd[] = { 0 };
57 struct uba_driver ildriver =
58 { ilprobe, 0, ilattach, 0, ilstd, "il", ilinfo };
59 #define ILUNIT(x) minor(x)
60 int ilinit(),iloutput(),ilioctl(),ilreset(),ilwatch(),ilstart();
61 int ildebug = 0;
62
63 /*
64 * Ethernet software status per interface.
65 *
66 * Each interface is referenced by a network interface structure,
67 * is_if, which the routing code uses to locate the interface.
68 * This structure contains the output queue for the interface, its address, ...
69 * We also have, for each interface, a UBA interface structure, which
70 * contains information about the UNIBUS resources held by the interface:
71 * map registers, buffered data paths, etc. Information is cached in this
72 * structure for use by the if_uba.c routines in running the interface
73 * efficiently.
74 */
75
76 struct ether_addr {
77 u_char addr[6];
78 };
79 struct il_softc {
80 struct arpcom is_ac; /* Ethernet common part */
81 #define is_if is_ac.ac_if /* network-visible interface */
82 #define is_addr is_ac.ac_enaddr /* hardware Ethernet address */
83 struct ifuba is_ifuba; /* UNIBUS resources */
84 int is_flags;
85 #define ILF_RCVPENDING 0x2 /* start rcv in ilcint */
86 #define ILF_STATPENDING 0x4 /* stat cmd pending */
87 #define ILF_RUNNING 0x8 /* board is running */
88 #define ILF_SETADDR 0x10 /* physical address is changed */
89 short is_lastcmd; /* can't read csr, so must save it */
90 short is_scaninterval; /* interval of stat collection */
91 #define ILWATCHINTERVAL 60 /* once every 60 seconds */
92 union {
93 struct il_stats isu_stats; /* holds on-board statistics */
94 struct ether_addr isu_maddrs[63]; /* multicast addrs */
95 } is_isu;
96 #define is_stats is_isu.isu_stats
97 #define is_maddrs is_isu.isu_maddrs
98 struct il_stats is_sum; /* summation over time */
99 int is_ubaddr; /* mapping registers of is_stats */
100 } il_softc[NIL];
101
ilprobe(reg)102 ilprobe(reg)
103 caddr_t reg;
104 {
105 register int br, cvec; /* r11, r10 value-result */
106 register struct ildevice *addr = (struct ildevice *)reg;
107 register i;
108
109 #ifdef lint
110 br = 0; cvec = br; br = cvec;
111 i = 0; ilrint(i); ilcint(i); ilwatch(i);
112 #endif
113
114 addr->il_csr = ILC_OFFLINE|IL_CIE;
115 DELAY(100000);
116 i = addr->il_csr; /* clear CDONE */
117 if (cvec > 0 && cvec != 0x200)
118 cvec -= 4;
119 return (1);
120 }
121
122 /*
123 * Interface exists: make available by filling in network interface
124 * record. System will initialize the interface when it is ready
125 * to accept packets. A STATUS command is done to get the ethernet
126 * address and other interesting data.
127 */
128 ilattach(ui)
129 struct uba_device *ui;
130 {
131 register struct il_softc *is = &il_softc[ui->ui_unit];
132 register struct ifnet *ifp = &is->is_if;
133 register struct ildevice *addr = (struct ildevice *)ui->ui_addr;
134
135 ifp->if_unit = ui->ui_unit;
136 ifp->if_name = "il";
137 ifp->if_mtu = ETHERMTU;
138 ifp->if_flags = IFF_BROADCAST;
139
140 /*
141 * Reset the board and map the statistics
142 * buffer onto the Unibus.
143 */
144 addr->il_csr = ILC_RESET;
145 (void)ilwait(ui, "reset");
146
147 is->is_ubaddr = uballoc(ui->ui_ubanum, (caddr_t)&is->is_stats,
148 sizeof (struct il_stats), 0);
149 addr->il_bar = is->is_ubaddr & 0xffff;
150 addr->il_bcr = sizeof (struct il_stats);
151 addr->il_csr = ((is->is_ubaddr >> 2) & IL_EUA)|ILC_STAT;
152 (void)ilwait(ui, "status");
153 ubarelse(ui->ui_ubanum, &is->is_ubaddr);
154 if (ildebug)
155 printf("il%d: module=%s firmware=%s\n", ui->ui_unit,
156 is->is_stats.ils_module, is->is_stats.ils_firmware);
157 bcopy((caddr_t)is->is_stats.ils_addr, (caddr_t)is->is_addr,
158 sizeof (is->is_addr));
159 printf("il%d: hardware address %s\n", ui->ui_unit,
160 ether_sprintf(is->is_addr));
161 ifp->if_init = ilinit;
162 ifp->if_output = ether_output;
163 ifp->if_ioctl = ilioctl;
164 ifp->if_reset = ilreset;
165 ifp->if_start = ilstart;
166 is->is_ifuba.ifu_flags = UBA_CANTWAIT;
167 if_attach(ifp);
168 }
169
170 ilwait(ui, op)
171 struct uba_device *ui;
172 char *op;
173 {
174 register struct ildevice *addr = (struct ildevice *)ui->ui_addr;
175
176 while ((addr->il_csr&IL_CDONE) == 0)
177 ;
178 if (addr->il_csr&IL_STATUS) {
179 printf("il%d: %s failed, csr=%b\n", ui->ui_unit, op,
180 addr->il_csr, IL_BITS);
181 return (-1);
182 }
183 return (0);
184 }
185
186 /*
187 * Reset of interface after UNIBUS reset.
188 * If interface is on specified uba, reset its state.
189 */
ilreset(unit,uban)190 ilreset(unit, uban)
191 int unit, uban;
192 {
193 register struct uba_device *ui;
194
195 if (unit >= NIL || (ui = ilinfo[unit]) == 0 || ui->ui_alive == 0 ||
196 ui->ui_ubanum != uban)
197 return;
198 printf(" il%d", unit);
199 il_softc[unit].is_if.if_flags &= ~IFF_RUNNING;
200 il_softc[unit].is_flags &= ~ILF_RUNNING;
201 ilinit(unit);
202 }
203
204 /*
205 * Initialization of interface; clear recorded pending
206 * operations, and reinitialize UNIBUS usage.
207 */
ilinit(unit)208 ilinit(unit)
209 int unit;
210 {
211 register struct il_softc *is = &il_softc[unit];
212 register struct uba_device *ui = ilinfo[unit];
213 register struct ildevice *addr;
214 register struct ifnet *ifp = &is->is_if;
215 int s;
216
217 /* not yet, if address still unknown */
218 if (ifp->if_addrlist == (struct ifaddr *)0)
219 return;
220 if (is->is_flags & ILF_RUNNING)
221 return;
222
223 if ((ifp->if_flags & IFF_RUNNING) == 0) {
224 if (if_ubainit(&is->is_ifuba, ui->ui_ubanum,
225 sizeof (struct il_rheader), (int)btoc(ETHERMTU)) == 0) {
226 printf("il%d: can't initialize\n", unit);
227 is->is_if.if_flags &= ~IFF_UP;
228 return;
229 }
230 is->is_ubaddr = uballoc(ui->ui_ubanum, (caddr_t)&is->is_isu,
231 sizeof (is->is_isu), 0);
232 }
233 ifp->if_watchdog = ilwatch;
234 is->is_scaninterval = ILWATCHINTERVAL;
235 ifp->if_timer = is->is_scaninterval;
236 addr = (struct ildevice *)ui->ui_addr;
237
238 /*
239 * Turn off source address insertion (it's faster this way),
240 * and set board online. Former doesn't work if board is
241 * already online (happens on ubareset), so we put it offline
242 * first.
243 */
244 s = splimp();
245 addr->il_csr = ILC_RESET;
246 if (ilwait(ui, "hardware diag")) {
247 is->is_if.if_flags &= ~IFF_UP;
248 splx(s);
249 return;
250 }
251 addr->il_csr = ILC_CISA;
252 while ((addr->il_csr & IL_CDONE) == 0)
253 ;
254 /*
255 * If we must reprogram this board's physical ethernet
256 * address (as for secondary XNS interfaces), we do so
257 * before putting it on line, and starting receive requests.
258 * If you try this on an older 1010 board, it will total
259 * wedge the board.
260 */
261 if (is->is_flags & ILF_SETADDR) {
262 bcopy((caddr_t)is->is_addr, (caddr_t)&is->is_isu,
263 sizeof is->is_addr);
264 addr->il_bar = is->is_ubaddr & 0xffff;
265 addr->il_bcr = sizeof is->is_addr;
266 addr->il_csr = ((is->is_ubaddr >> 2) & IL_EUA)|ILC_LDPA;
267 if (ilwait(ui, "setaddr"))
268 return;
269 addr->il_bar = is->is_ubaddr & 0xffff;
270 addr->il_bcr = sizeof (struct il_stats);
271 addr->il_csr = ((is->is_ubaddr >> 2) & IL_EUA)|ILC_STAT;
272 if (ilwait(ui, "verifying setaddr"))
273 return;
274 if (bcmp((caddr_t)is->is_stats.ils_addr, (caddr_t)is->is_addr,
275 sizeof (is->is_addr)) != 0) {
276 printf("il%d: setaddr didn't work\n", ui->ui_unit);
277 return;
278 }
279 }
280 #ifdef MULTICAST
281 if (is->is_if.if_flags & IFF_PROMISC) {
282 addr->il_csr = ILC_PRMSC;
283 if (ilwait(ui, "all multi"))
284 return;
285 } else if (is->is_if.if_flags & IFF_ALLMULTI) {
286 too_many_multis:
287 addr->il_csr = ILC_ALLMC;
288 if (ilwait(ui, "all multi"))
289 return;
290 else {
291 int i;
292 register struct ether_addr *ep = is->is_maddrs;
293 struct ether_multi *enm;
294 struct ether_multistep step;
295 /*
296 * Step through our list of multicast addresses. If we have
297 * too many multicast addresses, or if we have to listen to
298 * a range of multicast addresses, turn on reception of all
299 * multicasts.
300 */
301 i = 0;
302 ETHER_FIRST_MULTI(step, &is->is_ac, enm);
303 while (enm != NULL) {
304 if (++i > 63 && k != 0) {
305 break;
306 }
307 *ep++ = *(struct ether_addr *)enm->enm_addrlo;
308 ETHER_NEXT_MULTI(step, enm);
309 }
310 if (i = 0) {
311 /* no multicasts! */
312 } else if (i <= 63) {
313 addr->il_bar = is->is_ubaddr & 0xffff;
314 addr->il_bcr = i * sizeof (struct ether_addr);
315 addr->il_csr = ((is->is_ubaddr >> 2) & IL_EUA)|
316 LC_LDGRPS;
317 if (ilwait(ui, "load multi"))
318 return;
319 } else {
320 is->is_if.if_flags |= IFF_ALLMULTI;
321 goto too_many_multis;
322 }
323 }
324 #endif MULTI
325 /*
326 * Set board online.
327 * Hang receive buffer and start any pending
328 * writes by faking a transmit complete.
329 * Receive bcr is not a multiple of 8 so buffer
330 * chaining can't happen.
331 */
332 addr->il_csr = ILC_ONLINE;
333 while ((addr->il_csr & IL_CDONE) == 0)
334 ;
335 addr->il_bar = is->is_ifuba.ifu_r.ifrw_info & 0xffff;
336 addr->il_bcr = sizeof(struct il_rheader) + ETHERMTU + 6;
337 addr->il_csr =
338 ((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;
339 while ((addr->il_csr & IL_CDONE) == 0)
340 ;
341 is->is_if.if_flags |= IFF_RUNNING | IFF_OACTIVE;
342 is->is_flags |= ILF_RUNNING;
343 is->is_lastcmd = 0;
344 ilcint(unit);
345 splx(s);
346 }
347
348 /*
349 * Start output on interface.
350 * Get another datagram to send off of the interface queue,
351 * and map it to the interface before starting the output.
352 */
353 ilstart(ifp)
354 register struct ifnet *ifp;
355 {
356 int unit = ifp->if_unit, len;
357 struct uba_device *ui = ilinfo[unit];
358 register struct il_softc *is = &il_softc[unit];
359 register struct ildevice *addr;
360 struct mbuf *m;
361 short csr;
362
363 IF_DEQUEUE(&is->is_if.if_snd, m);
364 addr = (struct ildevice *)ui->ui_addr;
365 if (m == 0) {
366 if ((is->is_flags & ILF_STATPENDING) == 0)
367 return (0);
368 addr->il_bar = is->is_ubaddr & 0xffff;
369 addr->il_bcr = sizeof (struct il_stats);
370 csr = ((is->is_ubaddr >> 2) & IL_EUA)|ILC_STAT|IL_RIE|IL_CIE;
371 is->is_flags &= ~ILF_STATPENDING;
372 goto startcmd;
373 }
374 len = if_wubaput(&is->is_ifuba, m);
375 /*
376 * Ensure minimum packet length.
377 * This makes the safe assumtion that there are no virtual holes
378 * after the data.
379 * For security, it might be wise to zero out the added bytes,
380 * but we're mainly interested in speed at the moment.
381 */
382 if (len - sizeof(struct ether_header) < ETHERMIN)
383 len = ETHERMIN + sizeof(struct ether_header);
384 if (is->is_ifuba.ifu_flags & UBA_NEEDBDP)
385 UBAPURGE(is->is_ifuba.ifu_uba, is->is_ifuba.ifu_w.ifrw_bdp);
386 addr->il_bar = is->is_ifuba.ifu_w.ifrw_info & 0xffff;
387 addr->il_bcr = len;
388 csr =
389 ((is->is_ifuba.ifu_w.ifrw_info >> 2) & IL_EUA)|ILC_XMIT|IL_CIE|IL_RIE;
390
391 startcmd:
392 is->is_lastcmd = csr & IL_CMD;
393 addr->il_csr = csr;
394 is->is_if.if_flags |= IFF_OACTIVE;
395 return (0);
396 }
397
398 /*
399 * Command done interrupt.
400 */
401 ilcint(unit)
402 int unit;
403 {
404 register struct il_softc *is = &il_softc[unit];
405 struct uba_device *ui = ilinfo[unit];
406 register struct ildevice *addr = (struct ildevice *)ui->ui_addr;
407 short csr;
408
409 if ((is->is_if.if_flags & IFF_OACTIVE) == 0) {
410 printf("il%d: stray xmit interrupt, csr=%b\n", unit,
411 addr->il_csr, IL_BITS);
412 return;
413 }
414
415 csr = addr->il_csr;
416 /*
417 * Hang receive buffer if it couldn't
418 * be done earlier (in ilrint).
419 */
420 if (is->is_flags & ILF_RCVPENDING) {
421 int s;
422
423 addr->il_bar = is->is_ifuba.ifu_r.ifrw_info & 0xffff;
424 addr->il_bcr = sizeof(struct il_rheader) + ETHERMTU + 6;
425 addr->il_csr =
426 ((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;
427 s = splhigh();
428 while ((addr->il_csr & IL_CDONE) == 0)
429 ;
430 splx(s);
431 is->is_flags &= ~ILF_RCVPENDING;
432 }
433 is->is_if.if_flags &= ~IFF_OACTIVE;
434 csr &= IL_STATUS;
435 switch (is->is_lastcmd) {
436
437 case ILC_XMIT:
438 is->is_if.if_opackets++;
439 if (csr > ILERR_RETRIES)
440 is->is_if.if_oerrors++;
441 break;
442
443 case ILC_STAT:
444 if (csr == ILERR_SUCCESS)
445 iltotal(is);
446 break;
447 }
448 if (is->is_ifuba.ifu_xtofree) {
449 m_freem(is->is_ifuba.ifu_xtofree);
450 is->is_ifuba.ifu_xtofree = 0;
451 }
452 (void) ilstart(&is->is_if);
453 }
454
455 /*
456 * Ethernet interface receiver interrupt.
457 * If input error just drop packet.
458 * Otherwise purge input buffered data path and examine
459 * packet to determine type. If can't determine length
460 * from type, then have to drop packet. Othewise decapsulate
461 * packet based on type and pass to type specific higher-level
462 * input routine.
463 */
464 ilrint(unit)
465 int unit;
466 {
467 register struct il_softc *is = &il_softc[unit];
468 struct ildevice *addr = (struct ildevice *)ilinfo[unit]->ui_addr;
469 register struct il_rheader *il;
470 struct mbuf *m;
471 int len, off, resid, s;
472 register struct ifqueue *inq;
473
474 is->is_if.if_ipackets++;
475 if (is->is_ifuba.ifu_flags & UBA_NEEDBDP)
476 UBAPURGE(is->is_ifuba.ifu_uba, is->is_ifuba.ifu_r.ifrw_bdp);
477 il = (struct il_rheader *)(is->is_ifuba.ifu_r.ifrw_addr);
478 len = il->ilr_length - sizeof(struct il_rheader);
479 if ((il->ilr_status&(ILFSTAT_A|ILFSTAT_C)) || len < 46 ||
480 len > ETHERMTU) {
481 is->is_if.if_ierrors++;
482 #ifdef notdef
483 if (is->is_if.if_ierrors % 100 == 0)
484 printf("il%d: += 100 input errors\n", unit);
485 #endif
486 goto setup;
487 }
488
489 /*
490 * Deal with trailer protocol: if type is trailer type
491 * get true type from first 16-bit word past data.
492 * Remember that type was trailer by setting off.
493 */
494 il->ilr_type = ntohs((u_short)il->ilr_type);
495 #define ildataaddr(il, off, type) ((type)(((caddr_t)((il)+1)+(off))))
496 if (il->ilr_type >= ETHERTYPE_TRAIL &&
497 il->ilr_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
498 off = (il->ilr_type - ETHERTYPE_TRAIL) * 512;
499 if (off >= ETHERMTU)
500 goto setup; /* sanity */
501 il->ilr_type = ntohs(*ildataaddr(il, off, u_short *));
502 resid = ntohs(*(ildataaddr(il, off+2, u_short *)));
503 if (off + resid > len)
504 goto setup; /* sanity */
505 len = off + resid;
506 } else
507 off = 0;
508 if (len == 0)
509 goto setup;
510
511 /*
512 * Pull packet off interface. Off is nonzero if packet
513 * has trailing header; ilget will then force this header
514 * information to be at the front, but we still have to drop
515 * the type and length which are at the front of any trailer data.
516 */
517 m = if_rubaget(&is->is_ifuba, len, off, &is->is_if);
518 if (m)
519 ether_input(&is->is_if, (struct ether_header *)il->ilr_dhost, m);
520 setup:
521 /*
522 * Reset for next packet if possible.
523 * If waiting for transmit command completion, set flag
524 * and wait until command completes.
525 */
526 if (is->is_if.if_flags & IFF_OACTIVE) {
527 is->is_flags |= ILF_RCVPENDING;
528 return;
529 }
530 addr->il_bar = is->is_ifuba.ifu_r.ifrw_info & 0xffff;
531 addr->il_bcr = sizeof(struct il_rheader) + ETHERMTU + 6;
532 addr->il_csr =
533 ((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;
534 s = splhigh();
535 while ((addr->il_csr & IL_CDONE) == 0)
536 ;
537 splx(s);
538 }
539 /*
540 * Watchdog routine, request statistics from board.
541 */
542 ilwatch(unit)
543 int unit;
544 {
545 register struct il_softc *is = &il_softc[unit];
546 register struct ifnet *ifp = &is->is_if;
547 int s;
548
549 if (is->is_flags & ILF_STATPENDING) {
550 ifp->if_timer = is->is_scaninterval;
551 return;
552 }
553 s = splimp();
554 is->is_flags |= ILF_STATPENDING;
555 if ((is->is_if.if_flags & IFF_OACTIVE) == 0)
556 (void) ilstart(ifp);
557 splx(s);
558 ifp->if_timer = is->is_scaninterval;
559 }
560
561 /*
562 * Total up the on-board statistics.
563 */
564 iltotal(is)
565 register struct il_softc *is;
566 {
567 register u_short *interval, *sum, *end;
568
569 interval = &is->is_stats.ils_frames;
570 sum = &is->is_sum.ils_frames;
571 end = is->is_sum.ils_fill2;
572 while (sum < end)
573 *sum++ += *interval++;
574 is->is_if.if_collisions = is->is_sum.ils_collis;
575 if ((is->is_flags & ILF_SETADDR) &&
576 (bcmp((caddr_t)is->is_stats.ils_addr, (caddr_t)is->is_addr,
577 sizeof (is->is_addr)) != 0)) {
578 log(LOG_ERR, "il%d: physaddr reverted\n", is->is_if.if_unit);
579 is->is_flags &= ~ILF_RUNNING;
580 ilinit(is->is_if.if_unit);
581 }
582 }
583
584 /*
585 * Process an ioctl request.
586 */
587 ilioctl(ifp, cmd, data)
588 register struct ifnet *ifp;
589 int cmd;
590 caddr_t data;
591 {
592 register struct ifaddr *ifa = (struct ifaddr *)data;
593 register struct il_softc *is = &il_softc[ifp->if_unit];
594 int s = splimp(), error = 0;
595
596 switch (cmd) {
597
598 case SIOCSIFADDR:
599 ifp->if_flags |= IFF_UP;
600 ilinit(ifp->if_unit);
601
602 switch (ifa->ifa_addr->sa_family) {
603 #ifdef INET
604 case AF_INET:
605 ((struct arpcom *)ifp)->ac_ipaddr =
606 IA_SIN(ifa)->sin_addr;
607 arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
608 break;
609 #endif
610 #ifdef NS
611 case AF_NS:
612 {
613 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
614
615 if (ns_nullhost(*ina)) {
616 ina->x_host = * (union ns_host *)
617 (il_softc[ifp->if_unit].is_addr);
618 } else {
619 il_setaddr(ina->x_host.c_host, ifp->if_unit);
620 return (0);
621 }
622 break;
623 }
624 #endif
625 }
626 break;
627
628 case SIOCSIFFLAGS:
629 if ((ifp->if_flags & IFF_UP) == 0 &&
630 is->is_flags & ILF_RUNNING) {
631 ((struct ildevice *)
632 (ilinfo[ifp->if_unit]->ui_addr))->il_csr = ILC_RESET;
633 is->is_flags &= ~ILF_RUNNING;
634 } else if (ifp->if_flags & IFF_UP &&
635 (is->is_flags & ILF_RUNNING) == 0)
636 ilinit(ifp->if_unit);
637 break;
638
639 default:
640 error = EINVAL;
641 }
642 splx(s);
643 return (error);
644 }
645
646 /*
647 * set ethernet address for unit
648 */
649 il_setaddr(physaddr, unit)
650 u_char *physaddr;
651 int unit;
652 {
653 register struct il_softc *is = &il_softc[unit];
654
655 if (! (is->is_flags & ILF_RUNNING))
656 return;
657
658 bcopy((caddr_t)physaddr, (caddr_t)is->is_addr, sizeof is->is_addr);
659 is->is_flags &= ~ILF_RUNNING;
660 is->is_flags |= ILF_SETADDR;
661 ilinit(unit);
662 }
663 #endif
664