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