if_tl.c revision 1.5 1 /* $NetBSD: if_tl.c,v 1.5 1997/11/17 08:14:53 thorpej 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;
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 if (nullbuf)
563 free(nullbuf, M_DEVBUF);
564 nullbuf = NULL;
565 sc->tl_if.if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
566 sc->mii.mii_media_status &= ~IFM_ACTIVE;
567 sc->tl_flags = 0;
568 }
569
570 static void tl_restart(v)
571 void *v;
572 {
573 tl_init(v);
574 }
575
576 static int tl_init(sc)
577 tl_softc_t *sc;
578 {
579 struct ifnet *ifp = &sc->tl_if;
580 int i, s;
581
582 s = splimp();
583 /* cancel any pending IO */
584 tl_shutdown(sc);
585 tl_reset(sc);
586 if ((sc->tl_if.if_flags & IFF_UP) == 0) {
587 splx(s);
588 return 0;
589 }
590 /* Set various register to reasonable value */
591 /* setup NetCmd in promisc mode if needed */
592 i = (ifp->if_flags & IFF_PROMISC) ? TL_NETCOMMAND_CAF : 0;
593 tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetCmd,
594 TL_NETCOMMAND_NRESET | TL_NETCOMMAND_NWRAP | i);
595 /* Max receive size : MCLBYTES */
596 tl_intreg_write_byte(sc, TL_INT_MISC + TL_MISC_MaxRxL, MCLBYTES & 0xff);
597 tl_intreg_write_byte(sc, TL_INT_MISC + TL_MISC_MaxRxH,
598 (MCLBYTES >> 8) & 0xff);
599
600 /* init MAC addr */
601 for (i = 0; i < ETHER_ADDR_LEN; i++)
602 tl_intreg_write_byte(sc, TL_INT_Areg0 + i , sc->tl_enaddr[i]);
603 /* add multicast filters */
604 tl_addr_filter(sc);
605 #ifdef TLDEBUG_ADDR
606 printf("Wrote Mac addr, Areg & hash registers are now: \n");
607 for (i = TL_INT_Areg0; i <= TL_INT_HASH2; i = i + 4)
608 printf(" reg %x: %x\n", i, tl_intreg_read(sc, i));
609 #endif
610
611 /* Pre-allocate receivers mbuf, make the lists */
612 sc->Rx_list = malloc(sizeof(struct Rx_list) * TL_NBUF, M_DEVBUF, M_NOWAIT);
613 sc->Tx_list = malloc(sizeof(struct Tx_list) * TL_NBUF, M_DEVBUF, M_NOWAIT);
614 if (sc->Rx_list == NULL || sc->Tx_list == NULL) {
615 printf("%s: out of memory for lists\n", sc->sc_dev.dv_xname);
616 sc->tl_if.if_flags &= ~IFF_UP;
617 splx(s);
618 return ENOMEM;
619 }
620 for (i=0; i< TL_NBUF; i++) {
621 if(tl_add_RxBuff(&sc->Rx_list[i], NULL) == 0) {
622 printf("%s: out of mbuf for receive list\n", sc->sc_dev.dv_xname);
623 sc->tl_if.if_flags &= ~IFF_UP;
624 splx(s);
625 return ENOMEM;
626 }
627 if (i > 0) { /* chain the list */
628 sc->Rx_list[i-1].next = &sc->Rx_list[i];
629 sc->Rx_list[i-1].hw_list.fwd = vtophys(&sc->Rx_list[i].hw_list);
630 #ifdef DIAGNOSTIC
631 if (sc->Rx_list[i-1].hw_list.fwd & 0x7)
632 printf("%s: physical addr 0x%x of list not properly aligned\n",
633 sc->sc_dev.dv_xname, sc->Rx_list[i-1].hw_list.fwd);
634 #endif
635 sc->Tx_list[i-1].next = &sc->Tx_list[i];
636 }
637 }
638 sc->Rx_list[TL_NBUF-1].next = NULL;
639 sc->Rx_list[TL_NBUF-1].hw_list.fwd = 0;
640 sc->Tx_list[TL_NBUF-1].next = NULL;
641
642 sc->active_Rx = &sc->Rx_list[0];
643 sc->last_Rx = &sc->Rx_list[TL_NBUF-1];
644 sc->active_Tx = sc->last_Tx = NULL;
645 sc->Free_Tx = &sc->Tx_list[0];
646
647 nullbuf = malloc(ETHER_MIN_TX, M_DEVBUF, M_NOWAIT);
648 if (nullbuf == NULL) {
649 printf("%s: can't allocate space for pad buffer\n",
650 sc->sc_dev.dv_xname);
651 sc->tl_if.if_flags &= ~IFF_UP;
652 splx(s);
653 return ENOMEM;
654 }
655 bzero(nullbuf, ETHER_MIN_TX);
656
657 /* set media if needed */
658 if (IFM_SUBTYPE(sc->mii.mii_media_active) != IFM_NONE) {
659 mii_mediachg(&sc->mii);
660 }
661
662 /* start ticks calls */
663 timeout(tl_ticks, sc, hz);
664 /* write adress of Rx list and enable interrupts */
665 TL_HR_WRITE(sc, TL_HOST_CH_PARM, vtophys(&sc->Rx_list[0].hw_list));
666 TL_HR_WRITE(sc, TL_HOST_CMD,
667 HOST_CMD_GO | HOST_CMD_RT | HOST_CMD_Nes | HOST_CMD_IntOn);
668 sc->tl_if.if_flags |= IFF_RUNNING;
669 sc->tl_if.if_flags &= ~IFF_OACTIVE;
670 return 0;
671 }
672
673
674 static u_int32_t
675 tl_intreg_read(sc, reg)
676 tl_softc_t *sc;
677 u_int32_t reg;
678 {
679 TL_HR_WRITE(sc, TL_HOST_INTR_DIOADR, reg & TL_HOST_DIOADR_MASK);
680 return TL_HR_READ(sc, TL_HOST_DIO_DATA);
681 }
682
683 static u_int8_t
684 tl_intreg_read_byte(sc, reg)
685 tl_softc_t *sc;
686 u_int32_t reg;
687 {
688 TL_HR_WRITE(sc, TL_HOST_INTR_DIOADR,
689 (reg & (~0x07)) & TL_HOST_DIOADR_MASK);
690 return TL_HR_READ_BYTE(sc, TL_HOST_DIO_DATA + (reg & 0x07));
691 }
692
693 static void
694 tl_intreg_write(sc, reg, val)
695 tl_softc_t *sc;
696 u_int32_t reg;
697 u_int32_t val;
698 {
699 TL_HR_WRITE(sc, TL_HOST_INTR_DIOADR, reg & TL_HOST_DIOADR_MASK);
700 TL_HR_WRITE(sc, TL_HOST_DIO_DATA, val);
701 }
702
703 static void
704 tl_intreg_write_byte(sc, reg, val)
705 tl_softc_t *sc;
706 u_int32_t reg;
707 u_int8_t val;
708 {
709 TL_HR_WRITE(sc, TL_HOST_INTR_DIOADR,
710 (reg & (~0x03)) & TL_HOST_DIOADR_MASK);
711 TL_HR_WRITE_BYTE(sc, TL_HOST_DIO_DATA + (reg & 0x03), val);
712 }
713
714 void tl_mii_set(v, bit)
715 void *v;
716 u_int8_t bit;
717 {
718 tl_softc_t *sc = v;
719
720 switch (bit) {
721 case MII_DATA:
722 netsio_set(sc, TL_NETSIO_MDATA);
723 break;
724 case MII_CLOCK:
725 netsio_set(sc, TL_NETSIO_MCLK);
726 break;
727 case MII_TXEN:
728 netsio_set(sc, TL_NETSIO_MTXEN);
729 break;
730 default:
731 printf("tl_mii_set: unknown bit %d\n", bit);
732 }
733 }
734
735 void tl_mii_clr(v, bit)
736 void *v;
737 u_int8_t bit;
738 {
739 tl_softc_t *sc = v;
740
741 switch (bit) {
742 case MII_DATA:
743 netsio_clr(sc, TL_NETSIO_MDATA);
744 break;
745 case MII_CLOCK:
746 netsio_clr(sc, TL_NETSIO_MCLK);
747 break;
748 case MII_TXEN:
749 netsio_clr(sc, TL_NETSIO_MTXEN);
750 break;
751 default:
752 printf("tl_mii_clr: unknown bit %d\n", bit);
753 }
754 return;
755 }
756
757 int tl_mii_read(v, bit)
758 void *v;
759 u_int8_t bit;
760 {
761 tl_softc_t *sc = v;
762
763 switch (bit) {
764 case MII_DATA:
765 return netsio_read(sc, TL_NETSIO_MDATA);
766 break;
767 case MII_CLOCK:
768 return netsio_read(sc, TL_NETSIO_MCLK);
769 break;
770 case MII_TXEN:
771 return netsio_read(sc, TL_NETSIO_MTXEN);
772 break;
773 default:
774 printf("tl_mii_read: unknown bit %d\n", bit);
775 return -1;
776 }
777 }
778
779 void tl_i2c_set(v, bit)
780 void *v;
781 u_int8_t bit;
782 {
783 tl_softc_t *sc = v;
784
785 switch (bit) {
786 case I2C_DATA:
787 netsio_set(sc, TL_NETSIO_EDATA);
788 break;
789 case I2C_CLOCK:
790 netsio_set(sc, TL_NETSIO_ECLOCK);
791 break;
792 case I2C_TXEN:
793 netsio_set(sc, TL_NETSIO_ETXEN);
794 break;
795 default:
796 printf("tl_i2c_set: unknown bit %d\n", bit);
797 }
798 return;
799 }
800
801 void tl_i2c_clr(v, bit)
802 void *v;
803 u_int8_t bit;
804 {
805 tl_softc_t *sc = v;
806
807 switch (bit) {
808 case I2C_DATA:
809 netsio_clr(sc, TL_NETSIO_EDATA);
810 break;
811 case I2C_CLOCK:
812 netsio_clr(sc, TL_NETSIO_ECLOCK);
813 break;
814 case I2C_TXEN:
815 netsio_clr(sc, TL_NETSIO_ETXEN);
816 break;
817 default:
818 printf("tl_i2c_clr: unknown bit %d\n", bit);
819 }
820 return;
821 }
822
823 int tl_i2c_read(v, bit)
824 void *v;
825 u_int8_t bit;
826 {
827 tl_softc_t *sc = v;
828
829 switch (bit) {
830 case I2C_DATA:
831 return netsio_read(sc, TL_NETSIO_EDATA);
832 break;
833 case I2C_CLOCK:
834 return netsio_read(sc, TL_NETSIO_ECLOCK);
835 break;
836 case I2C_TXEN:
837 return netsio_read(sc, TL_NETSIO_ETXEN);
838 break;
839 default:
840 printf("tl_i2c_read: unknown bit %d\n", bit);
841 return -1;
842 }
843 }
844
845 static int
846 tl_intr(v)
847 void *v;
848 {
849 tl_softc_t *sc = v;
850 struct ifnet *ifp = &sc->tl_if;
851 struct Rx_list *Rx;
852 struct Tx_list *Tx;
853 struct mbuf *m;
854 u_int32_t int_type, int_reg;
855 int ack = 0;
856 int size;
857
858 int_reg = TL_HR_READ(sc, TL_HOST_INTR_DIOADR);
859 int_type = int_reg & TL_INTR_MASK;
860 if (int_type == 0)
861 return 0;
862 #if defined(TLDEBUG_RX) || defined(TLDEBUG_TX)
863 printf("%s: interrupt type %x, intr_reg %x\n", sc->sc_dev.dv_xname,
864 int_type, int_reg);
865 #endif
866 /* disable interrupts */
867 TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_IntOff);
868 switch(int_type & TL_INTR_MASK) {
869 case TL_INTR_RxEOF:
870 while(sc->active_Rx->hw_list.stat & TL_RX_CSTAT_CPLT) {
871 /* dequeue and requeue at end of list */
872 ack++;
873 Rx = sc->active_Rx;
874 sc->active_Rx = Rx->next;
875 m = Rx->m;
876 size = Rx->hw_list.stat >> 16;
877 #ifdef TLDEBUG_RX
878 printf("tl_intr: RX list complete, Rx %p, size=%d\n", Rx, size);
879 #endif
880 if (tl_add_RxBuff(Rx, m ) == 0) {
881 /* No new mbuf, reuse the same. This means that this packet
882 is lost */
883 m = NULL;
884 #ifdef TL_PRIV_STATS
885 sc->ierr_nomem++;
886 #endif
887 #ifdef TLDEBUG
888 printf("%s: out of mbuf, lost input packet\n",
889 sc->sc_dev.dv_xname);
890 #endif
891 }
892 Rx->next = NULL;
893 Rx->hw_list.fwd = 0;
894 sc->last_Rx->hw_list.fwd = vtophys(&Rx->hw_list);
895 #ifdef DIAGNOSTIC
896 if (sc->last_Rx->hw_list.fwd & 0x7)
897 printf("%s: physical addr 0x%x of list not properly aligned\n",
898 sc->sc_dev.dv_xname, sc->last_Rx->hw_list.fwd);
899 #endif
900 sc->last_Rx->next = Rx;
901 sc->last_Rx = Rx;
902
903 /* deliver packet */
904 if (m) {
905 struct ether_header *eh;
906 if (size < sizeof(struct ether_header)) {
907 m_freem(m);
908 continue;
909 }
910 m->m_pkthdr.rcvif = ifp;
911 m->m_pkthdr.len = m->m_len =
912 size - sizeof(struct ether_header);
913 eh = mtod(m, struct ether_header *);
914 #ifdef TLDEBUG_RX
915 printf("tl_intr: Rx packet:\n");
916 ether_printheader(eh);
917 #endif
918 #if NBPFILTER > 0
919 if (ifp->if_bpf) {
920 bpf_tap(ifp->if_bpf,
921 mtod(m, caddr_t),
922 size);
923 /*
924 * Only pass this packet up
925 * if it is for us.
926 */
927 if ((ifp->if_flags & IFF_PROMISC) &&
928 (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
929 bcmp(eh->ether_dhost, LLADDR(ifp->if_sadl),
930 sizeof(eh->ether_dhost)) != 0) {
931 m_freem(m);
932 continue;
933 }
934 }
935 #endif /* NBPFILTER > 0 */
936 m->m_data += sizeof(struct ether_header);
937 ether_input(ifp, eh, m);
938 }
939 }
940 #ifdef TLDEBUG_RX
941 printf("TL_INTR_RxEOF: ack %d\n", ack);
942 #else
943 if (ack == 0) {
944 printf("%s: EOF intr without anything to read !\n",
945 sc->sc_dev.dv_xname);
946 tl_reset(sc);
947 /* shedule reinit of the board */
948 timeout(tl_restart, sc, 1);
949 return(1);
950 }
951 #endif
952 break;
953 case TL_INTR_RxEOC:
954 ack++;
955 #ifdef TLDEBUG_RX
956 printf("TL_INTR_RxEOC: ack %d\n", ack);
957 #endif
958 #ifdef DIAGNOSTIC
959 if (sc->active_Rx->hw_list.stat & TL_RX_CSTAT_CPLT) {
960 printf("%s: Rx EOC interrupt and active Rx list not cleared\n",
961 sc->sc_dev.dv_xname);
962 return 0;
963 } else
964 #endif
965 {
966 /* write adress of Rx list and send Rx GO command, ack interrupt
967 and enable interrupts in one command */
968 TL_HR_WRITE(sc, TL_HOST_CH_PARM,
969 vtophys(&sc->active_Rx->hw_list));
970 TL_HR_WRITE(sc, TL_HOST_CMD,
971 HOST_CMD_GO | HOST_CMD_RT | HOST_CMD_Nes | ack | int_type |
972 HOST_CMD_ACK | HOST_CMD_IntOn);
973 return 1;
974 }
975 case TL_INTR_TxEOF:
976 case TL_INTR_TxEOC:
977 while ((Tx = sc->active_Tx) != NULL) {
978 if((Tx->hw_list.stat & TL_TX_CSTAT_CPLT) == 0)
979 break;
980 ack++;
981 #ifdef TLDEBUG_TX
982 printf("TL_INTR_TxEOC: list 0x%xp done\n", vtophys(&Tx->hw_list));
983 #endif
984 Tx->hw_list.stat = 0;
985 m_freem(Tx->m);
986 Tx->m = NULL;
987 sc->active_Tx = Tx->next;
988 if (sc->active_Tx == NULL)
989 sc->last_Tx = NULL;
990 Tx->next = sc->Free_Tx;
991 sc->Free_Tx = Tx;
992 }
993 /* if this was an EOC, ACK immediatly */
994 if (int_type == TL_INTR_TxEOC) {
995 #ifdef TLDEBUG_TX
996 printf("TL_INTR_TxEOC: ack %d (will be set to 1)\n", ack);
997 #endif
998 TL_HR_WRITE(sc, TL_HOST_CMD, 1 | int_type | HOST_CMD_ACK |
999 HOST_CMD_IntOn);
1000 if ( sc->active_Tx != NULL) { /* needs a Tx go command */
1001 TL_HR_WRITE(sc, TL_HOST_CH_PARM,
1002 vtophys(&sc->active_Tx->hw_list));
1003 TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_GO);
1004 }
1005 sc->tl_if.if_timer = 0;
1006 if (sc->tl_if.if_snd.ifq_head != NULL)
1007 tl_ifstart(&sc->tl_if);
1008 return 1;
1009 }
1010 #ifdef TLDEBUG
1011 else {
1012 printf("TL_INTR_TxEOF: ack %d\n", ack);
1013 }
1014 #endif
1015 sc->tl_if.if_timer = 0;
1016 if (sc->tl_if.if_snd.ifq_head != NULL)
1017 tl_ifstart(&sc->tl_if);
1018 break;
1019 case TL_INTR_Stat:
1020 ack++;
1021 #ifdef TLDEBUG
1022 printf("TL_INTR_Stat: ack %d\n", ack);
1023 #endif
1024 tl_read_stats(sc);
1025 break;
1026 case TL_INTR_Adc:
1027 if (int_reg & TL_INTVec_MASK) {
1028 /* adapter check conditions */
1029 printf("%s: check condition, intvect=0x%x, ch_param=0x%x\n",
1030 sc->sc_dev.dv_xname, int_reg & TL_INTVec_MASK,
1031 TL_HR_READ(sc, TL_HOST_CH_PARM));
1032 tl_reset(sc);
1033 /* shedule reinit of the board */
1034 timeout(tl_restart, sc, 1);
1035 return(1);
1036 } else {
1037 u_int8_t netstat;
1038 /* Network status */
1039 netstat = tl_intreg_read_byte(sc, TL_INT_NET+TL_INT_NetSts);
1040 printf("%s: network status, NetSts=%x\n",
1041 sc->sc_dev.dv_xname, netstat);
1042 /* Ack interrupts */
1043 tl_intreg_write_byte(sc, TL_INT_NET+TL_INT_NetSts, netstat);
1044 ack++;
1045 }
1046 break;
1047 default:
1048 printf("%s: unhandled interrupt code %x!\n",
1049 sc->sc_dev.dv_xname, int_type);
1050 ack++;
1051 }
1052
1053 if (ack) {
1054 /* Ack the interrupt and enable interrupts */
1055 TL_HR_WRITE(sc, TL_HOST_CMD, ack | int_type | HOST_CMD_ACK |
1056 HOST_CMD_IntOn);
1057 return 1;
1058 }
1059 /* ack = 0 ; interrupt was perhaps not our. Just enable interrupts */
1060 TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_IntOn);
1061 return 0;
1062 }
1063
1064 static int
1065 tl_ifioctl(ifp, cmd, data)
1066 struct ifnet *ifp;
1067 ioctl_cmd_t cmd;
1068 caddr_t data;
1069 {
1070 struct tl_softc *sc = ifp->if_softc;
1071 struct ifreq *ifr = (struct ifreq *)data;
1072 int s, error;
1073
1074 s = splimp();
1075 switch(cmd) {
1076 case SIOCSIFADDR: {
1077 struct ifaddr *ifa = (struct ifaddr *)data;
1078 sc->tl_if.if_flags |= IFF_UP;
1079 if ((error = tl_init(sc)) != NULL) {
1080 sc->tl_if.if_flags &= ~IFF_UP;
1081 break;
1082 }
1083 switch (ifa->ifa_addr->sa_family) {
1084 #ifdef INET
1085 case AF_INET:
1086 arp_ifinit(ifp, ifa);
1087 break;
1088 #endif
1089 #ifdef NS
1090 case AF_NS: {
1091 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
1092
1093 if (ns_nullhost(*ina))
1094 ina->x_host = *(union ns_host*) LLADDR(ifp->if_sadl);
1095 else
1096 bcopy(ina->x_host.c_host, LLADDR(ifp->if_sadl),
1097 ifp->if_addrlen);
1098 break;
1099 }
1100 #endif
1101 default:
1102 break;
1103 }
1104 break;
1105 }
1106 case SIOCSIFFLAGS:
1107 {
1108 u_int8_t reg;
1109 /*
1110 * If interface is marked up and not running, then start it.
1111 * If it is marked down and running, stop it.
1112 */
1113 if (ifp->if_flags & IFF_UP) {
1114 if ((ifp->if_flags & IFF_RUNNING) == 0) {
1115 error = tl_init(sc);
1116 /* all flags have been handled by init */
1117 break;
1118 }
1119 error = 0;
1120 reg = tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetCmd);
1121 if (ifp->if_flags & IFF_PROMISC)
1122 reg |= TL_NETCOMMAND_CAF;
1123 else
1124 reg &= ~TL_NETCOMMAND_CAF;
1125 tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetCmd, reg);
1126 #ifdef TL_PRIV_STATS
1127 if (ifp->if_flags & IFF_LINK0) {
1128 ifp->if_flags &= ~IFF_LINK0;
1129 printf("%s errors statistics\n", sc->sc_dev.dv_xname);
1130 printf(" %4d RX buffer overrun\n",sc->ierr_overr);
1131 printf(" %4d RX code error\n", sc->ierr_code);
1132 printf(" %4d RX crc error\n", sc->ierr_crc);
1133 printf(" %4d RX out of memory\n", sc->ierr_nomem);
1134 printf(" %4d TX buffer underrun\n", sc->oerr_underr);
1135 printf(" %4d TX deffered frames\n", sc->oerr_deffered);
1136 printf(" %4d TX single collisions\n", sc->oerr_coll);
1137 printf(" %4d TX multi collisions\n", sc->oerr_multicoll);
1138 printf(" %4d TX exessive collisions\n", sc->oerr_exesscoll);
1139 printf(" %4d TX late collisions\n", sc->oerr_latecoll);
1140 printf(" %4d TX carrier loss\n", sc->oerr_carrloss);
1141 printf(" %4d TX mbuf copy\n", sc->oerr_mcopy);
1142 }
1143 #endif
1144 } else {
1145 if (ifp->if_flags & IFF_RUNNING)
1146 tl_shutdown(sc);
1147 error = 0;
1148 }
1149 break;
1150 }
1151 case SIOCADDMULTI:
1152 case SIOCDELMULTI:
1153 /*
1154 * Update multicast listeners
1155 */
1156 if (cmd == SIOCADDMULTI)
1157 error = ether_addmulti(ifr, &sc->tl_ec);
1158 else
1159 error = ether_delmulti(ifr, &sc->tl_ec);
1160 if (error == ENETRESET) {
1161 tl_addr_filter(sc);
1162 error = 0;
1163 }
1164 break;
1165 case SIOCSIFMEDIA:
1166 case SIOCGIFMEDIA:
1167 error = ifmedia_ioctl(ifp, ifr, &sc->tl_ifmedia, cmd);
1168 break;
1169 default:
1170 error = EINVAL;
1171 }
1172 splx(s);
1173 return error;
1174 }
1175
1176 static void
1177 tl_ifstart(ifp)
1178 struct ifnet *ifp;
1179 {
1180 tl_softc_t *sc = ifp->if_softc;
1181 struct mbuf *m, *mb_head;
1182 struct Tx_list *Tx;
1183 int segment, size;
1184
1185 txloop:
1186 /* If we don't have more space ... */
1187 if (sc->Free_Tx == NULL) {
1188 #ifdef TLDEBUG
1189 printf("tl_ifstart: No free TX list\n");
1190 #endif
1191 return;
1192 }
1193 /* Grab a paquet for output */
1194 IF_DEQUEUE(&ifp->if_snd, mb_head);
1195 if (mb_head == NULL) {
1196 #ifdef TLDEBUG_TX
1197 printf("tl_ifstart: nothing to send\n");
1198 #endif
1199 return;
1200 }
1201 Tx = sc->Free_Tx;
1202 sc->Free_Tx = Tx->next;
1203 /*
1204 * Go through each of the mbufs in the chain and initialize
1205 * the transmit list descriptors with the physical address
1206 * and size of the mbuf.
1207 */
1208 tbdinit:
1209 bzero(Tx, sizeof(struct Tx_list));
1210 Tx->m = mb_head;
1211 size = 0;
1212 for (m = mb_head, segment = 0; m != NULL ; m = m->m_next) {
1213 if (m->m_len != 0) {
1214 if (segment == TL_NSEG)
1215 break;
1216 size += m->m_len;
1217 Tx->hw_list.seg[segment].data_addr =
1218 vtophys(mtod(m, vm_offset_t));
1219 Tx->hw_list.seg[segment].data_count = m->m_len;
1220 segment++;
1221 }
1222 }
1223 if (m != NULL || (size < ETHER_MIN_TX && segment == TL_NSEG)) {
1224 /*
1225 * We ran out of segments, or we will. We have to recopy this mbuf
1226 * chain first.
1227 */
1228 struct mbuf *mn;
1229 #ifdef TLDEBUG_TX
1230 printf("tl_ifstart: need to copy mbuf\n");
1231 #endif
1232 #ifdef TL_PRIV_STATS
1233 sc->oerr_mcopy++;
1234 #endif
1235 MGETHDR(mn, M_DONTWAIT, MT_DATA);
1236 if (mn == NULL) {
1237 m_freem(mb_head);
1238 goto bad;
1239 }
1240 if (mb_head->m_pkthdr.len > MHLEN) {
1241 MCLGET(mn, M_DONTWAIT);
1242 if ((mn->m_flags & M_EXT) == 0) {
1243 m_freem(mn);
1244 m_freem(mb_head);
1245 goto bad;
1246 }
1247 }
1248 m_copydata(mb_head, 0, mb_head->m_pkthdr.len,
1249 mtod(mn, caddr_t));
1250 mn->m_pkthdr.len = mn->m_len = mb_head->m_pkthdr.len;
1251 m_freem(mb_head);
1252 mb_head = mn;
1253 goto tbdinit;
1254 }
1255 /* We are at end of mbuf chain. check the size and
1256 * see if it needs to be extended
1257 */
1258 if (size < ETHER_MIN_TX) {
1259 #ifdef DIAGNOSTIC
1260 if (segment >= TL_NSEG) {
1261 panic("tl_ifstart: to much segmets (%d)\n", segment);
1262 }
1263 #endif
1264 /*
1265 * add the nullbuf in the seg
1266 */
1267 Tx->hw_list.seg[segment].data_count =
1268 ETHER_MIN_TX - size;
1269 Tx->hw_list.seg[segment].data_addr =
1270 vtophys(nullbuf);
1271 size = ETHER_MIN_TX;
1272 segment++;
1273 }
1274 /* The list is done, finish the list init */
1275 Tx->hw_list.seg[segment-1].data_count |=
1276 TL_LAST_SEG;
1277 Tx->hw_list.stat = (size << 16) | 0x3000;
1278 #ifdef TLDEBUG_TX
1279 printf("%s: sending, Tx : stat = 0x%x\n", sc->sc_dev.dv_xname,
1280 Tx->hw_list.stat);
1281 #if 0
1282 for(segment = 0; segment < TL_NSEG; segment++) {
1283 printf(" seg %d addr 0x%x len 0x%x\n",
1284 segment,
1285 Tx->hw_list.seg[segment].data_addr,
1286 Tx->hw_list.seg[segment].data_count);
1287 }
1288 #endif
1289 #endif
1290 sc->opkt++;
1291 if (sc->active_Tx == NULL) {
1292 sc->active_Tx = sc->last_Tx = Tx;
1293 #ifdef TLDEBUG_TX
1294 printf("%s: Tx GO, addr=0x%x\n", sc->sc_dev.dv_xname,
1295 vtophys(&Tx->hw_list));
1296 #endif
1297 TL_HR_WRITE(sc, TL_HOST_CH_PARM, vtophys(&Tx->hw_list));
1298 TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_GO);
1299 } else {
1300 #ifdef TLDEBUG_TX
1301 printf("%s: Tx addr=0x%x queued\n", sc->sc_dev.dv_xname,
1302 vtophys(&Tx->hw_list));
1303 #endif
1304 sc->last_Tx->hw_list.fwd = vtophys(&Tx->hw_list);
1305 sc->last_Tx->next = Tx;
1306 sc->last_Tx = Tx;
1307 #ifdef DIAGNOSTIC
1308 if (sc->last_Tx->hw_list.fwd & 0x7)
1309 printf("%s: physical addr 0x%x of list not properly aligned\n",
1310 sc->sc_dev.dv_xname, sc->last_Rx->hw_list.fwd);
1311 #endif
1312 }
1313 #if NBPFILTER > 0
1314 /* Pass packet to bpf if there is a listener */
1315 if (ifp->if_bpf)
1316 bpf_mtap(ifp->if_bpf, mb_head);
1317 #endif
1318 /* Set a 5 second timer just in case we don't hear from the card again. */
1319 ifp->if_timer = 5;
1320
1321 goto txloop;
1322 bad:
1323 #ifdef TLDEBUG
1324 printf("tl_ifstart: Out of mbuf, Tx pkt lost\n");
1325 #endif
1326 Tx->next = sc->Free_Tx;
1327 sc->Free_Tx = Tx;
1328 return;
1329 }
1330
1331 static void
1332 tl_ifwatchdog(ifp)
1333 struct ifnet *ifp;
1334 {
1335 tl_softc_t *sc = ifp->if_softc;
1336
1337 if ((ifp->if_flags & IFF_RUNNING) == 0)
1338 return;
1339 printf("%s: device timeout\n", sc->sc_dev.dv_xname);
1340 ifp->if_oerrors++;
1341 tl_init(sc);
1342 }
1343
1344 static int
1345 tl_mediachange(ifp)
1346 struct ifnet *ifp;
1347 {
1348
1349 tl_softc_t *sc = ifp->if_softc;
1350 int err;
1351 u_int32_t reg;
1352 int oldmedia;
1353 #ifdef TLDEBUG
1354 printf("tl_mediachange, media %x\n", sc->tl_ifmedia.ifm_media);
1355 #endif
1356 oldmedia = sc->mii.mii_media_active;
1357 sc->mii.mii_media_active = sc->tl_ifmedia.ifm_media;
1358 if ((err = mii_mediachg(&sc->mii)) != 0)
1359 sc->mii.mii_media_active = oldmedia;
1360 reg = tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetCmd);
1361 if (sc->mii.mii_media_active & IFM_FDX)
1362 reg |= TL_NETCOMMAND_DUPLEX;
1363 else
1364 reg &= ~TL_NETCOMMAND_DUPLEX;
1365 tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetCmd, reg);
1366 return err;
1367 }
1368
1369 static void
1370 tl_mediastatus(ifp, ifmr)
1371 struct ifnet *ifp;
1372 struct ifmediareq *ifmr;
1373 {
1374 tl_softc_t *sc = ifp->if_softc;
1375 if (IFM_SUBTYPE(sc->mii.mii_media_active) == IFM_10_2 ||
1376 IFM_SUBTYPE(sc->mii.mii_media_active) == IFM_10_5)
1377 if (sc->tl_flags & TL_IFACT)
1378 sc->mii.mii_media_status = IFM_AVALID | IFM_ACTIVE;
1379 else
1380 sc->mii.mii_media_status = IFM_AVALID;
1381 else
1382 mii_pollstat(&sc->mii);
1383
1384 ifmr->ifm_active = sc->mii.mii_media_active;
1385 ifmr->ifm_status = sc->mii.mii_media_status;
1386 }
1387
1388 static int tl_add_RxBuff(Rx, oldm)
1389 struct Rx_list *Rx;
1390 struct mbuf *oldm;
1391 {
1392 struct mbuf *m;
1393
1394 MGETHDR(m, M_DONTWAIT, MT_DATA);
1395 if (m != NULL) {
1396 MCLGET(m, M_DONTWAIT);
1397 if ((m->m_flags & M_EXT) == 0) {
1398 m_freem(m);
1399 if (oldm == NULL)
1400 return 0;
1401 m = oldm;
1402 m->m_data = m->m_ext.ext_buf;
1403 }
1404 } else {
1405 if (oldm == NULL)
1406 return 0;
1407 m = oldm;
1408 m->m_data = m->m_ext.ext_buf;
1409 }
1410 /*
1411 * Move the data pointer up so that the incoming data packet
1412 * will be 32-bit aligned.
1413 */
1414 m->m_data += 2;
1415
1416 /* (re)init the Rx_list struct */
1417
1418 Rx->m = m;
1419 Rx->hw_list.stat = ((MCLBYTES -2) << 16) | 0x3000;
1420 Rx->hw_list.seg.data_count = (MCLBYTES -2);
1421 Rx->hw_list.seg.data_addr = vtophys(m->m_data);
1422 return (m != oldm);
1423 }
1424
1425 static void tl_ticks(v)
1426 void *v;
1427 {
1428 tl_softc_t *sc = v;
1429
1430 tl_read_stats(sc);
1431 if (sc->opkt > 0) {
1432 if (sc->oerr_exesscoll > sc->opkt / 100) { /* exess collisions */
1433 if (sc->tl_flags & TL_IFACT) /* only print once */
1434 printf("%s: no carrier\n", sc->sc_dev.dv_xname);
1435 sc->tl_flags &= ~TL_IFACT;
1436 } else
1437 sc->tl_flags |= TL_IFACT;
1438 sc->oerr_exesscoll = sc->opkt = 0;
1439 sc->tl_lasttx = 0;
1440 } else {
1441 sc->tl_lasttx++;
1442 if (sc->tl_lasttx >= TL_IDLETIME) {
1443 /*
1444 * No TX activity in the last TL_IDLETIME seconds.
1445 * sends a LLC Class1 TEST pkt
1446 */
1447 struct mbuf *m;
1448 int s;
1449 MGETHDR(m, M_DONTWAIT, MT_DATA);
1450 if (m != NULL) {
1451 #ifdef TLDEBUG
1452 printf("tl_ticks: sending LLC test pkt\n");
1453 #endif
1454 bcopy(sc->tl_enaddr,
1455 mtod(m, struct ether_header *)->ether_dhost, 6);
1456 bcopy(sc->tl_enaddr,
1457 mtod(m, struct ether_header *)->ether_shost, 6);
1458 mtod(m, struct ether_header *)->ether_type = htons(3);
1459 mtod(m, unsigned char *)[14] = 0;
1460 mtod(m, unsigned char *)[15] = 0;
1461 mtod(m, unsigned char *)[16] = 0xE3;
1462 /* LLC Class1 TEST (no poll) */
1463 m->m_len = m->m_pkthdr.len = sizeof(struct ether_header) + 3;
1464 s = splnet();
1465 IF_PREPEND(&sc->tl_if.if_snd, m);
1466 tl_ifstart(&sc->tl_if);
1467 splx(s);
1468 }
1469 }
1470 }
1471
1472 /* read statistics every seconds */
1473 timeout(tl_ticks, v, hz);
1474 }
1475
1476 static void
1477 tl_read_stats(sc)
1478 tl_softc_t *sc;
1479 {
1480 u_int32_t reg;
1481 int ierr_overr;
1482 int ierr_code;
1483 int ierr_crc;
1484 int oerr_underr;
1485 int oerr_deffered;
1486 int oerr_coll;
1487 int oerr_multicoll;
1488 int oerr_exesscoll;
1489 int oerr_latecoll;
1490 int oerr_carrloss;
1491 struct ifnet *ifp = &sc->tl_if;
1492
1493 reg = tl_intreg_read(sc, TL_INT_STATS_TX);
1494 ifp->if_opackets += reg & 0x00ffffff;
1495 oerr_underr = reg >> 24;
1496
1497 reg = tl_intreg_read(sc, TL_INT_STATS_RX);
1498 ifp->if_ipackets += reg & 0x00ffffff;
1499 ierr_overr = reg >> 24;
1500
1501 reg = tl_intreg_read(sc, TL_INT_STATS_FERR);
1502 ierr_crc = (reg & TL_FERR_CRC) >> 16;
1503 ierr_code = (reg & TL_FERR_CODE) >> 24;
1504 oerr_deffered = (reg & TL_FERR_DEF);
1505
1506 reg = tl_intreg_read(sc, TL_INT_STATS_COLL);
1507 oerr_multicoll = (reg & TL_COL_MULTI);
1508 oerr_coll = (reg & TL_COL_SINGLE) >> 16;
1509
1510 reg = tl_intreg_read(sc, TL_INT_LERR);
1511 oerr_exesscoll = (reg & TL_LERR_ECOLL);
1512 oerr_latecoll = (reg & TL_LERR_LCOLL) >> 8;
1513 oerr_carrloss = (reg & TL_LERR_CL) >> 16;
1514
1515
1516 sc->stats_exesscoll += oerr_exesscoll;
1517 ifp->if_oerrors += oerr_underr + oerr_exesscoll + oerr_latecoll +
1518 oerr_carrloss;
1519 ifp->if_collisions += oerr_coll + oerr_multicoll;
1520 ifp->if_ierrors += ierr_overr + ierr_code + ierr_crc;
1521
1522 if (ierr_overr)
1523 printf("%s: receiver ring buffer overrun\n", sc->sc_dev.dv_xname);
1524 if (oerr_underr)
1525 printf("%s: transmit buffer underrun\n", sc->sc_dev.dv_xname);
1526 #ifdef TL_PRIV_STATS
1527 sc->ierr_overr += ierr_overr;
1528 sc->ierr_code += ierr_code;
1529 sc->ierr_crc += ierr_crc;
1530 sc->oerr_underr += oerr_underr;
1531 sc->oerr_deffered += oerr_deffered;
1532 sc->oerr_coll += oerr_coll;
1533 sc->oerr_multicoll += oerr_multicoll;
1534 sc->oerr_exesscoll += oerr_exesscoll;
1535 sc->oerr_latecoll += oerr_latecoll;
1536 sc->oerr_carrloss += oerr_carrloss;
1537 #endif
1538 }
1539
1540 static void tl_addr_filter(sc)
1541 tl_softc_t *sc;
1542 {
1543 struct ether_multistep step;
1544 struct ether_multi *enm;
1545 u_int32_t hash[2] = {0, 0};
1546 int i;
1547
1548 sc->tl_if.if_flags &= ~IFF_ALLMULTI;
1549 ETHER_FIRST_MULTI(step, &sc->tl_ec, enm);
1550 while (enm != NULL) {
1551 #ifdef TLDEBUG
1552 printf("tl_addr_filter: addrs %s %s\n", ether_sprintf(enm->enm_addrlo), ether_sprintf(enm->enm_addrhi));
1553 #endif
1554 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 6) == 0) {
1555 i = tl_multicast_hash(enm->enm_addrlo);
1556 hash[i/32] |= 1 << (i%32);
1557 } else {
1558 hash[0] = hash[1] = 0xffffffff;
1559 sc->tl_if.if_flags |= IFF_ALLMULTI;
1560 break;
1561 }
1562 ETHER_NEXT_MULTI(step, enm);
1563 }
1564 #ifdef TLDEBUG
1565 printf("tl_addr_filer: hash1 %x has2 %x\n", hash[0], hash[1]);
1566 #endif
1567 tl_intreg_write(sc, TL_INT_HASH1, hash[0]);
1568 tl_intreg_write(sc, TL_INT_HASH2, hash[1]);
1569 }
1570
1571 static int tl_multicast_hash(a)
1572 u_int8_t *a;
1573 {
1574 int hash;
1575
1576 #define DA(addr,bit) (addr[5 - (bit/8)] & (1 << bit%8))
1577 #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)
1578
1579 hash = xor8( DA(a,0), DA(a, 6), DA(a,12), DA(a,18), DA(a,24), DA(a,30),
1580 DA(a,36), DA(a,42));
1581 hash |= xor8( DA(a,1), DA(a, 7), DA(a,13), DA(a,19), DA(a,25), DA(a,31),
1582 DA(a,37), DA(a,43)) << 1;
1583 hash |= xor8( DA(a,2), DA(a, 8), DA(a,14), DA(a,20), DA(a,26), DA(a,32),
1584 DA(a,38), DA(a,44)) << 2;
1585 hash |= xor8( DA(a,3), DA(a, 9), DA(a,15), DA(a,21), DA(a,27), DA(a,33),
1586 DA(a,39), DA(a,45)) << 3;
1587 hash |= xor8( DA(a,4), DA(a,10), DA(a,16), DA(a,22), DA(a,28), DA(a,34),
1588 DA(a,40), DA(a,46)) << 4;
1589 hash |= xor8( DA(a,5), DA(a,11), DA(a,17), DA(a,23), DA(a,29), DA(a,35),
1590 DA(a,41), DA(a,47)) << 5;
1591
1592 return hash;
1593 }
1594
1595 #if defined(TLDEBUG_RX)
1596 void ether_printheader(eh)
1597 struct ether_header *eh;
1598 {
1599 u_char *c = (char*)eh;
1600 int i;
1601 for (i=0; i<sizeof(struct ether_header); i++)
1602 printf("%x ", (u_int)c[i]);
1603 printf("\n");
1604 }
1605 #endif
1606