1 /* $NetBSD: if_txp.c,v 1.34 2009/04/18 14:58:03 tsutsui Exp $ */
5 * Jason L. Wright <jason@thought.net>, Theo de Raadt, and
6 * Aaron Campbell <aaron@monkey.org>. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR THE VOICES IN THEIR HEADS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGE.
31 * Driver for 3c990 (Typhoon) Ethernet ASIC
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: if_txp.c,v 1.34 2009/04/18 14:58:03 tsutsui Exp $");
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/sockio.h>
44 #include <sys/malloc.h>
45 #include <sys/kernel.h>
46 #include <sys/socket.h>
47 #include <sys/device.h>
48 #include <sys/callout.h>
51 #include <net/if_dl.h>
52 #include <net/if_types.h>
53 #include <net/if_ether.h>
54 #include <net/if_arp.h>
57 #include <netinet/in.h>
58 #include <netinet/in_systm.h>
59 #include <netinet/in_var.h>
60 #include <netinet/ip.h>
61 #include <netinet/if_inarp.h>
64 #include <net/if_media.h>
70 #include <uvm/uvm_extern.h> /* for PAGE_SIZE */
73 #include <dev/mii/mii.h>
74 #include <dev/mii/miivar.h>
75 #include <dev/pci/pcireg.h>
76 #include <dev/pci/pcivar.h>
77 #include <dev/pci/pcidevs.h>
79 #include <dev/pci/if_txpreg.h>
81 #include <dev/microcode/typhoon/3c990img.h>
84 * These currently break the 3c990 firmware, hopefully will be resolved
87 #undef TRY_TX_UDP_CSUM
88 #undef TRY_TX_TCP_CSUM
90 int txp_probe(device_t
, cfdata_t
, void *);
91 void txp_attach(device_t
, device_t
, void *);
93 void txp_tick(void *);
94 bool txp_shutdown(device_t
, int);
95 int txp_ioctl(struct ifnet
*, u_long
, void *);
96 void txp_start(struct ifnet
*);
97 void txp_stop(struct txp_softc
*);
98 void txp_init(struct txp_softc
*);
99 void txp_watchdog(struct ifnet
*);
101 int txp_chip_init(struct txp_softc
*);
102 int txp_reset_adapter(struct txp_softc
*);
103 int txp_download_fw(struct txp_softc
*);
104 int txp_download_fw_wait(struct txp_softc
*);
105 int txp_download_fw_section(struct txp_softc
*,
106 const struct txp_fw_section_header
*, int);
107 int txp_alloc_rings(struct txp_softc
*);
108 void txp_dma_free(struct txp_softc
*, struct txp_dma_alloc
*);
109 int txp_dma_malloc(struct txp_softc
*, bus_size_t
, struct txp_dma_alloc
*, int);
110 void txp_set_filter(struct txp_softc
*);
112 int txp_cmd_desc_numfree(struct txp_softc
*);
113 int txp_command(struct txp_softc
*, u_int16_t
, u_int16_t
, u_int32_t
,
114 u_int32_t
, u_int16_t
*, u_int32_t
*, u_int32_t
*, int);
115 int txp_command2(struct txp_softc
*, u_int16_t
, u_int16_t
,
116 u_int32_t
, u_int32_t
, struct txp_ext_desc
*, u_int8_t
,
117 struct txp_rsp_desc
**, int);
118 int txp_response(struct txp_softc
*, u_int32_t
, u_int16_t
, u_int16_t
,
119 struct txp_rsp_desc
**);
120 void txp_rsp_fixup(struct txp_softc
*, struct txp_rsp_desc
*,
121 struct txp_rsp_desc
*);
122 void txp_capabilities(struct txp_softc
*);
124 void txp_ifmedia_sts(struct ifnet
*, struct ifmediareq
*);
125 int txp_ifmedia_upd(struct ifnet
*);
126 void txp_show_descriptor(void *);
127 void txp_tx_reclaim(struct txp_softc
*, struct txp_tx_ring
*,
128 struct txp_dma_alloc
*);
129 void txp_rxbuf_reclaim(struct txp_softc
*);
130 void txp_rx_reclaim(struct txp_softc
*, struct txp_rx_ring
*,
131 struct txp_dma_alloc
*);
133 CFATTACH_DECL(txp
, sizeof(struct txp_softc
), txp_probe
, txp_attach
,
136 const struct txp_pci_match
{
139 { PCI_VENDOR_3COM
, PCI_PRODUCT_3COM_3CR990
, 0 },
140 { PCI_VENDOR_3COM
, PCI_PRODUCT_3COM_3CR990TX95
, 0 },
141 { PCI_VENDOR_3COM
, PCI_PRODUCT_3COM_3CR990TX97
, 0 },
142 { PCI_VENDOR_3COM
, PCI_PRODUCT_3COM_3CR990SVR95
, TXP_SERVERVERSION
},
143 { PCI_VENDOR_3COM
, PCI_PRODUCT_3COM_3CR990SVR97
, TXP_SERVERVERSION
},
144 { PCI_VENDOR_3COM
, PCI_PRODUCT_3COM_3C990B
, TXP_USESUBSYSTEM
},
145 { PCI_VENDOR_3COM
, PCI_PRODUCT_3COM_3C990BSVR
, TXP_SERVERVERSION
},
146 { PCI_VENDOR_3COM
, PCI_PRODUCT_3COM_3CR990FX
, TXP_USESUBSYSTEM
},
149 static const struct txp_pci_match
*txp_pcilookup(pcireg_t
);
151 static const struct {
152 u_int16_t mask
, value
;
154 } txp_subsysinfo
[] = {
155 {0xf000, 0x2000, TXP_SERVERVERSION
},
156 {0x0100, 0x0100, TXP_FIBER
},
157 #if 0 /* information from 3com header, unused */
158 {0x0010, 0x0010, /* secured firmware */},
159 {0x0003, 0x0000, /* variable DES */},
160 {0x0003, 0x0001, /* single DES - "95" */},
161 {0x0003, 0x0002, /* triple DES - "97" */},
165 static const struct txp_pci_match
*
166 txp_pcilookup(pcireg_t id
)
170 for (i
= 0; i
< __arraycount(txp_devices
); i
++)
171 if (PCI_VENDOR(id
) == txp_devices
[i
].vid
&&
172 PCI_PRODUCT(id
) == txp_devices
[i
].did
)
173 return &txp_devices
[i
];
178 txp_probe(device_t parent
, cfdata_t match
, void *aux
)
180 struct pci_attach_args
*pa
= aux
;
182 if (txp_pcilookup(pa
->pa_id
))
188 txp_attach(device_t parent
, device_t self
, void *aux
)
190 struct txp_softc
*sc
= device_private(self
);
191 struct pci_attach_args
*pa
= aux
;
192 pci_chipset_tag_t pc
= pa
->pa_pc
;
193 pci_intr_handle_t ih
;
194 const char *intrstr
= NULL
;
195 struct ifnet
*ifp
= &sc
->sc_arpcom
.ec_if
;
200 const struct txp_pci_match
*match
;
207 match
= txp_pcilookup(pa
->pa_id
);
208 flags
= match
->flags
;
209 if (match
->flags
& TXP_USESUBSYSTEM
) {
210 subsys
= PCI_PRODUCT(pci_conf_read(pc
, pa
->pa_tag
,
213 i
< sizeof(txp_subsysinfo
)/sizeof(txp_subsysinfo
[0]);
215 if ((subsys
& txp_subsysinfo
[i
].mask
) ==
216 txp_subsysinfo
[i
].value
)
217 flags
|= txp_subsysinfo
[i
].flags
;
219 sc
->sc_flags
= flags
;
221 pci_devinfo(pa
->pa_id
, 0, 0, devinfo
, sizeof(devinfo
));
222 #define TXP_EXTRAINFO ((flags & (TXP_USESUBSYSTEM|TXP_SERVERVERSION)) == \
223 (TXP_USESUBSYSTEM|TXP_SERVERVERSION) ? " (SVR)" : "")
224 printf(": %s%s\n%s", devinfo
, TXP_EXTRAINFO
, device_xname(&sc
->sc_dev
));
226 command
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
);
228 if (!(command
& PCI_COMMAND_MASTER_ENABLE
)) {
229 printf(": failed to enable bus mastering\n");
233 if (!(command
& PCI_COMMAND_MEM_ENABLE
)) {
234 printf(": failed to enable memory mapping\n");
237 if (pci_mapreg_map(pa
, TXP_PCI_LOMEM
, PCI_MAPREG_TYPE_MEM
, 0,
238 &sc
->sc_bt
, &sc
->sc_bh
, NULL
, NULL
)) {
239 printf(": can't map mem space %d\n", 0);
243 sc
->sc_dmat
= pa
->pa_dmat
;
246 * Allocate our interrupt.
248 if (pci_intr_map(pa
, &ih
)) {
249 printf(": couldn't map interrupt\n");
253 intrstr
= pci_intr_string(pc
, ih
);
254 sc
->sc_ih
= pci_intr_establish(pc
, ih
, IPL_NET
, txp_intr
, sc
);
255 if (sc
->sc_ih
== NULL
) {
256 printf(": couldn't establish interrupt");
258 printf(" at %s", intrstr
);
262 printf(": interrupting at %s\n", intrstr
);
264 if (txp_chip_init(sc
))
267 if (txp_download_fw(sc
))
270 if (txp_alloc_rings(sc
))
273 if (txp_command(sc
, TXP_CMD_MAX_PKT_SIZE_WRITE
, TXP_MAX_PKTLEN
, 0, 0,
274 NULL
, NULL
, NULL
, 1))
277 if (txp_command(sc
, TXP_CMD_STATION_ADDRESS_READ
, 0, 0, 0,
284 enaddr
[0] = ((u_int8_t
*)&p1
)[1];
285 enaddr
[1] = ((u_int8_t
*)&p1
)[0];
287 enaddr
[2] = ((u_int8_t
*)&p2
)[3];
288 enaddr
[3] = ((u_int8_t
*)&p2
)[2];
289 enaddr
[4] = ((u_int8_t
*)&p2
)[1];
290 enaddr
[5] = ((u_int8_t
*)&p2
)[0];
292 printf("%s: Ethernet address %s\n", device_xname(&sc
->sc_dev
),
293 ether_sprintf(enaddr
));
296 ifmedia_init(&sc
->sc_ifmedia
, 0, txp_ifmedia_upd
, txp_ifmedia_sts
);
297 if (flags
& TXP_FIBER
) {
298 ifmedia_add(&sc
->sc_ifmedia
, IFM_ETHER
|IFM_100_FX
,
300 ifmedia_add(&sc
->sc_ifmedia
, IFM_ETHER
|IFM_100_FX
|IFM_HDX
,
302 ifmedia_add(&sc
->sc_ifmedia
, IFM_ETHER
|IFM_100_FX
|IFM_FDX
,
305 ifmedia_add(&sc
->sc_ifmedia
, IFM_ETHER
|IFM_10_T
,
307 ifmedia_add(&sc
->sc_ifmedia
, IFM_ETHER
|IFM_10_T
|IFM_HDX
,
309 ifmedia_add(&sc
->sc_ifmedia
, IFM_ETHER
|IFM_10_T
|IFM_FDX
,
311 ifmedia_add(&sc
->sc_ifmedia
, IFM_ETHER
|IFM_100_TX
,
313 ifmedia_add(&sc
->sc_ifmedia
, IFM_ETHER
|IFM_100_TX
|IFM_HDX
,
315 ifmedia_add(&sc
->sc_ifmedia
, IFM_ETHER
|IFM_100_TX
|IFM_FDX
,
318 ifmedia_add(&sc
->sc_ifmedia
, IFM_ETHER
|IFM_AUTO
, 0, NULL
);
320 sc
->sc_xcvr
= TXP_XCVR_AUTO
;
321 txp_command(sc
, TXP_CMD_XCVR_SELECT
, TXP_XCVR_AUTO
, 0, 0,
322 NULL
, NULL
, NULL
, 0);
323 ifmedia_set(&sc
->sc_ifmedia
, IFM_ETHER
|IFM_AUTO
);
326 ifp
->if_mtu
= ETHERMTU
;
327 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
328 ifp
->if_ioctl
= txp_ioctl
;
329 ifp
->if_start
= txp_start
;
330 ifp
->if_watchdog
= txp_watchdog
;
331 ifp
->if_baudrate
= 10000000;
332 IFQ_SET_MAXLEN(&ifp
->if_snd
, TX_ENTRIES
);
333 IFQ_SET_READY(&ifp
->if_snd
);
334 ifp
->if_capabilities
= 0;
335 strlcpy(ifp
->if_xname
, device_xname(&sc
->sc_dev
), IFNAMSIZ
);
337 txp_capabilities(sc
);
339 callout_init(&sc
->sc_tick
, 0);
340 callout_setfunc(&sc
->sc_tick
, txp_tick
, sc
);
343 * Attach us everywhere
346 ether_ifattach(ifp
, enaddr
);
348 if (pmf_device_register1(self
, NULL
, NULL
, txp_shutdown
))
349 pmf_class_network_register(self
, ifp
);
351 aprint_error_dev(self
, "couldn't establish power handler\n");
356 pci_intr_disestablish(pc
,sc
->sc_ih
);
363 txp_chip_init(struct txp_softc
*sc
)
365 /* disable interrupts */
366 WRITE_REG(sc
, TXP_IER
, 0);
367 WRITE_REG(sc
, TXP_IMR
,
368 TXP_INT_SELF
| TXP_INT_PCI_TABORT
| TXP_INT_PCI_MABORT
|
369 TXP_INT_DMA3
| TXP_INT_DMA2
| TXP_INT_DMA1
| TXP_INT_DMA0
|
372 /* ack all interrupts */
373 WRITE_REG(sc
, TXP_ISR
, TXP_INT_RESERVED
| TXP_INT_LATCH
|
374 TXP_INT_A2H_7
| TXP_INT_A2H_6
| TXP_INT_A2H_5
| TXP_INT_A2H_4
|
375 TXP_INT_SELF
| TXP_INT_PCI_TABORT
| TXP_INT_PCI_MABORT
|
376 TXP_INT_DMA3
| TXP_INT_DMA2
| TXP_INT_DMA1
| TXP_INT_DMA0
|
377 TXP_INT_A2H_3
| TXP_INT_A2H_2
| TXP_INT_A2H_1
| TXP_INT_A2H_0
);
379 if (txp_reset_adapter(sc
))
382 /* disable interrupts */
383 WRITE_REG(sc
, TXP_IER
, 0);
384 WRITE_REG(sc
, TXP_IMR
,
385 TXP_INT_SELF
| TXP_INT_PCI_TABORT
| TXP_INT_PCI_MABORT
|
386 TXP_INT_DMA3
| TXP_INT_DMA2
| TXP_INT_DMA1
| TXP_INT_DMA0
|
389 /* ack all interrupts */
390 WRITE_REG(sc
, TXP_ISR
, TXP_INT_RESERVED
| TXP_INT_LATCH
|
391 TXP_INT_A2H_7
| TXP_INT_A2H_6
| TXP_INT_A2H_5
| TXP_INT_A2H_4
|
392 TXP_INT_SELF
| TXP_INT_PCI_TABORT
| TXP_INT_PCI_MABORT
|
393 TXP_INT_DMA3
| TXP_INT_DMA2
| TXP_INT_DMA1
| TXP_INT_DMA0
|
394 TXP_INT_A2H_3
| TXP_INT_A2H_2
| TXP_INT_A2H_1
| TXP_INT_A2H_0
);
400 txp_reset_adapter(struct txp_softc
*sc
)
405 WRITE_REG(sc
, TXP_SRR
, TXP_SRR_ALL
);
407 WRITE_REG(sc
, TXP_SRR
, 0);
409 /* Should wait max 6 seconds */
410 for (i
= 0; i
< 6000; i
++) {
411 r
= READ_REG(sc
, TXP_A2H_0
);
412 if (r
== STAT_WAITING_FOR_HOST_REQUEST
)
417 if (r
!= STAT_WAITING_FOR_HOST_REQUEST
) {
418 printf("%s: reset hung\n", TXP_DEVNAME(sc
));
426 txp_download_fw(struct txp_softc
*sc
)
428 const struct txp_fw_file_header
*fileheader
;
429 const struct txp_fw_section_header
*secthead
;
431 u_int32_t r
, i
, ier
, imr
;
433 ier
= READ_REG(sc
, TXP_IER
);
434 WRITE_REG(sc
, TXP_IER
, ier
| TXP_INT_A2H_0
);
436 imr
= READ_REG(sc
, TXP_IMR
);
437 WRITE_REG(sc
, TXP_IMR
, imr
| TXP_INT_A2H_0
);
439 for (i
= 0; i
< 10000; i
++) {
440 r
= READ_REG(sc
, TXP_A2H_0
);
441 if (r
== STAT_WAITING_FOR_HOST_REQUEST
)
445 if (r
!= STAT_WAITING_FOR_HOST_REQUEST
) {
446 printf(": not waiting for host request\n");
451 WRITE_REG(sc
, TXP_ISR
, TXP_INT_A2H_0
);
453 fileheader
= (const struct txp_fw_file_header
*)tc990image
;
454 if (memcmp("TYPHOON", fileheader
->magicid
, sizeof(fileheader
->magicid
))) {
455 printf(": fw invalid magic\n");
459 /* Tell boot firmware to get ready for image */
460 WRITE_REG(sc
, TXP_H2A_1
, le32toh(fileheader
->addr
));
461 WRITE_REG(sc
, TXP_H2A_0
, TXP_BOOTCMD_RUNTIME_IMAGE
);
463 if (txp_download_fw_wait(sc
)) {
464 printf("%s: fw wait failed, initial\n", device_xname(&sc
->sc_dev
));
468 secthead
= (const struct txp_fw_section_header
*)
469 (((const u_int8_t
*)tc990image
) +
470 sizeof(struct txp_fw_file_header
));
472 for (sect
= 0; sect
< le32toh(fileheader
->nsections
); sect
++) {
473 if (txp_download_fw_section(sc
, secthead
, sect
))
475 secthead
= (const struct txp_fw_section_header
*)
476 (((const u_int8_t
*)secthead
) + le32toh(secthead
->nbytes
) +
480 WRITE_REG(sc
, TXP_H2A_0
, TXP_BOOTCMD_DOWNLOAD_COMPLETE
);
482 for (i
= 0; i
< 10000; i
++) {
483 r
= READ_REG(sc
, TXP_A2H_0
);
484 if (r
== STAT_WAITING_FOR_BOOT
)
488 if (r
!= STAT_WAITING_FOR_BOOT
) {
489 printf(": not waiting for boot\n");
493 WRITE_REG(sc
, TXP_IER
, ier
);
494 WRITE_REG(sc
, TXP_IMR
, imr
);
500 txp_download_fw_wait(struct txp_softc
*sc
)
504 for (i
= 0; i
< 10000; i
++) {
505 r
= READ_REG(sc
, TXP_ISR
);
506 if (r
& TXP_INT_A2H_0
)
511 if (!(r
& TXP_INT_A2H_0
)) {
512 printf(": fw wait failed comm0\n");
516 WRITE_REG(sc
, TXP_ISR
, TXP_INT_A2H_0
);
518 r
= READ_REG(sc
, TXP_A2H_0
);
519 if (r
!= STAT_WAITING_FOR_SEGMENT
) {
520 printf(": fw not waiting for segment\n");
527 txp_download_fw_section(struct txp_softc
*sc
, const struct txp_fw_section_header
*sect
, int sectnum
)
529 struct txp_dma_alloc dma
;
536 /* Skip zero length sections */
537 if (sect
->nbytes
== 0)
540 /* Make sure we aren't past the end of the image */
541 rseg
= ((const u_int8_t
*)sect
) - ((const u_int8_t
*)tc990image
);
542 if (rseg
>= sizeof(tc990image
)) {
543 printf(": fw invalid section address, section %d\n", sectnum
);
547 /* Make sure this section doesn't go past the end */
548 rseg
+= le32toh(sect
->nbytes
);
549 if (rseg
>= sizeof(tc990image
)) {
550 printf(": fw truncated section %d\n", sectnum
);
554 /* map a buffer, copy segment to it, get physaddr */
555 if (txp_dma_malloc(sc
, le32toh(sect
->nbytes
), &dma
, 0)) {
556 printf(": fw dma malloc failed, section %d\n", sectnum
);
560 memcpy(dma
.dma_vaddr
, ((const u_int8_t
*)sect
) + sizeof(*sect
),
561 le32toh(sect
->nbytes
));
564 * dummy up mbuf and verify section checksum
567 m
.m_next
= m
.m_nextpkt
= NULL
;
568 m
.m_len
= le32toh(sect
->nbytes
);
569 m
.m_data
= dma
.dma_vaddr
;
572 csum
= in_cksum(&m
, le32toh(sect
->nbytes
));
573 if (csum
!= sect
->cksum
) {
574 printf(": fw section %d, bad cksum (expected 0x%x got 0x%x)\n",
575 sectnum
, sect
->cksum
, csum
);
576 txp_dma_free(sc
, &dma
);
581 bus_dmamap_sync(sc
->sc_dmat
, dma
.dma_map
, 0,
582 dma
.dma_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
584 WRITE_REG(sc
, TXP_H2A_1
, le32toh(sect
->nbytes
));
585 WRITE_REG(sc
, TXP_H2A_2
, le32toh(sect
->cksum
));
586 WRITE_REG(sc
, TXP_H2A_3
, le32toh(sect
->addr
));
587 WRITE_REG(sc
, TXP_H2A_4
, dma
.dma_paddr
>> 32);
588 WRITE_REG(sc
, TXP_H2A_5
, dma
.dma_paddr
& 0xffffffff);
589 WRITE_REG(sc
, TXP_H2A_0
, TXP_BOOTCMD_SEGMENT_AVAILABLE
);
591 if (txp_download_fw_wait(sc
)) {
592 printf("%s: fw wait failed, section %d\n",
593 device_xname(&sc
->sc_dev
), sectnum
);
597 bus_dmamap_sync(sc
->sc_dmat
, dma
.dma_map
, 0,
598 dma
.dma_map
->dm_mapsize
, BUS_DMASYNC_POSTWRITE
);
600 txp_dma_free(sc
, &dma
);
607 struct txp_softc
*sc
= vsc
;
608 struct txp_hostvar
*hv
= sc
->sc_hostvar
;
612 /* mask all interrupts */
613 WRITE_REG(sc
, TXP_IMR
, TXP_INT_RESERVED
| TXP_INT_SELF
|
614 TXP_INT_A2H_7
| TXP_INT_A2H_6
| TXP_INT_A2H_5
| TXP_INT_A2H_4
|
615 TXP_INT_A2H_2
| TXP_INT_A2H_1
| TXP_INT_A2H_0
|
616 TXP_INT_DMA3
| TXP_INT_DMA2
| TXP_INT_DMA1
| TXP_INT_DMA0
|
617 TXP_INT_PCI_TABORT
| TXP_INT_PCI_MABORT
| TXP_INT_LATCH
);
619 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_host_dma
.dma_map
, 0,
620 sizeof(struct txp_hostvar
), BUS_DMASYNC_POSTWRITE
|BUS_DMASYNC_POSTREAD
);
622 isr
= READ_REG(sc
, TXP_ISR
);
625 WRITE_REG(sc
, TXP_ISR
, isr
);
627 if ((*sc
->sc_rxhir
.r_roff
) != (*sc
->sc_rxhir
.r_woff
))
628 txp_rx_reclaim(sc
, &sc
->sc_rxhir
, &sc
->sc_rxhiring_dma
);
629 if ((*sc
->sc_rxlor
.r_roff
) != (*sc
->sc_rxlor
.r_woff
))
630 txp_rx_reclaim(sc
, &sc
->sc_rxlor
, &sc
->sc_rxloring_dma
);
632 if (hv
->hv_rx_buf_write_idx
== hv
->hv_rx_buf_read_idx
)
633 txp_rxbuf_reclaim(sc
);
635 if (sc
->sc_txhir
.r_cnt
&& (sc
->sc_txhir
.r_cons
!=
636 TXP_OFFSET2IDX(le32toh(*(sc
->sc_txhir
.r_off
)))))
637 txp_tx_reclaim(sc
, &sc
->sc_txhir
, &sc
->sc_txhiring_dma
);
639 if (sc
->sc_txlor
.r_cnt
&& (sc
->sc_txlor
.r_cons
!=
640 TXP_OFFSET2IDX(le32toh(*(sc
->sc_txlor
.r_off
)))))
641 txp_tx_reclaim(sc
, &sc
->sc_txlor
, &sc
->sc_txloring_dma
);
643 isr
= READ_REG(sc
, TXP_ISR
);
646 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_host_dma
.dma_map
, 0,
647 sizeof(struct txp_hostvar
), BUS_DMASYNC_POSTWRITE
|BUS_DMASYNC_POSTREAD
);
649 /* unmask all interrupts */
650 WRITE_REG(sc
, TXP_IMR
, TXP_INT_A2H_3
);
652 txp_start(&sc
->sc_arpcom
.ec_if
);
658 txp_rx_reclaim(struct txp_softc
*sc
, struct txp_rx_ring
*r
, struct txp_dma_alloc
*dma
)
660 struct ifnet
*ifp
= &sc
->sc_arpcom
.ec_if
;
661 struct txp_rx_desc
*rxd
;
663 struct txp_swdesc
*sd
;
664 u_int32_t roff
, woff
;
668 roff
= le32toh(*r
->r_roff
);
669 woff
= le32toh(*r
->r_woff
);
670 idx
= roff
/ sizeof(struct txp_rx_desc
);
671 rxd
= r
->r_desc
+ idx
;
673 while (roff
!= woff
) {
675 bus_dmamap_sync(sc
->sc_dmat
, dma
->dma_map
,
676 idx
* sizeof(struct txp_rx_desc
), sizeof(struct txp_rx_desc
),
677 BUS_DMASYNC_POSTREAD
);
679 if (rxd
->rx_flags
& RX_FLAGS_ERROR
) {
680 printf("%s: error 0x%x\n", device_xname(&sc
->sc_dev
),
681 le32toh(rxd
->rx_stat
));
686 /* retrieve stashed pointer */
687 memcpy(&sd
, __UNVOLATILE(&rxd
->rx_vaddrlo
), sizeof(sd
));
689 bus_dmamap_sync(sc
->sc_dmat
, sd
->sd_map
, 0,
690 sd
->sd_map
->dm_mapsize
, BUS_DMASYNC_POSTREAD
);
691 bus_dmamap_unload(sc
->sc_dmat
, sd
->sd_map
);
692 bus_dmamap_destroy(sc
->sc_dmat
, sd
->sd_map
);
695 m
->m_pkthdr
.len
= m
->m_len
= le16toh(rxd
->rx_len
);
697 #ifdef __STRICT_ALIGNMENT
700 * XXX Nice chip, except it won't accept "off by 2"
701 * buffers, so we're force to copy. Supposedly
702 * this will be fixed in a newer firmware rev
703 * and this will be temporary.
707 MGETHDR(mnew
, M_DONTWAIT
, MT_DATA
);
712 if (m
->m_len
> (MHLEN
- 2)) {
713 MCLGET(mnew
, M_DONTWAIT
);
714 if (!(mnew
->m_flags
& M_EXT
)) {
720 mnew
->m_pkthdr
.rcvif
= ifp
;
721 mnew
->m_pkthdr
.len
= mnew
->m_len
= m
->m_len
;
723 memcpy(mnew
->m_data
, m
->m_data
, m
->m_len
);
731 * Handle BPF listeners. Let the BPF user see the packet.
734 bpf_mtap(ifp
->if_bpf
, m
);
737 if (rxd
->rx_stat
& htole32(RX_STAT_IPCKSUMBAD
))
738 sumflags
|= (M_CSUM_IPv4
|M_CSUM_IPv4_BAD
);
739 else if (rxd
->rx_stat
& htole32(RX_STAT_IPCKSUMGOOD
))
740 sumflags
|= M_CSUM_IPv4
;
742 if (rxd
->rx_stat
& htole32(RX_STAT_TCPCKSUMBAD
))
743 sumflags
|= (M_CSUM_TCPv4
|M_CSUM_TCP_UDP_BAD
);
744 else if (rxd
->rx_stat
& htole32(RX_STAT_TCPCKSUMGOOD
))
745 sumflags
|= M_CSUM_TCPv4
;
747 if (rxd
->rx_stat
& htole32(RX_STAT_UDPCKSUMBAD
))
748 sumflags
|= (M_CSUM_UDPv4
|M_CSUM_TCP_UDP_BAD
);
749 else if (rxd
->rx_stat
& htole32(RX_STAT_UDPCKSUMGOOD
))
750 sumflags
|= M_CSUM_UDPv4
;
752 m
->m_pkthdr
.csum_flags
= sumflags
;
754 if (rxd
->rx_stat
& htole32(RX_STAT_VLAN
)) {
755 VLAN_INPUT_TAG(ifp
, m
, htons(rxd
->rx_vlan
>> 16),
759 (*ifp
->if_input
)(ifp
, m
);
762 bus_dmamap_sync(sc
->sc_dmat
, dma
->dma_map
,
763 idx
* sizeof(struct txp_rx_desc
), sizeof(struct txp_rx_desc
),
764 BUS_DMASYNC_PREREAD
);
766 roff
+= sizeof(struct txp_rx_desc
);
767 if (roff
== (RX_ENTRIES
* sizeof(struct txp_rx_desc
))) {
775 woff
= le32toh(*r
->r_woff
);
778 *r
->r_roff
= htole32(woff
);
782 txp_rxbuf_reclaim(struct txp_softc
*sc
)
784 struct ifnet
*ifp
= &sc
->sc_arpcom
.ec_if
;
785 struct txp_hostvar
*hv
= sc
->sc_hostvar
;
786 struct txp_rxbuf_desc
*rbd
;
787 struct txp_swdesc
*sd
;
790 end
= TXP_OFFSET2IDX(le32toh(hv
->hv_rx_buf_read_idx
));
791 i
= TXP_OFFSET2IDX(le32toh(hv
->hv_rx_buf_write_idx
));
793 if (++i
== RXBUF_ENTRIES
)
796 rbd
= sc
->sc_rxbufs
+ i
;
799 sd
= (struct txp_swdesc
*)malloc(sizeof(struct txp_swdesc
),
804 MGETHDR(sd
->sd_mbuf
, M_DONTWAIT
, MT_DATA
);
805 if (sd
->sd_mbuf
== NULL
)
808 MCLGET(sd
->sd_mbuf
, M_DONTWAIT
);
809 if ((sd
->sd_mbuf
->m_flags
& M_EXT
) == 0)
811 sd
->sd_mbuf
->m_pkthdr
.rcvif
= ifp
;
812 sd
->sd_mbuf
->m_pkthdr
.len
= sd
->sd_mbuf
->m_len
= MCLBYTES
;
813 if (bus_dmamap_create(sc
->sc_dmat
, TXP_MAX_PKTLEN
, 1,
814 TXP_MAX_PKTLEN
, 0, BUS_DMA_NOWAIT
, &sd
->sd_map
))
816 if (bus_dmamap_load_mbuf(sc
->sc_dmat
, sd
->sd_map
, sd
->sd_mbuf
,
818 bus_dmamap_destroy(sc
->sc_dmat
, sd
->sd_map
);
822 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_rxbufring_dma
.dma_map
,
823 i
* sizeof(struct txp_rxbuf_desc
),
824 sizeof(struct txp_rxbuf_desc
), BUS_DMASYNC_POSTWRITE
);
826 /* stash away pointer */
827 memcpy(__UNVOLATILE(&rbd
->rb_vaddrlo
), &sd
, sizeof(sd
));
829 rbd
->rb_paddrlo
= ((u_int64_t
)sd
->sd_map
->dm_segs
[0].ds_addr
)
831 rbd
->rb_paddrhi
= ((u_int64_t
)sd
->sd_map
->dm_segs
[0].ds_addr
)
834 bus_dmamap_sync(sc
->sc_dmat
, sd
->sd_map
, 0,
835 sd
->sd_map
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
837 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_rxbufring_dma
.dma_map
,
838 i
* sizeof(struct txp_rxbuf_desc
),
839 sizeof(struct txp_rxbuf_desc
), BUS_DMASYNC_PREWRITE
);
841 hv
->hv_rx_buf_write_idx
= htole32(TXP_IDX2OFFSET(i
));
843 if (++i
== RXBUF_ENTRIES
) {
852 m_freem(sd
->sd_mbuf
);
858 * Reclaim mbufs and entries from a transmit ring.
861 txp_tx_reclaim(struct txp_softc
*sc
, struct txp_tx_ring
*r
, struct txp_dma_alloc
*dma
)
863 struct ifnet
*ifp
= &sc
->sc_arpcom
.ec_if
;
864 u_int32_t idx
= TXP_OFFSET2IDX(le32toh(*(r
->r_off
)));
865 u_int32_t cons
= r
->r_cons
, cnt
= r
->r_cnt
;
866 struct txp_tx_desc
*txd
= r
->r_desc
+ cons
;
867 struct txp_swdesc
*sd
= sc
->sc_txd
+ cons
;
870 while (cons
!= idx
) {
874 bus_dmamap_sync(sc
->sc_dmat
, dma
->dma_map
,
875 cons
* sizeof(struct txp_tx_desc
),
876 sizeof(struct txp_tx_desc
),
877 BUS_DMASYNC_POSTWRITE
);
879 if ((txd
->tx_flags
& TX_FLAGS_TYPE_M
) ==
880 TX_FLAGS_TYPE_DATA
) {
881 bus_dmamap_sync(sc
->sc_dmat
, sd
->sd_map
, 0,
882 sd
->sd_map
->dm_mapsize
, BUS_DMASYNC_POSTWRITE
);
883 bus_dmamap_unload(sc
->sc_dmat
, sd
->sd_map
);
892 ifp
->if_flags
&= ~IFF_OACTIVE
;
894 if (++cons
== TX_ENTRIES
) {
913 txp_shutdown(device_t self
, int howto
)
915 struct txp_softc
*sc
;
917 sc
= device_private(self
);
919 /* mask all interrupts */
920 WRITE_REG(sc
, TXP_IMR
,
921 TXP_INT_SELF
| TXP_INT_PCI_TABORT
| TXP_INT_PCI_MABORT
|
922 TXP_INT_DMA3
| TXP_INT_DMA2
| TXP_INT_DMA1
| TXP_INT_DMA0
|
925 txp_command(sc
, TXP_CMD_TX_DISABLE
, 0, 0, 0, NULL
, NULL
, NULL
, 0);
926 txp_command(sc
, TXP_CMD_RX_DISABLE
, 0, 0, 0, NULL
, NULL
, NULL
, 0);
927 txp_command(sc
, TXP_CMD_HALT
, 0, 0, 0, NULL
, NULL
, NULL
, 0);
933 txp_alloc_rings(struct txp_softc
*sc
)
935 struct ifnet
*ifp
= &sc
->sc_arpcom
.ec_if
;
936 struct txp_boot_record
*boot
;
937 struct txp_swdesc
*sd
;
942 if (txp_dma_malloc(sc
, sizeof(struct txp_boot_record
), &sc
->sc_boot_dma
,
944 printf(": can't allocate boot record\n");
947 boot
= (struct txp_boot_record
*)sc
->sc_boot_dma
.dma_vaddr
;
948 memset(boot
, 0, sizeof(*boot
));
952 if (txp_dma_malloc(sc
, sizeof(struct txp_hostvar
), &sc
->sc_host_dma
,
954 printf(": can't allocate host ring\n");
957 memset(sc
->sc_host_dma
.dma_vaddr
, 0, sizeof(struct txp_hostvar
));
958 boot
->br_hostvar_lo
= htole32(sc
->sc_host_dma
.dma_paddr
& 0xffffffff);
959 boot
->br_hostvar_hi
= htole32(sc
->sc_host_dma
.dma_paddr
>> 32);
960 sc
->sc_hostvar
= (struct txp_hostvar
*)sc
->sc_host_dma
.dma_vaddr
;
962 /* high priority tx ring */
963 if (txp_dma_malloc(sc
, sizeof(struct txp_tx_desc
) * TX_ENTRIES
,
964 &sc
->sc_txhiring_dma
, BUS_DMA_COHERENT
)) {
965 printf(": can't allocate high tx ring\n");
968 memset(sc
->sc_txhiring_dma
.dma_vaddr
, 0, sizeof(struct txp_tx_desc
) * TX_ENTRIES
);
969 boot
->br_txhipri_lo
= htole32(sc
->sc_txhiring_dma
.dma_paddr
& 0xffffffff);
970 boot
->br_txhipri_hi
= htole32(sc
->sc_txhiring_dma
.dma_paddr
>> 32);
971 boot
->br_txhipri_siz
= htole32(TX_ENTRIES
* sizeof(struct txp_tx_desc
));
972 sc
->sc_txhir
.r_reg
= TXP_H2A_1
;
973 sc
->sc_txhir
.r_desc
= (struct txp_tx_desc
*)sc
->sc_txhiring_dma
.dma_vaddr
;
974 sc
->sc_txhir
.r_cons
= sc
->sc_txhir
.r_prod
= sc
->sc_txhir
.r_cnt
= 0;
975 sc
->sc_txhir
.r_off
= &sc
->sc_hostvar
->hv_tx_hi_desc_read_idx
;
976 for (i
= 0; i
< TX_ENTRIES
; i
++) {
977 if (bus_dmamap_create(sc
->sc_dmat
, TXP_MAX_PKTLEN
,
978 TX_ENTRIES
- 4, TXP_MAX_SEGLEN
, 0,
979 BUS_DMA_NOWAIT
, &sc
->sc_txd
[i
].sd_map
) != 0) {
980 for (j
= 0; j
< i
; j
++) {
981 bus_dmamap_destroy(sc
->sc_dmat
,
982 sc
->sc_txd
[j
].sd_map
);
983 sc
->sc_txd
[j
].sd_map
= NULL
;
989 /* low priority tx ring */
990 if (txp_dma_malloc(sc
, sizeof(struct txp_tx_desc
) * TX_ENTRIES
,
991 &sc
->sc_txloring_dma
, BUS_DMA_COHERENT
)) {
992 printf(": can't allocate low tx ring\n");
995 memset(sc
->sc_txloring_dma
.dma_vaddr
, 0, sizeof(struct txp_tx_desc
) * TX_ENTRIES
);
996 boot
->br_txlopri_lo
= htole32(sc
->sc_txloring_dma
.dma_paddr
& 0xffffffff);
997 boot
->br_txlopri_hi
= htole32(sc
->sc_txloring_dma
.dma_paddr
>> 32);
998 boot
->br_txlopri_siz
= htole32(TX_ENTRIES
* sizeof(struct txp_tx_desc
));
999 sc
->sc_txlor
.r_reg
= TXP_H2A_3
;
1000 sc
->sc_txlor
.r_desc
= (struct txp_tx_desc
*)sc
->sc_txloring_dma
.dma_vaddr
;
1001 sc
->sc_txlor
.r_cons
= sc
->sc_txlor
.r_prod
= sc
->sc_txlor
.r_cnt
= 0;
1002 sc
->sc_txlor
.r_off
= &sc
->sc_hostvar
->hv_tx_lo_desc_read_idx
;
1004 /* high priority rx ring */
1005 if (txp_dma_malloc(sc
, sizeof(struct txp_rx_desc
) * RX_ENTRIES
,
1006 &sc
->sc_rxhiring_dma
, BUS_DMA_COHERENT
)) {
1007 printf(": can't allocate high rx ring\n");
1010 memset(sc
->sc_rxhiring_dma
.dma_vaddr
, 0, sizeof(struct txp_rx_desc
) * RX_ENTRIES
);
1011 boot
->br_rxhipri_lo
= htole32(sc
->sc_rxhiring_dma
.dma_paddr
& 0xffffffff);
1012 boot
->br_rxhipri_hi
= htole32(sc
->sc_rxhiring_dma
.dma_paddr
>> 32);
1013 boot
->br_rxhipri_siz
= htole32(RX_ENTRIES
* sizeof(struct txp_rx_desc
));
1014 sc
->sc_rxhir
.r_desc
=
1015 (struct txp_rx_desc
*)sc
->sc_rxhiring_dma
.dma_vaddr
;
1016 sc
->sc_rxhir
.r_roff
= &sc
->sc_hostvar
->hv_rx_hi_read_idx
;
1017 sc
->sc_rxhir
.r_woff
= &sc
->sc_hostvar
->hv_rx_hi_write_idx
;
1018 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_rxhiring_dma
.dma_map
,
1019 0, sc
->sc_rxhiring_dma
.dma_map
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
1021 /* low priority ring */
1022 if (txp_dma_malloc(sc
, sizeof(struct txp_rx_desc
) * RX_ENTRIES
,
1023 &sc
->sc_rxloring_dma
, BUS_DMA_COHERENT
)) {
1024 printf(": can't allocate low rx ring\n");
1027 memset(sc
->sc_rxloring_dma
.dma_vaddr
, 0, sizeof(struct txp_rx_desc
) * RX_ENTRIES
);
1028 boot
->br_rxlopri_lo
= htole32(sc
->sc_rxloring_dma
.dma_paddr
& 0xffffffff);
1029 boot
->br_rxlopri_hi
= htole32(sc
->sc_rxloring_dma
.dma_paddr
>> 32);
1030 boot
->br_rxlopri_siz
= htole32(RX_ENTRIES
* sizeof(struct txp_rx_desc
));
1031 sc
->sc_rxlor
.r_desc
=
1032 (struct txp_rx_desc
*)sc
->sc_rxloring_dma
.dma_vaddr
;
1033 sc
->sc_rxlor
.r_roff
= &sc
->sc_hostvar
->hv_rx_lo_read_idx
;
1034 sc
->sc_rxlor
.r_woff
= &sc
->sc_hostvar
->hv_rx_lo_write_idx
;
1035 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_rxloring_dma
.dma_map
,
1036 0, sc
->sc_rxloring_dma
.dma_map
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
1039 if (txp_dma_malloc(sc
, sizeof(struct txp_cmd_desc
) * CMD_ENTRIES
,
1040 &sc
->sc_cmdring_dma
, BUS_DMA_COHERENT
)) {
1041 printf(": can't allocate command ring\n");
1044 memset(sc
->sc_cmdring_dma
.dma_vaddr
, 0, sizeof(struct txp_cmd_desc
) * CMD_ENTRIES
);
1045 boot
->br_cmd_lo
= htole32(sc
->sc_cmdring_dma
.dma_paddr
& 0xffffffff);
1046 boot
->br_cmd_hi
= htole32(sc
->sc_cmdring_dma
.dma_paddr
>> 32);
1047 boot
->br_cmd_siz
= htole32(CMD_ENTRIES
* sizeof(struct txp_cmd_desc
));
1048 sc
->sc_cmdring
.base
= (struct txp_cmd_desc
*)sc
->sc_cmdring_dma
.dma_vaddr
;
1049 sc
->sc_cmdring
.size
= CMD_ENTRIES
* sizeof(struct txp_cmd_desc
);
1050 sc
->sc_cmdring
.lastwrite
= 0;
1053 if (txp_dma_malloc(sc
, sizeof(struct txp_rsp_desc
) * RSP_ENTRIES
,
1054 &sc
->sc_rspring_dma
, BUS_DMA_COHERENT
)) {
1055 printf(": can't allocate response ring\n");
1058 memset(sc
->sc_rspring_dma
.dma_vaddr
, 0, sizeof(struct txp_rsp_desc
) * RSP_ENTRIES
);
1059 boot
->br_resp_lo
= htole32(sc
->sc_rspring_dma
.dma_paddr
& 0xffffffff);
1060 boot
->br_resp_hi
= htole32(sc
->sc_rspring_dma
.dma_paddr
>> 32);
1061 boot
->br_resp_siz
= htole32(CMD_ENTRIES
* sizeof(struct txp_rsp_desc
));
1062 sc
->sc_rspring
.base
= (struct txp_rsp_desc
*)sc
->sc_rspring_dma
.dma_vaddr
;
1063 sc
->sc_rspring
.size
= RSP_ENTRIES
* sizeof(struct txp_rsp_desc
);
1064 sc
->sc_rspring
.lastwrite
= 0;
1066 /* receive buffer ring */
1067 if (txp_dma_malloc(sc
, sizeof(struct txp_rxbuf_desc
) * RXBUF_ENTRIES
,
1068 &sc
->sc_rxbufring_dma
, BUS_DMA_COHERENT
)) {
1069 printf(": can't allocate rx buffer ring\n");
1072 memset(sc
->sc_rxbufring_dma
.dma_vaddr
, 0, sizeof(struct txp_rxbuf_desc
) * RXBUF_ENTRIES
);
1073 boot
->br_rxbuf_lo
= htole32(sc
->sc_rxbufring_dma
.dma_paddr
& 0xffffffff);
1074 boot
->br_rxbuf_hi
= htole32(sc
->sc_rxbufring_dma
.dma_paddr
>> 32);
1075 boot
->br_rxbuf_siz
= htole32(RXBUF_ENTRIES
* sizeof(struct txp_rxbuf_desc
));
1076 sc
->sc_rxbufs
= (struct txp_rxbuf_desc
*)sc
->sc_rxbufring_dma
.dma_vaddr
;
1077 for (nb
= 0; nb
< RXBUF_ENTRIES
; nb
++) {
1078 sd
= (struct txp_swdesc
*)malloc(sizeof(struct txp_swdesc
),
1079 M_DEVBUF
, M_NOWAIT
);
1080 /* stash away pointer */
1081 memcpy(__UNVOLATILE(&sc
->sc_rxbufs
[nb
].rb_vaddrlo
), &sd
, sizeof(sd
));
1085 MGETHDR(sd
->sd_mbuf
, M_DONTWAIT
, MT_DATA
);
1086 if (sd
->sd_mbuf
== NULL
) {
1087 goto bail_rxbufring
;
1090 MCLGET(sd
->sd_mbuf
, M_DONTWAIT
);
1091 if ((sd
->sd_mbuf
->m_flags
& M_EXT
) == 0) {
1092 goto bail_rxbufring
;
1094 sd
->sd_mbuf
->m_pkthdr
.len
= sd
->sd_mbuf
->m_len
= MCLBYTES
;
1095 sd
->sd_mbuf
->m_pkthdr
.rcvif
= ifp
;
1096 if (bus_dmamap_create(sc
->sc_dmat
, TXP_MAX_PKTLEN
, 1,
1097 TXP_MAX_PKTLEN
, 0, BUS_DMA_NOWAIT
, &sd
->sd_map
)) {
1098 goto bail_rxbufring
;
1100 if (bus_dmamap_load_mbuf(sc
->sc_dmat
, sd
->sd_map
, sd
->sd_mbuf
,
1102 bus_dmamap_destroy(sc
->sc_dmat
, sd
->sd_map
);
1103 goto bail_rxbufring
;
1105 bus_dmamap_sync(sc
->sc_dmat
, sd
->sd_map
, 0,
1106 sd
->sd_map
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
1109 sc
->sc_rxbufs
[nb
].rb_paddrlo
=
1110 ((u_int64_t
)sd
->sd_map
->dm_segs
[0].ds_addr
) & 0xffffffff;
1111 sc
->sc_rxbufs
[nb
].rb_paddrhi
=
1112 ((u_int64_t
)sd
->sd_map
->dm_segs
[0].ds_addr
) >> 32;
1114 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_rxbufring_dma
.dma_map
,
1115 0, sc
->sc_rxbufring_dma
.dma_map
->dm_mapsize
,
1116 BUS_DMASYNC_PREWRITE
);
1117 sc
->sc_hostvar
->hv_rx_buf_write_idx
= htole32((RXBUF_ENTRIES
- 1) *
1118 sizeof(struct txp_rxbuf_desc
));
1121 if (txp_dma_malloc(sc
, sizeof(u_int32_t
), &sc
->sc_zero_dma
,
1122 BUS_DMA_COHERENT
)) {
1123 printf(": can't allocate response ring\n");
1124 goto bail_rxbufring
;
1126 memset(sc
->sc_zero_dma
.dma_vaddr
, 0, sizeof(u_int32_t
));
1127 boot
->br_zero_lo
= htole32(sc
->sc_zero_dma
.dma_paddr
& 0xffffffff);
1128 boot
->br_zero_hi
= htole32(sc
->sc_zero_dma
.dma_paddr
>> 32);
1130 /* See if it's waiting for boot, and try to boot it */
1131 for (i
= 0; i
< 10000; i
++) {
1132 r
= READ_REG(sc
, TXP_A2H_0
);
1133 if (r
== STAT_WAITING_FOR_BOOT
)
1137 if (r
!= STAT_WAITING_FOR_BOOT
) {
1138 printf(": not waiting for boot\n");
1141 WRITE_REG(sc
, TXP_H2A_2
, sc
->sc_boot_dma
.dma_paddr
>> 32);
1142 WRITE_REG(sc
, TXP_H2A_1
, sc
->sc_boot_dma
.dma_paddr
& 0xffffffff);
1143 WRITE_REG(sc
, TXP_H2A_0
, TXP_BOOTCMD_REGISTER_BOOT_RECORD
);
1145 /* See if it booted */
1146 for (i
= 0; i
< 10000; i
++) {
1147 r
= READ_REG(sc
, TXP_A2H_0
);
1148 if (r
== STAT_RUNNING
)
1152 if (r
!= STAT_RUNNING
) {
1153 printf(": fw not running\n");
1157 /* Clear TX and CMD ring write registers */
1158 WRITE_REG(sc
, TXP_H2A_1
, TXP_BOOTCMD_NULL
);
1159 WRITE_REG(sc
, TXP_H2A_2
, TXP_BOOTCMD_NULL
);
1160 WRITE_REG(sc
, TXP_H2A_3
, TXP_BOOTCMD_NULL
);
1161 WRITE_REG(sc
, TXP_H2A_0
, TXP_BOOTCMD_NULL
);
1166 txp_dma_free(sc
, &sc
->sc_zero_dma
);
1168 if (nb
== RXBUF_ENTRIES
)
1170 for (i
= 0; i
<= nb
; i
++) {
1171 memcpy(&sd
, __UNVOLATILE(&sc
->sc_rxbufs
[i
].rb_vaddrlo
),
1176 txp_dma_free(sc
, &sc
->sc_rxbufring_dma
);
1178 txp_dma_free(sc
, &sc
->sc_rspring_dma
);
1180 txp_dma_free(sc
, &sc
->sc_cmdring_dma
);
1182 txp_dma_free(sc
, &sc
->sc_rxloring_dma
);
1184 txp_dma_free(sc
, &sc
->sc_rxhiring_dma
);
1186 txp_dma_free(sc
, &sc
->sc_txloring_dma
);
1188 txp_dma_free(sc
, &sc
->sc_txhiring_dma
);
1190 txp_dma_free(sc
, &sc
->sc_host_dma
);
1192 txp_dma_free(sc
, &sc
->sc_boot_dma
);
1197 txp_dma_malloc(struct txp_softc
*sc
, bus_size_t size
, struct txp_dma_alloc
*dma
, int mapflags
)
1201 if ((r
= bus_dmamem_alloc(sc
->sc_dmat
, size
, PAGE_SIZE
, 0,
1202 &dma
->dma_seg
, 1, &dma
->dma_nseg
, 0)) != 0)
1205 if ((r
= bus_dmamem_map(sc
->sc_dmat
, &dma
->dma_seg
, dma
->dma_nseg
,
1206 size
, &dma
->dma_vaddr
, mapflags
| BUS_DMA_NOWAIT
)) != 0)
1209 if ((r
= bus_dmamap_create(sc
->sc_dmat
, size
, 1, size
, 0,
1210 BUS_DMA_NOWAIT
, &dma
->dma_map
)) != 0)
1213 if ((r
= bus_dmamap_load(sc
->sc_dmat
, dma
->dma_map
, dma
->dma_vaddr
,
1214 size
, NULL
, BUS_DMA_NOWAIT
)) != 0)
1217 dma
->dma_paddr
= dma
->dma_map
->dm_segs
[0].ds_addr
;
1221 bus_dmamap_destroy(sc
->sc_dmat
, dma
->dma_map
);
1223 bus_dmamem_unmap(sc
->sc_dmat
, dma
->dma_vaddr
, size
);
1225 bus_dmamem_free(sc
->sc_dmat
, &dma
->dma_seg
, dma
->dma_nseg
);
1231 txp_dma_free(struct txp_softc
*sc
, struct txp_dma_alloc
*dma
)
1233 bus_dmamap_unload(sc
->sc_dmat
, dma
->dma_map
);
1234 bus_dmamem_unmap(sc
->sc_dmat
, dma
->dma_vaddr
, dma
->dma_map
->dm_mapsize
);
1235 bus_dmamem_free(sc
->sc_dmat
, &dma
->dma_seg
, dma
->dma_nseg
);
1236 bus_dmamap_destroy(sc
->sc_dmat
, dma
->dma_map
);
1240 txp_ioctl(struct ifnet
*ifp
, u_long command
, void *data
)
1242 struct txp_softc
*sc
= ifp
->if_softc
;
1243 struct ifreq
*ifr
= (struct ifreq
*)data
;
1244 struct ifaddr
*ifa
= (struct ifaddr
*)data
;
1250 if ((error
= ether_ioctl(ifp
, &sc
->sc_arpcom
, command
, data
)) > 0) {
1257 case SIOCINITIFADDR
:
1258 ifp
->if_flags
|= IFF_UP
;
1260 switch (ifa
->ifa_addr
->sa_family
) {
1263 arp_ifinit(ifp
, ifa
);
1271 if ((error
= ifioctl_common(ifp
, command
, data
)) != 0)
1273 if (ifp
->if_flags
& IFF_UP
) {
1276 if (ifp
->if_flags
& IFF_RUNNING
)
1282 if ((error
= ether_ioctl(ifp
, command
, data
)) != ENETRESET
)
1287 if (command
!= SIOCADDMULTI
&& command
!= SIOCDELMULTI
)
1289 else if (ifp
->if_flags
& IFF_RUNNING
) {
1291 * Multicast list has changed; set the hardware
1292 * filter accordingly.
1299 error
= ifmedia_ioctl(ifp
, ifr
, &sc
->sc_ifmedia
, command
);
1302 error
= ether_ioctl(ifp
, command
, data
);
1312 txp_init(struct txp_softc
*sc
)
1314 struct ifnet
*ifp
= &sc
->sc_arpcom
.ec_if
;
1323 txp_command(sc
, TXP_CMD_TX_ENABLE
, 0, 0, 0, NULL
, NULL
, NULL
, 1);
1324 txp_command(sc
, TXP_CMD_RX_ENABLE
, 0, 0, 0, NULL
, NULL
, NULL
, 1);
1326 WRITE_REG(sc
, TXP_IER
, TXP_INT_RESERVED
| TXP_INT_SELF
|
1327 TXP_INT_A2H_7
| TXP_INT_A2H_6
| TXP_INT_A2H_5
| TXP_INT_A2H_4
|
1328 TXP_INT_A2H_2
| TXP_INT_A2H_1
| TXP_INT_A2H_0
|
1329 TXP_INT_DMA3
| TXP_INT_DMA2
| TXP_INT_DMA1
| TXP_INT_DMA0
|
1330 TXP_INT_PCI_TABORT
| TXP_INT_PCI_MABORT
| TXP_INT_LATCH
);
1331 WRITE_REG(sc
, TXP_IMR
, TXP_INT_A2H_3
);
1333 ifp
->if_flags
|= IFF_RUNNING
;
1334 ifp
->if_flags
&= ~IFF_OACTIVE
;
1337 if (!callout_pending(&sc
->sc_tick
))
1338 callout_schedule(&sc
->sc_tick
, hz
);
1346 struct txp_softc
*sc
= vsc
;
1347 struct ifnet
*ifp
= &sc
->sc_arpcom
.ec_if
;
1348 struct txp_rsp_desc
*rsp
= NULL
;
1349 struct txp_ext_desc
*ext
;
1353 txp_rxbuf_reclaim(sc
);
1355 if (txp_command2(sc
, TXP_CMD_READ_STATISTICS
, 0, 0, 0, NULL
, 0,
1358 if (rsp
->rsp_numdesc
!= 6)
1360 if (txp_command(sc
, TXP_CMD_CLEAR_STATISTICS
, 0, 0, 0,
1361 NULL
, NULL
, NULL
, 1))
1363 ext
= (struct txp_ext_desc
*)(rsp
+ 1);
1365 ifp
->if_ierrors
+= ext
[3].ext_2
+ ext
[3].ext_3
+ ext
[3].ext_4
+
1366 ext
[4].ext_1
+ ext
[4].ext_4
;
1367 ifp
->if_oerrors
+= ext
[0].ext_1
+ ext
[1].ext_1
+ ext
[1].ext_4
+
1369 ifp
->if_collisions
+= ext
[0].ext_2
+ ext
[0].ext_3
+ ext
[1].ext_2
+
1371 ifp
->if_opackets
+= rsp
->rsp_par2
;
1372 ifp
->if_ipackets
+= ext
[2].ext_3
;
1376 free(rsp
, M_DEVBUF
);
1379 callout_schedule(&sc
->sc_tick
, hz
);
1383 txp_start(struct ifnet
*ifp
)
1385 struct txp_softc
*sc
= ifp
->if_softc
;
1386 struct txp_tx_ring
*r
= &sc
->sc_txhir
;
1387 struct txp_tx_desc
*txd
;
1389 struct txp_frag_desc
*fxd
;
1390 struct mbuf
*m
, *mnew
;
1391 struct txp_swdesc
*sd
;
1392 u_int32_t firstprod
, firstcnt
, prod
, cnt
, i
;
1395 if ((ifp
->if_flags
& (IFF_RUNNING
| IFF_OACTIVE
)) != IFF_RUNNING
)
1402 IFQ_POLL(&ifp
->if_snd
, m
);
1410 sd
= sc
->sc_txd
+ prod
;
1413 if (bus_dmamap_load_mbuf(sc
->sc_dmat
, sd
->sd_map
, m
,
1415 MGETHDR(mnew
, M_DONTWAIT
, MT_DATA
);
1418 if (m
->m_pkthdr
.len
> MHLEN
) {
1419 MCLGET(mnew
, M_DONTWAIT
);
1420 if ((mnew
->m_flags
& M_EXT
) == 0) {
1425 m_copydata(m
, 0, m
->m_pkthdr
.len
, mtod(mnew
, void *));
1426 mnew
->m_pkthdr
.len
= mnew
->m_len
= m
->m_pkthdr
.len
;
1427 IFQ_DEQUEUE(&ifp
->if_snd
, m
);
1430 if (bus_dmamap_load_mbuf(sc
->sc_dmat
, sd
->sd_map
, m
,
1435 if ((TX_ENTRIES
- cnt
) < 4)
1438 txd
= r
->r_desc
+ prod
;
1440 txd
->tx_flags
= TX_FLAGS_TYPE_DATA
;
1441 txd
->tx_numdesc
= 0;
1444 txd
->tx_totlen
= m
->m_pkthdr
.len
;
1446 txd
->tx_numdesc
= sd
->sd_map
->dm_nsegs
;
1448 if (++prod
== TX_ENTRIES
)
1451 if (++cnt
>= (TX_ENTRIES
- 4))
1454 if ((mtag
= VLAN_OUTPUT_TAG(&sc
->sc_arpcom
, m
)))
1455 txd
->tx_pflags
= TX_PFLAGS_VLAN
|
1456 (htons(VLAN_TAG_VALUE(mtag
)) << TX_PFLAGS_VLANTAG_S
);
1458 if (m
->m_pkthdr
.csum_flags
& M_CSUM_IPv4
)
1459 txd
->tx_pflags
|= TX_PFLAGS_IPCKSUM
;
1460 #ifdef TRY_TX_TCP_CSUM
1461 if (m
->m_pkthdr
.csum_flags
& M_CSUM_TCPv4
)
1462 txd
->tx_pflags
|= TX_PFLAGS_TCPCKSUM
;
1464 #ifdef TRY_TX_UDP_CSUM
1465 if (m
->m_pkthdr
.csum_flags
& M_CSUM_UDPv4
)
1466 txd
->tx_pflags
|= TX_PFLAGS_UDPCKSUM
;
1469 bus_dmamap_sync(sc
->sc_dmat
, sd
->sd_map
, 0,
1470 sd
->sd_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
1472 fxd
= (struct txp_frag_desc
*)(r
->r_desc
+ prod
);
1473 for (i
= 0; i
< sd
->sd_map
->dm_nsegs
; i
++) {
1474 if (++cnt
>= (TX_ENTRIES
- 4)) {
1475 bus_dmamap_sync(sc
->sc_dmat
, sd
->sd_map
,
1476 0, sd
->sd_map
->dm_mapsize
,
1477 BUS_DMASYNC_POSTWRITE
);
1481 fxd
->frag_flags
= FRAG_FLAGS_TYPE_FRAG
|
1483 fxd
->frag_rsvd1
= 0;
1484 fxd
->frag_len
= sd
->sd_map
->dm_segs
[i
].ds_len
;
1486 ((u_int64_t
)sd
->sd_map
->dm_segs
[i
].ds_addr
) &
1489 ((u_int64_t
)sd
->sd_map
->dm_segs
[i
].ds_addr
) >>
1491 fxd
->frag_rsvd2
= 0;
1493 bus_dmamap_sync(sc
->sc_dmat
,
1494 sc
->sc_txhiring_dma
.dma_map
,
1495 prod
* sizeof(struct txp_frag_desc
),
1496 sizeof(struct txp_frag_desc
), BUS_DMASYNC_PREWRITE
);
1498 if (++prod
== TX_ENTRIES
) {
1499 fxd
= (struct txp_frag_desc
*)r
->r_desc
;
1507 * if mnew isn't NULL, we already dequeued and copied
1511 IFQ_DEQUEUE(&ifp
->if_snd
, m
);
1517 bpf_mtap(ifp
->if_bpf
, m
);
1520 txd
->tx_flags
|= TX_FLAGS_VALID
;
1521 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_txhiring_dma
.dma_map
,
1522 txdidx
* sizeof(struct txp_tx_desc
),
1523 sizeof(struct txp_tx_desc
), BUS_DMASYNC_PREWRITE
);
1530 printf("txd: flags 0x%x ndesc %d totlen %d pflags 0x%x\n",
1531 txd
->tx_flags
, txd
->tx_numdesc
, txd
->tx_totlen
,
1533 for (mx
= m
; mx
!= NULL
; mx
= mx
->m_next
) {
1534 for (i
= 0; i
< mx
->m_len
; i
++) {
1536 (u_int8_t
)m
->m_data
[i
]);
1543 WRITE_REG(sc
, r
->r_reg
, TXP_IDX2OFFSET(prod
));
1551 bus_dmamap_unload(sc
->sc_dmat
, sd
->sd_map
);
1553 ifp
->if_flags
|= IFF_OACTIVE
;
1554 r
->r_prod
= firstprod
;
1555 r
->r_cnt
= firstcnt
;
1559 * Handle simple commands sent to the typhoon
1562 txp_command(struct txp_softc
*sc
, u_int16_t id
, u_int16_t in1
, u_int32_t in2
, u_int32_t in3
, u_int16_t
*out1
, u_int32_t
*out2
, u_int32_t
*out3
, int wait
)
1564 struct txp_rsp_desc
*rsp
= NULL
;
1566 if (txp_command2(sc
, id
, in1
, in2
, in3
, NULL
, 0, &rsp
, wait
))
1573 *out1
= le16toh(rsp
->rsp_par1
);
1575 *out2
= le32toh(rsp
->rsp_par2
);
1577 *out3
= le32toh(rsp
->rsp_par3
);
1578 free(rsp
, M_DEVBUF
);
1583 txp_command2(struct txp_softc
*sc
, u_int16_t id
, u_int16_t in1
, u_int32_t in2
, u_int32_t in3
, struct txp_ext_desc
*in_extp
, u_int8_t in_extn
, struct txp_rsp_desc
**rspp
, int wait
)
1585 struct txp_hostvar
*hv
= sc
->sc_hostvar
;
1586 struct txp_cmd_desc
*cmd
;
1587 struct txp_ext_desc
*ext
;
1591 if (txp_cmd_desc_numfree(sc
) < (in_extn
+ 1)) {
1592 printf("%s: no free cmd descriptors\n", TXP_DEVNAME(sc
));
1596 idx
= sc
->sc_cmdring
.lastwrite
;
1597 cmd
= (struct txp_cmd_desc
*)(((u_int8_t
*)sc
->sc_cmdring
.base
) + idx
);
1598 memset(cmd
, 0, sizeof(*cmd
));
1600 cmd
->cmd_numdesc
= in_extn
;
1602 cmd
->cmd_seq
= htole16(seq
);
1603 cmd
->cmd_id
= htole16(id
);
1604 cmd
->cmd_par1
= htole16(in1
);
1605 cmd
->cmd_par2
= htole32(in2
);
1606 cmd
->cmd_par3
= htole32(in3
);
1607 cmd
->cmd_flags
= CMD_FLAGS_TYPE_CMD
|
1608 (wait
? CMD_FLAGS_RESP
: 0) | CMD_FLAGS_VALID
;
1610 idx
+= sizeof(struct txp_cmd_desc
);
1611 if (idx
== sc
->sc_cmdring
.size
)
1614 for (i
= 0; i
< in_extn
; i
++) {
1615 ext
= (struct txp_ext_desc
*)(((u_int8_t
*)sc
->sc_cmdring
.base
) + idx
);
1616 memcpy(ext
, in_extp
, sizeof(struct txp_ext_desc
));
1618 idx
+= sizeof(struct txp_cmd_desc
);
1619 if (idx
== sc
->sc_cmdring
.size
)
1623 sc
->sc_cmdring
.lastwrite
= idx
;
1625 WRITE_REG(sc
, TXP_H2A_2
, sc
->sc_cmdring
.lastwrite
);
1626 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_host_dma
.dma_map
, 0,
1627 sizeof(struct txp_hostvar
), BUS_DMASYNC_PREREAD
);
1632 for (i
= 0; i
< 10000; i
++) {
1633 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_host_dma
.dma_map
, 0,
1634 sizeof(struct txp_hostvar
), BUS_DMASYNC_POSTREAD
);
1635 idx
= le32toh(hv
->hv_resp_read_idx
);
1636 if (idx
!= le32toh(hv
->hv_resp_write_idx
)) {
1638 if (txp_response(sc
, idx
, id
, seq
, rspp
))
1643 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_host_dma
.dma_map
, 0,
1644 sizeof(struct txp_hostvar
), BUS_DMASYNC_PREREAD
);
1647 if (i
== 1000 || (*rspp
) == NULL
) {
1648 printf("%s: 0x%x command failed\n", TXP_DEVNAME(sc
), id
);
1656 txp_response(struct txp_softc
*sc
, u_int32_t ridx
, u_int16_t id
, u_int16_t seq
, struct txp_rsp_desc
**rspp
)
1658 struct txp_hostvar
*hv
= sc
->sc_hostvar
;
1659 struct txp_rsp_desc
*rsp
;
1661 while (ridx
!= le32toh(hv
->hv_resp_write_idx
)) {
1662 rsp
= (struct txp_rsp_desc
*)(((u_int8_t
*)sc
->sc_rspring
.base
) + ridx
);
1664 if (id
== le16toh(rsp
->rsp_id
) && le16toh(rsp
->rsp_seq
) == seq
) {
1665 *rspp
= (struct txp_rsp_desc
*)malloc(
1666 sizeof(struct txp_rsp_desc
) * (rsp
->rsp_numdesc
+ 1),
1667 M_DEVBUF
, M_NOWAIT
);
1668 if ((*rspp
) == NULL
)
1670 txp_rsp_fixup(sc
, rsp
, *rspp
);
1674 if (rsp
->rsp_flags
& RSP_FLAGS_ERROR
) {
1675 printf("%s: response error: id 0x%x\n",
1676 TXP_DEVNAME(sc
), le16toh(rsp
->rsp_id
));
1677 txp_rsp_fixup(sc
, rsp
, NULL
);
1678 ridx
= le32toh(hv
->hv_resp_read_idx
);
1682 switch (le16toh(rsp
->rsp_id
)) {
1683 case TXP_CMD_CYCLE_STATISTICS
:
1684 case TXP_CMD_MEDIA_STATUS_READ
:
1686 case TXP_CMD_HELLO_RESPONSE
:
1687 printf("%s: hello\n", TXP_DEVNAME(sc
));
1690 printf("%s: unknown id(0x%x)\n", TXP_DEVNAME(sc
),
1691 le16toh(rsp
->rsp_id
));
1694 txp_rsp_fixup(sc
, rsp
, NULL
);
1695 ridx
= le32toh(hv
->hv_resp_read_idx
);
1696 hv
->hv_resp_read_idx
= le32toh(ridx
);
1703 txp_rsp_fixup(struct txp_softc
*sc
, struct txp_rsp_desc
*rsp
, struct txp_rsp_desc
*dst
)
1705 struct txp_rsp_desc
*src
= rsp
;
1706 struct txp_hostvar
*hv
= sc
->sc_hostvar
;
1709 ridx
= le32toh(hv
->hv_resp_read_idx
);
1711 for (i
= 0; i
< rsp
->rsp_numdesc
+ 1; i
++) {
1713 memcpy(dst
++, src
, sizeof(struct txp_rsp_desc
));
1714 ridx
+= sizeof(struct txp_rsp_desc
);
1715 if (ridx
== sc
->sc_rspring
.size
) {
1716 src
= sc
->sc_rspring
.base
;
1720 sc
->sc_rspring
.lastwrite
= ridx
;
1721 hv
->hv_resp_read_idx
= htole32(ridx
);
1724 hv
->hv_resp_read_idx
= htole32(ridx
);
1728 txp_cmd_desc_numfree(struct txp_softc
*sc
)
1730 struct txp_hostvar
*hv
= sc
->sc_hostvar
;
1731 struct txp_boot_record
*br
= sc
->sc_boot
;
1732 u_int32_t widx
, ridx
, nfree
;
1734 widx
= sc
->sc_cmdring
.lastwrite
;
1735 ridx
= le32toh(hv
->hv_cmd_read_idx
);
1738 /* Ring is completely free */
1739 nfree
= le32toh(br
->br_cmd_siz
) - sizeof(struct txp_cmd_desc
);
1742 nfree
= le32toh(br
->br_cmd_siz
) -
1743 (widx
- ridx
+ sizeof(struct txp_cmd_desc
));
1745 nfree
= ridx
- widx
- sizeof(struct txp_cmd_desc
);
1748 return (nfree
/ sizeof(struct txp_cmd_desc
));
1752 txp_stop(struct txp_softc
*sc
)
1754 txp_command(sc
, TXP_CMD_TX_DISABLE
, 0, 0, 0, NULL
, NULL
, NULL
, 1);
1755 txp_command(sc
, TXP_CMD_RX_DISABLE
, 0, 0, 0, NULL
, NULL
, NULL
, 1);
1757 if (callout_pending(&sc
->sc_tick
))
1758 callout_stop(&sc
->sc_tick
);
1762 txp_watchdog(struct ifnet
*ifp
)
1767 txp_ifmedia_upd(struct ifnet
*ifp
)
1769 struct txp_softc
*sc
= ifp
->if_softc
;
1770 struct ifmedia
*ifm
= &sc
->sc_ifmedia
;
1773 if (IFM_TYPE(ifm
->ifm_media
) != IFM_ETHER
)
1776 if (IFM_SUBTYPE(ifm
->ifm_media
) == IFM_10_T
) {
1777 if ((ifm
->ifm_media
& IFM_GMASK
) == IFM_FDX
)
1778 new_xcvr
= TXP_XCVR_10_FDX
;
1780 new_xcvr
= TXP_XCVR_10_HDX
;
1781 } else if ((IFM_SUBTYPE(ifm
->ifm_media
) == IFM_100_TX
) ||
1782 (IFM_SUBTYPE(ifm
->ifm_media
) == IFM_100_FX
)) {
1783 if ((ifm
->ifm_media
& IFM_GMASK
) == IFM_FDX
)
1784 new_xcvr
= TXP_XCVR_100_FDX
;
1786 new_xcvr
= TXP_XCVR_100_HDX
;
1787 } else if (IFM_SUBTYPE(ifm
->ifm_media
) == IFM_AUTO
) {
1788 new_xcvr
= TXP_XCVR_AUTO
;
1793 if (sc
->sc_xcvr
== new_xcvr
)
1796 txp_command(sc
, TXP_CMD_XCVR_SELECT
, new_xcvr
, 0, 0,
1797 NULL
, NULL
, NULL
, 0);
1798 sc
->sc_xcvr
= new_xcvr
;
1804 txp_ifmedia_sts(struct ifnet
*ifp
, struct ifmediareq
*ifmr
)
1806 struct txp_softc
*sc
= ifp
->if_softc
;
1807 struct ifmedia
*ifm
= &sc
->sc_ifmedia
;
1808 u_int16_t bmsr
, bmcr
, anlpar
;
1810 ifmr
->ifm_status
= IFM_AVALID
;
1811 ifmr
->ifm_active
= IFM_ETHER
;
1813 if (txp_command(sc
, TXP_CMD_PHY_MGMT_READ
, 0, MII_BMSR
, 0,
1814 &bmsr
, NULL
, NULL
, 1))
1816 if (txp_command(sc
, TXP_CMD_PHY_MGMT_READ
, 0, MII_BMSR
, 0,
1817 &bmsr
, NULL
, NULL
, 1))
1820 if (txp_command(sc
, TXP_CMD_PHY_MGMT_READ
, 0, MII_BMCR
, 0,
1821 &bmcr
, NULL
, NULL
, 1))
1824 if (txp_command(sc
, TXP_CMD_PHY_MGMT_READ
, 0, MII_ANLPAR
, 0,
1825 &anlpar
, NULL
, NULL
, 1))
1828 if (bmsr
& BMSR_LINK
)
1829 ifmr
->ifm_status
|= IFM_ACTIVE
;
1831 if (bmcr
& BMCR_ISO
) {
1832 ifmr
->ifm_active
|= IFM_NONE
;
1833 ifmr
->ifm_status
= 0;
1837 if (bmcr
& BMCR_LOOP
)
1838 ifmr
->ifm_active
|= IFM_LOOP
;
1840 if (!(sc
->sc_flags
& TXP_FIBER
) && (bmcr
& BMCR_AUTOEN
)) {
1841 if ((bmsr
& BMSR_ACOMP
) == 0) {
1842 ifmr
->ifm_active
|= IFM_NONE
;
1846 if (anlpar
& ANLPAR_TX_FD
)
1847 ifmr
->ifm_active
|= IFM_100_TX
|IFM_FDX
;
1848 else if (anlpar
& ANLPAR_T4
)
1849 ifmr
->ifm_active
|= IFM_100_T4
;
1850 else if (anlpar
& ANLPAR_TX
)
1851 ifmr
->ifm_active
|= IFM_100_TX
;
1852 else if (anlpar
& ANLPAR_10_FD
)
1853 ifmr
->ifm_active
|= IFM_10_T
|IFM_FDX
;
1854 else if (anlpar
& ANLPAR_10
)
1855 ifmr
->ifm_active
|= IFM_10_T
;
1857 ifmr
->ifm_active
|= IFM_NONE
;
1859 ifmr
->ifm_active
= ifm
->ifm_cur
->ifm_media
;
1863 ifmr
->ifm_active
|= IFM_NONE
;
1864 ifmr
->ifm_status
&= ~IFM_AVALID
;
1868 txp_show_descriptor(void *d
)
1870 struct txp_cmd_desc
*cmd
= d
;
1871 struct txp_rsp_desc
*rsp
= d
;
1872 struct txp_tx_desc
*txd
= d
;
1873 struct txp_frag_desc
*frgd
= d
;
1875 switch (cmd
->cmd_flags
& CMD_FLAGS_TYPE_M
) {
1876 case CMD_FLAGS_TYPE_CMD
:
1877 /* command descriptor */
1878 printf("[cmd flags 0x%x num %d id %d seq %d par1 0x%x par2 0x%x par3 0x%x]\n",
1879 cmd
->cmd_flags
, cmd
->cmd_numdesc
, le16toh(cmd
->cmd_id
),
1880 le16toh(cmd
->cmd_seq
), le16toh(cmd
->cmd_par1
),
1881 le32toh(cmd
->cmd_par2
), le32toh(cmd
->cmd_par3
));
1883 case CMD_FLAGS_TYPE_RESP
:
1884 /* response descriptor */
1885 printf("[rsp flags 0x%x num %d id %d seq %d par1 0x%x par2 0x%x par3 0x%x]\n",
1886 rsp
->rsp_flags
, rsp
->rsp_numdesc
, le16toh(rsp
->rsp_id
),
1887 le16toh(rsp
->rsp_seq
), le16toh(rsp
->rsp_par1
),
1888 le32toh(rsp
->rsp_par2
), le32toh(rsp
->rsp_par3
));
1890 case CMD_FLAGS_TYPE_DATA
:
1891 /* data header (assuming tx for now) */
1892 printf("[data flags 0x%x num %d totlen %d addr 0x%x/0x%x pflags 0x%x]",
1893 txd
->tx_flags
, txd
->tx_numdesc
, txd
->tx_totlen
,
1894 txd
->tx_addrlo
, txd
->tx_addrhi
, txd
->tx_pflags
);
1896 case CMD_FLAGS_TYPE_FRAG
:
1897 /* fragment descriptor */
1898 printf("[frag flags 0x%x rsvd1 0x%x len %d addr 0x%x/0x%x rsvd2 0x%x]",
1899 frgd
->frag_flags
, frgd
->frag_rsvd1
, frgd
->frag_len
,
1900 frgd
->frag_addrlo
, frgd
->frag_addrhi
, frgd
->frag_rsvd2
);
1903 printf("[unknown(%x) flags 0x%x num %d id %d seq %d par1 0x%x par2 0x%x par3 0x%x]\n",
1904 cmd
->cmd_flags
& CMD_FLAGS_TYPE_M
,
1905 cmd
->cmd_flags
, cmd
->cmd_numdesc
, le16toh(cmd
->cmd_id
),
1906 le16toh(cmd
->cmd_seq
), le16toh(cmd
->cmd_par1
),
1907 le32toh(cmd
->cmd_par2
), le32toh(cmd
->cmd_par3
));
1913 txp_set_filter(struct txp_softc
*sc
)
1915 struct ethercom
*ac
= &sc
->sc_arpcom
;
1916 struct ifnet
*ifp
= &sc
->sc_arpcom
.ec_if
;
1917 u_int32_t crc
, carry
, hashbit
, hash
[2];
1921 struct ether_multi
*enm
;
1922 struct ether_multistep step
;
1924 if (ifp
->if_flags
& IFF_PROMISC
) {
1925 filter
= TXP_RXFILT_PROMISC
;
1930 filter
= TXP_RXFILT_DIRECT
;
1932 if (ifp
->if_flags
& IFF_BROADCAST
)
1933 filter
|= TXP_RXFILT_BROADCAST
;
1935 if (ifp
->if_flags
& IFF_ALLMULTI
)
1936 filter
|= TXP_RXFILT_ALLMULTI
;
1938 hash
[0] = hash
[1] = 0;
1940 ETHER_FIRST_MULTI(step
, ac
, enm
);
1941 while (enm
!= NULL
) {
1942 if (memcmp(enm
->enm_addrlo
, enm
->enm_addrhi
, ETHER_ADDR_LEN
)) {
1944 * We must listen to a range of multicast
1945 * addresses. For now, just accept all
1946 * multicasts, rather than trying to set only
1947 * those filter bits needed to match the range.
1948 * (At this time, the only use of address
1949 * ranges is for IP multicast routing, for
1950 * which the range is big enough to require
1953 ifp
->if_flags
|= IFF_ALLMULTI
;
1960 for (i
= 0; i
< ETHER_ADDR_LEN
; i
++) {
1961 octet
= enm
->enm_addrlo
[i
];
1962 for (j
= 0; j
< 8; j
++) {
1963 carry
= ((crc
& 0x80000000) ? 1 : 0) ^
1968 crc
= (crc
^ TXP_POLYNOMIAL
) |
1972 hashbit
= (u_int16_t
)(crc
& (64 - 1));
1973 hash
[hashbit
/ 32] |= (1 << hashbit
% 32);
1974 ETHER_NEXT_MULTI(step
, enm
);
1978 filter
|= TXP_RXFILT_HASHMULTI
;
1979 txp_command(sc
, TXP_CMD_MCAST_HASH_MASK_WRITE
,
1980 2, hash
[0], hash
[1], NULL
, NULL
, NULL
, 0);
1985 txp_command(sc
, TXP_CMD_RX_FILTER_WRITE
, filter
, 0, 0,
1986 NULL
, NULL
, NULL
, 1);
1990 txp_capabilities(struct txp_softc
*sc
)
1992 struct ifnet
*ifp
= &sc
->sc_arpcom
.ec_if
;
1993 struct txp_rsp_desc
*rsp
= NULL
;
1994 struct txp_ext_desc
*ext
;
1996 if (txp_command2(sc
, TXP_CMD_OFFLOAD_READ
, 0, 0, 0, NULL
, 0, &rsp
, 1))
1999 if (rsp
->rsp_numdesc
!= 1)
2001 ext
= (struct txp_ext_desc
*)(rsp
+ 1);
2003 sc
->sc_tx_capability
= ext
->ext_1
& OFFLOAD_MASK
;
2004 sc
->sc_rx_capability
= ext
->ext_2
& OFFLOAD_MASK
;
2006 sc
->sc_arpcom
.ec_capabilities
|= ETHERCAP_VLAN_MTU
;
2007 if (rsp
->rsp_par2
& rsp
->rsp_par3
& OFFLOAD_VLAN
) {
2008 sc
->sc_tx_capability
|= OFFLOAD_VLAN
;
2009 sc
->sc_rx_capability
|= OFFLOAD_VLAN
;
2010 sc
->sc_arpcom
.ec_capabilities
|= ETHERCAP_VLAN_HWTAGGING
;
2015 if (rsp
->rsp_par2
& rsp
->rsp_par3
& OFFLOAD_IPSEC
) {
2016 sc
->sc_tx_capability
|= OFFLOAD_IPSEC
;
2017 sc
->sc_rx_capability
|= OFFLOAD_IPSEC
;
2018 ifp
->if_capabilities
|= IFCAP_IPSEC
;
2022 if (rsp
->rsp_par2
& rsp
->rsp_par3
& OFFLOAD_IPCKSUM
) {
2023 sc
->sc_tx_capability
|= OFFLOAD_IPCKSUM
;
2024 sc
->sc_rx_capability
|= OFFLOAD_IPCKSUM
;
2025 ifp
->if_capabilities
|= IFCAP_CSUM_IPv4_Tx
| IFCAP_CSUM_IPv4_Rx
;
2028 if (rsp
->rsp_par2
& rsp
->rsp_par3
& OFFLOAD_TCPCKSUM
) {
2029 sc
->sc_rx_capability
|= OFFLOAD_TCPCKSUM
;
2030 #ifdef TRY_TX_TCP_CSUM
2031 sc
->sc_tx_capability
|= OFFLOAD_TCPCKSUM
;
2032 ifp
->if_capabilities
|=
2033 IFCAP_CSUM_TCPv4_Tx
| IFCAP_CSUM_TCPv4_Rx
;
2037 if (rsp
->rsp_par2
& rsp
->rsp_par3
& OFFLOAD_UDPCKSUM
) {
2038 sc
->sc_rx_capability
|= OFFLOAD_UDPCKSUM
;
2039 #ifdef TRY_TX_UDP_CSUM
2040 sc
->sc_tx_capability
|= OFFLOAD_UDPCKSUM
;
2041 ifp
->if_capabilities
|=
2042 IFCAP_CSUM_UDPv4_Tx
| IFCAP_CSUM_UDPv4_Rx
;
2046 if (txp_command(sc
, TXP_CMD_OFFLOAD_WRITE
, 0,
2047 sc
->sc_tx_capability
, sc
->sc_rx_capability
, NULL
, NULL
, NULL
, 1))
2052 free(rsp
, M_DEVBUF
);