1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 28 /* 29 * dnet -- DEC 21x4x 30 * 31 * Currently supports: 32 * 21040, 21041, 21140, 21142, 21143 33 * SROM versions 1, 3, 3.03, 4 34 * TP, AUI, BNC, 100BASETX, 100BASET4 35 * 36 * XXX NEEDSWORK 37 * All media SHOULD work, FX is untested 38 * 39 * Depends on the Generic LAN Driver utility functions in /kernel/misc/gld 40 */ 41 42 #define BUG_4010796 /* See 4007871, 4010796 */ 43 44 #include <sys/types.h> 45 #include <sys/errno.h> 46 #include <sys/param.h> 47 #include <sys/stropts.h> 48 #include <sys/stream.h> 49 #include <sys/kmem.h> 50 #include <sys/conf.h> 51 #include <sys/devops.h> 52 #include <sys/ksynch.h> 53 #include <sys/stat.h> 54 #include <sys/modctl.h> 55 #include <sys/debug.h> 56 #include <sys/dlpi.h> 57 #include <sys/ethernet.h> 58 #include <sys/gld.h> 59 #include <sys/pci.h> 60 #include <sys/ddi.h> 61 #include <sys/sunddi.h> 62 63 #include "dnet_mii.h" 64 #include "dnet.h" 65 66 char _depends_on[] = "misc/gld"; 67 68 /* 69 * Declarations and Module Linkage 70 */ 71 72 #define IDENT "DNET 21x4x" 73 74 /* 75 * #define DNET_NOISY 76 * #define SROMDEBUG 77 * #define SROMDUMPSTRUCTURES 78 */ 79 80 #ifdef DNETDEBUG 81 #ifdef DNET_NOISY 82 int dnetdebug = -1; 83 #else 84 int dnetdebug = 0; 85 #endif 86 #endif 87 88 /* used for message allocated using desballoc() */ 89 struct free_ptr { 90 struct free_rtn free_rtn; 91 caddr_t buf; 92 }; 93 94 struct rbuf_list { 95 struct rbuf_list *rbuf_next; /* next in the list */ 96 caddr_t rbuf_vaddr; /* virual addr of the buf */ 97 uint32_t rbuf_paddr; /* physical addr of the buf */ 98 uint32_t rbuf_endpaddr; /* physical addr at the end */ 99 ddi_dma_handle_t rbuf_dmahdl; /* dma handle */ 100 ddi_acc_handle_t rbuf_acchdl; /* handle for DDI functions */ 101 }; 102 103 /* Required system entry points */ 104 static int dnetdevinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 105 static int dnetprobe(dev_info_t *); 106 static int dnetattach(dev_info_t *, ddi_attach_cmd_t); 107 static int dnetdetach(dev_info_t *, ddi_detach_cmd_t); 108 109 /* Required driver entry points for GLD */ 110 static int dnet_reset(gld_mac_info_t *); 111 static int dnet_start_board(gld_mac_info_t *); 112 static int dnet_stop_board(gld_mac_info_t *); 113 static int dnet_set_mac_addr(gld_mac_info_t *, uchar_t *); 114 static int dnet_set_multicast(gld_mac_info_t *, uchar_t *, int); 115 static int dnet_set_promiscuous(gld_mac_info_t *, int); 116 static int dnet_get_stats(gld_mac_info_t *, struct gld_stats *); 117 static int dnet_send(gld_mac_info_t *, mblk_t *); 118 static uint_t dnetintr(gld_mac_info_t *); 119 120 /* Internal functions used by the above entry points */ 121 static void write_gpr(struct dnetinstance *dnetp, uint32_t val); 122 static void dnet_reset_board(gld_mac_info_t *); 123 static void dnet_init_board(gld_mac_info_t *); 124 static void dnet_chip_init(gld_mac_info_t *); 125 static unsigned int hashindex(uchar_t *); 126 static int dnet_start(gld_mac_info_t *); 127 static int dnet_set_addr(gld_mac_info_t *); 128 129 static void dnet_getp(gld_mac_info_t *); 130 static void update_rx_stats(gld_mac_info_t *, int); 131 static void update_tx_stats(gld_mac_info_t *, int); 132 133 /* Media Selection Setup Routines */ 134 static void set_gpr(gld_mac_info_t *macinfo); 135 static void set_opr(gld_mac_info_t *macinfo); 136 static void set_sia(gld_mac_info_t *macinfo); 137 138 /* Buffer Management Routines */ 139 static int dnet_alloc_bufs(gld_mac_info_t *); 140 static void dnet_free_bufs(gld_mac_info_t *); 141 static void dnet_init_txrx_bufs(gld_mac_info_t *); 142 static int alloc_descriptor(gld_mac_info_t *); 143 static void dnet_reclaim_Tx_desc(gld_mac_info_t *); 144 static int dnet_rbuf_init(dev_info_t *, int); 145 static int dnet_rbuf_destroy(); 146 static struct rbuf_list *dnet_rbuf_alloc(dev_info_t *, int); 147 static void dnet_rbuf_free(caddr_t); 148 static void dnet_freemsg_buf(struct free_ptr *); 149 150 static void setup_block(gld_mac_info_t *macinfo); 151 152 /* SROM read functions */ 153 static int dnet_read_srom(dev_info_t *, int, ddi_acc_handle_t, caddr_t, 154 uchar_t *, int); 155 static void dnet_read21040addr(dev_info_t *, ddi_acc_handle_t, caddr_t, 156 uchar_t *, int *); 157 static void dnet_read21140srom(ddi_acc_handle_t, caddr_t, uchar_t *, int); 158 static int get_alternative_srom_image(dev_info_t *, uchar_t *, int); 159 static void dnet_print_srom(SROM_FORMAT *sr); 160 static void dnet_dump_leaf(LEAF_FORMAT *leaf); 161 static void dnet_dump_block(media_block_t *block); 162 #ifdef BUG_4010796 163 static void set_alternative_srom_image(dev_info_t *, uchar_t *, int); 164 static int dnethack(dev_info_t *); 165 #endif 166 167 static int dnet_hack_interrupts(gld_mac_info_t *, int); 168 static int dnet_detach_hacked_interrupt(dev_info_t *devinfo); 169 static void enable_interrupts(struct dnetinstance *dnetp, int enable_xmit); 170 171 /* SROM parsing functions */ 172 static void dnet_parse_srom(struct dnetinstance *dnetp, SROM_FORMAT *sr, 173 uchar_t *vi); 174 static void parse_controller_leaf(struct dnetinstance *dnetp, LEAF_FORMAT *leaf, 175 uchar_t *vi); 176 static uchar_t *parse_media_block(struct dnetinstance *dnetp, 177 media_block_t *block, uchar_t *vi); 178 static int check_srom_valid(uchar_t *); 179 static void dnet_dumpbin(char *msg, uchar_t *, int size, int len); 180 static void setup_legacy_blocks(); 181 /* Active Media Determination Routines */ 182 static void find_active_media(gld_mac_info_t *); 183 static int send_test_packet(gld_mac_info_t *); 184 static int dnet_link_sense(gld_mac_info_t *macinfo); 185 186 /* PHY MII Routines */ 187 static ushort_t dnet_mii_read(dev_info_t *dip, int phy_addr, int reg_num); 188 static void dnet_mii_write(dev_info_t *dip, int phy_addr, int reg_num, 189 int reg_dat); 190 static void write_mii(struct dnetinstance *, uint32_t, int); 191 static void mii_tristate(struct dnetinstance *); 192 static void do_phy(gld_mac_info_t *); 193 static void dnet_mii_link_cb(dev_info_t *, int, enum mii_phy_state); 194 static void set_leaf(SROM_FORMAT *sr, LEAF_FORMAT *leaf); 195 196 #ifdef DNETDEBUG 197 uint32_t dnet_usecelapsed(struct dnetinstance *dnetp); 198 void dnet_timestamp(struct dnetinstance *, char *); 199 void dnet_usectimeout(struct dnetinstance *, uint32_t, int, timercb_t); 200 #endif 201 static char *media_str[] = { 202 "10BaseT", 203 "10Base2", 204 "10Base5", 205 "100BaseTX", 206 "10BaseT FD", 207 "100BaseTX FD", 208 "100BaseT4", 209 "100BaseFX", 210 "100BaseFX FD", 211 "MII" 212 }; 213 214 /* default SROM info for cards with no SROMs */ 215 static LEAF_FORMAT leaf_default_100; 216 static LEAF_FORMAT leaf_asante; 217 static LEAF_FORMAT leaf_phylegacy; 218 static LEAF_FORMAT leaf_cogent_100; 219 static LEAF_FORMAT leaf_21041; 220 static LEAF_FORMAT leaf_21040; 221 222 int rx_buf_size = (ETHERMAX + ETHERFCSL + 3) & ~3; /* roundup to 4 */ 223 224 int max_rx_desc_21040 = MAX_RX_DESC_21040; 225 int max_rx_desc_21140 = MAX_RX_DESC_21140; 226 int max_tx_desc = MAX_TX_DESC; 227 int dnet_xmit_threshold = MAX_TX_DESC >> 2; /* XXX need tuning? */ 228 229 static kmutex_t dnet_rbuf_lock; /* mutex to protect rbuf_list data */ 230 231 /* used for buffers allocated by ddi_dma_mem_alloc() */ 232 static ddi_dma_attr_t dma_attr = { 233 DMA_ATTR_V0, /* dma_attr version */ 234 0, /* dma_attr_addr_lo */ 235 (uint64_t)0xFFFFFFFF, /* dma_attr_addr_hi */ 236 0x7FFFFFFF, /* dma_attr_count_max */ 237 4, /* dma_attr_align */ 238 0x3F, /* dma_attr_burstsizes */ 239 1, /* dma_attr_minxfer */ 240 (uint64_t)0xFFFFFFFF, /* dma_attr_maxxfer */ 241 (uint64_t)0xFFFFFFFF, /* dma_attr_seg */ 242 1, /* dma_attr_sgllen */ 243 1, /* dma_attr_granular */ 244 0, /* dma_attr_flags */ 245 }; 246 247 /* used for buffers allocated for rbuf, allow 2 cookies */ 248 static ddi_dma_attr_t dma_attr_rb = { 249 DMA_ATTR_V0, /* dma_attr version */ 250 0, /* dma_attr_addr_lo */ 251 (uint64_t)0xFFFFFFFF, /* dma_attr_addr_hi */ 252 0x7FFFFFFF, /* dma_attr_count_max */ 253 4, /* dma_attr_align */ 254 0x3F, /* dma_attr_burstsizes */ 255 1, /* dma_attr_minxfer */ 256 (uint64_t)0xFFFFFFFF, /* dma_attr_maxxfer */ 257 (uint64_t)0xFFFFFFFF, /* dma_attr_seg */ 258 2, /* dma_attr_sgllen */ 259 1, /* dma_attr_granular */ 260 0, /* dma_attr_flags */ 261 }; 262 /* used for buffers which are NOT from ddi_dma_mem_alloc() - xmit side */ 263 static ddi_dma_attr_t dma_attr_tx = { 264 DMA_ATTR_V0, /* dma_attr version */ 265 0, /* dma_attr_addr_lo */ 266 (uint64_t)0xFFFFFFFF, /* dma_attr_addr_hi */ 267 0x7FFFFFFF, /* dma_attr_count_max */ 268 1, /* dma_attr_align */ 269 0x3F, /* dma_attr_burstsizes */ 270 1, /* dma_attr_minxfer */ 271 (uint64_t)0xFFFFFFFF, /* dma_attr_maxxfer */ 272 (uint64_t)0xFFFFFFFF, /* dma_attr_seg */ 273 0x7FFF, /* dma_attr_sgllen */ 274 1, /* dma_attr_granular */ 275 0, /* dma_attr_flags */ 276 }; 277 278 static ddi_device_acc_attr_t accattr = { 279 DDI_DEVICE_ATTR_V0, 280 DDI_NEVERSWAP_ACC, 281 DDI_STRICTORDER_ACC, 282 }; 283 284 uchar_t dnet_broadcastaddr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 285 286 /* Standard Streams initialization */ 287 static struct module_info minfo = { 288 DNETIDNUM, "dnet", 0, INFPSZ, DNETHIWAT, DNETLOWAT 289 }; 290 291 static struct qinit rinit = { /* read queues */ 292 NULL, gld_rsrv, gld_open, gld_close, NULL, &minfo, NULL 293 }; 294 295 static struct qinit winit = { /* write queues */ 296 gld_wput, gld_wsrv, NULL, NULL, NULL, &minfo, NULL 297 }; 298 299 static struct streamtab dnetinfo = {&rinit, &winit, NULL, NULL}; 300 301 /* Standard Module linkage initialization for a Streams driver */ 302 extern struct mod_ops mod_driverops; 303 304 static struct cb_ops cb_dnetops = { 305 nulldev, /* cb_open */ 306 nulldev, /* cb_close */ 307 nodev, /* cb_strategy */ 308 nodev, /* cb_print */ 309 nodev, /* cb_dump */ 310 nodev, /* cb_read */ 311 nodev, /* cb_write */ 312 nodev, /* cb_ioctl */ 313 nodev, /* cb_devmap */ 314 nodev, /* cb_mmap */ 315 nodev, /* cb_segmap */ 316 nochpoll, /* cb_chpoll */ 317 ddi_prop_op, /* cb_prop_op */ 318 &dnetinfo, /* cb_stream */ 319 (int)(D_MP | D_HOTPLUG) /* cb_flag */ 320 }; 321 322 static struct dev_ops dnetops = { 323 DEVO_REV, /* devo_rev */ 324 0, /* devo_refcnt */ 325 gld_getinfo, /* devo_getinfo */ 326 nulldev, /* devo_identify */ 327 dnetprobe, /* devo_probe */ 328 dnetattach, /* devo_attach */ 329 dnetdetach, /* devo_detach */ 330 nodev, /* devo_reset */ 331 &cb_dnetops, /* devo_cb_ops */ 332 (struct bus_ops *)NULL, /* devo_bus_ops */ 333 NULL, /* devo_power */ 334 ddi_quiesce_not_supported, /* devo_quiesce */ 335 }; 336 337 static struct modldrv modldrv = { 338 &mod_driverops, /* Type of module. This one is a driver */ 339 IDENT, /* short description */ 340 &dnetops /* driver specific ops */ 341 }; 342 343 static struct modlinkage modlinkage = { 344 MODREV_1, (void *)&modldrv, NULL 345 }; 346 347 348 /* 349 * Passed to the hacked interrupt for multiport Cogent and ZNYX cards with 350 * dodgy interrupt routing 351 */ 352 #define MAX_INST 8 /* Maximum instances on a multiport adapter. */ 353 struct hackintr_inf 354 { 355 gld_mac_info_t *macinfos[MAX_INST]; /* macinfos for each port */ 356 dev_info_t *devinfo; /* Devinfo of the primary device */ 357 kmutex_t lock; 358 /* Ensures the interrupt doesn't get called while detaching */ 359 }; 360 static char hackintr_propname[] = "InterruptData"; 361 static char macoffset_propname[] = "MAC_offset"; 362 static char speed_propname[] = "speed"; 363 static char ofloprob_propname[] = "dmaworkaround"; 364 static char duplex_propname[] = "full-duplex"; /* Must agree with MII */ 365 static char printsrom_propname[] = "print-srom"; 366 367 static uint_t dnet_hack_intr(struct hackintr_inf *); 368 369 /* 370 * ========== Module Loading Entry Points ========== 371 */ 372 373 int 374 _init(void) 375 { 376 int i; 377 378 /* Configure fake sroms for legacy cards */ 379 mutex_init(&dnet_rbuf_lock, NULL, MUTEX_DRIVER, NULL); 380 setup_legacy_blocks(); 381 if ((i = mod_install(&modlinkage)) != 0) { 382 mutex_destroy(&dnet_rbuf_lock); 383 } 384 return (i); 385 } 386 387 int 388 _fini(void) 389 { 390 int i; 391 if ((i = mod_remove(&modlinkage)) == 0) { /* module can be unloaded */ 392 /* loop until all the receive buffers are freed */ 393 while (dnet_rbuf_destroy() != 0) { 394 delay(drv_usectohz(100000)); 395 #ifdef DNETDEBUG 396 if (dnetdebug & DNETDDI) 397 cmn_err(CE_WARN, "dnet _fini delay"); 398 #endif 399 } 400 mutex_destroy(&dnet_rbuf_lock); 401 } 402 return (i); 403 } 404 405 int 406 _info(struct modinfo *modinfop) 407 { 408 return (mod_info(&modlinkage, modinfop)); 409 } 410 411 /* 412 * ========== DDI Entry Points ========== 413 */ 414 415 /* 416 * probe(9E) -- Determine if a device is present 417 */ 418 static int 419 dnetprobe(dev_info_t *devinfo) 420 { 421 ddi_acc_handle_t handle; 422 uint16_t vendorid; 423 uint16_t deviceid; 424 425 #ifdef DNETDEBUG 426 if (dnetdebug & DNETDDI) 427 cmn_err(CE_NOTE, "dnetprobe(0x%p)", (void *) devinfo); 428 #endif 429 430 if (pci_config_setup(devinfo, &handle) != DDI_SUCCESS) 431 return (DDI_PROBE_FAILURE); 432 433 vendorid = pci_config_get16(handle, PCI_CONF_VENID); 434 435 if (vendorid != DEC_VENDOR_ID) { 436 pci_config_teardown(&handle); 437 return (DDI_PROBE_FAILURE); 438 } 439 440 deviceid = pci_config_get16(handle, PCI_CONF_DEVID); 441 switch (deviceid) { 442 case DEVICE_ID_21040: 443 case DEVICE_ID_21041: 444 case DEVICE_ID_21140: 445 case DEVICE_ID_21143: /* And 142 */ 446 break; 447 default: 448 pci_config_teardown(&handle); 449 return (DDI_PROBE_FAILURE); 450 } 451 452 pci_config_teardown(&handle); 453 #ifndef BUG_4010796 454 return (DDI_PROBE_SUCCESS); 455 #else 456 return (dnethack(devinfo)); 457 #endif 458 } 459 460 #ifdef BUG_4010796 461 /* 462 * If we have a device, but we cannot presently access its SROM data, 463 * then we return DDI_PROBE_PARTIAL and hope that sometime later we 464 * will be able to get at the SROM data. This can only happen if we 465 * are a secondary port with no SROM, and the bootstrap failed to set 466 * our DNET_SROM property, and our primary sibling has not yet probed. 467 */ 468 static int 469 dnethack(dev_info_t *devinfo) 470 { 471 uchar_t vendor_info[SROM_SIZE]; 472 uint32_t csr; 473 uint16_t deviceid; 474 ddi_acc_handle_t handle; 475 uint32_t retval; 476 int secondary; 477 ddi_acc_handle_t io_handle; 478 caddr_t io_reg; 479 480 #define DNET_PCI_RNUMBER 1 481 482 #ifdef DNETDEBUG 483 if (dnetdebug & DNETDDI) 484 cmn_err(CE_NOTE, "dnethack(0x%p)", (void *) devinfo); 485 #endif 486 487 if (pci_config_setup(devinfo, &handle) != DDI_SUCCESS) 488 return (DDI_PROBE_FAILURE); 489 490 deviceid = pci_config_get16(handle, PCI_CONF_DEVID); 491 492 /* 493 * Turn on Master Enable and IO Enable bits. 494 */ 495 csr = pci_config_get32(handle, PCI_CONF_COMM); 496 pci_config_put32(handle, PCI_CONF_COMM, (csr |PCI_COMM_ME|PCI_COMM_IO)); 497 498 pci_config_teardown(&handle); 499 500 /* Now map I/O register */ 501 if (ddi_regs_map_setup(devinfo, DNET_PCI_RNUMBER, 502 &io_reg, 0, 0, &accattr, &io_handle) != DDI_SUCCESS) { 503 return (DDI_PROBE_FAILURE); 504 } 505 506 /* 507 * Reset the chip 508 */ 509 ddi_put32(io_handle, REG32(io_reg, BUS_MODE_REG), SW_RESET); 510 drv_usecwait(3); 511 ddi_put32(io_handle, REG32(io_reg, BUS_MODE_REG), 0); 512 drv_usecwait(8); 513 514 secondary = dnet_read_srom(devinfo, deviceid, io_handle, 515 io_reg, vendor_info, sizeof (vendor_info)); 516 517 switch (secondary) { 518 case -1: 519 /* We can't access our SROM data! */ 520 retval = DDI_PROBE_PARTIAL; 521 break; 522 case 0: 523 retval = DDI_PROBE_SUCCESS; 524 break; 525 default: 526 retval = DDI_PROBE_SUCCESS; 527 } 528 529 ddi_regs_map_free(&io_handle); 530 return (retval); 531 } 532 #endif /* BUG_4010796 */ 533 534 /* 535 * attach(9E) -- Attach a device to the system 536 * 537 * Called once for each board successfully probed. 538 */ 539 static int 540 dnetattach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) 541 { 542 uint16_t revid; 543 struct dnetinstance *dnetp; /* Our private device info */ 544 gld_mac_info_t *macinfo; /* GLD structure */ 545 uchar_t vendor_info[SROM_SIZE]; 546 uint32_t csr; 547 uint16_t deviceid; 548 ddi_acc_handle_t handle; 549 int secondary; 550 551 #define DNET_PCI_RNUMBER 1 552 553 #ifdef DNETDEBUG 554 if (dnetdebug & DNETDDI) 555 cmn_err(CE_NOTE, "dnetattach(0x%p)", (void *) devinfo); 556 #endif 557 558 switch (cmd) { 559 case DDI_ATTACH: 560 break; 561 562 case DDI_RESUME: 563 564 /* Get the driver private (gld_mac_info_t) structure */ 565 macinfo = ddi_get_driver_private(devinfo); 566 dnetp = (struct dnetinstance *)(macinfo->gldm_private); 567 568 mutex_enter(&dnetp->intrlock); 569 mutex_enter(&dnetp->txlock); 570 dnet_reset_board(macinfo); 571 dnet_init_board(macinfo); 572 dnetp->suspended = B_FALSE; 573 574 if (dnetp->running) { 575 dnetp->need_gld_sched = 0; 576 mutex_exit(&dnetp->txlock); 577 (void) dnet_start(macinfo); 578 mutex_exit(&dnetp->intrlock); 579 gld_sched(macinfo); 580 } else { 581 mutex_exit(&dnetp->txlock); 582 mutex_exit(&dnetp->intrlock); 583 } 584 return (DDI_SUCCESS); 585 default: 586 return (DDI_FAILURE); 587 } 588 if (pci_config_setup(devinfo, &handle) != DDI_SUCCESS) 589 return (DDI_FAILURE); 590 591 deviceid = pci_config_get16(handle, PCI_CONF_DEVID); 592 switch (deviceid) { 593 case DEVICE_ID_21040: 594 case DEVICE_ID_21041: 595 case DEVICE_ID_21140: 596 case DEVICE_ID_21143: /* And 142 */ 597 break; 598 default: 599 pci_config_teardown(&handle); 600 return (DDI_FAILURE); 601 } 602 603 /* 604 * Turn on Master Enable and IO Enable bits. 605 */ 606 csr = pci_config_get32(handle, PCI_CONF_COMM); 607 pci_config_put32(handle, PCI_CONF_COMM, (csr |PCI_COMM_ME|PCI_COMM_IO)); 608 609 /* Make sure the device is not asleep */ 610 csr = pci_config_get32(handle, PCI_DNET_CONF_CFDD); 611 pci_config_put32(handle, PCI_DNET_CONF_CFDD, 612 csr & ~(CFDD_SLEEP|CFDD_SNOOZE)); 613 614 revid = pci_config_get8(handle, PCI_CONF_REVID); 615 pci_config_teardown(&handle); 616 617 /* 618 * Allocate gld_mac_info_t and dnetinstance structures 619 */ 620 if ((macinfo = gld_mac_alloc(devinfo)) == NULL) 621 return (DDI_FAILURE); 622 623 if ((dnetp = (struct dnetinstance *) 624 kmem_zalloc(sizeof (struct dnetinstance), KM_SLEEP)) == NULL) { 625 gld_mac_free(macinfo); 626 return (DDI_FAILURE); 627 } 628 629 /* Now map I/O register */ 630 if (ddi_regs_map_setup(devinfo, DNET_PCI_RNUMBER, &dnetp->io_reg, 631 0, 0, &accattr, &dnetp->io_handle) != DDI_SUCCESS) { 632 kmem_free(dnetp, sizeof (struct dnetinstance)); 633 gld_mac_free(macinfo); 634 return (DDI_FAILURE); 635 } 636 637 dnetp->devinfo = devinfo; 638 dnetp->board_type = deviceid; 639 640 /* 641 * Initialize our private fields in macinfo and dnetinstance 642 */ 643 macinfo->gldm_private = (caddr_t)dnetp; 644 645 /* 646 * Initialize pointers to device specific functions which will be 647 * used by the generic layer. 648 */ 649 macinfo->gldm_reset = dnet_reset; 650 macinfo->gldm_start = dnet_start_board; 651 macinfo->gldm_stop = dnet_stop_board; 652 macinfo->gldm_set_mac_addr = dnet_set_mac_addr; 653 macinfo->gldm_set_multicast = dnet_set_multicast; 654 macinfo->gldm_set_promiscuous = dnet_set_promiscuous; 655 macinfo->gldm_get_stats = dnet_get_stats; 656 macinfo->gldm_send = dnet_send; 657 macinfo->gldm_intr = dnetintr; 658 macinfo->gldm_ioctl = NULL; 659 660 /* 661 * Initialize board characteristics needed by the generic layer. 662 */ 663 macinfo->gldm_ident = IDENT; 664 macinfo->gldm_type = DL_ETHER; 665 macinfo->gldm_minpkt = 0; /* assumes we pad ourselves */ 666 macinfo->gldm_maxpkt = DNETMAXPKT; 667 macinfo->gldm_addrlen = ETHERADDRL; 668 macinfo->gldm_saplen = -2; 669 670 /* Other required initialization */ 671 macinfo->gldm_ppa = ddi_get_instance(devinfo); 672 macinfo->gldm_vendor_addr = dnetp->vendor_addr; 673 macinfo->gldm_broadcast_addr = dnet_broadcastaddr; 674 macinfo->gldm_devinfo = devinfo; 675 676 677 /* 678 * Get the iblock cookie with which to initialize the mutexes. 679 */ 680 if (ddi_get_iblock_cookie(devinfo, 0, &macinfo->gldm_cookie) 681 != DDI_SUCCESS) 682 goto fail; 683 684 /* 685 * Initialize mutex's for this device. 686 * Do this before registering the interrupt handler to avoid 687 * condition where interrupt handler can try using uninitialized 688 * mutex. 689 * Lock ordering rules: always lock intrlock first before 690 * txlock if both are required. 691 */ 692 mutex_init(&dnetp->txlock, 693 NULL, MUTEX_DRIVER, macinfo->gldm_cookie); 694 mutex_init(&dnetp->intrlock, 695 NULL, MUTEX_DRIVER, macinfo->gldm_cookie); 696 697 /* 698 * Get the BNC/TP indicator from the conf file for 21040 699 */ 700 dnetp->bnc_indicator = 701 ddi_getprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS, 702 "bncaui", -1); 703 704 /* 705 * For 21140 check the data rate set in the conf file. Default is 706 * 100Mb/s. Disallow connections at settings that would conflict 707 * with what's in the conf file 708 */ 709 dnetp->speed = 710 ddi_getprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS, 711 speed_propname, 0); 712 dnetp->full_duplex = 713 ddi_getprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS, 714 duplex_propname, -1); 715 716 if (dnetp->speed == 100) { 717 dnetp->disallowed_media |= (1UL<<MEDIA_TP) | (1UL<<MEDIA_TP_FD); 718 } else if (dnetp->speed == 10) { 719 dnetp->disallowed_media |= 720 (1UL<<MEDIA_SYM_SCR) | (1UL<<MEDIA_SYM_SCR_FD); 721 } 722 723 if (dnetp->full_duplex == 1) { 724 dnetp->disallowed_media |= 725 (1UL<<MEDIA_TP) | (1UL<<MEDIA_SYM_SCR); 726 } else if (dnetp->full_duplex == 0) { 727 dnetp->disallowed_media |= 728 (1UL<<MEDIA_TP_FD) | (1UL<<MEDIA_SYM_SCR_FD); 729 } 730 731 if (dnetp->bnc_indicator == 0) /* Disable BNC and AUI media */ 732 dnetp->disallowed_media |= (1UL<<MEDIA_BNC) | (1UL<<MEDIA_AUI); 733 else if (dnetp->bnc_indicator == 1) /* Force BNC only */ 734 dnetp->disallowed_media = (uint32_t)~(1U<<MEDIA_BNC); 735 else if (dnetp->bnc_indicator == 2) /* Force AUI only */ 736 dnetp->disallowed_media = (uint32_t)~(1U<<MEDIA_AUI); 737 738 dnet_reset_board(macinfo); 739 740 secondary = dnet_read_srom(devinfo, dnetp->board_type, dnetp->io_handle, 741 dnetp->io_reg, vendor_info, sizeof (vendor_info)); 742 743 if (secondary == -1) /* ASSERT (vendor_info not big enough) */ 744 goto fail1; 745 746 dnet_parse_srom(dnetp, &dnetp->sr, vendor_info); 747 748 if (ddi_getprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS, 749 printsrom_propname, 0)) 750 dnet_print_srom(&dnetp->sr); 751 752 dnetp->sr.netaddr[ETHERADDRL-1] += secondary; /* unique ether addr */ 753 754 BCOPY((caddr_t)dnetp->sr.netaddr, 755 (caddr_t)dnetp->vendor_addr, ETHERADDRL); 756 757 BCOPY((caddr_t)dnetp->sr.netaddr, 758 (caddr_t)dnetp->curr_macaddr, ETHERADDRL); 759 760 761 /* 762 * determine whether to implement workaround from DEC 763 * for DMA overrun errata. 764 */ 765 dnetp->overrun_workaround = 766 ((dnetp->board_type == DEVICE_ID_21140 && revid >= 0x20) || 767 (dnetp->board_type == DEVICE_ID_21143 && revid <= 0x30)) ? 1 : 0; 768 769 dnetp->overrun_workaround = 770 ddi_getprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS, 771 ofloprob_propname, dnetp->overrun_workaround); 772 773 /* 774 * Add the interrupt handler if dnet_hack_interrupts() returns 0. 775 * Otherwise dnet_hack_interrupts() itself adds the handler. 776 */ 777 if (!dnet_hack_interrupts(macinfo, secondary)) { 778 (void) ddi_add_intr(devinfo, 0, NULL, 779 NULL, gld_intr, (caddr_t)macinfo); 780 } 781 782 dnetp->max_tx_desc = max_tx_desc; 783 dnetp->max_rx_desc = max_rx_desc_21040; 784 if (dnetp->board_type != DEVICE_ID_21040 && 785 dnetp->board_type != DEVICE_ID_21041 && 786 dnetp->speed != 10) 787 dnetp->max_rx_desc = max_rx_desc_21140; 788 789 /* Allocate the TX and RX descriptors/buffers. */ 790 if (dnet_alloc_bufs(macinfo) == FAILURE) { 791 cmn_err(CE_WARN, "DNET: Not enough DMA memory for buffers."); 792 goto fail2; 793 } 794 795 /* 796 * Register ourselves with the GLD interface 797 * 798 * gld_register will: 799 * link us with the GLD system; 800 * set our ddi_set_driver_private(9F) data to the macinfo pointer; 801 * save the devinfo pointer in macinfo->gldm_devinfo; 802 * map the registers, putting the kvaddr into macinfo->gldm_memp; 803 * add the interrupt, putting the cookie in gldm_cookie; 804 * init the gldm_intrlock mutex which will block that interrupt; 805 * create the minor node. 806 */ 807 808 if (gld_register(devinfo, "dnet", macinfo) == DDI_SUCCESS) { 809 mutex_enter(&dnetp->intrlock); 810 dnetp->phyaddr = -1; 811 if (dnetp->board_type == DEVICE_ID_21140 || 812 dnetp->board_type == DEVICE_ID_21143) 813 do_phy(macinfo); /* Initialize the PHY, if any */ 814 find_active_media(macinfo); 815 816 /* if the chosen media is non-MII, stop the port monitor */ 817 if (dnetp->selected_media_block->media_code != MEDIA_MII && 818 dnetp->mii != NULL) { 819 mii_destroy(dnetp->mii); 820 dnetp->mii = NULL; 821 dnetp->phyaddr = -1; 822 } 823 824 #ifdef DNETDEBUG 825 if (dnetdebug & DNETSENSE) 826 cmn_err(CE_NOTE, "dnet: link configured : %s", 827 media_str[dnetp->selected_media_block->media_code]); 828 #endif 829 bzero(dnetp->setup_buf_vaddr, SETUPBUF_SIZE); 830 dnet_reset_board(macinfo); 831 dnet_init_board(macinfo); 832 /* XXX function return value ignored */ 833 mutex_exit(&dnetp->intrlock); 834 /* dropped intrlock as dnet_stop_board() grabs intrlock */ 835 (void) dnet_stop_board(macinfo); 836 return (DDI_SUCCESS); 837 } 838 fail2: 839 /* XXX function return value ignored */ 840 /* 841 * dnet_detach_hacked_interrupt() will remove 842 * interrupt for the non-hacked case also. 843 */ 844 (void) dnet_detach_hacked_interrupt(devinfo); 845 dnet_free_bufs(macinfo); 846 fail1: 847 mutex_destroy(&dnetp->txlock); 848 mutex_destroy(&dnetp->intrlock); 849 fail: 850 ddi_regs_map_free(&dnetp->io_handle); 851 kmem_free(dnetp, sizeof (struct dnetinstance)); 852 gld_mac_free(macinfo); 853 return (DDI_FAILURE); 854 } 855 856 /* 857 * detach(9E) -- Detach a device from the system 858 */ 859 static int 860 dnetdetach(dev_info_t *devinfo, ddi_detach_cmd_t cmd) 861 { 862 int32_t rc; 863 gld_mac_info_t *macinfo; /* GLD structure */ 864 struct dnetinstance *dnetp; /* Our private device info */ 865 int32_t proplen; 866 867 #ifdef DNETDEBUG 868 if (dnetdebug & DNETDDI) 869 cmn_err(CE_NOTE, "dnetdetach(0x%p)", (void *) devinfo); 870 #endif 871 872 /* Get the driver private (gld_mac_info_t) structure */ 873 macinfo = ddi_get_driver_private(devinfo); 874 dnetp = (struct dnetinstance *)(macinfo->gldm_private); 875 876 switch (cmd) { 877 case DDI_DETACH: 878 break; 879 880 case DDI_SUSPEND: 881 /* 882 * NB: dnetp->suspended can only be modified (marked true) 883 * if both intrlock and txlock are held. This keeps both 884 * tx and rx code paths excluded. 885 */ 886 mutex_enter(&dnetp->intrlock); 887 mutex_enter(&dnetp->txlock); 888 dnetp->suspended = B_TRUE; 889 dnet_reset_board(macinfo); 890 mutex_exit(&dnetp->txlock); 891 mutex_exit(&dnetp->intrlock); 892 return (DDI_SUCCESS); 893 894 default: 895 return (DDI_FAILURE); 896 } 897 898 /* 899 * Unregister ourselves from the GLD interface 900 * 901 * gld_unregister will: 902 * remove the minor node; 903 * unmap the registers; 904 * remove the interrupt; 905 * destroy the gldm_intrlock mutex; 906 * unlink us from the GLD system. 907 */ 908 if (gld_unregister(macinfo) != DDI_SUCCESS) 909 return (DDI_FAILURE); 910 911 /* stop the board if it is running */ 912 dnet_reset_board(macinfo); 913 914 if ((rc = dnet_detach_hacked_interrupt(devinfo)) != DDI_SUCCESS) 915 return (rc); 916 917 if (dnetp->mii != NULL) 918 mii_destroy(dnetp->mii); 919 920 /* Free leaf information */ 921 set_leaf(&dnetp->sr, NULL); 922 923 ddi_regs_map_free(&dnetp->io_handle); 924 dnet_free_bufs(macinfo); 925 mutex_destroy(&dnetp->txlock); 926 mutex_destroy(&dnetp->intrlock); 927 kmem_free(dnetp, sizeof (struct dnetinstance)); 928 gld_mac_free(macinfo); 929 930 #ifdef BUG_4010796 931 if (ddi_getproplen(DDI_DEV_T_ANY, devinfo, 0, 932 "DNET_HACK", &proplen) != DDI_PROP_SUCCESS) 933 return (DDI_SUCCESS); 934 935 /* 936 * We must remove the properties we added, because if we leave 937 * them in the devinfo nodes and the driver is unloaded, when 938 * the driver is reloaded the info will still be there, causing 939 * nodes which had returned PROBE_PARTIAL the first time to 940 * instead return PROBE_SUCCESS, in turn causing the nodes to be 941 * attached in a different order, causing their PPA numbers to 942 * be different the second time around, which is undesirable. 943 */ 944 (void) ddi_prop_remove(DDI_DEV_T_NONE, devinfo, "DNET_HACK"); 945 (void) ddi_prop_remove(DDI_DEV_T_NONE, ddi_get_parent(devinfo), 946 "DNET_SROM"); 947 (void) ddi_prop_remove(DDI_DEV_T_NONE, ddi_get_parent(devinfo), 948 "DNET_DEVNUM"); 949 #endif 950 951 return (DDI_SUCCESS); 952 } 953 954 /* 955 * ========== GLD Entry Points ========== 956 */ 957 958 /* 959 * dnet_reset() -- reset the board to initial state; 960 */ 961 static int 962 dnet_reset(gld_mac_info_t *macinfo) 963 { 964 struct dnetinstance *dnetp = /* Our private device info */ 965 (struct dnetinstance *)macinfo->gldm_private; 966 #ifdef DNETDEBUG 967 if (dnetdebug & DNETTRACE) 968 cmn_err(CE_NOTE, "dnet_reset(0x%p)", (void *) macinfo); 969 #endif 970 971 mutex_enter(&dnetp->intrlock); 972 /* 973 * Initialize internal data structures 974 */ 975 bzero(dnetp->setup_buf_vaddr, SETUPBUF_SIZE); 976 bzero(dnetp->multicast_cnt, MCASTBUF_SIZE); 977 dnetp->promisc = 0; 978 979 mutex_enter(&dnetp->txlock); 980 dnetp->need_saddr = 0; 981 mutex_exit(&dnetp->txlock); 982 983 if (dnetp->suspended) { 984 mutex_exit(&dnetp->intrlock); 985 return (0); 986 } 987 dnet_reset_board(macinfo); 988 989 if (ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo, DDI_PROP_DONTPASS, 990 "reset_do_find_active_media", 0)) { 991 find_active_media(macinfo); /* Redetermine active media */ 992 /* Go back to a good state */ 993 bzero(dnetp->setup_buf_vaddr, SETUPBUF_SIZE); 994 dnet_reset_board(macinfo); 995 } 996 dnet_init_board(macinfo); 997 mutex_exit(&dnetp->intrlock); 998 return (0); 999 } 1000 1001 static void 1002 dnet_reset_board(gld_mac_info_t *macinfo) 1003 { 1004 struct dnetinstance *dnetp = /* Our private device info */ 1005 (struct dnetinstance *)macinfo->gldm_private; 1006 uint32_t val; 1007 1008 /* 1009 * before initializing the dnet should be in STOP state 1010 */ 1011 /* XXX function return value ignored */ 1012 /* (void) dnet_stop_board(macinfo); */ 1013 val = ddi_get32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG)); 1014 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG), 1015 val & ~(START_TRANSMIT | START_RECEIVE)); 1016 1017 /* 1018 * Reset the chip 1019 */ 1020 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, INT_MASK_REG), 0); 1021 ddi_put32(dnetp->io_handle, 1022 REG32(dnetp->io_reg, BUS_MODE_REG), SW_RESET); 1023 drv_usecwait(5); 1024 } 1025 1026 /* 1027 * dnet_init_board() -- initialize the specified network board short of 1028 * actually starting the board. Call after dnet_reset_board(). 1029 * called with intrlock held. 1030 */ 1031 static void 1032 dnet_init_board(gld_mac_info_t *macinfo) 1033 { 1034 #ifdef DNETDEBUG 1035 if (dnetdebug & DNETTRACE) 1036 cmn_err(CE_NOTE, "dnet_init_board(0x%p)", (void *) macinfo); 1037 #endif 1038 set_opr(macinfo); 1039 set_gpr(macinfo); 1040 set_sia(macinfo); 1041 dnet_chip_init(macinfo); 1042 } 1043 1044 /* dnet_chip_init() - called with intrlock held */ 1045 static void 1046 dnet_chip_init(gld_mac_info_t *macinfo) 1047 { 1048 struct dnetinstance *dnetp = (struct dnetinstance *) 1049 (macinfo->gldm_private); 1050 1051 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, BUS_MODE_REG), 1052 CACHE_ALIGN | BURST_SIZE); /* CSR0 */ 1053 1054 /* 1055 * Initialize the TX and RX descriptors/buffers 1056 */ 1057 dnet_init_txrx_bufs(macinfo); 1058 1059 /* 1060 * Set the base address of the Rx descriptor list in CSR3 1061 */ 1062 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, RX_BASE_ADDR_REG), 1063 dnetp->rx_desc_paddr); 1064 1065 /* 1066 * Set the base address of the Tx descrptor list in CSR4 1067 */ 1068 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, TX_BASE_ADDR_REG), 1069 dnetp->tx_desc_paddr); 1070 1071 dnetp->tx_current_desc = dnetp->rx_current_desc = 0; 1072 dnetp->transmitted_desc = 0; 1073 dnetp->free_desc = dnetp->max_tx_desc; 1074 enable_interrupts(dnetp, 1); 1075 } 1076 1077 /* 1078 * dnet_start() -- start the board receiving and allow transmits. 1079 * Called with intrlock held. 1080 */ 1081 static int 1082 dnet_start(gld_mac_info_t *macinfo) 1083 { 1084 struct dnetinstance *dnetp = /* Our private device info */ 1085 (struct dnetinstance *)macinfo->gldm_private; 1086 uint32_t val; 1087 1088 #ifdef DNETDEBUG 1089 if (dnetdebug & DNETTRACE) 1090 cmn_err(CE_NOTE, "dnet_start(0x%p)", (void *) macinfo); 1091 #endif 1092 1093 ASSERT(MUTEX_HELD(&dnetp->intrlock)); 1094 /* 1095 * start the board and enable receiving 1096 */ 1097 val = ddi_get32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG)); 1098 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG), 1099 val | START_TRANSMIT); 1100 (void) dnet_set_addr(macinfo); 1101 val = ddi_get32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG)); 1102 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG), 1103 val | START_RECEIVE); 1104 enable_interrupts(dnetp, 1); 1105 return (0); 1106 } 1107 1108 /* 1109 * dnet_start_board() -- start the board receiving and allow transmits. 1110 */ 1111 static int 1112 dnet_start_board(gld_mac_info_t *macinfo) 1113 { 1114 struct dnetinstance *dnetp = /* Our private device info */ 1115 (struct dnetinstance *)macinfo->gldm_private; 1116 1117 #ifdef DNETDEBUG 1118 if (dnetdebug & DNETTRACE) 1119 cmn_err(CE_NOTE, "dnet_start_board(0x%p)", (void *) macinfo); 1120 #endif 1121 1122 mutex_enter(&dnetp->intrlock); 1123 dnetp->running = B_TRUE; 1124 /* 1125 * start the board and enable receiving 1126 */ 1127 if (!dnetp->suspended) 1128 (void) dnet_start(macinfo); 1129 mutex_exit(&dnetp->intrlock); 1130 return (0); 1131 } 1132 1133 /* 1134 * dnet_stop_board() -- stop board receiving 1135 */ 1136 static int 1137 dnet_stop_board(gld_mac_info_t *macinfo) 1138 { 1139 struct dnetinstance *dnetp = /* Our private device info */ 1140 (struct dnetinstance *)macinfo->gldm_private; 1141 uint32_t val; 1142 1143 #ifdef DNETDEBUG 1144 if (dnetdebug & DNETTRACE) 1145 cmn_err(CE_NOTE, "dnet_stop_board(0x%p)", (void *) macinfo); 1146 #endif 1147 /* 1148 * stop the board and disable transmit/receive 1149 */ 1150 mutex_enter(&dnetp->intrlock); 1151 if (!dnetp->suspended) { 1152 val = ddi_get32(dnetp->io_handle, 1153 REG32(dnetp->io_reg, OPN_MODE_REG)); 1154 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG), 1155 val & ~(START_TRANSMIT | START_RECEIVE)); 1156 } 1157 dnetp->running = B_FALSE; 1158 mutex_exit(&dnetp->intrlock); 1159 return (0); 1160 } 1161 1162 /* 1163 * dnet_set_addr() -- set the physical network address on the board 1164 * Called with intrlock held. 1165 */ 1166 static int 1167 dnet_set_addr(gld_mac_info_t *macinfo) 1168 { 1169 struct dnetinstance *dnetp = /* Our private device info */ 1170 (struct dnetinstance *)macinfo->gldm_private; 1171 struct tx_desc_type *desc; 1172 int current_desc; 1173 uint32_t val; 1174 1175 ASSERT(MUTEX_HELD(&dnetp->intrlock)); 1176 #ifdef DNETDEBUG 1177 if (dnetdebug & DNETTRACE) 1178 cmn_err(CE_NOTE, "dnet_set_addr(0x%p)", (void *) macinfo); 1179 #endif 1180 1181 val = ddi_get32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG)); 1182 if (!(val & START_TRANSMIT)) 1183 return (0); 1184 1185 current_desc = dnetp->tx_current_desc; 1186 desc = &dnetp->tx_desc[current_desc]; 1187 1188 mutex_enter(&dnetp->txlock); 1189 dnetp->need_saddr = 0; 1190 mutex_exit(&dnetp->txlock); 1191 1192 if ((alloc_descriptor(macinfo)) == FAILURE) { 1193 mutex_enter(&dnetp->txlock); 1194 dnetp->need_saddr = 1; 1195 mutex_exit(&dnetp->txlock); 1196 #ifdef DNETDEBUG 1197 if (dnetdebug & DNETTRACE) 1198 cmn_err(CE_WARN, "DNET saddr:alloc descriptor failure"); 1199 #endif 1200 return (0); 1201 } 1202 1203 desc->buffer1 = dnetp->setup_buf_paddr; 1204 desc->buffer2 = 0; 1205 desc->desc1.buffer_size1 = SETUPBUF_SIZE; 1206 desc->desc1.buffer_size2 = 0; 1207 desc->desc1.setup_packet = 1; 1208 desc->desc1.first_desc = 0; 1209 desc->desc1.last_desc = 0; 1210 desc->desc1.filter_type0 = 1; 1211 desc->desc1.filter_type1 = 1; 1212 desc->desc1.int_on_comp = 1; 1213 1214 desc->desc0.own = 1; 1215 ddi_put8(dnetp->io_handle, REG8(dnetp->io_reg, TX_POLL_REG), 1216 TX_POLL_DEMAND); 1217 return (0); 1218 } 1219 1220 /* 1221 * dnet_set_mac_addr() -- set the physical network address on the board 1222 */ 1223 static int 1224 dnet_set_mac_addr(gld_mac_info_t *macinfo, uchar_t *macaddr) 1225 { 1226 struct dnetinstance *dnetp = /* Our private device info */ 1227 (struct dnetinstance *)macinfo->gldm_private; 1228 uint32_t index; 1229 uint32_t *hashp; 1230 1231 #ifdef DNETDEBUG 1232 if (dnetdebug & DNETTRACE) 1233 cmn_err(CE_NOTE, "dnet_set_mac_addr(0x%p)", (void *) macinfo); 1234 #endif 1235 mutex_enter(&dnetp->intrlock); 1236 1237 bcopy(macaddr, dnetp->curr_macaddr, ETHERADDRL); 1238 1239 /* 1240 * As we are using Imperfect filtering, the broadcast address has to 1241 * be set explicitly in the 512 bit hash table. Hence the index into 1242 * the hash table is calculated and the bit set to enable reception 1243 * of broadcast packets. 1244 * 1245 * We also use HASH_ONLY mode, without using the perfect filter for 1246 * our station address, because there appears to be a bug in the 1247 * 21140 where it fails to receive the specified perfect filter 1248 * address. 1249 * 1250 * Since dlsdmult comes through here, it doesn't matter that the count 1251 * is wrong for the two bits that correspond to the cases below. The 1252 * worst that could happen is that we'd leave on a bit for an old 1253 * macaddr, in the case where the macaddr gets changed, which is rare. 1254 * Since filtering is imperfect, it is OK if that happens. 1255 */ 1256 hashp = (uint32_t *)dnetp->setup_buf_vaddr; 1257 index = hashindex((uchar_t *)dnet_broadcastaddr); 1258 hashp[ index / 16 ] |= 1 << (index % 16); 1259 1260 index = hashindex((uchar_t *)dnetp->curr_macaddr); 1261 hashp[ index / 16 ] |= 1 << (index % 16); 1262 1263 if (!dnetp->suspended) 1264 (void) dnet_set_addr(macinfo); 1265 mutex_exit(&dnetp->intrlock); 1266 return (0); 1267 } 1268 1269 /* 1270 * dnet_set_multicast() -- set (enable) or disable a multicast address 1271 * 1272 * Program the hardware to enable/disable the multicast address 1273 * in "mcast". Enable if "op" is non-zero, disable if zero. 1274 */ 1275 static int 1276 dnet_set_multicast(gld_mac_info_t *macinfo, uchar_t *mcast, int op) 1277 { 1278 struct dnetinstance *dnetp = /* Our private device info */ 1279 (struct dnetinstance *)macinfo->gldm_private; 1280 uint32_t index; 1281 uint32_t *hashp; 1282 uint32_t retval; 1283 1284 #ifdef DNETDEBUG 1285 if (dnetdebug & DNETTRACE) 1286 cmn_err(CE_NOTE, "dnet_set_multicast(0x%p, %s)", 1287 (void *) macinfo, op ? "ON" : "OFF"); 1288 #endif 1289 mutex_enter(&dnetp->intrlock); 1290 index = hashindex(mcast); 1291 hashp = (uint32_t *)dnetp->setup_buf_vaddr; 1292 if (op == GLD_MULTI_ENABLE) { 1293 if (dnetp->multicast_cnt[index]++) { 1294 mutex_exit(&dnetp->intrlock); 1295 return (0); 1296 } 1297 hashp[ index / 16 ] |= 1 << (index % 16); 1298 } else { 1299 if (--dnetp->multicast_cnt[index]) { 1300 mutex_exit(&dnetp->intrlock); 1301 return (0); 1302 } 1303 hashp[ index / 16 ] &= ~ (1 << (index % 16)); 1304 } 1305 if (!dnetp->suspended) 1306 retval = dnet_set_addr(macinfo); 1307 else 1308 retval = 0; 1309 mutex_exit(&dnetp->intrlock); 1310 return (retval); 1311 } 1312 1313 /* 1314 * A hashing function used for setting the 1315 * node address or a multicast address 1316 */ 1317 static uint32_t 1318 hashindex(uchar_t *address) 1319 { 1320 uint32_t crc = (uint32_t)HASH_CRC; 1321 uint32_t const POLY = HASH_POLY; 1322 uint32_t msb; 1323 int32_t byteslength; 1324 uint8_t currentbyte; 1325 uint32_t index; 1326 int32_t bit; 1327 int32_t shift; 1328 1329 for (byteslength = 0; byteslength < ETHERADDRL; byteslength++) { 1330 currentbyte = address[byteslength]; 1331 for (bit = 0; bit < 8; bit++) { 1332 msb = crc >> 31; 1333 crc <<= 1; 1334 if (msb ^ (currentbyte & 1)) { 1335 crc ^= POLY; 1336 crc |= 0x00000001; 1337 } 1338 currentbyte >>= 1; 1339 } 1340 } 1341 1342 for (index = 0, bit = 23, shift = 8; shift >= 0; bit++, shift--) { 1343 index |= (((crc >> bit) & 1) << shift); 1344 } 1345 return (index); 1346 } 1347 1348 /* 1349 * dnet_set_promiscuous() -- set or reset promiscuous mode on the board 1350 * 1351 * Program the hardware to enable/disable promiscuous mode. 1352 * Enable if "on" is non-zero, disable if zero. 1353 */ 1354 1355 static int 1356 dnet_set_promiscuous(gld_mac_info_t *macinfo, int on) 1357 { 1358 struct dnetinstance *dnetp; 1359 uint32_t val; 1360 1361 #ifdef DNETDEBUG 1362 if (dnetdebug & DNETTRACE) 1363 cmn_err(CE_NOTE, "dnet_set_promiscuous(0x%p, %s)", 1364 (void *) macinfo, on ? "ON" : "OFF"); 1365 #endif 1366 1367 dnetp = (struct dnetinstance *)macinfo->gldm_private; 1368 mutex_enter(&dnetp->intrlock); 1369 if (dnetp->promisc == on) { 1370 mutex_exit(&dnetp->intrlock); 1371 return (SUCCESS); 1372 } 1373 dnetp->promisc = on; 1374 1375 if (!dnetp->suspended) { 1376 val = ddi_get32(dnetp->io_handle, 1377 REG32(dnetp->io_reg, OPN_MODE_REG)); 1378 if (on != GLD_MAC_PROMISC_NONE) 1379 ddi_put32(dnetp->io_handle, 1380 REG32(dnetp->io_reg, OPN_MODE_REG), 1381 val | PROM_MODE); 1382 else 1383 ddi_put32(dnetp->io_handle, 1384 REG32(dnetp->io_reg, OPN_MODE_REG), 1385 val & (~PROM_MODE)); 1386 } 1387 mutex_exit(&dnetp->intrlock); 1388 return (DDI_SUCCESS); 1389 } 1390 1391 /* 1392 * dnet_get_stats() -- update statistics 1393 * 1394 * GLD calls this routine just before it reads the driver's statistics 1395 * structure. If your board maintains statistics, this is the time to 1396 * read them in and update the values in the structure. If the driver 1397 * maintains statistics continuously, this routine need do nothing. 1398 */ 1399 1400 static int 1401 dnet_get_stats(gld_mac_info_t *macinfo, struct gld_stats *sp) 1402 { 1403 struct dnetinstance *dnetp = /* Our private device info */ 1404 (struct dnetinstance *)macinfo->gldm_private; 1405 #ifdef DNETDEBUG 1406 if (dnetdebug & DNETTRACE) 1407 cmn_err(CE_NOTE, "dnet_get_stats(0x%p)", (void *) macinfo); 1408 #endif 1409 sp->glds_errrcv = dnetp->stat_errrcv; 1410 sp->glds_overflow = dnetp->stat_overflow; 1411 sp->glds_intr = dnetp->stat_intr; 1412 sp->glds_defer = dnetp->stat_defer; 1413 sp->glds_missed = dnetp->stat_missed; 1414 sp->glds_norcvbuf = dnetp->stat_norcvbuf; 1415 sp->glds_crc = dnetp->stat_crc; 1416 sp->glds_short = dnetp->stat_short; 1417 sp->glds_frame = dnetp->stat_frame; 1418 sp->glds_errxmt = dnetp->stat_errxmt; 1419 sp->glds_collisions = dnetp->stat_collisions; 1420 sp->glds_xmtlatecoll = dnetp->stat_xmtlatecoll; 1421 sp->glds_excoll = dnetp->stat_excoll; 1422 sp->glds_underflow = dnetp->stat_underflow; 1423 sp->glds_nocarrier = dnetp->stat_nocarrier; 1424 1425 /* stats from instance structure */ 1426 if (dnetp->mii_up) { 1427 sp->glds_speed = dnetp->mii_speed * 1000000; 1428 sp->glds_duplex = dnetp->mii_duplex ? 1429 GLD_DUPLEX_FULL : GLD_DUPLEX_HALF; 1430 } else { 1431 sp->glds_speed = dnetp->speed * 1000000; 1432 sp->glds_duplex = 1433 dnetp->full_duplex ? GLD_DUPLEX_FULL : GLD_DUPLEX_HALF; 1434 } 1435 1436 return (DDI_SUCCESS); 1437 } 1438 1439 /* 1440 * dnet_send() -- send a packet 1441 * 1442 * Called when a packet is ready to be transmitted. A pointer to an 1443 * M_DATA message that contains the packet is passed to this routine. 1444 * The complete LLC header is contained in the message's first message 1445 * block, and the remainder of the packet is contained within 1446 * additional M_DATA message blocks linked to the first message block. 1447 */ 1448 1449 #define NextTXIndex(index) (((index)+1) % dnetp->max_tx_desc) 1450 #define PrevTXIndex(index) (((index)-1) < 0 ? dnetp->max_tx_desc - 1: (index)-1) 1451 1452 static int 1453 dnet_send(gld_mac_info_t *macinfo, mblk_t *mp) 1454 { 1455 struct dnetinstance *dnetp = /* Our private device info */ 1456 (struct dnetinstance *)macinfo->gldm_private; 1457 struct tx_desc_type *ring = dnetp->tx_desc; 1458 int mblen, totlen; 1459 int index, end_index, start_index; 1460 int avail; 1461 int error; 1462 int bufn; 1463 int bp_count; 1464 int retval; 1465 mblk_t *bp; 1466 uint32_t tx_interrupt_mask; 1467 1468 #ifdef DNETDEBUG 1469 if (dnetdebug & DNETSEND) 1470 cmn_err(CE_NOTE, "dnet_send(0x%p, 0x%p)", 1471 (void *) macinfo, (void *) mp); 1472 #endif 1473 mutex_enter(&dnetp->txlock); 1474 /* if suspended, drop the packet on the floor, we missed it */ 1475 if (dnetp->suspended) { 1476 mutex_exit(&dnetp->txlock); 1477 freemsg(mp); 1478 return (0); 1479 } 1480 if (dnetp->need_saddr) { 1481 /* XXX function return value ignored */ 1482 mutex_exit(&dnetp->txlock); 1483 mutex_enter(&dnetp->intrlock); 1484 (void) dnet_set_addr(macinfo); 1485 mutex_exit(&dnetp->intrlock); 1486 mutex_enter(&dnetp->txlock); 1487 } 1488 1489 /* reclaim any xmit descriptors completed */ 1490 dnet_reclaim_Tx_desc(macinfo); 1491 1492 /* 1493 * Use the data buffers from the message and construct the 1494 * scatter/gather list by calling ddi_dma_addr_bind_handle(). 1495 */ 1496 error = bp_count = 0; 1497 totlen = 0; 1498 bp = mp; 1499 bufn = 0; 1500 index = start_index = dnetp->tx_current_desc; 1501 avail = dnetp->free_desc; 1502 while (bp != NULL) { 1503 uint_t ncookies; 1504 ddi_dma_cookie_t dma_cookie; 1505 1506 if (++bp_count > DNET_MAX_FRAG) { 1507 #ifndef DNET_NOISY 1508 (void) pullupmsg(bp, -1); 1509 #else 1510 if (pullupmsg(bp, -1)) 1511 cmn_err(CE_NOTE, "DNET: pulled up send msg"); 1512 else 1513 cmn_err(CE_NOTE, 1514 "DNET: couldn't pullup send msg"); 1515 #endif 1516 } 1517 1518 mblen = (int)(bp->b_wptr - bp->b_rptr); 1519 1520 if (!mblen) { /* skip zero-length message blocks */ 1521 bp = bp->b_cont; 1522 continue; 1523 } 1524 1525 retval = ddi_dma_addr_bind_handle(dnetp->dma_handle_tx, NULL, 1526 (caddr_t)bp->b_rptr, mblen, 1527 DDI_DMA_WRITE | DDI_DMA_STREAMING, DDI_DMA_SLEEP, 0, 1528 &dma_cookie, &ncookies); 1529 1530 switch (retval) { 1531 case DDI_DMA_MAPPED: 1532 break; /* everything's fine */ 1533 1534 case DDI_DMA_NORESOURCES: 1535 error = 1; /* allow retry by gld */ 1536 break; 1537 1538 case DDI_DMA_NOMAPPING: 1539 case DDI_DMA_INUSE: 1540 case DDI_DMA_TOOBIG: 1541 default: 1542 error = 2; /* error, no retry */ 1543 break; 1544 } 1545 1546 /* 1547 * we can use two cookies per descriptor (i.e buffer1 and 1548 * buffer2) so we need at least (ncookies+1)/2 descriptors. 1549 */ 1550 if (((ncookies + 1) >> 1) > dnetp->free_desc) { 1551 (void) ddi_dma_unbind_handle(dnetp->dma_handle_tx); 1552 error = 1; 1553 break; 1554 } 1555 1556 /* setup the descriptors for this data buffer */ 1557 while (ncookies) { 1558 end_index = index; 1559 if (bufn % 2) { 1560 ring[index].buffer2 = 1561 (uint32_t)dma_cookie.dmac_address; 1562 ring[index].desc1.buffer_size2 = 1563 dma_cookie.dmac_size; 1564 index = NextTXIndex(index); /* goto next desc */ 1565 } else { 1566 /* initialize the descriptor */ 1567 ASSERT(ring[index].desc0.own == 0); 1568 *(uint32_t *)&ring[index].desc0 = 0; 1569 *(uint32_t *)&ring[index].desc1 &= 1570 DNET_END_OF_RING; 1571 ring[index].buffer1 = 1572 (uint32_t)dma_cookie.dmac_address; 1573 ring[index].desc1.buffer_size1 = 1574 dma_cookie.dmac_size; 1575 ring[index].buffer2 = (uint32_t)(0); 1576 dnetp->free_desc--; 1577 ASSERT(dnetp->free_desc >= 0); 1578 } 1579 totlen += dma_cookie.dmac_size; 1580 bufn++; 1581 if (--ncookies) 1582 ddi_dma_nextcookie(dnetp->dma_handle_tx, 1583 &dma_cookie); 1584 } 1585 (void) ddi_dma_unbind_handle(dnetp->dma_handle_tx); 1586 bp = bp->b_cont; 1587 } 1588 1589 if (error == 1) { 1590 dnetp->stat_defer++; 1591 dnetp->free_desc = avail; 1592 dnetp->need_gld_sched = 1; 1593 mutex_exit(&dnetp->txlock); 1594 return (GLD_TX_RESEND); 1595 } else if (error) { 1596 dnetp->free_desc = avail; 1597 mutex_exit(&dnetp->txlock); 1598 freemsg(mp); 1599 return (0); /* Drop packet, don't retry */ 1600 } 1601 1602 if (totlen > ETHERMAX) { 1603 cmn_err(CE_WARN, "DNET: tried to send large %d packet", totlen); 1604 dnetp->free_desc = avail; 1605 mutex_exit(&dnetp->txlock); 1606 freemsg(mp); 1607 return (0); /* We don't want to repeat this attempt */ 1608 } 1609 1610 /* 1611 * Remeber the message buffer pointer to do freemsg() at xmit 1612 * interrupt time. 1613 */ 1614 dnetp->tx_msgbufp[end_index] = mp; 1615 1616 /* 1617 * Now set the first/last buffer and own bits 1618 * Since the 21040 looks for these bits set in the 1619 * first buffer, work backwards in multiple buffers. 1620 */ 1621 ring[end_index].desc1.last_desc = 1; 1622 ring[end_index].desc1.int_on_comp = 1; 1623 for (index = end_index; index != start_index; 1624 index = PrevTXIndex(index)) 1625 ring[index].desc0.own = 1; 1626 ring[start_index].desc1.first_desc = 1; 1627 ring[start_index].desc0.own = 1; 1628 1629 dnetp->tx_current_desc = NextTXIndex(end_index); 1630 1631 /* 1632 * Safety check: make sure end-of-ring is set in last desc. 1633 */ 1634 ASSERT(ring[dnetp->max_tx_desc-1].desc1.end_of_ring != 0); 1635 1636 /* 1637 * Enable xmit interrupt if we are running out of xmit descriptors 1638 * or there are more packets on the queue waiting to be transmitted. 1639 */ 1640 #ifdef GLD_INTR_WAIT /* XXX This relies on new GLD changes */ 1641 if (dnetp->free_desc <= dnet_xmit_threshold) 1642 tx_interrupt_mask = TX_INTERRUPT_MASK; 1643 else 1644 tx_interrupt_mask = (macinfo->gldm_GLD_flags & GLD_INTR_WAIT) ? 1645 TX_INTERRUPT_MASK : 0; 1646 #else 1647 tx_interrupt_mask = TX_INTERRUPT_MASK; 1648 #endif 1649 1650 mutex_exit(&dnetp->txlock); 1651 mutex_enter(&dnetp->intrlock); 1652 enable_interrupts(dnetp, tx_interrupt_mask); 1653 1654 /* 1655 * Kick the transmitter 1656 */ 1657 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, TX_POLL_REG), 1658 TX_POLL_DEMAND); 1659 mutex_exit(&dnetp->intrlock); 1660 return (GLD_TX_OK); /* successful transmit attempt */ 1661 } 1662 1663 /* 1664 * dnetintr() -- interrupt from board to inform us that a receive or 1665 * transmit has completed. 1666 */ 1667 1668 1669 static uint_t 1670 dnetintr(gld_mac_info_t *macinfo) 1671 { 1672 struct dnetinstance *dnetp = /* Our private device info */ 1673 (struct dnetinstance *)macinfo->gldm_private; 1674 uint32_t int_status; 1675 uint32_t tx_interrupt_mask; 1676 1677 mutex_enter(&dnetp->intrlock); 1678 #ifdef DNETDEBUG 1679 if (dnetdebug & DNETINT) 1680 cmn_err(CE_NOTE, "dnetintr(0x%p)", (void *)macinfo); 1681 #endif 1682 if (dnetp->suspended) { 1683 mutex_exit(&dnetp->intrlock); 1684 return (DDI_INTR_UNCLAIMED); 1685 } 1686 1687 int_status = ddi_get32(dnetp->io_handle, REG32(dnetp->io_reg, 1688 STATUS_REG)); 1689 1690 /* 1691 * If interrupt was not from this board 1692 */ 1693 if (!(int_status & (NORMAL_INTR_SUMM | ABNORMAL_INTR_SUMM))) { 1694 mutex_exit(&dnetp->intrlock); 1695 return (DDI_INTR_UNCLAIMED); 1696 } 1697 1698 dnetp->stat_intr++; 1699 1700 if (int_status & GPTIMER_INTR) { 1701 ddi_put32(dnetp->io_handle, 1702 REG32(dnetp->io_reg, STATUS_REG), GPTIMER_INTR); 1703 if (dnetp->timer.cb) 1704 dnetp->timer.cb(dnetp); 1705 else 1706 cmn_err(CE_WARN, "dnet: unhandled timer interrupt"); 1707 } 1708 1709 if (int_status & TX_INTR) { 1710 ddi_put32(dnetp->io_handle, 1711 REG32(dnetp->io_reg, STATUS_REG), TX_INTR); 1712 mutex_enter(&dnetp->txlock); 1713 if (dnetp->need_gld_sched) { 1714 mutex_exit(&dnetp->txlock); 1715 mutex_exit(&dnetp->intrlock); 1716 gld_sched(macinfo); 1717 mutex_enter(&dnetp->intrlock); 1718 mutex_enter(&dnetp->txlock); 1719 dnetp->need_gld_sched = 0; 1720 } 1721 /* reclaim any xmit descriptors that are completed */ 1722 dnet_reclaim_Tx_desc(macinfo); 1723 mutex_exit(&dnetp->txlock); 1724 } 1725 1726 /* 1727 * Check if receive interrupt bit is set 1728 */ 1729 if (int_status & (RX_INTR | RX_UNAVAIL_INTR)) { 1730 ddi_put32(dnetp->io_handle, 1731 REG32(dnetp->io_reg, STATUS_REG), 1732 int_status & (RX_INTR | RX_UNAVAIL_INTR)); 1733 dnet_getp(macinfo); 1734 } 1735 1736 if (int_status & ABNORMAL_INTR_SUMM) { 1737 /* 1738 * Check for system error 1739 */ 1740 if (int_status & SYS_ERR) { 1741 if ((int_status & SYS_ERR_BITS) == MASTER_ABORT) 1742 cmn_err(CE_WARN, "DNET: Bus Master Abort"); 1743 if ((int_status & SYS_ERR_BITS) == TARGET_ABORT) 1744 cmn_err(CE_WARN, "DNET: Bus Target Abort"); 1745 if ((int_status & SYS_ERR_BITS) == PARITY_ERROR) 1746 cmn_err(CE_WARN, "DNET: Parity error"); 1747 } 1748 1749 /* 1750 * If the jabber has timed out then reset the chip 1751 */ 1752 if (int_status & TX_JABBER_TIMEOUT) 1753 cmn_err(CE_WARN, "DNET: Jabber timeout."); 1754 1755 /* 1756 * If an underflow has occurred, reset the chip 1757 */ 1758 if (int_status & TX_UNDERFLOW) 1759 cmn_err(CE_WARN, "DNET: Tx Underflow."); 1760 1761 #ifdef DNETDEBUG 1762 if (dnetdebug & DNETINT) 1763 cmn_err(CE_NOTE, "Trying to reset..."); 1764 #endif 1765 dnet_reset_board(macinfo); 1766 dnet_init_board(macinfo); 1767 /* XXX function return value ignored */ 1768 (void) dnet_start(macinfo); 1769 } 1770 1771 /* 1772 * Enable the interrupts. Enable xmit interrupt only if we are 1773 * running out of free descriptors or if there are packets 1774 * in the queue waiting to be transmitted. 1775 */ 1776 #ifdef GLD_INTR_WAIT /* XXX This relies on new GLD changes */ 1777 if (dnetp->free_desc <= dnet_xmit_threshold) 1778 tx_interrupt_mask = TX_INTERRUPT_MASK; 1779 else 1780 tx_interrupt_mask = (macinfo->gldm_GLD_flags & GLD_INTR_WAIT) ? 1781 TX_INTERRUPT_MASK : 0; 1782 #else 1783 tx_interrupt_mask = TX_INTERRUPT_MASK; 1784 #endif 1785 enable_interrupts(dnetp, tx_interrupt_mask); 1786 mutex_exit(&dnetp->intrlock); 1787 return (DDI_INTR_CLAIMED); /* Indicate it was our interrupt */ 1788 } 1789 1790 static void 1791 dnet_getp(gld_mac_info_t *macinfo) 1792 { 1793 struct dnetinstance *dnetp = 1794 (struct dnetinstance *)macinfo->gldm_private; 1795 int packet_length, index; 1796 mblk_t *mp; 1797 caddr_t virtual_address; 1798 struct rx_desc_type *desc = dnetp->rx_desc; 1799 int marker = dnetp->rx_current_desc; 1800 int misses; 1801 1802 #ifdef DNETDEBUG 1803 if (dnetdebug & DNETRECV) 1804 cmn_err(CE_NOTE, "dnet_getp(0x%p)", (void *)macinfo); 1805 #endif 1806 1807 if (!dnetp->overrun_workaround) { 1808 /* 1809 * If the workaround is not in place, we must still update 1810 * the missed frame statistic from the on-chip counter. 1811 */ 1812 misses = ddi_get32(dnetp->io_handle, 1813 REG32(dnetp->io_reg, MISSED_FRAME_REG)); 1814 dnetp->stat_missed += (misses & MISSED_FRAME_MASK); 1815 } 1816 1817 /* While host owns the current descriptor */ 1818 while (!(desc[dnetp->rx_current_desc].desc0.own)) { 1819 struct free_ptr *frp; 1820 caddr_t newbuf; 1821 struct rbuf_list *rp; 1822 1823 index = dnetp->rx_current_desc; 1824 ASSERT(desc[index].desc0.first_desc != 0); 1825 1826 /* 1827 * DMA overrun errata from DEC: avoid possible bus hangs 1828 * and data corruption 1829 */ 1830 if (dnetp->overrun_workaround && 1831 marker == dnetp->rx_current_desc) { 1832 int opn; 1833 do { 1834 marker = (marker+1) % dnetp->max_rx_desc; 1835 } while (!(dnetp->rx_desc[marker].desc0.own) && 1836 marker != index); 1837 1838 misses = ddi_get32(dnetp->io_handle, 1839 REG32(dnetp->io_reg, MISSED_FRAME_REG)); 1840 dnetp->stat_missed += 1841 (misses & MISSED_FRAME_MASK); 1842 if (misses & OVERFLOW_COUNTER_MASK) { 1843 /* 1844 * Overflow(s) have occurred : stop receiver, 1845 * and wait until in stopped state 1846 */ 1847 opn = ddi_get32(dnetp->io_handle, 1848 REG32(dnetp->io_reg, OPN_MODE_REG)); 1849 ddi_put32(dnetp->io_handle, 1850 REG32(dnetp->io_reg, OPN_MODE_REG), 1851 opn & ~(START_RECEIVE)); 1852 1853 do { 1854 drv_usecwait(10); 1855 } while ((ddi_get32(dnetp->io_handle, 1856 REG32(dnetp->io_reg, STATUS_REG)) & 1857 RECEIVE_PROCESS_STATE) != 0); 1858 #ifdef DNETDEBUG 1859 if (dnetdebug & DNETRECV) 1860 cmn_err(CE_CONT, "^*"); 1861 #endif 1862 /* Discard probably corrupt frames */ 1863 while (!(dnetp->rx_desc[index].desc0.own)) { 1864 dnetp->rx_desc[index].desc0.own = 1; 1865 index = (index+1) % dnetp->max_rx_desc; 1866 dnetp->stat_missed++; 1867 } 1868 1869 /* restart the receiver */ 1870 opn = ddi_get32(dnetp->io_handle, 1871 REG32(dnetp->io_reg, OPN_MODE_REG)); 1872 ddi_put32(dnetp->io_handle, 1873 REG32(dnetp->io_reg, OPN_MODE_REG), 1874 opn | START_RECEIVE); 1875 marker = dnetp->rx_current_desc = index; 1876 continue; 1877 } 1878 /* 1879 * At this point, we know that all packets before 1880 * "marker" were received before a dma overrun occurred 1881 */ 1882 } 1883 1884 /* 1885 * If we get an oversized packet it could span multiple 1886 * descriptors. If this happens an error bit should be set. 1887 */ 1888 while (desc[index].desc0.last_desc == 0) { 1889 index = (index + 1) % dnetp->max_rx_desc; 1890 if (desc[index].desc0.own) 1891 return; /* not done receiving large packet */ 1892 } 1893 while (dnetp->rx_current_desc != index) { 1894 desc[dnetp->rx_current_desc].desc0.own = 1; 1895 dnetp->rx_current_desc = 1896 (dnetp->rx_current_desc + 1) % dnetp->max_rx_desc; 1897 #ifdef DNETDEBUG 1898 if (dnetdebug & DNETRECV) 1899 cmn_err(CE_WARN, "dnet: received large packet"); 1900 #endif 1901 } 1902 1903 packet_length = desc[index].desc0.frame_len; 1904 1905 /* 1906 * Remove CRC from received data. This is an artefact of the 1907 * 21x4x chip and should not be passed higher up the network 1908 * stack. 1909 */ 1910 packet_length -= ETHERFCSL; 1911 1912 #ifdef DNETDEBUG 1913 if (dnetdebug & DNETRECV) { 1914 if (packet_length > ETHERMAX) 1915 cmn_err(CE_WARN, "dnet: large packet size %d", 1916 packet_length); 1917 } 1918 #endif 1919 1920 /* get the virtual address of the packet received */ 1921 virtual_address = 1922 dnetp->rx_buf_vaddr[index]; 1923 1924 /* 1925 * If no packet errors then do: 1926 * 1. Allocate a new receive buffer so that we can 1927 * use the current buffer as streams buffer to 1928 * avoid bcopy. 1929 * 2. If we got a new receive buffer then allocate 1930 * an mblk using desballoc(). 1931 * 3. Otherwise use the mblk from allocb() and do 1932 * the bcopy. 1933 */ 1934 frp = NULL; 1935 rp = NULL; 1936 newbuf = NULL; 1937 mp = NULL; 1938 if (!desc[index].desc0.err_summary) { 1939 ASSERT(packet_length < rx_buf_size); 1940 /* 1941 * Allocate another receive buffer for this descriptor. 1942 * If we fail to allocate then we do the normal bcopy. 1943 */ 1944 rp = dnet_rbuf_alloc(dnetp->devinfo, 0); 1945 if (rp != NULL) { 1946 newbuf = rp->rbuf_vaddr; 1947 frp = kmem_zalloc(sizeof (*frp), KM_NOSLEEP); 1948 if (frp != NULL) { 1949 frp->free_rtn.free_func = 1950 dnet_freemsg_buf; 1951 frp->free_rtn.free_arg = (char *)frp; 1952 frp->buf = virtual_address; 1953 mp = desballoc( 1954 (uchar_t *)virtual_address, 1955 packet_length, 0, &frp->free_rtn); 1956 if (mp == NULL) { 1957 kmem_free(frp, sizeof (*frp)); 1958 dnet_rbuf_free((caddr_t)newbuf); 1959 frp = NULL; 1960 newbuf = NULL; 1961 } 1962 } 1963 } 1964 if (mp == NULL) { 1965 if (newbuf != NULL) 1966 dnet_rbuf_free((caddr_t)newbuf); 1967 mp = allocb(packet_length, 0); 1968 } 1969 } 1970 1971 if (desc[index].desc0.err_summary || (mp == NULL)) { 1972 1973 /* Update gld statistics */ 1974 if (desc[index].desc0.err_summary) 1975 update_rx_stats(macinfo, index); 1976 else 1977 dnetp->stat_norcvbuf++; 1978 1979 /* 1980 * Reset ownership of the descriptor. 1981 */ 1982 desc[index].desc0.own = 1; 1983 dnetp->rx_current_desc = 1984 (dnetp->rx_current_desc+1) % dnetp->max_rx_desc; 1985 1986 /* Demand receive polling by the chip */ 1987 ddi_put32(dnetp->io_handle, 1988 REG32(dnetp->io_reg, RX_POLL_REG), RX_POLL_DEMAND); 1989 1990 continue; 1991 } 1992 1993 if (newbuf != NULL) { 1994 uint32_t end_paddr; 1995 /* attach the new buffer to the rx descriptor */ 1996 dnetp->rx_buf_vaddr[index] = newbuf; 1997 dnetp->rx_buf_paddr[index] = rp->rbuf_paddr; 1998 desc[index].buffer1 = rp->rbuf_paddr; 1999 desc[index].desc1.buffer_size1 = rx_buf_size; 2000 desc[index].desc1.buffer_size2 = 0; 2001 end_paddr = rp->rbuf_endpaddr; 2002 if ((desc[index].buffer1 & ~dnetp->pgmask) != 2003 (end_paddr & ~dnetp->pgmask)) { 2004 /* discontiguous */ 2005 desc[index].buffer2 = end_paddr&~dnetp->pgmask; 2006 desc[index].desc1.buffer_size2 = 2007 (end_paddr & dnetp->pgmask) + 1; 2008 desc[index].desc1.buffer_size1 = 2009 rx_buf_size-desc[index].desc1.buffer_size2; 2010 } 2011 } else { 2012 /* couldn't allocate another buffer; copy the data */ 2013 BCOPY((caddr_t)virtual_address, (caddr_t)mp->b_wptr, 2014 packet_length); 2015 } 2016 2017 mp->b_wptr += packet_length; 2018 2019 desc[dnetp->rx_current_desc].desc0.own = 1; 2020 2021 /* 2022 * Increment receive desc index. This is for the scan of 2023 * next packet 2024 */ 2025 dnetp->rx_current_desc = 2026 (dnetp->rx_current_desc+1) % dnetp->max_rx_desc; 2027 2028 /* Demand polling by chip */ 2029 ddi_put32(dnetp->io_handle, 2030 REG32(dnetp->io_reg, RX_POLL_REG), RX_POLL_DEMAND); 2031 2032 /* send the packet upstream */ 2033 mutex_exit(&dnetp->intrlock); 2034 gld_recv(macinfo, mp); 2035 mutex_enter(&dnetp->intrlock); 2036 } 2037 } 2038 /* 2039 * Function to update receive statistics 2040 */ 2041 static void 2042 update_rx_stats(gld_mac_info_t *macinfo, int index) 2043 { 2044 struct dnetinstance *dnetp = 2045 (struct dnetinstance *)macinfo->gldm_private; 2046 struct rx_desc_type *descp = &(dnetp->rx_desc[index]); 2047 2048 /* 2049 * Update gld statistics 2050 */ 2051 dnetp->stat_errrcv++; 2052 2053 if (descp->desc0.overflow) { 2054 /* FIFO Overrun */ 2055 dnetp->stat_overflow++; 2056 } 2057 2058 if (descp->desc0.collision) { 2059 /*EMPTY*/ 2060 /* Late Colllision on receive */ 2061 /* no appropriate counter */ 2062 } 2063 2064 if (descp->desc0.crc) { 2065 /* CRC Error */ 2066 dnetp->stat_crc++; 2067 } 2068 2069 if (descp->desc0.runt_frame) { 2070 /* Runt Error */ 2071 dnetp->stat_short++; 2072 } 2073 2074 if (descp->desc0.desc_err) { 2075 /*EMPTY*/ 2076 /* Not enough receive descriptors */ 2077 /* This condition is accounted in dnetintr() */ 2078 /* macinfo->gldm_stats.glds_missed++; */ 2079 } 2080 2081 if (descp->desc0.frame2long) { 2082 dnetp->stat_frame++; 2083 } 2084 } 2085 2086 /* 2087 * Function to update transmit statistics 2088 */ 2089 static void 2090 update_tx_stats(gld_mac_info_t *macinfo, int index) 2091 { 2092 struct dnetinstance *dnetp = 2093 (struct dnetinstance *)macinfo->gldm_private; 2094 struct tx_desc_type *descp = &(dnetp->tx_desc[index]); 2095 int fd; 2096 media_block_t *block = dnetp->selected_media_block; 2097 2098 2099 /* Update gld statistics */ 2100 dnetp->stat_errxmt++; 2101 2102 /* If we're in full-duplex don't count collisions or carrier loss. */ 2103 if (dnetp->mii_up) { 2104 fd = dnetp->mii_duplex; 2105 } else { 2106 /* Rely on media code */ 2107 fd = block->media_code == MEDIA_TP_FD || 2108 block->media_code == MEDIA_SYM_SCR_FD; 2109 } 2110 2111 if (descp->desc0.collision_count && !fd) { 2112 dnetp->stat_collisions += descp->desc0.collision_count; 2113 } 2114 2115 if (descp->desc0.late_collision && !fd) { 2116 dnetp->stat_xmtlatecoll++; 2117 } 2118 2119 if (descp->desc0.excess_collision && !fd) { 2120 dnetp->stat_excoll++; 2121 } 2122 2123 if (descp->desc0.underflow) { 2124 dnetp->stat_underflow++; 2125 } 2126 2127 #if 0 2128 if (descp->desc0.tx_jabber_to) { 2129 /* no appropriate counter */ 2130 } 2131 #endif 2132 2133 if (descp->desc0.carrier_loss && !fd) { 2134 dnetp->stat_nocarrier++; 2135 } 2136 2137 if (descp->desc0.no_carrier && !fd) { 2138 dnetp->stat_nocarrier++; 2139 } 2140 } 2141 2142 /* 2143 * ========== Media Selection Setup Routines ========== 2144 */ 2145 2146 2147 static void 2148 write_gpr(struct dnetinstance *dnetp, uint32_t val) 2149 { 2150 #ifdef DEBUG 2151 if (dnetdebug & DNETREGCFG) 2152 cmn_err(CE_NOTE, "GPR: %x", val); 2153 #endif 2154 switch (dnetp->board_type) { 2155 case DEVICE_ID_21143: 2156 /* Set the correct bit for a control write */ 2157 if (val & GPR_CONTROL_WRITE) 2158 val |= CWE_21143, val &= ~GPR_CONTROL_WRITE; 2159 /* Write to upper half of CSR15 */ 2160 dnetp->gprsia = (dnetp->gprsia & 0xffff) | (val << 16); 2161 ddi_put32(dnetp->io_handle, 2162 REG32(dnetp->io_reg, SIA_GENERAL_REG), dnetp->gprsia); 2163 break; 2164 default: 2165 /* Set the correct bit for a control write */ 2166 if (val & GPR_CONTROL_WRITE) 2167 val |= CWE_21140, val &= ~GPR_CONTROL_WRITE; 2168 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, GP_REG), val); 2169 break; 2170 } 2171 } 2172 2173 static uint32_t 2174 read_gpr(struct dnetinstance *dnetp) 2175 { 2176 switch (dnetp->board_type) { 2177 case DEVICE_ID_21143: 2178 /* Read upper half of CSR15 */ 2179 return (ddi_get32(dnetp->io_handle, 2180 REG32(dnetp->io_reg, SIA_GENERAL_REG)) >> 16); 2181 default: 2182 return (ddi_get32(dnetp->io_handle, 2183 REG32(dnetp->io_reg, GP_REG))); 2184 } 2185 } 2186 2187 static void 2188 set_gpr(gld_mac_info_t *macinfo) 2189 { 2190 uint32_t *sequence; 2191 int len; 2192 struct dnetinstance *dnetp = (struct dnetinstance *) 2193 macinfo->gldm_private; 2194 LEAF_FORMAT *leaf = &dnetp->sr.leaf[dnetp->leaf]; 2195 media_block_t *block = dnetp->selected_media_block; 2196 int i; 2197 2198 if (ddi_getlongprop(DDI_DEV_T_ANY, dnetp->devinfo, 2199 DDI_PROP_DONTPASS, "gpr-sequence", (caddr_t)&sequence, 2200 &len) == DDI_PROP_SUCCESS) { 2201 for (i = 0; i < len / sizeof (uint32_t); i++) 2202 write_gpr(dnetp, sequence[i]); 2203 kmem_free(sequence, len); 2204 } else { 2205 /* 2206 * Write the reset sequence if this is the first time this 2207 * block has been selected. 2208 */ 2209 if (block->rstseqlen) { 2210 for (i = 0; i < block->rstseqlen; i++) 2211 write_gpr(dnetp, block->rstseq[i]); 2212 /* 2213 * XXX Legacy blocks do not have reset sequences, so the 2214 * static blocks will never be modified by this 2215 */ 2216 block->rstseqlen = 0; 2217 } 2218 if (leaf->gpr) 2219 write_gpr(dnetp, leaf->gpr | GPR_CONTROL_WRITE); 2220 2221 /* write GPR sequence each time */ 2222 for (i = 0; i < block->gprseqlen; i++) 2223 write_gpr(dnetp, block->gprseq[i]); 2224 } 2225 2226 /* This has possibly caused a PHY to reset. Let MII know */ 2227 if (dnetp->phyaddr != -1) 2228 /* XXX function return value ignored */ 2229 (void) mii_sync(dnetp->mii, dnetp->phyaddr); 2230 drv_usecwait(5); 2231 } 2232 2233 /* set_opr() - must be called with intrlock held */ 2234 2235 static void 2236 set_opr(gld_mac_info_t *macinfo) 2237 { 2238 uint32_t fd, mb1, sf; 2239 2240 struct dnetinstance *dnetp = 2241 (struct dnetinstance *)macinfo->gldm_private; 2242 int opnmode_len; 2243 uint32_t val; 2244 media_block_t *block = dnetp->selected_media_block; 2245 2246 ASSERT(block); 2247 2248 /* Check for custom "opnmode_reg" property */ 2249 opnmode_len = sizeof (val); 2250 if (ddi_prop_op(DDI_DEV_T_ANY, dnetp->devinfo, 2251 PROP_LEN_AND_VAL_BUF, DDI_PROP_DONTPASS, "opnmode_reg", 2252 (caddr_t)&val, &opnmode_len) != DDI_PROP_SUCCESS) 2253 opnmode_len = 0; 2254 2255 /* Some bits exist only on 21140 and greater */ 2256 if (dnetp->board_type != DEVICE_ID_21040 && 2257 dnetp->board_type != DEVICE_ID_21041) { 2258 mb1 = OPN_REG_MB1; 2259 sf = STORE_AND_FORWARD; 2260 } else { 2261 mb1 = sf = 0; 2262 mb1 = OPN_REG_MB1; /* Needed for 21040? */ 2263 } 2264 2265 if (opnmode_len) { 2266 ddi_put32(dnetp->io_handle, 2267 REG32(dnetp->io_reg, OPN_MODE_REG), val); 2268 dnet_reset_board(macinfo); 2269 ddi_put32(dnetp->io_handle, 2270 REG32(dnetp->io_reg, OPN_MODE_REG), val); 2271 return; 2272 } 2273 2274 /* 2275 * Set each bit in CSR6 that we want 2276 */ 2277 2278 /* Always want these bits set */ 2279 val = HASH_FILTERING | HASH_ONLY | TX_THRESHOLD_160 | mb1 | sf; 2280 2281 /* Promiscuous mode */ 2282 val |= dnetp->promisc ? PROM_MODE : 0; 2283 2284 /* Scrambler for SYM style media */ 2285 val |= ((block->command & CMD_SCR) && !dnetp->disable_scrambler) ? 2286 SCRAMBLER_MODE : 0; 2287 2288 /* Full duplex */ 2289 if (dnetp->mii_up) { 2290 fd = dnetp->mii_duplex; 2291 } else { 2292 /* Rely on media code */ 2293 fd = block->media_code == MEDIA_TP_FD || 2294 block->media_code == MEDIA_SYM_SCR_FD; 2295 } 2296 2297 /* Port select (and therefore, heartbeat disable) */ 2298 val |= block->command & CMD_PS ? (PORT_SELECT | HEARTBEAT_DISABLE) : 0; 2299 2300 /* PCS function */ 2301 val |= (block->command) & CMD_PCS ? PCS_FUNCTION : 0; 2302 val |= fd ? FULL_DUPLEX : 0; 2303 2304 #ifdef DNETDEBUG 2305 if (dnetdebug & DNETREGCFG) 2306 cmn_err(CE_NOTE, "OPN: %x", val); 2307 #endif 2308 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG), val); 2309 dnet_reset_board(macinfo); 2310 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG), val); 2311 } 2312 2313 static void 2314 set_sia(gld_mac_info_t *macinfo) 2315 { 2316 struct dnetinstance *dnetp = (struct dnetinstance *) 2317 (macinfo->gldm_private); 2318 media_block_t *block = dnetp->selected_media_block; 2319 2320 ASSERT(MUTEX_HELD(&dnetp->intrlock)); 2321 if (block->type == 2) { 2322 int sia_delay; 2323 #ifdef DNETDEBUG 2324 if (dnetdebug & DNETREGCFG) 2325 cmn_err(CE_NOTE, 2326 "SIA: CSR13: %x, CSR14: %x, CSR15: %x", 2327 block->un.sia.csr13, 2328 block->un.sia.csr14, 2329 block->un.sia.csr15); 2330 #endif 2331 sia_delay = ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo, 2332 DDI_PROP_DONTPASS, "sia-delay", 10000); 2333 2334 ddi_put32(dnetp->io_handle, 2335 REG32(dnetp->io_reg, SIA_CONNECT_REG), 0); 2336 2337 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, SIA_TXRX_REG), 2338 block->un.sia.csr14); 2339 2340 /* 2341 * For '143, we need to write through a copy of the register 2342 * to keep the GP half intact 2343 */ 2344 dnetp->gprsia = (dnetp->gprsia&0xffff0000)|block->un.sia.csr15; 2345 ddi_put32(dnetp->io_handle, 2346 REG32(dnetp->io_reg, SIA_GENERAL_REG), 2347 dnetp->gprsia); 2348 2349 ddi_put32(dnetp->io_handle, 2350 REG32(dnetp->io_reg, SIA_CONNECT_REG), 2351 block->un.sia.csr13); 2352 2353 drv_usecwait(sia_delay); 2354 2355 } else if (dnetp->board_type != DEVICE_ID_21140) { 2356 ddi_put32(dnetp->io_handle, 2357 REG32(dnetp->io_reg, SIA_CONNECT_REG), 0); 2358 ddi_put32(dnetp->io_handle, 2359 REG32(dnetp->io_reg, SIA_TXRX_REG), 0); 2360 } 2361 } 2362 2363 /* 2364 * ========== Buffer Management Routines ========== 2365 */ 2366 2367 /* 2368 * This function (re)allocates the receive and transmit buffers and 2369 * descriptors. It can be called more than once per instance, though 2370 * currently it is only called from attach. It should only be called 2371 * while the device is reset. 2372 */ 2373 static int 2374 dnet_alloc_bufs(gld_mac_info_t *macinfo) 2375 { 2376 struct dnetinstance *dnetp = (struct dnetinstance *) 2377 (macinfo->gldm_private); 2378 int i; 2379 size_t len; 2380 int page_size; 2381 int realloc = 0; 2382 int nrecv_desc_old = 0; 2383 ddi_dma_cookie_t cookie; 2384 uint_t ncookies; 2385 2386 /* 2387 * check if we are trying to reallocate with different xmit/recv 2388 * descriptor ring sizes. 2389 */ 2390 if ((dnetp->tx_desc != NULL) && 2391 (dnetp->nxmit_desc != dnetp->max_tx_desc)) 2392 realloc = 1; 2393 2394 if ((dnetp->rx_desc != NULL) && 2395 (dnetp->nrecv_desc != dnetp->max_rx_desc)) 2396 realloc = 1; 2397 2398 /* free up the old buffers if we are reallocating them */ 2399 if (realloc) { 2400 nrecv_desc_old = dnetp->nrecv_desc; 2401 dnet_free_bufs(macinfo); /* free the old buffers */ 2402 } 2403 2404 if (dnetp->dma_handle == NULL) 2405 if (ddi_dma_alloc_handle(dnetp->devinfo, &dma_attr, 2406 DDI_DMA_SLEEP, 0, &dnetp->dma_handle) != DDI_SUCCESS) 2407 return (FAILURE); 2408 2409 if (dnetp->dma_handle_tx == NULL) 2410 if (ddi_dma_alloc_handle(dnetp->devinfo, &dma_attr_tx, 2411 DDI_DMA_SLEEP, 0, &dnetp->dma_handle_tx) != DDI_SUCCESS) 2412 return (FAILURE); 2413 2414 if (dnetp->dma_handle_txdesc == NULL) 2415 if (ddi_dma_alloc_handle(dnetp->devinfo, &dma_attr, 2416 DDI_DMA_SLEEP, 0, &dnetp->dma_handle_txdesc) != DDI_SUCCESS) 2417 return (FAILURE); 2418 2419 if (dnetp->dma_handle_setbuf == NULL) 2420 if (ddi_dma_alloc_handle(dnetp->devinfo, &dma_attr, 2421 DDI_DMA_SLEEP, 0, &dnetp->dma_handle_setbuf) != DDI_SUCCESS) 2422 return (FAILURE); 2423 2424 page_size = ddi_ptob(dnetp->devinfo, 1); 2425 2426 dnetp->pgmask = page_size - 1; 2427 2428 /* allocate setup buffer if necessary */ 2429 if (dnetp->setup_buf_vaddr == NULL) { 2430 if (ddi_dma_mem_alloc(dnetp->dma_handle_setbuf, 2431 SETUPBUF_SIZE, &accattr, DDI_DMA_STREAMING, 2432 DDI_DMA_DONTWAIT, 0, (caddr_t *)&dnetp->setup_buf_vaddr, 2433 &len, &dnetp->setup_buf_acchdl) != DDI_SUCCESS) 2434 return (FAILURE); 2435 2436 if (ddi_dma_addr_bind_handle(dnetp->dma_handle_setbuf, 2437 NULL, dnetp->setup_buf_vaddr, SETUPBUF_SIZE, 2438 DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP, 2439 NULL, &cookie, &ncookies) != DDI_DMA_MAPPED) 2440 return (FAILURE); 2441 2442 dnetp->setup_buf_paddr = cookie.dmac_address; 2443 bzero(dnetp->setup_buf_vaddr, len); 2444 } 2445 2446 /* allocate xmit descriptor array of size dnetp->max_tx_desc */ 2447 if (dnetp->tx_desc == NULL) { 2448 if (ddi_dma_mem_alloc(dnetp->dma_handle_txdesc, 2449 sizeof (struct tx_desc_type) * dnetp->max_tx_desc, 2450 &accattr, DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0, 2451 (caddr_t *)&dnetp->tx_desc, &len, 2452 &dnetp->tx_desc_acchdl) != DDI_SUCCESS) 2453 return (FAILURE); 2454 2455 if (ddi_dma_addr_bind_handle(dnetp->dma_handle_txdesc, 2456 NULL, (caddr_t)dnetp->tx_desc, 2457 sizeof (struct tx_desc_type) * dnetp->max_tx_desc, 2458 DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP, 2459 NULL, &cookie, &ncookies) != DDI_DMA_MAPPED) 2460 return (FAILURE); 2461 dnetp->tx_desc_paddr = cookie.dmac_address; 2462 bzero(dnetp->tx_desc, len); 2463 dnetp->nxmit_desc = dnetp->max_tx_desc; 2464 2465 dnetp->tx_msgbufp = 2466 kmem_zalloc(dnetp->max_tx_desc * sizeof (mblk_t **), 2467 KM_SLEEP); 2468 } 2469 2470 /* allocate receive descriptor array of size dnetp->max_rx_desc */ 2471 if (dnetp->rx_desc == NULL) { 2472 int ndesc; 2473 2474 if (ddi_dma_mem_alloc(dnetp->dma_handle, 2475 sizeof (struct rx_desc_type) * dnetp->max_rx_desc, 2476 &accattr, DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0, 2477 (caddr_t *)&dnetp->rx_desc, &len, 2478 &dnetp->rx_desc_acchdl) != DDI_SUCCESS) 2479 return (FAILURE); 2480 2481 if (ddi_dma_addr_bind_handle(dnetp->dma_handle, 2482 NULL, (caddr_t)dnetp->rx_desc, 2483 sizeof (struct rx_desc_type) * dnetp->max_rx_desc, 2484 DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP, 2485 NULL, &cookie, &ncookies) != DDI_DMA_MAPPED) 2486 return (FAILURE); 2487 2488 dnetp->rx_desc_paddr = cookie.dmac_address; 2489 bzero(dnetp->rx_desc, len); 2490 dnetp->nrecv_desc = dnetp->max_rx_desc; 2491 2492 dnetp->rx_buf_vaddr = 2493 kmem_zalloc(dnetp->max_rx_desc * sizeof (caddr_t), 2494 KM_SLEEP); 2495 dnetp->rx_buf_paddr = 2496 kmem_zalloc(dnetp->max_rx_desc * sizeof (uint32_t), 2497 KM_SLEEP); 2498 /* 2499 * Allocate or add to the pool of receive buffers. The pool 2500 * is shared among all instances of dnet. 2501 * 2502 * XXX NEEDSWORK 2503 * 2504 * We arbitrarily allocate twice as many receive buffers as 2505 * receive descriptors because we use the buffers for streams 2506 * messages to pass the packets up the stream. We should 2507 * instead have initialized constants reflecting 2508 * MAX_RX_BUF_2104x and MAX_RX_BUF_2114x, and we should also 2509 * probably have a total maximum for the free pool, so that we 2510 * don't get out of hand when someone puts in an 8-port board. 2511 * The maximum for the entire pool should be the total number 2512 * of descriptors for all attached instances together, plus the 2513 * total maximum for the free pool. This maximum would only be 2514 * reached after some number of instances allocate buffers: 2515 * each instance would add (max_rx_buf-max_rx_desc) to the free 2516 * pool. 2517 */ 2518 ndesc = dnetp->max_rx_desc - nrecv_desc_old; 2519 if ((ndesc > 0) && 2520 (dnet_rbuf_init(dnetp->devinfo, ndesc * 2) != 0)) 2521 return (FAILURE); 2522 2523 for (i = 0; i < dnetp->max_rx_desc; i++) { 2524 struct rbuf_list *rp; 2525 2526 rp = dnet_rbuf_alloc(dnetp->devinfo, 1); 2527 if (rp == NULL) 2528 return (FAILURE); 2529 dnetp->rx_buf_vaddr[i] = rp->rbuf_vaddr; 2530 dnetp->rx_buf_paddr[i] = rp->rbuf_paddr; 2531 } 2532 } 2533 2534 return (SUCCESS); 2535 } 2536 /* 2537 * free descriptors/buffers allocated for this device instance. This routine 2538 * should only be called while the device is reset. 2539 */ 2540 static void 2541 dnet_free_bufs(gld_mac_info_t *macinfo) 2542 { 2543 int i; 2544 struct dnetinstance *dnetp = (struct dnetinstance *) 2545 (macinfo->gldm_private); 2546 /* free up any xmit descriptors/buffers */ 2547 if (dnetp->tx_desc != NULL) { 2548 ddi_dma_mem_free(&dnetp->tx_desc_acchdl); 2549 dnetp->tx_desc = NULL; 2550 /* we use streams buffers for DMA in xmit process */ 2551 if (dnetp->tx_msgbufp != NULL) { 2552 /* free up any streams message buffers unclaimed */ 2553 for (i = 0; i < dnetp->nxmit_desc; i++) { 2554 if (dnetp->tx_msgbufp[i] != NULL) { 2555 freemsg(dnetp->tx_msgbufp[i]); 2556 } 2557 } 2558 kmem_free(dnetp->tx_msgbufp, 2559 dnetp->nxmit_desc * sizeof (mblk_t **)); 2560 dnetp->tx_msgbufp = NULL; 2561 } 2562 dnetp->nxmit_desc = 0; 2563 } 2564 2565 /* free up any receive descriptors/buffers */ 2566 if (dnetp->rx_desc != NULL) { 2567 ddi_dma_mem_free(&dnetp->rx_desc_acchdl); 2568 dnetp->rx_desc = NULL; 2569 if (dnetp->rx_buf_vaddr != NULL) { 2570 /* free up the attached rbufs if any */ 2571 for (i = 0; i < dnetp->nrecv_desc; i++) { 2572 if (dnetp->rx_buf_vaddr[i]) 2573 dnet_rbuf_free( 2574 (caddr_t)dnetp->rx_buf_vaddr[i]); 2575 } 2576 kmem_free(dnetp->rx_buf_vaddr, 2577 dnetp->nrecv_desc * sizeof (caddr_t)); 2578 kmem_free(dnetp->rx_buf_paddr, 2579 dnetp->nrecv_desc * sizeof (uint32_t)); 2580 dnetp->rx_buf_vaddr = NULL; 2581 dnetp->rx_buf_paddr = NULL; 2582 } 2583 dnetp->nrecv_desc = 0; 2584 } 2585 2586 if (dnetp->setup_buf_vaddr != NULL) { 2587 ddi_dma_mem_free(&dnetp->setup_buf_acchdl); 2588 dnetp->setup_buf_vaddr = NULL; 2589 } 2590 2591 if (dnetp->dma_handle != NULL) { 2592 (void) ddi_dma_unbind_handle(dnetp->dma_handle); 2593 ddi_dma_free_handle(&dnetp->dma_handle); 2594 dnetp->dma_handle = NULL; 2595 } 2596 2597 if (dnetp->dma_handle_tx != NULL) { 2598 (void) ddi_dma_unbind_handle(dnetp->dma_handle_tx); 2599 ddi_dma_free_handle(&dnetp->dma_handle_tx); 2600 dnetp->dma_handle_tx = NULL; 2601 } 2602 2603 if (dnetp->dma_handle_txdesc != NULL) { 2604 (void) ddi_dma_unbind_handle(dnetp->dma_handle_txdesc); 2605 ddi_dma_free_handle(&dnetp->dma_handle_txdesc); 2606 dnetp->dma_handle_txdesc = NULL; 2607 } 2608 2609 if (dnetp->dma_handle_setbuf != NULL) { 2610 (void) ddi_dma_unbind_handle(dnetp->dma_handle_setbuf); 2611 ddi_dma_free_handle(&dnetp->dma_handle_setbuf); 2612 dnetp->dma_handle_setbuf = NULL; 2613 } 2614 2615 } 2616 2617 /* 2618 * Initialize transmit and receive descriptors. 2619 */ 2620 static void 2621 dnet_init_txrx_bufs(gld_mac_info_t *macinfo) 2622 { 2623 int i; 2624 struct dnetinstance *dnetp = (struct dnetinstance *) 2625 (macinfo->gldm_private); 2626 2627 /* 2628 * Initilize all the Tx descriptors 2629 */ 2630 for (i = 0; i < dnetp->nxmit_desc; i++) { 2631 /* 2632 * We may be resetting the device due to errors, 2633 * so free up any streams message buffer unclaimed. 2634 */ 2635 if (dnetp->tx_msgbufp[i] != NULL) { 2636 freemsg(dnetp->tx_msgbufp[i]); 2637 dnetp->tx_msgbufp[i] = NULL; 2638 } 2639 *(uint32_t *)&dnetp->tx_desc[i].desc0 = 0; 2640 *(uint32_t *)&dnetp->tx_desc[i].desc1 = 0; 2641 dnetp->tx_desc[i].buffer1 = 0; 2642 dnetp->tx_desc[i].buffer2 = 0; 2643 } 2644 dnetp->tx_desc[i - 1].desc1.end_of_ring = 1; 2645 2646 /* 2647 * Initialize the Rx descriptors 2648 */ 2649 for (i = 0; i < dnetp->nrecv_desc; i++) { 2650 uint32_t end_paddr; 2651 *(uint32_t *)&dnetp->rx_desc[i].desc0 = 0; 2652 *(uint32_t *)&dnetp->rx_desc[i].desc1 = 0; 2653 dnetp->rx_desc[i].desc0.own = 1; 2654 dnetp->rx_desc[i].desc1.buffer_size1 = rx_buf_size; 2655 dnetp->rx_desc[i].buffer1 = dnetp->rx_buf_paddr[i]; 2656 dnetp->rx_desc[i].buffer2 = 0; 2657 end_paddr = dnetp->rx_buf_paddr[i]+rx_buf_size-1; 2658 2659 if ((dnetp->rx_desc[i].buffer1 & ~dnetp->pgmask) != 2660 (end_paddr & ~dnetp->pgmask)) { 2661 /* discontiguous */ 2662 dnetp->rx_desc[i].buffer2 = end_paddr&~dnetp->pgmask; 2663 dnetp->rx_desc[i].desc1.buffer_size2 = 2664 (end_paddr & dnetp->pgmask) + 1; 2665 dnetp->rx_desc[i].desc1.buffer_size1 = 2666 rx_buf_size-dnetp->rx_desc[i].desc1.buffer_size2; 2667 } 2668 } 2669 dnetp->rx_desc[i - 1].desc1.end_of_ring = 1; 2670 } 2671 2672 static int 2673 alloc_descriptor(gld_mac_info_t *macinfo) 2674 { 2675 int index; 2676 struct dnetinstance *dnetp = /* Our private device info */ 2677 (struct dnetinstance *)macinfo->gldm_private; 2678 struct tx_desc_type *ring = dnetp->tx_desc; 2679 2680 ASSERT(MUTEX_HELD(&dnetp->intrlock)); 2681 alloctop: 2682 mutex_enter(&dnetp->txlock); 2683 index = dnetp->tx_current_desc; 2684 2685 dnet_reclaim_Tx_desc(macinfo); 2686 2687 /* we do have free descriptors, right? */ 2688 if (dnetp->free_desc <= 0) { 2689 #ifdef DNETDEBUG 2690 if (dnetdebug & DNETRECV) 2691 cmn_err(CE_NOTE, "dnet: Ring buffer is full"); 2692 #endif 2693 mutex_exit(&dnetp->txlock); 2694 return (FAILURE); 2695 } 2696 2697 /* sanity, make sure the next descriptor is free for use (should be) */ 2698 if (ring[index].desc0.own) { 2699 #ifdef DNETDEBUG 2700 if (dnetdebug & DNETRECV) 2701 cmn_err(CE_WARN, 2702 "dnet: next descriptor is not free for use"); 2703 #endif 2704 mutex_exit(&dnetp->txlock); 2705 return (FAILURE); 2706 } 2707 if (dnetp->need_saddr) { 2708 mutex_exit(&dnetp->txlock); 2709 /* XXX function return value ignored */ 2710 if (!dnetp->suspended) 2711 (void) dnet_set_addr(macinfo); 2712 goto alloctop; 2713 } 2714 2715 *(uint32_t *)&ring[index].desc0 = 0; /* init descs */ 2716 *(uint32_t *)&ring[index].desc1 &= DNET_END_OF_RING; 2717 2718 /* hardware will own this descriptor when poll activated */ 2719 dnetp->free_desc--; 2720 2721 /* point to next free descriptor to be used */ 2722 dnetp->tx_current_desc = NextTXIndex(index); 2723 2724 #ifdef DNET_NOISY 2725 cmn_err(CE_WARN, "sfree 0x%x, transmitted 0x%x, tx_current 0x%x", 2726 dnetp->free_desc, dnetp->transmitted_desc, dnetp->tx_current_desc); 2727 #endif 2728 mutex_exit(&dnetp->txlock); 2729 return (SUCCESS); 2730 } 2731 2732 /* 2733 * dnet_reclaim_Tx_desc() - called with txlock held. 2734 */ 2735 static void 2736 dnet_reclaim_Tx_desc(gld_mac_info_t *macinfo) 2737 { 2738 struct dnetinstance *dnetp = (struct dnetinstance *) 2739 (macinfo->gldm_private); 2740 struct tx_desc_type *desc = dnetp->tx_desc; 2741 int index; 2742 2743 ASSERT(MUTEX_HELD(&dnetp->txlock)); 2744 #ifdef DNETDEBUG 2745 if (dnetdebug & DNETTRACE) 2746 cmn_err(CE_NOTE, "dnet_reclaim_Tx_desc(0x%p)", 2747 (void *) macinfo); 2748 #endif 2749 2750 index = dnetp->transmitted_desc; 2751 while (((dnetp->free_desc == 0) || (index != dnetp->tx_current_desc)) && 2752 !(desc[index].desc0.own)) { 2753 /* 2754 * Check for Tx Error that gets set 2755 * in the last desc. 2756 */ 2757 if (desc[index].desc1.setup_packet == 0 && 2758 desc[index].desc1.last_desc && 2759 desc[index].desc0.err_summary) 2760 update_tx_stats(macinfo, index); 2761 2762 /* 2763 * If we have used the streams message buffer for this 2764 * descriptor then free up the message now. 2765 */ 2766 if (dnetp->tx_msgbufp[index] != NULL) { 2767 freemsg(dnetp->tx_msgbufp[index]); 2768 dnetp->tx_msgbufp[index] = NULL; 2769 } 2770 dnetp->free_desc++; 2771 index = (index+1) % dnetp->max_tx_desc; 2772 } 2773 2774 dnetp->transmitted_desc = index; 2775 } 2776 2777 /* 2778 * Receive buffer allocation/freeing routines. 2779 * 2780 * There is a common pool of receive buffers shared by all dnet instances. 2781 * 2782 * XXX NEEDSWORK 2783 * 2784 * We arbitrarily allocate twice as many receive buffers as 2785 * receive descriptors because we use the buffers for streams 2786 * messages to pass the packets up the stream. We should 2787 * instead have initialized constants reflecting 2788 * MAX_RX_BUF_2104x and MAX_RX_BUF_2114x, and we should also 2789 * probably have a total maximum for the free pool, so that we 2790 * don't get out of hand when someone puts in an 8-port board. 2791 * The maximum for the entire pool should be the total number 2792 * of descriptors for all attached instances together, plus the 2793 * total maximum for the free pool. This maximum would only be 2794 * reached after some number of instances allocate buffers: 2795 * each instance would add (max_rx_buf-max_rx_desc) to the free 2796 * pool. 2797 */ 2798 2799 static struct rbuf_list *rbuf_usedlist_head; 2800 static struct rbuf_list *rbuf_freelist_head; 2801 static struct rbuf_list *rbuf_usedlist_end; /* last buffer allocated */ 2802 2803 static int rbuf_freebufs; /* no. of free buffers in the pool */ 2804 static int rbuf_pool_size; /* total no. of buffers in the pool */ 2805 2806 /* initialize/add 'nbufs' buffers to the rbuf pool */ 2807 /* ARGSUSED */ 2808 static int 2809 dnet_rbuf_init(dev_info_t *dip, int nbufs) 2810 { 2811 int i; 2812 struct rbuf_list *rp; 2813 ddi_dma_cookie_t cookie; 2814 uint_t ncookies; 2815 size_t len; 2816 2817 mutex_enter(&dnet_rbuf_lock); 2818 2819 /* allocate buffers and add them to the pool */ 2820 for (i = 0; i < nbufs; i++) { 2821 /* allocate rbuf_list element */ 2822 rp = kmem_zalloc(sizeof (struct rbuf_list), KM_SLEEP); 2823 if (ddi_dma_alloc_handle(dip, &dma_attr_rb, DDI_DMA_SLEEP, 2824 0, &rp->rbuf_dmahdl) != DDI_SUCCESS) 2825 goto fail_kfree; 2826 2827 /* allocate dma memory for the buffer */ 2828 if (ddi_dma_mem_alloc(rp->rbuf_dmahdl, rx_buf_size, &accattr, 2829 DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0, 2830 &rp->rbuf_vaddr, &len, 2831 &rp->rbuf_acchdl) != DDI_SUCCESS) 2832 goto fail_freehdl; 2833 2834 if (ddi_dma_addr_bind_handle(rp->rbuf_dmahdl, NULL, 2835 rp->rbuf_vaddr, len, DDI_DMA_RDWR | DDI_DMA_STREAMING, 2836 DDI_DMA_SLEEP, NULL, &cookie, 2837 &ncookies) != DDI_DMA_MAPPED) 2838 goto fail_free; 2839 2840 if (ncookies > 2) 2841 goto fail_unbind; 2842 if (ncookies == 1) { 2843 rp->rbuf_endpaddr = 2844 cookie.dmac_address + rx_buf_size - 1; 2845 } else { 2846 ddi_dma_nextcookie(rp->rbuf_dmahdl, &cookie); 2847 rp->rbuf_endpaddr = 2848 cookie.dmac_address + cookie.dmac_size - 1; 2849 } 2850 rp->rbuf_paddr = cookie.dmac_address; 2851 2852 rp->rbuf_next = rbuf_freelist_head; 2853 rbuf_freelist_head = rp; 2854 rbuf_pool_size++; 2855 rbuf_freebufs++; 2856 } 2857 2858 mutex_exit(&dnet_rbuf_lock); 2859 return (0); 2860 fail_unbind: 2861 (void) ddi_dma_unbind_handle(rp->rbuf_dmahdl); 2862 fail_free: 2863 ddi_dma_mem_free(&rp->rbuf_acchdl); 2864 fail_freehdl: 2865 ddi_dma_free_handle(&rp->rbuf_dmahdl); 2866 fail_kfree: 2867 kmem_free(rp, sizeof (struct rbuf_list)); 2868 2869 mutex_exit(&dnet_rbuf_lock); 2870 return (-1); 2871 } 2872 2873 /* 2874 * Try to free up all the rbufs in the pool. Returns 0 if it frees up all 2875 * buffers. The buffers in the used list are considered busy so these 2876 * buffers are not freed. 2877 */ 2878 static int 2879 dnet_rbuf_destroy() 2880 { 2881 struct rbuf_list *rp, *next; 2882 2883 mutex_enter(&dnet_rbuf_lock); 2884 2885 for (rp = rbuf_freelist_head; rp; rp = next) { 2886 next = rp->rbuf_next; 2887 ddi_dma_mem_free(&rp->rbuf_acchdl); 2888 (void) ddi_dma_unbind_handle(rp->rbuf_dmahdl); 2889 kmem_free(rp, sizeof (struct rbuf_list)); 2890 rbuf_pool_size--; 2891 rbuf_freebufs--; 2892 } 2893 rbuf_freelist_head = NULL; 2894 2895 if (rbuf_pool_size) { /* pool is still not empty */ 2896 mutex_exit(&dnet_rbuf_lock); 2897 return (-1); 2898 } 2899 mutex_exit(&dnet_rbuf_lock); 2900 return (0); 2901 } 2902 static struct rbuf_list * 2903 dnet_rbuf_alloc(dev_info_t *dip, int cansleep) 2904 { 2905 struct rbuf_list *rp; 2906 size_t len; 2907 ddi_dma_cookie_t cookie; 2908 uint_t ncookies; 2909 2910 mutex_enter(&dnet_rbuf_lock); 2911 2912 if (rbuf_freelist_head == NULL) { 2913 2914 if (!cansleep) { 2915 mutex_exit(&dnet_rbuf_lock); 2916 return (NULL); 2917 } 2918 2919 /* allocate rbuf_list element */ 2920 rp = kmem_zalloc(sizeof (struct rbuf_list), KM_SLEEP); 2921 if (ddi_dma_alloc_handle(dip, &dma_attr_rb, DDI_DMA_SLEEP, 2922 0, &rp->rbuf_dmahdl) != DDI_SUCCESS) 2923 goto fail_kfree; 2924 2925 /* allocate dma memory for the buffer */ 2926 if (ddi_dma_mem_alloc(rp->rbuf_dmahdl, rx_buf_size, &accattr, 2927 DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0, 2928 &rp->rbuf_vaddr, &len, 2929 &rp->rbuf_acchdl) != DDI_SUCCESS) 2930 goto fail_freehdl; 2931 2932 if (ddi_dma_addr_bind_handle(rp->rbuf_dmahdl, NULL, 2933 rp->rbuf_vaddr, len, DDI_DMA_RDWR | DDI_DMA_STREAMING, 2934 DDI_DMA_SLEEP, NULL, &cookie, 2935 &ncookies) != DDI_DMA_MAPPED) 2936 goto fail_free; 2937 2938 if (ncookies > 2) 2939 goto fail_unbind; 2940 if (ncookies == 1) { 2941 rp->rbuf_endpaddr = 2942 cookie.dmac_address + rx_buf_size - 1; 2943 } else { 2944 ddi_dma_nextcookie(rp->rbuf_dmahdl, &cookie); 2945 rp->rbuf_endpaddr = 2946 cookie.dmac_address + cookie.dmac_size - 1; 2947 } 2948 rp->rbuf_paddr = cookie.dmac_address; 2949 2950 rbuf_freelist_head = rp; 2951 rbuf_pool_size++; 2952 rbuf_freebufs++; 2953 } 2954 2955 /* take the buffer from the head of the free list */ 2956 rp = rbuf_freelist_head; 2957 rbuf_freelist_head = rbuf_freelist_head->rbuf_next; 2958 2959 /* update the used list; put the entry at the end */ 2960 if (rbuf_usedlist_head == NULL) 2961 rbuf_usedlist_head = rp; 2962 else 2963 rbuf_usedlist_end->rbuf_next = rp; 2964 rp->rbuf_next = NULL; 2965 rbuf_usedlist_end = rp; 2966 rbuf_freebufs--; 2967 2968 mutex_exit(&dnet_rbuf_lock); 2969 2970 return (rp); 2971 fail_unbind: 2972 (void) ddi_dma_unbind_handle(rp->rbuf_dmahdl); 2973 fail_free: 2974 ddi_dma_mem_free(&rp->rbuf_acchdl); 2975 fail_freehdl: 2976 ddi_dma_free_handle(&rp->rbuf_dmahdl); 2977 fail_kfree: 2978 kmem_free(rp, sizeof (struct rbuf_list)); 2979 mutex_exit(&dnet_rbuf_lock); 2980 return (NULL); 2981 } 2982 2983 static void 2984 dnet_rbuf_free(caddr_t vaddr) 2985 { 2986 struct rbuf_list *rp, *prev; 2987 2988 ASSERT(vaddr != NULL); 2989 ASSERT(rbuf_usedlist_head != NULL); 2990 2991 mutex_enter(&dnet_rbuf_lock); 2992 2993 /* find the entry in the used list */ 2994 for (prev = rp = rbuf_usedlist_head; rp; rp = rp->rbuf_next) { 2995 if (rp->rbuf_vaddr == vaddr) 2996 break; 2997 prev = rp; 2998 } 2999 3000 if (rp == NULL) { 3001 cmn_err(CE_WARN, "DNET: rbuf_free: bad addr 0x%p", 3002 (void *)vaddr); 3003 mutex_exit(&dnet_rbuf_lock); 3004 return; 3005 } 3006 3007 /* update the used list and put the buffer back in the free list */ 3008 if (rbuf_usedlist_head != rp) { 3009 prev->rbuf_next = rp->rbuf_next; 3010 if (rbuf_usedlist_end == rp) 3011 rbuf_usedlist_end = prev; 3012 } else { 3013 rbuf_usedlist_head = rp->rbuf_next; 3014 if (rbuf_usedlist_end == rp) 3015 rbuf_usedlist_end = NULL; 3016 } 3017 rp->rbuf_next = rbuf_freelist_head; 3018 rbuf_freelist_head = rp; 3019 rbuf_freebufs++; 3020 3021 mutex_exit(&dnet_rbuf_lock); 3022 } 3023 3024 /* 3025 * Free the receive buffer used in a stream's message block allocated 3026 * thru desballoc(). 3027 */ 3028 static void 3029 dnet_freemsg_buf(struct free_ptr *frp) 3030 { 3031 dnet_rbuf_free((caddr_t)frp->buf); /* buffer goes back to the pool */ 3032 kmem_free(frp, sizeof (*frp)); /* free up the free_rtn structure */ 3033 } 3034 3035 /* 3036 * ========== SROM Read Routines ========== 3037 */ 3038 3039 /* 3040 * The following code gets the SROM information, either by reading it 3041 * from the device or, failing that, by reading a property. 3042 */ 3043 static int 3044 dnet_read_srom(dev_info_t *devinfo, int board_type, ddi_acc_handle_t io_handle, 3045 caddr_t io_reg, uchar_t *vi, int maxlen) 3046 { 3047 int all_ones, zerocheck, i; 3048 3049 /* 3050 * Load SROM into vendor_info 3051 */ 3052 if (board_type == DEVICE_ID_21040) 3053 dnet_read21040addr(devinfo, io_handle, io_reg, vi, &maxlen); 3054 else 3055 /* 21041/21140 serial rom */ 3056 dnet_read21140srom(io_handle, io_reg, vi, maxlen); 3057 /* 3058 * If the dumpsrom property is present in the conf file, print 3059 * the contents of the SROM to the console 3060 */ 3061 if (ddi_getprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS, 3062 "dumpsrom", 0)) 3063 dnet_dumpbin("SROM", vi, 1, maxlen); 3064 3065 for (zerocheck = i = 0, all_ones = 0xff; i < maxlen; i++) { 3066 zerocheck |= vi[i]; 3067 all_ones &= vi[i]; 3068 } 3069 if (zerocheck == 0 || all_ones == 0xff) { 3070 return (get_alternative_srom_image(devinfo, vi, maxlen)); 3071 } else { 3072 #ifdef BUG_4010796 3073 set_alternative_srom_image(devinfo, vi, maxlen); 3074 #endif 3075 return (0); /* Primary */ 3076 } 3077 } 3078 3079 /* 3080 * The function reads the ethernet address of the 21040 adapter 3081 */ 3082 static void 3083 dnet_read21040addr(dev_info_t *dip, ddi_acc_handle_t io_handle, caddr_t io_reg, 3084 uchar_t *addr, int *len) 3085 { 3086 uint32_t val; 3087 int i; 3088 3089 /* No point reading more than the ethernet address */ 3090 *len = ddi_getprop(DDI_DEV_T_ANY, dip, 3091 DDI_PROP_DONTPASS, macoffset_propname, 0) + ETHERADDRL; 3092 3093 /* Reset ROM pointer */ 3094 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 0); 3095 for (i = 0; i < *len; i++) { 3096 do { 3097 val = ddi_get32(io_handle, 3098 REG32(io_reg, ETHER_ROM_REG)); 3099 } while (val & 0x80000000); 3100 addr[i] = val & 0xFF; 3101 } 3102 } 3103 3104 #define drv_nsecwait(x) drv_usecwait(((x)+999)/1000) /* XXX */ 3105 3106 /* 3107 * The function reads the SROM of the 21140 adapter 3108 */ 3109 static void 3110 dnet_read21140srom(ddi_acc_handle_t io_handle, caddr_t io_reg, uchar_t *addr, 3111 int maxlen) 3112 { 3113 uint32_t i, j; 3114 uint32_t dout; 3115 uint16_t word; 3116 uint8_t rom_addr; 3117 uint8_t bit; 3118 3119 3120 rom_addr = 0; 3121 for (i = 0; i < maxlen; i += 2) { 3122 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3123 READ_OP | SEL_ROM); 3124 drv_nsecwait(30); 3125 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3126 READ_OP | SEL_ROM | SEL_CHIP); 3127 drv_nsecwait(50); 3128 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3129 READ_OP | SEL_ROM | SEL_CHIP | SEL_CLK); 3130 drv_nsecwait(250); 3131 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3132 READ_OP | SEL_ROM | SEL_CHIP); 3133 drv_nsecwait(100); 3134 3135 /* command */ 3136 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3137 READ_OP | SEL_ROM | SEL_CHIP | DATA_IN); 3138 drv_nsecwait(150); 3139 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3140 READ_OP | SEL_ROM | SEL_CHIP | DATA_IN | SEL_CLK); 3141 drv_nsecwait(250); 3142 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3143 READ_OP | SEL_ROM | SEL_CHIP | DATA_IN); 3144 drv_nsecwait(250); 3145 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3146 READ_OP | SEL_ROM | SEL_CHIP | DATA_IN | SEL_CLK); 3147 drv_nsecwait(250); 3148 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3149 READ_OP | SEL_ROM | SEL_CHIP | DATA_IN); 3150 drv_nsecwait(100); 3151 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3152 READ_OP | SEL_ROM | SEL_CHIP); 3153 drv_nsecwait(150); 3154 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3155 READ_OP | SEL_ROM | SEL_CHIP | SEL_CLK); 3156 drv_nsecwait(250); 3157 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3158 READ_OP | SEL_ROM | SEL_CHIP); 3159 drv_nsecwait(100); 3160 3161 /* Address */ 3162 for (j = HIGH_ADDRESS_BIT; j >= 1; j >>= 1) { 3163 bit = (rom_addr & j) ? DATA_IN : 0; 3164 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3165 READ_OP | SEL_ROM | SEL_CHIP | bit); 3166 drv_nsecwait(150); 3167 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3168 READ_OP | SEL_ROM | SEL_CHIP | bit | SEL_CLK); 3169 drv_nsecwait(250); 3170 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3171 READ_OP | SEL_ROM | SEL_CHIP | bit); 3172 drv_nsecwait(100); 3173 } 3174 drv_nsecwait(150); 3175 3176 /* Data */ 3177 word = 0; 3178 for (j = 0x8000; j >= 1; j >>= 1) { 3179 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3180 READ_OP | SEL_ROM | SEL_CHIP | SEL_CLK); 3181 drv_nsecwait(100); 3182 dout = ddi_get32(io_handle, 3183 REG32(io_reg, ETHER_ROM_REG)); 3184 drv_nsecwait(150); 3185 if (dout & DATA_OUT) 3186 word |= j; 3187 ddi_put32(io_handle, 3188 REG32(io_reg, ETHER_ROM_REG), 3189 READ_OP | SEL_ROM | SEL_CHIP); 3190 drv_nsecwait(250); 3191 } 3192 addr[i] = (word & 0x0000FF); 3193 addr[i + 1] = (word >> 8); 3194 rom_addr++; 3195 ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 3196 READ_OP | SEL_ROM); 3197 drv_nsecwait(100); 3198 } 3199 } 3200 3201 3202 /* 3203 * XXX NEEDSWORK 3204 * 3205 * Some lame multiport cards have only one SROM, which can be accessed 3206 * only from the "first" 21x4x chip, whichever that one is. If we can't 3207 * get at our SROM, we look for its contents in a property instead, which 3208 * we rely on the bootstrap to have properly set. 3209 * #ifdef BUG_4010796 3210 * We also have a hack to try to set it ourselves, when the "first" port 3211 * attaches, if it has not already been properly set. However, this method 3212 * is not reliable, since it makes the unwarrented assumption that the 3213 * "first" port will attach first. 3214 * #endif 3215 */ 3216 3217 static int 3218 get_alternative_srom_image(dev_info_t *devinfo, uchar_t *vi, int len) 3219 { 3220 int l = len; 3221 3222 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS, 3223 "DNET_SROM", (caddr_t)vi, &len) != DDI_PROP_SUCCESS && 3224 (len = l) && ddi_getlongprop_buf(DDI_DEV_T_ANY, 3225 ddi_get_parent(devinfo), DDI_PROP_DONTPASS, "DNET_SROM", 3226 (caddr_t)vi, &len) != DDI_PROP_SUCCESS) 3227 return (-1); /* Can't find it! */ 3228 3229 /* 3230 * The return value from this routine specifies which port number 3231 * we are. The primary port is denoted port 0. On a QUAD card we 3232 * should return 1, 2, and 3 from this routine. The return value 3233 * is used to modify the ethernet address from the SROM data. 3234 */ 3235 3236 #ifdef BUG_4010796 3237 { 3238 /* 3239 * For the present, we remember the device number of our primary 3240 * sibling and hope we and our other siblings are consecutively 3241 * numbered up from there. In the future perhaps the bootstrap 3242 * will pass us the necessary information telling us which physical 3243 * port we really are. 3244 */ 3245 pci_regspec_t *assignp; 3246 int assign_len; 3247 int devnum; 3248 int primary_devnum; 3249 3250 primary_devnum = ddi_getprop(DDI_DEV_T_ANY, devinfo, 0, 3251 "DNET_DEVNUM", -1); 3252 if (primary_devnum == -1) 3253 return (1); /* XXX NEEDSWORK -- We have no better idea */ 3254 3255 if ((ddi_getlongprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS, 3256 "assigned-addresses", (caddr_t)&assignp, 3257 &assign_len)) != DDI_PROP_SUCCESS) 3258 return (1); /* XXX NEEDSWORK -- We have no better idea */ 3259 3260 devnum = PCI_REG_DEV_G(assignp->pci_phys_hi); 3261 kmem_free(assignp, assign_len); 3262 return (devnum - primary_devnum); 3263 } 3264 #else 3265 return (1); /* XXX NEEDSWORK -- We have no better idea */ 3266 #endif 3267 } 3268 3269 3270 #ifdef BUG_4010796 3271 static void 3272 set_alternative_srom_image(dev_info_t *devinfo, uchar_t *vi, int len) 3273 { 3274 int proplen; 3275 pci_regspec_t *assignp; 3276 int assign_len; 3277 int devnum; 3278 3279 if (ddi_getproplen(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS, 3280 "DNET_SROM", &proplen) == DDI_PROP_SUCCESS || 3281 ddi_getproplen(DDI_DEV_T_ANY, ddi_get_parent(devinfo), 3282 DDI_PROP_DONTPASS, "DNET_SROM", &proplen) == DDI_PROP_SUCCESS) 3283 return; /* Already done! */ 3284 3285 /* function return value ignored */ 3286 (void) ddi_prop_update_byte_array(DDI_DEV_T_NONE, 3287 ddi_get_parent(devinfo), "DNET_SROM", (uchar_t *)vi, len); 3288 (void) ddi_prop_update_string(DDI_DEV_T_NONE, devinfo, 3289 "DNET_HACK", "hack"); 3290 3291 if ((ddi_getlongprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS, 3292 "assigned-addresses", (caddr_t)&assignp, 3293 &assign_len)) == DDI_PROP_SUCCESS) { 3294 devnum = PCI_REG_DEV_G(assignp->pci_phys_hi); 3295 kmem_free(assignp, assign_len); 3296 /* function return value ignored */ 3297 (void) ddi_prop_update_int(DDI_DEV_T_NONE, 3298 ddi_get_parent(devinfo), "DNET_DEVNUM", devnum); 3299 } 3300 } 3301 #endif 3302 3303 /* 3304 * ========== SROM Parsing Routines ========== 3305 */ 3306 3307 static int 3308 check_srom_valid(uchar_t *vi) 3309 { 3310 int word, bit; 3311 uint8_t crc; 3312 uint16_t *wvi; /* word16 pointer to vendor info */ 3313 uint16_t bitval; 3314 3315 /* verify that the number of controllers on the card is within range */ 3316 if (vi[SROM_ADAPTER_CNT] < 1 || vi[SROM_ADAPTER_CNT] > MAX_ADAPTERS) 3317 return (0); 3318 3319 /* 3320 * version 1 and 3 of this card did not check the id block CRC value 3321 * and this can't be changed without retesting every supported card 3322 * 3323 * however version 4 of the SROM can have this test applied 3324 * without fear of breaking something that used to work. 3325 * the CRC algorithm is taken from the Intel document 3326 * "21x4 Serial ROM Format" 3327 * version 4.09 3328 * 3-Mar-1999 3329 */ 3330 3331 switch (vi[SROM_VERSION]) { 3332 case 1: 3333 /* fallthru */ 3334 case 3: 3335 return (vi[SROM_MBZ] == 0 && /* must be zero */ 3336 vi[SROM_MBZ2] == 0 && /* must be zero */ 3337 vi[SROM_MBZ3] == 0); /* must be zero */ 3338 3339 case 4: 3340 wvi = (uint16_t *)vi; 3341 crc = 0xff; 3342 for (word = 0; word < 9; word++) 3343 for (bit = 15; bit >= 0; bit--) { 3344 if (word == 8 && bit == 7) 3345 return (crc == vi[16]); 3346 bitval = 3347 ((wvi[word] >> bit) & 1) ^ ((crc >> 7) & 1); 3348 crc <<= 1; 3349 if (bitval == 1) { 3350 crc ^= 7; 3351 } 3352 } 3353 3354 default: 3355 return (0); 3356 } 3357 } 3358 3359 /* 3360 * ========== Active Media Determination Routines ========== 3361 */ 3362 3363 /* This routine is also called for V3 Compact and extended type 0 SROMs */ 3364 static int 3365 is_fdmedia(int media) 3366 { 3367 if (media == MEDIA_TP_FD || media == MEDIA_SYM_SCR_FD) 3368 return (1); 3369 else 3370 return (0); 3371 } 3372 3373 /* 3374 * "Linkset" is used to merge media that use the same link test check. So, 3375 * if the TP link is added to the linkset, so is the TP Full duplex link. 3376 * Used to avoid checking the same link status twice. 3377 */ 3378 static void 3379 linkset_add(uint32_t *set, int media) 3380 { 3381 if (media == MEDIA_TP_FD || media == MEDIA_TP) 3382 *set |= (1UL<<MEDIA_TP_FD) | (1UL<<MEDIA_TP); 3383 else if (media == MEDIA_SYM_SCR_FD || media == MEDIA_SYM_SCR) 3384 *set |= (1UL<<MEDIA_SYM_SCR_FD) | (1UL<<MEDIA_SYM_SCR); 3385 else *set |= 1UL<<media; 3386 } 3387 static int 3388 linkset_isset(uint32_t linkset, int media) 3389 { 3390 return (((1UL<<media) & linkset) ? 1:0); 3391 } 3392 3393 /* 3394 * The following code detects which Media is connected for 21041/21140 3395 * Expect to change this code to support new 21140 variants. 3396 * find_active_media() - called with intrlock held. 3397 */ 3398 static void 3399 find_active_media(gld_mac_info_t *macinfo) 3400 { 3401 int i; 3402 media_block_t *block; 3403 media_block_t *best_allowed = NULL; 3404 media_block_t *hd_found = NULL; 3405 media_block_t *fd_found = NULL; 3406 struct dnetinstance *dnetp = (struct dnetinstance *) 3407 (macinfo->gldm_private); 3408 LEAF_FORMAT *leaf = &dnetp->sr.leaf[dnetp->leaf]; 3409 uint32_t checked = 0, links_up = 0; 3410 3411 ASSERT(MUTEX_HELD(&dnetp->intrlock)); 3412 #ifdef SROMDEBUG 3413 cmn_err(CE_NOTE, "find_active_media 0x%x,0x%x", sr->version, macinfo); 3414 #endif 3415 dnetp->selected_media_block = leaf->default_block; 3416 3417 if (dnetp->phyaddr != -1) { 3418 dnetp->selected_media_block = leaf->mii_block; 3419 setup_block(macinfo); 3420 3421 if (ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo, 3422 DDI_PROP_DONTPASS, "portmon", 1)) { 3423 /* XXX return value ignored */ 3424 (void) mii_start_portmon(dnetp->mii, dnet_mii_link_cb, 3425 &dnetp->intrlock); 3426 /* 3427 * If the port monitor detects the link is already 3428 * up, there is no point going through the rest of the 3429 * link sense 3430 */ 3431 if (dnetp->mii_up) { 3432 return; 3433 } 3434 } 3435 } 3436 3437 /* 3438 * Media is searched for in order of Precedence. This DEC SROM spec 3439 * tells us that the first media entry in the SROM is the lowest 3440 * precedence and should be checked last. This is why we go to the last 3441 * Media block and work back to the beginning. 3442 * 3443 * However, some older SROMs (Cogent EM110's etc.) have this the wrong 3444 * way around. As a result, following the SROM spec would result in a 3445 * 10 link being chosen over a 100 link if both media are available. 3446 * So we continue trying the media until we have at least tried the 3447 * DEFAULT media. 3448 */ 3449 3450 /* Search for an active medium, and select it */ 3451 for (block = leaf->block + leaf->block_count - 1; 3452 block >= leaf->block; block--) { 3453 int media = block->media_code; 3454 3455 /* User settings disallow selection of this block */ 3456 if (dnetp->disallowed_media & (1UL<<media)) 3457 continue; 3458 3459 /* We may not be able to pick the default */ 3460 if (best_allowed == NULL || block == leaf->default_block) 3461 best_allowed = block; 3462 #ifdef DEBUG 3463 if (dnetdebug & DNETSENSE) 3464 cmn_err(CE_NOTE, "Testing %s medium (block type %d)", 3465 media_str[media], block->type); 3466 #endif 3467 3468 dnetp->selected_media_block = block; 3469 switch (block->type) { 3470 3471 case 2: /* SIA Media block: Best we can do is send a packet */ 3472 setup_block(macinfo); 3473 if (send_test_packet(macinfo)) { 3474 if (!is_fdmedia(media)) 3475 return; 3476 if (!fd_found) 3477 fd_found = block; 3478 } 3479 break; 3480 3481 /* SYM/SCR or TP block: Use the link-sense bits */ 3482 case 0: 3483 if (!linkset_isset(checked, media)) { 3484 linkset_add(&checked, media); 3485 if (((media == MEDIA_BNC || 3486 media == MEDIA_AUI) && 3487 send_test_packet(macinfo)) || 3488 dnet_link_sense(macinfo)) 3489 linkset_add(&links_up, media); 3490 } 3491 3492 if (linkset_isset(links_up, media)) { 3493 /* 3494 * Half Duplex is *always* the favoured media. 3495 * Full Duplex can be set and forced via the 3496 * conf file. 3497 */ 3498 if (!is_fdmedia(media) && 3499 dnetp->selected_media_block == 3500 leaf->default_block) { 3501 /* 3502 * Cogent cards have the media in 3503 * opposite order to the spec., 3504 * this code forces the media test to 3505 * keep going until the default media 3506 * is tested. 3507 * 3508 * In Cogent case, 10, 10FD, 100FD, 100 3509 * 100 is the default but 10 could have 3510 * been detected and would have been 3511 * chosen but now we force it through to 3512 * 100. 3513 */ 3514 setup_block(macinfo); 3515 return; 3516 } else if (!is_fdmedia(media)) { 3517 /* 3518 * This allows all the others to work 3519 * properly by remembering the media 3520 * that works and not defaulting to 3521 * a FD link. 3522 */ 3523 if (hd_found == NULL) 3524 hd_found = block; 3525 } else if (fd_found == NULL) { 3526 /* 3527 * No media have already been found 3528 * so far, this is FD, it works so 3529 * remember it and if no others are 3530 * detected, use it. 3531 */ 3532 fd_found = block; 3533 } 3534 } 3535 break; 3536 3537 /* 3538 * MII block: May take up to a second or so to settle if 3539 * setup causes a PHY reset 3540 */ 3541 case 1: case 3: 3542 setup_block(macinfo); 3543 for (i = 0; ; i++) { 3544 if (mii_linkup(dnetp->mii, dnetp->phyaddr)) { 3545 /* XXX function return value ignored */ 3546 (void) mii_getspeed(dnetp->mii, 3547 dnetp->phyaddr, 3548 &dnetp->mii_speed, 3549 &dnetp->mii_duplex); 3550 dnetp->mii_up = 1; 3551 leaf->mii_block = block; 3552 return; 3553 } 3554 if (i == 10) 3555 break; 3556 delay(drv_usectohz(150000)); 3557 } 3558 dnetp->mii_up = 0; 3559 break; 3560 } 3561 } /* for loop */ 3562 if (hd_found) { 3563 dnetp->selected_media_block = hd_found; 3564 } else if (fd_found) { 3565 dnetp->selected_media_block = fd_found; 3566 } else { 3567 if (best_allowed == NULL) 3568 best_allowed = leaf->default_block; 3569 dnetp->selected_media_block = best_allowed; 3570 cmn_err(CE_WARN, "!dnet: Default media selected\n"); 3571 } 3572 setup_block(macinfo); 3573 } 3574 3575 /* 3576 * Do anything neccessary to select the selected_media_block. 3577 * setup_block() - called with intrlock held. 3578 */ 3579 static void 3580 setup_block(gld_mac_info_t *macinfo) 3581 { 3582 dnet_reset_board(macinfo); 3583 dnet_init_board(macinfo); 3584 /* XXX function return value ignored */ 3585 (void) dnet_start(macinfo); 3586 } 3587 3588 /* dnet_link_sense() - called with intrlock held */ 3589 static int 3590 dnet_link_sense(gld_mac_info_t *macinfo) 3591 { 3592 /* 3593 * This routine makes use of the command word from the srom config. 3594 * Details of the auto-sensing information contained in this can 3595 * be found in the "Digital Semiconductor 21X4 Serial ROM Format v3.03" 3596 * spec. Section 4.3.2.1, and 4.5.2.1.3 3597 */ 3598 struct dnetinstance *dnetp = (struct dnetinstance *) 3599 (macinfo->gldm_private); 3600 media_block_t *block = dnetp->selected_media_block; 3601 uint32_t link, status, mask, polarity; 3602 int settletime, stabletime, waittime, upsamples; 3603 int delay_100, delay_10; 3604 3605 3606 ASSERT(MUTEX_HELD(&dnetp->intrlock)); 3607 /* Don't autosense if the medium does not support it */ 3608 if (block->command & (1 << 15)) { 3609 /* This should be the default block */ 3610 if (block->command & (1UL<<14)) 3611 dnetp->sr.leaf[dnetp->leaf].default_block = block; 3612 return (0); 3613 } 3614 3615 delay_100 = ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo, 3616 DDI_PROP_DONTPASS, "autosense-delay-100", 2000); 3617 3618 delay_10 = ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo, 3619 DDI_PROP_DONTPASS, "autosense-delay-10", 400); 3620 3621 /* 3622 * Scrambler may need to be disabled for link sensing 3623 * to work 3624 */ 3625 dnetp->disable_scrambler = 1; 3626 setup_block(macinfo); 3627 dnetp->disable_scrambler = 0; 3628 3629 if (block->media_code == MEDIA_TP || block->media_code == MEDIA_TP_FD) 3630 settletime = delay_10; 3631 else 3632 settletime = delay_100; 3633 stabletime = settletime / 4; 3634 3635 mask = 1 << ((block->command & CMD_MEDIABIT_MASK) >> 1); 3636 polarity = block->command & CMD_POL ? 0xffffffff : 0; 3637 3638 for (waittime = 0, upsamples = 0; 3639 waittime <= settletime + stabletime && upsamples < 8; 3640 waittime += stabletime/8) { 3641 delay(drv_usectohz(stabletime*1000 / 8)); 3642 status = read_gpr(dnetp); 3643 link = (status^polarity) & mask; 3644 if (link) 3645 upsamples++; 3646 else 3647 upsamples = 0; 3648 } 3649 #ifdef DNETDEBUG 3650 if (dnetdebug & DNETSENSE) 3651 cmn_err(CE_NOTE, "%s upsamples:%d stat:%x polarity:%x " 3652 "mask:%x link:%x", 3653 upsamples == 8 ? "UP":"DOWN", 3654 upsamples, status, polarity, mask, link); 3655 #endif 3656 if (upsamples == 8) 3657 return (1); 3658 return (0); 3659 } 3660 3661 static int 3662 send_test_packet(gld_mac_info_t *macinfo) 3663 { 3664 int packet_delay; 3665 struct dnetinstance *dnetp = (struct dnetinstance *) 3666 (macinfo->gldm_private); 3667 struct tx_desc_type *desc; 3668 int bufindex; 3669 int media_code = dnetp->selected_media_block->media_code; 3670 uint32_t del; 3671 3672 ASSERT(MUTEX_HELD(&dnetp->intrlock)); 3673 /* 3674 * For a successful test packet, the card must have settled into 3675 * its current setting. Almost all cards we've tested manage to 3676 * do this with all media within 50ms. However, the SMC 8432 3677 * requires 300ms to settle into BNC mode. We now only do this 3678 * from attach, and we do sleeping delay() instead of drv_usecwait() 3679 * so we hope this .2 second delay won't cause too much suffering. 3680 * ALSO: with an autonegotiating hub, an aditional 1 second delay is 3681 * required. This is done if the media type is TP 3682 */ 3683 if (media_code == MEDIA_TP || media_code == MEDIA_TP_FD) { 3684 packet_delay = ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo, 3685 DDI_PROP_DONTPASS, "test_packet_delay_tp", 1300000); 3686 } else { 3687 packet_delay = ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo, 3688 DDI_PROP_DONTPASS, "test_packet_delay", 300000); 3689 } 3690 delay(drv_usectohz(packet_delay)); 3691 3692 desc = dnetp->tx_desc; 3693 3694 bufindex = dnetp->tx_current_desc; 3695 if (alloc_descriptor(macinfo) == FAILURE) { 3696 cmn_err(CE_WARN, "DNET: send_test_packet: alloc_descriptor" 3697 "failed"); 3698 return (0); 3699 } 3700 3701 /* 3702 * use setup buffer as the buffer for the test packet 3703 * instead of allocating one. 3704 */ 3705 3706 ASSERT(dnetp->setup_buf_vaddr != NULL); 3707 /* Put something decent in dest address so we don't annoy other cards */ 3708 BCOPY((caddr_t)dnetp->curr_macaddr, 3709 (caddr_t)dnetp->setup_buf_vaddr, ETHERADDRL); 3710 BCOPY((caddr_t)dnetp->curr_macaddr, 3711 (caddr_t)dnetp->setup_buf_vaddr+ETHERADDRL, ETHERADDRL); 3712 3713 desc[bufindex].buffer1 = dnetp->setup_buf_paddr; 3714 desc[bufindex].desc1.buffer_size1 = SETUPBUF_SIZE; 3715 desc[bufindex].buffer2 = (uint32_t)(0); 3716 desc[bufindex].desc1.first_desc = 1; 3717 desc[bufindex].desc1.last_desc = 1; 3718 desc[bufindex].desc1.int_on_comp = 1; 3719 desc[bufindex].desc0.own = 1; 3720 3721 ddi_put8(dnetp->io_handle, REG8(dnetp->io_reg, TX_POLL_REG), 3722 TX_POLL_DEMAND); 3723 3724 /* 3725 * Give enough time for the chip to transmit the packet 3726 */ 3727 #if 1 3728 del = 1000; 3729 while (desc[bufindex].desc0.own && --del) 3730 drv_usecwait(10); /* quickly wait up to 10ms */ 3731 if (desc[bufindex].desc0.own) 3732 delay(drv_usectohz(200000)); /* nicely wait a longer time */ 3733 #else 3734 del = 0x10000; 3735 while (desc[bufindex].desc0.own && --del) 3736 drv_usecwait(10); 3737 #endif 3738 3739 #ifdef DNETDEBUG 3740 if (dnetdebug & DNETSENSE) 3741 cmn_err(CE_NOTE, "desc0 bits = %u, %u, %u, %u, %u, %u", 3742 desc[bufindex].desc0.own, 3743 desc[bufindex].desc0.err_summary, 3744 desc[bufindex].desc0.carrier_loss, 3745 desc[bufindex].desc0.no_carrier, 3746 desc[bufindex].desc0.late_collision, 3747 desc[bufindex].desc0.link_fail); 3748 #endif 3749 if (desc[bufindex].desc0.own) /* it shouldn't take this long, error */ 3750 return (0); 3751 3752 return (!desc[bufindex].desc0.err_summary); 3753 } 3754 3755 /* enable_interrupts - called with intrlock held */ 3756 static void 3757 enable_interrupts(struct dnetinstance *dnetp, int enable_xmit) 3758 { 3759 ASSERT(MUTEX_HELD(&dnetp->intrlock)); 3760 /* Don't enable interrupts if they have been forced off */ 3761 if (dnetp->interrupts_disabled) 3762 return; 3763 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, INT_MASK_REG), 3764 NORMAL_INTR_MASK | ABNORMAL_INTR_MASK | TX_UNDERFLOW_MASK | 3765 (enable_xmit ? TX_INTERRUPT_MASK : 0) | 3766 (dnetp->timer.cb ? GPTIMER_INTR : 0) | 3767 RX_INTERRUPT_MASK | SYSTEM_ERROR_MASK | TX_JABBER_MASK); 3768 3769 } 3770 3771 /* 3772 * Some older multiport cards are non-PCI compliant in their interrupt routing. 3773 * Second and subsequent devices are incorrectly configured by the BIOS 3774 * (either in their ILINE configuration or the MP Configuration Table for PC+MP 3775 * systems). 3776 * The hack stops gldregister() registering the interrupt routine for the 3777 * FIRST device on the adapter, and registers its own. It builds up a table 3778 * of macinfo structures for each device, and the new interrupt routine 3779 * calls gldintr for each of them. 3780 * Known cards that suffer from this problem are: 3781 * All Cogent multiport cards; 3782 * Znyx 314; 3783 * Znyx 315. 3784 * 3785 * XXX NEEDSWORK -- see comments above get_alternative_srom_image(). This 3786 * hack relies on the fact that the offending cards will have only one SROM. 3787 * It uses this fact to identify devices that are on the same multiport 3788 * adapter, as opposed to multiple devices from the same vendor (as 3789 * indicated by "secondary") 3790 */ 3791 static int 3792 dnet_hack_interrupts(gld_mac_info_t *macinfo, int secondary) 3793 { 3794 int i; 3795 struct hackintr_inf *hackintr_inf; 3796 struct dnetinstance *dnetp = 3797 (struct dnetinstance *)macinfo->gldm_private; 3798 dev_info_t *devinfo = dnetp->devinfo; 3799 uint32_t oui = 0; /* Organizationally Unique ID */ 3800 3801 if (ddi_getprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS, 3802 "no_INTA_workaround", 0) != 0) 3803 return (0); 3804 3805 for (i = 0; i < 3; i++) 3806 oui = (oui << 8) | dnetp->vendor_addr[i]; 3807 3808 /* Check wheather or not we need to implement the hack */ 3809 3810 switch (oui) { 3811 case ZNYX_ETHER: 3812 /* Znyx multiport 21040 cards <<==>> ZX314 or ZX315 */ 3813 if (dnetp->board_type != DEVICE_ID_21040) 3814 return (0); 3815 break; 3816 3817 case COGENT_ETHER: 3818 /* All known Cogent multiport cards */ 3819 break; 3820 3821 case ADAPTEC_ETHER: 3822 /* Adaptec multiport cards */ 3823 break; 3824 3825 default: 3826 /* Other cards work correctly */ 3827 return (0); 3828 } 3829 3830 /* card is (probably) non-PCI compliant in its interrupt routing */ 3831 3832 3833 if (!secondary) { 3834 3835 /* 3836 * If we have already registered a hacked interrupt, and 3837 * this is also a 'primary' adapter, then this is NOT part of 3838 * a multiport card, but a second card on the same PCI bus. 3839 * BUGID: 4057747 3840 */ 3841 if (ddi_getprop(DDI_DEV_T_ANY, ddi_get_parent(devinfo), 3842 DDI_PROP_DONTPASS, hackintr_propname, 0) != 0) 3843 return (0); 3844 /* ... Primary not part of a multiport device */ 3845 3846 #ifdef DNETDEBUG 3847 if (dnetdebug & DNETTRACE) 3848 cmn_err(CE_NOTE, "dnet: Implementing hardware " 3849 "interrupt flaw workaround"); 3850 #endif 3851 dnetp->hackintr_inf = hackintr_inf = 3852 kmem_zalloc(sizeof (struct hackintr_inf), KM_SLEEP); 3853 if (hackintr_inf == NULL) 3854 goto fail; 3855 3856 hackintr_inf->macinfos[0] = macinfo; 3857 hackintr_inf->devinfo = devinfo; 3858 3859 /* 3860 * Add a property to allow successive attaches to find the 3861 * table 3862 */ 3863 3864 if (ddi_prop_update_byte_array(DDI_DEV_T_NONE, 3865 ddi_get_parent(devinfo), hackintr_propname, 3866 (uchar_t *)&dnetp->hackintr_inf, 3867 sizeof (void *)) != DDI_PROP_SUCCESS) 3868 goto fail; 3869 3870 3871 /* Register our hacked interrupt routine */ 3872 if (ddi_add_intr(devinfo, 0, &macinfo->gldm_cookie, NULL, 3873 (uint_t (*)(char *))dnet_hack_intr, 3874 (caddr_t)hackintr_inf) != DDI_SUCCESS) { 3875 /* XXX function return value ignored */ 3876 (void) ddi_prop_remove(DDI_DEV_T_NONE, 3877 ddi_get_parent(devinfo), 3878 hackintr_propname); 3879 goto fail; 3880 } 3881 3882 /* 3883 * Mutex required to ensure interrupt routine has completed 3884 * when detaching devices 3885 */ 3886 mutex_init(&hackintr_inf->lock, NULL, MUTEX_DRIVER, 3887 macinfo->gldm_cookie); 3888 3889 /* Stop GLD registering an interrupt */ 3890 return (-1); 3891 } else { 3892 3893 /* Add the macinfo for this secondary device to the table */ 3894 3895 hackintr_inf = (struct hackintr_inf *)(uintptr_t) 3896 ddi_getprop(DDI_DEV_T_ANY, ddi_get_parent(devinfo), 3897 DDI_PROP_DONTPASS, hackintr_propname, 0); 3898 3899 if (hackintr_inf == NULL) 3900 goto fail; 3901 3902 /* Find an empty slot */ 3903 for (i = 0; i < MAX_INST; i++) 3904 if (hackintr_inf->macinfos[i] == NULL) 3905 break; 3906 3907 /* More than 8 ports on adapter ?! */ 3908 if (i == MAX_INST) 3909 goto fail; 3910 3911 hackintr_inf->macinfos[i] = macinfo; 3912 3913 /* 3914 * Allow GLD to register a handler for this 3915 * device. If the card is actually broken, as we suspect, this 3916 * handler will never get called. However, by registering the 3917 * interrupt handler, we can copy gracefully with new multiport 3918 * Cogent cards that decide to fix the hardware problem 3919 */ 3920 return (0); 3921 } 3922 3923 fail: 3924 cmn_err(CE_WARN, "dnet: Could not work around hardware interrupt" 3925 " routing problem"); 3926 return (0); 3927 } 3928 3929 /* 3930 * Call gld_intr for all adapters on a multiport card 3931 */ 3932 3933 static uint_t 3934 dnet_hack_intr(struct hackintr_inf *hackintr_inf) 3935 { 3936 int i; 3937 int claimed = DDI_INTR_UNCLAIMED; 3938 3939 /* Stop detaches while processing interrupts */ 3940 mutex_enter(&hackintr_inf->lock); 3941 3942 for (i = 0; i < MAX_INST; i++) { 3943 if (hackintr_inf->macinfos[i] && 3944 gld_intr(hackintr_inf->macinfos[i]) == DDI_INTR_CLAIMED) 3945 claimed = DDI_INTR_CLAIMED; 3946 } 3947 mutex_exit(&hackintr_inf->lock); 3948 return (claimed); 3949 } 3950 3951 /* 3952 * This removes the detaching device from the table procesed by the hacked 3953 * interrupt routine. Because the interrupts from all devices come in to the 3954 * same interrupt handler, ALL devices must stop interrupting once the 3955 * primary device detaches. This isn't a problem at present, because all 3956 * instances of a device are detached when the driver is unloaded. 3957 */ 3958 static int 3959 dnet_detach_hacked_interrupt(dev_info_t *devinfo) 3960 { 3961 int i; 3962 struct hackintr_inf *hackintr_inf; 3963 gld_mac_info_t *mac, *macinfo = ddi_get_driver_private(devinfo); 3964 3965 hackintr_inf = (struct hackintr_inf *)(uintptr_t) 3966 ddi_getprop(DDI_DEV_T_ANY, ddi_get_parent(devinfo), 3967 DDI_PROP_DONTPASS, hackintr_propname, 0); 3968 3969 /* 3970 * No hackintr_inf implies hack was not required or the primary has 3971 * detached, and our interrupts are already disabled 3972 */ 3973 if (!hackintr_inf) { 3974 /* remove the interrupt for the non-hacked case */ 3975 ddi_remove_intr(devinfo, 0, macinfo->gldm_cookie); 3976 return (DDI_SUCCESS); 3977 } 3978 3979 /* Remove this device from the handled table */ 3980 mutex_enter(&hackintr_inf->lock); 3981 for (i = 0; i < MAX_INST; i++) { 3982 if (hackintr_inf->macinfos[i] == macinfo) { 3983 hackintr_inf->macinfos[i] = NULL; 3984 break; 3985 } 3986 } 3987 3988 mutex_exit(&hackintr_inf->lock); 3989 3990 /* Not the primary card, we are done */ 3991 if (devinfo != hackintr_inf->devinfo) 3992 return (DDI_SUCCESS); 3993 3994 /* 3995 * This is the primary card. All remaining adapters on this device 3996 * must have their interrupts disabled before we remove the handler 3997 */ 3998 for (i = 0; i < MAX_INST; i++) { 3999 if ((mac = hackintr_inf->macinfos[i]) != NULL) { 4000 struct dnetinstance *altdnetp = 4001 (struct dnetinstance *)mac->gldm_private; 4002 altdnetp->interrupts_disabled = 1; 4003 ddi_put32(altdnetp->io_handle, 4004 REG32(altdnetp->io_reg, INT_MASK_REG), 0); 4005 } 4006 } 4007 4008 /* It should now be safe to remove the interrupt handler */ 4009 4010 ddi_remove_intr(devinfo, 0, macinfo->gldm_cookie); 4011 mutex_destroy(&hackintr_inf->lock); 4012 /* XXX function return value ignored */ 4013 (void) ddi_prop_remove(DDI_DEV_T_NONE, ddi_get_parent(devinfo), 4014 hackintr_propname); 4015 kmem_free(hackintr_inf, sizeof (struct hackintr_inf)); 4016 return (DDI_SUCCESS); 4017 } 4018 4019 /* 4020 * ========== PHY MII Routines ========== 4021 */ 4022 4023 /* do_phy() - called with intrlock held */ 4024 static void 4025 do_phy(gld_mac_info_t *macinfo) 4026 { 4027 dev_info_t *dip; 4028 struct dnetinstance 4029 *dnetp = (struct dnetinstance *)macinfo->gldm_private; 4030 LEAF_FORMAT *leaf = dnetp->sr.leaf + dnetp->leaf; 4031 media_block_t *block; 4032 int phy; 4033 4034 dip = dnetp->devinfo; 4035 4036 /* 4037 * Find and configure the PHY media block. If NO PHY blocks are 4038 * found on the SROM, but a PHY device is present, we assume the card 4039 * is a legacy device, and that there is ONLY a PHY interface on the 4040 * card (ie, no BNC or AUI, and 10BaseT is implemented by the PHY 4041 */ 4042 4043 for (block = leaf->block + leaf->block_count -1; 4044 block >= leaf->block; block --) { 4045 if (block->type == 3 || block->type == 1) { 4046 leaf->mii_block = block; 4047 break; 4048 } 4049 } 4050 4051 /* 4052 * If no MII block, select default, and hope this configuration will 4053 * allow the phy to be read/written if it is present 4054 */ 4055 dnetp->selected_media_block = leaf->mii_block ? 4056 leaf->mii_block : leaf->default_block; 4057 4058 setup_block(macinfo); 4059 /* XXX function return value ignored */ 4060 (void) mii_create(dip, dnet_mii_write, dnet_mii_read, &dnetp->mii); 4061 4062 /* 4063 * We try PHY 0 LAST because it is less likely to be connected 4064 */ 4065 for (phy = 1; phy < 33; phy++) 4066 if (mii_probe_phy(dnetp->mii, phy % 32) == MII_SUCCESS && 4067 mii_init_phy(dnetp->mii, phy % 32) == MII_SUCCESS) { 4068 #ifdef DNETDEBUG 4069 if (dnetdebug & DNETSENSE) 4070 cmn_err(CE_NOTE, "dnet: " 4071 "PHY at address %d", phy % 32); 4072 #endif 4073 dnetp->phyaddr = phy % 32; 4074 if (!leaf->mii_block) { 4075 /* Legacy card, change the leaf node */ 4076 set_leaf(&dnetp->sr, &leaf_phylegacy); 4077 } 4078 return; 4079 } 4080 #ifdef DNETDEBUG 4081 if (dnetdebug & DNETSENSE) 4082 cmn_err(CE_NOTE, "dnet: No PHY found"); 4083 #endif 4084 } 4085 4086 static ushort_t 4087 dnet_mii_read(dev_info_t *dip, int phy_addr, int reg_num) 4088 { 4089 gld_mac_info_t *macinfo; 4090 struct dnetinstance *dnetp; 4091 4092 uint32_t command_word; 4093 uint32_t tmp; 4094 uint32_t data = 0; 4095 int i; 4096 int bits_in_ushort = ((sizeof (ushort_t))*8); 4097 int turned_around = 0; 4098 4099 macinfo = ddi_get_driver_private(dip); 4100 dnetp = (struct dnetinstance *)macinfo->gldm_private; 4101 4102 ASSERT(MUTEX_HELD(&dnetp->intrlock)); 4103 /* Write Preamble */ 4104 write_mii(dnetp, MII_PRE, 2*bits_in_ushort); 4105 4106 /* Prepare command word */ 4107 command_word = (uint32_t)phy_addr << MII_PHY_ADDR_ALIGN; 4108 command_word |= (uint32_t)reg_num << MII_REG_ADDR_ALIGN; 4109 command_word |= MII_READ_FRAME; 4110 4111 write_mii(dnetp, command_word, bits_in_ushort-2); 4112 4113 mii_tristate(dnetp); 4114 4115 /* Check that the PHY generated a zero bit the 2nd clock */ 4116 tmp = ddi_get32(dnetp->io_handle, REG32(dnetp->io_reg, ETHER_ROM_REG)); 4117 4118 turned_around = (tmp & MII_DATA_IN) ? 0 : 1; 4119 4120 /* read data WORD */ 4121 for (i = 0; i < bits_in_ushort; i++) { 4122 ddi_put32(dnetp->io_handle, 4123 REG32(dnetp->io_reg, ETHER_ROM_REG), MII_READ); 4124 drv_usecwait(MII_DELAY); 4125 ddi_put32(dnetp->io_handle, 4126 REG32(dnetp->io_reg, ETHER_ROM_REG), MII_READ | MII_CLOCK); 4127 drv_usecwait(MII_DELAY); 4128 tmp = ddi_get32(dnetp->io_handle, 4129 REG32(dnetp->io_reg, ETHER_ROM_REG)); 4130 drv_usecwait(MII_DELAY); 4131 data = (data << 1) | (tmp >> MII_DATA_IN_POSITION) & 0x0001; 4132 } 4133 4134 mii_tristate(dnetp); 4135 return (turned_around ? data: -1); 4136 } 4137 4138 static void 4139 dnet_mii_write(dev_info_t *dip, int phy_addr, int reg_num, int reg_dat) 4140 { 4141 gld_mac_info_t *macinfo; 4142 struct dnetinstance *dnetp; 4143 uint32_t command_word; 4144 int bits_in_ushort = ((sizeof (ushort_t))*8); 4145 4146 macinfo = ddi_get_driver_private(dip); 4147 dnetp = (struct dnetinstance *)macinfo->gldm_private; 4148 4149 ASSERT(MUTEX_HELD(&dnetp->intrlock)); 4150 write_mii(dnetp, MII_PRE, 2*bits_in_ushort); 4151 4152 /* Prepare command word */ 4153 command_word = ((uint32_t)phy_addr << MII_PHY_ADDR_ALIGN); 4154 command_word |= ((uint32_t)reg_num << MII_REG_ADDR_ALIGN); 4155 command_word |= (MII_WRITE_FRAME | (uint32_t)reg_dat); 4156 4157 write_mii(dnetp, command_word, 2*bits_in_ushort); 4158 mii_tristate(dnetp); 4159 } 4160 4161 /* 4162 * Write data size bits from mii_data to the MII control lines. 4163 */ 4164 static void 4165 write_mii(struct dnetinstance *dnetp, uint32_t mii_data, int data_size) 4166 { 4167 int i; 4168 uint32_t dbit; 4169 4170 ASSERT(MUTEX_HELD(&dnetp->intrlock)); 4171 for (i = data_size; i > 0; i--) { 4172 dbit = ((mii_data >> 4173 (31 - MII_WRITE_DATA_POSITION)) & MII_WRITE_DATA); 4174 ddi_put32(dnetp->io_handle, 4175 REG32(dnetp->io_reg, ETHER_ROM_REG), 4176 MII_WRITE | dbit); 4177 drv_usecwait(MII_DELAY); 4178 ddi_put32(dnetp->io_handle, 4179 REG32(dnetp->io_reg, ETHER_ROM_REG), 4180 MII_WRITE | MII_CLOCK | dbit); 4181 drv_usecwait(MII_DELAY); 4182 mii_data <<= 1; 4183 } 4184 } 4185 4186 /* 4187 * Put the MDIO port in tri-state for the turn around bits 4188 * in MII read and at end of MII management sequence. 4189 */ 4190 static void 4191 mii_tristate(struct dnetinstance *dnetp) 4192 { 4193 ASSERT(MUTEX_HELD(&dnetp->intrlock)); 4194 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, ETHER_ROM_REG), 4195 MII_WRITE_TS); 4196 drv_usecwait(MII_DELAY); 4197 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, ETHER_ROM_REG), 4198 MII_WRITE_TS | MII_CLOCK); 4199 drv_usecwait(MII_DELAY); 4200 } 4201 4202 4203 static void 4204 set_leaf(SROM_FORMAT *sr, LEAF_FORMAT *leaf) 4205 { 4206 if (sr->leaf && !sr->leaf->is_static) 4207 kmem_free(sr->leaf, sr->adapters * sizeof (LEAF_FORMAT)); 4208 sr->leaf = leaf; 4209 } 4210 4211 /* 4212 * Callback from MII module. Makes sure that the CSR registers are 4213 * configured properly if the PHY changes mode. 4214 */ 4215 /* ARGSUSED */ 4216 /* dnet_mii_link_cb - called with intrlock held */ 4217 static void 4218 dnet_mii_link_cb(dev_info_t *dip, int phy, enum mii_phy_state state) 4219 { 4220 gld_mac_info_t *macinfo = ddi_get_driver_private(dip); 4221 struct dnetinstance *dnetp = 4222 (struct dnetinstance *)macinfo->gldm_private; 4223 LEAF_FORMAT *leaf; 4224 4225 ASSERT(MUTEX_HELD(&dnetp->intrlock)); 4226 leaf = dnetp->sr.leaf + dnetp->leaf; 4227 if (state == phy_state_linkup) { 4228 dnetp->mii_up = 1; 4229 /* XXX function return value ignored */ 4230 (void) mii_getspeed(dnetp->mii, 4231 dnetp->phyaddr, &dnetp->mii_speed, 4232 &dnetp->mii_duplex); 4233 dnetp->selected_media_block = leaf->mii_block; 4234 setup_block(macinfo); 4235 } else { 4236 /* NEEDSWORK: Probably can call find_active_media here */ 4237 dnetp->mii_up = 0; 4238 dnetp->mii_speed = 0; 4239 dnetp->mii_duplex = 0; 4240 if (leaf->default_block->media_code == MEDIA_MII) 4241 dnetp->selected_media_block = leaf->default_block; 4242 setup_block(macinfo); 4243 } 4244 } 4245 4246 /* 4247 * SROM parsing routines. 4248 * Refer to the Digital 3.03 SROM spec while reading this! (references refer 4249 * to this document) 4250 * Where possible ALL vendor specific changes should be localised here. The 4251 * SROM data should be capable of describing any programmatic irregularities 4252 * of DNET cards (via SIA or GP registers, in particular), so vendor specific 4253 * code elsewhere should not be required 4254 */ 4255 static void 4256 dnet_parse_srom(struct dnetinstance *dnetp, SROM_FORMAT *sr, uchar_t *vi) 4257 { 4258 uint32_t ether_mfg = 0; 4259 int i; 4260 uchar_t *p; 4261 4262 if (!ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo, 4263 DDI_PROP_DONTPASS, "no_sromconfig", 0)) 4264 dnetp->sr.init_from_srom = check_srom_valid(vi); 4265 4266 if (dnetp->sr.init_from_srom && dnetp->board_type != DEVICE_ID_21040) { 4267 /* Section 2/3: General SROM Format/ ID Block */ 4268 p = vi+18; 4269 sr->version = *p++; 4270 sr->adapters = *p++; 4271 4272 sr->leaf = 4273 kmem_zalloc(sr->adapters * sizeof (LEAF_FORMAT), KM_SLEEP); 4274 for (i = 0; i < 6; i++) 4275 sr->netaddr[i] = *p++; 4276 4277 for (i = 0; i < sr->adapters; i++) { 4278 uchar_t devno = *p++; 4279 uint16_t offset = *p++; 4280 offset |= *p++ << 8; 4281 sr->leaf[i].device_number = devno; 4282 parse_controller_leaf(dnetp, sr->leaf+i, vi+offset); 4283 } 4284 /* 4285 * 'Orrible hack for cogent cards. The 6911A board seems to 4286 * have an incorrect SROM. (From the OEMDEMO program 4287 * supplied by cogent, it seems that the ROM matches a setup 4288 * or a board with a QSI or ICS PHY. 4289 */ 4290 for (i = 0; i < 3; i++) 4291 ether_mfg = (ether_mfg << 8) | sr->netaddr[i]; 4292 4293 if (ether_mfg == ADAPTEC_ETHER) { 4294 static uint16_t cogent_gprseq[] = {0x821, 0}; 4295 switch (vi[COGENT_SROM_ID]) { 4296 case COGENT_ANA6911A_C: 4297 case COGENT_ANA6911AC_C: 4298 #ifdef DNETDEBUG 4299 if (dnetdebug & DNETTRACE) 4300 cmn_err(CE_WARN, 4301 "Suspected bad GPR sequence." 4302 " Making a guess (821,0)"); 4303 #endif 4304 4305 /* XXX function return value ignored */ 4306 (void) ddi_prop_update_byte_array( 4307 DDI_DEV_T_NONE, dnetp->devinfo, 4308 "gpr-sequence", (uchar_t *)cogent_gprseq, 4309 sizeof (cogent_gprseq)); 4310 break; 4311 } 4312 } 4313 } else { 4314 /* 4315 * Adhoc SROM, check for some cards which need special handling 4316 * Assume vendor info contains ether address in first six bytes 4317 */ 4318 4319 uchar_t *mac = vi + ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo, 4320 DDI_PROP_DONTPASS, macoffset_propname, 0); 4321 4322 for (i = 0; i < 6; i++) 4323 sr->netaddr[i] = mac[i]; 4324 4325 if (dnetp->board_type == DEVICE_ID_21140) { 4326 for (i = 0; i < 3; i++) 4327 ether_mfg = (ether_mfg << 8) | mac[i]; 4328 4329 switch (ether_mfg) { 4330 case ASANTE_ETHER: 4331 dnetp->vendor_21140 = ASANTE_TYPE; 4332 dnetp->vendor_revision = 0; 4333 set_leaf(sr, &leaf_asante); 4334 sr->adapters = 1; 4335 break; 4336 4337 case COGENT_ETHER: 4338 case ADAPTEC_ETHER: 4339 dnetp->vendor_21140 = COGENT_EM_TYPE; 4340 dnetp->vendor_revision = 4341 vi[VENDOR_REVISION_OFFSET]; 4342 set_leaf(sr, &leaf_cogent_100); 4343 sr->adapters = 1; 4344 break; 4345 4346 default: 4347 dnetp->vendor_21140 = DEFAULT_TYPE; 4348 dnetp->vendor_revision = 0; 4349 set_leaf(sr, &leaf_default_100); 4350 sr->adapters = 1; 4351 break; 4352 } 4353 } else if (dnetp->board_type == DEVICE_ID_21041) { 4354 set_leaf(sr, &leaf_21041); 4355 } else if (dnetp->board_type == DEVICE_ID_21040) { 4356 set_leaf(sr, &leaf_21040); 4357 } 4358 } 4359 } 4360 4361 /* Section 4.2, 4.3, 4.4, 4.5 */ 4362 static void 4363 parse_controller_leaf(struct dnetinstance *dnetp, LEAF_FORMAT *leaf, 4364 uchar_t *vi) 4365 { 4366 int i; 4367 4368 leaf->selected_contype = *vi++; 4369 leaf->selected_contype |= *vi++ << 8; 4370 4371 if (dnetp->board_type == DEVICE_ID_21140) /* Sect. 4.3 */ 4372 leaf->gpr = *vi++; 4373 4374 leaf->block_count = *vi++; 4375 4376 if (leaf->block_count > MAX_MEDIA) { 4377 cmn_err(CE_WARN, "dnet: Too many media in SROM!"); 4378 leaf->block_count = 1; 4379 } 4380 for (i = 0; i <= leaf->block_count; i++) { 4381 vi = parse_media_block(dnetp, leaf->block + i, vi); 4382 if (leaf->block[i].command & CMD_DEFAULT_MEDIUM) 4383 leaf->default_block = leaf->block+i; 4384 } 4385 /* No explicit default block: use last in the ROM */ 4386 if (leaf->default_block == NULL) 4387 leaf->default_block = leaf->block + leaf->block_count -1; 4388 4389 } 4390 4391 static uchar_t * 4392 parse_media_block(struct dnetinstance *dnetp, media_block_t *block, uchar_t *vi) 4393 { 4394 int i; 4395 4396 /* 4397 * There are three kinds of media block we need to worry about: 4398 * The 21041 blocks. 4399 * 21140 blocks from a version 1 SROM 4400 * 2114[023] block from a version 3 SROM 4401 */ 4402 4403 if (dnetp->board_type == DEVICE_ID_21041) { 4404 /* Section 4.2 */ 4405 block->media_code = *vi & 0x3f; 4406 block->type = 2; 4407 if (*vi++ & 0x40) { 4408 block->un.sia.csr13 = *vi++; 4409 block->un.sia.csr13 |= *vi++ << 8; 4410 block->un.sia.csr14 = *vi++; 4411 block->un.sia.csr14 |= *vi++ << 8; 4412 block->un.sia.csr15 = *vi++; 4413 block->un.sia.csr15 |= *vi++ << 8; 4414 } else { 4415 /* No media data (csrs 13,14,15). Insert defaults */ 4416 switch (block->media_code) { 4417 case MEDIA_TP: 4418 block->un.sia.csr13 = 0xef01; 4419 block->un.sia.csr14 = 0x7f3f; 4420 block->un.sia.csr15 = 0x0008; 4421 break; 4422 case MEDIA_TP_FD: 4423 block->un.sia.csr13 = 0xef01; 4424 block->un.sia.csr14 = 0x7f3d; 4425 block->un.sia.csr15 = 0x0008; 4426 break; 4427 case MEDIA_BNC: 4428 block->un.sia.csr13 = 0xef09; 4429 block->un.sia.csr14 = 0x0705; 4430 block->un.sia.csr15 = 0x0006; 4431 break; 4432 case MEDIA_AUI: 4433 block->un.sia.csr13 = 0xef09; 4434 block->un.sia.csr14 = 0x0705; 4435 block->un.sia.csr15 = 0x000e; 4436 break; 4437 } 4438 } 4439 } else if (*vi & 0x80) { /* Extended format: Section 4.3.2.2 */ 4440 int blocklen = *vi++ & 0x7f; 4441 block->type = *vi++; 4442 switch (block->type) { 4443 case 0: /* "non-MII": Section 4.3.2.2.1 */ 4444 block->media_code = (*vi++) & 0x3f; 4445 block->gprseqlen = 1; 4446 block->gprseq[0] = *vi++; 4447 block->command = *vi++; 4448 block->command |= *vi++ << 8; 4449 break; 4450 4451 case 1: /* MII/PHY: Section 4.3.2.2.2 */ 4452 block->command = CMD_PS; 4453 block->media_code = MEDIA_MII; 4454 /* This is whats needed in CSR6 */ 4455 4456 block->un.mii.phy_num = *vi++; 4457 block->gprseqlen = *vi++; 4458 4459 for (i = 0; i < block->gprseqlen; i++) 4460 block->gprseq[i] = *vi++; 4461 block->rstseqlen = *vi++; 4462 for (i = 0; i < block->rstseqlen; i++) 4463 block->rstseq[i] = *vi++; 4464 4465 block->un.mii.mediacaps = *vi++; 4466 block->un.mii.mediacaps |= *vi++ << 8; 4467 block->un.mii.nwayadvert = *vi++; 4468 block->un.mii.nwayadvert |= *vi++ << 8; 4469 block->un.mii.fdxmask = *vi++; 4470 block->un.mii.fdxmask |= *vi++ << 8; 4471 block->un.mii.ttmmask = *vi++; 4472 block->un.mii.ttmmask |= *vi++ << 8; 4473 break; 4474 4475 case 2: /* SIA Media: Section 4.4.2.1.1 */ 4476 block->media_code = *vi & 0x3f; 4477 if (*vi++ & 0x40) { 4478 block->un.sia.csr13 = *vi++; 4479 block->un.sia.csr13 |= *vi++ << 8; 4480 block->un.sia.csr14 = *vi++; 4481 block->un.sia.csr14 |= *vi++ << 8; 4482 block->un.sia.csr15 = *vi++; 4483 block->un.sia.csr15 |= *vi++ << 8; 4484 } else { 4485 /* 4486 * SIA values not provided by SROM; provide 4487 * defaults. See appendix D of 2114[23] manuals. 4488 */ 4489 switch (block->media_code) { 4490 case MEDIA_BNC: 4491 block->un.sia.csr13 = 0x0009; 4492 block->un.sia.csr14 = 0x0705; 4493 block->un.sia.csr15 = 0x0000; 4494 break; 4495 case MEDIA_AUI: 4496 block->un.sia.csr13 = 0x0009; 4497 block->un.sia.csr14 = 0x0705; 4498 block->un.sia.csr15 = 0x0008; 4499 break; 4500 case MEDIA_TP: 4501 block->un.sia.csr13 = 0x0001; 4502 block->un.sia.csr14 = 0x7f3f; 4503 block->un.sia.csr15 = 0x0000; 4504 break; 4505 case MEDIA_TP_FD: 4506 block->un.sia.csr13 = 0x0001; 4507 block->un.sia.csr14 = 0x7f3d; 4508 block->un.sia.csr15 = 0x0000; 4509 break; 4510 default: 4511 block->un.sia.csr13 = 0x0000; 4512 block->un.sia.csr14 = 0x0000; 4513 block->un.sia.csr15 = 0x0000; 4514 } 4515 } 4516 4517 /* Treat GP control/data as a GPR sequence */ 4518 block->gprseqlen = 2; 4519 block->gprseq[0] = *vi++; 4520 block->gprseq[0] |= *vi++ << 8; 4521 block->gprseq[0] |= GPR_CONTROL_WRITE; 4522 block->gprseq[1] = *vi++; 4523 block->gprseq[1] |= *vi++ << 8; 4524 break; 4525 4526 case 3: /* MII/PHY : Section 4.4.2.1.2 */ 4527 block->command = CMD_PS; 4528 block->media_code = MEDIA_MII; 4529 block->un.mii.phy_num = *vi++; 4530 4531 block->gprseqlen = *vi++; 4532 for (i = 0; i < block->gprseqlen; i++) { 4533 block->gprseq[i] = *vi++; 4534 block->gprseq[i] |= *vi++ << 8; 4535 } 4536 4537 block->rstseqlen = *vi++; 4538 for (i = 0; i < block->rstseqlen; i++) { 4539 block->rstseq[i] = *vi++; 4540 block->rstseq[i] |= *vi++ << 8; 4541 } 4542 block->un.mii.mediacaps = *vi++; 4543 block->un.mii.mediacaps |= *vi++ << 8; 4544 block->un.mii.nwayadvert = *vi++; 4545 block->un.mii.nwayadvert |= *vi++ << 8; 4546 block->un.mii.fdxmask = *vi++; 4547 block->un.mii.fdxmask |= *vi++ << 8; 4548 block->un.mii.ttmmask = *vi++; 4549 block->un.mii.ttmmask |= *vi++ << 8; 4550 block->un.mii.miiintr |= *vi++; 4551 break; 4552 4553 case 4: /* SYM Media: 4.5.2.1.3 */ 4554 block->media_code = *vi++ & 0x3f; 4555 /* Treat GP control and data as a GPR sequence */ 4556 block->gprseqlen = 2; 4557 block->gprseq[0] = *vi++; 4558 block->gprseq[0] |= *vi++ << 8; 4559 block->gprseq[0] |= GPR_CONTROL_WRITE; 4560 block->gprseq[1] = *vi++; 4561 block->gprseq[1] |= *vi++ << 8; 4562 block->command = *vi++; 4563 block->command |= *vi++ << 8; 4564 break; 4565 4566 case 5: /* GPR reset sequence: Section 4.5.2.1.4 */ 4567 block->rstseqlen = *vi++; 4568 for (i = 0; i < block->rstseqlen; i++) 4569 block->rstseq[i] = *vi++; 4570 break; 4571 4572 default: /* Unknown media block. Skip it. */ 4573 cmn_err(CE_WARN, "dnet: Unsupported SROM block."); 4574 vi += blocklen; 4575 break; 4576 } 4577 } else { /* Compact format (or V1 SROM): Section 4.3.2.1 */ 4578 block->type = 0; 4579 block->media_code = *vi++ & 0x3f; 4580 block->gprseqlen = 1; 4581 block->gprseq[0] = *vi++; 4582 block->command = *vi++; 4583 block->command |= (*vi++) << 8; 4584 } 4585 return (vi); 4586 } 4587 4588 4589 /* 4590 * An alternative to doing this would be to store the legacy ROMs in binary 4591 * format in the conf file, and in read_srom, pick out the data. This would 4592 * then allow the parser to continue on as normal. This makes it a little 4593 * easier to read. 4594 */ 4595 static void 4596 setup_legacy_blocks() 4597 { 4598 LEAF_FORMAT *leaf; 4599 media_block_t *block; 4600 4601 /* Default FAKE SROM */ 4602 leaf = &leaf_default_100; 4603 leaf->is_static = 1; 4604 leaf->default_block = &leaf->block[3]; 4605 leaf->block_count = 4; /* 100 cards are highly unlikely to have BNC */ 4606 block = leaf->block; 4607 block->media_code = MEDIA_TP_FD; 4608 block->type = 0; 4609 block->command = 0x8e; /* PCS, PS off, media sense: bit7, pol=1 */ 4610 block++; 4611 block->media_code = MEDIA_TP; 4612 block->type = 0; 4613 block->command = 0x8e; /* PCS, PS off, media sense: bit7, pol=1 */ 4614 block++; 4615 block->media_code = MEDIA_SYM_SCR_FD; 4616 block->type = 0; 4617 block->command = 0x6d; /* PCS, PS, SCR on, media sense: bit6, pol=0 */ 4618 block++; 4619 block->media_code = MEDIA_SYM_SCR; 4620 block->type = 0; 4621 block->command = 0x406d; /* PCS, PS, SCR on, media sense: bit6, pol=0 */ 4622 4623 /* COGENT FAKE SROM */ 4624 leaf = &leaf_cogent_100; 4625 leaf->is_static = 1; 4626 leaf->default_block = &leaf->block[4]; 4627 leaf->block_count = 5; /* 100TX, 100TX-FD, 10T 10T-FD, BNC */ 4628 block = leaf->block; /* BNC */ 4629 block->media_code = MEDIA_BNC; 4630 block->type = 0; 4631 block->command = 0x8000; /* No media sense, PCS, SCR, PS all off */ 4632 block->gprseqlen = 2; 4633 block->rstseqlen = 0; 4634 block->gprseq[0] = 0x13f; 4635 block->gprseq[1] = 1; 4636 4637 block++; 4638 block->media_code = MEDIA_TP_FD; 4639 block->type = 0; 4640 block->command = 0x8e; /* PCS, PS off, media sense: bit7, pol=1 */ 4641 block->gprseqlen = 2; 4642 block->rstseqlen = 0; 4643 block->gprseq[0] = 0x13f; 4644 block->gprseq[1] = 0x26; 4645 4646 block++; /* 10BaseT */ 4647 block->media_code = MEDIA_TP; 4648 block->type = 0; 4649 block->command = 0x8e; /* PCS, PS off, media sense: bit7, pol=1 */ 4650 block->gprseqlen = 2; 4651 block->rstseqlen = 0; 4652 block->gprseq[0] = 0x13f; 4653 block->gprseq[1] = 0x3e; 4654 4655 block++; /* 100BaseTX-FD */ 4656 block->media_code = MEDIA_SYM_SCR_FD; 4657 block->type = 0; 4658 block->command = 0x6d; /* PCS, PS, SCR on, media sense: bit6, pol=0 */ 4659 block->gprseqlen = 2; 4660 block->rstseqlen = 0; 4661 block->gprseq[0] = 0x13f; 4662 block->gprseq[1] = 1; 4663 4664 block++; /* 100BaseTX */ 4665 block->media_code = MEDIA_SYM_SCR; 4666 block->type = 0; 4667 block->command = 0x406d; /* PCS, PS, SCR on, media sense: bit6, pol=0 */ 4668 block->gprseqlen = 2; 4669 block->rstseqlen = 0; 4670 block->gprseq[0] = 0x13f; 4671 block->gprseq[1] = 1; 4672 4673 /* Generic legacy card with a PHY. */ 4674 leaf = &leaf_phylegacy; 4675 leaf->block_count = 1; 4676 leaf->mii_block = leaf->block; 4677 leaf->default_block = &leaf->block[0]; 4678 leaf->is_static = 1; 4679 block = leaf->block; 4680 block->media_code = MEDIA_MII; 4681 block->type = 1; /* MII Block type 1 */ 4682 block->command = 1; /* Port select */ 4683 block->gprseqlen = 0; 4684 block->rstseqlen = 0; 4685 4686 /* ASANTE FAKE SROM */ 4687 leaf = &leaf_asante; 4688 leaf->is_static = 1; 4689 leaf->default_block = &leaf->block[0]; 4690 leaf->block_count = 1; 4691 block = leaf->block; 4692 block->media_code = MEDIA_MII; 4693 block->type = 1; /* MII Block type 1 */ 4694 block->command = 1; /* Port select */ 4695 block->gprseqlen = 3; 4696 block->rstseqlen = 0; 4697 block->gprseq[0] = 0x180; 4698 block->gprseq[1] = 0x80; 4699 block->gprseq[2] = 0x0; 4700 4701 /* LEGACY 21041 card FAKE SROM */ 4702 leaf = &leaf_21041; 4703 leaf->is_static = 1; 4704 leaf->block_count = 4; /* SIA Blocks for TP, TPfd, BNC, AUI */ 4705 leaf->default_block = &leaf->block[3]; 4706 4707 block = leaf->block; 4708 block->media_code = MEDIA_AUI; 4709 block->type = 2; 4710 block->un.sia.csr13 = 0xef09; 4711 block->un.sia.csr14 = 0x0705; 4712 block->un.sia.csr15 = 0x000e; 4713 4714 block++; 4715 block->media_code = MEDIA_TP_FD; 4716 block->type = 2; 4717 block->un.sia.csr13 = 0xef01; 4718 block->un.sia.csr14 = 0x7f3d; 4719 block->un.sia.csr15 = 0x0008; 4720 4721 block++; 4722 block->media_code = MEDIA_BNC; 4723 block->type = 2; 4724 block->un.sia.csr13 = 0xef09; 4725 block->un.sia.csr14 = 0x0705; 4726 block->un.sia.csr15 = 0x0006; 4727 4728 block++; 4729 block->media_code = MEDIA_TP; 4730 block->type = 2; 4731 block->un.sia.csr13 = 0xef01; 4732 block->un.sia.csr14 = 0x7f3f; 4733 block->un.sia.csr15 = 0x0008; 4734 4735 /* LEGACY 21040 card FAKE SROM */ 4736 leaf = &leaf_21040; 4737 leaf->is_static = 1; 4738 leaf->block_count = 4; /* SIA Blocks for TP, TPfd, BNC, AUI */ 4739 block = leaf->block; 4740 block->media_code = MEDIA_AUI; 4741 block->type = 2; 4742 block->un.sia.csr13 = 0x8f09; 4743 block->un.sia.csr14 = 0x0705; 4744 block->un.sia.csr15 = 0x000e; 4745 block++; 4746 block->media_code = MEDIA_TP_FD; 4747 block->type = 2; 4748 block->un.sia.csr13 = 0x0f01; 4749 block->un.sia.csr14 = 0x7f3d; 4750 block->un.sia.csr15 = 0x0008; 4751 block++; 4752 block->media_code = MEDIA_BNC; 4753 block->type = 2; 4754 block->un.sia.csr13 = 0xef09; 4755 block->un.sia.csr14 = 0x0705; 4756 block->un.sia.csr15 = 0x0006; 4757 block++; 4758 block->media_code = MEDIA_TP; 4759 block->type = 2; 4760 block->un.sia.csr13 = 0x8f01; 4761 block->un.sia.csr14 = 0x7f3f; 4762 block->un.sia.csr15 = 0x0008; 4763 } 4764 4765 static void 4766 dnet_print_srom(SROM_FORMAT *sr) 4767 { 4768 int i; 4769 uchar_t *a = sr->netaddr; 4770 cmn_err(CE_NOTE, "SROM Dump: %d. ver %d, Num adapters %d," 4771 "Addr:%x:%x:%x:%x:%x:%x", 4772 sr->init_from_srom, sr->version, sr->adapters, 4773 a[0], a[1], a[2], a[3], a[4], a[5]); 4774 4775 for (i = 0; i < sr->adapters; i++) 4776 dnet_dump_leaf(sr->leaf+i); 4777 } 4778 4779 static void 4780 dnet_dump_leaf(LEAF_FORMAT *leaf) 4781 { 4782 int i; 4783 cmn_err(CE_NOTE, "Leaf: Device %d, block_count %d, gpr: %x", 4784 leaf->device_number, leaf->block_count, leaf->gpr); 4785 for (i = 0; i < leaf->block_count; i++) 4786 dnet_dump_block(leaf->block+i); 4787 } 4788 4789 static void 4790 dnet_dump_block(media_block_t *block) 4791 { 4792 cmn_err(CE_NOTE, "Block(%p): type %x, media %s, command: %x ", 4793 (void *)block, 4794 block->type, media_str[block->media_code], block->command); 4795 dnet_dumpbin("\tGPR Seq", (uchar_t *)block->gprseq, 2, 4796 block->gprseqlen *2); 4797 dnet_dumpbin("\tGPR Reset", (uchar_t *)block->rstseq, 2, 4798 block->rstseqlen *2); 4799 switch (block->type) { 4800 case 1: case 3: 4801 cmn_err(CE_NOTE, "\tMII Info: phy %d, nway %x, fdx" 4802 "%x, ttm %x, mediacap %x", 4803 block->un.mii.phy_num, block->un.mii.nwayadvert, 4804 block->un.mii.fdxmask, block->un.mii.ttmmask, 4805 block->un.mii.mediacaps); 4806 break; 4807 case 2: 4808 cmn_err(CE_NOTE, "\tSIA Regs: CSR13:%x, CSR14:%x, CSR15:%x", 4809 block->un.sia.csr13, block->un.sia.csr14, 4810 block->un.sia.csr15); 4811 break; 4812 } 4813 } 4814 4815 4816 /* Utility to print out binary info dumps. Handy for SROMs, etc */ 4817 4818 static int 4819 hexcode(unsigned val) 4820 { 4821 if (val <= 9) 4822 return (val +'0'); 4823 if (val <= 15) 4824 return (val + 'a' - 10); 4825 return (-1); 4826 } 4827 4828 static void 4829 dnet_dumpbin(char *msg, unsigned char *data, int size, int len) 4830 { 4831 char hex[128], *p = hex; 4832 char ascii[128], *q = ascii; 4833 int i, j; 4834 4835 if (!len) 4836 return; 4837 4838 for (i = 0; i < len; i += size) { 4839 for (j = size - 1; j >= 0; j--) { /* PORTABILITY: byte order */ 4840 *p++ = hexcode(data[i+j] >> 4); 4841 *p++ = hexcode(data[i+j] & 0xf); 4842 *q++ = (data[i+j] < 32 || data[i+j] > 127) ? 4843 '.' : data[i]; 4844 } 4845 *p++ = ' '; 4846 if (q-ascii >= 8) { 4847 *p = *q = 0; 4848 cmn_err(CE_NOTE, "%s: %s\t%s", msg, hex, ascii); 4849 p = hex; 4850 q = ascii; 4851 } 4852 } 4853 if (p != hex) { 4854 while ((p - hex) < 8*3) 4855 *p++ = ' '; 4856 *p = *q = 0; 4857 cmn_err(CE_NOTE, "%s: %s\t%s", msg, hex, ascii); 4858 } 4859 } 4860 4861 #ifdef DNETDEBUG 4862 void 4863 dnet_usectimeout(struct dnetinstance *dnetp, uint32_t usecs, int contin, 4864 timercb_t cback) 4865 { 4866 mutex_enter(&dnetp->intrlock); 4867 dnetp->timer.start_ticks = (usecs * 100) / 8192; 4868 dnetp->timer.cb = cback; 4869 ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, GP_TIMER_REG), 4870 dnetp->timer.start_ticks | (contin ? GPTIMER_CONT : 0)); 4871 if (dnetp->timer.cb) 4872 enable_interrupts(dnetp, 1); 4873 mutex_exit(&dnetp->intrlock); 4874 } 4875 4876 uint32_t 4877 dnet_usecelapsed(struct dnetinstance *dnetp) 4878 { 4879 uint32_t ticks = dnetp->timer.start_ticks - 4880 (ddi_get32(dnetp->io_handle, REG32(dnetp->io_reg, GP_TIMER_REG)) & 4881 0xffff); 4882 return ((ticks * 8192) / 100); 4883 } 4884 4885 /* ARGSUSED */ 4886 void 4887 dnet_timestamp(struct dnetinstance *dnetp, char *buf) 4888 { 4889 uint32_t elapsed = dnet_usecelapsed(dnetp); 4890 char loc[32], *p = loc; 4891 int firstdigit = 1; 4892 uint32_t divisor; 4893 4894 while (*p++ = *buf++) 4895 ; 4896 p--; 4897 4898 for (divisor = 1000000000; divisor /= 10; ) { 4899 int digit = (elapsed / divisor); 4900 elapsed -= digit * divisor; 4901 if (!firstdigit || digit) { 4902 *p++ = digit + '0'; 4903 firstdigit = 0; 4904 } 4905 4906 } 4907 4908 /* Actual zero, output it */ 4909 if (firstdigit) 4910 *p++ = '0'; 4911 4912 *p++ = '-'; 4913 *p++ = '>'; 4914 *p++ = 0; 4915 4916 printf(loc); 4917 dnet_usectimeout(dnetp, 1000000, 0, 0); 4918 } 4919 4920 #endif 4921