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