if_le.c revision 1.1 1 /*
2 * Copyright (c) 1982, 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)if_le.c 7.6 (Berkeley) 5/8/91
34 */
35
36 #include "le.h"
37 #if NLE > 0
38
39 #include "bpfilter.h"
40
41 /*
42 * AMD 7990 LANCE
43 *
44 * This driver will generate and accept tailer encapsulated packets even
45 * though it buys us nothing. The motivation was to avoid incompatibilities
46 * with VAXen, SUNs, and others that handle and benefit from them.
47 * This reasoning is dubious.
48 */
49 #include "sys/param.h"
50 #include "sys/systm.h"
51 #include "sys/mbuf.h"
52 #include "sys/buf.h"
53 #include "sys/protosw.h"
54 #include "sys/socket.h"
55 #include "sys/syslog.h"
56 #include "sys/ioctl.h"
57 #include "sys/errno.h"
58
59 #include "net/if.h"
60 #include "net/netisr.h"
61 #include "net/route.h"
62
63 #ifdef INET
64 #include "netinet/in.h"
65 #include "netinet/in_systm.h"
66 #include "netinet/in_var.h"
67 #include "netinet/ip.h"
68 #include "netinet/if_ether.h"
69 #endif
70
71 #ifdef NS
72 #include "netns/ns.h"
73 #include "netns/ns_if.h"
74 #endif
75
76 #ifdef RMP
77 #include "netrmp/rmp.h"
78 #include "netrmp/rmp_var.h"
79 #endif
80
81 #include "../include/cpu.h"
82 #include "../hp300/isr.h"
83 #include "../include/mtpr.h"
84 #include "device.h"
85 #include "if_lereg.h"
86
87 #if NBPFILTER > 0
88 #include "../net/bpf.h"
89 #include "../net/bpfdesc.h"
90 #endif
91
92 /* offsets for: ID, REGS, MEM, NVRAM */
93 int lestd[] = { 0, 0x4000, 0x8000, 0xC008 };
94
95 int leattach();
96 struct driver ledriver = {
97 leattach, "le",
98 };
99
100 struct isr le_isr[NLE];
101 int ledebug = 0; /* console error messages */
102
103 int leintr(), leinit(), leioctl(), lestart(), ether_output();
104 struct mbuf *leget();
105 extern struct ifnet loif;
106
107 /*
108 * Ethernet software status per interface.
109 *
110 * Each interface is referenced by a network interface structure,
111 * le_if, which the routing code uses to locate the interface.
112 * This structure contains the output queue for the interface, its address, ...
113 */
114 struct le_softc {
115 struct arpcom sc_ac; /* common Ethernet structures */
116 #define sc_if sc_ac.ac_if /* network-visible interface */
117 #define sc_addr sc_ac.ac_enaddr /* hardware Ethernet address */
118 struct lereg0 *sc_r0; /* DIO registers */
119 struct lereg1 *sc_r1; /* LANCE registers */
120 struct lereg2 *sc_r2; /* dual-port RAM */
121 int sc_rmd; /* predicted next rmd to process */
122 int sc_runt;
123 int sc_jab;
124 int sc_merr;
125 int sc_babl;
126 int sc_cerr;
127 int sc_miss;
128 int sc_xint;
129 int sc_xown;
130 int sc_uflo;
131 int sc_rxlen;
132 int sc_rxoff;
133 int sc_txoff;
134 int sc_busy;
135 short sc_iflags;
136 #if NBPFILTER > 0
137 caddr_t sc_bpf;
138 #endif
139 } le_softc[NLE];
140
141 /* access LANCE registers */
142 #define LERDWR(cntl, src, dst) \
143 do { \
144 (dst) = (src); \
145 } while (((cntl)->ler0_status & LE_ACK) == 0);
146
147 /*
148 * Interface exists: make available by filling in network interface
149 * record. System will initialize the interface when it is ready
150 * to accept packets.
151 */
152 leattach(hd)
153 struct hp_device *hd;
154 {
155 register struct lereg0 *ler0;
156 register struct lereg2 *ler2;
157 struct lereg2 *lemem = 0;
158 struct le_softc *le = &le_softc[hd->hp_unit];
159 struct ifnet *ifp = &le->sc_if;
160 char *cp;
161 int i;
162
163 ler0 = le->sc_r0 = (struct lereg0 *)(lestd[0] + (int)hd->hp_addr);
164 le->sc_r1 = (struct lereg1 *)(lestd[1] + (int)hd->hp_addr);
165 ler2 = le->sc_r2 = (struct lereg2 *)(lestd[2] + (int)hd->hp_addr);
166 if (ler0->ler0_id != LEID)
167 return(0);
168 le_isr[hd->hp_unit].isr_intr = leintr;
169 hd->hp_ipl = le_isr[hd->hp_unit].isr_ipl = LE_IPL(ler0->ler0_status);
170 le_isr[hd->hp_unit].isr_arg = hd->hp_unit;
171 ler0->ler0_id = 0xFF;
172 DELAY(100);
173
174 /*
175 * Read the ethernet address off the board, one nibble at a time.
176 */
177 cp = (char *)(lestd[3] + (int)hd->hp_addr);
178 for (i = 0; i < sizeof(le->sc_addr); i++) {
179 le->sc_addr[i] = (*++cp & 0xF) << 4;
180 cp++;
181 le->sc_addr[i] |= *++cp & 0xF;
182 cp++;
183 }
184 printf("le%d: hardware address %s\n", hd->hp_unit,
185 ether_sprintf(le->sc_addr));
186
187 /*
188 * Setup for transmit/receive
189 */
190 ler2->ler2_mode = LE_MODE;
191 ler2->ler2_padr[0] = le->sc_addr[1];
192 ler2->ler2_padr[1] = le->sc_addr[0];
193 ler2->ler2_padr[2] = le->sc_addr[3];
194 ler2->ler2_padr[3] = le->sc_addr[2];
195 ler2->ler2_padr[4] = le->sc_addr[5];
196 ler2->ler2_padr[5] = le->sc_addr[4];
197 #ifdef RMP
198 /*
199 * Set up logical addr filter to accept multicast 9:0:9:0:0:4
200 * This should be an ioctl() to the driver. (XXX)
201 */
202 ler2->ler2_ladrf0 = 0x00100000;
203 ler2->ler2_ladrf1 = 0x0;
204 #else
205 ler2->ler2_ladrf0 = 0;
206 ler2->ler2_ladrf1 = 0;
207 #endif
208 ler2->ler2_rlen = LE_RLEN;
209 ler2->ler2_rdra = (int)lemem->ler2_rmd;
210 ler2->ler2_tlen = LE_TLEN;
211 ler2->ler2_tdra = (int)lemem->ler2_tmd;
212 isrlink(&le_isr[hd->hp_unit]);
213 ler0->ler0_status = LE_IE;
214
215 ifp->if_unit = hd->hp_unit;
216 ifp->if_name = "le";
217 ifp->if_mtu = ETHERMTU;
218 ifp->if_init = leinit;
219 ifp->if_ioctl = leioctl;
220 ifp->if_output = ether_output;
221 ifp->if_start = lestart;
222 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
223 #if NBPFILTER > 0
224 bpfattach(&le->sc_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
225 #endif
226 if_attach(ifp);
227 return (1);
228 }
229
230 ledrinit(ler2)
231 register struct lereg2 *ler2;
232 {
233 register struct lereg2 *lemem = 0;
234 register int i;
235
236 for (i = 0; i < LERBUF; i++) {
237 ler2->ler2_rmd[i].rmd0 = (int)lemem->ler2_rbuf[i];
238 ler2->ler2_rmd[i].rmd1 = LE_OWN;
239 ler2->ler2_rmd[i].rmd2 = -LEMTU;
240 ler2->ler2_rmd[i].rmd3 = 0;
241 }
242 for (i = 0; i < LETBUF; i++) {
243 ler2->ler2_tmd[i].tmd0 = (int)lemem->ler2_tbuf[i];
244 ler2->ler2_tmd[i].tmd1 = 0;
245 ler2->ler2_tmd[i].tmd2 = 0;
246 ler2->ler2_tmd[i].tmd3 = 0;
247 }
248 }
249
250 lereset(unit)
251 register int unit;
252 {
253 register struct le_softc *le = &le_softc[unit];
254 register struct lereg0 *ler0 = le->sc_r0;
255 register struct lereg1 *ler1 = le->sc_r1;
256 register struct lereg2 *lemem = 0;
257 register int timo = 100000;
258 register int stat;
259
260 #ifdef lint
261 stat = unit;
262 #endif
263 #if NBPFILTER > 0
264 if (le->sc_if.if_flags & IFF_PROMISC)
265 /* set the promiscuous bit */
266 le->sc_r2->ler2_mode = LE_MODE|0x8000;
267 else
268 le->sc_r2->ler2_mode = LE_MODE;
269 #endif
270 LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
271 LERDWR(ler0, LE_STOP, ler1->ler1_rdp);
272 ledrinit(le->sc_r2);
273 le->sc_rmd = 0;
274 LERDWR(ler0, LE_CSR1, ler1->ler1_rap);
275 LERDWR(ler0, (int)&lemem->ler2_mode, ler1->ler1_rdp);
276 LERDWR(ler0, LE_CSR2, ler1->ler1_rap);
277 LERDWR(ler0, 0, ler1->ler1_rdp);
278 LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
279 LERDWR(ler0, LE_INIT, ler1->ler1_rdp);
280 do {
281 if (--timo == 0) {
282 printf("le%d: init timeout, stat = 0x%x\n",
283 unit, stat);
284 break;
285 }
286 LERDWR(ler0, ler1->ler1_rdp, stat);
287 } while ((stat & LE_IDON) == 0);
288 LERDWR(ler0, LE_STOP, ler1->ler1_rdp);
289 LERDWR(ler0, LE_CSR3, ler1->ler1_rap);
290 LERDWR(ler0, LE_BSWP, ler1->ler1_rdp);
291 LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
292 LERDWR(ler0, LE_STRT | LE_INEA, ler1->ler1_rdp);
293 le->sc_if.if_flags &= ~IFF_OACTIVE;
294 }
295
296 /*
297 * Initialization of interface
298 */
299 leinit(unit)
300 int unit;
301 {
302 struct le_softc *le = &le_softc[unit];
303 register struct ifnet *ifp = &le->sc_if;
304 int s;
305
306 /* not yet, if address still unknown */
307 if (ifp->if_addrlist == (struct ifaddr *)0)
308 return;
309 if ((ifp->if_flags & IFF_RUNNING) == 0) {
310 s = splimp();
311 ifp->if_flags |= IFF_RUNNING;
312 lereset(unit);
313 (void) lestart(ifp);
314 splx(s);
315 }
316 }
317
318 /*
319 * Start output on interface. Get another datagram to send
320 * off of the interface queue, and copy it to the interface
321 * before starting the output.
322 */
323 lestart(ifp)
324 struct ifnet *ifp;
325 {
326 register struct le_softc *le = &le_softc[ifp->if_unit];
327 register struct letmd *tmd;
328 register struct mbuf *m;
329 int len;
330
331 if ((le->sc_if.if_flags & IFF_RUNNING) == 0)
332 return (0);
333 IF_DEQUEUE(&le->sc_if.if_snd, m);
334 if (m == 0)
335 return (0);
336 len = leput(le->sc_r2->ler2_tbuf[0], m);
337 #if NBPFILTER > 0
338 /*
339 * If bpf is listening on this interface, let it
340 * see the packet before we commit it to the wire.
341 */
342 if (le->sc_bpf)
343 bpf_tap(le->sc_bpf, le->sc_r2->ler2_tbuf[0], len);
344 #endif
345 tmd = le->sc_r2->ler2_tmd;
346 tmd->tmd3 = 0;
347 tmd->tmd2 = -len;
348 tmd->tmd1 = LE_OWN | LE_STP | LE_ENP;
349 le->sc_if.if_flags |= IFF_OACTIVE;
350 return (0);
351 }
352
353 leintr(unit)
354 register int unit;
355 {
356 register struct le_softc *le = &le_softc[unit];
357 register struct lereg0 *ler0 = le->sc_r0;
358 register struct lereg1 *ler1;
359 register int stat;
360
361 if ((ler0->ler0_status & LE_IR) == 0)
362 return(0);
363 if (ler0->ler0_status & LE_JAB) {
364 le->sc_jab++;
365 lereset(unit);
366 return(1);
367 }
368 ler1 = le->sc_r1;
369 LERDWR(ler0, ler1->ler1_rdp, stat);
370 if (stat & LE_SERR) {
371 leerror(unit, stat);
372 if (stat & LE_MERR) {
373 le->sc_merr++;
374 lereset(unit);
375 return(1);
376 }
377 if (stat & LE_BABL)
378 le->sc_babl++;
379 if (stat & LE_CERR)
380 le->sc_cerr++;
381 if (stat & LE_MISS)
382 le->sc_miss++;
383 LERDWR(ler0, LE_BABL|LE_CERR|LE_MISS|LE_INEA, ler1->ler1_rdp);
384 }
385 if ((stat & LE_RXON) == 0) {
386 le->sc_rxoff++;
387 lereset(unit);
388 return(1);
389 }
390 if ((stat & LE_TXON) == 0) {
391 le->sc_txoff++;
392 lereset(unit);
393 return(1);
394 }
395 if (stat & LE_RINT) {
396 /* interrupt is cleared in lerint */
397 lerint(unit);
398 }
399 if (stat & LE_TINT) {
400 LERDWR(ler0, LE_TINT|LE_INEA, ler1->ler1_rdp);
401 lexint(unit);
402 }
403 return(1);
404 }
405
406 /*
407 * Ethernet interface transmitter interrupt.
408 * Start another output if more data to send.
409 */
410 lexint(unit)
411 register int unit;
412 {
413 register struct le_softc *le = &le_softc[unit];
414 register struct letmd *tmd = le->sc_r2->ler2_tmd;
415
416 if ((le->sc_if.if_flags & IFF_OACTIVE) == 0) {
417 le->sc_xint++;
418 return;
419 }
420 if (tmd->tmd1 & LE_OWN) {
421 le->sc_xown++;
422 return;
423 }
424 if (tmd->tmd1 & LE_ERR) {
425 err:
426 lexerror(unit);
427 le->sc_if.if_oerrors++;
428 if (tmd->tmd3 & (LE_TBUFF|LE_UFLO)) {
429 le->sc_uflo++;
430 lereset(unit);
431 }
432 else if (tmd->tmd3 & LE_LCOL)
433 le->sc_if.if_collisions++;
434 else if (tmd->tmd3 & LE_RTRY)
435 le->sc_if.if_collisions += 16;
436 }
437 else if (tmd->tmd3 & LE_TBUFF)
438 /* XXX documentation says BUFF not included in ERR */
439 goto err;
440 else if (tmd->tmd1 & LE_ONE)
441 le->sc_if.if_collisions++;
442 else if (tmd->tmd1 & LE_MORE)
443 /* what is the real number? */
444 le->sc_if.if_collisions += 2;
445 else
446 le->sc_if.if_opackets++;
447 le->sc_if.if_flags &= ~IFF_OACTIVE;
448 (void) lestart(&le->sc_if);
449 }
450
451 #define LENEXTRMP \
452 if (++bix == LERBUF) bix = 0, rmd = le->sc_r2->ler2_rmd; else ++rmd
453
454 /*
455 * Ethernet interface receiver interrupt.
456 * If input error just drop packet.
457 * Decapsulate packet based on type and pass to type specific
458 * higher-level input routine.
459 */
460 lerint(unit)
461 int unit;
462 {
463 register struct le_softc *le = &le_softc[unit];
464 register int bix = le->sc_rmd;
465 register struct lermd *rmd = &le->sc_r2->ler2_rmd[bix];
466
467 /*
468 * Out of sync with hardware, should never happen?
469 */
470 if (rmd->rmd1 & LE_OWN) {
471 LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp);
472 return;
473 }
474
475 /*
476 * Process all buffers with valid data
477 */
478 while ((rmd->rmd1 & LE_OWN) == 0) {
479 int len = rmd->rmd3;
480
481 /* Clear interrupt to avoid race condition */
482 LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp);
483
484 if (rmd->rmd1 & LE_ERR) {
485 le->sc_rmd = bix;
486 lererror(unit, "bad packet");
487 le->sc_if.if_ierrors++;
488 } else if ((rmd->rmd1 & (LE_STP|LE_ENP)) != (LE_STP|LE_ENP)) {
489 /*
490 * Find the end of the packet so we can see how long
491 * it was. We still throw it away.
492 */
493 do {
494 LERDWR(le->sc_r0, LE_RINT|LE_INEA,
495 le->sc_r1->ler1_rdp);
496 rmd->rmd3 = 0;
497 rmd->rmd1 = LE_OWN;
498 LENEXTRMP;
499 } while (!(rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP)));
500 le->sc_rmd = bix;
501 lererror(unit, "chained buffer");
502 le->sc_rxlen++;
503 /*
504 * If search terminated without successful completion
505 * we reset the hardware (conservative).
506 */
507 if ((rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP)) !=
508 LE_ENP) {
509 lereset(unit);
510 return;
511 }
512 } else
513 leread(unit, le->sc_r2->ler2_rbuf[bix], len);
514 rmd->rmd3 = 0;
515 rmd->rmd1 = LE_OWN;
516 LENEXTRMP;
517 }
518 le->sc_rmd = bix;
519 }
520
521 leread(unit, buf, len)
522 int unit;
523 char *buf;
524 int len;
525 {
526 register struct le_softc *le = &le_softc[unit];
527 register struct ether_header *et;
528 struct mbuf *m;
529 int off, resid;
530
531 le->sc_if.if_ipackets++;
532 et = (struct ether_header *)buf;
533 et->ether_type = ntohs((u_short)et->ether_type);
534 /* adjust input length to account for header and CRC */
535 len = len - sizeof(struct ether_header) - 4;
536
537 #ifdef RMP
538 /* (XXX)
539 *
540 * If Ethernet Type field is < MaxPacketSize, we probably have
541 * a IEEE802 packet here. Make sure that the size is at least
542 * that of the HP LLC. Also do sanity checks on length of LLC
543 * (old Ethernet Type field) and packet length.
544 *
545 * Provided the above checks succeed, change `len' to reflect
546 * the length of the LLC (i.e. et->ether_type) and change the
547 * type field to ETHERTYPE_IEEE so we can switch() on it later.
548 * Yes, this is a hack and will eventually be done "right".
549 */
550 if (et->ether_type <= IEEE802LEN_MAX && len >= sizeof(struct hp_llc) &&
551 len >= et->ether_type && len >= IEEE802LEN_MIN) {
552 len = et->ether_type;
553 et->ether_type = ETHERTYPE_IEEE; /* hack! */
554 }
555 #endif
556
557 #define ledataaddr(et, off, type) ((type)(((caddr_t)((et)+1)+(off))))
558 if (et->ether_type >= ETHERTYPE_TRAIL &&
559 et->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
560 off = (et->ether_type - ETHERTYPE_TRAIL) * 512;
561 if (off >= ETHERMTU)
562 return; /* sanity */
563 et->ether_type = ntohs(*ledataaddr(et, off, u_short *));
564 resid = ntohs(*(ledataaddr(et, off+2, u_short *)));
565 if (off + resid > len)
566 return; /* sanity */
567 len = off + resid;
568 } else
569 off = 0;
570
571 if (len <= 0) {
572 if (ledebug)
573 log(LOG_WARNING,
574 "le%d: ierror(runt packet): from %s: len=%d\n",
575 unit, ether_sprintf(et->ether_shost), len);
576 le->sc_runt++;
577 le->sc_if.if_ierrors++;
578 return;
579 }
580 #if NBPFILTER > 0
581 /*
582 * Check if there's a bpf filter listening on this interface.
583 * If so, hand off the raw packet to bpf, which must deal with
584 * trailers in its own way.
585 */
586 if (le->sc_bpf) {
587 bpf_tap(le->sc_bpf, buf, len + sizeof(struct ether_header));
588
589 /*
590 * Note that the interface cannot be in promiscuous mode if
591 * there are no bpf listeners. And if we are in promiscuous
592 * mode, we have to check if this packet is really ours.
593 *
594 * XXX This test does not support multicasts.
595 */
596 if ((le->sc_if.if_flags & IFF_PROMISC)
597 && bcmp(et->ether_dhost, le->sc_addr,
598 sizeof(et->ether_dhost)) != 0
599 && bcmp(et->ether_dhost, etherbroadcastaddr,
600 sizeof(et->ether_dhost)) != 0)
601 return;
602 }
603 #endif
604 /*
605 * Pull packet off interface. Off is nonzero if packet
606 * has trailing header; leget will then force this header
607 * information to be at the front, but we still have to drop
608 * the type and length which are at the front of any trailer data.
609 */
610 m = leget(buf, len, off, &le->sc_if);
611 if (m == 0)
612 return;
613 #ifdef RMP
614 /*
615 * (XXX)
616 * This needs to be integrated with the ISO stuff in ether_input()
617 */
618 if (et->ether_type == ETHERTYPE_IEEE) {
619 /*
620 * Snag the Logical Link Control header (IEEE 802.2).
621 */
622 struct hp_llc *llc = &(mtod(m, struct rmp_packet *)->hp_llc);
623
624 /*
625 * If the DSAP (and HP's extended DXSAP) indicate this
626 * is an RMP packet, hand it to the raw input routine.
627 */
628 if (llc->dsap == IEEE_DSAP_HP && llc->dxsap == HPEXT_DXSAP) {
629 static struct sockproto rmp_sp = {AF_RMP,RMPPROTO_BOOT};
630 static struct sockaddr rmp_src = {AF_RMP};
631 static struct sockaddr rmp_dst = {AF_RMP};
632
633 bcopy(et->ether_shost, rmp_src.sa_data,
634 sizeof(et->ether_shost));
635 bcopy(et->ether_dhost, rmp_dst.sa_data,
636 sizeof(et->ether_dhost));
637
638 raw_input(m, &rmp_sp, &rmp_src, &rmp_dst);
639 return;
640 }
641 }
642 #endif
643 ether_input(&le->sc_if, et, m);
644 }
645
646 /*
647 * Routine to copy from mbuf chain to transmit
648 * buffer in board local memory.
649 */
650 leput(lebuf, m)
651 register char *lebuf;
652 register struct mbuf *m;
653 {
654 register struct mbuf *mp;
655 register int len, tlen = 0;
656
657 for (mp = m; mp; mp = mp->m_next) {
658 len = mp->m_len;
659 if (len == 0)
660 continue;
661 tlen += len;
662 bcopy(mtod(mp, char *), lebuf, len);
663 lebuf += len;
664 }
665 m_freem(m);
666 if (tlen < LEMINSIZE) {
667 bzero(lebuf, LEMINSIZE - tlen);
668 tlen = LEMINSIZE;
669 }
670 return(tlen);
671 }
672
673 /*
674 * Routine to copy from board local memory into mbufs.
675 */
676 struct mbuf *
677 leget(lebuf, totlen, off0, ifp)
678 char *lebuf;
679 int totlen, off0;
680 struct ifnet *ifp;
681 {
682 register struct mbuf *m;
683 struct mbuf *top = 0, **mp = ⊤
684 register int off = off0, len;
685 register char *cp;
686 char *epkt;
687
688 lebuf += sizeof (struct ether_header);
689 cp = lebuf;
690 epkt = cp + totlen;
691 if (off) {
692 cp += off + 2 * sizeof(u_short);
693 totlen -= 2 * sizeof(u_short);
694 }
695
696 MGETHDR(m, M_DONTWAIT, MT_DATA);
697 if (m == 0)
698 return (0);
699 m->m_pkthdr.rcvif = ifp;
700 m->m_pkthdr.len = totlen;
701 m->m_len = MHLEN;
702
703 while (totlen > 0) {
704 if (top) {
705 MGET(m, M_DONTWAIT, MT_DATA);
706 if (m == 0) {
707 m_freem(top);
708 return (0);
709 }
710 m->m_len = MLEN;
711 }
712 len = min(totlen, epkt - cp);
713 if (len >= MINCLSIZE) {
714 MCLGET(m, M_DONTWAIT);
715 if (m->m_flags & M_EXT)
716 m->m_len = len = min(len, MCLBYTES);
717 else
718 len = m->m_len;
719 } else {
720 /*
721 * Place initial small packet/header at end of mbuf.
722 */
723 if (len < m->m_len) {
724 if (top == 0 && len + max_linkhdr <= m->m_len)
725 m->m_data += max_linkhdr;
726 m->m_len = len;
727 } else
728 len = m->m_len;
729 }
730 bcopy(cp, mtod(m, caddr_t), (unsigned)len);
731 cp += len;
732 *mp = m;
733 mp = &m->m_next;
734 totlen -= len;
735 if (cp == epkt)
736 cp = lebuf;
737 }
738 return (top);
739 }
740
741 /*
742 * Process an ioctl request.
743 */
744 leioctl(ifp, cmd, data)
745 register struct ifnet *ifp;
746 int cmd;
747 caddr_t data;
748 {
749 register struct ifaddr *ifa = (struct ifaddr *)data;
750 struct le_softc *le = &le_softc[ifp->if_unit];
751 struct lereg1 *ler1 = le->sc_r1;
752 int s = splimp(), error = 0;
753
754 switch (cmd) {
755
756 case SIOCSIFADDR:
757 ifp->if_flags |= IFF_UP;
758 switch (ifa->ifa_addr->sa_family) {
759 #ifdef INET
760 case AF_INET:
761 leinit(ifp->if_unit); /* before arpwhohas */
762 ((struct arpcom *)ifp)->ac_ipaddr =
763 IA_SIN(ifa)->sin_addr;
764 arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
765 break;
766 #endif
767 #ifdef NS
768 case AF_NS:
769 {
770 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
771
772 if (ns_nullhost(*ina))
773 ina->x_host = *(union ns_host *)(le->sc_addr);
774 else {
775 /*
776 * The manual says we can't change the address
777 * while the receiver is armed,
778 * so reset everything
779 */
780 ifp->if_flags &= ~IFF_RUNNING;
781 bcopy((caddr_t)ina->x_host.c_host,
782 (caddr_t)le->sc_addr, sizeof(le->sc_addr));
783 }
784 leinit(ifp->if_unit); /* does le_setaddr() */
785 break;
786 }
787 #endif
788 default:
789 leinit(ifp->if_unit);
790 break;
791 }
792 break;
793
794 case SIOCSIFFLAGS:
795 if ((ifp->if_flags & IFF_UP) == 0 &&
796 ifp->if_flags & IFF_RUNNING) {
797 LERDWR(le->sc_r0, LE_STOP, ler1->ler1_rdp);
798 ifp->if_flags &= ~IFF_RUNNING;
799 } else if (ifp->if_flags & IFF_UP &&
800 (ifp->if_flags & IFF_RUNNING) == 0)
801 leinit(ifp->if_unit);
802 /*
803 * If the state of the promiscuous bit changes, the interface
804 * must be reset to effect the change.
805 */
806 if (((ifp->if_flags ^ le->sc_iflags) & IFF_PROMISC) &&
807 (ifp->if_flags & IFF_RUNNING)) {
808 le->sc_iflags = ifp->if_flags;
809 lereset(ifp->if_unit);
810 lestart(ifp);
811 }
812 break;
813
814 default:
815 error = EINVAL;
816 }
817 splx(s);
818 return (error);
819 }
820
821 leerror(unit, stat)
822 int unit;
823 int stat;
824 {
825 if (!ledebug)
826 return;
827
828 /*
829 * Not all transceivers implement heartbeat
830 * so we only log CERR once.
831 */
832 if ((stat & LE_CERR) && le_softc[unit].sc_cerr)
833 return;
834 log(LOG_WARNING,
835 "le%d: error: stat=%b\n", unit,
836 stat,
837 "\20\20ERR\17BABL\16CERR\15MISS\14MERR\13RINT\12TINT\11IDON\10INTR\07INEA\06RXON\05TXON\04TDMD\03STOP\02STRT\01INIT");
838 }
839
840 lererror(unit, msg)
841 int unit;
842 char *msg;
843 {
844 register struct le_softc *le = &le_softc[unit];
845 register struct lermd *rmd;
846 int len;
847
848 if (!ledebug)
849 return;
850
851 rmd = &le->sc_r2->ler2_rmd[le->sc_rmd];
852 len = rmd->rmd3;
853 log(LOG_WARNING,
854 "le%d: ierror(%s): from %s: buf=%d, len=%d, rmd1=%b\n",
855 unit, msg,
856 len > 11 ? ether_sprintf(&le->sc_r2->ler2_rbuf[le->sc_rmd][6]) : "unknown",
857 le->sc_rmd, len,
858 rmd->rmd1,
859 "\20\20OWN\17ERR\16FRAM\15OFLO\14CRC\13RBUF\12STP\11ENP");
860 }
861
862 lexerror(unit)
863 int unit;
864 {
865 register struct le_softc *le = &le_softc[unit];
866 register struct letmd *tmd;
867 int len;
868
869 if (!ledebug)
870 return;
871
872 tmd = le->sc_r2->ler2_tmd;
873 len = -tmd->tmd2;
874 log(LOG_WARNING,
875 "le%d: oerror: to %s: buf=%d, len=%d, tmd1=%b, tmd3=%b\n",
876 unit,
877 len > 5 ? ether_sprintf(&le->sc_r2->ler2_tbuf[0][0]) : "unknown",
878 0, len,
879 tmd->tmd1,
880 "\20\20OWN\17ERR\16RES\15MORE\14ONE\13DEF\12STP\11ENP",
881 tmd->tmd3,
882 "\20\20BUFF\17UFLO\16RES\15LCOL\14LCAR\13RTRY");
883 }
884 #endif
885