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