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