if_tl.c revision 1.6 1 /* $NetBSD: if_tl.c,v 1.6 1997/11/18 12:26:09 bouyer Exp $ */
2
3 /*
4 * Copyright (c) 1997 Manuel Bouyer. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Manuel Bouyer.
17 * 4. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * Texas Instruments ThunderLAN ethernet controller
34 * ThunderLAN Programmer's Guide (TI Literature Number SPWU013A)
35 * available from www.ti.com
36 */
37
38 #undef TLDEBUG
39 #define TL_PRIV_STATS
40 #undef TLDEBUG_RX
41 #undef TLDEBUG_TX
42 #undef TLDEBUG_ADDR
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/mbuf.h>
47 #include <sys/protosw.h>
48 #include <sys/socket.h>
49 #include <sys/ioctl.h>
50 #include <sys/errno.h>
51 #include <sys/malloc.h>
52 #include <sys/kernel.h>
53 #include <sys/proc.h> /* only for declaration of wakeup() used by vm.h */
54 #include <sys/device.h>
55
56 #include <net/if.h>
57 #if defined(SIOCSIFMEDIA)
58 #include <net/if_media.h>
59 #endif
60 #include <net/if_types.h>
61 #include <net/if_dl.h>
62 #include <net/route.h>
63 #include <net/netisr.h>
64
65 #include "bpfilter.h"
66 #if NBPFILTER > 0
67 #include <net/bpf.h>
68 #include <net/bpfdesc.h>
69 #endif
70
71 #ifdef INET
72 #include <netinet/in.h>
73 #include <netinet/in_systm.h>
74 #include <netinet/in_var.h>
75 #include <netinet/ip.h>
76 #endif
77
78 #ifdef NS
79 #include <netns/ns.h>
80 #include <netns/ns_if.h>
81 #endif
82
83 #include <vm/vm.h>
84 #include <vm/vm_param.h>
85 #include <vm/vm_kern.h>
86
87 #if defined(__NetBSD__)
88 #include <net/if_ether.h>
89 #if defined(INET)
90 #include <netinet/if_inarp.h>
91 #endif
92
93 #include <machine/bus.h>
94 #include <machine/intr.h>
95
96 #include <dev/pci/pcireg.h>
97 #include <dev/pci/pcivar.h>
98 #include <dev/pci/pcidevs.h>
99 #include <dev/i2c/i2c_bus.h>
100 #include <dev/i2c/i2c_eeprom.h>
101 #include <dev/mii/mii_adapter.h>
102 #include <dev/mii/mii_adapters_id.h>
103 #include <dev/pci/if_tlregs.h>
104 #endif /* __NetBSD__ */
105
106 /* number of transmit/receive buffers */
107 #ifndef TL_NBUF
108 #define TL_NBUF 10
109 #endif
110
111 /* number of seconds the link can be idle */
112 #ifndef TL_IDLETIME
113 #define TL_IDLETIME 10
114 #endif
115
116 struct tl_softc {
117 struct device sc_dev; /* base device */
118 bus_space_tag_t tl_bustag;
119 bus_space_handle_t tl_bushandle; /* CSR region handle */
120 void* tl_ih;
121 struct ethercom tl_ec;
122 u_int8_t tl_enaddr[ETHER_ADDR_LEN]; /* hardware adress */
123 struct ifmedia tl_ifmedia;
124 u_int16_t tl_flags;
125 #define TL_IFACT 0x0001 /* chip has interface activity */
126 u_int8_t tl_lasttx; /* we were without input this many seconds */
127 i2c_adapter_t i2cbus; /* i2c bus, for eeprom */
128 mii_data_t mii; /* mii bus */
129 struct Rx_list *Rx_list; /* Receive and transmit lists */
130 struct Tx_list *Tx_list;
131 struct Rx_list *active_Rx, *last_Rx;
132 struct Tx_list *active_Tx, *last_Tx;
133 struct Tx_list *Free_Tx;
134 int opkt; /* used to detect link up/down for AUI/BNC */
135 int stats_exesscoll; /* idem */
136 #ifdef TL_PRIV_STATS
137 int ierr_overr;
138 int ierr_code;
139 int ierr_crc;
140 int ierr_nomem;
141 int oerr_underr;
142 int oerr_deffered;
143 int oerr_coll;
144 int oerr_multicoll;
145 int oerr_latecoll;
146 int oerr_exesscoll;
147 int oerr_carrloss;
148 int oerr_mcopy;
149 #endif
150 };
151 #define tl_if tl_ec.ec_if
152 #define tl_bpf tl_if.if_bpf
153
154 typedef struct tl_softc tl_softc_t;
155 typedef u_long ioctl_cmd_t;
156
157 #define TL_HR_READ(sc, reg) \
158 bus_space_read_4(sc->tl_bustag, sc->tl_bushandle, (reg))
159 #define TL_HR_READ_BYTE(sc, reg) \
160 bus_space_read_1(sc->tl_bustag, sc->tl_bushandle, (reg))
161 #define TL_HR_WRITE(sc, reg, data) \
162 bus_space_write_4(sc->tl_bustag, sc->tl_bushandle, (reg), (data))
163 #define TL_HR_WRITE_BYTE(sc, reg, data) \
164 bus_space_write_1(sc->tl_bustag, sc->tl_bushandle, (reg), (data))
165 #define ETHER_MIN_TX (ETHERMIN + sizeof(struct ether_header))
166
167 static int tl_pci_match __P((struct device *, void *, void *));
168 static void tl_pci_attach __P((struct device *, struct device *, void *));
169 static int tl_intr __P((void *));
170
171 static int tl_ifioctl __P((struct ifnet *, ioctl_cmd_t, caddr_t));
172 static int tl_mediachange __P((struct ifnet *));
173 static void tl_mediastatus __P((struct ifnet *, struct ifmediareq *));
174 static void tl_ifwatchdog __P((struct ifnet *));
175 static void tl_shutdown __P((void*));
176
177 static void tl_ifstart __P((struct ifnet *));
178 static void tl_reset __P((tl_softc_t*));
179 static int tl_init __P((tl_softc_t*));
180 static void tl_restart __P((void *));
181 static int tl_add_RxBuff __P((struct Rx_list*, struct mbuf*));
182 static void tl_read_stats __P((tl_softc_t*));
183 static void tl_ticks __P((void*));
184 static int tl_multicast_hash __P((u_int8_t*));
185 static void tl_addr_filter __P((tl_softc_t*));
186
187 static u_int32_t tl_intreg_read __P((tl_softc_t*, u_int32_t));
188 static void tl_intreg_write __P((tl_softc_t*, u_int32_t, u_int32_t));
189 static u_int8_t tl_intreg_read_byte __P((tl_softc_t*, u_int32_t));
190 static void tl_intreg_write_byte __P((tl_softc_t*, u_int32_t, u_int8_t));
191
192
193 #if defined(TLDEBUG_RX)
194 static void ether_printheader __P((struct ether_header*));
195 #endif
196
197 void tl_mii_set __P((void*, u_int8_t));
198 void tl_mii_clr __P((void*, u_int8_t));
199 int tl_mii_read __P((void*, u_int8_t));
200
201 void tl_i2c_set __P((void*, u_int8_t));
202 void tl_i2c_clr __P((void*, u_int8_t));
203 int tl_i2c_read __P((void*, u_int8_t));
204
205 static __inline void netsio_clr __P((tl_softc_t*, u_int8_t));
206 static __inline void netsio_set __P((tl_softc_t*, u_int8_t));
207 static __inline u_int8_t netsio_read __P((tl_softc_t*, u_int8_t));
208 static __inline void netsio_clr(sc, bits)
209 tl_softc_t* sc;
210 u_int8_t bits;
211 {
212 tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetSio,
213 tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetSio) & (~bits));
214 }
215 static __inline void netsio_set(sc, bits)
216 tl_softc_t* sc;
217 u_int8_t bits;
218 {
219 tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetSio,
220 tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetSio) | bits);
221 }
222 static __inline u_int8_t netsio_read(sc, bits)
223 tl_softc_t* sc;
224 u_int8_t bits;
225 {
226 return (tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetSio) & bits);
227 }
228
229 struct cfattach tl_ca = {
230 sizeof(tl_softc_t), tl_pci_match, tl_pci_attach
231 };
232
233 struct cfdriver tl_cd = {
234 0, "tl", DV_IFNET
235 };
236
237 struct tl_product_desc {
238 u_int32_t tp_product;
239 u_int32_t tp_adapter;
240 const char *tp_desc;
241 };
242
243 const struct tl_product_desc tl_compaq_products[] = {
244 { PCI_PRODUCT_COMPAQ_N100TX, COMPAQ_NETLIGENT_10_100,
245 "Compaq Netelligent 10/100 TX" },
246 { PCI_PRODUCT_COMPAQ_N10T, COMPAQ_NETLIGENT_10,
247 "Compaq Netelligent 10 T" },
248 { PCI_PRODUCT_COMPAQ_IntNF3P, COMPAQ_INT_NETFLEX,
249 "Compaq Integrated NetFlex 3/P" },
250 { PCI_PRODUCT_COMPAQ_IntPL100TX, COMPAQ_INT_NETLIGENT_10_100,
251 "Compaq ProLiant Integrated Netelligent 10/100 TX" },
252 { PCI_PRODUCT_COMPAQ_DPNet100TX, COMPAQ_DUAL_NETLIGENT_10_100,
253 "Compaq Dual Port Netelligent 10/100 TX" },
254 { PCI_PRODUCT_COMPAQ_DP4000, COMPAQ_DSKP4000,
255 "Compaq Deskpro 4000 5233MMX" },
256 { PCI_PRODUCT_COMPAQ_NF3P_BNC, COMPAQ_NETFLEX_BNC,
257 "Compaq NetFlex 3/P w/ BNC" },
258 { PCI_PRODUCT_COMPAQ_NF3P, COMPAQ_NETFLEX,
259 "Compaq NetFlex 3/P" },
260 { 0, 0, NULL },
261 };
262
263 const struct tl_product_desc tl_ti_products[] = {
264 { PCI_PRODUCT_TI_TLAN, TI_TLAN,
265 "Texas Instruments ThunderLAN" },
266 { 0, 0, NULL },
267 };
268
269 struct tl_vendor_desc {
270 u_int32_t tv_vendor;
271 const struct tl_product_desc *tv_products;
272 };
273
274 const struct tl_vendor_desc tl_vendors[] = {
275 { PCI_VENDOR_COMPAQ, tl_compaq_products },
276 { PCI_VENDOR_TI, tl_ti_products },
277 { 0, NULL },
278 };
279
280 const struct tl_product_desc *tl_lookup_product __P((u_int32_t));
281
282 const struct tl_product_desc *
283 tl_lookup_product(id)
284 u_int32_t id;
285 {
286 const struct tl_product_desc *tp;
287 const struct tl_vendor_desc *tv;
288
289 for (tv = tl_vendors; tv->tv_products != NULL; tv++)
290 if (PCI_VENDOR(id) == tv->tv_vendor)
291 break;
292
293 if ((tp = tv->tv_products) == NULL)
294 return (NULL);
295
296 for (; tp->tp_desc != NULL; tp++)
297 if (PCI_PRODUCT(id) == tp->tp_product)
298 break;
299
300 if (tp->tp_desc == NULL)
301 return (NULL);
302
303 return (tp);
304 }
305
306 static char *nullbuf = NULL;
307
308 static int
309 tl_pci_match(parent, match, aux)
310 struct device *parent;
311 void *match;
312 void *aux;
313 {
314 struct pci_attach_args *pa = (struct pci_attach_args *) aux;
315
316 if (tl_lookup_product(pa->pa_id) != NULL)
317 return (1);
318
319 return (0);
320 }
321
322 static void
323 tl_pci_attach(parent, self, aux)
324 struct device * parent;
325 struct device * self;
326 void * aux;
327 {
328 tl_softc_t *sc = (tl_softc_t *)self;
329 struct pci_attach_args * const pa = (struct pci_attach_args *) aux;
330 const struct tl_product_desc *tp;
331 struct ifnet * const ifp = &sc->tl_if;
332 bus_space_tag_t iot, memt;
333 bus_space_handle_t ioh, memh;
334 pci_intr_handle_t intrhandle;
335 const char *intrstr;
336 int i, tmp, ioh_valid, memh_valid;
337 pcireg_t csr;
338
339 printf("\n");
340
341 /* Map the card space. */
342 ioh_valid = (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
343 &iot, &ioh, NULL, NULL) == 0);
344 memh_valid = (pci_mapreg_map(pa, PCI_CBMA,
345 PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
346 0, &memt, &memh, NULL, NULL) == 0);
347
348 #if 1
349 /*
350 * XXX HACK! Due to a bug in a previous revision of this driver,
351 * XXX i/o space was always selected. Now that this bug is fixed,
352 * XXX we discover that memory mapped use fails on at least one
353 * XXX ThunderLAN variant - the built-in Ethernet on TI Travelmate
354 * XXX docking stations. We hack around this by "prefering" i/o
355 * XXX access for now.
356 */
357 if (ioh_valid) {
358 sc->tl_bustag = iot;
359 sc->tl_bushandle = ioh;
360 } else if (memh_valid) {
361 sc->tl_bustag = memt;
362 sc->tl_bushandle = memh;
363 } else {
364 printf("%s: unable to map device registers\n",
365 sc->sc_dev.dv_xname);
366 return;
367 }
368 #else
369 if (memh_valid) {
370 sc->tl_bustag = memt;
371 sc->tl_bushandle = memh;
372 } else if (ioh_valid) {
373 sc->tl_bustag = iot;
374 sc->tl_bushandle = ioh;
375 } else {
376 printf("%s: unable to map device registers\n",
377 sc->sc_dev.dv_xname);
378 return;
379 }
380 #endif
381
382 /* Enable the device. */
383 csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
384 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
385 csr | PCI_COMMAND_MASTER_ENABLE);
386
387 tp = tl_lookup_product(pa->pa_id);
388 if (tp == NULL)
389 panic("tl_pci_attach: impossible");
390
391 printf("%s: %s\n", sc->sc_dev.dv_xname, tp->tp_desc);
392 sc->mii.adapter_id = tp->tp_adapter;
393
394 tl_reset(sc);
395
396 /* fill in the i2c struct */
397 sc->i2cbus.adapter_softc = sc;
398 sc->i2cbus.set_bit = tl_i2c_set;
399 sc->i2cbus.clr_bit = tl_i2c_clr;
400 sc->i2cbus.read_bit = tl_i2c_read;
401
402 #ifdef TLDEBUG
403 printf("default values of INTreg: 0x%x\n",
404 tl_intreg_read(sc, TL_INT_Defaults));
405 #endif
406
407 /* read mac addr */
408 for (i=0; i<ETHER_ADDR_LEN; i++) {
409 tmp = i2c_eeprom_read(&sc->i2cbus, 0x83 + i);
410 if (tmp < 0) {
411 printf("%s: error reading Ethernet adress\n",
412 sc->sc_dev.dv_xname);
413 return;
414 } else {
415 sc->tl_enaddr[i] = tmp;
416 }
417 }
418 printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
419 ether_sprintf(sc->tl_enaddr));
420
421 /* Map and establish interrupts */
422 if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
423 pa->pa_intrline, &intrhandle)) {
424 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
425 return;
426 }
427 intrstr = pci_intr_string(pa->pa_pc, intrhandle);
428 sc->tl_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_NET,
429 tl_intr, sc);
430 if (sc->tl_ih == NULL) {
431 printf("%s: couldn't establish interrupt",
432 sc->sc_dev.dv_xname);
433 if (intrstr != NULL)
434 printf(" at %s", intrstr);
435 printf("\n");
436 return;
437 }
438 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
439
440 /*
441 * Add shutdown hook so that DMA is disabled prior to reboot. Not
442 * doing do could allow DMA to corrupt kernel memory during the
443 * reboot before the driver initializes.
444 */
445 (void) shutdownhook_establish(tl_shutdown, sc);
446
447 sc->mii.adapter_softc = sc;
448 sc->mii.mii_setbit = tl_mii_set;
449 sc->mii.mii_clrbit = tl_mii_clr;
450 sc->mii.mii_readbit = tl_mii_read;
451 sc->mii.mii_readreg = NULL; /* Let generic MII function handle that */
452 sc->mii.mii_writereg = NULL;
453 if (config_found(self, (void*)&sc->mii, NULL) == NULL) {
454 printf("%s: no mii configured\n", sc->sc_dev.dv_xname);
455 return;
456 }
457
458 ifmedia_init(&sc->tl_ifmedia, 0, tl_mediachange, tl_mediastatus);
459 mii_media_add(&sc->tl_ifmedia, &sc->mii);
460 ifmedia_set(&sc->tl_ifmedia, IFM_ETHER | IFM_NONE);
461
462 bcopy(sc->sc_dev.dv_xname, sc->tl_if.if_xname, IFNAMSIZ);
463 sc->tl_if.if_softc = sc;
464 ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST;
465 ifp->if_ioctl = tl_ifioctl;
466 ifp->if_start = tl_ifstart;
467 ifp->if_watchdog = tl_ifwatchdog;
468 ifp->if_timer = 0;
469 if_attach(ifp);
470 ether_ifattach(&(sc)->tl_if, (sc)->tl_enaddr);
471 #if NBPFILTER > 0
472 bpfattach(&sc->tl_bpf, &sc->tl_if, DLT_EN10MB,
473 sizeof(struct ether_header));
474 #endif
475 sc->mii.mii_media_active = IFM_NONE;
476 }
477
478 static void
479 tl_reset(sc)
480 tl_softc_t *sc;
481 {
482 int i;
483
484 /* read stats */
485 if (sc->tl_if.if_flags & IFF_RUNNING) {
486 untimeout(tl_ticks, sc);
487 tl_read_stats(sc);
488 }
489 /* Reset adapter */
490 TL_HR_WRITE(sc, TL_HOST_CMD,
491 TL_HR_READ(sc, TL_HOST_CMD) | HOST_CMD_Ad_Rst);
492 DELAY(100000);
493 /* Disable interrupts */
494 TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_IntOff);
495 /* setup aregs & hash */
496 for (i = TL_INT_Areg0; i <= TL_INT_HASH2; i = i + 4)
497 tl_intreg_write(sc, i, 0);
498 #ifdef TLDEBUG_ADDR
499 printf("Areg & hash registers: \n");
500 for (i = TL_INT_Areg0; i <= TL_INT_HASH2; i = i + 4)
501 printf(" reg %x: %x\n", i, tl_intreg_read(sc, i));
502 #endif
503 /* Setup NetConfig */
504 tl_intreg_write(sc, TL_INT_NetConfig,
505 TL_NETCONFIG_1F | TL_NETCONFIG_1chn | TL_NETCONFIG_PHY_EN);
506 /* Bsize: accept default */
507 /* TX commit in Acommit: accept default */
508 /* Load Ld_tmr and Ld_thr */
509 /* Ld_tmr = 3 */
510 TL_HR_WRITE(sc, TL_HOST_CMD, 0x3 | HOST_CMD_LdTmr);
511 /* Ld_thr = 0 */
512 TL_HR_WRITE(sc, TL_HOST_CMD, 0x0 | HOST_CMD_LdThr);
513 /* Unreset MII */
514 netsio_set(sc, TL_NETSIO_NMRST);
515 DELAY(100000);
516 sc->mii.mii_media_status &= ~IFM_ACTIVE;
517 sc->tl_flags = 0;
518 sc->opkt = 0;
519 sc->stats_exesscoll = 0;
520 }
521
522 static void tl_shutdown(v)
523 void *v;
524 {
525 tl_softc_t *sc = v;
526 struct Tx_list *Tx;
527 int i;
528
529 if ((sc->tl_if.if_flags & IFF_RUNNING) == 0)
530 return;
531 /* disable interrupts */
532 TL_HR_WRITE(sc, TL_HOST_CMD,
533 HOST_CMD_IntOff);
534 /* stop TX and RX channels */
535 TL_HR_WRITE(sc, TL_HOST_CMD,
536 HOST_CMD_STOP | HOST_CMD_RT | HOST_CMD_Nes);
537 TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_STOP);
538 DELAY(100000);
539
540 /* stop statistics reading loop, read stats */
541 untimeout(tl_ticks, sc);
542 tl_read_stats(sc);
543
544 /* deallocate memory allocations */
545 for (i=0; i< TL_NBUF; i++) {
546 if (sc->Rx_list[i].m)
547 m_freem(sc->Rx_list[i].m);
548 sc->Rx_list[i].m = NULL;
549 }
550 free(sc->Rx_list, M_DEVBUF);
551 sc->Rx_list = NULL;
552 while ((Tx = sc->active_Tx) != NULL) {
553 Tx->hw_list.stat = 0;
554 m_freem(Tx->m);
555 sc->active_Tx = Tx->next;
556 Tx->next = sc->Free_Tx;
557 sc->Free_Tx = Tx;
558 }
559 sc->last_Tx = NULL;
560 free(sc->Tx_list, M_DEVBUF);
561 sc->Tx_list = NULL;
562 sc->tl_if.if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
563 sc->mii.mii_media_status &= ~IFM_ACTIVE;
564 sc->tl_flags = 0;
565 }
566
567 static void tl_restart(v)
568 void *v;
569 {
570 tl_init(v);
571 }
572
573 static int tl_init(sc)
574 tl_softc_t *sc;
575 {
576 struct ifnet *ifp = &sc->tl_if;
577 int i, s;
578
579 s = splimp();
580 /* cancel any pending IO */
581 tl_shutdown(sc);
582 tl_reset(sc);
583 if ((sc->tl_if.if_flags & IFF_UP) == 0) {
584 splx(s);
585 return 0;
586 }
587 /* Set various register to reasonable value */
588 /* setup NetCmd in promisc mode if needed */
589 i = (ifp->if_flags & IFF_PROMISC) ? TL_NETCOMMAND_CAF : 0;
590 tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetCmd,
591 TL_NETCOMMAND_NRESET | TL_NETCOMMAND_NWRAP | i);
592 /* Max receive size : MCLBYTES */
593 tl_intreg_write_byte(sc, TL_INT_MISC + TL_MISC_MaxRxL, MCLBYTES & 0xff);
594 tl_intreg_write_byte(sc, TL_INT_MISC + TL_MISC_MaxRxH,
595 (MCLBYTES >> 8) & 0xff);
596
597 /* init MAC addr */
598 for (i = 0; i < ETHER_ADDR_LEN; i++)
599 tl_intreg_write_byte(sc, TL_INT_Areg0 + i , sc->tl_enaddr[i]);
600 /* add multicast filters */
601 tl_addr_filter(sc);
602 #ifdef TLDEBUG_ADDR
603 printf("Wrote Mac addr, Areg & hash registers are now: \n");
604 for (i = TL_INT_Areg0; i <= TL_INT_HASH2; i = i + 4)
605 printf(" reg %x: %x\n", i, tl_intreg_read(sc, i));
606 #endif
607
608 /* Pre-allocate receivers mbuf, make the lists */
609 sc->Rx_list = malloc(sizeof(struct Rx_list) * TL_NBUF, M_DEVBUF, M_NOWAIT);
610 sc->Tx_list = malloc(sizeof(struct Tx_list) * TL_NBUF, M_DEVBUF, M_NOWAIT);
611 if (sc->Rx_list == NULL || sc->Tx_list == NULL) {
612 printf("%s: out of memory for lists\n", sc->sc_dev.dv_xname);
613 sc->tl_if.if_flags &= ~IFF_UP;
614 splx(s);
615 return ENOMEM;
616 }
617 for (i=0; i< TL_NBUF; i++) {
618 if(tl_add_RxBuff(&sc->Rx_list[i], NULL) == 0) {
619 printf("%s: out of mbuf for receive list\n", sc->sc_dev.dv_xname);
620 sc->tl_if.if_flags &= ~IFF_UP;
621 splx(s);
622 return ENOMEM;
623 }
624 if (i > 0) { /* chain the list */
625 sc->Rx_list[i-1].next = &sc->Rx_list[i];
626 sc->Rx_list[i-1].hw_list.fwd = vtophys(&sc->Rx_list[i].hw_list);
627 #ifdef DIAGNOSTIC
628 if (sc->Rx_list[i-1].hw_list.fwd & 0x7)
629 printf("%s: physical addr 0x%x of list not properly aligned\n",
630 sc->sc_dev.dv_xname, sc->Rx_list[i-1].hw_list.fwd);
631 #endif
632 sc->Tx_list[i-1].next = &sc->Tx_list[i];
633 }
634 }
635 sc->Rx_list[TL_NBUF-1].next = NULL;
636 sc->Rx_list[TL_NBUF-1].hw_list.fwd = 0;
637 sc->Tx_list[TL_NBUF-1].next = NULL;
638
639 sc->active_Rx = &sc->Rx_list[0];
640 sc->last_Rx = &sc->Rx_list[TL_NBUF-1];
641 sc->active_Tx = sc->last_Tx = NULL;
642 sc->Free_Tx = &sc->Tx_list[0];
643
644 if (nullbuf == NULL)
645 nullbuf = malloc(ETHER_MIN_TX, M_DEVBUF, M_NOWAIT);
646 if (nullbuf == NULL) {
647 printf("%s: can't allocate space for pad buffer\n",
648 sc->sc_dev.dv_xname);
649 sc->tl_if.if_flags &= ~IFF_UP;
650 splx(s);
651 return ENOMEM;
652 }
653 bzero(nullbuf, ETHER_MIN_TX);
654
655 /* set media if needed */
656 if (IFM_SUBTYPE(sc->mii.mii_media_active) != IFM_NONE) {
657 mii_mediachg(&sc->mii);
658 }
659
660 /* start ticks calls */
661 timeout(tl_ticks, sc, hz);
662 /* write adress of Rx list and enable interrupts */
663 TL_HR_WRITE(sc, TL_HOST_CH_PARM, vtophys(&sc->Rx_list[0].hw_list));
664 TL_HR_WRITE(sc, TL_HOST_CMD,
665 HOST_CMD_GO | HOST_CMD_RT | HOST_CMD_Nes | HOST_CMD_IntOn);
666 sc->tl_if.if_flags |= IFF_RUNNING;
667 sc->tl_if.if_flags &= ~IFF_OACTIVE;
668 return 0;
669 }
670
671
672 static u_int32_t
673 tl_intreg_read(sc, reg)
674 tl_softc_t *sc;
675 u_int32_t reg;
676 {
677 TL_HR_WRITE(sc, TL_HOST_INTR_DIOADR, reg & TL_HOST_DIOADR_MASK);
678 return TL_HR_READ(sc, TL_HOST_DIO_DATA);
679 }
680
681 static u_int8_t
682 tl_intreg_read_byte(sc, reg)
683 tl_softc_t *sc;
684 u_int32_t reg;
685 {
686 TL_HR_WRITE(sc, TL_HOST_INTR_DIOADR,
687 (reg & (~0x07)) & TL_HOST_DIOADR_MASK);
688 return TL_HR_READ_BYTE(sc, TL_HOST_DIO_DATA + (reg & 0x07));
689 }
690
691 static void
692 tl_intreg_write(sc, reg, val)
693 tl_softc_t *sc;
694 u_int32_t reg;
695 u_int32_t val;
696 {
697 TL_HR_WRITE(sc, TL_HOST_INTR_DIOADR, reg & TL_HOST_DIOADR_MASK);
698 TL_HR_WRITE(sc, TL_HOST_DIO_DATA, val);
699 }
700
701 static void
702 tl_intreg_write_byte(sc, reg, val)
703 tl_softc_t *sc;
704 u_int32_t reg;
705 u_int8_t val;
706 {
707 TL_HR_WRITE(sc, TL_HOST_INTR_DIOADR,
708 (reg & (~0x03)) & TL_HOST_DIOADR_MASK);
709 TL_HR_WRITE_BYTE(sc, TL_HOST_DIO_DATA + (reg & 0x03), val);
710 }
711
712 void tl_mii_set(v, bit)
713 void *v;
714 u_int8_t bit;
715 {
716 tl_softc_t *sc = v;
717
718 switch (bit) {
719 case MII_DATA:
720 netsio_set(sc, TL_NETSIO_MDATA);
721 break;
722 case MII_CLOCK:
723 netsio_set(sc, TL_NETSIO_MCLK);
724 break;
725 case MII_TXEN:
726 netsio_set(sc, TL_NETSIO_MTXEN);
727 break;
728 default:
729 printf("tl_mii_set: unknown bit %d\n", bit);
730 }
731 }
732
733 void tl_mii_clr(v, bit)
734 void *v;
735 u_int8_t bit;
736 {
737 tl_softc_t *sc = v;
738
739 switch (bit) {
740 case MII_DATA:
741 netsio_clr(sc, TL_NETSIO_MDATA);
742 break;
743 case MII_CLOCK:
744 netsio_clr(sc, TL_NETSIO_MCLK);
745 break;
746 case MII_TXEN:
747 netsio_clr(sc, TL_NETSIO_MTXEN);
748 break;
749 default:
750 printf("tl_mii_clr: unknown bit %d\n", bit);
751 }
752 return;
753 }
754
755 int tl_mii_read(v, bit)
756 void *v;
757 u_int8_t bit;
758 {
759 tl_softc_t *sc = v;
760
761 switch (bit) {
762 case MII_DATA:
763 return netsio_read(sc, TL_NETSIO_MDATA);
764 break;
765 case MII_CLOCK:
766 return netsio_read(sc, TL_NETSIO_MCLK);
767 break;
768 case MII_TXEN:
769 return netsio_read(sc, TL_NETSIO_MTXEN);
770 break;
771 default:
772 printf("tl_mii_read: unknown bit %d\n", bit);
773 return -1;
774 }
775 }
776
777 void tl_i2c_set(v, bit)
778 void *v;
779 u_int8_t bit;
780 {
781 tl_softc_t *sc = v;
782
783 switch (bit) {
784 case I2C_DATA:
785 netsio_set(sc, TL_NETSIO_EDATA);
786 break;
787 case I2C_CLOCK:
788 netsio_set(sc, TL_NETSIO_ECLOCK);
789 break;
790 case I2C_TXEN:
791 netsio_set(sc, TL_NETSIO_ETXEN);
792 break;
793 default:
794 printf("tl_i2c_set: unknown bit %d\n", bit);
795 }
796 return;
797 }
798
799 void tl_i2c_clr(v, bit)
800 void *v;
801 u_int8_t bit;
802 {
803 tl_softc_t *sc = v;
804
805 switch (bit) {
806 case I2C_DATA:
807 netsio_clr(sc, TL_NETSIO_EDATA);
808 break;
809 case I2C_CLOCK:
810 netsio_clr(sc, TL_NETSIO_ECLOCK);
811 break;
812 case I2C_TXEN:
813 netsio_clr(sc, TL_NETSIO_ETXEN);
814 break;
815 default:
816 printf("tl_i2c_clr: unknown bit %d\n", bit);
817 }
818 return;
819 }
820
821 int tl_i2c_read(v, bit)
822 void *v;
823 u_int8_t bit;
824 {
825 tl_softc_t *sc = v;
826
827 switch (bit) {
828 case I2C_DATA:
829 return netsio_read(sc, TL_NETSIO_EDATA);
830 break;
831 case I2C_CLOCK:
832 return netsio_read(sc, TL_NETSIO_ECLOCK);
833 break;
834 case I2C_TXEN:
835 return netsio_read(sc, TL_NETSIO_ETXEN);
836 break;
837 default:
838 printf("tl_i2c_read: unknown bit %d\n", bit);
839 return -1;
840 }
841 }
842
843 static int
844 tl_intr(v)
845 void *v;
846 {
847 tl_softc_t *sc = v;
848 struct ifnet *ifp = &sc->tl_if;
849 struct Rx_list *Rx;
850 struct Tx_list *Tx;
851 struct mbuf *m;
852 u_int32_t int_type, int_reg;
853 int ack = 0;
854 int size;
855
856 int_reg = TL_HR_READ(sc, TL_HOST_INTR_DIOADR);
857 int_type = int_reg & TL_INTR_MASK;
858 if (int_type == 0)
859 return 0;
860 #if defined(TLDEBUG_RX) || defined(TLDEBUG_TX)
861 printf("%s: interrupt type %x, intr_reg %x\n", sc->sc_dev.dv_xname,
862 int_type, int_reg);
863 #endif
864 /* disable interrupts */
865 TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_IntOff);
866 switch(int_type & TL_INTR_MASK) {
867 case TL_INTR_RxEOF:
868 while(sc->active_Rx->hw_list.stat & TL_RX_CSTAT_CPLT) {
869 /* dequeue and requeue at end of list */
870 ack++;
871 Rx = sc->active_Rx;
872 sc->active_Rx = Rx->next;
873 m = Rx->m;
874 size = Rx->hw_list.stat >> 16;
875 #ifdef TLDEBUG_RX
876 printf("tl_intr: RX list complete, Rx %p, size=%d\n", Rx, size);
877 #endif
878 if (tl_add_RxBuff(Rx, m ) == 0) {
879 /* No new mbuf, reuse the same. This means that this packet
880 is lost */
881 m = NULL;
882 #ifdef TL_PRIV_STATS
883 sc->ierr_nomem++;
884 #endif
885 #ifdef TLDEBUG
886 printf("%s: out of mbuf, lost input packet\n",
887 sc->sc_dev.dv_xname);
888 #endif
889 }
890 Rx->next = NULL;
891 Rx->hw_list.fwd = 0;
892 sc->last_Rx->hw_list.fwd = vtophys(&Rx->hw_list);
893 #ifdef DIAGNOSTIC
894 if (sc->last_Rx->hw_list.fwd & 0x7)
895 printf("%s: physical addr 0x%x of list not properly aligned\n",
896 sc->sc_dev.dv_xname, sc->last_Rx->hw_list.fwd);
897 #endif
898 sc->last_Rx->next = Rx;
899 sc->last_Rx = Rx;
900
901 /* deliver packet */
902 if (m) {
903 struct ether_header *eh;
904 if (size < sizeof(struct ether_header)) {
905 m_freem(m);
906 continue;
907 }
908 m->m_pkthdr.rcvif = ifp;
909 m->m_pkthdr.len = m->m_len =
910 size - sizeof(struct ether_header);
911 eh = mtod(m, struct ether_header *);
912 #ifdef TLDEBUG_RX
913 printf("tl_intr: Rx packet:\n");
914 ether_printheader(eh);
915 #endif
916 #if NBPFILTER > 0
917 if (ifp->if_bpf) {
918 bpf_tap(ifp->if_bpf,
919 mtod(m, caddr_t),
920 size);
921 /*
922 * Only pass this packet up
923 * if it is for us.
924 */
925 if ((ifp->if_flags & IFF_PROMISC) &&
926 (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
927 bcmp(eh->ether_dhost, LLADDR(ifp->if_sadl),
928 sizeof(eh->ether_dhost)) != 0) {
929 m_freem(m);
930 continue;
931 }
932 }
933 #endif /* NBPFILTER > 0 */
934 m->m_data += sizeof(struct ether_header);
935 ether_input(ifp, eh, m);
936 }
937 }
938 #ifdef TLDEBUG_RX
939 printf("TL_INTR_RxEOF: ack %d\n", ack);
940 #else
941 if (ack == 0) {
942 printf("%s: EOF intr without anything to read !\n",
943 sc->sc_dev.dv_xname);
944 tl_reset(sc);
945 /* shedule reinit of the board */
946 timeout(tl_restart, sc, 1);
947 return(1);
948 }
949 #endif
950 break;
951 case TL_INTR_RxEOC:
952 ack++;
953 #ifdef TLDEBUG_RX
954 printf("TL_INTR_RxEOC: ack %d\n", ack);
955 #endif
956 #ifdef DIAGNOSTIC
957 if (sc->active_Rx->hw_list.stat & TL_RX_CSTAT_CPLT) {
958 printf("%s: Rx EOC interrupt and active Rx list not cleared\n",
959 sc->sc_dev.dv_xname);
960 return 0;
961 } else
962 #endif
963 {
964 /* write adress of Rx list and send Rx GO command, ack interrupt
965 and enable interrupts in one command */
966 TL_HR_WRITE(sc, TL_HOST_CH_PARM,
967 vtophys(&sc->active_Rx->hw_list));
968 TL_HR_WRITE(sc, TL_HOST_CMD,
969 HOST_CMD_GO | HOST_CMD_RT | HOST_CMD_Nes | ack | int_type |
970 HOST_CMD_ACK | HOST_CMD_IntOn);
971 return 1;
972 }
973 case TL_INTR_TxEOF:
974 case TL_INTR_TxEOC:
975 while ((Tx = sc->active_Tx) != NULL) {
976 if((Tx->hw_list.stat & TL_TX_CSTAT_CPLT) == 0)
977 break;
978 ack++;
979 #ifdef TLDEBUG_TX
980 printf("TL_INTR_TxEOC: list 0x%xp done\n", vtophys(&Tx->hw_list));
981 #endif
982 Tx->hw_list.stat = 0;
983 m_freem(Tx->m);
984 Tx->m = NULL;
985 sc->active_Tx = Tx->next;
986 if (sc->active_Tx == NULL)
987 sc->last_Tx = NULL;
988 Tx->next = sc->Free_Tx;
989 sc->Free_Tx = Tx;
990 }
991 /* if this was an EOC, ACK immediatly */
992 if (int_type == TL_INTR_TxEOC) {
993 #ifdef TLDEBUG_TX
994 printf("TL_INTR_TxEOC: ack %d (will be set to 1)\n", ack);
995 #endif
996 TL_HR_WRITE(sc, TL_HOST_CMD, 1 | int_type | HOST_CMD_ACK |
997 HOST_CMD_IntOn);
998 if ( sc->active_Tx != NULL) { /* needs a Tx go command */
999 TL_HR_WRITE(sc, TL_HOST_CH_PARM,
1000 vtophys(&sc->active_Tx->hw_list));
1001 TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_GO);
1002 }
1003 sc->tl_if.if_timer = 0;
1004 if (sc->tl_if.if_snd.ifq_head != NULL)
1005 tl_ifstart(&sc->tl_if);
1006 return 1;
1007 }
1008 #ifdef TLDEBUG
1009 else {
1010 printf("TL_INTR_TxEOF: ack %d\n", ack);
1011 }
1012 #endif
1013 sc->tl_if.if_timer = 0;
1014 if (sc->tl_if.if_snd.ifq_head != NULL)
1015 tl_ifstart(&sc->tl_if);
1016 break;
1017 case TL_INTR_Stat:
1018 ack++;
1019 #ifdef TLDEBUG
1020 printf("TL_INTR_Stat: ack %d\n", ack);
1021 #endif
1022 tl_read_stats(sc);
1023 break;
1024 case TL_INTR_Adc:
1025 if (int_reg & TL_INTVec_MASK) {
1026 /* adapter check conditions */
1027 printf("%s: check condition, intvect=0x%x, ch_param=0x%x\n",
1028 sc->sc_dev.dv_xname, int_reg & TL_INTVec_MASK,
1029 TL_HR_READ(sc, TL_HOST_CH_PARM));
1030 tl_reset(sc);
1031 /* shedule reinit of the board */
1032 timeout(tl_restart, sc, 1);
1033 return(1);
1034 } else {
1035 u_int8_t netstat;
1036 /* Network status */
1037 netstat = tl_intreg_read_byte(sc, TL_INT_NET+TL_INT_NetSts);
1038 printf("%s: network status, NetSts=%x\n",
1039 sc->sc_dev.dv_xname, netstat);
1040 /* Ack interrupts */
1041 tl_intreg_write_byte(sc, TL_INT_NET+TL_INT_NetSts, netstat);
1042 ack++;
1043 }
1044 break;
1045 default:
1046 printf("%s: unhandled interrupt code %x!\n",
1047 sc->sc_dev.dv_xname, int_type);
1048 ack++;
1049 }
1050
1051 if (ack) {
1052 /* Ack the interrupt and enable interrupts */
1053 TL_HR_WRITE(sc, TL_HOST_CMD, ack | int_type | HOST_CMD_ACK |
1054 HOST_CMD_IntOn);
1055 return 1;
1056 }
1057 /* ack = 0 ; interrupt was perhaps not our. Just enable interrupts */
1058 TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_IntOn);
1059 return 0;
1060 }
1061
1062 static int
1063 tl_ifioctl(ifp, cmd, data)
1064 struct ifnet *ifp;
1065 ioctl_cmd_t cmd;
1066 caddr_t data;
1067 {
1068 struct tl_softc *sc = ifp->if_softc;
1069 struct ifreq *ifr = (struct ifreq *)data;
1070 int s, error;
1071
1072 s = splimp();
1073 switch(cmd) {
1074 case SIOCSIFADDR: {
1075 struct ifaddr *ifa = (struct ifaddr *)data;
1076 sc->tl_if.if_flags |= IFF_UP;
1077 if ((error = tl_init(sc)) != NULL) {
1078 sc->tl_if.if_flags &= ~IFF_UP;
1079 break;
1080 }
1081 switch (ifa->ifa_addr->sa_family) {
1082 #ifdef INET
1083 case AF_INET:
1084 arp_ifinit(ifp, ifa);
1085 break;
1086 #endif
1087 #ifdef NS
1088 case AF_NS: {
1089 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
1090
1091 if (ns_nullhost(*ina))
1092 ina->x_host = *(union ns_host*) LLADDR(ifp->if_sadl);
1093 else
1094 bcopy(ina->x_host.c_host, LLADDR(ifp->if_sadl),
1095 ifp->if_addrlen);
1096 break;
1097 }
1098 #endif
1099 default:
1100 break;
1101 }
1102 break;
1103 }
1104 case SIOCSIFFLAGS:
1105 {
1106 u_int8_t reg;
1107 /*
1108 * If interface is marked up and not running, then start it.
1109 * If it is marked down and running, stop it.
1110 */
1111 if (ifp->if_flags & IFF_UP) {
1112 if ((ifp->if_flags & IFF_RUNNING) == 0) {
1113 error = tl_init(sc);
1114 /* all flags have been handled by init */
1115 break;
1116 }
1117 error = 0;
1118 reg = tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetCmd);
1119 if (ifp->if_flags & IFF_PROMISC)
1120 reg |= TL_NETCOMMAND_CAF;
1121 else
1122 reg &= ~TL_NETCOMMAND_CAF;
1123 tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetCmd, reg);
1124 #ifdef TL_PRIV_STATS
1125 if (ifp->if_flags & IFF_LINK0) {
1126 ifp->if_flags &= ~IFF_LINK0;
1127 printf("%s errors statistics\n", sc->sc_dev.dv_xname);
1128 printf(" %4d RX buffer overrun\n",sc->ierr_overr);
1129 printf(" %4d RX code error\n", sc->ierr_code);
1130 printf(" %4d RX crc error\n", sc->ierr_crc);
1131 printf(" %4d RX out of memory\n", sc->ierr_nomem);
1132 printf(" %4d TX buffer underrun\n", sc->oerr_underr);
1133 printf(" %4d TX deffered frames\n", sc->oerr_deffered);
1134 printf(" %4d TX single collisions\n", sc->oerr_coll);
1135 printf(" %4d TX multi collisions\n", sc->oerr_multicoll);
1136 printf(" %4d TX exessive collisions\n", sc->oerr_exesscoll);
1137 printf(" %4d TX late collisions\n", sc->oerr_latecoll);
1138 printf(" %4d TX carrier loss\n", sc->oerr_carrloss);
1139 printf(" %4d TX mbuf copy\n", sc->oerr_mcopy);
1140 }
1141 #endif
1142 } else {
1143 if (ifp->if_flags & IFF_RUNNING)
1144 tl_shutdown(sc);
1145 error = 0;
1146 }
1147 break;
1148 }
1149 case SIOCADDMULTI:
1150 case SIOCDELMULTI:
1151 /*
1152 * Update multicast listeners
1153 */
1154 if (cmd == SIOCADDMULTI)
1155 error = ether_addmulti(ifr, &sc->tl_ec);
1156 else
1157 error = ether_delmulti(ifr, &sc->tl_ec);
1158 if (error == ENETRESET) {
1159 tl_addr_filter(sc);
1160 error = 0;
1161 }
1162 break;
1163 case SIOCSIFMEDIA:
1164 case SIOCGIFMEDIA:
1165 error = ifmedia_ioctl(ifp, ifr, &sc->tl_ifmedia, cmd);
1166 break;
1167 default:
1168 error = EINVAL;
1169 }
1170 splx(s);
1171 return error;
1172 }
1173
1174 static void
1175 tl_ifstart(ifp)
1176 struct ifnet *ifp;
1177 {
1178 tl_softc_t *sc = ifp->if_softc;
1179 struct mbuf *m, *mb_head;
1180 struct Tx_list *Tx;
1181 int segment, size;
1182
1183 txloop:
1184 /* If we don't have more space ... */
1185 if (sc->Free_Tx == NULL) {
1186 #ifdef TLDEBUG
1187 printf("tl_ifstart: No free TX list\n");
1188 #endif
1189 return;
1190 }
1191 /* Grab a paquet for output */
1192 IF_DEQUEUE(&ifp->if_snd, mb_head);
1193 if (mb_head == NULL) {
1194 #ifdef TLDEBUG_TX
1195 printf("tl_ifstart: nothing to send\n");
1196 #endif
1197 return;
1198 }
1199 Tx = sc->Free_Tx;
1200 sc->Free_Tx = Tx->next;
1201 /*
1202 * Go through each of the mbufs in the chain and initialize
1203 * the transmit list descriptors with the physical address
1204 * and size of the mbuf.
1205 */
1206 tbdinit:
1207 bzero(Tx, sizeof(struct Tx_list));
1208 Tx->m = mb_head;
1209 size = 0;
1210 for (m = mb_head, segment = 0; m != NULL ; m = m->m_next) {
1211 if (m->m_len != 0) {
1212 if (segment == TL_NSEG)
1213 break;
1214 size += m->m_len;
1215 Tx->hw_list.seg[segment].data_addr =
1216 vtophys(mtod(m, vm_offset_t));
1217 Tx->hw_list.seg[segment].data_count = m->m_len;
1218 segment++;
1219 }
1220 }
1221 if (m != NULL || (size < ETHER_MIN_TX && segment == TL_NSEG)) {
1222 /*
1223 * We ran out of segments, or we will. We have to recopy this mbuf
1224 * chain first.
1225 */
1226 struct mbuf *mn;
1227 #ifdef TLDEBUG_TX
1228 printf("tl_ifstart: need to copy mbuf\n");
1229 #endif
1230 #ifdef TL_PRIV_STATS
1231 sc->oerr_mcopy++;
1232 #endif
1233 MGETHDR(mn, M_DONTWAIT, MT_DATA);
1234 if (mn == NULL) {
1235 m_freem(mb_head);
1236 goto bad;
1237 }
1238 if (mb_head->m_pkthdr.len > MHLEN) {
1239 MCLGET(mn, M_DONTWAIT);
1240 if ((mn->m_flags & M_EXT) == 0) {
1241 m_freem(mn);
1242 m_freem(mb_head);
1243 goto bad;
1244 }
1245 }
1246 m_copydata(mb_head, 0, mb_head->m_pkthdr.len,
1247 mtod(mn, caddr_t));
1248 mn->m_pkthdr.len = mn->m_len = mb_head->m_pkthdr.len;
1249 m_freem(mb_head);
1250 mb_head = mn;
1251 goto tbdinit;
1252 }
1253 /* We are at end of mbuf chain. check the size and
1254 * see if it needs to be extended
1255 */
1256 if (size < ETHER_MIN_TX) {
1257 #ifdef DIAGNOSTIC
1258 if (segment >= TL_NSEG) {
1259 panic("tl_ifstart: to much segmets (%d)\n", segment);
1260 }
1261 #endif
1262 /*
1263 * add the nullbuf in the seg
1264 */
1265 Tx->hw_list.seg[segment].data_count =
1266 ETHER_MIN_TX - size;
1267 Tx->hw_list.seg[segment].data_addr =
1268 vtophys(nullbuf);
1269 size = ETHER_MIN_TX;
1270 segment++;
1271 }
1272 /* The list is done, finish the list init */
1273 Tx->hw_list.seg[segment-1].data_count |=
1274 TL_LAST_SEG;
1275 Tx->hw_list.stat = (size << 16) | 0x3000;
1276 #ifdef TLDEBUG_TX
1277 printf("%s: sending, Tx : stat = 0x%x\n", sc->sc_dev.dv_xname,
1278 Tx->hw_list.stat);
1279 #if 0
1280 for(segment = 0; segment < TL_NSEG; segment++) {
1281 printf(" seg %d addr 0x%x len 0x%x\n",
1282 segment,
1283 Tx->hw_list.seg[segment].data_addr,
1284 Tx->hw_list.seg[segment].data_count);
1285 }
1286 #endif
1287 #endif
1288 sc->opkt++;
1289 if (sc->active_Tx == NULL) {
1290 sc->active_Tx = sc->last_Tx = Tx;
1291 #ifdef TLDEBUG_TX
1292 printf("%s: Tx GO, addr=0x%x\n", sc->sc_dev.dv_xname,
1293 vtophys(&Tx->hw_list));
1294 #endif
1295 TL_HR_WRITE(sc, TL_HOST_CH_PARM, vtophys(&Tx->hw_list));
1296 TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_GO);
1297 } else {
1298 #ifdef TLDEBUG_TX
1299 printf("%s: Tx addr=0x%x queued\n", sc->sc_dev.dv_xname,
1300 vtophys(&Tx->hw_list));
1301 #endif
1302 sc->last_Tx->hw_list.fwd = vtophys(&Tx->hw_list);
1303 sc->last_Tx->next = Tx;
1304 sc->last_Tx = Tx;
1305 #ifdef DIAGNOSTIC
1306 if (sc->last_Tx->hw_list.fwd & 0x7)
1307 printf("%s: physical addr 0x%x of list not properly aligned\n",
1308 sc->sc_dev.dv_xname, sc->last_Rx->hw_list.fwd);
1309 #endif
1310 }
1311 #if NBPFILTER > 0
1312 /* Pass packet to bpf if there is a listener */
1313 if (ifp->if_bpf)
1314 bpf_mtap(ifp->if_bpf, mb_head);
1315 #endif
1316 /* Set a 5 second timer just in case we don't hear from the card again. */
1317 ifp->if_timer = 5;
1318
1319 goto txloop;
1320 bad:
1321 #ifdef TLDEBUG
1322 printf("tl_ifstart: Out of mbuf, Tx pkt lost\n");
1323 #endif
1324 Tx->next = sc->Free_Tx;
1325 sc->Free_Tx = Tx;
1326 return;
1327 }
1328
1329 static void
1330 tl_ifwatchdog(ifp)
1331 struct ifnet *ifp;
1332 {
1333 tl_softc_t *sc = ifp->if_softc;
1334
1335 if ((ifp->if_flags & IFF_RUNNING) == 0)
1336 return;
1337 printf("%s: device timeout\n", sc->sc_dev.dv_xname);
1338 ifp->if_oerrors++;
1339 tl_init(sc);
1340 }
1341
1342 static int
1343 tl_mediachange(ifp)
1344 struct ifnet *ifp;
1345 {
1346
1347 tl_softc_t *sc = ifp->if_softc;
1348 int err;
1349 u_int32_t reg;
1350 int oldmedia;
1351 #ifdef TLDEBUG
1352 printf("tl_mediachange, media %x\n", sc->tl_ifmedia.ifm_media);
1353 #endif
1354 oldmedia = sc->mii.mii_media_active;
1355 sc->mii.mii_media_active = sc->tl_ifmedia.ifm_media;
1356 if ((err = mii_mediachg(&sc->mii)) != 0)
1357 sc->mii.mii_media_active = oldmedia;
1358 reg = tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetCmd);
1359 if (sc->mii.mii_media_active & IFM_FDX)
1360 reg |= TL_NETCOMMAND_DUPLEX;
1361 else
1362 reg &= ~TL_NETCOMMAND_DUPLEX;
1363 tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetCmd, reg);
1364 return err;
1365 }
1366
1367 static void
1368 tl_mediastatus(ifp, ifmr)
1369 struct ifnet *ifp;
1370 struct ifmediareq *ifmr;
1371 {
1372 tl_softc_t *sc = ifp->if_softc;
1373 if (IFM_SUBTYPE(sc->mii.mii_media_active) == IFM_10_2 ||
1374 IFM_SUBTYPE(sc->mii.mii_media_active) == IFM_10_5)
1375 if (sc->tl_flags & TL_IFACT)
1376 sc->mii.mii_media_status = IFM_AVALID | IFM_ACTIVE;
1377 else
1378 sc->mii.mii_media_status = IFM_AVALID;
1379 else
1380 mii_pollstat(&sc->mii);
1381
1382 ifmr->ifm_active = sc->mii.mii_media_active;
1383 ifmr->ifm_status = sc->mii.mii_media_status;
1384 }
1385
1386 static int tl_add_RxBuff(Rx, oldm)
1387 struct Rx_list *Rx;
1388 struct mbuf *oldm;
1389 {
1390 struct mbuf *m;
1391
1392 MGETHDR(m, M_DONTWAIT, MT_DATA);
1393 if (m != NULL) {
1394 MCLGET(m, M_DONTWAIT);
1395 if ((m->m_flags & M_EXT) == 0) {
1396 m_freem(m);
1397 if (oldm == NULL)
1398 return 0;
1399 m = oldm;
1400 m->m_data = m->m_ext.ext_buf;
1401 }
1402 } else {
1403 if (oldm == NULL)
1404 return 0;
1405 m = oldm;
1406 m->m_data = m->m_ext.ext_buf;
1407 }
1408 /*
1409 * Move the data pointer up so that the incoming data packet
1410 * will be 32-bit aligned.
1411 */
1412 m->m_data += 2;
1413
1414 /* (re)init the Rx_list struct */
1415
1416 Rx->m = m;
1417 Rx->hw_list.stat = ((MCLBYTES -2) << 16) | 0x3000;
1418 Rx->hw_list.seg.data_count = (MCLBYTES -2);
1419 Rx->hw_list.seg.data_addr = vtophys(m->m_data);
1420 return (m != oldm);
1421 }
1422
1423 static void tl_ticks(v)
1424 void *v;
1425 {
1426 tl_softc_t *sc = v;
1427
1428 tl_read_stats(sc);
1429 if (sc->opkt > 0) {
1430 if (sc->oerr_exesscoll > sc->opkt / 100) { /* exess collisions */
1431 if (sc->tl_flags & TL_IFACT) /* only print once */
1432 printf("%s: no carrier\n", sc->sc_dev.dv_xname);
1433 sc->tl_flags &= ~TL_IFACT;
1434 } else
1435 sc->tl_flags |= TL_IFACT;
1436 sc->oerr_exesscoll = sc->opkt = 0;
1437 sc->tl_lasttx = 0;
1438 } else {
1439 sc->tl_lasttx++;
1440 if (sc->tl_lasttx >= TL_IDLETIME) {
1441 /*
1442 * No TX activity in the last TL_IDLETIME seconds.
1443 * sends a LLC Class1 TEST pkt
1444 */
1445 struct mbuf *m;
1446 int s;
1447 MGETHDR(m, M_DONTWAIT, MT_DATA);
1448 if (m != NULL) {
1449 #ifdef TLDEBUG
1450 printf("tl_ticks: sending LLC test pkt\n");
1451 #endif
1452 bcopy(sc->tl_enaddr,
1453 mtod(m, struct ether_header *)->ether_dhost, 6);
1454 bcopy(sc->tl_enaddr,
1455 mtod(m, struct ether_header *)->ether_shost, 6);
1456 mtod(m, struct ether_header *)->ether_type = htons(3);
1457 mtod(m, unsigned char *)[14] = 0;
1458 mtod(m, unsigned char *)[15] = 0;
1459 mtod(m, unsigned char *)[16] = 0xE3;
1460 /* LLC Class1 TEST (no poll) */
1461 m->m_len = m->m_pkthdr.len = sizeof(struct ether_header) + 3;
1462 s = splnet();
1463 IF_PREPEND(&sc->tl_if.if_snd, m);
1464 tl_ifstart(&sc->tl_if);
1465 splx(s);
1466 }
1467 }
1468 }
1469
1470 /* read statistics every seconds */
1471 timeout(tl_ticks, v, hz);
1472 }
1473
1474 static void
1475 tl_read_stats(sc)
1476 tl_softc_t *sc;
1477 {
1478 u_int32_t reg;
1479 int ierr_overr;
1480 int ierr_code;
1481 int ierr_crc;
1482 int oerr_underr;
1483 int oerr_deffered;
1484 int oerr_coll;
1485 int oerr_multicoll;
1486 int oerr_exesscoll;
1487 int oerr_latecoll;
1488 int oerr_carrloss;
1489 struct ifnet *ifp = &sc->tl_if;
1490
1491 reg = tl_intreg_read(sc, TL_INT_STATS_TX);
1492 ifp->if_opackets += reg & 0x00ffffff;
1493 oerr_underr = reg >> 24;
1494
1495 reg = tl_intreg_read(sc, TL_INT_STATS_RX);
1496 ifp->if_ipackets += reg & 0x00ffffff;
1497 ierr_overr = reg >> 24;
1498
1499 reg = tl_intreg_read(sc, TL_INT_STATS_FERR);
1500 ierr_crc = (reg & TL_FERR_CRC) >> 16;
1501 ierr_code = (reg & TL_FERR_CODE) >> 24;
1502 oerr_deffered = (reg & TL_FERR_DEF);
1503
1504 reg = tl_intreg_read(sc, TL_INT_STATS_COLL);
1505 oerr_multicoll = (reg & TL_COL_MULTI);
1506 oerr_coll = (reg & TL_COL_SINGLE) >> 16;
1507
1508 reg = tl_intreg_read(sc, TL_INT_LERR);
1509 oerr_exesscoll = (reg & TL_LERR_ECOLL);
1510 oerr_latecoll = (reg & TL_LERR_LCOLL) >> 8;
1511 oerr_carrloss = (reg & TL_LERR_CL) >> 16;
1512
1513
1514 sc->stats_exesscoll += oerr_exesscoll;
1515 ifp->if_oerrors += oerr_underr + oerr_exesscoll + oerr_latecoll +
1516 oerr_carrloss;
1517 ifp->if_collisions += oerr_coll + oerr_multicoll;
1518 ifp->if_ierrors += ierr_overr + ierr_code + ierr_crc;
1519
1520 if (ierr_overr)
1521 printf("%s: receiver ring buffer overrun\n", sc->sc_dev.dv_xname);
1522 if (oerr_underr)
1523 printf("%s: transmit buffer underrun\n", sc->sc_dev.dv_xname);
1524 #ifdef TL_PRIV_STATS
1525 sc->ierr_overr += ierr_overr;
1526 sc->ierr_code += ierr_code;
1527 sc->ierr_crc += ierr_crc;
1528 sc->oerr_underr += oerr_underr;
1529 sc->oerr_deffered += oerr_deffered;
1530 sc->oerr_coll += oerr_coll;
1531 sc->oerr_multicoll += oerr_multicoll;
1532 sc->oerr_exesscoll += oerr_exesscoll;
1533 sc->oerr_latecoll += oerr_latecoll;
1534 sc->oerr_carrloss += oerr_carrloss;
1535 #endif
1536 }
1537
1538 static void tl_addr_filter(sc)
1539 tl_softc_t *sc;
1540 {
1541 struct ether_multistep step;
1542 struct ether_multi *enm;
1543 u_int32_t hash[2] = {0, 0};
1544 int i;
1545
1546 sc->tl_if.if_flags &= ~IFF_ALLMULTI;
1547 ETHER_FIRST_MULTI(step, &sc->tl_ec, enm);
1548 while (enm != NULL) {
1549 #ifdef TLDEBUG
1550 printf("tl_addr_filter: addrs %s %s\n", ether_sprintf(enm->enm_addrlo), ether_sprintf(enm->enm_addrhi));
1551 #endif
1552 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 6) == 0) {
1553 i = tl_multicast_hash(enm->enm_addrlo);
1554 hash[i/32] |= 1 << (i%32);
1555 } else {
1556 hash[0] = hash[1] = 0xffffffff;
1557 sc->tl_if.if_flags |= IFF_ALLMULTI;
1558 break;
1559 }
1560 ETHER_NEXT_MULTI(step, enm);
1561 }
1562 #ifdef TLDEBUG
1563 printf("tl_addr_filer: hash1 %x has2 %x\n", hash[0], hash[1]);
1564 #endif
1565 tl_intreg_write(sc, TL_INT_HASH1, hash[0]);
1566 tl_intreg_write(sc, TL_INT_HASH2, hash[1]);
1567 }
1568
1569 static int tl_multicast_hash(a)
1570 u_int8_t *a;
1571 {
1572 int hash;
1573
1574 #define DA(addr,bit) (addr[5 - (bit/8)] & (1 << bit%8))
1575 #define xor8(a,b,c,d,e,f,g,h) (((a != 0) + (b != 0) + (c != 0) + (d != 0) + (e != 0) + (f != 0) + (g != 0) + (h != 0)) & 1)
1576
1577 hash = xor8( DA(a,0), DA(a, 6), DA(a,12), DA(a,18), DA(a,24), DA(a,30),
1578 DA(a,36), DA(a,42));
1579 hash |= xor8( DA(a,1), DA(a, 7), DA(a,13), DA(a,19), DA(a,25), DA(a,31),
1580 DA(a,37), DA(a,43)) << 1;
1581 hash |= xor8( DA(a,2), DA(a, 8), DA(a,14), DA(a,20), DA(a,26), DA(a,32),
1582 DA(a,38), DA(a,44)) << 2;
1583 hash |= xor8( DA(a,3), DA(a, 9), DA(a,15), DA(a,21), DA(a,27), DA(a,33),
1584 DA(a,39), DA(a,45)) << 3;
1585 hash |= xor8( DA(a,4), DA(a,10), DA(a,16), DA(a,22), DA(a,28), DA(a,34),
1586 DA(a,40), DA(a,46)) << 4;
1587 hash |= xor8( DA(a,5), DA(a,11), DA(a,17), DA(a,23), DA(a,29), DA(a,35),
1588 DA(a,41), DA(a,47)) << 5;
1589
1590 return hash;
1591 }
1592
1593 #if defined(TLDEBUG_RX)
1594 void ether_printheader(eh)
1595 struct ether_header *eh;
1596 {
1597 u_char *c = (char*)eh;
1598 int i;
1599 for (i=0; i<sizeof(struct ether_header); i++)
1600 printf("%x ", (u_int)c[i]);
1601 printf("\n");
1602 }
1603 #endif
1604