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