if_txp.c revision 158651
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 158651 2006-05-16 14:37:58Z phk $"); 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 158651 2006-05-16 14:37:58Z phk $"); 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/bus.h> 77#include <machine/resource.h> 78#include <sys/bus.h> 79#include <sys/rman.h> 80 81#include <dev/mii/mii.h> 82#include <dev/mii/miivar.h> 83#include <dev/pci/pcireg.h> 84#include <dev/pci/pcivar.h> 85 86#define TXP_USEIOSPACE 87#define __STRICT_ALIGNMENT 88 89#include <dev/txp/if_txpreg.h> 90#include <dev/txp/3c990img.h> 91 92#ifndef lint 93static const char rcsid[] = 94 "$FreeBSD: head/sys/dev/txp/if_txp.c 158651 2006-05-16 14:37:58Z phk $"; 95#endif 96 97/* 98 * Various supported device vendors/types and their names. 99 */ 100static struct txp_type txp_devs[] = { 101 { TXP_VENDORID_3COM, TXP_DEVICEID_3CR990_TX_95, 102 "3Com 3cR990-TX-95 Etherlink with 3XP Processor" }, 103 { TXP_VENDORID_3COM, TXP_DEVICEID_3CR990_TX_97, 104 "3Com 3cR990-TX-97 Etherlink with 3XP Processor" }, 105 { TXP_VENDORID_3COM, TXP_DEVICEID_3CR990B_TXM, 106 "3Com 3cR990B-TXM Etherlink with 3XP Processor" }, 107 { TXP_VENDORID_3COM, TXP_DEVICEID_3CR990_SRV_95, 108 "3Com 3cR990-SRV-95 Etherlink Server with 3XP Processor" }, 109 { TXP_VENDORID_3COM, TXP_DEVICEID_3CR990_SRV_97, 110 "3Com 3cR990-SRV-97 Etherlink Server with 3XP Processor" }, 111 { TXP_VENDORID_3COM, TXP_DEVICEID_3CR990B_SRV, 112 "3Com 3cR990B-SRV Etherlink Server with 3XP Processor" }, 113 { 0, 0, NULL } 114}; 115 116static int txp_probe(device_t); 117static int txp_attach(device_t); 118static int txp_detach(device_t); 119static void txp_intr(void *); 120static void txp_tick(void *); 121static int txp_shutdown(device_t); 122static int txp_ioctl(struct ifnet *, u_long, caddr_t); 123static void txp_start(struct ifnet *); 124static void txp_start_locked(struct ifnet *); 125static void txp_stop(struct txp_softc *); 126static void txp_init(void *); 127static void txp_init_locked(struct txp_softc *); 128static void txp_watchdog(struct ifnet *); 129 130static void txp_release_resources(struct txp_softc *); 131static int txp_chip_init(struct txp_softc *); 132static int txp_reset_adapter(struct txp_softc *); 133static int txp_download_fw(struct txp_softc *); 134static int txp_download_fw_wait(struct txp_softc *); 135static int txp_download_fw_section(struct txp_softc *, 136 struct txp_fw_section_header *, int); 137static int txp_alloc_rings(struct txp_softc *); 138static int txp_rxring_fill(struct txp_softc *); 139static void txp_rxring_empty(struct txp_softc *); 140static void txp_set_filter(struct txp_softc *); 141 142static int txp_cmd_desc_numfree(struct txp_softc *); 143static int txp_command(struct txp_softc *, u_int16_t, u_int16_t, u_int32_t, 144 u_int32_t, u_int16_t *, u_int32_t *, u_int32_t *, int); 145static int txp_command2(struct txp_softc *, u_int16_t, u_int16_t, 146 u_int32_t, u_int32_t, struct txp_ext_desc *, u_int8_t, 147 struct txp_rsp_desc **, int); 148static int txp_response(struct txp_softc *, u_int32_t, u_int16_t, u_int16_t, 149 struct txp_rsp_desc **); 150static void txp_rsp_fixup(struct txp_softc *, struct txp_rsp_desc *, 151 struct txp_rsp_desc *); 152static void txp_capabilities(struct txp_softc *); 153 154static void txp_ifmedia_sts(struct ifnet *, struct ifmediareq *); 155static int txp_ifmedia_upd(struct ifnet *); 156#ifdef TXP_DEBUG 157static void txp_show_descriptor(void *); 158#endif 159static void txp_tx_reclaim(struct txp_softc *, struct txp_tx_ring *); 160static void txp_rxbuf_reclaim(struct txp_softc *); 161static void txp_rx_reclaim(struct txp_softc *, struct txp_rx_ring *); 162 163#ifdef TXP_USEIOSPACE 164#define TXP_RES SYS_RES_IOPORT 165#define TXP_RID TXP_PCI_LOIO 166#else 167#define TXP_RES SYS_RES_MEMORY 168#define TXP_RID TXP_PCI_LOMEM 169#endif 170 171static device_method_t txp_methods[] = { 172 /* Device interface */ 173 DEVMETHOD(device_probe, txp_probe), 174 DEVMETHOD(device_attach, txp_attach), 175 DEVMETHOD(device_detach, txp_detach), 176 DEVMETHOD(device_shutdown, txp_shutdown), 177 { 0, 0 } 178}; 179 180static driver_t txp_driver = { 181 "txp", 182 txp_methods, 183 sizeof(struct txp_softc) 184}; 185 186static devclass_t txp_devclass; 187 188DRIVER_MODULE(txp, pci, txp_driver, txp_devclass, 0, 0); 189MODULE_DEPEND(txp, pci, 1, 1, 1); 190MODULE_DEPEND(txp, ether, 1, 1, 1); 191 192static int 193txp_probe(dev) 194 device_t dev; 195{ 196 struct txp_type *t; 197 198 t = txp_devs; 199 200 while(t->txp_name != NULL) { 201 if ((pci_get_vendor(dev) == t->txp_vid) && 202 (pci_get_device(dev) == t->txp_did)) { 203 device_set_desc(dev, t->txp_name); 204 return(BUS_PROBE_DEFAULT); 205 } 206 t++; 207 } 208 209 return(ENXIO); 210} 211 212static int 213txp_attach(dev) 214 device_t dev; 215{ 216 struct txp_softc *sc; 217 struct ifnet *ifp; 218 u_int16_t p1; 219 u_int32_t p2; 220 int error = 0, rid; 221 u_char eaddr[6]; 222 223 sc = device_get_softc(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); 229 callout_init_mtx(&sc->sc_tick, &sc->sc_mtx, 0); 230 231 /* 232 * Map control/status registers. 233 */ 234 pci_enable_busmaster(dev); 235 236 rid = TXP_RID; 237 sc->sc_res = bus_alloc_resource_any(dev, TXP_RES, &rid, 238 RF_ACTIVE); 239 240 if (sc->sc_res == NULL) { 241 device_printf(dev, "couldn't map ports/memory\n"); 242 error = ENXIO; 243 goto fail; 244 } 245 246 sc->sc_bt = rman_get_bustag(sc->sc_res); 247 sc->sc_bh = rman_get_bushandle(sc->sc_res); 248 249 /* Allocate interrupt */ 250 rid = 0; 251 sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 252 RF_SHAREABLE | RF_ACTIVE); 253 254 if (sc->sc_irq == NULL) { 255 device_printf(dev, "couldn't map interrupt\n"); 256 error = ENXIO; 257 goto fail; 258 } 259 260 if (txp_chip_init(sc)) { 261 error = ENXIO; 262 goto fail; 263 } 264 265 sc->sc_fwbuf = contigmalloc(32768, M_DEVBUF, 266 M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0); 267 error = txp_download_fw(sc); 268 contigfree(sc->sc_fwbuf, 32768, M_DEVBUF); 269 sc->sc_fwbuf = NULL; 270 271 if (error) 272 goto fail; 273 274 sc->sc_ldata = contigmalloc(sizeof(struct txp_ldata), M_DEVBUF, 275 M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0); 276 bzero(sc->sc_ldata, sizeof(struct txp_ldata)); 277 278 if (txp_alloc_rings(sc)) { 279 error = ENXIO; 280 goto fail; 281 } 282 283 if (txp_command(sc, TXP_CMD_MAX_PKT_SIZE_WRITE, TXP_MAX_PKTLEN, 0, 0, 284 NULL, NULL, NULL, 1)) { 285 error = ENXIO; 286 goto fail; 287 } 288 289 if (txp_command(sc, TXP_CMD_STATION_ADDRESS_READ, 0, 0, 0, 290 &p1, &p2, NULL, 1)) { 291 error = ENXIO; 292 goto fail; 293 } 294 295 eaddr[0] = ((u_int8_t *)&p1)[1]; 296 eaddr[1] = ((u_int8_t *)&p1)[0]; 297 eaddr[2] = ((u_int8_t *)&p2)[3]; 298 eaddr[3] = ((u_int8_t *)&p2)[2]; 299 eaddr[4] = ((u_int8_t *)&p2)[1]; 300 eaddr[5] = ((u_int8_t *)&p2)[0]; 301 302 sc->sc_cold = 0; 303 304 ifmedia_init(&sc->sc_ifmedia, 0, txp_ifmedia_upd, txp_ifmedia_sts); 305 ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); 306 ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL); 307 ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); 308 ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL); 309 ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX|IFM_HDX, 0, NULL); 310 ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL); 311 ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL); 312 313 sc->sc_xcvr = TXP_XCVR_AUTO; 314 txp_command(sc, TXP_CMD_XCVR_SELECT, TXP_XCVR_AUTO, 0, 0, 315 NULL, NULL, NULL, 0); 316 ifmedia_set(&sc->sc_ifmedia, IFM_ETHER|IFM_AUTO); 317 318 ifp = sc->sc_ifp = if_alloc(IFT_ETHER); 319 if (ifp == NULL) { 320 device_printf(dev, "can not if_alloc()\n"); 321 error = ENOSPC; 322 goto fail; 323 } 324 ifp->if_softc = sc; 325 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 326 ifp->if_mtu = ETHERMTU; 327 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 328 ifp->if_ioctl = txp_ioctl; 329 ifp->if_start = txp_start; 330 ifp->if_watchdog = txp_watchdog; 331 ifp->if_init = txp_init; 332 ifp->if_baudrate = 100000000; 333 ifp->if_snd.ifq_maxlen = TX_ENTRIES; 334 ifp->if_hwassist = 0; 335 txp_capabilities(sc); 336 337 /* 338 * Attach us everywhere 339 */ 340 ether_ifattach(ifp, eaddr); 341 342 error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_NET | INTR_MPSAFE, 343 txp_intr, sc, &sc->sc_intrhand); 344 345 if (error) { 346 ether_ifdetach(ifp); 347 device_printf(dev, "couldn't set up irq\n"); 348 goto fail; 349 } 350 351 return(0); 352 353fail: 354 txp_release_resources(sc); 355 mtx_destroy(&sc->sc_mtx); 356 return(error); 357} 358 359static int 360txp_detach(dev) 361 device_t dev; 362{ 363 struct txp_softc *sc; 364 struct ifnet *ifp; 365 int i; 366 367 sc = device_get_softc(dev); 368 ifp = sc->sc_ifp; 369 370 TXP_LOCK(sc); 371 txp_stop(sc); 372 TXP_UNLOCK(sc); 373 txp_shutdown(dev); 374 callout_drain(&sc->sc_tick); 375 376 ifmedia_removeall(&sc->sc_ifmedia); 377 ether_ifdetach(ifp); 378 379 for (i = 0; i < RXBUF_ENTRIES; i++) 380 free(sc->sc_rxbufs[i].rb_sd, M_DEVBUF); 381 382 txp_release_resources(sc); 383 384 mtx_destroy(&sc->sc_mtx); 385 return(0); 386} 387 388static void 389txp_release_resources(sc) 390 struct txp_softc *sc; 391{ 392 device_t dev; 393 394 dev = sc->sc_dev; 395 396 if (sc->sc_intrhand != NULL) 397 bus_teardown_intr(dev, sc->sc_irq, sc->sc_intrhand); 398 399 if (sc->sc_irq != NULL) 400 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq); 401 402 if (sc->sc_res != NULL) 403 bus_release_resource(dev, TXP_RES, TXP_RID, sc->sc_res); 404 405 if (sc->sc_ldata != NULL) 406 contigfree(sc->sc_ldata, sizeof(struct txp_ldata), M_DEVBUF); 407 408 if (sc->sc_ifp) 409 if_free(sc->sc_ifp); 410 411 return; 412} 413 414static int 415txp_chip_init(sc) 416 struct txp_softc *sc; 417{ 418 /* disable interrupts */ 419 WRITE_REG(sc, TXP_IER, 0); 420 WRITE_REG(sc, TXP_IMR, 421 TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT | 422 TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 | 423 TXP_INT_LATCH); 424 425 /* ack all interrupts */ 426 WRITE_REG(sc, TXP_ISR, TXP_INT_RESERVED | TXP_INT_LATCH | 427 TXP_INT_A2H_7 | TXP_INT_A2H_6 | TXP_INT_A2H_5 | TXP_INT_A2H_4 | 428 TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT | 429 TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 | 430 TXP_INT_A2H_3 | TXP_INT_A2H_2 | TXP_INT_A2H_1 | TXP_INT_A2H_0); 431 432 if (txp_reset_adapter(sc)) 433 return (-1); 434 435 /* disable interrupts */ 436 WRITE_REG(sc, TXP_IER, 0); 437 WRITE_REG(sc, TXP_IMR, 438 TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT | 439 TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 | 440 TXP_INT_LATCH); 441 442 /* ack all interrupts */ 443 WRITE_REG(sc, TXP_ISR, TXP_INT_RESERVED | TXP_INT_LATCH | 444 TXP_INT_A2H_7 | TXP_INT_A2H_6 | TXP_INT_A2H_5 | TXP_INT_A2H_4 | 445 TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT | 446 TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 | 447 TXP_INT_A2H_3 | TXP_INT_A2H_2 | TXP_INT_A2H_1 | TXP_INT_A2H_0); 448 449 return (0); 450} 451 452static int 453txp_reset_adapter(sc) 454 struct txp_softc *sc; 455{ 456 u_int32_t r; 457 int i; 458 459 r = 0; 460 WRITE_REG(sc, TXP_SRR, TXP_SRR_ALL); 461 DELAY(1000); 462 WRITE_REG(sc, TXP_SRR, 0); 463 464 /* Should wait max 6 seconds */ 465 for (i = 0; i < 6000; i++) { 466 r = READ_REG(sc, TXP_A2H_0); 467 if (r == STAT_WAITING_FOR_HOST_REQUEST) 468 break; 469 DELAY(1000); 470 } 471 472 if (r != STAT_WAITING_FOR_HOST_REQUEST) { 473 device_printf(sc->sc_dev, "reset hung\n"); 474 return (-1); 475 } 476 477 return (0); 478} 479 480static int 481txp_download_fw(sc) 482 struct txp_softc *sc; 483{ 484 struct txp_fw_file_header *fileheader; 485 struct txp_fw_section_header *secthead; 486 int sect; 487 u_int32_t r, i, ier, imr; 488 489 r = 0; 490 ier = READ_REG(sc, TXP_IER); 491 WRITE_REG(sc, TXP_IER, ier | TXP_INT_A2H_0); 492 493 imr = READ_REG(sc, TXP_IMR); 494 WRITE_REG(sc, TXP_IMR, imr | TXP_INT_A2H_0); 495 496 for (i = 0; i < 10000; i++) { 497 r = READ_REG(sc, TXP_A2H_0); 498 if (r == STAT_WAITING_FOR_HOST_REQUEST) 499 break; 500 DELAY(50); 501 } 502 if (r != STAT_WAITING_FOR_HOST_REQUEST) { 503 device_printf(sc->sc_dev, "not waiting for host request\n"); 504 return (-1); 505 } 506 507 /* Ack the status */ 508 WRITE_REG(sc, TXP_ISR, TXP_INT_A2H_0); 509 510 fileheader = (struct txp_fw_file_header *)tc990image; 511 if (bcmp("TYPHOON", fileheader->magicid, sizeof(fileheader->magicid))) { 512 device_printf(sc->sc_dev, "fw invalid magic\n"); 513 return (-1); 514 } 515 516 /* Tell boot firmware to get ready for image */ 517 WRITE_REG(sc, TXP_H2A_1, fileheader->addr); 518 WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_RUNTIME_IMAGE); 519 520 if (txp_download_fw_wait(sc)) { 521 device_printf(sc->sc_dev, "fw wait failed, initial\n"); 522 return (-1); 523 } 524 525 secthead = (struct txp_fw_section_header *)(((u_int8_t *)tc990image) + 526 sizeof(struct txp_fw_file_header)); 527 528 for (sect = 0; sect < fileheader->nsections; sect++) { 529 if (txp_download_fw_section(sc, secthead, sect)) 530 return (-1); 531 secthead = (struct txp_fw_section_header *) 532 (((u_int8_t *)secthead) + secthead->nbytes + 533 sizeof(*secthead)); 534 } 535 536 WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_DOWNLOAD_COMPLETE); 537 538 for (i = 0; i < 10000; i++) { 539 r = READ_REG(sc, TXP_A2H_0); 540 if (r == STAT_WAITING_FOR_BOOT) 541 break; 542 DELAY(50); 543 } 544 if (r != STAT_WAITING_FOR_BOOT) { 545 device_printf(sc->sc_dev, "not waiting for boot\n"); 546 return (-1); 547 } 548 549 WRITE_REG(sc, TXP_IER, ier); 550 WRITE_REG(sc, TXP_IMR, imr); 551 552 return (0); 553} 554 555static int 556txp_download_fw_wait(sc) 557 struct txp_softc *sc; 558{ 559 u_int32_t i, r; 560 561 r = 0; 562 for (i = 0; i < 10000; i++) { 563 r = READ_REG(sc, TXP_ISR); 564 if (r & TXP_INT_A2H_0) 565 break; 566 DELAY(50); 567 } 568 569 if (!(r & TXP_INT_A2H_0)) { 570 device_printf(sc->sc_dev, "fw wait failed comm0\n"); 571 return (-1); 572 } 573 574 WRITE_REG(sc, TXP_ISR, TXP_INT_A2H_0); 575 576 r = READ_REG(sc, TXP_A2H_0); 577 if (r != STAT_WAITING_FOR_SEGMENT) { 578 device_printf(sc->sc_dev, "fw not waiting for segment\n"); 579 return (-1); 580 } 581 return (0); 582} 583 584static int 585txp_download_fw_section(sc, sect, sectnum) 586 struct txp_softc *sc; 587 struct txp_fw_section_header *sect; 588 int sectnum; 589{ 590 vm_offset_t dma; 591 int rseg, err = 0; 592 struct mbuf m; 593 u_int16_t csum; 594 595 /* Skip zero length sections */ 596 if (sect->nbytes == 0) 597 return (0); 598 599 /* Make sure we aren't past the end of the image */ 600 rseg = ((u_int8_t *)sect) - ((u_int8_t *)tc990image); 601 if (rseg >= sizeof(tc990image)) { 602 device_printf(sc->sc_dev, "fw invalid section address, " 603 "section %d\n", sectnum); 604 return (-1); 605 } 606 607 /* Make sure this section doesn't go past the end */ 608 rseg += sect->nbytes; 609 if (rseg >= sizeof(tc990image)) { 610 device_printf(sc->sc_dev, "fw truncated section %d\n", 611 sectnum); 612 return (-1); 613 } 614 615 bcopy(((u_int8_t *)sect) + sizeof(*sect), sc->sc_fwbuf, sect->nbytes); 616 dma = vtophys(sc->sc_fwbuf); 617 618 /* 619 * dummy up mbuf and verify section checksum 620 */ 621 m.m_type = MT_DATA; 622 m.m_next = m.m_nextpkt = NULL; 623 m.m_len = sect->nbytes; 624 m.m_data = sc->sc_fwbuf; 625 m.m_flags = 0; 626 csum = in_cksum(&m, sect->nbytes); 627 if (csum != sect->cksum) { 628 device_printf(sc->sc_dev, "fw section %d, bad " 629 "cksum (expected 0x%x got 0x%x)\n", 630 sectnum, sect->cksum, csum); 631 err = -1; 632 goto bail; 633 } 634 635 WRITE_REG(sc, TXP_H2A_1, sect->nbytes); 636 WRITE_REG(sc, TXP_H2A_2, sect->cksum); 637 WRITE_REG(sc, TXP_H2A_3, sect->addr); 638 WRITE_REG(sc, TXP_H2A_4, 0); 639 WRITE_REG(sc, TXP_H2A_5, dma & 0xffffffff); 640 WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_SEGMENT_AVAILABLE); 641 642 if (txp_download_fw_wait(sc)) { 643 device_printf(sc->sc_dev, "fw wait failed, " 644 "section %d\n", sectnum); 645 err = -1; 646 } 647 648bail: 649 return (err); 650} 651 652static void 653txp_intr(vsc) 654 void *vsc; 655{ 656 struct txp_softc *sc = vsc; 657 struct txp_hostvar *hv = sc->sc_hostvar; 658 u_int32_t isr; 659 660 /* mask all interrupts */ 661 TXP_LOCK(sc); 662 WRITE_REG(sc, TXP_IMR, TXP_INT_RESERVED | TXP_INT_SELF | 663 TXP_INT_A2H_7 | TXP_INT_A2H_6 | TXP_INT_A2H_5 | TXP_INT_A2H_4 | 664 TXP_INT_A2H_2 | TXP_INT_A2H_1 | TXP_INT_A2H_0 | 665 TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 | 666 TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT | TXP_INT_LATCH); 667 668 isr = READ_REG(sc, TXP_ISR); 669 while (isr) { 670 WRITE_REG(sc, TXP_ISR, isr); 671 672 if ((*sc->sc_rxhir.r_roff) != (*sc->sc_rxhir.r_woff)) 673 txp_rx_reclaim(sc, &sc->sc_rxhir); 674 if ((*sc->sc_rxlor.r_roff) != (*sc->sc_rxlor.r_woff)) 675 txp_rx_reclaim(sc, &sc->sc_rxlor); 676 677 if (hv->hv_rx_buf_write_idx == hv->hv_rx_buf_read_idx) 678 txp_rxbuf_reclaim(sc); 679 680 if (sc->sc_txhir.r_cnt && (sc->sc_txhir.r_cons != 681 TXP_OFFSET2IDX(*(sc->sc_txhir.r_off)))) 682 txp_tx_reclaim(sc, &sc->sc_txhir); 683 684 if (sc->sc_txlor.r_cnt && (sc->sc_txlor.r_cons != 685 TXP_OFFSET2IDX(*(sc->sc_txlor.r_off)))) 686 txp_tx_reclaim(sc, &sc->sc_txlor); 687 688 isr = READ_REG(sc, TXP_ISR); 689 } 690 691 /* unmask all interrupts */ 692 WRITE_REG(sc, TXP_IMR, TXP_INT_A2H_3); 693 694 txp_start_locked(sc->sc_ifp); 695 TXP_UNLOCK(sc); 696 697 return; 698} 699 700static void 701txp_rx_reclaim(sc, r) 702 struct txp_softc *sc; 703 struct txp_rx_ring *r; 704{ 705 struct ifnet *ifp = sc->sc_ifp; 706 struct txp_rx_desc *rxd; 707 struct mbuf *m; 708 struct txp_swdesc *sd = NULL; 709 u_int32_t roff, woff; 710 711 TXP_LOCK_ASSERT(sc); 712 roff = *r->r_roff; 713 woff = *r->r_woff; 714 rxd = r->r_desc + (roff / sizeof(struct txp_rx_desc)); 715 716 while (roff != woff) { 717 718 if (rxd->rx_flags & RX_FLAGS_ERROR) { 719 device_printf(sc->sc_dev, "error 0x%x\n", 720 rxd->rx_stat); 721 ifp->if_ierrors++; 722 goto next; 723 } 724 725 /* retrieve stashed pointer */ 726 sd = rxd->rx_sd; 727 728 m = sd->sd_mbuf; 729 sd->sd_mbuf = NULL; 730 731 m->m_pkthdr.len = m->m_len = rxd->rx_len; 732 733#ifdef __STRICT_ALIGNMENT 734 { 735 /* 736 * XXX Nice chip, except it won't accept "off by 2" 737 * buffers, so we're force to copy. Supposedly 738 * this will be fixed in a newer firmware rev 739 * and this will be temporary. 740 */ 741 struct mbuf *mnew; 742 743 mnew = m_devget(mtod(m, caddr_t), rxd->rx_len, 744 ETHER_ALIGN, ifp, NULL); 745 m_freem(m); 746 if (mnew == NULL) { 747 ifp->if_ierrors++; 748 goto next; 749 } 750 m = mnew; 751 } 752#endif 753 754 if (rxd->rx_stat & RX_STAT_IPCKSUMBAD) 755 m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED; 756 else if (rxd->rx_stat & RX_STAT_IPCKSUMGOOD) 757 m->m_pkthdr.csum_flags |= 758 CSUM_IP_CHECKED|CSUM_IP_VALID; 759 760 if ((rxd->rx_stat & RX_STAT_TCPCKSUMGOOD) || 761 (rxd->rx_stat & RX_STAT_UDPCKSUMGOOD)) { 762 m->m_pkthdr.csum_flags |= 763 CSUM_DATA_VALID|CSUM_PSEUDO_HDR; 764 m->m_pkthdr.csum_data = 0xffff; 765 } 766 767 if (rxd->rx_stat & RX_STAT_VLAN) { 768 VLAN_INPUT_TAG(ifp, m, htons(rxd->rx_vlan >> 16)); 769 if (m == NULL) 770 goto next; 771 } 772 773 TXP_UNLOCK(sc); 774 (*ifp->if_input)(ifp, m); 775 TXP_LOCK(sc); 776 777next: 778 779 roff += sizeof(struct txp_rx_desc); 780 if (roff == (RX_ENTRIES * sizeof(struct txp_rx_desc))) { 781 roff = 0; 782 rxd = r->r_desc; 783 } else 784 rxd++; 785 woff = *r->r_woff; 786 } 787 788 *r->r_roff = woff; 789 790 return; 791} 792 793static void 794txp_rxbuf_reclaim(sc) 795 struct txp_softc *sc; 796{ 797 struct ifnet *ifp = sc->sc_ifp; 798 struct txp_hostvar *hv = sc->sc_hostvar; 799 struct txp_rxbuf_desc *rbd; 800 struct txp_swdesc *sd; 801 u_int32_t i; 802 803 TXP_LOCK_ASSERT(sc); 804 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) 805 return; 806 807 i = sc->sc_rxbufprod; 808 rbd = sc->sc_rxbufs + i; 809 810 while (1) { 811 sd = rbd->rb_sd; 812 if (sd->sd_mbuf != NULL) 813 break; 814 815 sd->sd_mbuf = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 816 if (sd->sd_mbuf == NULL) 817 return; 818 sd->sd_mbuf->m_pkthdr.rcvif = ifp; 819 sd->sd_mbuf->m_pkthdr.len = sd->sd_mbuf->m_len = MCLBYTES; 820 821 rbd->rb_paddrlo = vtophys(mtod(sd->sd_mbuf, vm_offset_t)) 822 & 0xffffffff; 823 rbd->rb_paddrhi = 0; 824 825 hv->hv_rx_buf_write_idx = TXP_IDX2OFFSET(i); 826 827 if (++i == RXBUF_ENTRIES) { 828 i = 0; 829 rbd = sc->sc_rxbufs; 830 } else 831 rbd++; 832 } 833 834 sc->sc_rxbufprod = i; 835 836 return; 837} 838 839/* 840 * Reclaim mbufs and entries from a transmit ring. 841 */ 842static void 843txp_tx_reclaim(sc, r) 844 struct txp_softc *sc; 845 struct txp_tx_ring *r; 846{ 847 struct ifnet *ifp = sc->sc_ifp; 848 u_int32_t idx = TXP_OFFSET2IDX(*(r->r_off)); 849 u_int32_t cons = r->r_cons, cnt = r->r_cnt; 850 struct txp_tx_desc *txd = r->r_desc + cons; 851 struct txp_swdesc *sd = sc->sc_txd + cons; 852 struct mbuf *m; 853 854 TXP_LOCK_ASSERT(sc); 855 while (cons != idx) { 856 if (cnt == 0) 857 break; 858 859 if ((txd->tx_flags & TX_FLAGS_TYPE_M) == 860 TX_FLAGS_TYPE_DATA) { 861 m = sd->sd_mbuf; 862 if (m != NULL) { 863 m_freem(m); 864 txd->tx_addrlo = 0; 865 txd->tx_addrhi = 0; 866 ifp->if_opackets++; 867 } 868 } 869 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 870 871 if (++cons == TX_ENTRIES) { 872 txd = r->r_desc; 873 cons = 0; 874 sd = sc->sc_txd; 875 } else { 876 txd++; 877 sd++; 878 } 879 880 cnt--; 881 } 882 883 r->r_cons = cons; 884 r->r_cnt = cnt; 885 if (cnt == 0) 886 ifp->if_timer = 0; 887} 888 889static int 890txp_shutdown(dev) 891 device_t dev; 892{ 893 struct txp_softc *sc; 894 895 sc = device_get_softc(dev); 896 897 TXP_LOCK(sc); 898 899 /* mask all interrupts */ 900 WRITE_REG(sc, TXP_IMR, 901 TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT | 902 TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 | 903 TXP_INT_LATCH); 904 905 txp_command(sc, TXP_CMD_TX_DISABLE, 0, 0, 0, NULL, NULL, NULL, 0); 906 txp_command(sc, TXP_CMD_RX_DISABLE, 0, 0, 0, NULL, NULL, NULL, 0); 907 txp_command(sc, TXP_CMD_HALT, 0, 0, 0, NULL, NULL, NULL, 0); 908 TXP_UNLOCK(sc); 909 910 return(0); 911} 912 913static int 914txp_alloc_rings(sc) 915 struct txp_softc *sc; 916{ 917 struct txp_boot_record *boot; 918 struct txp_ldata *ld; 919 u_int32_t r; 920 int i; 921 922 r = 0; 923 ld = sc->sc_ldata; 924 boot = &ld->txp_boot; 925 926 /* boot record */ 927 sc->sc_boot = boot; 928 929 /* host variables */ 930 bzero(&ld->txp_hostvar, sizeof(struct txp_hostvar)); 931 boot->br_hostvar_lo = vtophys(&ld->txp_hostvar); 932 boot->br_hostvar_hi = 0; 933 sc->sc_hostvar = (struct txp_hostvar *)&ld->txp_hostvar; 934 935 /* hi priority tx ring */ 936 boot->br_txhipri_lo = vtophys(&ld->txp_txhiring);; 937 boot->br_txhipri_hi = 0; 938 boot->br_txhipri_siz = TX_ENTRIES * sizeof(struct txp_tx_desc); 939 sc->sc_txhir.r_reg = TXP_H2A_1; 940 sc->sc_txhir.r_desc = (struct txp_tx_desc *)&ld->txp_txhiring; 941 sc->sc_txhir.r_cons = sc->sc_txhir.r_prod = sc->sc_txhir.r_cnt = 0; 942 sc->sc_txhir.r_off = &sc->sc_hostvar->hv_tx_hi_desc_read_idx; 943 944 /* lo priority tx ring */ 945 boot->br_txlopri_lo = vtophys(&ld->txp_txloring); 946 boot->br_txlopri_hi = 0; 947 boot->br_txlopri_siz = TX_ENTRIES * sizeof(struct txp_tx_desc); 948 sc->sc_txlor.r_reg = TXP_H2A_3; 949 sc->sc_txlor.r_desc = (struct txp_tx_desc *)&ld->txp_txloring; 950 sc->sc_txlor.r_cons = sc->sc_txlor.r_prod = sc->sc_txlor.r_cnt = 0; 951 sc->sc_txlor.r_off = &sc->sc_hostvar->hv_tx_lo_desc_read_idx; 952 953 /* high priority rx ring */ 954 boot->br_rxhipri_lo = vtophys(&ld->txp_rxhiring); 955 boot->br_rxhipri_hi = 0; 956 boot->br_rxhipri_siz = RX_ENTRIES * sizeof(struct txp_rx_desc); 957 sc->sc_rxhir.r_desc = (struct txp_rx_desc *)&ld->txp_rxhiring; 958 sc->sc_rxhir.r_roff = &sc->sc_hostvar->hv_rx_hi_read_idx; 959 sc->sc_rxhir.r_woff = &sc->sc_hostvar->hv_rx_hi_write_idx; 960 961 /* low priority rx ring */ 962 boot->br_rxlopri_lo = vtophys(&ld->txp_rxloring); 963 boot->br_rxlopri_hi = 0; 964 boot->br_rxlopri_siz = RX_ENTRIES * sizeof(struct txp_rx_desc); 965 sc->sc_rxlor.r_desc = (struct txp_rx_desc *)&ld->txp_rxloring; 966 sc->sc_rxlor.r_roff = &sc->sc_hostvar->hv_rx_lo_read_idx; 967 sc->sc_rxlor.r_woff = &sc->sc_hostvar->hv_rx_lo_write_idx; 968 969 /* command ring */ 970 bzero(&ld->txp_cmdring, sizeof(struct txp_cmd_desc) * CMD_ENTRIES); 971 boot->br_cmd_lo = vtophys(&ld->txp_cmdring); 972 boot->br_cmd_hi = 0; 973 boot->br_cmd_siz = CMD_ENTRIES * sizeof(struct txp_cmd_desc); 974 sc->sc_cmdring.base = (struct txp_cmd_desc *)&ld->txp_cmdring; 975 sc->sc_cmdring.size = CMD_ENTRIES * sizeof(struct txp_cmd_desc); 976 sc->sc_cmdring.lastwrite = 0; 977 978 /* response ring */ 979 bzero(&ld->txp_rspring, sizeof(struct txp_rsp_desc) * RSP_ENTRIES); 980 boot->br_resp_lo = vtophys(&ld->txp_rspring); 981 boot->br_resp_hi = 0; 982 boot->br_resp_siz = CMD_ENTRIES * sizeof(struct txp_rsp_desc); 983 sc->sc_rspring.base = (struct txp_rsp_desc *)&ld->txp_rspring; 984 sc->sc_rspring.size = RSP_ENTRIES * sizeof(struct txp_rsp_desc); 985 sc->sc_rspring.lastwrite = 0; 986 987 /* receive buffer ring */ 988 boot->br_rxbuf_lo = vtophys(&ld->txp_rxbufs); 989 boot->br_rxbuf_hi = 0; 990 boot->br_rxbuf_siz = RXBUF_ENTRIES * sizeof(struct txp_rxbuf_desc); 991 sc->sc_rxbufs = (struct txp_rxbuf_desc *)&ld->txp_rxbufs; 992 993 for (i = 0; i < RXBUF_ENTRIES; i++) { 994 struct txp_swdesc *sd; 995 if (sc->sc_rxbufs[i].rb_sd != NULL) 996 continue; 997 sc->sc_rxbufs[i].rb_sd = malloc(sizeof(struct txp_swdesc), 998 M_DEVBUF, M_NOWAIT); 999 if (sc->sc_rxbufs[i].rb_sd == NULL) 1000 return(ENOBUFS); 1001 sd = sc->sc_rxbufs[i].rb_sd; 1002 sd->sd_mbuf = NULL; 1003 } 1004 sc->sc_rxbufprod = 0; 1005 1006 /* zero dma */ 1007 bzero(&ld->txp_zero, sizeof(u_int32_t)); 1008 boot->br_zero_lo = vtophys(&ld->txp_zero); 1009 boot->br_zero_hi = 0; 1010 1011 /* See if it's waiting for boot, and try to boot it */ 1012 for (i = 0; i < 10000; i++) { 1013 r = READ_REG(sc, TXP_A2H_0); 1014 if (r == STAT_WAITING_FOR_BOOT) 1015 break; 1016 DELAY(50); 1017 } 1018 1019 if (r != STAT_WAITING_FOR_BOOT) { 1020 device_printf(sc->sc_dev, "not waiting for boot\n"); 1021 return(ENXIO); 1022 } 1023 1024 WRITE_REG(sc, TXP_H2A_2, 0); 1025 WRITE_REG(sc, TXP_H2A_1, vtophys(sc->sc_boot)); 1026 WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_REGISTER_BOOT_RECORD); 1027 1028 /* See if it booted */ 1029 for (i = 0; i < 10000; i++) { 1030 r = READ_REG(sc, TXP_A2H_0); 1031 if (r == STAT_RUNNING) 1032 break; 1033 DELAY(50); 1034 } 1035 if (r != STAT_RUNNING) { 1036 device_printf(sc->sc_dev, "fw not running\n"); 1037 return(ENXIO); 1038 } 1039 1040 /* Clear TX and CMD ring write registers */ 1041 WRITE_REG(sc, TXP_H2A_1, TXP_BOOTCMD_NULL); 1042 WRITE_REG(sc, TXP_H2A_2, TXP_BOOTCMD_NULL); 1043 WRITE_REG(sc, TXP_H2A_3, TXP_BOOTCMD_NULL); 1044 WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_NULL); 1045 1046 return (0); 1047} 1048 1049static int 1050txp_ioctl(ifp, command, data) 1051 struct ifnet *ifp; 1052 u_long command; 1053 caddr_t data; 1054{ 1055 struct txp_softc *sc = ifp->if_softc; 1056 struct ifreq *ifr = (struct ifreq *)data; 1057 int error = 0; 1058 1059 switch(command) { 1060 case SIOCSIFFLAGS: 1061 TXP_LOCK(sc); 1062 if (ifp->if_flags & IFF_UP) { 1063 txp_init_locked(sc); 1064 } else { 1065 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 1066 txp_stop(sc); 1067 } 1068 TXP_UNLOCK(sc); 1069 break; 1070 case SIOCADDMULTI: 1071 case SIOCDELMULTI: 1072 /* 1073 * Multicast list has changed; set the hardware 1074 * filter accordingly. 1075 */ 1076 TXP_LOCK(sc); 1077 txp_set_filter(sc); 1078 TXP_UNLOCK(sc); 1079 error = 0; 1080 break; 1081 case SIOCGIFMEDIA: 1082 case SIOCSIFMEDIA: 1083 error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, command); 1084 break; 1085 default: 1086 error = ether_ioctl(ifp, command, data); 1087 break; 1088 } 1089 1090 return(error); 1091} 1092 1093static int 1094txp_rxring_fill(sc) 1095 struct txp_softc *sc; 1096{ 1097 int i; 1098 struct ifnet *ifp; 1099 struct txp_swdesc *sd; 1100 1101 TXP_LOCK_ASSERT(sc); 1102 ifp = sc->sc_ifp; 1103 1104 for (i = 0; i < RXBUF_ENTRIES; i++) { 1105 sd = sc->sc_rxbufs[i].rb_sd; 1106 sd->sd_mbuf = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 1107 if (sd->sd_mbuf == NULL) 1108 return(ENOBUFS); 1109 1110 sd->sd_mbuf->m_pkthdr.len = sd->sd_mbuf->m_len = MCLBYTES; 1111 sd->sd_mbuf->m_pkthdr.rcvif = ifp; 1112 1113 sc->sc_rxbufs[i].rb_paddrlo = 1114 vtophys(mtod(sd->sd_mbuf, vm_offset_t)); 1115 sc->sc_rxbufs[i].rb_paddrhi = 0; 1116 } 1117 1118 sc->sc_hostvar->hv_rx_buf_write_idx = (RXBUF_ENTRIES - 1) * 1119 sizeof(struct txp_rxbuf_desc); 1120 1121 return(0); 1122} 1123 1124static void 1125txp_rxring_empty(sc) 1126 struct txp_softc *sc; 1127{ 1128 int i; 1129 struct txp_swdesc *sd; 1130 1131 TXP_LOCK_ASSERT(sc); 1132 if (sc->sc_rxbufs == NULL) 1133 return; 1134 1135 for (i = 0; i < RXBUF_ENTRIES; i++) { 1136 if (&sc->sc_rxbufs[i] == NULL) 1137 continue; 1138 sd = sc->sc_rxbufs[i].rb_sd; 1139 if (sd == NULL) 1140 continue; 1141 if (sd->sd_mbuf != NULL) { 1142 m_freem(sd->sd_mbuf); 1143 sd->sd_mbuf = NULL; 1144 } 1145 } 1146 1147 return; 1148} 1149 1150static void 1151txp_init(xsc) 1152 void *xsc; 1153{ 1154 struct txp_softc *sc; 1155 1156 sc = xsc; 1157 TXP_LOCK(sc); 1158 txp_init_locked(sc); 1159 TXP_UNLOCK(sc); 1160} 1161 1162static void 1163txp_init_locked(sc) 1164 struct txp_softc *sc; 1165{ 1166 struct ifnet *ifp; 1167 u_int16_t p1; 1168 u_int32_t p2; 1169 1170 TXP_LOCK_ASSERT(sc); 1171 ifp = sc->sc_ifp; 1172 1173 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 1174 return; 1175 1176 txp_stop(sc); 1177 1178 txp_command(sc, TXP_CMD_MAX_PKT_SIZE_WRITE, TXP_MAX_PKTLEN, 0, 0, 1179 NULL, NULL, NULL, 1); 1180 1181 /* Set station address. */ 1182 ((u_int8_t *)&p1)[1] = IF_LLADDR(sc->sc_ifp)[0]; 1183 ((u_int8_t *)&p1)[0] = IF_LLADDR(sc->sc_ifp)[1]; 1184 ((u_int8_t *)&p2)[3] = IF_LLADDR(sc->sc_ifp)[2]; 1185 ((u_int8_t *)&p2)[2] = IF_LLADDR(sc->sc_ifp)[3]; 1186 ((u_int8_t *)&p2)[1] = IF_LLADDR(sc->sc_ifp)[4]; 1187 ((u_int8_t *)&p2)[0] = IF_LLADDR(sc->sc_ifp)[5]; 1188 txp_command(sc, TXP_CMD_STATION_ADDRESS_WRITE, p1, p2, 0, 1189 NULL, NULL, NULL, 1); 1190 1191 txp_set_filter(sc); 1192 1193 txp_rxring_fill(sc); 1194 1195 txp_command(sc, TXP_CMD_TX_ENABLE, 0, 0, 0, NULL, NULL, NULL, 1); 1196 txp_command(sc, TXP_CMD_RX_ENABLE, 0, 0, 0, NULL, NULL, NULL, 1); 1197 1198 WRITE_REG(sc, TXP_IER, TXP_INT_RESERVED | TXP_INT_SELF | 1199 TXP_INT_A2H_7 | TXP_INT_A2H_6 | TXP_INT_A2H_5 | TXP_INT_A2H_4 | 1200 TXP_INT_A2H_2 | TXP_INT_A2H_1 | TXP_INT_A2H_0 | 1201 TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 | 1202 TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT | TXP_INT_LATCH); 1203 WRITE_REG(sc, TXP_IMR, TXP_INT_A2H_3); 1204 1205 ifp->if_drv_flags |= IFF_DRV_RUNNING; 1206 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1207 ifp->if_timer = 0; 1208 1209 callout_reset(&sc->sc_tick, hz, txp_tick, sc); 1210} 1211 1212static void 1213txp_tick(vsc) 1214 void *vsc; 1215{ 1216 struct txp_softc *sc = vsc; 1217 struct ifnet *ifp = sc->sc_ifp; 1218 struct txp_rsp_desc *rsp = NULL; 1219 struct txp_ext_desc *ext; 1220 1221 TXP_LOCK_ASSERT(sc); 1222 txp_rxbuf_reclaim(sc); 1223 1224 if (txp_command2(sc, TXP_CMD_READ_STATISTICS, 0, 0, 0, NULL, 0, 1225 &rsp, 1)) 1226 goto out; 1227 if (rsp->rsp_numdesc != 6) 1228 goto out; 1229 if (txp_command(sc, TXP_CMD_CLEAR_STATISTICS, 0, 0, 0, 1230 NULL, NULL, NULL, 1)) 1231 goto out; 1232 ext = (struct txp_ext_desc *)(rsp + 1); 1233 1234 ifp->if_ierrors += ext[3].ext_2 + ext[3].ext_3 + ext[3].ext_4 + 1235 ext[4].ext_1 + ext[4].ext_4; 1236 ifp->if_oerrors += ext[0].ext_1 + ext[1].ext_1 + ext[1].ext_4 + 1237 ext[2].ext_1; 1238 ifp->if_collisions += ext[0].ext_2 + ext[0].ext_3 + ext[1].ext_2 + 1239 ext[1].ext_3; 1240 ifp->if_opackets += rsp->rsp_par2; 1241 ifp->if_ipackets += ext[2].ext_3; 1242 1243out: 1244 if (rsp != NULL) 1245 free(rsp, M_DEVBUF); 1246 1247 callout_reset(&sc->sc_tick, hz, txp_tick, sc); 1248 1249 return; 1250} 1251 1252static void 1253txp_start(ifp) 1254 struct ifnet *ifp; 1255{ 1256 struct txp_softc *sc; 1257 1258 sc = ifp->if_softc; 1259 TXP_LOCK(sc); 1260 txp_start_locked(ifp); 1261 TXP_UNLOCK(sc); 1262} 1263 1264static void 1265txp_start_locked(ifp) 1266 struct ifnet *ifp; 1267{ 1268 struct txp_softc *sc = ifp->if_softc; 1269 struct txp_tx_ring *r = &sc->sc_txhir; 1270 struct txp_tx_desc *txd; 1271 struct txp_frag_desc *fxd; 1272 struct mbuf *m, *m0; 1273 struct txp_swdesc *sd; 1274 u_int32_t firstprod, firstcnt, prod, cnt; 1275 struct m_tag *mtag; 1276 1277 TXP_LOCK_ASSERT(sc); 1278 if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != 1279 IFF_DRV_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_drv_flags |= IFF_DRV_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 TXP_LOCK_ASSERT(sc); 1582 ifp = sc->sc_ifp; 1583 1584 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 1585 1586 callout_stop(&sc->sc_tick); 1587 1588 txp_command(sc, TXP_CMD_TX_DISABLE, 0, 0, 0, NULL, NULL, NULL, 1); 1589 txp_command(sc, TXP_CMD_RX_DISABLE, 0, 0, 0, NULL, NULL, NULL, 1); 1590 1591 txp_rxring_empty(sc); 1592 1593 return; 1594} 1595 1596static void 1597txp_watchdog(ifp) 1598 struct ifnet *ifp; 1599{ 1600 return; 1601} 1602 1603static int 1604txp_ifmedia_upd(ifp) 1605 struct ifnet *ifp; 1606{ 1607 struct txp_softc *sc = ifp->if_softc; 1608 struct ifmedia *ifm = &sc->sc_ifmedia; 1609 u_int16_t new_xcvr; 1610 1611 TXP_LOCK(sc); 1612 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) { 1613 TXP_UNLOCK(sc); 1614 return (EINVAL); 1615 } 1616 1617 if (IFM_SUBTYPE(ifm->ifm_media) == IFM_10_T) { 1618 if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) 1619 new_xcvr = TXP_XCVR_10_FDX; 1620 else 1621 new_xcvr = TXP_XCVR_10_HDX; 1622 } else if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_TX) { 1623 if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) 1624 new_xcvr = TXP_XCVR_100_FDX; 1625 else 1626 new_xcvr = TXP_XCVR_100_HDX; 1627 } else if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO) { 1628 new_xcvr = TXP_XCVR_AUTO; 1629 } else { 1630 TXP_UNLOCK(sc); 1631 return (EINVAL); 1632 } 1633 1634 /* nothing to do */ 1635 if (sc->sc_xcvr == new_xcvr) { 1636 TXP_UNLOCK(sc); 1637 return (0); 1638 } 1639 1640 txp_command(sc, TXP_CMD_XCVR_SELECT, new_xcvr, 0, 0, 1641 NULL, NULL, NULL, 0); 1642 sc->sc_xcvr = new_xcvr; 1643 TXP_UNLOCK(sc); 1644 1645 return (0); 1646} 1647 1648static void 1649txp_ifmedia_sts(ifp, ifmr) 1650 struct ifnet *ifp; 1651 struct ifmediareq *ifmr; 1652{ 1653 struct txp_softc *sc = ifp->if_softc; 1654 struct ifmedia *ifm = &sc->sc_ifmedia; 1655 u_int16_t bmsr, bmcr, anlpar; 1656 1657 ifmr->ifm_status = IFM_AVALID; 1658 ifmr->ifm_active = IFM_ETHER; 1659 1660 TXP_LOCK(sc); 1661 if (txp_command(sc, TXP_CMD_PHY_MGMT_READ, 0, MII_BMSR, 0, 1662 &bmsr, NULL, NULL, 1)) 1663 goto bail; 1664 if (txp_command(sc, TXP_CMD_PHY_MGMT_READ, 0, MII_BMSR, 0, 1665 &bmsr, NULL, NULL, 1)) 1666 goto bail; 1667 1668 if (txp_command(sc, TXP_CMD_PHY_MGMT_READ, 0, MII_BMCR, 0, 1669 &bmcr, NULL, NULL, 1)) 1670 goto bail; 1671 1672 if (txp_command(sc, TXP_CMD_PHY_MGMT_READ, 0, MII_ANLPAR, 0, 1673 &anlpar, NULL, NULL, 1)) 1674 goto bail; 1675 TXP_UNLOCK(sc); 1676 1677 if (bmsr & BMSR_LINK) 1678 ifmr->ifm_status |= IFM_ACTIVE; 1679 1680 if (bmcr & BMCR_ISO) { 1681 ifmr->ifm_active |= IFM_NONE; 1682 ifmr->ifm_status = 0; 1683 return; 1684 } 1685 1686 if (bmcr & BMCR_LOOP) 1687 ifmr->ifm_active |= IFM_LOOP; 1688 1689 if (bmcr & BMCR_AUTOEN) { 1690 if ((bmsr & BMSR_ACOMP) == 0) { 1691 ifmr->ifm_active |= IFM_NONE; 1692 return; 1693 } 1694 1695 if (anlpar & ANLPAR_T4) 1696 ifmr->ifm_active |= IFM_100_T4; 1697 else if (anlpar & ANLPAR_TX_FD) 1698 ifmr->ifm_active |= IFM_100_TX|IFM_FDX; 1699 else if (anlpar & ANLPAR_TX) 1700 ifmr->ifm_active |= IFM_100_TX; 1701 else if (anlpar & ANLPAR_10_FD) 1702 ifmr->ifm_active |= IFM_10_T|IFM_FDX; 1703 else if (anlpar & ANLPAR_10) 1704 ifmr->ifm_active |= IFM_10_T; 1705 else 1706 ifmr->ifm_active |= IFM_NONE; 1707 } else 1708 ifmr->ifm_active = ifm->ifm_cur->ifm_media; 1709 return; 1710 1711bail: 1712 TXP_UNLOCK(sc); 1713 ifmr->ifm_active |= IFM_NONE; 1714 ifmr->ifm_status &= ~IFM_AVALID; 1715} 1716 1717#ifdef TXP_DEBUG 1718static void 1719txp_show_descriptor(d) 1720 void *d; 1721{ 1722 struct txp_cmd_desc *cmd = d; 1723 struct txp_rsp_desc *rsp = d; 1724 struct txp_tx_desc *txd = d; 1725 struct txp_frag_desc *frgd = d; 1726 1727 switch (cmd->cmd_flags & CMD_FLAGS_TYPE_M) { 1728 case CMD_FLAGS_TYPE_CMD: 1729 /* command descriptor */ 1730 printf("[cmd flags 0x%x num %d id %d seq %d par1 0x%x par2 0x%x par3 0x%x]\n", 1731 cmd->cmd_flags, cmd->cmd_numdesc, cmd->cmd_id, cmd->cmd_seq, 1732 cmd->cmd_par1, cmd->cmd_par2, cmd->cmd_par3); 1733 break; 1734 case CMD_FLAGS_TYPE_RESP: 1735 /* response descriptor */ 1736 printf("[rsp flags 0x%x num %d id %d seq %d par1 0x%x par2 0x%x par3 0x%x]\n", 1737 rsp->rsp_flags, rsp->rsp_numdesc, rsp->rsp_id, rsp->rsp_seq, 1738 rsp->rsp_par1, rsp->rsp_par2, rsp->rsp_par3); 1739 break; 1740 case CMD_FLAGS_TYPE_DATA: 1741 /* data header (assuming tx for now) */ 1742 printf("[data flags 0x%x num %d totlen %d addr 0x%x/0x%x pflags 0x%x]", 1743 txd->tx_flags, txd->tx_numdesc, txd->tx_totlen, 1744 txd->tx_addrlo, txd->tx_addrhi, txd->tx_pflags); 1745 break; 1746 case CMD_FLAGS_TYPE_FRAG: 1747 /* fragment descriptor */ 1748 printf("[frag flags 0x%x rsvd1 0x%x len %d addr 0x%x/0x%x rsvd2 0x%x]", 1749 frgd->frag_flags, frgd->frag_rsvd1, frgd->frag_len, 1750 frgd->frag_addrlo, frgd->frag_addrhi, frgd->frag_rsvd2); 1751 break; 1752 default: 1753 printf("[unknown(%x) flags 0x%x num %d id %d seq %d par1 0x%x par2 0x%x par3 0x%x]\n", 1754 cmd->cmd_flags & CMD_FLAGS_TYPE_M, 1755 cmd->cmd_flags, cmd->cmd_numdesc, cmd->cmd_id, cmd->cmd_seq, 1756 cmd->cmd_par1, cmd->cmd_par2, cmd->cmd_par3); 1757 break; 1758 } 1759} 1760#endif 1761 1762static void 1763txp_set_filter(sc) 1764 struct txp_softc *sc; 1765{ 1766 struct ifnet *ifp = sc->sc_ifp; 1767 u_int32_t crc, carry, hashbit, hash[2]; 1768 u_int16_t filter; 1769 u_int8_t octet; 1770 int i, j, mcnt = 0; 1771 struct ifmultiaddr *ifma; 1772 char *enm; 1773 1774 if (ifp->if_flags & IFF_PROMISC) { 1775 filter = TXP_RXFILT_PROMISC; 1776 goto setit; 1777 } 1778 1779 filter = TXP_RXFILT_DIRECT; 1780 1781 if (ifp->if_flags & IFF_BROADCAST) 1782 filter |= TXP_RXFILT_BROADCAST; 1783 1784 if (ifp->if_flags & IFF_ALLMULTI) 1785 filter |= TXP_RXFILT_ALLMULTI; 1786 else { 1787 hash[0] = hash[1] = 0; 1788 1789 IF_ADDR_LOCK(ifp); 1790 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1791 if (ifma->ifma_addr->sa_family != AF_LINK) 1792 continue; 1793 1794 enm = LLADDR((struct sockaddr_dl *)ifma->ifma_addr); 1795 mcnt++; 1796 crc = 0xffffffff; 1797 1798 for (i = 0; i < ETHER_ADDR_LEN; i++) { 1799 octet = enm[i]; 1800 for (j = 0; j < 8; j++) { 1801 carry = ((crc & 0x80000000) ? 1 : 0) ^ 1802 (octet & 1); 1803 crc <<= 1; 1804 octet >>= 1; 1805 if (carry) 1806 crc = (crc ^ TXP_POLYNOMIAL) | 1807 carry; 1808 } 1809 } 1810 hashbit = (u_int16_t)(crc & (64 - 1)); 1811 hash[hashbit / 32] |= (1 << hashbit % 32); 1812 } 1813 IF_ADDR_UNLOCK(ifp); 1814 1815 if (mcnt > 0) { 1816 filter |= TXP_RXFILT_HASHMULTI; 1817 txp_command(sc, TXP_CMD_MCAST_HASH_MASK_WRITE, 1818 2, hash[0], hash[1], NULL, NULL, NULL, 0); 1819 } 1820 } 1821 1822setit: 1823 1824 txp_command(sc, TXP_CMD_RX_FILTER_WRITE, filter, 0, 0, 1825 NULL, NULL, NULL, 1); 1826 1827 return; 1828} 1829 1830static void 1831txp_capabilities(sc) 1832 struct txp_softc *sc; 1833{ 1834 struct ifnet *ifp = sc->sc_ifp; 1835 struct txp_rsp_desc *rsp = NULL; 1836 struct txp_ext_desc *ext; 1837 1838 if (txp_command2(sc, TXP_CMD_OFFLOAD_READ, 0, 0, 0, NULL, 0, &rsp, 1)) 1839 goto out; 1840 1841 if (rsp->rsp_numdesc != 1) 1842 goto out; 1843 ext = (struct txp_ext_desc *)(rsp + 1); 1844 1845 sc->sc_tx_capability = ext->ext_1 & OFFLOAD_MASK; 1846 sc->sc_rx_capability = ext->ext_2 & OFFLOAD_MASK; 1847 ifp->if_capabilities = 0; 1848 1849 if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_VLAN) { 1850 sc->sc_tx_capability |= OFFLOAD_VLAN; 1851 sc->sc_rx_capability |= OFFLOAD_VLAN; 1852 ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; 1853 } 1854 1855#if 0 1856 /* not ready yet */ 1857 if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_IPSEC) { 1858 sc->sc_tx_capability |= OFFLOAD_IPSEC; 1859 sc->sc_rx_capability |= OFFLOAD_IPSEC; 1860 ifp->if_capabilities |= IFCAP_IPSEC; 1861 } 1862#endif 1863 1864 if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_IPCKSUM) { 1865 sc->sc_tx_capability |= OFFLOAD_IPCKSUM; 1866 sc->sc_rx_capability |= OFFLOAD_IPCKSUM; 1867 ifp->if_capabilities |= IFCAP_HWCSUM; 1868 ifp->if_hwassist |= CSUM_IP; 1869 } 1870 1871 if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_TCPCKSUM) { 1872#if 0 1873 sc->sc_tx_capability |= OFFLOAD_TCPCKSUM; 1874#endif 1875 sc->sc_rx_capability |= OFFLOAD_TCPCKSUM; 1876 ifp->if_capabilities |= IFCAP_HWCSUM; 1877 } 1878 1879 if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_UDPCKSUM) { 1880#if 0 1881 sc->sc_tx_capability |= OFFLOAD_UDPCKSUM; 1882#endif 1883 sc->sc_rx_capability |= OFFLOAD_UDPCKSUM; 1884 ifp->if_capabilities |= IFCAP_HWCSUM; 1885 } 1886 ifp->if_capenable = ifp->if_capabilities; 1887 1888 if (txp_command(sc, TXP_CMD_OFFLOAD_WRITE, 0, 1889 sc->sc_tx_capability, sc->sc_rx_capability, NULL, NULL, NULL, 1)) 1890 goto out; 1891 1892out: 1893 if (rsp != NULL) 1894 free(rsp, M_DEVBUF); 1895 1896 return; 1897} 1898