FreeBSD/Linux Kernel Cross Reference
sys/chips/lance.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993-1989 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: lance.c,v $
29 * Revision 2.30 93/05/30 21:07:14 rvb
30 * Sanity check in copy_to_lance was screwed by type promotions.
31 * [93/05/28 af]
32 *
33 * Revision 2.29 93/05/15 19:38:06 mrt
34 * machparam.h -> machspl.h
35 *
36 * Revision 2.28 93/05/10 20:08:02 rvb
37 * No more sys/types.h. Define what is exported and what not.
38 * [93/05/06 09:52:17 af]
39 *
40 * Revision 2.27 93/05/10 17:45:04 rvb
41 * Tell the lance to send the packet now instead of waiting
42 * until the next 1.6 ms poll interval expires.
43 * [from cmaeda.]
44 *
45 * Revision 2.26 93/03/26 17:58:11 mrt
46 * Removed all uses of minor().
47 * [93/03/17 af]
48 *
49 * Revision 2.25 93/03/09 10:51:59 danner
50 * Propagated protos of switch structure.
51 * [93/03/06 af]
52 * Removed dev_t, which is just a U*x compat type. Lint.
53 * Would be nice to be able to make this file readable again.
54 * Reset lo(n)g history, contributors so far:
55 * rvb, af, mja, rpd, jsb, danner, jfriedl, jeffreyh
56 * [93/03/05 af]
57 *
58 * 18-May-89 Robert Baron (rvb) at Carnegie-Mellon University
59 * Created.
60 */
61 /*
62 * File: lance.c
63 * Author: Robert V. Baron & Alessandro Forin
64 * Date: 5/90
65 *
66 * Driver for the DEC LANCE Ethernet Controller.
67 */
68
69 /*
70
71 Byte ordering issues.
72
73 The lance sees data naturally as half word (16 bit) quantitites.
74 Bit 2 (BSWP) in control register 3 (CSR3) controls byte swapping.
75 To quote the spec:
76
77 02 BSWP BYTE SWAP allows the chip to
78 operate in systems that consdier bits (15:08) of data pointers
79 by an even addressa and bits (7:0) to be pointed by an
80 odd address.
81
82 When BSWP=1, the chip will swap the high and low bytes on DMA
83 data transfers between the silo and bus memory. Only data from
84 silo transfers is swapped; the Initialization Block data and
85 the Descriptor Ring entries are NOT swapped. (emphasis theirs)
86
87
88 So on systems with BYTE_MSF=1, the BSWP bit should be set. Note,
89 however, that all shorts in the descriptor ring and initialization
90 block need to be swapped. The BITFIELD macros in lance.h handle this
91 magic.
92
93 */
94
95 #include <ln.h>
96 #if NLN > 0
97 #include <platforms.h>
98
99 /*
100 * AMD Am7990 LANCE (Ethernet Interface)
101 */
102 #include <sys/ioctl.h>
103 #include <vm/vm_kern.h>
104
105 #include <machine/machspl.h> /* spl definitions */
106 #include <kern/time_out.h>
107 #include <sys/syslog.h>
108 #include <ipc/ipc_port.h>
109 #include <ipc/ipc_kmsg.h>
110
111 #include <device/device_types.h>
112 #include <device/errno.h>
113 #include <device/io_req.h>
114 #include <device/if_hdr.h>
115 #include <device/if_ether.h>
116 #include <device/net_status.h>
117 #include <device/net_io.h>
118
119 #ifdef FLAMINGO
120 #define se_reg_type unsigned int
121 #endif
122
123 #include <chips/lance.h>
124 #include <chips/busses.h>
125
126 #define private static
127 #define public
128
129 typedef struct se_softc *se_softc_t; /* move above prototypes */
130
131 void se_write_reg(); /* forwards */
132 void se_read();
133 void se_rint();
134 void se_tint();
135
136 private vm_offset_t se_Hmem_nogap(), se_Hmem_gap16();
137 private vm_offset_t se_malloc();
138
139
140 /* This config section should go into a separate file */
141
142 #ifdef LUNA88K
143 # include <luna88k/board.h>
144 # define MAPPED 1
145 #undef bcopy
146 extern void bcopy(), bzero();
147
148 #define wbflush()
149 #define Hmem(lna) (vm_offset_t)((lna) + sc->lnbuf)
150 #define Lmem(lna) (vm_offset_t)((lna) + sc->lnoffset)
151
152 #define SPACE (TRI_PORT_RAM_SPACE>>1)
153 private struct se_switch se_switch[] = {
154 { LANCE_ADDR - TRI_PORT_RAM, /* pointer */
155 SPACE /* host side */,
156 SPACE /* lance side */,
157 - TRI_PORT_RAM,
158 0, /* romstride */
159 0, /* ramstride */
160 SPACE,
161 /* desc_copyin */ bcopy,
162 /* desc_copyout */ bcopy,
163 /* data_copyin */ bcopy,
164 /* data_copyout */ bcopy,
165 /* bzero */ bzero,
166 /* mapaddr */ se_Hmem_nogap,
167 /* mapoffs */ se_Hmem_nogap
168 },
169 };
170
171 #endif
172
173 #ifdef DECSTATION
174 #include <mips/mips_cpu.h>
175 #include <mips/PMAX/pmad_aa.h>
176
177 #define MAPPED 1
178
179 /*
180 * The LANCE buffer memory as seen from the Pmax cpu is funny.
181 * It is viewed as short words (16bits), spaced at word (32bits)
182 * intervals. The same applies to the registers. From the LANCE
183 * point of view memory is instead contiguous.
184 * The ROM that contains the station address is in the space belonging
185 * to the clock/battery backup memory. This space is again 16 bits
186 * in a 32bit envelope. And the ether address is stored in the "high"
187 * byte of 6 consecutive quantities.
188 *
189 * But Pmaxen and 3maxen (and..) map lance space differently.
190 * This requires dynamic adaptation of the driver, which
191 * is done via the following switches.
192 * For convenience, the switch holds information about
193 * the location of the lance control registers as well.
194 * This could be either absolute (pmax) or relative to
195 * some register base (3max, turbochannel)
196 */
197 void copyin_gap16(), copyout_gap16(), bzero_gap16();
198 extern void bcopy(), bzero();
199 void copyin_gap32(), copyout_gap32();
200
201 private struct se_switch se_switch[] = {
202 /* pmax */
203 { 0x00000000, 0x01000000, 0x0, 0x05000000, 8, 16, 64*1024,
204 copyin_gap16, copyout_gap16, copyin_gap16, copyout_gap16,
205 bzero_gap16, se_Hmem_gap16, se_Hmem_gap16},
206 /* 3max */
207 { PMAD_OFFSET_LANCE, PMAD_OFFSET_RAM, PMAD_OFFSET_RAM, PMAD_OFFSET_ROM,
208 16, 0, PMAD_RAM_SIZE,
209 bcopy, bcopy, bcopy, bcopy, bzero, se_Hmem_nogap, se_Hmem_nogap},
210 /* 3min */
211 /* XXX re-use other 64k */
212 { 0/*later*/, 0/*later*/, 0x0, 0/*later*/, 0, 128, 64*1024,
213 copyin_gap16, copyout_gap16, copyin_gap32, copyout_gap32,
214 bzero_gap16, se_Hmem_gap16, se_Hmem_nogap},
215 };
216
217 /*
218 * "lna" is what se_malloc hands back. They are offsets using
219 * the sizing that the Lance would use. The Lance space is
220 * mapped somewhere in the I/O space, as indicated by the softc.
221 * Hence we have these two macros:
222 */
223 /* H & L are not hi and lo but
224 H = HOST == addresses for host to reference board memory
225 L = LOCAL == addresses on board
226 */
227 #define Hmem(lna) (vm_offset_t)((se_sw->mapaddr)(lna) + sc->lnbuf)
228 #define Lmem(lna) (vm_offset_t)((vm_offset_t)lna + sc->lnoffset)
229 #endif /*DECSTATION*/
230
231
232 #ifdef VAXSTATION
233 #include <vax/ka3100.h>
234
235 #define wbflush()
236
237 void xzero(x, l) vm_offset_t x; int l; { blkclr(x, l); }
238 void xcopy(f, t, l) vm_offset_t f, t; int l; { bcopy(f, t, l); }
239
240 private struct se_switch se_switch[] = {
241 /* pvax sees contiguous bits in lower 16Meg of memory */
242 { 0, 0, 0, 0, 0, 0, 64*1024,
243 xcopy, xcopy, xcopy, xcopy, xzero, se_Hmem_nogap, se_Hmem_nogap},
244 };
245
246 /*
247 * "lna" is what se_malloc hands back. They are offsets using
248 * the sizing that the Lance would use. The Lance space is
249 * mapped somewhere in the I/O space, as indicated by the softc.
250 * Hence we have these two macros:
251 */
252 /* H & L are not hi and lo but
253 H = HOST == addresses for host to reference board memory
254 L = LOCAL == addresses on board
255 */
256 /*
257 * This does not deal with > 16 Meg physical memory, where
258 * Hmem != Lmem
259 */
260 #define Hmem(lna) (vm_offset_t)((lna) + sc->lnbuf)
261 #define Lmem(lna) (vm_offset_t)((lna) + sc->lnoffset)
262
263 #endif /*VAXSTATION*/
264
265
266 #ifdef FLAMINGO
267 #include <alpha/alpha_cpu.h>
268
269 /* XXX might be wrong, mostly stolen from kmin */
270 extern void copyin_gap16(), copyout_gap16(), bzero_gap16();
271 extern void copyin_gap32(), copyout_gap32();
272 extern void bcopy(), bzero();
273
274 private struct se_switch se_switch[] = {
275 /* XXX re-use other 64k */
276 { 0/*later*/, 0/*later*/, 0x0, 0/*later*/, 0, 128, 64*1024,
277 copyin_gap16, copyout_gap16, copyin_gap32, copyout_gap32,
278 bzero_gap16, se_Hmem_gap16, se_Hmem_nogap},
279 };
280
281 /*
282 * "lna" is what se_malloc hands back. They are offsets using
283 * the sizing that the Lance would use. The Lance space is
284 * mapped somewhere in the I/O space, as indicated by the softc.
285 * Hence we have these two macros:
286 */
287 /* H & L are not hi and lo but
288 H = HOST == addresses for host to reference board memory
289 L = LOCAL == addresses on board
290 */
291 #define Hmem(lna) (vm_offset_t)((se_sw->mapaddr)(lna) + sc->lnbuf)
292 #define Lmem(lna) (vm_offset_t)((vm_offset_t)lna + sc->lnoffset)
293 #endif /*FLAMINGO*/
294
295
296 /*
297 * Map a lance-space offset into an host-space one
298 */
299 private vm_offset_t se_Hmem_nogap( vm_offset_t lna) { return lna;}
300 private vm_offset_t se_Hmem_gap16( vm_offset_t lna) { return lna << 1;}
301
302 /*
303 * Memory addresses for LANCE are 24 bits wide.
304 */
305 #define Addr_lo(y) ((unsigned short)((vm_offset_t)(y) & 0xffff))
306 #define Addr_hi(y) ((unsigned short)(((vm_offset_t)(y)>>16) & 0xff))
307
308 #define LN_MEMORY_SIZE (se_sw->ramsize)
309
310 /* XXX to accomodate heterogeneity this should be made per-drive */
311 /* XXX and then some more */
312
313 struct se_switch *se_sw = se_switch;
314
315 void set_se_switch(n)
316 int n;
317 {
318 se_sw = &se_switch[n];
319 }
320
321 #ifndef LUNA88K
322 void setse_switch(n, r, b, l, o)
323 vm_offset_t r, b, l, o;
324 int n;
325 {
326 se_switch[n].regspace = r;
327 se_switch[n].bufspace = b;
328 se_switch[n].ln_bufspace = l;
329 se_switch[n].romspace = o;
330
331 /* make sure longword aligned */
332 if (se_switch[n].bufspace & 0x7) {
333 se_switch[n].bufspace = (se_switch[n].bufspace+0x7) & ~0x7;
334 }
335
336 set_se_switch(n);
337 }
338 #endif
339
340 /*
341 * Autoconf info
342 */
343
344 private vm_offset_t se_std[NLN] = { 0 };
345 private struct bus_device *se_info[NLN];
346 private int se_probe();
347 private void se_attach();
348
349 struct bus_driver se_driver =
350 { se_probe, 0, se_attach, 0, se_std, "se", se_info, };
351
352 /*
353 * Externally visible functions
354 */
355 char *se_unprobed_addr = 0;
356 void se_intr(); /* kernel */
357
358 int se_open(), se_output(), se_get_status(), /* user */
359 se_set_status(), se_setinput(), se_restart();
360
361 /*
362 *
363 * Internal functions & definitions
364 *
365 */
366
367 private int se_probe();
368 private void se_init();
369 private void init_lance_space();
370 private void se_desc_set_status();
371 private volatile long *se_desc_alloc(); /* must be aligned! */
372 void se_start();
373 private void copy_from_lance();
374 private int copy_to_lance();
375
376 int se_verbose = 0; /* debug flag */
377
378 #define RLOG 4 /* 2**4 = 16 receive descriptors */
379 #define TLOG 4 /* 2**4 = 16 transmit descriptors */
380 #define NRCV (1<<RLOG) /* Receive descriptors */
381 #define NXMT (1<<TLOG) /* Transmit descriptors */
382
383 #define LN_BUFFER_SIZE (0x800-0x80)
384
385 /*
386 * Ethernet software status per interface.
387 *
388 * Each interface is referenced by a network interface structure,
389 * is_if, which contains the output queue for the interface, its address, ...
390 */
391 int se_loopback_hack = 1;
392
393 struct se_softc {
394 struct ifnet is_if; /* generic interface header */
395 unsigned char is_addr[6]; /* ethernet hardware address */
396 unsigned short pad;
397 se_reg_t lnregs; /* Lance registers */
398 vm_offset_t lnbuf; /* Lance memory, Host offset */
399 vm_offset_t lnoffset; /* Lance memory, Lance offset */
400 vm_offset_t lnrom;
401 vm_offset_t lnsbrk; /* Lance memory allocator */
402 vm_offset_t lninit_block; /* Init block address */
403 se_desc_t lnrring[NRCV]; /* Receive ring desc. */
404 volatile long *lnrbuf[NRCV]; /* Receive buffers */
405 se_desc_t lntring[NXMT]; /* Transmit ring desc. */
406 volatile long *lntbuf[NXMT]; /* Transmit buffers */
407
408 int rcv_last; /* Rcv buffer last read */
409
410 io_req_t tpkt[NXMT+1]; /* Xmt pkt queue */
411 int xmt_count; /* Xmt queue size */
412 int xmt_last; /* Xmt queue head (insert) */
413 int xmt_complete; /* Xmt queue tail (remove) */
414
415 int se_flags; /* Flags for SIOCSIFFLAGS */
416 int counters[4]; /* error counters */
417 #define bablcnt counters[0]
418 #define misscnt counters[1]
419 #define merrcnt counters[2]
420 #define rstrtcnt counters[3]
421 } se_softc_data[NLN];
422
423 se_softc_t se_softc[NLN]; /* quick access */
424
425 /*
426 * Probe the Lance to see if it's there
427 */
428 private int se_open_state = 0;
429
430 private int se_probe(
431 vm_offset_t reg,
432 register struct bus_device *ui)
433 {
434 register se_softc_t sc;
435 se_reg_t rdp, rap;
436 int unit = ui->unit;
437
438 /*
439 * See if the interface is there by reading the lance CSR. On pmaxen
440 * and 3maxen this is superfluous, but..
441 */
442 rdp = (se_reg_t) (reg + se_sw->regspace);
443 #ifdef DECSTATION
444 if (check_memory(rdp, 0))
445 return 0;
446 #endif /*DECSTATION*/
447 #ifdef MAPPED
448 SE_probe(reg,ui);
449 #endif /*MAPPED*/
450 rap = rdp + 2; /* XXX might not be true in the future XXX */
451 /* rdp and rap are "shorts" on consecutive
452 "long" word boundaries */
453
454 /*
455 * Bind this interface to the softc.
456 */
457 sc = &se_softc_data[unit];
458 se_softc[unit] = sc;
459 sc->lnregs = (se_reg_t) (reg + se_sw->regspace);
460 sc->lnbuf = (vm_offset_t) (reg + se_sw->bufspace);
461 sc->lnoffset = (vm_offset_t) (se_sw->ln_bufspace);
462 sc->lnrom = (vm_offset_t) (reg + se_sw->romspace);
463
464 /*
465 * Reset the interface, and make sure we really do it! (the 3max
466 * seems quite stubborn about these registers)
467 */
468 se_write_reg(rap, CSR0_SELECT, CSR0_SELECT, "RAP");
469 se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0");
470
471 /*
472 * Allocate lance RAM buffer memory
473 */
474 init_lance_space(sc);
475
476 /*
477 * Initialize the chip
478 *
479 * NOTE: From now on we will only touch csr0
480 */
481 if (se_ship_init_block(sc, unit))
482 return 0;
483
484 /*
485 * Tell the world we are alive and well
486 */
487 se_open_state++;
488 return 1;
489 }
490
491 int se_ship_init_block(
492 register se_softc_t sc,
493 int unit)
494 {
495 se_reg_t rdp = sc->lnregs;
496 se_reg_t rap;
497 register int i = 0;
498
499 rap = rdp + 2; /* XXX might not be true in the future XXX */
500
501 /*
502 * Load LANCE control block.
503 */
504
505 #ifdef LUNA88K
506 /* turn on byte swap bit in csr3, set bcon bit - as in 2.5 */
507 se_write_reg(rap, CSR3_SELECT, CSR3_SELECT, "RAP");
508 se_write_reg(rdp, LN_CSR3_BSWP|LN_CSR3_BCON,
509 LN_CSR3_BSWP|LN_CSR3_BCON, "csr3");
510 #endif
511
512 se_write_reg(rap, CSR1_SELECT, CSR1_SELECT, "RAP");
513 se_write_reg(rdp, Addr_lo(Lmem(sc->lninit_block)),
514 Addr_lo(Lmem(sc->lninit_block)), "csr1");
515
516 se_write_reg(rap, CSR2_SELECT, CSR2_SELECT, "RAP");
517 se_write_reg(rdp, Addr_hi(Lmem(sc->lninit_block)),
518 Addr_hi(Lmem(sc->lninit_block)), "csr2");
519
520 /*
521 * Start the INIT sequence now
522 */
523 se_write_reg(rap, CSR0_SELECT, CSR0_SELECT, "RAP");
524 *rdp = (LN_CSR0_IDON | LN_CSR0_INIT);
525 wbflush();
526
527 /* give it plenty of time to settle */
528 while (i++ < 10000) {
529 delay(100);
530 if ((*rdp & LN_CSR0_IDON) != 0)
531 break;
532 }
533 /* make sure got out okay */
534 if ((*rdp & LN_CSR0_IDON) == 0) {
535 printf("se%d: cannot initialize\n", unit);
536 if (*rdp & LN_CSR0_ERR)
537 printf("se%d: initialization error, csr = %04x\n",
538 unit, (*rdp & 0xffff));
539 return 1;
540 }
541 /*
542 * Do not enable interrupts just yet.
543 */
544 /* se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0"); */
545
546 return 0;
547 }
548
549 void
550 se_write_reg(
551 register se_reg_t regptr,
552 register int val,
553 register int result,
554 char *regname)
555 {
556 register int i = 0;
557
558 while ((unsigned short)(*regptr) != (unsigned short)result) {
559 *regptr = (se_reg_type)val;
560 wbflush();
561 if (++i > 10000) {
562 printf("se: %s did not settle (to x%x): x%x\n",
563 regname, result, (unsigned short)(*regptr));
564 return;
565 }
566 delay(100);
567 }
568 }
569
570 unsigned short
571 se_read_reg(
572 register se_reg_t regptr)
573 {
574 return (unsigned short) (*regptr);
575 }
576
577 private void
578 init_lance_space(
579 register se_softc_t sc)
580 {
581 register int lptr; /* Generic lance pointer */
582 se_desc_t ringaddr;
583 long *rom_eaddress = (long *) sc->lnrom;
584 int i;
585 struct se_init_block init_block;
586
587 /*
588 * Allocate local RAM buffer memory for the init block,
589 * fill in our local copy then copyout.
590 */
591
592 sc->lninit_block = se_malloc(sc, sizeof (struct se_init_block));
593
594 /*
595 * Set values on stack, then copyout en-masse
596 */
597 bzero(&init_block, sizeof(init_block));
598 init_block.mode = 0;
599
600 /* byte swapping between host and lance */
601
602 init_block.phys_addr_low = ((rom_eaddress[0]>>se_sw->romstride)&0xff) |
603 (((rom_eaddress[1]>>se_sw->romstride)&0xff) << 8);
604 init_block.phys_addr_med = ((rom_eaddress[2]>>se_sw->romstride)&0xff) |
605 (((rom_eaddress[3]>>se_sw->romstride)&0xff) << 8);
606 init_block.phys_addr_high = ((rom_eaddress[4]>>se_sw->romstride)&0xff) |
607 (((rom_eaddress[5]>>se_sw->romstride)&0xff) << 8);
608
609 /*
610 * Allocate both descriptor rings at once.
611 * Note that the quadword alignment requirement is
612 * inherent in the way we perform allocation,
613 * but it does depend on the size of the init block.
614 */
615 lptr = se_malloc(sc, sizeof (struct se_desc) * (NXMT + NRCV));
616
617 /*
618 * Initialize the buffer descriptors
619 */
620 init_block.recv_ring_pointer_lo = Addr_lo(Lmem(lptr));
621 init_block.recv_ring_pointer_hi = Addr_hi(Lmem(lptr));
622 init_block.recv_ring_len = RLOG;
623
624 for ( i = 0; i < NRCV ; i++, lptr += sizeof(struct se_desc)) {
625 ringaddr = (se_desc_t)Hmem(lptr);
626 sc->lnrring[i] = ringaddr;
627 sc->lnrbuf[i] = se_desc_alloc (sc, ringaddr);
628 }
629
630 init_block.xmit_ring_pointer_lo = Addr_lo(Lmem(lptr));
631 init_block.xmit_ring_pointer_hi = Addr_hi(Lmem(lptr));
632 init_block.xmit_ring_len = TLOG;
633
634 for ( i = 0 ; i < NXMT ; i++, lptr += sizeof(struct se_desc)) {
635 ringaddr = (se_desc_t)Hmem(lptr);
636 sc->lntring[i] = ringaddr;
637 sc->lntbuf[i] = se_desc_alloc (sc, ringaddr);
638 }
639
640 /*
641 * No logical address filtering
642 */
643 init_block.logical_addr_filter0 = 0;
644 init_block.logical_addr_filter1 = 0;
645 init_block.logical_addr_filter2 = 0;
646 init_block.logical_addr_filter3 = 0;
647
648 /*
649 * Move init block into lance space
650 */
651 (se_sw->desc_copyout)((vm_offset_t)&init_block, Hmem(sc->lninit_block), sizeof(init_block));
652 wbflush();
653 }
654
655 /*
656 * Interface exists: make available by filling in network interface
657 * record. System will initialize the interface when it is ready
658 * to accept packets.
659 */
660 private void
661 se_attach(
662 register struct bus_device *ui)
663 {
664 unsigned char *enaddr;
665 struct ifnet *ifp;
666 long *rom_eaddress;
667 int unit = ui->unit;
668 se_softc_t sc = se_softc[unit];
669
670 rom_eaddress = (long *) sc->lnrom;
671
672 /*
673 * Read the address from the prom and save it.
674 */
675 enaddr = sc->is_addr;
676 enaddr[0] = (unsigned char) ((rom_eaddress[0] >> se_sw->romstride) & 0xff);
677 enaddr[1] = (unsigned char) ((rom_eaddress[1] >> se_sw->romstride) & 0xff);
678 enaddr[2] = (unsigned char) ((rom_eaddress[2] >> se_sw->romstride) & 0xff);
679 enaddr[3] = (unsigned char) ((rom_eaddress[3] >> se_sw->romstride) & 0xff);
680 enaddr[4] = (unsigned char) ((rom_eaddress[4] >> se_sw->romstride) & 0xff);
681 enaddr[5] = (unsigned char) ((rom_eaddress[5] >> se_sw->romstride) & 0xff);
682
683 printf(": %x-%x-%x-%x-%x-%x",
684 (rom_eaddress[0] >> se_sw->romstride) & 0xff,
685 (rom_eaddress[1] >> se_sw->romstride) & 0xff,
686 (rom_eaddress[2] >> se_sw->romstride) & 0xff,
687 (rom_eaddress[3] >> se_sw->romstride) & 0xff,
688 (rom_eaddress[4] >> se_sw->romstride) & 0xff,
689 (rom_eaddress[5] >> se_sw->romstride) & 0xff);
690
691 /*
692 * Initialize the standard interface descriptor
693 */
694 ifp = &sc->is_if;
695 ifp->if_unit = unit;
696 ifp->if_header_size = sizeof(struct ether_header);
697 ifp->if_header_format = HDR_ETHERNET;
698 ifp->if_address_size = 6;
699 ifp->if_mtu = ETHERMTU;
700 ifp->if_flags |= IFF_BROADCAST;
701
702 ifp->if_address = (char *) enaddr;
703
704 if_init_queues(ifp);
705 #ifdef MAPPED
706 SE_attach(ui);
707 #endif /*MAPPED*/
708
709 }
710
711 /*
712 * Use a different hardware address for interface
713 */
714 void
715 se_setaddr(
716 unsigned char eaddr[6],
717 int unit)
718 {
719 register se_softc_t sc = se_softc[unit];
720 struct se_init_block init_block;
721
722 /*
723 * Modify initialization block accordingly
724 */
725 (se_sw->desc_copyin) (Hmem(sc->lninit_block), (vm_offset_t)&init_block, sizeof(init_block));
726 bcopy(eaddr, &init_block.phys_addr_low, sizeof(*eaddr));
727 (se_sw->desc_copyout)((vm_offset_t)&init_block, Hmem(sc->lninit_block), sizeof(init_block));
728 /*
729 * Make a note of it
730 */
731 bcopy(eaddr, sc->is_addr, sizeof(*eaddr));
732
733 /*
734 * Restart the interface
735 */
736 se_restart(&sc->is_if);
737 se_init(unit);
738 }
739
740 /*
741 * Restart interface
742 *
743 * We use this internally on those errors that hang the chip,
744 * not sure yet what use the MI code will make of it.
745 *
746 * After stopping the chip and effectively turning off the interface
747 * we release all pending buffers and cause the chip to init
748 * itself. We do not enable interrupts here.
749 */
750 int
751 se_restart( register struct ifnet *ifp )
752 {
753 register se_softc_t sc = se_softc[ifp->if_unit];
754 se_reg_t rdp;
755 register int i;
756
757 rdp = sc->lnregs;
758
759 /*
760 * stop the chip
761 */
762 se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0");
763
764 /*
765 * stop network activity
766 */
767 if (ifp->if_flags & IFF_RUNNING) {
768 ifp->if_flags &= ~(IFF_UP | IFF_RUNNING);
769 sc->se_flags &= ~(IFF_UP | IFF_RUNNING);
770 }
771 sc->rstrtcnt++;
772
773 if (se_verbose)
774 printf("se%d: %d restarts\n", ifp->if_unit, sc->rstrtcnt);
775
776 /*
777 * free up any buffers currently in use
778 */
779 for (i = 0; i < NXMT; i++)
780 if (sc->tpkt[i]) {
781 iodone(sc->tpkt[i]);
782 sc->tpkt[i] = (io_req_t) 0;
783 }
784 /*
785 * INIT the chip again, no need to reload init block address.
786 */
787 se_ship_init_block(sc, ifp->if_unit);
788
789 return (0);
790 }
791
792 /*
793 * Initialize the interface.
794 */
795 private void
796 se_init( int unit )
797 {
798 register se_softc_t sc = se_softc[unit];
799 register se_desc_t *rp;
800 register struct ifnet *ifp = &sc->is_if;
801 se_reg_t rdp;
802 short mode;
803 spl_t s;
804 int i;
805
806 if (ifp->if_flags & IFF_RUNNING)
807 return;
808
809 rdp = sc->lnregs;
810
811 /*
812 * Init the buffer descriptors and indexes for each of the rings.
813 */
814 for (i = 0, rp = sc->lnrring; i < NRCV; i++, rp++)
815 se_desc_set_status(*rp, LN_RSTATE_OWN);
816
817 for (i = 0, rp = sc->lntring; i < NXMT; i++, rp++)
818 se_desc_set_status(*rp, 0);
819
820 sc->xmt_count = sc->xmt_complete = sc->xmt_last = sc->rcv_last = 0;
821
822 /*
823 * Deal with loopback mode operation
824 */
825 s = splimp();
826
827 (se_sw->desc_copyin) (Hmem(sc->lninit_block), (vm_offset_t)&mode, sizeof(mode));
828
829 if (ifp->if_flags & IFF_LOOPBACK
830 && ((mode & LN_MODE_LOOP) == 0)) {
831 /* if not already in loopback mode, do external loopback */
832 mode &= ~LN_MODE_INTL;
833 mode |= LN_MODE_LOOP;
834 (se_sw->desc_copyout) ((vm_offset_t)&mode, Hmem(sc->lninit_block), sizeof(mode));
835 se_restart(ifp);
836 se_init(ifp->if_unit);
837 splx(s);
838 return;
839 }
840
841 ifp->if_flags |= (IFF_UP | IFF_RUNNING);
842 sc->se_flags |= (IFF_UP | IFF_RUNNING);
843
844 /*
845 * Start the Lance and enable interrupts
846 */
847 *rdp = (LN_CSR0_STRT | LN_CSR0_INEA);
848 wbflush();
849
850 /*
851 * See if anything is already queued
852 */
853 se_start(unit);
854 splx(s);
855 }
856
857
858 /*
859 * Shut off the lance
860 */
861 void
862 se_stop(int unit)
863 {
864 se_reg_t rdp = se_softc[unit]->lnregs;
865
866 se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0");
867 }
868
869
870 /*
871 * Open the device, declaring the interface up
872 * and enabling lance interrupts.
873 */
874 /*ARGSUSED*/
875 int
876 se_open(
877 int unit,
878 int flag)
879 {
880 register se_softc_t sc = se_softc[unit];
881
882 if (unit >= NLN)
883 return EINVAL;
884 if (!se_open_state)
885 return ENXIO;
886
887 sc->is_if.if_flags |= IFF_UP;
888 se_open_state++;
889 se_init(unit);
890 return (0);
891 }
892
893 #ifdef MAPPED
894 int se_use_mapped_interface[NLN];
895 #endif /*MAPPED*/
896
897 void
898 se_normal(int unit)
899 {
900 #ifdef MAPPED
901 se_use_mapped_interface[unit] = 0;
902 #endif /*MAPPED*/
903 if (se_softc[unit]) {
904 se_restart((struct ifnet *)se_softc[unit]);
905 se_init(unit);
906 }
907 }
908
909 /*
910 * Ethernet interface interrupt routine
911 */
912 void
913 se_intr(
914 int unit,
915 spl_t spllevel)
916 {
917 register se_softc_t sc = se_softc[unit];
918 se_reg_t rdp;
919 register struct ifnet *ifp = &sc->is_if;
920 register unsigned short csr;
921
922 #ifdef MAPPED
923 if (se_use_mapped_interface[unit])
924 {
925 SE_intr(unit,spllevel);
926 return;
927 }
928 #endif /*MAPPED*/
929
930 if (se_open_state < 2) { /* Stray, or not open for business */
931 rdp = (sc ? sc->lnregs : (se_reg_t)se_unprobed_addr);
932 *rdp |= LN_CSR0_STOP;
933 wbflush();
934 return;
935 }
936 rdp = sc->lnregs;
937
938 /*
939 * Read the CSR and process any error condition.
940 * Later on, restart the lance by writing back
941 * the CSR (for set-to-clear bits).
942 */
943 csr = *rdp; /* pick up the csr */
944
945 /* drop spurious interrupts */
946 if ((csr & LN_CSR0_INTR) == 0)
947 return;
948
949 #ifdef DECSTATION
950 splx(spllevel); /* drop priority now */
951 #endif /*DECSTATION*/
952 again:
953 /*
954 * Check for errors first
955 */
956 if ( csr & LN_CSR0_ERR ) {
957 if (csr & LN_CSR0_MISS) {
958 /*
959 * Stop the chip to prevent a corrupt packet from
960 * being transmitted. There is a known problem with
961 * missed packet errors causing corrupted data to
962 * be transmitted to the same host as was just
963 * transmitted, with a valid crc appended to the
964 * packet. The only solution is to stop the chip,
965 * which will clear the Lance silo, thus preventing
966 * the corrupt data from being sent.
967 */
968 se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0");
969
970 sc->misscnt++;
971 if (se_verbose) {
972 int me = 0, lance = 0, index;
973 struct se_desc r;
974 for (index = 0; index < NRCV; index++) {
975 (se_sw->desc_copyin)(
976 (vm_offset_t)sc->lnrring[index],
977 (vm_offset_t)&r,
978 sizeof(r));
979 if (r.status & LN_RSTATE_OWN)
980 lance++;
981 else
982 me++;
983 }
984 printf("se%d: missed packet (%d) csr = %x, Lance %x, me %x\n",
985 unit, sc->misscnt, csr, lance, me);
986 }
987 se_restart(ifp);
988 se_init(unit);
989 return;
990 }
991 if (csr & LN_CSR0_BABL) {
992 sc->bablcnt++;
993 if (se_verbose)
994 printf("se%d: xmt timeout (%d)\n",
995 unit, sc->bablcnt);
996 }
997 if (csr & LN_CSR0_MERR) {
998 sc->merrcnt++;
999 printf("se%d: memory error (%d)\n",
1000 unit, sc->merrcnt);
1001
1002 if (((csr & LN_CSR0_RXON) == 0)
1003 || ((csr & LN_CSR0_TXON) == 0)) {
1004 se_restart(ifp);
1005 se_init(unit);
1006 return;
1007 }
1008 }
1009 }
1010
1011 *rdp = LN_CSR0_INEA | (csr & LN_CSR0_WTC);
1012 wbflush();
1013
1014 if ( csr & LN_CSR0_RINT )
1015 se_rint( unit );
1016
1017 if ( csr & LN_CSR0_TINT )
1018 se_tint( unit );
1019
1020 if ((csr = *rdp) & (LN_CSR0_RINT | LN_CSR0_TINT))
1021 goto again;
1022 }
1023
1024 /*
1025 * Handle a transmitter complete interrupt.
1026 */
1027 void
1028 se_tint(int unit)
1029 {
1030 register se_softc_t sc = se_softc[unit];
1031 register index;
1032 register status;
1033 io_req_t request;
1034 struct se_desc r;
1035
1036 /*
1037 * Free up descriptors for all packets in queue for which
1038 * transmission is complete. Start from queue tail, stop at first
1039 * descriptor we do not OWN, or which is in an inconsistent state
1040 * (lance still working).
1041 */
1042
1043 while ((sc->xmt_complete != sc->xmt_last) && (sc->xmt_count > 0)) {
1044
1045 index = sc->xmt_complete;
1046 (se_sw->desc_copyin) ((vm_offset_t)sc->lntring[index],
1047 (vm_offset_t)&r, sizeof(r));
1048 status = r.status;
1049
1050 /*
1051 * Does lance still own it ?
1052 */
1053 if (status & LN_TSTATE_OWN)
1054 break;
1055
1056 /*
1057 * Packet sent allright, release queue slot.
1058 */
1059 request = sc->tpkt[index];
1060 sc->tpkt[index] = (io_req_t) 0;
1061 sc->xmt_complete = ++index & (NXMT - 1);
1062 --sc->xmt_count;
1063
1064 sc->is_if.if_opackets++;
1065 if (status & (LN_TSTATE_DEF|LN_TSTATE_ONE|LN_TSTATE_MORE))
1066 sc->is_if.if_collisions++;
1067
1068 /*
1069 * Check for transmission errors.
1070 */
1071 if (!se_loopback_hack && status & LN_TSTATE_ERR) {
1072 sc->is_if.if_oerrors++;
1073 if (se_verbose)
1074 printf("se%d: xmt error (x%x)\n", unit, r.status2);
1075
1076 if (r.status2 & (LN_TSTATE2_RTRY|LN_TSTATE2_LCOL))
1077 sc->is_if.if_collisions++;
1078
1079 /*
1080 * Restart chip on errors that disable the
1081 * transmitter.
1082 */
1083 iodone(request);
1084 if (r.status2 & LN_TSTATE2_DISABLE) {
1085 register struct ifnet *ifp = &sc->is_if;
1086 se_restart(ifp);
1087 se_init(ifp->if_unit);
1088 return;
1089 }
1090 } else if (request) {
1091 /*
1092 * If this was a broadcast packet loop it back.
1093 * Signal successful transmission of the packet.
1094 */
1095 register struct ether_header *eh;
1096 register int i;
1097
1098 eh = (struct ether_header *) request->io_data;
1099 /* ether broadcast address is in the spec */
1100 for (i = 0; (i < 6) && (eh->ether_dhost[i] == 0xff); i++)
1101 ; /* nop */
1102 /* sending to ourselves makes sense sometimes */
1103 if (i != 6 && se_loopback_hack)
1104 for (i = 0;
1105 (i < 6) && (eh->ether_dhost[i] == sc->is_addr[i]);
1106 i++)
1107 ; /* nop */
1108 if (i == 6)
1109 se_read(sc, 0, request->io_count, request);
1110 iodone(request);
1111 }
1112 }
1113 /*
1114 * Dequeue next transmit request, if any.
1115 */
1116 if (sc->xmt_count <= 0)
1117 se_start(unit);
1118 }
1119
1120 /*
1121 * Handle a receiver complete interrupt.
1122 */
1123 void
1124 se_rint(int unit)
1125 {
1126 register se_softc_t sc = se_softc[unit];
1127 register index, first, len;
1128 unsigned char status, status1;
1129 int ring_cnt;
1130 struct se_desc r;
1131
1132 /*
1133 * Starting from where we left off, look around the receive ring and
1134 * pass on all complete packets.
1135 */
1136
1137 for (;; sc->rcv_last = ++index & (NRCV - 1)) {
1138
1139 /*
1140 * Read in current descriptor
1141 */
1142 read_descriptor:
1143 (se_sw->desc_copyin) ((vm_offset_t)sc->lnrring[sc->rcv_last],
1144 (vm_offset_t)&r, sizeof(r));
1145 status = r.status;
1146 if (status & LN_RSTATE_OWN)
1147 break;
1148 first = index = sc->rcv_last;
1149
1150 /*
1151 * If not the start of a packet, error
1152 */
1153 if (!(status & LN_RSTATE_STP)) {
1154 if (se_verbose)
1155 printf("se%d: Rring #%d, status=%x !STP\n",
1156 unit, index, status);
1157 break;
1158 }
1159 /*
1160 * See if packet is chained (should not) by looking at
1161 * the last descriptor (OWN clear and ENP set).
1162 * Remember the status info in this last descriptor.
1163 */
1164 ring_cnt = 1, status1 = status;
1165 while (((status1 & (LN_RSTATE_ERR | LN_RSTATE_OWN | LN_RSTATE_ENP)) == 0) &&
1166 (ring_cnt++ <= NRCV)) {
1167 struct se_desc r1;
1168 index = (index + 1) & (NRCV - 1);
1169 (se_sw->desc_copyin) ((vm_offset_t)sc->lnrring[index],
1170 (vm_offset_t)&r1, sizeof(r1));
1171 status1 = r1.status;
1172 }
1173
1174 /*
1175 * Chained packet (--> illegally sized!); re-init the
1176 * descriptors involved and ignore this bogus packet. I
1177 * donno how, but it really happens that we get these
1178 * monsters.
1179 */
1180 if (ring_cnt > 1) {
1181 /*
1182 * Return all descriptors to lance
1183 */
1184 se_desc_set_status(sc->lnrring[first], LN_RSTATE_OWN);
1185 while (first != index) {
1186 first = (first + 1) & (NRCV - 1);
1187 se_desc_set_status(sc->lnrring[first], LN_RSTATE_OWN);
1188 }
1189 if ((status1 & LN_RSTATE_ERR) && se_verbose)
1190 printf("se%d: rcv error %x (chained)\n", unit, status1);
1191 continue;
1192 }
1193
1194 /*
1195 * Good packets must be owned by us and have the end of
1196 * packet flag. And nothing else.
1197 */
1198 if ((status & ~LN_RSTATE_STP) == LN_RSTATE_ENP) {
1199 sc->is_if.if_ipackets++;
1200
1201 if ((len = r.message_size) == 0)
1202 /* race seen on pmaxen: the lance
1203 * has not updated the size yet ??
1204 */
1205 goto read_descriptor;
1206 /*
1207 * Drop trailing CRC bytes from len and ship packet
1208 * up
1209 */
1210 se_read(sc, (volatile char*)sc->lnrbuf[first], len-4,0);
1211
1212 /*
1213 * Return descriptor to lance, and move on to next
1214 * packet
1215 */
1216 r.status = LN_RSTATE_OWN;
1217 (se_sw->desc_copyout)((vm_offset_t)&r,
1218 (vm_offset_t)sc->lnrring[first],
1219 sizeof(r));
1220 continue;
1221 }
1222 /*
1223 * Not a good packet, see what is wrong
1224 */
1225 if (status & LN_RSTATE_ERR) {
1226 sc->is_if.if_ierrors++;
1227
1228 if (se_verbose)
1229 printf("se%d: rcv error (x%x)\n", unit, status);
1230
1231 /*
1232 * Return descriptor to lance
1233 */
1234 se_desc_set_status(sc->lnrring[first], LN_RSTATE_OWN);
1235 } else {
1236 /*
1237 * Race condition viz lance, Wait for the next
1238 * interrupt.
1239 */
1240 return;
1241 }
1242 }
1243 }
1244
1245 /*
1246 * Output routine.
1247 * Call common function for wiring memory,
1248 * come back later (to se_start) to get
1249 * things going.
1250 */
1251 io_return_t
1252 se_output(
1253 int dev,
1254 io_req_t ior)
1255 {
1256 return net_write(&se_softc[dev]->is_if, (int(*)())se_start, ior);
1257 }
1258
1259 /*
1260 * Start output on interface.
1261 *
1262 */
1263 void
1264 se_start(int unit)
1265 {
1266 register se_softc_t sc = se_softc[unit];
1267 io_req_t request;
1268 struct se_desc r;
1269 int tlen;
1270 spl_t s;
1271 register int index;
1272
1273 s = splimp();
1274
1275 for (index = sc->xmt_last;
1276 sc->xmt_count < (NXMT - 1);
1277 sc->xmt_last = index = (index + 1) & (NXMT - 1)) {
1278 /*
1279 * Dequeue the next transmit request, if any.
1280 */
1281 IF_DEQUEUE(&sc->is_if.if_snd, request);
1282 if (request == 0) {
1283 /*
1284 * Tell the lance to send the packet now
1285 * instead of waiting until the next 1.6 ms
1286 * poll interval expires.
1287 */
1288 *sc->lnregs = LN_CSR0_TDMD | LN_CSR0_INEA;
1289 splx(s);
1290 return; /* Nothing on the queue */
1291 }
1292
1293 /*
1294 * Keep request around until transmission complete
1295 */
1296 sc->tpkt[index] = request;
1297 tlen = copy_to_lance(request, sc->lntbuf[index]);
1298
1299 /*
1300 * Give away buffer. Must copyin/out, set len,
1301 * and set the OWN flag. We do not do chaining.
1302 */
1303 (se_sw->desc_copyin)((vm_offset_t)sc->lntring[index],
1304 (vm_offset_t)&r, sizeof(r));
1305 r.buffer_size = -(tlen) | 0xf000;
1306 r.status = (LN_TSTATE_OWN | LN_TSTATE_STP | LN_TSTATE_ENP);
1307 (se_sw->desc_copyout)((vm_offset_t)&r,
1308 (vm_offset_t)sc->lntring[index],
1309 sizeof(r));
1310 wbflush();
1311
1312 sc->xmt_count++;
1313 }
1314 /*
1315 * Since we actually have queued new packets, tell
1316 * the chip to rescan the descriptors _now_.
1317 * It is quite unlikely that the ring be filled,
1318 * but if it is .. the more reason to do it!
1319 */
1320 *sc->lnregs = LN_CSR0_TDMD | LN_CSR0_INEA;
1321 splx(s);
1322 }
1323
1324
1325 /*
1326 * Pull a packet off the interface and
1327 * hand it up to the higher levels.
1328 *
1329 * Simulate broadcast packets in software.
1330 */
1331 void
1332 se_read(
1333 register se_softc_t sc,
1334 volatile char *lnrbuf,
1335 int len,
1336 io_req_t loop_back)
1337 {
1338 register struct ifnet *ifp = &sc->is_if;
1339 register ipc_kmsg_t new_kmsg;
1340 char *hdr, *pkt;
1341
1342 if (len <= sizeof(struct ether_header))
1343 return; /* sanity */
1344
1345 /*
1346 * Get a new kmsg to put data into.
1347 */
1348 new_kmsg = net_kmsg_get();
1349 if (new_kmsg == IKM_NULL) {
1350 /*
1351 * No room, drop the packet
1352 */
1353 ifp->if_rcvdrops++;
1354 return;
1355 }
1356
1357 hdr = net_kmsg(new_kmsg)->header;
1358 pkt = net_kmsg(new_kmsg)->packet;
1359
1360 #define OFF0 (sizeof(struct ether_header) - sizeof(struct packet_header))
1361 #define OFF1 (OFF0 & ~3)
1362 if (loop_back) {
1363 bcopy(loop_back->io_data, hdr, sizeof(struct ether_header));
1364 bcopy(loop_back->io_data + OFF0,
1365 pkt, len - OFF0);
1366 } else
1367 copy_from_lance(lnrbuf, len, (struct ether_header*)hdr,
1368 (struct packet_header*)pkt);
1369
1370 /*
1371 * Set up the 'fake' header with length. Type has been left
1372 * in the correct place.
1373 */
1374 len = len - OFF0;
1375 ((struct packet_header *)pkt)->length = len;
1376
1377 /*
1378 * Hand the packet to the network module.
1379 */
1380 net_packet(ifp, new_kmsg, len, ethernet_priority(new_kmsg));
1381 }
1382
1383
1384 /*
1385 * Get a packet out of Lance memory and into main memory.
1386 */
1387 private void
1388 copy_from_lance(
1389 register volatile unsigned char *rbuf,
1390 register unsigned int nbytes,
1391 struct ether_header *hdr,
1392 struct packet_header *pkt)
1393 {
1394 /*
1395 * Read in ethernet header
1396 */
1397 (se_sw->data_copyin) ((vm_offset_t)rbuf, (vm_offset_t)hdr, sizeof(struct ether_header));
1398
1399 nbytes -= sizeof(struct ether_header);
1400 rbuf += (se_sw->mapoffs) (sizeof(struct ether_header));
1401
1402 pkt->type = (unsigned short) hdr->ether_type;
1403
1404 (se_sw->data_copyin) ((vm_offset_t)rbuf, (vm_offset_t)(pkt + 1), nbytes);
1405 }
1406
1407
1408 /*
1409 * Move a packet into Lance space
1410 */
1411 private int
1412 copy_to_lance(
1413 register io_req_t request,
1414 volatile char *sbuf)
1415 {
1416 register unsigned short *dp;
1417 register int len;
1418
1419 dp = (unsigned short *) request->io_data;
1420 len = request->io_count;
1421
1422 if (len > (int)(ETHERMTU + sizeof(struct ether_header))) {
1423 printf("se: truncating HUGE packet\n");
1424 len = ETHERMTU + sizeof(struct ether_header);
1425 }
1426
1427 (se_sw->data_copyout) ((vm_offset_t)dp, (vm_offset_t)sbuf, len);
1428
1429 if (len < LN_MINBUF_NOCH)
1430 /*
1431 * The lance needs at least this much data in a packet. Who
1432 * cares if I send some garbage that was left in the lance
1433 * buffer ? If one can spoof packets then one can spoof
1434 * packets!
1435 */
1436 len = LN_MINBUF_NOCH;
1437 return len;
1438 }
1439
1440 /*
1441 * Reset a descriptor's flags.
1442 * Optionally give the descriptor to the lance
1443 */
1444 private void
1445 se_desc_set_status (
1446 register se_desc_t lndesc,
1447 int val)
1448 {
1449 struct se_desc desc;
1450
1451 (se_sw->desc_copyin) ((vm_offset_t)lndesc, (vm_offset_t)&desc, sizeof(desc));
1452 desc.desc4.bits = 0;
1453 desc.status = val;
1454 (se_sw->desc_copyout) ((vm_offset_t)&desc, (vm_offset_t)lndesc, sizeof(desc));
1455 wbflush();
1456 }
1457
1458 /*
1459 * Set/Get status functions
1460 */
1461 int
1462 se_get_status(
1463 int dev,
1464 dev_flavor_t flavor,
1465 dev_status_t status, /* pointer to OUT array */
1466 natural_t *status_count) /* out */
1467 {
1468 return (net_getstat(&se_softc[dev]->is_if,
1469 flavor, status, status_count));
1470 }
1471
1472 int
1473 se_set_status(
1474 int unit,
1475 dev_flavor_t flavor,
1476 dev_status_t status,
1477 natural_t status_count)
1478 {
1479 register se_softc_t sc;
1480
1481 sc = se_softc[unit];
1482
1483
1484 switch (flavor) {
1485
1486 case NET_STATUS:
1487 break;
1488
1489 case NET_ADDRESS: {
1490
1491 register union ether_cvt {
1492 unsigned char addr[6];
1493 int lwd[2];
1494 } *ec = (union ether_cvt *) status;
1495
1496 if (status_count < sizeof(*ec) / sizeof(int))
1497 return (D_INVALID_SIZE);
1498
1499 ec->lwd[0] = ntohl(ec->lwd[0]);
1500 ec->lwd[1] = ntohl(ec->lwd[1]);
1501
1502 se_setaddr(ec->addr, unit);
1503
1504 break;
1505 }
1506
1507 default:
1508 return (D_INVALID_OPERATION);
1509 }
1510
1511 return (D_SUCCESS);
1512 }
1513
1514
1515 /*
1516 * Install new filter.
1517 * Nothing special needs to be done here.
1518 */
1519 io_return_t
1520 se_setinput(
1521 int dev,
1522 ipc_port_t receive_port,
1523 int priority,
1524 filter_t *filter,
1525 natural_t filter_count)
1526 {
1527 return (net_set_filter(&se_softc[dev]->is_if,
1528 receive_port, priority,
1529 filter, filter_count));
1530 }
1531
1532 /*
1533 * Allocate and initialize a ring descriptor.
1534 * Allocates a buffer from the lance memory and writes a descriptor
1535 * for that buffer to the host virtual address LNDESC.
1536 */
1537 private volatile long
1538 *se_desc_alloc (
1539 register se_softc_t sc,
1540 register se_desc_t lndesc)
1541 {
1542 register vm_offset_t dp; /* data pointer */
1543 struct se_desc desc;
1544
1545 /*
1546 * Allocate buffer in lance space
1547 */
1548 dp = se_malloc(sc, LN_BUFFER_SIZE);
1549
1550 /*
1551 * Build a descriptor pointing to it
1552 */
1553 desc.addr_low = Addr_lo(Lmem(dp));
1554 desc.addr_hi = Addr_hi(Lmem(dp));
1555 desc.status = 0;
1556 desc.buffer_size = -LN_BUFFER_SIZE;
1557 desc.desc4.bits = 0;
1558
1559 /*
1560 * Copy the descriptor to lance space
1561 */
1562 (se_sw->desc_copyout) ((vm_offset_t)&desc, (vm_offset_t)lndesc, sizeof(desc));
1563 wbflush();
1564
1565 return (volatile long *) Hmem(dp);
1566 }
1567
1568 /*
1569 * Allocate a chunk of lance RAM buffer. Since we never
1570 * give lance RAM buffer memory back, we'll just step up the
1571 * byte-count on a per-unit basis.
1572 *
1573 * The return value is an index into the lance memory, which can be
1574 * passed with Hmem() and Lmem() to get the host and chip virtual addresses.
1575 */
1576 private vm_offset_t
1577 se_malloc(
1578 se_softc_t sc,
1579 int size)
1580 {
1581 register vm_offset_t ret;
1582
1583 /*
1584 * On first call, zero lance memory
1585 */
1586 if (sc->lnsbrk == 0)
1587 (se_sw->bzero) (Hmem(0), LN_MEMORY_SIZE);
1588
1589 /*
1590 * Start out on the first double longword boundary
1591 * (this accomodates some machines, with minimal loss)
1592 */
1593 if (sc->lnsbrk & 0xf)
1594 sc->lnsbrk = (sc->lnsbrk + 0x10) & ~0xf;
1595
1596 ret = sc->lnsbrk;
1597 sc->lnsbrk += size;
1598
1599 if (sc->lnsbrk > LN_MEMORY_SIZE)
1600 panic("se_malloc");
1601
1602 return ret;
1603 }
1604
1605 #endif NLN > 0
Cache object: a6d447fb7a59116d4afd126abafb9521
|