1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)if_en.c 7.1 (Berkeley) 6/5/86
7: */
8:
9: #include "en.h"
10: #if NEN > 0
11:
12: /*
13: * Xerox prototype (3 Mb) Ethernet interface driver.
14: */
15: #include "../machine/pte.h"
16:
17: #include "param.h"
18: #include "systm.h"
19: #include "mbuf.h"
20: #include "buf.h"
21: #include "protosw.h"
22: #include "socket.h"
23: #include "vmmac.h"
24: #include "errno.h"
25: #include "ioctl.h"
26:
27: #include "../net/if.h"
28: #include "../net/netisr.h"
29: #include "../net/route.h"
30:
31: #ifdef INET
32: #include "../netinet/in.h"
33: #include "../netinet/in_systm.h"
34: #include "../netinet/in_var.h"
35: #include "../netinet/ip.h"
36: #endif
37:
38: #ifdef PUP
39: #include "../netpup/pup.h"
40: #include "../netpup/ether.h"
41: #endif
42:
43: #ifdef NS
44: #include "../netns/ns.h"
45: #include "../netns/ns_if.h"
46: #endif
47:
48: #include "../vax/cpu.h"
49: #include "../vax/mtpr.h"
50: #include "if_en.h"
51: #include "if_enreg.h"
52: #include "if_uba.h"
53: #include "../vaxuba/ubareg.h"
54: #include "../vaxuba/ubavar.h"
55:
56: #define ENMTU (1024+512)
57: #define ENMRU (1024+512+16) /* 16 is enough to receive trailer */
58:
59: int enprobe(), enattach(), enrint(), enxint(), encollide();
60: struct uba_device *eninfo[NEN];
61: u_short enstd[] = { 0 };
62: struct uba_driver endriver =
63: { enprobe, 0, enattach, 0, enstd, "en", eninfo };
64: #define ENUNIT(x) minor(x)
65:
66: int eninit(),enoutput(),enreset(),enioctl();
67:
68: #ifdef notdef
69: /*
70: * If you need to byte swap IP's in the system, define
71: * this and do a SIOCSIFFLAGS at boot time.
72: */
73: #define ENF_SWABIPS 0x1000
74: #endif
75:
76: /*
77: * Ethernet software status per interface.
78: *
79: * Each interface is referenced by a network interface structure,
80: * es_if, which the routing code uses to locate the interface.
81: * This structure contains the output queue for the interface, its address, ...
82: * We also have, for each interface, a UBA interface structure, which
83: * contains information about the UNIBUS resources held by the interface:
84: * map registers, buffered data paths, etc. Information is cached in this
85: * structure for use by the if_uba.c routines in running the interface
86: * efficiently.
87: */
88: struct en_softc {
89: struct ifnet es_if; /* network-visible interface */
90: struct ifuba es_ifuba; /* UNIBUS resources */
91: short es_host; /* hardware host number */
92: short es_delay; /* current output delay */
93: short es_mask; /* mask for current output delay */
94: short es_lastx; /* host last transmitted to */
95: short es_oactive; /* is output active? */
96: short es_olen; /* length of last output */
97: short es_nsactive; /* is interface enabled for ns? */
98: } en_softc[NEN];
99:
100: /*
101: * Do output DMA to determine interface presence and
102: * interrupt vector. DMA is too short to disturb other hosts.
103: */
104: enprobe(reg)
105: caddr_t reg;
106: {
107: register int br, cvec; /* r11, r10 value-result */
108: register struct endevice *addr = (struct endevice *)reg;
109:
110: #ifdef lint
111: br = 0; cvec = br; br = cvec;
112: enrint(0); enxint(0); encollide(0);
113: #endif
114: addr->en_istat = 0;
115: addr->en_owc = -1;
116: addr->en_oba = 0;
117: addr->en_ostat = EN_IEN|EN_GO;
118: DELAY(100000);
119: addr->en_ostat = 0;
120: return (1);
121: }
122:
123: /*
124: * Interface exists: make available by filling in network interface
125: * record. System will initialize the interface when it is ready
126: * to accept packets.
127: */
128: enattach(ui)
129: struct uba_device *ui;
130: {
131: register struct en_softc *es = &en_softc[ui->ui_unit];
132:
133: es->es_if.if_unit = ui->ui_unit;
134: es->es_if.if_name = "en";
135: es->es_if.if_mtu = ENMTU;
136: es->es_if.if_flags = IFF_BROADCAST;
137: es->es_if.if_init = eninit;
138: es->es_if.if_output = enoutput;
139: es->es_if.if_ioctl = enioctl;
140: es->es_if.if_reset = enreset;
141: es->es_ifuba.ifu_flags = UBA_NEEDBDP | UBA_NEED16 | UBA_CANTWAIT;
142: #if defined(VAX750)
143: /* don't chew up 750 bdp's */
144: if (cpu == VAX_750 && ui->ui_unit > 0)
145: es->es_ifuba.ifu_flags &= ~UBA_NEEDBDP;
146: #endif
147: if_attach(&es->es_if);
148: }
149:
150: /*
151: * Reset of interface after UNIBUS reset.
152: * If interface is on specified uba, reset its state.
153: */
154: enreset(unit, uban)
155: int unit, uban;
156: {
157: register struct uba_device *ui;
158:
159: if (unit >= NEN || (ui = eninfo[unit]) == 0 || ui->ui_alive == 0 ||
160: ui->ui_ubanum != uban)
161: return;
162: printf(" en%d", unit);
163: eninit(unit);
164: }
165:
166: /*
167: * Initialization of interface; clear recorded pending
168: * operations, and reinitialize UNIBUS usage.
169: */
170: eninit(unit)
171: int unit;
172: {
173: register struct en_softc *es = &en_softc[unit];
174: register struct uba_device *ui = eninfo[unit];
175: register struct endevice *addr;
176: int s;
177:
178: if (es->es_if.if_addrlist == (struct ifaddr *)0)
179: return;
180: if (if_ubainit(&es->es_ifuba, ui->ui_ubanum,
181: sizeof (struct en_header), (int)btoc(ENMRU)) == 0) {
182: printf("en%d: can't initialize\n", unit);
183: es->es_if.if_flags &= ~IFF_UP;
184: return;
185: }
186: addr = (struct endevice *)ui->ui_addr;
187: addr->en_istat = addr->en_ostat = 0;
188:
189: /*
190: * Hang a receive and start any
191: * pending writes by faking a transmit complete.
192: */
193: s = splimp();
194: addr->en_iba = es->es_ifuba.ifu_r.ifrw_info;
195: addr->en_iwc = -(sizeof (struct en_header) + ENMRU) >> 1;
196: addr->en_istat = EN_IEN|EN_GO;
197: es->es_oactive = 1;
198: es->es_if.if_flags |= IFF_RUNNING;
199: enxint(unit);
200: splx(s);
201: }
202:
203: int enalldelay = 0;
204: int enlastdel = 50;
205: int enlastmask = (~0) << 5;
206:
207: /*
208: * Start or restart output on interface.
209: * If interface is already active, then this is a retransmit
210: * after a collision, and just restuff registers and delay.
211: * If interface is not already active, get another datagram
212: * to send off of the interface queue, and map it to the interface
213: * before starting the output.
214: */
215: enstart(dev)
216: dev_t dev;
217: {
218: int unit = ENUNIT(dev);
219: struct uba_device *ui = eninfo[unit];
220: register struct en_softc *es = &en_softc[unit];
221: register struct endevice *addr;
222: register struct en_header *en;
223: struct mbuf *m;
224: int dest;
225:
226: if (es->es_oactive)
227: goto restart;
228:
229: /*
230: * Not already active: dequeue another request
231: * and map it to the UNIBUS. If no more requests,
232: * just return.
233: */
234: IF_DEQUEUE(&es->es_if.if_snd, m);
235: if (m == 0) {
236: es->es_oactive = 0;
237: return;
238: }
239: en = mtod(m, struct en_header *);
240: dest = en->en_dhost;
241: en->en_shost = es->es_host;
242: es->es_olen = if_wubaput(&es->es_ifuba, m);
243: #ifdef ENF_SWABIPS
244: /*
245: * The Xerox interface does word at a time DMA, so
246: * someone must do byte swapping of user data if high
247: * and low ender machines are to communicate. It doesn't
248: * belong here, but certain people depend on it, so...
249: *
250: * Should swab everybody, but this is a kludge anyway.
251: */
252: if (es->es_if.if_flags & ENF_SWABIPS) {
253: en = (struct en_header *)es->es_ifuba.ifu_w.ifrw_addr;
254: if (en->en_type == ENTYPE_IP)
255: enswab((caddr_t)(en + 1), (caddr_t)(en + 1),
256: es->es_olen - sizeof (struct en_header) + 1);
257: }
258: #endif
259:
260: /*
261: * Ethernet cannot take back-to-back packets (no
262: * buffering in interface. To help avoid overrunning
263: * receivers, enforce a small delay (about 1ms) in interface:
264: * * between all packets when enalldelay
265: * * whenever last packet was broadcast
266: * * whenever this packet is to same host as last packet
267: */
268: if (enalldelay || es->es_lastx == 0 || es->es_lastx == dest) {
269: es->es_delay = enlastdel;
270: es->es_mask = enlastmask;
271: }
272: es->es_lastx = dest;
273:
274: restart:
275: /*
276: * Have request mapped to UNIBUS for transmission.
277: * Purge any stale data from this BDP, and start the otput.
278: */
279: if (es->es_ifuba.ifu_flags & UBA_NEEDBDP)
280: UBAPURGE(es->es_ifuba.ifu_uba, es->es_ifuba.ifu_w.ifrw_bdp);
281: addr = (struct endevice *)ui->ui_addr;
282: addr->en_oba = (int)es->es_ifuba.ifu_w.ifrw_info;
283: addr->en_odelay = es->es_delay;
284: addr->en_owc = -((es->es_olen + 1) >> 1);
285: addr->en_ostat = EN_IEN|EN_GO;
286: es->es_oactive = 1;
287: }
288:
289: /*
290: * Ethernet interface transmitter interrupt.
291: * Start another output if more data to send.
292: */
293: enxint(unit)
294: int unit;
295: {
296: register struct uba_device *ui = eninfo[unit];
297: register struct en_softc *es = &en_softc[unit];
298: register struct endevice *addr = (struct endevice *)ui->ui_addr;
299:
300: if (es->es_oactive == 0)
301: return;
302: if (es->es_mask && (addr->en_ostat&EN_OERROR)) {
303: es->es_if.if_oerrors++;
304: endocoll(unit);
305: return;
306: }
307: es->es_if.if_opackets++;
308: es->es_oactive = 0;
309: es->es_delay = 0;
310: es->es_mask = ~0;
311: if (es->es_ifuba.ifu_xtofree) {
312: m_freem(es->es_ifuba.ifu_xtofree);
313: es->es_ifuba.ifu_xtofree = 0;
314: }
315: if (es->es_if.if_snd.ifq_head == 0) {
316: es->es_lastx = 256; /* putatively illegal */
317: return;
318: }
319: enstart(unit);
320: }
321:
322: /*
323: * Collision on ethernet interface. Do exponential
324: * backoff, and retransmit. If have backed off all
325: * the way print warning diagnostic, and drop packet.
326: */
327: encollide(unit)
328: int unit;
329: {
330: struct en_softc *es = &en_softc[unit];
331:
332: es->es_if.if_collisions++;
333: if (es->es_oactive == 0)
334: return;
335: endocoll(unit);
336: }
337:
338: endocoll(unit)
339: int unit;
340: {
341: register struct en_softc *es = &en_softc[unit];
342:
343: /*
344: * Es_mask is a 16 bit number with n low zero bits, with
345: * n the number of backoffs. When es_mask is 0 we have
346: * backed off 16 times, and give up.
347: */
348: if (es->es_mask == 0) {
349: printf("en%d: send error\n", unit);
350: enxint(unit);
351: return;
352: }
353: /*
354: * Another backoff. Restart with delay based on n low bits
355: * of the interval timer.
356: */
357: es->es_mask <<= 1;
358: es->es_delay = mfpr(ICR) &~ es->es_mask;
359: enstart(unit);
360: }
361:
362: #ifdef notdef
363: struct sockproto enproto = { AF_ETHERLINK };
364: struct sockaddr_en endst = { AF_ETHERLINK };
365: struct sockaddr_en ensrc = { AF_ETHERLINK };
366: #endif
367: /*
368: * Ethernet interface receiver interrupt.
369: * If input error just drop packet.
370: * Otherwise purge input buffered data path and examine
371: * packet to determine type. If can't determine length
372: * from type, then have to drop packet. Othewise decapsulate
373: * packet based on type and pass to type specific higher-level
374: * input routine.
375: */
376: enrint(unit)
377: int unit;
378: {
379: register struct en_softc *es = &en_softc[unit];
380: struct endevice *addr = (struct endevice *)eninfo[unit]->ui_addr;
381: register struct en_header *en;
382: struct mbuf *m;
383: int len; short resid;
384: register struct ifqueue *inq;
385: int off, s;
386:
387: es->es_if.if_ipackets++;
388:
389: /*
390: * Purge BDP; drop if input error indicated.
391: */
392: if (es->es_ifuba.ifu_flags & UBA_NEEDBDP)
393: UBAPURGE(es->es_ifuba.ifu_uba, es->es_ifuba.ifu_r.ifrw_bdp);
394: if (addr->en_istat&EN_IERROR) {
395: es->es_if.if_ierrors++;
396: goto setup;
397: }
398:
399: /*
400: * Calculate input data length.
401: * Get pointer to ethernet header (in input buffer).
402: * Deal with trailer protocol: if type is PUP trailer
403: * get true type from first 16-bit word past data.
404: * Remember that type was trailer by setting off.
405: */
406: resid = addr->en_iwc;
407: if (resid)
408: resid |= 0176000;
409: len = (((sizeof (struct en_header) + ENMRU) >> 1) + resid) << 1;
410: len -= sizeof (struct en_header);
411: if (len > ENMRU)
412: goto setup; /* sanity */
413: en = (struct en_header *)(es->es_ifuba.ifu_r.ifrw_addr);
414: en->en_type = ntohs(en->en_type);
415: #define endataaddr(en, off, type) ((type)(((caddr_t)((en)+1)+(off))))
416: if (en->en_type >= ENTYPE_TRAIL &&
417: en->en_type < ENTYPE_TRAIL+ENTYPE_NTRAILER) {
418: off = (en->en_type - ENTYPE_TRAIL) * 512;
419: if (off > ENMTU)
420: goto setup; /* sanity */
421: en->en_type = ntohs(*endataaddr(en, off, u_short *));
422: resid = ntohs(*(endataaddr(en, off+2, u_short *)));
423: if (off + resid > len)
424: goto setup; /* sanity */
425: len = off + resid;
426: } else
427: off = 0;
428: if (len == 0)
429: goto setup;
430: #ifdef ENF_SWABIPS
431: if (es->es_if.if_flags & ENF_SWABIPS && en->en_type == ENTYPE_IP)
432: enswab((caddr_t)(en + 1), (caddr_t)(en + 1), len);
433: #endif
434: /*
435: * Pull packet off interface. Off is nonzero if packet
436: * has trailing header; if_rubaget will then force this header
437: * information to be at the front, but we still have to drop
438: * the type and length which are at the front of any trailer data.
439: */
440: m = if_rubaget(&es->es_ifuba, len, off, &es->es_if);
441: if (m == 0)
442: goto setup;
443: if (off) {
444: struct ifnet *ifp;
445:
446: ifp = *(mtod(m, struct ifnet **));
447: m->m_off += 2 * sizeof (u_short);
448: m->m_len -= 2 * sizeof (u_short);
449: *(mtod(m, struct ifnet **)) = ifp;
450: }
451: switch (en->en_type) {
452:
453: #ifdef INET
454: case ENTYPE_IP:
455: schednetisr(NETISR_IP);
456: inq = &ipintrq;
457: break;
458: #endif
459: #ifdef PUP
460: case ENTYPE_PUP:
461: rpup_input(m);
462: goto setup;
463: #endif
464: #ifdef NS
465: case ETHERTYPE_NS:
466: if (es->es_nsactive) {
467: schednetisr(NETISR_NS);
468: inq = &nsintrq;
469: } else {
470: m_freem(m);
471: goto setup;
472: }
473: break;
474: #endif
475:
476: default:
477: #ifdef notdef
478: enproto.sp_protocol = en->en_type;
479: endst.sen_host = en->en_dhost;
480: endst.sen_net = ensrc.sen_net = es->es_if.if_net;
481: ensrc.sen_host = en->en_shost;
482: raw_input(m, &enproto,
483: (struct sockaddr *)&ensrc, (struct sockaddr *)&endst);
484: #else
485: m_freem(m);
486: #endif
487: goto setup;
488: }
489:
490: s = splimp();
491: if (IF_QFULL(inq)) {
492: IF_DROP(inq);
493: m_freem(m);
494: } else
495: IF_ENQUEUE(inq, m);
496: splx(s);
497:
498: setup:
499: /*
500: * Reset for next packet.
501: */
502: addr->en_iba = es->es_ifuba.ifu_r.ifrw_info;
503: addr->en_iwc = -(sizeof (struct en_header) + ENMRU) >> 1;
504: addr->en_istat = EN_IEN|EN_GO;
505: }
506:
507: /*
508: * Ethernet output routine.
509: * Encapsulate a packet of type family for the local net.
510: * Use trailer local net encapsulation if enough data in first
511: * packet leaves a multiple of 512 bytes of data in remainder.
512: */
513: enoutput(ifp, m0, dst)
514: struct ifnet *ifp;
515: struct mbuf *m0;
516: struct sockaddr *dst;
517: {
518: int type, dest, s, error;
519: register struct mbuf *m = m0;
520: register struct en_header *en;
521: register int off;
522:
523: if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
524: error = ENETDOWN;
525: goto bad;
526: }
527: switch (dst->sa_family) {
528:
529: #ifdef INET
530: case AF_INET:
531: {
532: struct in_addr in;
533:
534: in = ((struct sockaddr_in *)dst)->sin_addr;
535: if (in_broadcast(in))
536: dest = EN_BROADCAST;
537: else
538: dest = in_lnaof(in);
539: }
540: if (dest >= 0x100) {
541: error = EPERM; /* ??? */
542: goto bad;
543: }
544: off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
545: /* need per host negotiation */
546: if ((ifp->if_flags & IFF_NOTRAILERS) == 0)
547: if (off > 0 && (off & 0x1ff) == 0 &&
548: m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
549: type = ENTYPE_TRAIL + (off>>9);
550: m->m_off -= 2 * sizeof (u_short);
551: m->m_len += 2 * sizeof (u_short);
552: *mtod(m, u_short *) = htons((u_short)ENTYPE_IP);
553: *(mtod(m, u_short *) + 1) = ntohs((u_short)m->m_len);
554: goto gottrailertype;
555: }
556: type = ENTYPE_IP;
557: off = 0;
558: goto gottype;
559: #endif
560: #ifdef NS
561: case AF_NS:
562: {
563: u_char *up;
564:
565: type = ETHERTYPE_NS;
566: up = ((struct sockaddr_ns *)dst)->sns_addr.x_host.c_host;
567: if (*up & 1)
568: dest = EN_BROADCAST;
569: else
570: dest = up[5];
571:
572: off = 0;
573: goto gottype;
574: }
575: #endif
576: #ifdef PUP
577: case AF_PUP:
578: dest = ((struct sockaddr_pup *)dst)->spup_host;
579: type = ENTYPE_PUP;
580: off = 0;
581: goto gottype;
582: #endif
583:
584: #ifdef notdef
585: case AF_ETHERLINK:
586: goto gotheader;
587: #endif
588:
589: default:
590: printf("en%d: can't handle af%d\n", ifp->if_unit,
591: dst->sa_family);
592: error = EAFNOSUPPORT;
593: goto bad;
594: }
595:
596: gottrailertype:
597: /*
598: * Packet to be sent as trailer: move first packet
599: * (control information) to end of chain.
600: */
601: while (m->m_next)
602: m = m->m_next;
603: m->m_next = m0;
604: m = m0->m_next;
605: m0->m_next = 0;
606: m0 = m;
607:
608: gottype:
609: /*
610: * Add local net header. If no space in first mbuf,
611: * allocate another.
612: */
613: if (m->m_off > MMAXOFF ||
614: MMINOFF + sizeof (struct en_header) > m->m_off) {
615: MGET(m, M_DONTWAIT, MT_HEADER);
616: if (m == 0) {
617: error = ENOBUFS;
618: goto bad;
619: }
620: m->m_next = m0;
621: m->m_off = MMINOFF;
622: m->m_len = sizeof (struct en_header);
623: } else {
624: m->m_off -= sizeof (struct en_header);
625: m->m_len += sizeof (struct en_header);
626: }
627: en = mtod(m, struct en_header *);
628: /* add en_shost later */
629: en->en_dhost = dest;
630: en->en_type = htons((u_short)type);
631:
632: #ifdef notdef
633: :
634: #endif
635: /*
636: * Queue message on interface, and start output if interface
637: * not yet active.
638: */
639: s = splimp();
640: if (IF_QFULL(&ifp->if_snd)) {
641: IF_DROP(&ifp->if_snd);
642: error = ENOBUFS;
643: goto qfull;
644: }
645: IF_ENQUEUE(&ifp->if_snd, m);
646: if (en_softc[ifp->if_unit].es_oactive == 0)
647: enstart(ifp->if_unit);
648: splx(s);
649: return (0);
650: qfull:
651: m0 = m;
652: splx(s);
653: bad:
654: m_freem(m0);
655: return (error);
656: }
657:
658: /*
659: * Process an ioctl request.
660: */
661: enioctl(ifp, cmd, data)
662: register struct ifnet *ifp;
663: int cmd;
664: caddr_t data;
665: {
666: register struct en_softc *es = ((struct en_softc *)ifp);
667: struct ifaddr *ifa = (struct ifaddr *) data;
668: int s = splimp(), error = 0;
669: struct endevice *enaddr;
670:
671: switch (cmd) {
672:
673: case SIOCSIFADDR:
674: enaddr = (struct endevice *)eninfo[ifp->if_unit]->ui_addr;
675: es->es_host = (~enaddr->en_addr) & 0xff;
676: /*
677: * Attempt to check agreement of protocol address
678: * and board address.
679: */
680: switch (ifa->ifa_addr.sa_family) {
681: case AF_INET:
682: if (in_lnaof(IA_SIN(ifa)->sin_addr) != es->es_host)
683: return (EADDRNOTAVAIL);
684: break;
685: #ifdef NS
686: case AF_NS:
687: if (IA_SNS(ifa)->sns_addr.x_host.c_host[5]
688: != es->es_host)
689: return (EADDRNOTAVAIL);
690: es->es_nsactive = 1;
691: break;
692: #endif
693: }
694: ifp->if_flags |= IFF_UP;
695: if ((ifp->if_flags & IFF_RUNNING) == 0)
696: eninit(ifp->if_unit);
697: break;
698:
699: default:
700: error = EINVAL;
701: break;
702: }
703: splx(s);
704: return (error);
705: }
706:
707: #ifdef ENF_SWABIPS
708: /*
709: * Swab bytes
710: * Jeffrey Mogul, Stanford
711: */
712: enswab(from, to, n)
713: register unsigned char *from, *to;
714: register int n;
715: {
716: register unsigned long temp;
717:
718: if ((n <= 0) || (n > 0xFFFF)) {
719: printf("enswab: bad len %d\n", n);
720: return;
721: }
722:
723: n >>= 1; n++;
724: #define STEP {temp = *from++;*to++ = *from++;*to++ = temp;}
725: /* round to multiple of 8 */
726: while ((--n) & 07)
727: STEP;
728: n >>= 3;
729: while (--n >= 0) {
730: STEP; STEP; STEP; STEP;
731: STEP; STEP; STEP; STEP;
732: }
733: }
734: #endif
735: #endif