|
|
1.1 root 1: /* STREAMS style driver for the DP8390 Ethernet interface */
2: /*
3: * An interesting problem is how to manage the interface address binding,
4: * especially for upper protocols (specifically, the Internet ARP protocol)
5: * that need to advertise the physical host address, especially in the
6: * presence of multiple hardware adapters (or network types).
7: *
8: * For now, I am happy with having a specific version of ARP for each network
9: * type, and having ARP catch any M_PROTO SP_BIND messages going past.
10: */
11: #include <sys/kernel.h>
12: #include <sys/dma.h>
13: #include <sys/stream.h>
14: #include <sys/strmlib.h>
15: #include <sys/strproto.h>
16: #include <sys/dp8390.h>
17: #include <sys/ether.h>
18: #include <sys/ints.h>
19: #include <sys/netstuff.h>
20: #include <string.h>
21:
22: /*
23: * Allow up to 8 minor devices connected to us - each one receives a copy of
24: * all incoming traffic, and each can place datagrams.
25: */
26: #define MAXMINOR 8
27: static queue_t * minortab[MAXMINOR];
28:
29: #ifdef M68K
30: /*
31: * The 68070 uses memory mapped I/O exclusively, so treat the 8390 as a
32: * structure at a fixed location in memory. The header file also defines
33: * the padding of the structure on the 16-bit 68000 bus.
34: *
35: * We usually assign this to a local to put the base into an address
36: * register, which gets faster code than using the folded immediate address.
37: */
38: #define DP8390 volatile dp8390 *
39: #define DP8390_BASE ((DP8390)(0x1FFC00 + PHYSICAL_SEG))
40: #define DEVICE _device
41: #define DEVICE_REG DP8390 DEVICE = DP8390_BASE;
42:
43: #define input(dev, dp_reg) (dev)->dp_pg0rd.dp_reg
44: #define input1(dev, dp_reg) (dev)->dp_pg1rdwr.dp_reg
45: #define output(dev, dp_reg, val) (dev)->dp_pg0wr.dp_reg = val
46: #define output1(dev, dp_reg, val) (dev)->dp_pg1rdwr.dp_reg = val
47: #endif
48:
49: #ifdef IBMPC
50: /*
51: * The 8086 has special instructions for I/O, but if we treat the base
52: * address as a NEAR mode pointer (16-bit, current data segment) then cast
53: * it to a short for the I/O instructions, we'll have the right kind of
54: * effect.
55: *
56: * We DON'T assign the base to a local, since better code is produced by
57: * folding the constants and loading a new one into DX every I/O.
58: *
59: * Note that we emit a JMP $+2 just before the I/O instruction to waste a
60: * little time, as a NIC CS should not occur more often than 400ns.
61: */
62: #define DP8390 dp8390 near *
63: #define DP8390_BASE ((DP8390)0x300)
64: #define DEVICE DP8390_BASE
65: #define DEVICE_REG
66:
67: #define _input(addr) (_DX=(UWORD)addr, __emit__ (0xEB, 0, 0xEB, 0, 0xEB, 0, 0xEB, 0, 0xEB, 0, 0xEC), _AL)
68: #define _output(addr,val) (_DX=(UWORD)addr, _AL = val, __emit__ (0xEB, 0, 0xEB, 0, 0xEB, 0, 0xEB, 0, 0xEB, 0, 0xEE))
69: #define input(dev, dp_reg) _input (&(dev)->dp_pg0rd.dp_reg)
70: #define input1(dev, dp_reg) _input (&(dev)->dp_pg1rdwr.dp_reg)
71: #define output(dev, dp_reg, val) _output (&(dev)->dp_pg0wr.dp_reg,(val))
72: #define output1(dev, dp_reg, val) _output (&(dev)->dp_pg1rdwr.dp_reg,(val))
73:
74:
75: #define ETHER_IRQ 2
76:
77: #endif
78:
79:
80: /*
81: * For scheduling remote DMA operations on the NIC, since there is only one
82: * channel on the NIC which is shared between remote read and remote write
83: * operations. Complicated since the TX buffer area is held until the NIC has
84: * actually completed the transmission, and because RX DMA may be halted in the
85: * middle of a packet due to STREAMS buffer depletion.
86: *
87: * Made a structure in the anticipation of one day having multiple interfaces.
88: */
89: static struct ethcb { /* control block for a single interface */
90: char tx_state; /* TX DMA in progress or TX DMA blocked */
91: /* cleared when packet send completed */
92: char rx_state; /* RX DMA in progress or waiting for buffers */
93: char rx_pending; /* flag that RX packets for DMA are waiting */
94: short rx_length; /* remaining length of RX packet */
95: UWORD rx_base; /* NIC buffer address of RX DMA */
96: mblk_t * rx_start; /* first mblk in RX packet */
97: mblk_t * rx_current; /* current RX DMA buffer */
98: short tx_length; /* length of packet being transmitted */
99:
100: short tx_count; /* count packets sent */
101: short rx_count; /* RX activity */
102:
103: char tx_error; /* packet never ended transmission */
104: short tx_lastcount; /* count at last timer tick */
105: short rx_lastcount; /* count at last timre tick */
106:
107: /*
108: * About write packet queueing - since this device effectively functions as a
109: * kind of multiplexor, flow control needs explicit attention. I use the
110: * general methods developed for the other multiplexing drivers (like TCP),
111: * namely the generic scheduler in my STREAMS implementation.
112: */
113: /* schedule of driver queues that have output packets queued */
114: struct schedule tx_sched;
115:
116: struct dp8390info dp8390info;
117:
118: /* useful addresses that we may wish to keep copies of */
119: Eth_addr myaddr; /* our own address */
120:
121: /* This flag gets set when the NIC tests OK */
122: int netok;
123:
124: /* error counter extensions */
125: int errcnt0, errcnt1, errcnt2;
126: } eth;
127:
128:
129: #define ETH LONG_TO_PTR (eth, struct ethcb *)
130: #define QETH ((struct ethcb *) q->q_ptr)
131:
132: /*
133: * Possible states for TX
134: */
135: #define TX_IDLE 0
136: #define TX_DMA 1
137: #define TX_SEND 2
138: /*
139: * Possible events for TX
140: */
141: #define TXE_CRANK 0
142: #define TXE_DMADONE 1
143: #define TXE_SENDDONE 2
144:
145: /*
146: * Possible states for RX.
147: *
148: * The two states RX_HALT and RX_BLOCKED distinguish whether or not to
149: * continue RX dma after a TX DMA or not.
150: */
151: #define RX_IDLE 0
152: #define RX_DMA 1
153: #define RX_HALT 2
154: #define RX_BLOCKED 3
155: /*
156: * possible events for RX
157: */
158: #define RXE_CRANK 0
159: #define RXE_GOTMEM 1
160: #define RXE_NOMEM 2
161: #define RXE_DMADONE 3
162: #define RXE_ALLDONE 4
163:
164: /*
165: * To aid in detecting when the cable has been unplugged (which causes a
166: * constant collision state, so the backoff count doesn't get incremented).
167: */
168: static P_TIMER eth_timer = NIL_TIMER;
169:
170: /*
171: * program the address into the address registers.
172: * Note : assumes that register set 1 has already been chosen!
173: */
174: static void set_addr (int selpage)
175: {
176: DEVICE_REG
177:
178: if (selpage)
179: output (DEVICE, dp_cr, CR_PS_P1 | CR_DM_ABORT | CR_STA);
180: output1 (DEVICE, dp_par0, eth.myaddr.e[0]);
181: output1 (DEVICE, dp_par1, eth.myaddr.e[1]);
182: output1 (DEVICE, dp_par2, eth.myaddr.e[2]);
183: output1 (DEVICE, dp_par3, eth.myaddr.e[3]);
184: output1 (DEVICE, dp_par4, eth.myaddr.e[4]);
185: output1 (DEVICE, dp_par5, eth.myaddr.e[5]);
186: if (input1 (DEVICE, dp_par0) != eth.myaddr.e[0] ||
187: input1 (DEVICE, dp_par1) != eth.myaddr.e[1] ||
188: input1 (DEVICE, dp_par2) != eth.myaddr.e[2] ||
189: input1 (DEVICE, dp_par3) != eth.myaddr.e[3] ||
190: input1 (DEVICE, dp_par4) != eth.myaddr.e[4] ||
191: input1 (DEVICE, dp_par5) != eth.myaddr.e[5] )
192: STREAMS_DEBUG ("Device not accepting physical address!\n");
193: if (selpage)
194: output (DEVICE, dp_cr, CR_PS_P0 | CR_DM_ABORT | CR_STA);
195: }
196:
197: /*
198: * Since the DMA channel to the DP8390 is word-wide, I have taken special care
199: * to deal with odd-length subunits of packets, or packets that are not word
200: * aligned with pullupmsg(). It's not fast, but such ugly messages should not
201: * occur often.
202: */
203:
204: extern void streams_levels (void);
205:
206: static void eth_timer_func (ULONG eth)
207: {
208: char buf [4];
209: TIMER_SET (eth_timer, 1, eth_timer_func, eth);
210:
211: if (ETH->tx_lastcount != ETH->tx_count)
212: ETH->tx_lastcount = ETH->tx_count;
213: else if (ETH->tx_state != TX_IDLE &&
214: ETH->tx_error == 0) {/* packet send taking too long */
215: mblk_t * temp;
216:
217: ETH->tx_error = 1;
218:
219: /* dispose of all the packets queued here */
220: while (ETH->tx_sched.s_head != NULL) {
221: temp = getq (ETH->tx_sched.s_head);
222: freemsg (temp);
223: muxrobin (& ETH->tx_sched);
224: }
225: #if 1
226: STREAMS_DEBUG ("Stuck in TX ");
227: #endif
228: }
229: if (ETH->rx_lastcount != ETH->rx_count)
230: ETH->rx_lastcount = ETH->rx_count;
231: else if (ETH->rx_state != RX_IDLE &&
232: ETH->tx_error == 0) {
233: ETH->tx_error = 1;
234: STREAMS_DEBUG ("Stuck in RX ");
235: }
236: }
237:
238:
239: static UWORD dma_base; /* DMA base address in NIC */
240: static UWORD dma_len; /* remote DMA length */
241: static void *dma_buf; /* local buffer address */
242: static int dma_dir; /* 1 => remote write */
243:
244: /* start a piece of remote DMA, rounding the transfer size up */
245: void dma_start (void)
246: {
247: DEVICE_REG
248: int xfer_len;
249:
250: if (dma_dir) {
251: output(DEVICE, dp_rbcr0, 15); /* dummy byte count */
252: output(DEVICE, dp_rbcr1, 0);
253: output(DEVICE, dp_cr, CR_PS_P0 | CR_DM_RR | CR_STA);
254: // for (xfer_len = 0; xfer_len < 5; xfer_len ++)
255: // ;
256: }
257:
258: output(DEVICE, dp_rsar0, dma_base & 0xff); /* remote DMA base */
259: output(DEVICE, dp_rsar1, dma_base >> 8 );
260: if ((xfer_len = dma_len) & 1)
261: xfer_len++;
262: output(DEVICE, dp_rbcr0, xfer_len & 0xff); /* remote DMA count */
263: output(DEVICE, dp_rbcr1, xfer_len >> 8 );
264:
265: output(DEVICE, dp_cr, dma_dir ?
266: CR_PS_P0 | CR_DM_RW | CR_STA :
267: CR_PS_P0 | CR_DM_RR | CR_STA);
268:
269: dma_setup (DMA_0, (char *)dma_buf, xfer_len >> 1,
270: dma_dir ? DMAF_TODEV|DMAF_WORDWIDE|DMAF_BURST :
271: DMAF_TOMEM|DMAF_WORDWIDE|DMAF_BURST);
272: }
273:
274: /*
275: * During test, we want to poll for DMA completion. Also used when reading
276: * NIC packet header, since it's so short.
277: */
278: void wait_for_dma (void)
279: {
280: DEVICE_REG
281:
282: for (;;) {
283: while ((input (DEVICE, dp_cr) & CR_DM_ABORT) == 0)
284: ;
285: if (dma_done (DMA_0) == -1)
286: break;
287: dma_reset (DMA_0);
288: dma_start (); /* restart */
289: }
290: }
291:
292: /*
293: * retrieve NIC memory from "base" to "buffer"
294: */
295: static INLINE void get_mem (int base, int len, void * buffer)
296: {
297: dma_base = base;
298: dma_len = len;
299: dma_buf = buffer;
300: dma_dir = 0;
301: dma_start ();
302: }
303: static INLINE void set_mem (int base, int len, unsigned char * buf)
304: {
305: dma_base = base;
306: dma_len = len;
307: dma_buf = buf;
308: dma_dir = 1;
309: dma_start ();
310: }
311:
312: /* send streams message block "mp" to NIC */
313: static void send_block (queue_t * q, mblk_t * mp)
314: {
315: /*
316: * identify the losers, and fix them with pullupmsg(), which both
317: * concatenates (fixing length) and aligns at the same time.
318: */
319: if ((mp->b_cont != NULL && ((mp->b_wptr - mp->b_rptr) & 1) != 0) ||
320: ((ULONG)mp->b_rptr & 1) != 0)
321: pullupmsg (mp, -1);
322:
323: dma_base = (QETH->dp8390info.dpi_tbuf << 8) + QETH->tx_length;
324: dma_len = mp->b_wptr - mp->b_rptr;
325: dma_buf = mp->b_rptr;
326: dma_dir = 1;
327:
328: dma_start ();
329: }
330:
331: /* initiate transmission of the buffered packet, with length "len". */
332: static void send_pkt (struct ethcb * eth)
333: {
334: DEVICE_REG
335:
336: if (eth->tx_length < 64) /* Ethernet magic */
337: eth->tx_length = 64;
338: output (DEVICE, dp_tbcr0, eth->tx_length & 0xff);
339: output (DEVICE, dp_tbcr1, eth->tx_length >> 8);
340: output (DEVICE, dp_tpsr, eth->dp8390info.dpi_tbuf);
341:
342: output (DEVICE, dp_cr, CR_PS_P0|CR_DM_ABORT|CR_TXP|CR_STA);
343: }
344:
345: static void rx_next (struct ethcb * eth, int event);
346: static void tx_next (struct ethcb * eth, int event)
347: {
348: again:
349: SCREEN (26) = 'T';
350: SCREEN (28) = eth->tx_state + '0';
351: SCREEN (30) = event + '0';
352: switch (eth->tx_state) {
353: case TX_IDLE:
354: if (event == TXE_CRANK) {
355: if (eth->tx_sched.s_head != NULL &&
356: eth->rx_state != RX_DMA) {
357: eth->tx_count ++;
358: eth->tx_state = TX_DMA;
359: eth->tx_length = 0;
360: send_block (eth->tx_sched.s_head,
361: eth->tx_sched.s_head->q_first);
362: }
363: return;
364: }
365: break;
366: case TX_DMA:
367: if (event == TXE_DMADONE) {
368: mblk_t * temp = getq (eth->tx_sched.s_head),
369: * msg = temp->b_cont;
370:
371: eth->tx_length += dma_len;
372: freeb (temp);
373: if (msg != NULL) {
374: putbq (eth->tx_sched.s_head, msg);
375: send_block (eth->tx_sched.s_head, msg);
376: } else {
377: send_pkt (eth); /* spit it out */
378: muxrobin (& eth->tx_sched);
379: eth->tx_state = TX_SEND;
380:
381: rx_next (eth, RXE_CRANK);
382: }
383: return;
384: }
385: if (event == TXE_CRANK)
386: return;
387: break;
388: case TX_SEND:
389: if (event == TXE_SENDDONE) {
390: eth->tx_error = 0;
391: eth->tx_state = TX_IDLE;
392: rx_next (eth, RXE_CRANK);
393: event = TXE_CRANK;
394: goto again;
395: }
396: if (event == TXE_CRANK)
397: return;
398: break;
399: }
400: STREAMS_DEBUG ("Bad TX state/event ");
401: }
402:
403: static void rx_got_mem (long eth)
404: {
405: short s = SPL7 ();
406: rx_next (LONG_TO_PTR (eth, struct ethcb *), RXE_GOTMEM);
407: SPLX (s);
408: }
409: static void rx_next (struct ethcb * eth, int event)
410: {
411: mblk_t * mp;
412: int len;
413:
414: again:
415: SCREEN (26) = 'R';
416: SCREEN (28) = eth->rx_state + '0';
417: SCREEN (30) = event + '0';
418: switch (eth->rx_state) {
419: case RX_IDLE:
420: if (event == RXE_CRANK) {
421: if (eth->rx_pending && eth->tx_state != TX_DMA) {
422: /* busy wait on the header part */
423: struct rcvdheader nic;
424:
425: get_mem (eth->dp8390info.dpi_next << 8, 4, & nic);
426: wait_for_dma ();
427: eth->dp8390info.dpi_next = nic.rp_next;
428: /*
429: * count in packet header includes FCS, which we
430: * are not really interested in.
431: */
432: eth->rx_length = (nic.rp_rbch << 8) + nic.rp_rbcl - 4;
433: eth->rx_base = dma_base + 4;
434: if ((input (DEVICE, dp_isr) & ISR_RDC) == 0)
435: STREAMS_DEBUG ("IMPOSSIBLE 1");
436: output (DEVICE, dp_isr, ISR_RDC);
437:
438: eth->rx_count ++;
439: eth->rx_state = RX_DMA;
440: event = RXE_DMADONE;
441:
442: if (input (DEVICE, dp_isr) & ISR_RDC)
443: STREAMS_DEBUG ("IMPOSSIBLE 2");
444: goto again;
445: }
446: return;
447: }
448: break;
449: case RX_DMA:
450: len = eth->rx_length;
451: if (len > 768) {
452: if (len > 1024)
453: len = 1024;
454: } else if (len > 192) {
455: if (len > 256)
456: len = 256;
457: } else if (len > 64)
458: len = 64;
459: if (event == RXE_DMADONE) {
460: if (len == 0) {
461: event = RXE_ALLDONE;
462: goto again;
463: }
464: if ((mp = allocb (len, BPRI_MED)) == NULL) {
465: while (len < 1024) {
466: if ((mp = allocb (len, BPRI_LO)) != NULL)
467: break;
468: len *= 2;
469: }
470: if (len >= 1024) {
471: event = RXE_NOMEM;
472: goto again;
473: }
474: if (len > eth->rx_length)
475: len = eth->rx_length;
476: }
477:
478: eth->rx_count ++;
479: mp->b_wptr += len;
480: if (eth->rx_start == NULL)
481: eth->rx_start = mp; /* first buffer */
482: else
483: eth->rx_current->b_cont = mp; /* link buffers */
484: eth->rx_current = mp;
485: get_mem (eth->rx_base, len, mp->b_rptr);
486: /* take care to wrap the rx_base! */
487: if (((eth->rx_base += len) >> 8) >= eth->dp8390info.dpi_pstop)
488: eth->rx_base -= (eth->dp8390info.dpi_pstop - eth->dp8390info.dpi_pstart) << 8;
489: eth->rx_length -= len;
490: return;
491: }
492: if (event == RXE_NOMEM) {
493: eth->rx_state = RX_HALT;
494: bufcall (len, BPRI_MED, rx_got_mem, (long) eth);
495: tx_next (eth, TXE_CRANK);
496: event = RXE_CRANK;
497: goto again;
498: }
499: if (event == RXE_ALLDONE) {
500: /*
501: * finished a piece of receive DMA - advance buffer
502: * queue endpoint over just received packet. In
503: * addition, we should check to see if there are any
504: * more buffered receive packets.
505: */
506: output (DEVICE, dp_bnry, eth->dp8390info.dpi_next == eth->dp8390info.dpi_pstart ?
507: eth->dp8390info.dpi_pstop - 1 :
508: eth->dp8390info.dpi_next - 1);
509: output (DEVICE, dp_cr, CR_PS_P1 | CR_DM_ABORT | CR_STA);
510: if (input1 (DEVICE, dp_curr) == eth->dp8390info.dpi_next)
511: eth->rx_pending = 0;
512: output (DEVICE, dp_cr, CR_PS_P0 | CR_DM_ABORT | CR_STA);
513: if (eth->rx_start != NULL) {
514: /* send a copy of every message upwards */
515: for (len = 0; len < MAXMINOR ; len ++)
516: if (minortab [len] &&
517: (mp = dupmsg (eth->rx_start)) != NULL)
518: putq (minortab [len], mp);
519: SCREEN (22) ++;
520: freemsg (eth->rx_start);
521: eth->rx_start = eth->rx_current = NULL;
522: }
523: eth->rx_state = RX_IDLE;
524: tx_next (eth, TXE_CRANK);
525: event = RXE_CRANK;
526: goto again;
527: }
528: return;
529: case RX_HALT:
530: if (event == RXE_GOTMEM) {
531: if (eth->tx_state == TX_DMA) {
532: eth->rx_state = RX_BLOCKED;
533: return;
534: }
535: eth->rx_state = RX_DMA;
536: event = RXE_DMADONE;
537: goto again;
538: }
539: if (event == RXE_CRANK)
540: return;
541: break;
542: case RX_BLOCKED:
543: if (event == RXE_CRANK && eth->tx_state != TX_DMA) {
544: eth->rx_state = RX_DMA;
545: event = RXE_DMADONE;
546: goto again;
547: }
548: break;
549: default:
550: STREAMS_DEBUG ("Impossible state");
551: return;
552: }
553: STREAMS_DEBUG ("Bad RX state/event combo ");
554: }
555:
556:
557: /* Referenced in "system.asm", here is the interrupt service routine */
558: HW_INT_FUNC (void) etherint (void)
559: {
560: DEVICE_REG
561: UBYTE status = input (DEVICE, dp_isr);
562: static UBYTE reentry;
563:
564: if (reentry ++ != 0) {
565: STREAMS_DEBUG ("Reentry ");
566: reentry --;
567: return;
568: }
569:
570: /*
571: * GCC - specific kernel hack, save all used registers on entry to
572: * this function. We don't use INTERRUPT for the PC version since
573: * hardware IRQ handlers need assembly-language wrappers to give
574: * us enough stack to use STREAMS library routines.
575: */
576: GNU_INTERRUPT;
577:
578: rescan:
579: /* reset the flag bits that were indicated for us */
580: output (DEVICE, dp_isr, status);
581:
582: if (eth.netok == 0) { /* device not active! */
583: reentry --;
584: return;
585: }
586: if ((status & ISR_PRX) != 0) {
587: eth.rx_pending = 1;
588: rx_next (& eth, RXE_CRANK);
589: }
590: SCREEN (16) ++;
591: if ((status & ISR_PTX) != 0) {
592: if ((input (DEVICE, dp_tsr) & ~(TSR_COL | TSR_CRS | TSR_PTX | TSR_DFR))
593: != 0)
594: STREAMS_DEBUG ("Packet TX error\n");
595: SCREEN (18) ++;
596: tx_next (& eth, TXE_SENDDONE);
597: }
598: /*
599: * The ISR_RDC bit is gated with CR_DM_ABORT since the fix for the
600: * NIC remote write problem causes spurious RDCs, which are not
601: * normally detected unless the TX DMA is delayed by arrive DMA to
602: * the NIC local memory.
603: */
604: if ((status & ISR_RDC) != 0 &&
605: (input (DEVICE, dp_cr) & CR_DM_ABORT) != 0)
606: if (dma_done (DMA_0) != -1) {
607: dma_reset (DMA_0);
608: dma_start ();
609: } else if (dma_dir)
610: tx_next (& eth, TXE_DMADONE);
611: else
612: rx_next (& eth, RXE_DMADONE);
613:
614: if ((status & (ISR_RXE | ISR_TXE | ISR_OVW | ISR_CNT)) != 0) {
615: if (status & ISR_RXE)
616: STREAMS_DEBUG ("Receive error\n");
617: if (status & ISR_TXE) {
618: /*
619: * This can happen due to excessive collisions if
620: * there is an open cable end or due to a FIFO
621: * underrun (which indicates a board problem).
622: */
623: if ((input (DEVICE, dp_tsr) & (TSR_FU)) != 0)
624: STREAMS_DEBUG ("TX FIFO underrun");
625: tx_next (& eth, TXE_SENDDONE);
626: }
627: if (status & ISR_OVW)
628: STREAMS_DEBUG ("Buffer overflow\n");
629: if (status & ISR_CNT) {
630: /* reset the error counters by reading them */
631: eth.errcnt0 += input (DEVICE, dp_cntr0);
632: eth.errcnt1 += input (DEVICE, dp_cntr1);
633: eth.errcnt2 += input (DEVICE, dp_cntr2);
634: }
635: }
636: if ((status = input (DEVICE, dp_isr)) != 0)
637: goto rescan;
638:
639: reentry --;
640: }
641:
642: /*
643: * Routines for reading from/writing to the NIC memory.
644: */
645:
646: /* queue a packet for transmission */
647: static void queue_packet (queue_t *q, mblk_t *mp)
648: {
649: if (QETH->tx_error != 0)
650: return;
651:
652: short s = SPL7 ();
653: /*
654: * We queue the message "normally" for STREAMS so that flow control
655: * operates as one would expect. Then we place the streams queue onto
656: * our own "scheduling" list for processing by the NIC interrupt.
657: */
658: putq (q, mp);
659: qschedule (q, & QETH->tx_sched);
660:
661: /*
662: * If there is no I/O presently being executed, we must start
663: * the ball rolling.
664: */
665: tx_next (QETH, TXE_CRANK);
666: SPLX (s);
667: }
668:
669: /*
670: * Set up the DP8390. This initialisation procedure comes fairly directly
671: * from the NatSemi manual - much dark magic.
672: */
673: static void chipinit (Eth_addr * addr)
674: {
675: unsigned char * testbuf, * test2;
676: mblk_t * testmem;
677: int i, start = -1, len;
678: DEVICE_REG
679:
680: if (input (DEVICE, dp_cr) == 0xFF) {
681: eth.netok = -1;
682: return;
683: }
684:
685: /* reset dp8390 */
686: output(DEVICE, dp_cr, CR_STP|CR_PS_P0|CR_DM_ABORT);
687:
688: #ifdef M68K
689: output(DEVICE, dp_dcr,
690: DCR_LOOP | DCR_WORDWIDE | DCR_BIGENDIAN | DCR_8BYTES);
691: #endif
692: #ifdef IBMPC
693: set_hw_int (ETHER_IRQ, etherint);
694: output(DEVICE, dp_dcr, DCR_LOOP | DCR_WORDWIDE | DCR_8BYTES);
695: #endif
696:
697: output(DEVICE, dp_rbcr0, 0);
698: output(DEVICE, dp_rbcr1, 0);
699: output(DEVICE, dp_rcr, RCR_AB);
700: output(DEVICE, dp_tcr, TCR_INTERNAL);
701: output(DEVICE, dp_isr, 0xff);
702: output(DEVICE, dp_imr, 0);
703:
704: /*
705: * We start the device here (and shut it down later) since the
706: * Remote DMA doesn't work until we do, and we can't find out how
707: * much memory we have until we can DMA. (Sigh)
708: */
709: output (DEVICE, dp_cr, CR_PS_P0 | CR_DM_ABORT | CR_STA);
710:
711: /*
712: * Since the NIC is in internal loopback mode (TCR_INTERNAL), and
713: * interrupts are disabled, we can now test the NIC's memory to
714: * determine how much there is.
715: */
716: testmem = getbuf (1024); /* get temporary space */
717: testbuf = testmem->b_rptr;
718: test2 = testbuf + 256;
719:
720: for (i = 0 ; i < 256 ; i ++)
721: testbuf [i] = i;
722: for (i = 0 ; i < 256 ; i ++) {
723: testbuf [0] = i;
724: testbuf [1] = ~i;
725: set_mem (i << 8, 256, testbuf);
726: wait_for_dma ();
727: }
728:
729: /* find start of memory */
730: for (i = 0 ; i < 256 ; i++) {
731: testbuf [0] = i;
732: testbuf [1] = ~i;
733: get_mem (i << 8, 256, test2);
734: wait_for_dma ();
735: if (memcmp (test2, testbuf, 256) == 0)
736: /* got one - either start or extend a span */
737: if (start < 0) {
738: start = i;
739: len = 1;
740: } else
741: len++;
742: else
743: if (start >= 0)
744: break;
745: }
746: if (len < 16) { /* needs at least 4k to work */
747: eth.netok = -1;
748: goto alldone;
749: }
750:
751: eth.dp8390info.dpi_pstart = start + 8;
752: eth.dp8390info.dpi_pstop = start + len;
753: eth.dp8390info.dpi_tbuf = start;
754:
755: /*
756: * Since we're at it... if the board has an address PROM, it should
757: * be at address 0 (where the NIC has trouble locating RAM), so
758: * unless we're given an address, try finding our location.
759: */
760: if (addr != NULL)
761: eth.myaddr = * addr;
762: else if (start > 0) { /* may have PROM, there's no RAM */
763: get_mem (0, 12, testbuf);
764: wait_for_dma ();
765:
766: /* Fetch the PROM data from every second word */
767: for (i = 0;i < 6;i++)
768: eth.myaddr.e [i] = testbuf [i + i];
769: }
770:
771: STREAMS_DEBUG_LONG (len << 8, 16);
772: STREAMS_DEBUG ("h bytes of Ethernet memory, Address = $");
773: for (i = 0 ; i < 6 ; i ++)
774: STREAMS_DEBUG_LONG (eth.myaddr.e [i], 16);
775: STREAMS_DEBUG (", IRQ ");
776: STREAMS_DEBUG_LONG (ETHER_IRQ, 10);
777: STREAMS_DEBUG ("\r\n");
778:
779: output (DEVICE, dp_isr, 0xFF);
780: output (DEVICE, dp_tpsr, eth.dp8390info.dpi_tbuf);
781: output (DEVICE, dp_pstart, eth.dp8390info.dpi_pstart);
782: output (DEVICE, dp_bnry, eth.dp8390info.dpi_pstart);
783: output (DEVICE, dp_pstop, eth.dp8390info.dpi_pstop);
784:
785: output (DEVICE, dp_cr, CR_PS_P1|CR_DM_ABORT|CR_STP);
786: output1 (DEVICE, dp_curr, eth.dp8390info.dpi_pstart + 1);
787: eth.dp8390info.dpi_next = eth.dp8390info.dpi_pstart + 1;
788:
789: set_addr (0);
790:
791: output (DEVICE, dp_cr, CR_PS_P0|CR_DM_ABORT|CR_STA);
792: output (DEVICE, dp_tcr, 0);
793: output (DEVICE, dp_imr, 0x7F); /* all interrupts */
794:
795: if ((eth_timer = TIMER_ALLOC ()) != NIL_TIMER)
796: TIMER_SET (eth_timer, 1, eth_timer_func, (long) & eth);
797: eth.netok ++;
798:
799: alldone:
800: freemsg (testmem);
801: }
802:
803: /*
804: * Shut down the E'net chip. Whenever I get around to it, this will send
805: * the ARP-style packet that indicates this station is dead'n'gone. This
806: * will use the poll-type DMA access shown in the open.
807: */
808: static void chipoff (void)
809: {
810: DEVICE_REG
811:
812: if (eth.netok < 0)
813: return;
814: #ifdef IBMPC
815: set_hw_int (ETHER_IRQ, NULL);
816: #endif /* IBMPC */
817: output (DEVICE, dp_imr, 0);
818: output (DEVICE, dp_cr, CR_PS_P0 | CR_DM_ABORT | CR_STP);
819: }
820:
821: /*
822: * stream open routine for the driver
823: */
824: static int ethopen (queue_t * q, dev_t dev, int /* flag */, int sflag)
825: {
826: /* refuse to do anything unless everything checked out OK at boot */
827: W (q)->q_ptr = q->q_ptr = & eth;
828: if (QETH->netok < 0)
829: return OPENFAIL;
830: if (QETH->netok == 0) {
831: chipinit (NULL);
832: if (QETH->netok < 0)
833: return OPENFAIL;
834:
835: } else
836: QETH->netok ++;
837: /* allow regular or clone device open */
838: if (sflag == CLONEOPEN) {
839: for (dev = 0;dev < MAXMINOR;dev++)
840: if (minortab[dev] == NULL)
841: break;
842: } else
843: dev = minor(dev);
844: if (dev < 0 || dev >= MAXMINOR)
845: return OPENFAIL;
846:
847: minortab[dev] = q;
848: return dev;
849: }
850:
851: /* ethernet write put procedure */
852: static void ethwput (queue_t * q, mblk_t * mp)
853: {
854: Framehdr * frame;
855: struct sp_bind * spbind;
856: Eth_addr * addr;
857:
858: switch (mp->b_datap->db_type) {
859: case M_PROTO:
860: spbind = (struct sp_bind *)mp->b_rptr;
861: addr = (Eth_addr *)(spbind + 1);
862: if (spbind->protoid == SP_BIND) {
863: if (spbind->family != AF_ENET) {
864: freemsg (mp);
865: return;
866: }
867: if (mp->b_wptr > (unsigned char *) addr) {
868: QETH->myaddr = * addr ++;
869: set_addr (1);
870: }
871: freemsg (mp);
872: mp = allocb (sizeof (struct sp_bind) + sizeof (Eth_addr),
873: BPRI_MED);
874: if (mp != NULL) {
875: spbind = (struct sp_bind *)mp->b_rptr;
876: addr = (Eth_addr *)(spbind + 1);
877: spbind->protoid = SP_BIND;
878: spbind->family = AF_ENET;
879: spbind->connect = TPS_BOUND;
880: * addr ++ = QETH->myaddr;
881: mp->b_wptr = (unsigned char *) addr;
882: mp->b_datap->db_type = M_PROTO;
883: qreply (q, mp);
884: }
885: return;
886: }
887: default:
888: nogood:
889: freemsg (mp);
890: break;
891: case M_DATA:
892: frame = (Framehdr *)mp->b_rptr;
893: if ((unsigned char *)(frame + 1) > mp->b_wptr)
894: goto nogood;
895: SCREEN (20) ++;
896: frame->f_srcaddr = QETH->myaddr;
897: queue_packet (q, mp);
898: break;
899: case M_FLUSH:
900: /* canonical flush processing */
901: if ((* mp->b_rptr & FLUSHW) != 0)
902: flushq (q, FLUSHDATA);
903: if ((* mp->b_rptr & FLUSHR) != 0) {
904: flushq (RD(q), FLUSHDATA);
905: * mp->b_rptr &= ~FLUSHW;
906: qreply (q, mp);
907: } else
908: freemsg (mp);
909: break;
910: case M_IOCTL:
911: mp->b_datap->db_type = M_IOCNAK;
912: qreply (q, mp);
913: break;
914: }
915: }
916:
917: /* read service routine */
918: static void ethrsrv (queue_t * q)
919: {
920: mblk_t * mp;
921:
922: while ((mp = getq (q)) != NULL)
923: if (canput (q->q_next))
924: putnext (q, mp);
925: else {
926: putbq (q, mp);
927: break;
928: }
929: SCREEN (24) ++;
930: }
931:
932: /* close procedure - called on last close of stream */
933: static int ethclose(queue_t *q)
934: {
935: int i;
936:
937: if (QETH->netok == 1)
938: chipoff ();
939: QETH->netok --;
940: for (i = 0;i < MAXMINOR;i++)
941: if (minortab[i] == q)
942: break;
943: minortab[i] = NULL;
944: return(0);
945: }
946:
947: static struct module_info ethrinfo = {
948: 0, "ether", 0, 1024, 1024, 0
949: };
950: static struct qinit ethread = {
951: NULLFUNC, ethrsrv, ethopen, ethclose, NULLFUNC,
952: ðrinfo, NULLSTAT
953: }, ethwrite = {
954: ethwput, NULLFUNC, NULLFUNC, NULLFUNC, NULLFUNC,
955: ðrinfo, NULLSTAT
956: };
957: struct streamtab ethinfo = {
958: ðread, ðwrite, NULLINIT, NULLINIT
959: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.