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