xref: /dragonfly/sys/dev/netif/txp/if_txp.c (revision 1bf4b486)
1 /*	$OpenBSD: if_txp.c,v 1.48 2001/06/27 06:34:50 kjc Exp $	*/
2 /*	$FreeBSD: src/sys/dev/txp/if_txp.c,v 1.4.2.4 2001/12/14 19:50:43 jlemon Exp $ */
3 /*	$DragonFly: src/sys/dev/netif/txp/if_txp.c,v 1.30 2005/06/20 15:10:41 joerg Exp $ */
4 
5 /*
6  * Copyright (c) 2001
7  *	Jason L. Wright <jason@thought.net>, Theo de Raadt, and
8  *	Aaron Campbell <aaron@monkey.org>.  All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by Jason L. Wright,
21  *	Theo de Raadt and Aaron Campbell.
22  * 4. Neither the name of the author nor the names of any co-contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
27  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36  * THE POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*
40  * Driver for 3c990 (Typhoon) Ethernet ASIC
41  */
42 
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/sockio.h>
46 #include <sys/mbuf.h>
47 #include <sys/malloc.h>
48 #include <sys/kernel.h>
49 #include <sys/socket.h>
50 #include <sys/thread2.h>
51 
52 #include <net/if.h>
53 #include <net/ifq_var.h>
54 #include <net/if_arp.h>
55 #include <net/ethernet.h>
56 #include <net/if_dl.h>
57 #include <net/if_types.h>
58 #include <net/vlan/if_vlan_var.h>
59 
60 #include <netinet/in.h>
61 #include <netinet/in_systm.h>
62 #include <netinet/in_var.h>
63 #include <netinet/ip.h>
64 #include <netinet/if_ether.h>
65 #include <sys/in_cksum.h>
66 
67 #include <net/if_media.h>
68 
69 #include <net/bpf.h>
70 
71 #include <vm/vm.h>              /* for vtophys */
72 #include <vm/pmap.h>            /* for vtophys */
73 #include <machine/bus_pio.h>
74 #include <machine/bus_memio.h>
75 #include <machine/bus.h>
76 #include <machine/resource.h>
77 #include <sys/bus.h>
78 #include <sys/rman.h>
79 
80 #include "../mii_layer/mii.h"
81 #include "../mii_layer/miivar.h"
82 #include <bus/pci/pcireg.h>
83 #include <bus/pci/pcivar.h>
84 
85 #define TXP_USEIOSPACE
86 #define __STRICT_ALIGNMENT
87 
88 #include "if_txpreg.h"
89 #include "3c990img.h"
90 
91 /*
92  * Various supported device vendors/types and their names.
93  */
94 static struct txp_type txp_devs[] = {
95 	{ TXP_VENDORID_3COM, TXP_DEVICEID_3CR990_TX_95,
96 	    "3Com 3cR990-TX-95 Etherlink with 3XP Processor" },
97 	{ TXP_VENDORID_3COM, TXP_DEVICEID_3CR990_TX_97,
98 	    "3Com 3cR990-TX-97 Etherlink with 3XP Processor" },
99 	{ TXP_VENDORID_3COM, TXP_DEVICEID_3CR990B_TXM,
100 	    "3Com 3cR990B-TXM Etherlink with 3XP Processor" },
101 	{ TXP_VENDORID_3COM, TXP_DEVICEID_3CR990_SRV_95,
102 	    "3Com 3cR990-SRV-95 Etherlink Server with 3XP Processor" },
103 	{ TXP_VENDORID_3COM, TXP_DEVICEID_3CR990_SRV_97,
104 	    "3Com 3cR990-SRV-97 Etherlink Server with 3XP Processor" },
105 	{ TXP_VENDORID_3COM, TXP_DEVICEID_3CR990B_SRV,
106 	    "3Com 3cR990B-SRV Etherlink Server with 3XP Processor" },
107 	{ 0, 0, NULL }
108 };
109 
110 static int txp_probe	(device_t);
111 static int txp_attach	(device_t);
112 static int txp_detach	(device_t);
113 static void txp_intr	(void *);
114 static void txp_tick	(void *);
115 static int txp_shutdown	(device_t);
116 static int txp_ioctl	(struct ifnet *, u_long, caddr_t, struct ucred *);
117 static void txp_start	(struct ifnet *);
118 static void txp_stop	(struct txp_softc *);
119 static void txp_init	(void *);
120 static void txp_watchdog	(struct ifnet *);
121 
122 static void txp_release_resources (device_t);
123 static int txp_chip_init (struct txp_softc *);
124 static int txp_reset_adapter (struct txp_softc *);
125 static int txp_download_fw (struct txp_softc *);
126 static int txp_download_fw_wait (struct txp_softc *);
127 static int txp_download_fw_section (struct txp_softc *,
128     struct txp_fw_section_header *, int);
129 static int txp_alloc_rings (struct txp_softc *);
130 static int txp_rxring_fill (struct txp_softc *);
131 static void txp_rxring_empty (struct txp_softc *);
132 static void txp_set_filter (struct txp_softc *);
133 
134 static int txp_cmd_desc_numfree (struct txp_softc *);
135 static int txp_command (struct txp_softc *, u_int16_t, u_int16_t, u_int32_t,
136     u_int32_t, u_int16_t *, u_int32_t *, u_int32_t *, int);
137 static int txp_command2 (struct txp_softc *, u_int16_t, u_int16_t,
138     u_int32_t, u_int32_t, struct txp_ext_desc *, u_int8_t,
139     struct txp_rsp_desc **, int);
140 static int txp_response (struct txp_softc *, u_int32_t, u_int16_t, u_int16_t,
141     struct txp_rsp_desc **);
142 static void txp_rsp_fixup (struct txp_softc *, struct txp_rsp_desc *,
143     struct txp_rsp_desc *);
144 static void txp_capabilities (struct txp_softc *);
145 
146 static void txp_ifmedia_sts (struct ifnet *, struct ifmediareq *);
147 static int txp_ifmedia_upd (struct ifnet *);
148 #ifdef TXP_DEBUG
149 static void txp_show_descriptor (void *);
150 #endif
151 static void txp_tx_reclaim (struct txp_softc *, struct txp_tx_ring *);
152 static void txp_rxbuf_reclaim (struct txp_softc *);
153 static void txp_rx_reclaim (struct txp_softc *, struct txp_rx_ring *);
154 
155 #ifdef TXP_USEIOSPACE
156 #define TXP_RES			SYS_RES_IOPORT
157 #define TXP_RID			TXP_PCI_LOIO
158 #else
159 #define TXP_RES			SYS_RES_MEMORY
160 #define TXP_RID			TXP_PCI_LOMEM
161 #endif
162 
163 static device_method_t txp_methods[] = {
164         /* Device interface */
165 	DEVMETHOD(device_probe,		txp_probe),
166 	DEVMETHOD(device_attach,	txp_attach),
167 	DEVMETHOD(device_detach,	txp_detach),
168 	DEVMETHOD(device_shutdown,	txp_shutdown),
169 	{ 0, 0 }
170 };
171 
172 static driver_t txp_driver = {
173 	"txp",
174 	txp_methods,
175 	sizeof(struct txp_softc)
176 };
177 
178 static devclass_t txp_devclass;
179 
180 DECLARE_DUMMY_MODULE(if_txp);
181 DRIVER_MODULE(if_txp, pci, txp_driver, txp_devclass, 0, 0);
182 
183 static int
184 txp_probe(dev)
185 	device_t dev;
186 {
187 	struct txp_type *t;
188 	uint16_t vid, did;
189 
190 	vid = pci_get_vendor(dev);
191 	did = pci_get_device(dev);
192 
193 	for (t = txp_devs; t->txp_name != NULL; ++t) {
194 		if ((vid == t->txp_vid) && (did == t->txp_did)) {
195 			device_set_desc(dev, t->txp_name);
196 			return(0);
197 		}
198 	}
199 
200 	return(ENXIO);
201 }
202 
203 static int
204 txp_attach(dev)
205 	device_t dev;
206 {
207 	struct txp_softc *sc;
208 	struct ifnet *ifp;
209 	uint16_t p1;
210 	uint32_t p2;
211 	uint8_t enaddr[ETHER_ADDR_LEN];
212 	int error = 0, rid;
213 
214 	sc = device_get_softc(dev);
215 	callout_init(&sc->txp_stat_timer);
216 
217 	ifp = &sc->sc_arpcom.ac_if;
218 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
219 
220 	pci_enable_busmaster(dev);
221 
222 	rid = TXP_RID;
223 	sc->sc_res = bus_alloc_resource_any(dev, TXP_RES, &rid, RF_ACTIVE);
224 
225 	if (sc->sc_res == NULL) {
226 		device_printf(dev, "couldn't map ports/memory\n");
227 		return(ENXIO);
228 	}
229 
230 	sc->sc_bt = rman_get_bustag(sc->sc_res);
231 	sc->sc_bh = rman_get_bushandle(sc->sc_res);
232 
233 	/* Allocate interrupt */
234 	rid = 0;
235 	sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
236 	    RF_SHAREABLE | RF_ACTIVE);
237 
238 	if (sc->sc_irq == NULL) {
239 		device_printf(dev, "couldn't map interrupt\n");
240 		error = ENXIO;
241 		goto fail;
242 	}
243 
244 	if (txp_chip_init(sc)) {
245 		error = ENXIO;
246 		goto fail;
247 	}
248 
249 	sc->sc_fwbuf = contigmalloc(32768, M_DEVBUF,
250 	    M_WAITOK, 0, 0xffffffff, PAGE_SIZE, 0);
251 	error = txp_download_fw(sc);
252 	contigfree(sc->sc_fwbuf, 32768, M_DEVBUF);
253 	sc->sc_fwbuf = NULL;
254 
255 	if (error)
256 		goto fail;
257 
258 	sc->sc_ldata = contigmalloc(sizeof(struct txp_ldata), M_DEVBUF,
259 	    M_WAITOK, 0, 0xffffffff, PAGE_SIZE, 0);
260 	bzero(sc->sc_ldata, sizeof(struct txp_ldata));
261 
262 	if (txp_alloc_rings(sc)) {
263 		error = ENXIO;
264 		goto fail;
265 	}
266 
267 	if (txp_command(sc, TXP_CMD_MAX_PKT_SIZE_WRITE, TXP_MAX_PKTLEN, 0, 0,
268 	    NULL, NULL, NULL, 1)) {
269 		error = ENXIO;
270 		goto fail;
271 	}
272 
273 	if (txp_command(sc, TXP_CMD_STATION_ADDRESS_READ, 0, 0, 0,
274 	    &p1, &p2, NULL, 1)) {
275 		error = ENXIO;
276 		goto fail;
277 	}
278 
279 	txp_set_filter(sc);
280 
281 	enaddr[0] = ((uint8_t *)&p1)[1];
282 	enaddr[1] = ((uint8_t *)&p1)[0];
283 	enaddr[2] = ((uint8_t *)&p2)[3];
284 	enaddr[3] = ((uint8_t *)&p2)[2];
285 	enaddr[4] = ((uint8_t *)&p2)[1];
286 	enaddr[5] = ((uint8_t *)&p2)[0];
287 
288 	ifmedia_init(&sc->sc_ifmedia, 0, txp_ifmedia_upd, txp_ifmedia_sts);
289 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
290 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
291 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
292 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL);
293 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX|IFM_HDX, 0, NULL);
294 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
295 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
296 
297 	sc->sc_xcvr = TXP_XCVR_AUTO;
298 	txp_command(sc, TXP_CMD_XCVR_SELECT, TXP_XCVR_AUTO, 0, 0,
299 	    NULL, NULL, NULL, 0);
300 	ifmedia_set(&sc->sc_ifmedia, IFM_ETHER|IFM_AUTO);
301 
302 	ifp->if_softc = sc;
303 	ifp->if_mtu = ETHERMTU;
304 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
305 	ifp->if_ioctl = txp_ioctl;
306 	ifp->if_start = txp_start;
307 	ifp->if_watchdog = txp_watchdog;
308 	ifp->if_init = txp_init;
309 	ifp->if_baudrate = 100000000;
310 	ifq_set_maxlen(&ifp->if_snd, TX_ENTRIES);
311 	ifq_set_ready(&ifp->if_snd);
312 	ifp->if_hwassist = 0;
313 	txp_capabilities(sc);
314 
315 	ether_ifattach(ifp, enaddr);
316 
317 	error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_NET,
318 			       txp_intr, sc, &sc->sc_intrhand, NULL);
319 	if (error) {
320 		device_printf(dev, "couldn't set up irq\n");
321 		ether_ifdetach(ifp);
322 		goto fail;
323 	}
324 
325 	return(0);
326 
327 fail:
328 	txp_release_resources(dev);
329 	return(error);
330 }
331 
332 static int
333 txp_detach(dev)
334 	device_t dev;
335 {
336 	struct txp_softc *sc;
337 	struct ifnet *ifp;
338 	int i;
339 
340 	crit_enter();
341 
342 	sc = device_get_softc(dev);
343 	ifp = &sc->sc_arpcom.ac_if;
344 
345 	txp_stop(sc);
346 	txp_shutdown(dev);
347 
348 	ifmedia_removeall(&sc->sc_ifmedia);
349 	ether_ifdetach(ifp);
350 
351 	for (i = 0; i < RXBUF_ENTRIES; i++)
352 		free(sc->sc_rxbufs[i].rb_sd, M_DEVBUF);
353 
354 	txp_release_resources(dev);
355 
356 	crit_exit();
357 
358 	return(0);
359 }
360 
361 static void
362 txp_release_resources(device_t dev)
363 {
364 	struct txp_softc *sc;
365 
366 	sc = device_get_softc(dev);
367 
368 	if (sc->sc_intrhand != NULL)
369 		bus_teardown_intr(dev, sc->sc_irq, sc->sc_intrhand);
370 
371 	if (sc->sc_irq != NULL)
372 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq);
373 
374 	if (sc->sc_res != NULL)
375 		bus_release_resource(dev, TXP_RES, TXP_RID, sc->sc_res);
376 
377 	if (sc->sc_ldata != NULL)
378 		contigfree(sc->sc_ldata, sizeof(struct txp_ldata), M_DEVBUF);
379 
380 	return;
381 }
382 
383 static int
384 txp_chip_init(sc)
385 	struct txp_softc *sc;
386 {
387 	/* disable interrupts */
388 	WRITE_REG(sc, TXP_IER, 0);
389 	WRITE_REG(sc, TXP_IMR,
390 	    TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT |
391 	    TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 |
392 	    TXP_INT_LATCH);
393 
394 	/* ack all interrupts */
395 	WRITE_REG(sc, TXP_ISR, TXP_INT_RESERVED | TXP_INT_LATCH |
396 	    TXP_INT_A2H_7 | TXP_INT_A2H_6 | TXP_INT_A2H_5 | TXP_INT_A2H_4 |
397 	    TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT |
398 	    TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 |
399 	    TXP_INT_A2H_3 | TXP_INT_A2H_2 | TXP_INT_A2H_1 | TXP_INT_A2H_0);
400 
401 	if (txp_reset_adapter(sc))
402 		return (-1);
403 
404 	/* disable interrupts */
405 	WRITE_REG(sc, TXP_IER, 0);
406 	WRITE_REG(sc, TXP_IMR,
407 	    TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT |
408 	    TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 |
409 	    TXP_INT_LATCH);
410 
411 	/* ack all interrupts */
412 	WRITE_REG(sc, TXP_ISR, TXP_INT_RESERVED | TXP_INT_LATCH |
413 	    TXP_INT_A2H_7 | TXP_INT_A2H_6 | TXP_INT_A2H_5 | TXP_INT_A2H_4 |
414 	    TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT |
415 	    TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 |
416 	    TXP_INT_A2H_3 | TXP_INT_A2H_2 | TXP_INT_A2H_1 | TXP_INT_A2H_0);
417 
418 	return (0);
419 }
420 
421 static int
422 txp_reset_adapter(sc)
423 	struct txp_softc *sc;
424 {
425 	u_int32_t r;
426 	int i;
427 
428 	WRITE_REG(sc, TXP_SRR, TXP_SRR_ALL);
429 	DELAY(1000);
430 	WRITE_REG(sc, TXP_SRR, 0);
431 
432 	/* Should wait max 6 seconds */
433 	for (i = 0; i < 6000; i++) {
434 		r = READ_REG(sc, TXP_A2H_0);
435 		if (r == STAT_WAITING_FOR_HOST_REQUEST)
436 			break;
437 		DELAY(1000);
438 	}
439 
440 	if (r != STAT_WAITING_FOR_HOST_REQUEST) {
441 		if_printf(&sc->sc_arpcom.ac_if, "reset hung\n");
442 		return (-1);
443 	}
444 
445 	return (0);
446 }
447 
448 static int
449 txp_download_fw(sc)
450 	struct txp_softc *sc;
451 {
452 	struct txp_fw_file_header *fileheader;
453 	struct txp_fw_section_header *secthead;
454 	int sect;
455 	u_int32_t r, i, ier, imr;
456 
457 	ier = READ_REG(sc, TXP_IER);
458 	WRITE_REG(sc, TXP_IER, ier | TXP_INT_A2H_0);
459 
460 	imr = READ_REG(sc, TXP_IMR);
461 	WRITE_REG(sc, TXP_IMR, imr | TXP_INT_A2H_0);
462 
463 	for (i = 0; i < 10000; i++) {
464 		r = READ_REG(sc, TXP_A2H_0);
465 		if (r == STAT_WAITING_FOR_HOST_REQUEST)
466 			break;
467 		DELAY(50);
468 	}
469 	if (r != STAT_WAITING_FOR_HOST_REQUEST) {
470 		if_printf(&sc->sc_arpcom.ac_if,
471 			  "not waiting for host request\n");
472 		return (-1);
473 	}
474 
475 	/* Ack the status */
476 	WRITE_REG(sc, TXP_ISR, TXP_INT_A2H_0);
477 
478 	fileheader = (struct txp_fw_file_header *)tc990image;
479 	if (bcmp("TYPHOON", fileheader->magicid, sizeof(fileheader->magicid))) {
480 		if_printf(&sc->sc_arpcom.ac_if, "fw invalid magic\n");
481 		return (-1);
482 	}
483 
484 	/* Tell boot firmware to get ready for image */
485 	WRITE_REG(sc, TXP_H2A_1, fileheader->addr);
486 	WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_RUNTIME_IMAGE);
487 
488 	if (txp_download_fw_wait(sc)) {
489 		if_printf(&sc->sc_arpcom.ac_if, "fw wait failed, initial\n");
490 		return (-1);
491 	}
492 
493 	secthead = (struct txp_fw_section_header *)(((u_int8_t *)tc990image) +
494 	    sizeof(struct txp_fw_file_header));
495 
496 	for (sect = 0; sect < fileheader->nsections; sect++) {
497 		if (txp_download_fw_section(sc, secthead, sect))
498 			return (-1);
499 		secthead = (struct txp_fw_section_header *)
500 		    (((u_int8_t *)secthead) + secthead->nbytes +
501 		    sizeof(*secthead));
502 	}
503 
504 	WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_DOWNLOAD_COMPLETE);
505 
506 	for (i = 0; i < 10000; i++) {
507 		r = READ_REG(sc, TXP_A2H_0);
508 		if (r == STAT_WAITING_FOR_BOOT)
509 			break;
510 		DELAY(50);
511 	}
512 	if (r != STAT_WAITING_FOR_BOOT) {
513 		if_printf(&sc->sc_arpcom.ac_if, "not waiting for boot\n");
514 		return (-1);
515 	}
516 
517 	WRITE_REG(sc, TXP_IER, ier);
518 	WRITE_REG(sc, TXP_IMR, imr);
519 
520 	return (0);
521 }
522 
523 static int
524 txp_download_fw_wait(sc)
525 	struct txp_softc *sc;
526 {
527 	u_int32_t i, r;
528 
529 	for (i = 0; i < 10000; i++) {
530 		r = READ_REG(sc, TXP_ISR);
531 		if (r & TXP_INT_A2H_0)
532 			break;
533 		DELAY(50);
534 	}
535 
536 	if (!(r & TXP_INT_A2H_0)) {
537 		if_printf(&sc->sc_arpcom.ac_if, "fw wait failed comm0\n");
538 		return (-1);
539 	}
540 
541 	WRITE_REG(sc, TXP_ISR, TXP_INT_A2H_0);
542 
543 	r = READ_REG(sc, TXP_A2H_0);
544 	if (r != STAT_WAITING_FOR_SEGMENT) {
545 		if_printf(&sc->sc_arpcom.ac_if, "fw not waiting for segment\n");
546 		return (-1);
547 	}
548 	return (0);
549 }
550 
551 static int
552 txp_download_fw_section(sc, sect, sectnum)
553 	struct txp_softc *sc;
554 	struct txp_fw_section_header *sect;
555 	int sectnum;
556 {
557 	vm_offset_t dma;
558 	int rseg, err = 0;
559 	struct mbuf m;
560 	u_int16_t csum;
561 
562 	/* Skip zero length sections */
563 	if (sect->nbytes == 0)
564 		return (0);
565 
566 	/* Make sure we aren't past the end of the image */
567 	rseg = ((u_int8_t *)sect) - ((u_int8_t *)tc990image);
568 	if (rseg >= sizeof(tc990image)) {
569 		if_printf(&sc->sc_arpcom.ac_if, "fw invalid section address, "
570 		    "section %d\n", sectnum);
571 		return (-1);
572 	}
573 
574 	/* Make sure this section doesn't go past the end */
575 	rseg += sect->nbytes;
576 	if (rseg >= sizeof(tc990image)) {
577 		if_printf(&sc->sc_arpcom.ac_if, "fw truncated section %d\n",
578 		    sectnum);
579 		return (-1);
580 	}
581 
582 	bcopy(((u_int8_t *)sect) + sizeof(*sect), sc->sc_fwbuf, sect->nbytes);
583 	dma = vtophys(sc->sc_fwbuf);
584 
585 	/*
586 	 * dummy up mbuf and verify section checksum
587 	 */
588 	m.m_type = MT_DATA;
589 	m.m_next = m.m_nextpkt = NULL;
590 	m.m_len = sect->nbytes;
591 	m.m_data = sc->sc_fwbuf;
592 	m.m_flags = 0;
593 	csum = in_cksum(&m, sect->nbytes);
594 	if (csum != sect->cksum) {
595 		if_printf(&sc->sc_arpcom.ac_if, "fw section %d, bad "
596 		    "cksum (expected 0x%x got 0x%x)\n",
597 		    sectnum, sect->cksum, csum);
598 		err = -1;
599 		goto bail;
600 	}
601 
602 	WRITE_REG(sc, TXP_H2A_1, sect->nbytes);
603 	WRITE_REG(sc, TXP_H2A_2, sect->cksum);
604 	WRITE_REG(sc, TXP_H2A_3, sect->addr);
605 	WRITE_REG(sc, TXP_H2A_4, 0);
606 	WRITE_REG(sc, TXP_H2A_5, dma & 0xffffffff);
607 	WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_SEGMENT_AVAILABLE);
608 
609 	if (txp_download_fw_wait(sc)) {
610 		if_printf(&sc->sc_arpcom.ac_if, "fw wait failed, "
611 		    "section %d\n", sectnum);
612 		err = -1;
613 	}
614 
615 bail:
616 	return (err);
617 }
618 
619 static void
620 txp_intr(vsc)
621 	void *vsc;
622 {
623 	struct txp_softc *sc = vsc;
624 	struct txp_hostvar *hv = sc->sc_hostvar;
625 	u_int32_t isr;
626 
627 	/* mask all interrupts */
628 	WRITE_REG(sc, TXP_IMR, TXP_INT_RESERVED | TXP_INT_SELF |
629 	    TXP_INT_A2H_7 | TXP_INT_A2H_6 | TXP_INT_A2H_5 | TXP_INT_A2H_4 |
630 	    TXP_INT_A2H_2 | TXP_INT_A2H_1 | TXP_INT_A2H_0 |
631 	    TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 |
632 	    TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT |  TXP_INT_LATCH);
633 
634 	isr = READ_REG(sc, TXP_ISR);
635 	while (isr) {
636 		WRITE_REG(sc, TXP_ISR, isr);
637 
638 		if ((*sc->sc_rxhir.r_roff) != (*sc->sc_rxhir.r_woff))
639 			txp_rx_reclaim(sc, &sc->sc_rxhir);
640 		if ((*sc->sc_rxlor.r_roff) != (*sc->sc_rxlor.r_woff))
641 			txp_rx_reclaim(sc, &sc->sc_rxlor);
642 
643 		if (hv->hv_rx_buf_write_idx == hv->hv_rx_buf_read_idx)
644 			txp_rxbuf_reclaim(sc);
645 
646 		if (sc->sc_txhir.r_cnt && (sc->sc_txhir.r_cons !=
647 		    TXP_OFFSET2IDX(*(sc->sc_txhir.r_off))))
648 			txp_tx_reclaim(sc, &sc->sc_txhir);
649 
650 		if (sc->sc_txlor.r_cnt && (sc->sc_txlor.r_cons !=
651 		    TXP_OFFSET2IDX(*(sc->sc_txlor.r_off))))
652 			txp_tx_reclaim(sc, &sc->sc_txlor);
653 
654 		isr = READ_REG(sc, TXP_ISR);
655 	}
656 
657 	/* unmask all interrupts */
658 	WRITE_REG(sc, TXP_IMR, TXP_INT_A2H_3);
659 
660 	txp_start(&sc->sc_arpcom.ac_if);
661 
662 	return;
663 }
664 
665 static void
666 txp_rx_reclaim(sc, r)
667 	struct txp_softc *sc;
668 	struct txp_rx_ring *r;
669 {
670 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
671 	struct txp_rx_desc *rxd;
672 	struct mbuf *m;
673 	struct txp_swdesc *sd = NULL;
674 	u_int32_t roff, woff;
675 
676 	roff = *r->r_roff;
677 	woff = *r->r_woff;
678 	rxd = r->r_desc + (roff / sizeof(struct txp_rx_desc));
679 
680 	while (roff != woff) {
681 
682 		if (rxd->rx_flags & RX_FLAGS_ERROR) {
683 			if_printf(ifp, "error 0x%x\n", rxd->rx_stat);
684 			ifp->if_ierrors++;
685 			goto next;
686 		}
687 
688 		/* retrieve stashed pointer */
689 		sd = rxd->rx_sd;
690 
691 		m = sd->sd_mbuf;
692 		sd->sd_mbuf = NULL;
693 
694 		m->m_pkthdr.len = m->m_len = rxd->rx_len;
695 
696 #ifdef __STRICT_ALIGNMENT
697 		{
698 			/*
699 			 * XXX Nice chip, except it won't accept "off by 2"
700 			 * buffers, so we're force to copy.  Supposedly
701 			 * this will be fixed in a newer firmware rev
702 			 * and this will be temporary.
703 			 */
704 			struct mbuf *mnew;
705 
706 			MGETHDR(mnew, MB_DONTWAIT, MT_DATA);
707 			if (mnew == NULL) {
708 				m_freem(m);
709 				goto next;
710 			}
711 			if (m->m_len > (MHLEN - 2)) {
712 				MCLGET(mnew, MB_DONTWAIT);
713 				if (!(mnew->m_flags & M_EXT)) {
714 					m_freem(mnew);
715 					m_freem(m);
716 					goto next;
717 				}
718 			}
719 			mnew->m_pkthdr.rcvif = ifp;
720 			m_adj(mnew, 2);
721 			mnew->m_pkthdr.len = mnew->m_len = m->m_len;
722 			m_copydata(m, 0, m->m_pkthdr.len, mtod(mnew, caddr_t));
723 			m_freem(m);
724 			m = mnew;
725 		}
726 #endif
727 
728 		if (rxd->rx_stat & RX_STAT_IPCKSUMBAD)
729 			m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
730 		else if (rxd->rx_stat & RX_STAT_IPCKSUMGOOD)
731 		 	m->m_pkthdr.csum_flags |=
732 			    CSUM_IP_CHECKED|CSUM_IP_VALID;
733 
734 		if ((rxd->rx_stat & RX_STAT_TCPCKSUMGOOD) ||
735 		    (rxd->rx_stat & RX_STAT_UDPCKSUMGOOD)) {
736 			m->m_pkthdr.csum_flags |=
737 			    CSUM_DATA_VALID|CSUM_PSEUDO_HDR;
738 			m->m_pkthdr.csum_data = 0xffff;
739 		}
740 
741 		if (rxd->rx_stat & RX_STAT_VLAN)
742 			VLAN_INPUT_TAG(m, htons(rxd->rx_vlan >> 16));
743 		else
744 			(*ifp->if_input)(ifp, m);
745 
746 next:
747 
748 		roff += sizeof(struct txp_rx_desc);
749 		if (roff == (RX_ENTRIES * sizeof(struct txp_rx_desc))) {
750 			roff = 0;
751 			rxd = r->r_desc;
752 		} else
753 			rxd++;
754 		woff = *r->r_woff;
755 	}
756 
757 	*r->r_roff = woff;
758 
759 	return;
760 }
761 
762 static void
763 txp_rxbuf_reclaim(sc)
764 	struct txp_softc *sc;
765 {
766 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
767 	struct txp_hostvar *hv = sc->sc_hostvar;
768 	struct txp_rxbuf_desc *rbd;
769 	struct txp_swdesc *sd;
770 	u_int32_t i;
771 
772 	if (!(ifp->if_flags & IFF_RUNNING))
773 		return;
774 
775 	i = sc->sc_rxbufprod;
776 	rbd = sc->sc_rxbufs + i;
777 
778 	while (1) {
779 		sd = rbd->rb_sd;
780 		if (sd->sd_mbuf != NULL)
781 			break;
782 
783 		MGETHDR(sd->sd_mbuf, MB_DONTWAIT, MT_DATA);
784 		if (sd->sd_mbuf == NULL)
785 			goto err_sd;
786 
787 		MCLGET(sd->sd_mbuf, MB_DONTWAIT);
788 		if ((sd->sd_mbuf->m_flags & M_EXT) == 0)
789 			goto err_mbuf;
790 		sd->sd_mbuf->m_pkthdr.rcvif = ifp;
791 		sd->sd_mbuf->m_pkthdr.len = sd->sd_mbuf->m_len = MCLBYTES;
792 
793 		rbd->rb_paddrlo = vtophys(mtod(sd->sd_mbuf, vm_offset_t))
794 		    & 0xffffffff;
795 		rbd->rb_paddrhi = 0;
796 
797 		hv->hv_rx_buf_write_idx = TXP_IDX2OFFSET(i);
798 
799 		if (++i == RXBUF_ENTRIES) {
800 			i = 0;
801 			rbd = sc->sc_rxbufs;
802 		} else
803 			rbd++;
804 	}
805 
806 	sc->sc_rxbufprod = i;
807 
808 	return;
809 
810 err_mbuf:
811 	m_freem(sd->sd_mbuf);
812 err_sd:
813 	free(sd, M_DEVBUF);
814 }
815 
816 /*
817  * Reclaim mbufs and entries from a transmit ring.
818  */
819 static void
820 txp_tx_reclaim(sc, r)
821 	struct txp_softc *sc;
822 	struct txp_tx_ring *r;
823 {
824 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
825 	u_int32_t idx = TXP_OFFSET2IDX(*(r->r_off));
826 	u_int32_t cons = r->r_cons, cnt = r->r_cnt;
827 	struct txp_tx_desc *txd = r->r_desc + cons;
828 	struct txp_swdesc *sd = sc->sc_txd + cons;
829 	struct mbuf *m;
830 
831 	while (cons != idx) {
832 		if (cnt == 0)
833 			break;
834 
835 		if ((txd->tx_flags & TX_FLAGS_TYPE_M) ==
836 		    TX_FLAGS_TYPE_DATA) {
837 			m = sd->sd_mbuf;
838 			if (m != NULL) {
839 				m_freem(m);
840 				txd->tx_addrlo = 0;
841 				txd->tx_addrhi = 0;
842 				ifp->if_opackets++;
843 			}
844 		}
845 		ifp->if_flags &= ~IFF_OACTIVE;
846 
847 		if (++cons == TX_ENTRIES) {
848 			txd = r->r_desc;
849 			cons = 0;
850 			sd = sc->sc_txd;
851 		} else {
852 			txd++;
853 			sd++;
854 		}
855 
856 		cnt--;
857 	}
858 
859 	r->r_cons = cons;
860 	r->r_cnt = cnt;
861 	if (cnt == 0)
862 		ifp->if_timer = 0;
863 }
864 
865 static int
866 txp_shutdown(dev)
867 	device_t dev;
868 {
869 	struct txp_softc *sc;
870 
871 	sc = device_get_softc(dev);
872 
873 	/* mask all interrupts */
874 	WRITE_REG(sc, TXP_IMR,
875 	    TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT |
876 	    TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 |
877 	    TXP_INT_LATCH);
878 
879 	txp_command(sc, TXP_CMD_TX_DISABLE, 0, 0, 0, NULL, NULL, NULL, 0);
880 	txp_command(sc, TXP_CMD_RX_DISABLE, 0, 0, 0, NULL, NULL, NULL, 0);
881 	txp_command(sc, TXP_CMD_HALT, 0, 0, 0, NULL, NULL, NULL, 0);
882 
883 	return(0);
884 }
885 
886 static int
887 txp_alloc_rings(sc)
888 	struct txp_softc *sc;
889 {
890 	struct txp_boot_record *boot;
891 	struct txp_ldata *ld;
892 	u_int32_t r;
893 	int i;
894 
895 	ld = sc->sc_ldata;
896 	boot = &ld->txp_boot;
897 
898 	/* boot record */
899 	sc->sc_boot = boot;
900 
901 	/* host variables */
902 	bzero(&ld->txp_hostvar, sizeof(struct txp_hostvar));
903 	boot->br_hostvar_lo = vtophys(&ld->txp_hostvar);
904 	boot->br_hostvar_hi = 0;
905 	sc->sc_hostvar = (struct txp_hostvar *)&ld->txp_hostvar;
906 
907 	/* hi priority tx ring */
908 	boot->br_txhipri_lo = vtophys(&ld->txp_txhiring);;
909 	boot->br_txhipri_hi = 0;
910 	boot->br_txhipri_siz = TX_ENTRIES * sizeof(struct txp_tx_desc);
911 	sc->sc_txhir.r_reg = TXP_H2A_1;
912 	sc->sc_txhir.r_desc = (struct txp_tx_desc *)&ld->txp_txhiring;
913 	sc->sc_txhir.r_cons = sc->sc_txhir.r_prod = sc->sc_txhir.r_cnt = 0;
914 	sc->sc_txhir.r_off = &sc->sc_hostvar->hv_tx_hi_desc_read_idx;
915 
916 	/* lo priority tx ring */
917 	boot->br_txlopri_lo = vtophys(&ld->txp_txloring);
918 	boot->br_txlopri_hi = 0;
919 	boot->br_txlopri_siz = TX_ENTRIES * sizeof(struct txp_tx_desc);
920 	sc->sc_txlor.r_reg = TXP_H2A_3;
921 	sc->sc_txlor.r_desc = (struct txp_tx_desc *)&ld->txp_txloring;
922 	sc->sc_txlor.r_cons = sc->sc_txlor.r_prod = sc->sc_txlor.r_cnt = 0;
923 	sc->sc_txlor.r_off = &sc->sc_hostvar->hv_tx_lo_desc_read_idx;
924 
925 	/* high priority rx ring */
926 	boot->br_rxhipri_lo = vtophys(&ld->txp_rxhiring);
927 	boot->br_rxhipri_hi = 0;
928 	boot->br_rxhipri_siz = RX_ENTRIES * sizeof(struct txp_rx_desc);
929 	sc->sc_rxhir.r_desc = (struct txp_rx_desc *)&ld->txp_rxhiring;
930 	sc->sc_rxhir.r_roff = &sc->sc_hostvar->hv_rx_hi_read_idx;
931 	sc->sc_rxhir.r_woff = &sc->sc_hostvar->hv_rx_hi_write_idx;
932 
933 	/* low priority rx ring */
934 	boot->br_rxlopri_lo = vtophys(&ld->txp_rxloring);
935 	boot->br_rxlopri_hi = 0;
936 	boot->br_rxlopri_siz = RX_ENTRIES * sizeof(struct txp_rx_desc);
937 	sc->sc_rxlor.r_desc = (struct txp_rx_desc *)&ld->txp_rxloring;
938 	sc->sc_rxlor.r_roff = &sc->sc_hostvar->hv_rx_lo_read_idx;
939 	sc->sc_rxlor.r_woff = &sc->sc_hostvar->hv_rx_lo_write_idx;
940 
941 	/* command ring */
942 	bzero(&ld->txp_cmdring, sizeof(struct txp_cmd_desc) * CMD_ENTRIES);
943 	boot->br_cmd_lo = vtophys(&ld->txp_cmdring);
944 	boot->br_cmd_hi = 0;
945 	boot->br_cmd_siz = CMD_ENTRIES * sizeof(struct txp_cmd_desc);
946 	sc->sc_cmdring.base = (struct txp_cmd_desc *)&ld->txp_cmdring;
947 	sc->sc_cmdring.size = CMD_ENTRIES * sizeof(struct txp_cmd_desc);
948 	sc->sc_cmdring.lastwrite = 0;
949 
950 	/* response ring */
951 	bzero(&ld->txp_rspring, sizeof(struct txp_rsp_desc) * RSP_ENTRIES);
952 	boot->br_resp_lo = vtophys(&ld->txp_rspring);
953 	boot->br_resp_hi = 0;
954 	boot->br_resp_siz = CMD_ENTRIES * sizeof(struct txp_rsp_desc);
955 	sc->sc_rspring.base = (struct txp_rsp_desc *)&ld->txp_rspring;
956 	sc->sc_rspring.size = RSP_ENTRIES * sizeof(struct txp_rsp_desc);
957 	sc->sc_rspring.lastwrite = 0;
958 
959 	/* receive buffer ring */
960 	boot->br_rxbuf_lo = vtophys(&ld->txp_rxbufs);
961 	boot->br_rxbuf_hi = 0;
962 	boot->br_rxbuf_siz = RXBUF_ENTRIES * sizeof(struct txp_rxbuf_desc);
963 	sc->sc_rxbufs = (struct txp_rxbuf_desc *)&ld->txp_rxbufs;
964 
965 	for (i = 0; i < RXBUF_ENTRIES; i++) {
966 		struct txp_swdesc *sd;
967 		if (sc->sc_rxbufs[i].rb_sd != NULL)
968 			continue;
969 		sc->sc_rxbufs[i].rb_sd = malloc(sizeof(struct txp_swdesc),
970 		    M_DEVBUF, M_WAITOK);
971 		if (sc->sc_rxbufs[i].rb_sd == NULL)
972 			return(ENOBUFS);
973 		sd = sc->sc_rxbufs[i].rb_sd;
974 		sd->sd_mbuf = NULL;
975 	}
976 	sc->sc_rxbufprod = 0;
977 
978 	/* zero dma */
979 	bzero(&ld->txp_zero, sizeof(u_int32_t));
980 	boot->br_zero_lo = vtophys(&ld->txp_zero);
981 	boot->br_zero_hi = 0;
982 
983 	/* See if it's waiting for boot, and try to boot it */
984 	for (i = 0; i < 10000; i++) {
985 		r = READ_REG(sc, TXP_A2H_0);
986 		if (r == STAT_WAITING_FOR_BOOT)
987 			break;
988 		DELAY(50);
989 	}
990 
991 	if (r != STAT_WAITING_FOR_BOOT) {
992 		if_printf(&sc->sc_arpcom.ac_if, "not waiting for boot\n");
993 		return(ENXIO);
994 	}
995 
996 	WRITE_REG(sc, TXP_H2A_2, 0);
997 	WRITE_REG(sc, TXP_H2A_1, vtophys(sc->sc_boot));
998 	WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_REGISTER_BOOT_RECORD);
999 
1000 	/* See if it booted */
1001 	for (i = 0; i < 10000; i++) {
1002 		r = READ_REG(sc, TXP_A2H_0);
1003 		if (r == STAT_RUNNING)
1004 			break;
1005 		DELAY(50);
1006 	}
1007 	if (r != STAT_RUNNING) {
1008 		if_printf(&sc->sc_arpcom.ac_if, "fw not running\n");
1009 		return(ENXIO);
1010 	}
1011 
1012 	/* Clear TX and CMD ring write registers */
1013 	WRITE_REG(sc, TXP_H2A_1, TXP_BOOTCMD_NULL);
1014 	WRITE_REG(sc, TXP_H2A_2, TXP_BOOTCMD_NULL);
1015 	WRITE_REG(sc, TXP_H2A_3, TXP_BOOTCMD_NULL);
1016 	WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_NULL);
1017 
1018 	return (0);
1019 }
1020 
1021 static int
1022 txp_ioctl(ifp, command, data, cr)
1023 	struct ifnet *ifp;
1024 	u_long command;
1025 	caddr_t data;
1026 	struct ucred *cr;
1027 {
1028 	struct txp_softc *sc = ifp->if_softc;
1029 	struct ifreq *ifr = (struct ifreq *)data;
1030 	int error = 0;
1031 
1032 	crit_enter();
1033 
1034 	switch(command) {
1035 	case SIOCSIFFLAGS:
1036 		if (ifp->if_flags & IFF_UP) {
1037 			txp_init(sc);
1038 		} else {
1039 			if (ifp->if_flags & IFF_RUNNING)
1040 				txp_stop(sc);
1041 		}
1042 		break;
1043 	case SIOCADDMULTI:
1044 	case SIOCDELMULTI:
1045 		/*
1046 		 * Multicast list has changed; set the hardware
1047 		 * filter accordingly.
1048 		 */
1049 		txp_set_filter(sc);
1050 		error = 0;
1051 		break;
1052 	case SIOCGIFMEDIA:
1053 	case SIOCSIFMEDIA:
1054 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, command);
1055 		break;
1056 	default:
1057 		error = ether_ioctl(ifp, command, data);
1058 		break;
1059 	}
1060 
1061 	crit_exit();
1062 
1063 	return(error);
1064 }
1065 
1066 static int
1067 txp_rxring_fill(sc)
1068 	struct txp_softc *sc;
1069 {
1070 	int i;
1071 	struct ifnet *ifp;
1072 	struct txp_swdesc *sd;
1073 
1074 	ifp = &sc->sc_arpcom.ac_if;
1075 
1076 	for (i = 0; i < RXBUF_ENTRIES; i++) {
1077 		sd = sc->sc_rxbufs[i].rb_sd;
1078 		MGETHDR(sd->sd_mbuf, MB_DONTWAIT, MT_DATA);
1079 		if (sd->sd_mbuf == NULL)
1080 			return(ENOBUFS);
1081 
1082 		MCLGET(sd->sd_mbuf, MB_DONTWAIT);
1083 		if ((sd->sd_mbuf->m_flags & M_EXT) == 0) {
1084 			m_freem(sd->sd_mbuf);
1085 			return(ENOBUFS);
1086 		}
1087 		sd->sd_mbuf->m_pkthdr.len = sd->sd_mbuf->m_len = MCLBYTES;
1088 		sd->sd_mbuf->m_pkthdr.rcvif = ifp;
1089 
1090 		sc->sc_rxbufs[i].rb_paddrlo =
1091 		    vtophys(mtod(sd->sd_mbuf, vm_offset_t));
1092 		sc->sc_rxbufs[i].rb_paddrhi = 0;
1093 	}
1094 
1095 	sc->sc_hostvar->hv_rx_buf_write_idx = (RXBUF_ENTRIES - 1) *
1096 	    sizeof(struct txp_rxbuf_desc);
1097 
1098 	return(0);
1099 }
1100 
1101 static void
1102 txp_rxring_empty(sc)
1103 	struct txp_softc *sc;
1104 {
1105 	int i;
1106 	struct txp_swdesc *sd;
1107 
1108 	if (sc->sc_rxbufs == NULL)
1109 		return;
1110 
1111 	for (i = 0; i < RXBUF_ENTRIES; i++) {
1112 		if (&sc->sc_rxbufs[i] == NULL)
1113 			continue;
1114 		sd = sc->sc_rxbufs[i].rb_sd;
1115 		if (sd == NULL)
1116 			continue;
1117 		if (sd->sd_mbuf != NULL) {
1118 			m_freem(sd->sd_mbuf);
1119 			sd->sd_mbuf = NULL;
1120 		}
1121 	}
1122 
1123 	return;
1124 }
1125 
1126 static void
1127 txp_init(xsc)
1128 	void *xsc;
1129 {
1130 	struct txp_softc *sc;
1131 	struct ifnet *ifp;
1132 	u_int16_t p1;
1133 	u_int32_t p2;
1134 
1135 	sc = xsc;
1136 	ifp = &sc->sc_arpcom.ac_if;
1137 
1138 	if (ifp->if_flags & IFF_RUNNING)
1139 		return;
1140 
1141 	txp_stop(sc);
1142 
1143 	crit_enter();
1144 
1145 	txp_command(sc, TXP_CMD_MAX_PKT_SIZE_WRITE, TXP_MAX_PKTLEN, 0, 0,
1146 	    NULL, NULL, NULL, 1);
1147 
1148 	/* Set station address. */
1149 	((u_int8_t *)&p1)[1] = sc->sc_arpcom.ac_enaddr[0];
1150 	((u_int8_t *)&p1)[0] = sc->sc_arpcom.ac_enaddr[1];
1151 	((u_int8_t *)&p2)[3] = sc->sc_arpcom.ac_enaddr[2];
1152 	((u_int8_t *)&p2)[2] = sc->sc_arpcom.ac_enaddr[3];
1153 	((u_int8_t *)&p2)[1] = sc->sc_arpcom.ac_enaddr[4];
1154 	((u_int8_t *)&p2)[0] = sc->sc_arpcom.ac_enaddr[5];
1155 	txp_command(sc, TXP_CMD_STATION_ADDRESS_WRITE, p1, p2, 0,
1156 	    NULL, NULL, NULL, 1);
1157 
1158 	txp_set_filter(sc);
1159 
1160 	txp_rxring_fill(sc);
1161 
1162 	txp_command(sc, TXP_CMD_TX_ENABLE, 0, 0, 0, NULL, NULL, NULL, 1);
1163 	txp_command(sc, TXP_CMD_RX_ENABLE, 0, 0, 0, NULL, NULL, NULL, 1);
1164 
1165 	WRITE_REG(sc, TXP_IER, TXP_INT_RESERVED | TXP_INT_SELF |
1166 	    TXP_INT_A2H_7 | TXP_INT_A2H_6 | TXP_INT_A2H_5 | TXP_INT_A2H_4 |
1167 	    TXP_INT_A2H_2 | TXP_INT_A2H_1 | TXP_INT_A2H_0 |
1168 	    TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 |
1169 	    TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT |  TXP_INT_LATCH);
1170 	WRITE_REG(sc, TXP_IMR, TXP_INT_A2H_3);
1171 
1172 	ifp->if_flags |= IFF_RUNNING;
1173 	ifp->if_flags &= ~IFF_OACTIVE;
1174 	ifp->if_timer = 0;
1175 
1176 	callout_reset(&sc->txp_stat_timer, hz, txp_tick, sc);
1177 
1178 	crit_exit();
1179 }
1180 
1181 static void
1182 txp_tick(vsc)
1183 	void *vsc;
1184 {
1185 	struct txp_softc *sc = vsc;
1186 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1187 	struct txp_rsp_desc *rsp = NULL;
1188 	struct txp_ext_desc *ext;
1189 
1190 	crit_enter();
1191 	txp_rxbuf_reclaim(sc);
1192 
1193 	if (txp_command2(sc, TXP_CMD_READ_STATISTICS, 0, 0, 0, NULL, 0,
1194 	    &rsp, 1))
1195 		goto out;
1196 	if (rsp->rsp_numdesc != 6)
1197 		goto out;
1198 	if (txp_command(sc, TXP_CMD_CLEAR_STATISTICS, 0, 0, 0,
1199 	    NULL, NULL, NULL, 1))
1200 		goto out;
1201 	ext = (struct txp_ext_desc *)(rsp + 1);
1202 
1203 	ifp->if_ierrors += ext[3].ext_2 + ext[3].ext_3 + ext[3].ext_4 +
1204 	    ext[4].ext_1 + ext[4].ext_4;
1205 	ifp->if_oerrors += ext[0].ext_1 + ext[1].ext_1 + ext[1].ext_4 +
1206 	    ext[2].ext_1;
1207 	ifp->if_collisions += ext[0].ext_2 + ext[0].ext_3 + ext[1].ext_2 +
1208 	    ext[1].ext_3;
1209 	ifp->if_opackets += rsp->rsp_par2;
1210 	ifp->if_ipackets += ext[2].ext_3;
1211 
1212 out:
1213 	if (rsp != NULL)
1214 		free(rsp, M_DEVBUF);
1215 
1216 	callout_reset(&sc->txp_stat_timer, hz, txp_tick, sc);
1217 	crit_exit();
1218 }
1219 
1220 static void
1221 txp_start(ifp)
1222 	struct ifnet *ifp;
1223 {
1224 	struct txp_softc *sc = ifp->if_softc;
1225 	struct txp_tx_ring *r = &sc->sc_txhir;
1226 	struct txp_tx_desc *txd;
1227 	struct txp_frag_desc *fxd;
1228 	struct mbuf *m, *m0;
1229 	struct txp_swdesc *sd;
1230 	u_int32_t firstprod, firstcnt, prod, cnt;
1231 	struct ifvlan		*ifv;
1232 
1233 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
1234 		return;
1235 
1236 	prod = r->r_prod;
1237 	cnt = r->r_cnt;
1238 
1239 	while (1) {
1240 		m = ifq_poll(&ifp->if_snd);
1241 		if (m == NULL)
1242 			break;
1243 
1244 		firstprod = prod;
1245 		firstcnt = cnt;
1246 
1247 		sd = sc->sc_txd + prod;
1248 		sd->sd_mbuf = m;
1249 
1250 		if ((TX_ENTRIES - cnt) < 4)
1251 			goto oactive;
1252 
1253 		txd = r->r_desc + prod;
1254 
1255 		txd->tx_flags = TX_FLAGS_TYPE_DATA;
1256 		txd->tx_numdesc = 0;
1257 		txd->tx_addrlo = 0;
1258 		txd->tx_addrhi = 0;
1259 		txd->tx_totlen = 0;
1260 		txd->tx_pflags = 0;
1261 
1262 		if (++prod == TX_ENTRIES)
1263 			prod = 0;
1264 
1265 		if (++cnt >= (TX_ENTRIES - 4))
1266 			goto oactive;
1267 
1268 		if ((m->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
1269 		    m->m_pkthdr.rcvif != NULL) {
1270 			ifv = m->m_pkthdr.rcvif->if_softc;
1271 			txd->tx_pflags = TX_PFLAGS_VLAN |
1272 			    (htons(ifv->ifv_tag) << TX_PFLAGS_VLANTAG_S);
1273 		}
1274 
1275 		if (m->m_pkthdr.csum_flags & CSUM_IP)
1276 			txd->tx_pflags |= TX_PFLAGS_IPCKSUM;
1277 
1278 #if 0
1279 		if (m->m_pkthdr.csum_flags & CSUM_TCP)
1280 			txd->tx_pflags |= TX_PFLAGS_TCPCKSUM;
1281 		if (m->m_pkthdr.csum_flags & CSUM_UDP)
1282 			txd->tx_pflags |= TX_PFLAGS_UDPCKSUM;
1283 #endif
1284 
1285 		fxd = (struct txp_frag_desc *)(r->r_desc + prod);
1286 		for (m0 = m; m0 != NULL; m0 = m0->m_next) {
1287 			if (m0->m_len == 0)
1288 				continue;
1289 			if (++cnt >= (TX_ENTRIES - 4))
1290 				goto oactive;
1291 
1292 			txd->tx_numdesc++;
1293 
1294 			fxd->frag_flags = FRAG_FLAGS_TYPE_FRAG;
1295 			fxd->frag_rsvd1 = 0;
1296 			fxd->frag_len = m0->m_len;
1297 			fxd->frag_addrlo = vtophys(mtod(m0, vm_offset_t));
1298 			fxd->frag_addrhi = 0;
1299 			fxd->frag_rsvd2 = 0;
1300 
1301 			if (++prod == TX_ENTRIES) {
1302 				fxd = (struct txp_frag_desc *)r->r_desc;
1303 				prod = 0;
1304 			} else
1305 				fxd++;
1306 
1307 		}
1308 
1309 		ifp->if_timer = 5;
1310 
1311 		m = ifq_dequeue(&ifp->if_snd);
1312 		BPF_MTAP(ifp, m);
1313 		WRITE_REG(sc, r->r_reg, TXP_IDX2OFFSET(prod));
1314 	}
1315 
1316 	r->r_prod = prod;
1317 	r->r_cnt = cnt;
1318 	return;
1319 
1320 oactive:
1321 	ifp->if_flags |= IFF_OACTIVE;
1322 	r->r_prod = firstprod;
1323 	r->r_cnt = firstcnt;
1324 	return;
1325 }
1326 
1327 /*
1328  * Handle simple commands sent to the typhoon
1329  */
1330 static int
1331 txp_command(sc, id, in1, in2, in3, out1, out2, out3, wait)
1332 	struct txp_softc *sc;
1333 	u_int16_t id, in1, *out1;
1334 	u_int32_t in2, in3, *out2, *out3;
1335 	int wait;
1336 {
1337 	struct txp_rsp_desc *rsp = NULL;
1338 
1339 	if (txp_command2(sc, id, in1, in2, in3, NULL, 0, &rsp, wait))
1340 		return (-1);
1341 
1342 	if (!wait)
1343 		return (0);
1344 
1345 	if (out1 != NULL)
1346 		*out1 = rsp->rsp_par1;
1347 	if (out2 != NULL)
1348 		*out2 = rsp->rsp_par2;
1349 	if (out3 != NULL)
1350 		*out3 = rsp->rsp_par3;
1351 	free(rsp, M_DEVBUF);
1352 	return (0);
1353 }
1354 
1355 static int
1356 txp_command2(sc, id, in1, in2, in3, in_extp, in_extn, rspp, wait)
1357 	struct txp_softc *sc;
1358 	u_int16_t id, in1;
1359 	u_int32_t in2, in3;
1360 	struct txp_ext_desc *in_extp;
1361 	u_int8_t in_extn;
1362 	struct txp_rsp_desc **rspp;
1363 	int wait;
1364 {
1365 	struct txp_hostvar *hv = sc->sc_hostvar;
1366 	struct txp_cmd_desc *cmd;
1367 	struct txp_ext_desc *ext;
1368 	u_int32_t idx, i;
1369 	u_int16_t seq;
1370 
1371 	if (txp_cmd_desc_numfree(sc) < (in_extn + 1)) {
1372 		if_printf(&sc->sc_arpcom.ac_if, "no free cmd descriptors\n");
1373 		return (-1);
1374 	}
1375 
1376 	idx = sc->sc_cmdring.lastwrite;
1377 	cmd = (struct txp_cmd_desc *)(((u_int8_t *)sc->sc_cmdring.base) + idx);
1378 	bzero(cmd, sizeof(*cmd));
1379 
1380 	cmd->cmd_numdesc = in_extn;
1381 	cmd->cmd_seq = seq = sc->sc_seq++;
1382 	cmd->cmd_id = id;
1383 	cmd->cmd_par1 = in1;
1384 	cmd->cmd_par2 = in2;
1385 	cmd->cmd_par3 = in3;
1386 	cmd->cmd_flags = CMD_FLAGS_TYPE_CMD |
1387 	    (wait ? CMD_FLAGS_RESP : 0) | CMD_FLAGS_VALID;
1388 
1389 	idx += sizeof(struct txp_cmd_desc);
1390 	if (idx == sc->sc_cmdring.size)
1391 		idx = 0;
1392 
1393 	for (i = 0; i < in_extn; i++) {
1394 		ext = (struct txp_ext_desc *)(((u_int8_t *)sc->sc_cmdring.base) + idx);
1395 		bcopy(in_extp, ext, sizeof(struct txp_ext_desc));
1396 		in_extp++;
1397 		idx += sizeof(struct txp_cmd_desc);
1398 		if (idx == sc->sc_cmdring.size)
1399 			idx = 0;
1400 	}
1401 
1402 	sc->sc_cmdring.lastwrite = idx;
1403 
1404 	WRITE_REG(sc, TXP_H2A_2, sc->sc_cmdring.lastwrite);
1405 
1406 	if (!wait)
1407 		return (0);
1408 
1409 	for (i = 0; i < 10000; i++) {
1410 		idx = hv->hv_resp_read_idx;
1411 		if (idx != hv->hv_resp_write_idx) {
1412 			*rspp = NULL;
1413 			if (txp_response(sc, idx, id, seq, rspp))
1414 				return (-1);
1415 			if (*rspp != NULL)
1416 				break;
1417 		}
1418 		DELAY(50);
1419 	}
1420 	if (i == 1000 || (*rspp) == NULL) {
1421 		if_printf(&sc->sc_arpcom.ac_if, "0x%x command failed\n", id);
1422 		return (-1);
1423 	}
1424 
1425 	return (0);
1426 }
1427 
1428 static int
1429 txp_response(sc, ridx, id, seq, rspp)
1430 	struct txp_softc *sc;
1431 	u_int32_t ridx;
1432 	u_int16_t id;
1433 	u_int16_t seq;
1434 	struct txp_rsp_desc **rspp;
1435 {
1436 	struct txp_hostvar *hv = sc->sc_hostvar;
1437 	struct txp_rsp_desc *rsp;
1438 
1439 	while (ridx != hv->hv_resp_write_idx) {
1440 		rsp = (struct txp_rsp_desc *)(((u_int8_t *)sc->sc_rspring.base) + ridx);
1441 
1442 		if (id == rsp->rsp_id && rsp->rsp_seq == seq) {
1443 			*rspp = (struct txp_rsp_desc *)malloc(
1444 			    sizeof(struct txp_rsp_desc) * (rsp->rsp_numdesc + 1),
1445 			    M_DEVBUF, M_INTWAIT);
1446 			if ((*rspp) == NULL)
1447 				return (-1);
1448 			txp_rsp_fixup(sc, rsp, *rspp);
1449 			return (0);
1450 		}
1451 
1452 		if (rsp->rsp_flags & RSP_FLAGS_ERROR) {
1453 			if_printf(&sc->sc_arpcom.ac_if, "response error!\n");
1454 			txp_rsp_fixup(sc, rsp, NULL);
1455 			ridx = hv->hv_resp_read_idx;
1456 			continue;
1457 		}
1458 
1459 		switch (rsp->rsp_id) {
1460 		case TXP_CMD_CYCLE_STATISTICS:
1461 		case TXP_CMD_MEDIA_STATUS_READ:
1462 			break;
1463 		case TXP_CMD_HELLO_RESPONSE:
1464 			if_printf(&sc->sc_arpcom.ac_if, "hello\n");
1465 			break;
1466 		default:
1467 			if_printf(&sc->sc_arpcom.ac_if, "unknown id(0x%x)\n",
1468 			    rsp->rsp_id);
1469 		}
1470 
1471 		txp_rsp_fixup(sc, rsp, NULL);
1472 		ridx = hv->hv_resp_read_idx;
1473 		hv->hv_resp_read_idx = ridx;
1474 	}
1475 
1476 	return (0);
1477 }
1478 
1479 static void
1480 txp_rsp_fixup(sc, rsp, dst)
1481 	struct txp_softc *sc;
1482 	struct txp_rsp_desc *rsp, *dst;
1483 {
1484 	struct txp_rsp_desc *src = rsp;
1485 	struct txp_hostvar *hv = sc->sc_hostvar;
1486 	u_int32_t i, ridx;
1487 
1488 	ridx = hv->hv_resp_read_idx;
1489 
1490 	for (i = 0; i < rsp->rsp_numdesc + 1; i++) {
1491 		if (dst != NULL)
1492 			bcopy(src, dst++, sizeof(struct txp_rsp_desc));
1493 		ridx += sizeof(struct txp_rsp_desc);
1494 		if (ridx == sc->sc_rspring.size) {
1495 			src = sc->sc_rspring.base;
1496 			ridx = 0;
1497 		} else
1498 			src++;
1499 		sc->sc_rspring.lastwrite = hv->hv_resp_read_idx = ridx;
1500 	}
1501 
1502 	hv->hv_resp_read_idx = ridx;
1503 }
1504 
1505 static int
1506 txp_cmd_desc_numfree(sc)
1507 	struct txp_softc *sc;
1508 {
1509 	struct txp_hostvar *hv = sc->sc_hostvar;
1510 	struct txp_boot_record *br = sc->sc_boot;
1511 	u_int32_t widx, ridx, nfree;
1512 
1513 	widx = sc->sc_cmdring.lastwrite;
1514 	ridx = hv->hv_cmd_read_idx;
1515 
1516 	if (widx == ridx) {
1517 		/* Ring is completely free */
1518 		nfree = br->br_cmd_siz - sizeof(struct txp_cmd_desc);
1519 	} else {
1520 		if (widx > ridx)
1521 			nfree = br->br_cmd_siz -
1522 			    (widx - ridx + sizeof(struct txp_cmd_desc));
1523 		else
1524 			nfree = ridx - widx - sizeof(struct txp_cmd_desc);
1525 	}
1526 
1527 	return (nfree / sizeof(struct txp_cmd_desc));
1528 }
1529 
1530 static void
1531 txp_stop(sc)
1532 	struct txp_softc *sc;
1533 {
1534 	struct ifnet *ifp;
1535 
1536 	ifp = &sc->sc_arpcom.ac_if;
1537 
1538 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1539 
1540 	callout_stop(&sc->txp_stat_timer);
1541 
1542 	txp_command(sc, TXP_CMD_TX_DISABLE, 0, 0, 0, NULL, NULL, NULL, 1);
1543 	txp_command(sc, TXP_CMD_RX_DISABLE, 0, 0, 0, NULL, NULL, NULL, 1);
1544 
1545 	txp_rxring_empty(sc);
1546 
1547 	return;
1548 }
1549 
1550 static void
1551 txp_watchdog(ifp)
1552 	struct ifnet *ifp;
1553 {
1554 	return;
1555 }
1556 
1557 static int
1558 txp_ifmedia_upd(ifp)
1559 	struct ifnet *ifp;
1560 {
1561 	struct txp_softc *sc = ifp->if_softc;
1562 	struct ifmedia *ifm = &sc->sc_ifmedia;
1563 	u_int16_t new_xcvr;
1564 
1565 	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
1566 		return (EINVAL);
1567 
1568 	if (IFM_SUBTYPE(ifm->ifm_media) == IFM_10_T) {
1569 		if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
1570 			new_xcvr = TXP_XCVR_10_FDX;
1571 		else
1572 			new_xcvr = TXP_XCVR_10_HDX;
1573 	} else if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_TX) {
1574 		if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
1575 			new_xcvr = TXP_XCVR_100_FDX;
1576 		else
1577 			new_xcvr = TXP_XCVR_100_HDX;
1578 	} else if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO) {
1579 		new_xcvr = TXP_XCVR_AUTO;
1580 	} else
1581 		return (EINVAL);
1582 
1583 	/* nothing to do */
1584 	if (sc->sc_xcvr == new_xcvr)
1585 		return (0);
1586 
1587 	txp_command(sc, TXP_CMD_XCVR_SELECT, new_xcvr, 0, 0,
1588 	    NULL, NULL, NULL, 0);
1589 	sc->sc_xcvr = new_xcvr;
1590 
1591 	return (0);
1592 }
1593 
1594 static void
1595 txp_ifmedia_sts(ifp, ifmr)
1596 	struct ifnet *ifp;
1597 	struct ifmediareq *ifmr;
1598 {
1599 	struct txp_softc *sc = ifp->if_softc;
1600 	struct ifmedia *ifm = &sc->sc_ifmedia;
1601 	u_int16_t bmsr, bmcr, anlpar;
1602 
1603 	ifmr->ifm_status = IFM_AVALID;
1604 	ifmr->ifm_active = IFM_ETHER;
1605 
1606 	if (txp_command(sc, TXP_CMD_PHY_MGMT_READ, 0, MII_BMSR, 0,
1607 	    &bmsr, NULL, NULL, 1))
1608 		goto bail;
1609 	if (txp_command(sc, TXP_CMD_PHY_MGMT_READ, 0, MII_BMSR, 0,
1610 	    &bmsr, NULL, NULL, 1))
1611 		goto bail;
1612 
1613 	if (txp_command(sc, TXP_CMD_PHY_MGMT_READ, 0, MII_BMCR, 0,
1614 	    &bmcr, NULL, NULL, 1))
1615 		goto bail;
1616 
1617 	if (txp_command(sc, TXP_CMD_PHY_MGMT_READ, 0, MII_ANLPAR, 0,
1618 	    &anlpar, NULL, NULL, 1))
1619 		goto bail;
1620 
1621 	if (bmsr & BMSR_LINK)
1622 		ifmr->ifm_status |= IFM_ACTIVE;
1623 
1624 	if (bmcr & BMCR_ISO) {
1625 		ifmr->ifm_active |= IFM_NONE;
1626 		ifmr->ifm_status = 0;
1627 		return;
1628 	}
1629 
1630 	if (bmcr & BMCR_LOOP)
1631 		ifmr->ifm_active |= IFM_LOOP;
1632 
1633 	if (bmcr & BMCR_AUTOEN) {
1634 		if ((bmsr & BMSR_ACOMP) == 0) {
1635 			ifmr->ifm_active |= IFM_NONE;
1636 			return;
1637 		}
1638 
1639 		if (anlpar & ANLPAR_T4)
1640 			ifmr->ifm_active |= IFM_100_T4;
1641 		else if (anlpar & ANLPAR_TX_FD)
1642 			ifmr->ifm_active |= IFM_100_TX|IFM_FDX;
1643 		else if (anlpar & ANLPAR_TX)
1644 			ifmr->ifm_active |= IFM_100_TX;
1645 		else if (anlpar & ANLPAR_10_FD)
1646 			ifmr->ifm_active |= IFM_10_T|IFM_FDX;
1647 		else if (anlpar & ANLPAR_10)
1648 			ifmr->ifm_active |= IFM_10_T;
1649 		else
1650 			ifmr->ifm_active |= IFM_NONE;
1651 	} else
1652 		ifmr->ifm_active = ifm->ifm_cur->ifm_media;
1653 	return;
1654 
1655 bail:
1656 	ifmr->ifm_active |= IFM_NONE;
1657 	ifmr->ifm_status &= ~IFM_AVALID;
1658 }
1659 
1660 #ifdef TXP_DEBUG
1661 static void
1662 txp_show_descriptor(d)
1663 	void *d;
1664 {
1665 	struct txp_cmd_desc *cmd = d;
1666 	struct txp_rsp_desc *rsp = d;
1667 	struct txp_tx_desc *txd = d;
1668 	struct txp_frag_desc *frgd = d;
1669 
1670 	switch (cmd->cmd_flags & CMD_FLAGS_TYPE_M) {
1671 	case CMD_FLAGS_TYPE_CMD:
1672 		/* command descriptor */
1673 		printf("[cmd flags 0x%x num %d id %d seq %d par1 0x%x par2 0x%x par3 0x%x]\n",
1674 		    cmd->cmd_flags, cmd->cmd_numdesc, cmd->cmd_id, cmd->cmd_seq,
1675 		    cmd->cmd_par1, cmd->cmd_par2, cmd->cmd_par3);
1676 		break;
1677 	case CMD_FLAGS_TYPE_RESP:
1678 		/* response descriptor */
1679 		printf("[rsp flags 0x%x num %d id %d seq %d par1 0x%x par2 0x%x par3 0x%x]\n",
1680 		    rsp->rsp_flags, rsp->rsp_numdesc, rsp->rsp_id, rsp->rsp_seq,
1681 		    rsp->rsp_par1, rsp->rsp_par2, rsp->rsp_par3);
1682 		break;
1683 	case CMD_FLAGS_TYPE_DATA:
1684 		/* data header (assuming tx for now) */
1685 		printf("[data flags 0x%x num %d totlen %d addr 0x%x/0x%x pflags 0x%x]",
1686 		    txd->tx_flags, txd->tx_numdesc, txd->tx_totlen,
1687 		    txd->tx_addrlo, txd->tx_addrhi, txd->tx_pflags);
1688 		break;
1689 	case CMD_FLAGS_TYPE_FRAG:
1690 		/* fragment descriptor */
1691 		printf("[frag flags 0x%x rsvd1 0x%x len %d addr 0x%x/0x%x rsvd2 0x%x]",
1692 		    frgd->frag_flags, frgd->frag_rsvd1, frgd->frag_len,
1693 		    frgd->frag_addrlo, frgd->frag_addrhi, frgd->frag_rsvd2);
1694 		break;
1695 	default:
1696 		printf("[unknown(%x) flags 0x%x num %d id %d seq %d par1 0x%x par2 0x%x par3 0x%x]\n",
1697 		    cmd->cmd_flags & CMD_FLAGS_TYPE_M,
1698 		    cmd->cmd_flags, cmd->cmd_numdesc, cmd->cmd_id, cmd->cmd_seq,
1699 		    cmd->cmd_par1, cmd->cmd_par2, cmd->cmd_par3);
1700 		break;
1701 	}
1702 }
1703 #endif
1704 
1705 static void
1706 txp_set_filter(sc)
1707 	struct txp_softc *sc;
1708 {
1709 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1710 	uint16_t filter;
1711 	struct ifmultiaddr *ifma;
1712 
1713 	if (ifp->if_flags & IFF_PROMISC) {
1714 		filter = TXP_RXFILT_PROMISC;
1715 		goto setit;
1716 	}
1717 
1718 	filter = TXP_RXFILT_DIRECT;
1719 
1720 	if (ifp->if_flags & IFF_BROADCAST)
1721 		filter |= TXP_RXFILT_BROADCAST;
1722 
1723 	if (ifp->if_flags & IFF_ALLMULTI) {
1724 		filter |= TXP_RXFILT_ALLMULTI;
1725 	} else {
1726 		uint32_t hashbit, hash[2];
1727 		int mcnt = 0;
1728 
1729 		hash[0] = hash[1] = 0;
1730 
1731 		LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1732 			if (ifma->ifma_addr->sa_family != AF_LINK)
1733 				continue;
1734 
1735 			mcnt++;
1736 			hashbit = (uint16_t)(ether_crc32_be(
1737 			    LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
1738 			    ETHER_ADDR_LEN) & (64 - 1));
1739 			hash[hashbit / 32] |= (1 << hashbit % 32);
1740 		}
1741 
1742 		if (mcnt > 0) {
1743 			filter |= TXP_RXFILT_HASHMULTI;
1744 			txp_command(sc, TXP_CMD_MCAST_HASH_MASK_WRITE,
1745 			    2, hash[0], hash[1], NULL, NULL, NULL, 0);
1746 		}
1747 	}
1748 
1749 setit:
1750 	txp_command(sc, TXP_CMD_RX_FILTER_WRITE, filter, 0, 0,
1751 	    NULL, NULL, NULL, 1);
1752 }
1753 
1754 static void
1755 txp_capabilities(sc)
1756 	struct txp_softc *sc;
1757 {
1758 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1759 	struct txp_rsp_desc *rsp = NULL;
1760 	struct txp_ext_desc *ext;
1761 
1762 	if (txp_command2(sc, TXP_CMD_OFFLOAD_READ, 0, 0, 0, NULL, 0, &rsp, 1))
1763 		goto out;
1764 
1765 	if (rsp->rsp_numdesc != 1)
1766 		goto out;
1767 	ext = (struct txp_ext_desc *)(rsp + 1);
1768 
1769 	sc->sc_tx_capability = ext->ext_1 & OFFLOAD_MASK;
1770 	sc->sc_rx_capability = ext->ext_2 & OFFLOAD_MASK;
1771 	ifp->if_capabilities = 0;
1772 
1773 	if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_VLAN) {
1774 		sc->sc_tx_capability |= OFFLOAD_VLAN;
1775 		sc->sc_rx_capability |= OFFLOAD_VLAN;
1776 	}
1777 
1778 #if 0
1779 	/* not ready yet */
1780 	if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_IPSEC) {
1781 		sc->sc_tx_capability |= OFFLOAD_IPSEC;
1782 		sc->sc_rx_capability |= OFFLOAD_IPSEC;
1783 		ifp->if_capabilities |= IFCAP_IPSEC;
1784 	}
1785 #endif
1786 
1787 	if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_IPCKSUM) {
1788 		sc->sc_tx_capability |= OFFLOAD_IPCKSUM;
1789 		sc->sc_rx_capability |= OFFLOAD_IPCKSUM;
1790 		ifp->if_capabilities |= IFCAP_HWCSUM;
1791 		ifp->if_hwassist |= CSUM_IP;
1792 	}
1793 
1794 	if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_TCPCKSUM) {
1795 #if 0
1796 		sc->sc_tx_capability |= OFFLOAD_TCPCKSUM;
1797 #endif
1798 		sc->sc_rx_capability |= OFFLOAD_TCPCKSUM;
1799 		ifp->if_capabilities |= IFCAP_HWCSUM;
1800 	}
1801 
1802 	if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_UDPCKSUM) {
1803 #if 0
1804 		sc->sc_tx_capability |= OFFLOAD_UDPCKSUM;
1805 #endif
1806 		sc->sc_rx_capability |= OFFLOAD_UDPCKSUM;
1807 		ifp->if_capabilities |= IFCAP_HWCSUM;
1808 	}
1809 	ifp->if_capenable = ifp->if_capabilities;
1810 
1811 	if (txp_command(sc, TXP_CMD_OFFLOAD_WRITE, 0,
1812 	    sc->sc_tx_capability, sc->sc_rx_capability, NULL, NULL, NULL, 1))
1813 		goto out;
1814 
1815 out:
1816 	if (rsp != NULL)
1817 		free(rsp, M_DEVBUF);
1818 
1819 	return;
1820 }
1821