1 /* 2 * Solaris driver for ethernet cards based on the Macronix 98715 3 * 4 * Copyright (c) 2007 by Garrett D'Amore <garrett@damore.org>. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the author nor the names of any co-contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 /* 32 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 33 * Use is subject to license terms. 34 */ 35 36 37 #include <sys/varargs.h> 38 #include <sys/types.h> 39 #include <sys/modctl.h> 40 #include <sys/conf.h> 41 #include <sys/devops.h> 42 #include <sys/stream.h> 43 #include <sys/strsun.h> 44 #include <sys/cmn_err.h> 45 #include <sys/dlpi.h> 46 #include <sys/ethernet.h> 47 #include <sys/kmem.h> 48 #include <sys/time.h> 49 #include <sys/miiregs.h> 50 #include <sys/strsun.h> 51 #include <sys/mac.h> 52 #include <sys/mac_ether.h> 53 #include <sys/ddi.h> 54 #include <sys/sunddi.h> 55 #include <sys/vlan.h> 56 57 #include "mxfe.h" 58 #include "mxfeimpl.h" 59 60 /* 61 * Driver globals. 62 */ 63 64 /* patchable debug flag ... must not be static! */ 65 #ifdef DEBUG 66 unsigned mxfe_debug = DWARN; 67 #endif 68 69 /* table of supported devices */ 70 static mxfe_card_t mxfe_cards[] = { 71 72 /* 73 * Lite-On products 74 */ 75 { 0x11ad, 0xc115, 0, 0, "Lite-On LC82C115", MXFE_PNICII }, 76 77 /* 78 * Macronix chips 79 */ 80 { 0x10d9, 0x0531, 0x25, 0xff, "Macronix MX98715AEC", MXFE_98715AEC }, 81 { 0x10d9, 0x0531, 0x20, 0xff, "Macronix MX98715A", MXFE_98715A }, 82 { 0x10d9, 0x0531, 0x60, 0xff, "Macronix MX98715B", MXFE_98715B }, 83 { 0x10d9, 0x0531, 0x30, 0xff, "Macronix MX98725", MXFE_98725 }, 84 { 0x10d9, 0x0531, 0x00, 0xff, "Macronix MX98715", MXFE_98715 }, 85 { 0x10d9, 0x0512, 0, 0, "Macronix MX98713", MXFE_98713 }, 86 87 /* 88 * Compex (relabeled Macronix products) 89 */ 90 { 0x11fc, 0x9881, 0x00, 0x00, "Compex 9881", MXFE_98713 }, 91 { 0x11fc, 0x9881, 0x10, 0xff, "Compex 9881A", MXFE_98713A }, 92 /* 93 * Models listed here 94 */ 95 { 0x11ad, 0xc001, 0, 0, "Linksys LNE100TX", MXFE_PNICII }, 96 { 0x2646, 0x000b, 0, 0, "Kingston KNE111TX", MXFE_PNICII }, 97 { 0x1154, 0x0308, 0, 0, "Buffalo LGY-PCI-TXL", MXFE_98715AEC }, 98 }; 99 100 #define ETHERVLANMTU (ETHERMAX + 4) 101 102 /* 103 * Function prototypes 104 */ 105 static int mxfe_attach(dev_info_t *, ddi_attach_cmd_t); 106 static int mxfe_detach(dev_info_t *, ddi_detach_cmd_t); 107 static int mxfe_resume(dev_info_t *); 108 static int mxfe_quiesce(dev_info_t *); 109 static int mxfe_m_unicst(void *, const uint8_t *); 110 static int mxfe_m_multicst(void *, boolean_t, const uint8_t *); 111 static int mxfe_m_promisc(void *, boolean_t); 112 static mblk_t *mxfe_m_tx(void *, mblk_t *); 113 static int mxfe_m_stat(void *, uint_t, uint64_t *); 114 static int mxfe_m_start(void *); 115 static void mxfe_m_stop(void *); 116 static int mxfe_m_getprop(void *, const char *, mac_prop_id_t, uint_t, 117 void *); 118 static int mxfe_m_setprop(void *, const char *, mac_prop_id_t, uint_t, 119 const void *); 120 static void mxfe_m_propinfo(void *, const char *, mac_prop_id_t, 121 mac_prop_info_handle_t); 122 static unsigned mxfe_intr(caddr_t); 123 static void mxfe_startmac(mxfe_t *); 124 static void mxfe_stopmac(mxfe_t *); 125 static void mxfe_resetrings(mxfe_t *); 126 static boolean_t mxfe_initialize(mxfe_t *); 127 static void mxfe_startall(mxfe_t *); 128 static void mxfe_stopall(mxfe_t *); 129 static void mxfe_resetall(mxfe_t *); 130 static mxfe_txbuf_t *mxfe_alloctxbuf(mxfe_t *); 131 static void mxfe_destroytxbuf(mxfe_txbuf_t *); 132 static mxfe_rxbuf_t *mxfe_allocrxbuf(mxfe_t *); 133 static void mxfe_destroyrxbuf(mxfe_rxbuf_t *); 134 static void mxfe_send_setup(mxfe_t *); 135 static boolean_t mxfe_send(mxfe_t *, mblk_t *); 136 static int mxfe_allocrxring(mxfe_t *); 137 static void mxfe_freerxring(mxfe_t *); 138 static int mxfe_alloctxring(mxfe_t *); 139 static void mxfe_freetxring(mxfe_t *); 140 static void mxfe_error(dev_info_t *, char *, ...); 141 static uint8_t mxfe_sromwidth(mxfe_t *); 142 static uint16_t mxfe_readsromword(mxfe_t *, unsigned); 143 static void mxfe_readsrom(mxfe_t *, unsigned, unsigned, void *); 144 static void mxfe_getfactaddr(mxfe_t *, uchar_t *); 145 static uint8_t mxfe_miireadbit(mxfe_t *); 146 static void mxfe_miiwritebit(mxfe_t *, uint8_t); 147 static void mxfe_miitristate(mxfe_t *); 148 static uint16_t mxfe_miiread(mxfe_t *, int, int); 149 static void mxfe_miiwrite(mxfe_t *, int, int, uint16_t); 150 static uint16_t mxfe_miireadgeneral(mxfe_t *, int, int); 151 static void mxfe_miiwritegeneral(mxfe_t *, int, int, uint16_t); 152 static uint16_t mxfe_miiread98713(mxfe_t *, int, int); 153 static void mxfe_miiwrite98713(mxfe_t *, int, int, uint16_t); 154 static void mxfe_startphy(mxfe_t *); 155 static void mxfe_stopphy(mxfe_t *); 156 static void mxfe_startphymii(mxfe_t *); 157 static void mxfe_startphynway(mxfe_t *); 158 static void mxfe_startnway(mxfe_t *); 159 static void mxfe_reportlink(mxfe_t *); 160 static void mxfe_checklink(mxfe_t *); 161 static void mxfe_checklinkmii(mxfe_t *); 162 static void mxfe_checklinknway(mxfe_t *); 163 static void mxfe_disableinterrupts(mxfe_t *); 164 static void mxfe_enableinterrupts(mxfe_t *); 165 static void mxfe_reclaim(mxfe_t *); 166 static boolean_t mxfe_receive(mxfe_t *, mblk_t **); 167 168 #ifdef DEBUG 169 static void mxfe_dprintf(mxfe_t *, const char *, int, char *, ...); 170 #endif 171 172 #define KIOIP KSTAT_INTR_PTR(mxfep->mxfe_intrstat) 173 174 static mac_callbacks_t mxfe_m_callbacks = { 175 MC_SETPROP | MC_GETPROP | MC_PROPINFO, 176 mxfe_m_stat, 177 mxfe_m_start, 178 mxfe_m_stop, 179 mxfe_m_promisc, 180 mxfe_m_multicst, 181 mxfe_m_unicst, 182 mxfe_m_tx, 183 NULL, 184 NULL, /* mc_ioctl */ 185 NULL, /* mc_getcapab */ 186 NULL, /* mc_open */ 187 NULL, /* mc_close */ 188 mxfe_m_setprop, 189 mxfe_m_getprop, 190 mxfe_m_propinfo 191 }; 192 193 /* 194 * Stream information 195 */ 196 DDI_DEFINE_STREAM_OPS(mxfe_devops, nulldev, nulldev, mxfe_attach, mxfe_detach, 197 nodev, NULL, D_MP, NULL, mxfe_quiesce); 198 199 /* 200 * Module linkage information. 201 */ 202 203 static struct modldrv mxfe_modldrv = { 204 &mod_driverops, /* drv_modops */ 205 "Macronix Fast Ethernet", /* drv_linkinfo */ 206 &mxfe_devops /* drv_dev_ops */ 207 }; 208 209 static struct modlinkage mxfe_modlinkage = { 210 MODREV_1, /* ml_rev */ 211 { &mxfe_modldrv, NULL } /* ml_linkage */ 212 }; 213 214 /* 215 * Device attributes. 216 */ 217 static ddi_device_acc_attr_t mxfe_devattr = { 218 DDI_DEVICE_ATTR_V0, 219 DDI_STRUCTURE_LE_ACC, 220 DDI_STRICTORDER_ACC 221 }; 222 223 static ddi_device_acc_attr_t mxfe_bufattr = { 224 DDI_DEVICE_ATTR_V0, 225 DDI_NEVERSWAP_ACC, 226 DDI_STRICTORDER_ACC 227 }; 228 229 static ddi_dma_attr_t mxfe_dma_attr = { 230 DMA_ATTR_V0, /* dma_attr_version */ 231 0, /* dma_attr_addr_lo */ 232 0xFFFFFFFFU, /* dma_attr_addr_hi */ 233 0x7FFFFFFFU, /* dma_attr_count_max */ 234 4, /* dma_attr_align */ 235 0x3F, /* dma_attr_burstsizes */ 236 1, /* dma_attr_minxfer */ 237 0xFFFFFFFFU, /* dma_attr_maxxfer */ 238 0xFFFFFFFFU, /* dma_attr_seg */ 239 1, /* dma_attr_sgllen */ 240 1, /* dma_attr_granular */ 241 0 /* dma_attr_flags */ 242 }; 243 244 /* 245 * Tx buffers can be arbitrarily aligned. Additionally, they can 246 * cross a page boundary, so we use the two buffer addresses of the 247 * chip to provide a two-entry scatter-gather list. 248 */ 249 static ddi_dma_attr_t mxfe_dma_txattr = { 250 DMA_ATTR_V0, /* dma_attr_version */ 251 0, /* dma_attr_addr_lo */ 252 0xFFFFFFFFU, /* dma_attr_addr_hi */ 253 0x7FFFFFFFU, /* dma_attr_count_max */ 254 1, /* dma_attr_align */ 255 0x3F, /* dma_attr_burstsizes */ 256 1, /* dma_attr_minxfer */ 257 0xFFFFFFFFU, /* dma_attr_maxxfer */ 258 0xFFFFFFFFU, /* dma_attr_seg */ 259 2, /* dma_attr_sgllen */ 260 1, /* dma_attr_granular */ 261 0 /* dma_attr_flags */ 262 }; 263 264 /* 265 * Ethernet addresses. 266 */ 267 static uchar_t mxfe_broadcast[ETHERADDRL] = { 268 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 269 }; 270 271 /* 272 * DDI entry points. 273 */ 274 int 275 _init(void) 276 { 277 int rv; 278 mac_init_ops(&mxfe_devops, "mxfe"); 279 if ((rv = mod_install(&mxfe_modlinkage)) != DDI_SUCCESS) { 280 mac_fini_ops(&mxfe_devops); 281 } 282 return (rv); 283 } 284 285 int 286 _fini(void) 287 { 288 int rv; 289 if ((rv = mod_remove(&mxfe_modlinkage)) == DDI_SUCCESS) { 290 mac_fini_ops(&mxfe_devops); 291 } 292 return (rv); 293 } 294 295 int 296 _info(struct modinfo *modinfop) 297 { 298 return (mod_info(&mxfe_modlinkage, modinfop)); 299 } 300 301 int 302 mxfe_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 303 { 304 mxfe_t *mxfep; 305 mac_register_t *macp; 306 int inst = ddi_get_instance(dip); 307 ddi_acc_handle_t pci; 308 uint16_t venid; 309 uint16_t devid; 310 uint16_t revid; 311 uint16_t svid; 312 uint16_t ssid; 313 uint16_t cachesize; 314 mxfe_card_t *cardp; 315 int i; 316 317 switch (cmd) { 318 case DDI_RESUME: 319 return (mxfe_resume(dip)); 320 321 case DDI_ATTACH: 322 break; 323 324 default: 325 return (DDI_FAILURE); 326 } 327 328 /* this card is a bus master, reject any slave-only slot */ 329 if (ddi_slaveonly(dip) == DDI_SUCCESS) { 330 mxfe_error(dip, "slot does not support PCI bus-master"); 331 return (DDI_FAILURE); 332 } 333 /* PCI devices shouldn't generate hilevel interrupts */ 334 if (ddi_intr_hilevel(dip, 0) != 0) { 335 mxfe_error(dip, "hilevel interrupts not supported"); 336 return (DDI_FAILURE); 337 } 338 if (pci_config_setup(dip, &pci) != DDI_SUCCESS) { 339 mxfe_error(dip, "unable to setup PCI config handle"); 340 return (DDI_FAILURE); 341 } 342 343 venid = pci_config_get16(pci, PCI_VID); 344 devid = pci_config_get16(pci, PCI_DID); 345 revid = pci_config_get16(pci, PCI_RID); 346 svid = pci_config_get16(pci, PCI_SVID); 347 ssid = pci_config_get16(pci, PCI_SSID); 348 349 /* 350 * the last entry in the card table matches every possible 351 * card, so the for-loop always terminates properly. 352 */ 353 cardp = NULL; 354 for (i = 0; i < (sizeof (mxfe_cards) / sizeof (mxfe_card_t)); i++) { 355 if ((venid == mxfe_cards[i].card_venid) && 356 (devid == mxfe_cards[i].card_devid) && 357 ((revid & mxfe_cards[i].card_revmask) == 358 mxfe_cards[i].card_revid)) { 359 cardp = &mxfe_cards[i]; 360 } 361 if ((svid == mxfe_cards[i].card_venid) && 362 (ssid == mxfe_cards[i].card_devid) && 363 ((revid & mxfe_cards[i].card_revmask) == 364 mxfe_cards[i].card_revid)) { 365 cardp = &mxfe_cards[i]; 366 break; 367 } 368 } 369 370 if (cardp == NULL) { 371 pci_config_teardown(&pci); 372 mxfe_error(dip, "Unable to identify PCI card"); 373 return (DDI_FAILURE); 374 } 375 376 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, "model", 377 cardp->card_cardname) != DDI_PROP_SUCCESS) { 378 pci_config_teardown(&pci); 379 mxfe_error(dip, "Unable to create model property"); 380 return (DDI_FAILURE); 381 } 382 383 /* 384 * Grab the PCI cachesize -- we use this to program the 385 * cache-optimization bus access bits. 386 */ 387 cachesize = pci_config_get8(pci, PCI_CLS); 388 389 /* this cannot fail */ 390 mxfep = kmem_zalloc(sizeof (mxfe_t), KM_SLEEP); 391 ddi_set_driver_private(dip, mxfep); 392 393 /* get the interrupt block cookie */ 394 if (ddi_get_iblock_cookie(dip, 0, &mxfep->mxfe_icookie) 395 != DDI_SUCCESS) { 396 mxfe_error(dip, "ddi_get_iblock_cookie failed"); 397 pci_config_teardown(&pci); 398 kmem_free(mxfep, sizeof (mxfe_t)); 399 return (DDI_FAILURE); 400 } 401 402 mxfep->mxfe_dip = dip; 403 mxfep->mxfe_cardp = cardp; 404 mxfep->mxfe_phyaddr = -1; 405 mxfep->mxfe_cachesize = cachesize; 406 407 /* default properties */ 408 mxfep->mxfe_adv_aneg = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 409 "adv_autoneg_cap", 1); 410 mxfep->mxfe_adv_100T4 = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 411 "adv_100T4_cap", 1); 412 mxfep->mxfe_adv_100fdx = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 413 "adv_100fdx_cap", 1); 414 mxfep->mxfe_adv_100hdx = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 415 "adv_100hdx_cap", 1); 416 mxfep->mxfe_adv_10fdx = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 417 "adv_10fdx_cap", 1); 418 mxfep->mxfe_adv_10hdx = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 419 "adv_10hdx_cap", 1); 420 421 DBG(DPCI, "PCI vendor id = %x", venid); 422 DBG(DPCI, "PCI device id = %x", devid); 423 DBG(DPCI, "PCI revision id = %x", revid); 424 DBG(DPCI, "PCI cachesize = %d", cachesize); 425 DBG(DPCI, "PCI COMM = %x", pci_config_get8(pci, PCI_CMD)); 426 DBG(DPCI, "PCI STAT = %x", pci_config_get8(pci, PCI_STAT)); 427 428 mutex_init(&mxfep->mxfe_xmtlock, NULL, MUTEX_DRIVER, 429 mxfep->mxfe_icookie); 430 mutex_init(&mxfep->mxfe_intrlock, NULL, MUTEX_DRIVER, 431 mxfep->mxfe_icookie); 432 433 /* 434 * Enable bus master, IO space, and memory space accesses. 435 */ 436 pci_config_put16(pci, PCI_CMD, 437 pci_config_get16(pci, PCI_CMD) | 438 PCI_CMD_BME | PCI_CMD_MAE | PCI_CMD_MWIE); 439 440 /* we're done with this now, drop it */ 441 pci_config_teardown(&pci); 442 443 /* 444 * Initialize interrupt kstat. This should not normally fail, since 445 * we don't use a persistent stat. We do it this way to avoid having 446 * to test for it at run time on the hot path. 447 */ 448 mxfep->mxfe_intrstat = kstat_create("mxfe", inst, "intr", "controller", 449 KSTAT_TYPE_INTR, 1, 0); 450 if (mxfep->mxfe_intrstat == NULL) { 451 mxfe_error(dip, "kstat_create failed"); 452 goto failed; 453 } 454 kstat_install(mxfep->mxfe_intrstat); 455 456 /* 457 * Map in the device registers. 458 */ 459 if (ddi_regs_map_setup(dip, 1, (caddr_t *)&mxfep->mxfe_regs, 460 0, 0, &mxfe_devattr, &mxfep->mxfe_regshandle)) { 461 mxfe_error(dip, "ddi_regs_map_setup failed"); 462 goto failed; 463 } 464 465 /* 466 * Allocate DMA resources (descriptor rings and buffers). 467 */ 468 if ((mxfe_allocrxring(mxfep) != DDI_SUCCESS) || 469 (mxfe_alloctxring(mxfep) != DDI_SUCCESS)) { 470 mxfe_error(dip, "unable to allocate DMA resources"); 471 goto failed; 472 } 473 474 /* Initialize the chip. */ 475 mutex_enter(&mxfep->mxfe_intrlock); 476 mutex_enter(&mxfep->mxfe_xmtlock); 477 if (!mxfe_initialize(mxfep)) { 478 mutex_exit(&mxfep->mxfe_xmtlock); 479 mutex_exit(&mxfep->mxfe_intrlock); 480 goto failed; 481 } 482 mutex_exit(&mxfep->mxfe_xmtlock); 483 mutex_exit(&mxfep->mxfe_intrlock); 484 485 /* Determine the number of address bits to our EEPROM. */ 486 mxfep->mxfe_sromwidth = mxfe_sromwidth(mxfep); 487 488 /* 489 * Get the factory ethernet address. This becomes the current 490 * ethernet address (it can be overridden later via ifconfig). 491 */ 492 mxfe_getfactaddr(mxfep, mxfep->mxfe_curraddr); 493 mxfep->mxfe_promisc = B_FALSE; 494 495 /* 496 * Establish interrupt handler. 497 */ 498 if (ddi_add_intr(dip, 0, NULL, NULL, mxfe_intr, (caddr_t)mxfep) != 499 DDI_SUCCESS) { 500 mxfe_error(dip, "unable to add interrupt"); 501 goto failed; 502 } 503 504 /* TODO: do the power management stuff */ 505 506 if ((macp = mac_alloc(MAC_VERSION)) == NULL) { 507 mxfe_error(dip, "mac_alloc failed"); 508 goto failed; 509 } 510 511 macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 512 macp->m_driver = mxfep; 513 macp->m_dip = dip; 514 macp->m_src_addr = mxfep->mxfe_curraddr; 515 macp->m_callbacks = &mxfe_m_callbacks; 516 macp->m_min_sdu = 0; 517 macp->m_max_sdu = ETHERMTU; 518 macp->m_margin = VLAN_TAGSZ; 519 520 if (mac_register(macp, &mxfep->mxfe_mh) == DDI_SUCCESS) { 521 mac_free(macp); 522 return (DDI_SUCCESS); 523 } 524 525 /* failed to register with MAC */ 526 mac_free(macp); 527 failed: 528 if (mxfep->mxfe_icookie != NULL) { 529 ddi_remove_intr(dip, 0, mxfep->mxfe_icookie); 530 } 531 if (mxfep->mxfe_intrstat) { 532 kstat_delete(mxfep->mxfe_intrstat); 533 } 534 mutex_destroy(&mxfep->mxfe_intrlock); 535 mutex_destroy(&mxfep->mxfe_xmtlock); 536 537 mxfe_freerxring(mxfep); 538 mxfe_freetxring(mxfep); 539 540 if (mxfep->mxfe_regshandle != NULL) { 541 ddi_regs_map_free(&mxfep->mxfe_regshandle); 542 } 543 kmem_free(mxfep, sizeof (mxfe_t)); 544 return (DDI_FAILURE); 545 } 546 547 int 548 mxfe_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 549 { 550 mxfe_t *mxfep; 551 552 mxfep = ddi_get_driver_private(dip); 553 if (mxfep == NULL) { 554 mxfe_error(dip, "no soft state in detach!"); 555 return (DDI_FAILURE); 556 } 557 558 switch (cmd) { 559 case DDI_DETACH: 560 561 if (mac_unregister(mxfep->mxfe_mh) != 0) { 562 return (DDI_FAILURE); 563 } 564 565 /* make sure hardware is quiesced */ 566 mutex_enter(&mxfep->mxfe_intrlock); 567 mutex_enter(&mxfep->mxfe_xmtlock); 568 mxfep->mxfe_flags &= ~MXFE_RUNNING; 569 mxfe_stopall(mxfep); 570 mutex_exit(&mxfep->mxfe_xmtlock); 571 mutex_exit(&mxfep->mxfe_intrlock); 572 573 /* clean up and shut down device */ 574 ddi_remove_intr(dip, 0, mxfep->mxfe_icookie); 575 576 /* clean up kstats */ 577 kstat_delete(mxfep->mxfe_intrstat); 578 579 ddi_prop_remove_all(dip); 580 581 /* free up any left over buffers or DMA resources */ 582 mxfe_freerxring(mxfep); 583 mxfe_freetxring(mxfep); 584 585 ddi_regs_map_free(&mxfep->mxfe_regshandle); 586 mutex_destroy(&mxfep->mxfe_intrlock); 587 mutex_destroy(&mxfep->mxfe_xmtlock); 588 589 kmem_free(mxfep, sizeof (mxfe_t)); 590 return (DDI_SUCCESS); 591 592 case DDI_SUSPEND: 593 /* quiesce the hardware */ 594 mutex_enter(&mxfep->mxfe_intrlock); 595 mutex_enter(&mxfep->mxfe_xmtlock); 596 mxfep->mxfe_flags |= MXFE_SUSPENDED; 597 mxfe_stopall(mxfep); 598 mutex_exit(&mxfep->mxfe_xmtlock); 599 mutex_exit(&mxfep->mxfe_intrlock); 600 return (DDI_SUCCESS); 601 default: 602 return (DDI_FAILURE); 603 } 604 } 605 606 int 607 mxfe_resume(dev_info_t *dip) 608 { 609 mxfe_t *mxfep; 610 611 if ((mxfep = ddi_get_driver_private(dip)) == NULL) { 612 return (DDI_FAILURE); 613 } 614 615 mutex_enter(&mxfep->mxfe_intrlock); 616 mutex_enter(&mxfep->mxfe_xmtlock); 617 618 mxfep->mxfe_flags &= ~MXFE_SUSPENDED; 619 620 /* re-initialize chip */ 621 if (!mxfe_initialize(mxfep)) { 622 mxfe_error(mxfep->mxfe_dip, "unable to resume chip!"); 623 mxfep->mxfe_flags |= MXFE_SUSPENDED; 624 mutex_exit(&mxfep->mxfe_intrlock); 625 mutex_exit(&mxfep->mxfe_xmtlock); 626 return (DDI_SUCCESS); 627 } 628 629 /* start the chip */ 630 if (mxfep->mxfe_flags & MXFE_RUNNING) { 631 mxfe_startall(mxfep); 632 } 633 634 /* drop locks */ 635 mutex_exit(&mxfep->mxfe_xmtlock); 636 mutex_exit(&mxfep->mxfe_intrlock); 637 638 return (DDI_SUCCESS); 639 } 640 641 int 642 mxfe_quiesce(dev_info_t *dip) 643 { 644 mxfe_t *mxfep; 645 646 if ((mxfep = ddi_get_driver_private(dip)) == NULL) { 647 return (DDI_FAILURE); 648 } 649 650 /* just do a hard reset of everything */ 651 SETBIT(mxfep, CSR_PAR, PAR_RESET); 652 653 return (DDI_SUCCESS); 654 } 655 656 /*ARGSUSED*/ 657 int 658 mxfe_m_multicst(void *arg, boolean_t add, const uint8_t *macaddr) 659 { 660 /* we already receive all multicast frames */ 661 return (0); 662 } 663 664 int 665 mxfe_m_promisc(void *arg, boolean_t on) 666 { 667 mxfe_t *mxfep = arg; 668 669 /* exclusive access to the card while we reprogram it */ 670 mutex_enter(&mxfep->mxfe_intrlock); 671 mutex_enter(&mxfep->mxfe_xmtlock); 672 /* save current promiscuous mode state for replay in resume */ 673 mxfep->mxfe_promisc = on; 674 675 if ((mxfep->mxfe_flags & (MXFE_RUNNING|MXFE_SUSPENDED)) == 676 MXFE_RUNNING) { 677 if (on) 678 SETBIT(mxfep, CSR_NAR, NAR_RX_PROMISC); 679 else 680 CLRBIT(mxfep, CSR_NAR, NAR_RX_PROMISC); 681 } 682 683 mutex_exit(&mxfep->mxfe_xmtlock); 684 mutex_exit(&mxfep->mxfe_intrlock); 685 686 return (0); 687 } 688 689 int 690 mxfe_m_unicst(void *arg, const uint8_t *macaddr) 691 { 692 mxfe_t *mxfep = arg; 693 694 mutex_enter(&mxfep->mxfe_intrlock); 695 mutex_enter(&mxfep->mxfe_xmtlock); 696 bcopy(macaddr, mxfep->mxfe_curraddr, ETHERADDRL); 697 698 mxfe_resetall(mxfep); 699 700 mutex_exit(&mxfep->mxfe_intrlock); 701 mutex_exit(&mxfep->mxfe_xmtlock); 702 703 return (0); 704 } 705 706 mblk_t * 707 mxfe_m_tx(void *arg, mblk_t *mp) 708 { 709 mxfe_t *mxfep = arg; 710 mblk_t *nmp; 711 712 mutex_enter(&mxfep->mxfe_xmtlock); 713 714 if (mxfep->mxfe_flags & MXFE_SUSPENDED) { 715 mutex_exit(&mxfep->mxfe_xmtlock); 716 return (mp); 717 } 718 719 while (mp != NULL) { 720 nmp = mp->b_next; 721 mp->b_next = NULL; 722 723 if (!mxfe_send(mxfep, mp)) { 724 mp->b_next = nmp; 725 break; 726 } 727 mp = nmp; 728 } 729 mutex_exit(&mxfep->mxfe_xmtlock); 730 731 return (mp); 732 } 733 734 /* 735 * Hardware management. 736 */ 737 boolean_t 738 mxfe_initialize(mxfe_t *mxfep) 739 { 740 int i; 741 unsigned val; 742 uint32_t par, nar; 743 744 ASSERT(mutex_owned(&mxfep->mxfe_intrlock)); 745 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock)); 746 747 DBG(DCHATTY, "resetting!"); 748 SETBIT(mxfep, CSR_PAR, PAR_RESET); 749 for (i = 1; i < 10; i++) { 750 drv_usecwait(5); 751 val = GETCSR(mxfep, CSR_PAR); 752 if (!(val & PAR_RESET)) { 753 break; 754 } 755 } 756 if (i == 10) { 757 mxfe_error(mxfep->mxfe_dip, "timed out waiting for reset!"); 758 return (B_FALSE); 759 } 760 761 /* initialize busctl register */ 762 par = PAR_BAR | PAR_MRME | PAR_MRLE | PAR_MWIE; 763 764 /* set the cache alignment if its supported */ 765 switch (mxfep->mxfe_cachesize) { 766 case 8: 767 par |= PAR_CALIGN_8; 768 break; 769 case 16: 770 par |= PAR_CALIGN_16; 771 break; 772 case 32: 773 par |= PAR_CALIGN_32; 774 break; 775 default: 776 par &= ~(PAR_MWIE | PAR_MRME | PAR_MRLE); 777 } 778 779 /* leave the burst length at zero, indicating infinite burst */ 780 PUTCSR(mxfep, CSR_PAR, par); 781 782 mxfe_resetrings(mxfep); 783 784 /* clear the lost packet counter (cleared on read) */ 785 (void) GETCSR(mxfep, CSR_LPC); 786 787 /* a few other NAR bits */ 788 nar = GETCSR(mxfep, CSR_NAR); 789 nar &= ~NAR_RX_HO; /* disable hash only filtering */ 790 nar |= NAR_RX_HP; /* hash perfect forwarding */ 791 nar |= NAR_RX_MULTI; /* receive all multicast */ 792 nar |= NAR_SF; /* store-and-forward */ 793 794 if (mxfep->mxfe_promisc) { 795 nar |= NAR_RX_PROMISC; 796 } else { 797 nar &= ~NAR_RX_PROMISC; 798 } 799 PUTCSR(mxfep, CSR_NAR, nar); 800 801 mxfe_send_setup(mxfep); 802 803 return (B_TRUE); 804 } 805 806 /* 807 * Serial EEPROM access - inspired by the FreeBSD implementation. 808 */ 809 810 uint8_t 811 mxfe_sromwidth(mxfe_t *mxfep) 812 { 813 int i; 814 int eeread; 815 uint8_t addrlen = 8; 816 817 eeread = SPR_SROM_READ | SPR_SROM_SEL | SPR_SROM_CHIP; 818 819 PUTCSR(mxfep, CSR_SPR, eeread & ~SPR_SROM_CHIP); 820 drv_usecwait(1); 821 PUTCSR(mxfep, CSR_SPR, eeread); 822 823 /* command bits first */ 824 for (i = 4; i != 0; i >>= 1) { 825 unsigned val = (SROM_READCMD & i) ? SPR_SROM_DIN : 0; 826 PUTCSR(mxfep, CSR_SPR, eeread | val); 827 drv_usecwait(1); 828 PUTCSR(mxfep, CSR_SPR, eeread | val | SPR_SROM_CLOCK); 829 drv_usecwait(1); 830 } 831 832 PUTCSR(mxfep, CSR_SPR, eeread); 833 834 for (addrlen = 1; addrlen <= 12; addrlen++) { 835 PUTCSR(mxfep, CSR_SPR, eeread | SPR_SROM_CLOCK); 836 drv_usecwait(1); 837 if (!(GETCSR(mxfep, CSR_SPR) & SPR_SROM_DOUT)) { 838 PUTCSR(mxfep, CSR_SPR, eeread); 839 drv_usecwait(1); 840 break; 841 } 842 PUTCSR(mxfep, CSR_SPR, eeread); 843 drv_usecwait(1); 844 } 845 846 /* turn off accesses to the EEPROM */ 847 PUTCSR(mxfep, CSR_SPR, eeread &~ SPR_SROM_CHIP); 848 849 DBG(DSROM, "detected srom width = %d bits", addrlen); 850 851 return ((addrlen < 4 || addrlen > 12) ? 6 : addrlen); 852 } 853 854 /* 855 * The words in EEPROM are stored in little endian order. We 856 * shift bits out in big endian order, though. This requires 857 * a byte swap on some platforms. 858 */ 859 uint16_t 860 mxfe_readsromword(mxfe_t *mxfep, unsigned romaddr) 861 { 862 int i; 863 uint16_t word = 0; 864 uint16_t retval; 865 int eeread; 866 uint8_t addrlen; 867 int readcmd; 868 uchar_t *ptr; 869 870 eeread = SPR_SROM_READ | SPR_SROM_SEL | SPR_SROM_CHIP; 871 addrlen = mxfep->mxfe_sromwidth; 872 readcmd = (SROM_READCMD << addrlen) | romaddr; 873 874 if (romaddr >= (1 << addrlen)) { 875 /* too big to fit! */ 876 return (0); 877 } 878 879 PUTCSR(mxfep, CSR_SPR, eeread & ~SPR_SROM_CHIP); 880 PUTCSR(mxfep, CSR_SPR, eeread); 881 882 /* command and address bits */ 883 for (i = 4 + addrlen; i >= 0; i--) { 884 short val = (readcmd & (1 << i)) ? SPR_SROM_DIN : 0; 885 PUTCSR(mxfep, CSR_SPR, eeread | val); 886 drv_usecwait(1); 887 PUTCSR(mxfep, CSR_SPR, eeread | val | SPR_SROM_CLOCK); 888 drv_usecwait(1); 889 } 890 891 PUTCSR(mxfep, CSR_SPR, eeread); 892 893 for (i = 0; i < 16; i++) { 894 PUTCSR(mxfep, CSR_SPR, eeread | SPR_SROM_CLOCK); 895 drv_usecwait(1); 896 word <<= 1; 897 if (GETCSR(mxfep, CSR_SPR) & SPR_SROM_DOUT) { 898 word |= 1; 899 } 900 PUTCSR(mxfep, CSR_SPR, eeread); 901 drv_usecwait(1); 902 } 903 904 /* turn off accesses to the EEPROM */ 905 PUTCSR(mxfep, CSR_SPR, eeread &~ SPR_SROM_CHIP); 906 907 /* 908 * Fix up the endianness thing. Note that the values 909 * are stored in little endian format on the SROM. 910 */ 911 DBG(DSROM, "got value %d from SROM (before swap)", word); 912 ptr = (uchar_t *)&word; 913 retval = (ptr[1] << 8) | ptr[0]; 914 return (retval); 915 } 916 917 void 918 mxfe_readsrom(mxfe_t *mxfep, unsigned romaddr, unsigned len, void *dest) 919 { 920 char *ptr = dest; 921 int i; 922 uint16_t word; 923 924 for (i = 0; i < len; i++) { 925 word = mxfe_readsromword(mxfep, romaddr + i); 926 bcopy(&word, ptr, 2); 927 ptr += 2; 928 DBG(DSROM, "word at %d is 0x%x", romaddr + i, word); 929 } 930 } 931 932 void 933 mxfe_getfactaddr(mxfe_t *mxfep, uchar_t *eaddr) 934 { 935 uint16_t word; 936 uchar_t *ptr; 937 938 /* first read to get the location of mac address in srom */ 939 word = mxfe_readsromword(mxfep, SROM_ENADDR / 2); 940 ptr = (uchar_t *)&word; 941 word = (ptr[1] << 8) | ptr[0]; 942 943 /* then read the actual mac address */ 944 mxfe_readsrom(mxfep, word / 2, ETHERADDRL / 2, eaddr); 945 DBG(DMACID, 946 "factory ethernet address = %02x:%02x:%02x:%02x:%02x:%02x", 947 eaddr[0], eaddr[1], eaddr[2], eaddr[3], eaddr[4], eaddr[5]); 948 } 949 950 void 951 mxfe_startphy(mxfe_t *mxfep) 952 { 953 switch (MXFE_MODEL(mxfep)) { 954 case MXFE_98713A: 955 mxfe_startphymii(mxfep); 956 break; 957 default: 958 mxfe_startphynway(mxfep); 959 break; 960 } 961 } 962 963 void 964 mxfe_stopphy(mxfe_t *mxfep) 965 { 966 uint32_t nar; 967 int i; 968 969 /* stop the phy timer */ 970 PUTCSR(mxfep, CSR_TIMER, 0); 971 972 switch (MXFE_MODEL(mxfep)) { 973 case MXFE_98713A: 974 for (i = 0; i < 32; i++) { 975 mxfe_miiwrite(mxfep, mxfep->mxfe_phyaddr, MII_CONTROL, 976 MII_CONTROL_PWRDN | MII_CONTROL_ISOLATE); 977 } 978 break; 979 default: 980 DBG(DPHY, "resetting SIA"); 981 PUTCSR(mxfep, CSR_SIA, SIA_RESET); 982 drv_usecwait(500); 983 CLRBIT(mxfep, CSR_TCTL, TCTL_PWR | TCTL_ANE); 984 nar = GETCSR(mxfep, CSR_NAR); 985 nar &= ~(NAR_PORTSEL | NAR_PCS | NAR_SCR | NAR_FDX); 986 nar |= NAR_SPEED; 987 PUTCSR(mxfep, CSR_NAR, nar); 988 break; 989 } 990 991 /* 992 * mark the link state unknown 993 */ 994 if (!mxfep->mxfe_resetting) { 995 mxfep->mxfe_linkup = LINK_STATE_UNKNOWN; 996 mxfep->mxfe_ifspeed = 0; 997 mxfep->mxfe_duplex = LINK_DUPLEX_UNKNOWN; 998 if (mxfep->mxfe_flags & MXFE_RUNNING) 999 mxfe_reportlink(mxfep); 1000 } 1001 } 1002 1003 /* 1004 * NWay support. 1005 */ 1006 void 1007 mxfe_startnway(mxfe_t *mxfep) 1008 { 1009 unsigned nar; 1010 unsigned tctl; 1011 unsigned restart; 1012 1013 /* this should not happen in a healthy system */ 1014 if (mxfep->mxfe_nwaystate != MXFE_NOLINK) { 1015 DBG(DWARN, "link start called out of state (%x)", 1016 mxfep->mxfe_nwaystate); 1017 return; 1018 } 1019 1020 if (mxfep->mxfe_adv_aneg == 0) { 1021 /* not done for forced mode */ 1022 return; 1023 } 1024 1025 nar = GETCSR(mxfep, CSR_NAR); 1026 restart = nar & (NAR_TX_ENABLE | NAR_RX_ENABLE); 1027 nar &= ~restart; 1028 1029 if (restart != 0) 1030 mxfe_stopmac(mxfep); 1031 1032 nar |= NAR_SCR | NAR_PCS | NAR_HBD; 1033 nar &= ~(NAR_FDX); 1034 1035 tctl = GETCSR(mxfep, CSR_TCTL); 1036 tctl &= ~(TCTL_100FDX | TCTL_100HDX | TCTL_HDX); 1037 1038 if (mxfep->mxfe_adv_100fdx) { 1039 tctl |= TCTL_100FDX; 1040 } 1041 if (mxfep->mxfe_adv_100hdx) { 1042 tctl |= TCTL_100HDX; 1043 } 1044 if (mxfep->mxfe_adv_10fdx) { 1045 nar |= NAR_FDX; 1046 } 1047 if (mxfep->mxfe_adv_10hdx) { 1048 tctl |= TCTL_HDX; 1049 } 1050 tctl |= TCTL_PWR | TCTL_ANE | TCTL_LTE | TCTL_RSQ; 1051 1052 /* possibly we should add in support for PAUSE frames */ 1053 DBG(DPHY, "writing nar = 0x%x", nar); 1054 PUTCSR(mxfep, CSR_NAR, nar); 1055 1056 DBG(DPHY, "writing tctl = 0x%x", tctl); 1057 PUTCSR(mxfep, CSR_TCTL, tctl); 1058 1059 /* restart autonegotation */ 1060 DBG(DPHY, "writing tstat = 0x%x", TSTAT_ANS_START); 1061 PUTCSR(mxfep, CSR_TSTAT, TSTAT_ANS_START); 1062 1063 /* restart tx/rx processes... */ 1064 if (restart != 0) 1065 mxfe_startmac(mxfep); 1066 1067 /* Macronix initializations from Bolo Tsai */ 1068 PUTCSR(mxfep, CSR_MXMAGIC, 0x0b2c0000); 1069 PUTCSR(mxfep, CSR_ACOMP, 0x11000); 1070 1071 mxfep->mxfe_nwaystate = MXFE_NWAYCHECK; 1072 } 1073 1074 void 1075 mxfe_checklinknway(mxfe_t *mxfep) 1076 { 1077 unsigned tstat; 1078 uint16_t lpar; 1079 1080 DBG(DPHY, "NWay check, state %x", mxfep->mxfe_nwaystate); 1081 tstat = GETCSR(mxfep, CSR_TSTAT); 1082 lpar = TSTAT_LPAR(tstat); 1083 1084 mxfep->mxfe_anlpar = lpar; 1085 if (tstat & TSTAT_LPN) { 1086 mxfep->mxfe_aner |= MII_AN_EXP_LPCANAN; 1087 } else { 1088 mxfep->mxfe_aner &= ~(MII_AN_EXP_LPCANAN); 1089 } 1090 1091 DBG(DPHY, "tstat(CSR12) = 0x%x", tstat); 1092 DBG(DPHY, "ANEG state = 0x%x", (tstat & TSTAT_ANS) >> 12); 1093 1094 if ((tstat & TSTAT_ANS) != TSTAT_ANS_OK) { 1095 /* autoneg did not complete */ 1096 mxfep->mxfe_bmsr &= ~MII_STATUS_ANDONE; 1097 } else { 1098 mxfep->mxfe_bmsr |= ~MII_STATUS_ANDONE; 1099 } 1100 1101 if ((tstat & TSTAT_100F) && (tstat & TSTAT_10F)) { 1102 mxfep->mxfe_linkup = LINK_STATE_DOWN; 1103 mxfep->mxfe_ifspeed = 0; 1104 mxfep->mxfe_duplex = LINK_DUPLEX_UNKNOWN; 1105 mxfep->mxfe_nwaystate = MXFE_NOLINK; 1106 mxfe_reportlink(mxfep); 1107 mxfe_startnway(mxfep); 1108 return; 1109 } 1110 1111 /* 1112 * if the link is newly up, then we might need to set various 1113 * mode bits, or negotiate for parameters, etc. 1114 */ 1115 if (mxfep->mxfe_adv_aneg) { 1116 1117 uint16_t anlpar; 1118 1119 mxfep->mxfe_linkup = LINK_STATE_UP; 1120 anlpar = mxfep->mxfe_anlpar; 1121 1122 if (tstat & TSTAT_LPN) { 1123 /* partner has NWay */ 1124 1125 if ((anlpar & MII_ABILITY_100BASE_TX_FD) && 1126 mxfep->mxfe_adv_100fdx) { 1127 mxfep->mxfe_ifspeed = 100000000; 1128 mxfep->mxfe_duplex = LINK_DUPLEX_FULL; 1129 } else if ((anlpar & MII_ABILITY_100BASE_TX) && 1130 mxfep->mxfe_adv_100hdx) { 1131 mxfep->mxfe_ifspeed = 100000000; 1132 mxfep->mxfe_duplex = LINK_DUPLEX_HALF; 1133 } else if ((anlpar & MII_ABILITY_10BASE_T_FD) && 1134 mxfep->mxfe_adv_10fdx) { 1135 mxfep->mxfe_ifspeed = 10000000; 1136 mxfep->mxfe_duplex = LINK_DUPLEX_FULL; 1137 } else if ((anlpar & MII_ABILITY_10BASE_T) && 1138 mxfep->mxfe_adv_10hdx) { 1139 mxfep->mxfe_ifspeed = 10000000; 1140 mxfep->mxfe_duplex = LINK_DUPLEX_HALF; 1141 } else { 1142 mxfep->mxfe_ifspeed = 0; 1143 } 1144 } else { 1145 /* link partner does not have NWay */ 1146 /* just assume half duplex, since we can't detect */ 1147 mxfep->mxfe_duplex = LINK_DUPLEX_HALF; 1148 if (!(tstat & TSTAT_100F)) { 1149 DBG(DPHY, "Partner doesn't have NWAY"); 1150 mxfep->mxfe_ifspeed = 100000000; 1151 } else { 1152 mxfep->mxfe_ifspeed = 10000000; 1153 } 1154 } 1155 } else { 1156 /* forced modes */ 1157 mxfep->mxfe_linkup = LINK_STATE_UP; 1158 if (mxfep->mxfe_adv_100fdx) { 1159 mxfep->mxfe_ifspeed = 100000000; 1160 mxfep->mxfe_duplex = LINK_DUPLEX_FULL; 1161 } else if (mxfep->mxfe_adv_100hdx) { 1162 mxfep->mxfe_ifspeed = 100000000; 1163 mxfep->mxfe_duplex = LINK_DUPLEX_HALF; 1164 } else if (mxfep->mxfe_adv_10fdx) { 1165 mxfep->mxfe_ifspeed = 10000000; 1166 mxfep->mxfe_duplex = LINK_DUPLEX_FULL; 1167 } else if (mxfep->mxfe_adv_10hdx) { 1168 mxfep->mxfe_ifspeed = 10000000; 1169 mxfep->mxfe_duplex = LINK_DUPLEX_HALF; 1170 } else { 1171 mxfep->mxfe_ifspeed = 0; 1172 } 1173 } 1174 mxfe_reportlink(mxfep); 1175 mxfep->mxfe_nwaystate = MXFE_GOODLINK; 1176 } 1177 1178 void 1179 mxfe_startphynway(mxfe_t *mxfep) 1180 { 1181 /* take NWay and PHY out of reset */ 1182 PUTCSR(mxfep, CSR_SIA, SIA_NRESET); 1183 drv_usecwait(500); 1184 1185 mxfep->mxfe_nwaystate = MXFE_NOLINK; 1186 mxfep->mxfe_bmsr = MII_STATUS_CANAUTONEG | 1187 MII_STATUS_100_BASEX_FD | MII_STATUS_100_BASEX | 1188 MII_STATUS_10_FD | MII_STATUS_10; 1189 mxfep->mxfe_cap_aneg = 1190 mxfep->mxfe_cap_100fdx = mxfep->mxfe_cap_100hdx = 1191 mxfep->mxfe_cap_10fdx = mxfep->mxfe_cap_10hdx = 1; 1192 1193 /* lie about the transceiver... its not really 802.3u compliant */ 1194 mxfep->mxfe_phyaddr = 0; 1195 mxfep->mxfe_phyinuse = XCVR_100X; 1196 mxfep->mxfe_phyid = 0; 1197 1198 /* 100-T4 not supported with NWay */ 1199 mxfep->mxfe_adv_100T4 = 0; 1200 mxfep->mxfe_cap_100T4 = 0; 1201 1202 /* make sure at least one valid mode is selected */ 1203 if ((!mxfep->mxfe_adv_100fdx) && 1204 (!mxfep->mxfe_adv_100hdx) && 1205 (!mxfep->mxfe_adv_10fdx) && 1206 (!mxfep->mxfe_adv_10hdx)) { 1207 mxfe_error(mxfep->mxfe_dip, "No valid link mode selected."); 1208 mxfe_error(mxfep->mxfe_dip, "Powering down PHY."); 1209 mxfe_stopphy(mxfep); 1210 mxfep->mxfe_linkup = LINK_STATE_DOWN; 1211 if (mxfep->mxfe_flags & MXFE_RUNNING) 1212 mxfe_reportlink(mxfep); 1213 return; 1214 } 1215 1216 if (mxfep->mxfe_adv_aneg == 0) { 1217 /* forced mode */ 1218 unsigned nar; 1219 unsigned tctl; 1220 1221 nar = GETCSR(mxfep, CSR_NAR); 1222 tctl = GETCSR(mxfep, CSR_TCTL); 1223 1224 ASSERT((nar & (NAR_TX_ENABLE | NAR_RX_ENABLE)) == 0); 1225 1226 nar &= ~(NAR_FDX | NAR_PORTSEL | NAR_SCR | NAR_SPEED); 1227 tctl &= ~TCTL_ANE; 1228 if (mxfep->mxfe_adv_100fdx) { 1229 nar |= NAR_PORTSEL | NAR_PCS | NAR_SCR | NAR_FDX; 1230 } else if (mxfep->mxfe_adv_100hdx) { 1231 nar |= NAR_PORTSEL | NAR_PCS | NAR_SCR; 1232 } else if (mxfep->mxfe_adv_10fdx) { 1233 nar |= NAR_FDX | NAR_SPEED; 1234 } else { /* mxfep->mxfe_adv_10hdx */ 1235 nar |= NAR_SPEED; 1236 } 1237 1238 PUTCSR(mxfep, CSR_NAR, nar); 1239 PUTCSR(mxfep, CSR_TCTL, tctl); 1240 1241 /* Macronix initializations from Bolo Tsai */ 1242 PUTCSR(mxfep, CSR_MXMAGIC, 0x0b2c0000); 1243 PUTCSR(mxfep, CSR_ACOMP, 0x11000); 1244 } else { 1245 mxfe_startnway(mxfep); 1246 } 1247 PUTCSR(mxfep, CSR_TIMER, TIMER_LOOP | 1248 (MXFE_LINKTIMER * 1000 / TIMER_USEC)); 1249 } 1250 1251 /* 1252 * MII management. 1253 */ 1254 void 1255 mxfe_startphymii(mxfe_t *mxfep) 1256 { 1257 unsigned phyaddr; 1258 unsigned bmcr; 1259 unsigned bmsr; 1260 unsigned anar; 1261 unsigned phyidr1; 1262 unsigned phyidr2; 1263 int retries; 1264 int cnt; 1265 1266 mxfep->mxfe_phyaddr = -1; 1267 1268 /* search for first PHY we can find */ 1269 for (phyaddr = 0; phyaddr < 32; phyaddr++) { 1270 bmsr = mxfe_miiread(mxfep, phyaddr, MII_STATUS); 1271 if ((bmsr != 0) && (bmsr != 0xffff)) { 1272 mxfep->mxfe_phyaddr = phyaddr; 1273 break; 1274 } 1275 } 1276 1277 phyidr1 = mxfe_miiread(mxfep, phyaddr, MII_PHYIDH); 1278 phyidr2 = mxfe_miiread(mxfep, phyaddr, MII_PHYIDL); 1279 mxfep->mxfe_phyid = (phyidr1 << 16) | (phyidr2); 1280 1281 /* 1282 * Generally, all Macronix based devices use an internal 1283 * 100BASE-TX internal transceiver. If we ever run into a 1284 * variation on this, then the following logic will need to be 1285 * enhanced. 1286 * 1287 * One could question the value of the XCVR_INUSE field in the 1288 * MII statistics. 1289 */ 1290 if (bmsr & MII_STATUS_100_BASE_T4) { 1291 mxfep->mxfe_phyinuse = XCVR_100T4; 1292 } else { 1293 mxfep->mxfe_phyinuse = XCVR_100X; 1294 } 1295 1296 /* assume we support everything to start */ 1297 mxfep->mxfe_cap_aneg = mxfep->mxfe_cap_100T4 = 1298 mxfep->mxfe_cap_100fdx = mxfep->mxfe_cap_100hdx = 1299 mxfep->mxfe_cap_10fdx = mxfep->mxfe_cap_10hdx = 1; 1300 1301 DBG(DPHY, "phy at %d: %x,%x", phyaddr, phyidr1, phyidr2); 1302 DBG(DPHY, "bmsr = %x", mxfe_miiread(mxfep, 1303 mxfep->mxfe_phyaddr, MII_STATUS)); 1304 DBG(DPHY, "anar = %x", mxfe_miiread(mxfep, 1305 mxfep->mxfe_phyaddr, MII_AN_ADVERT)); 1306 DBG(DPHY, "anlpar = %x", mxfe_miiread(mxfep, 1307 mxfep->mxfe_phyaddr, MII_AN_LPABLE)); 1308 DBG(DPHY, "aner = %x", mxfe_miiread(mxfep, 1309 mxfep->mxfe_phyaddr, MII_AN_EXPANSION)); 1310 1311 DBG(DPHY, "resetting phy"); 1312 1313 /* we reset the phy block */ 1314 mxfe_miiwrite(mxfep, phyaddr, MII_CONTROL, MII_CONTROL_RESET); 1315 /* 1316 * wait for it to complete -- 500usec is still to short to 1317 * bother getting the system clock involved. 1318 */ 1319 drv_usecwait(500); 1320 for (retries = 0; retries < 10; retries++) { 1321 if (mxfe_miiread(mxfep, phyaddr, MII_CONTROL) & 1322 MII_CONTROL_RESET) { 1323 drv_usecwait(500); 1324 continue; 1325 } 1326 break; 1327 } 1328 if (retries == 100) { 1329 mxfe_error(mxfep->mxfe_dip, "timeout waiting on phy to reset"); 1330 return; 1331 } 1332 1333 DBG(DPHY, "phy reset complete"); 1334 1335 bmsr = mxfe_miiread(mxfep, phyaddr, MII_STATUS); 1336 bmcr = mxfe_miiread(mxfep, phyaddr, MII_CONTROL); 1337 anar = mxfe_miiread(mxfep, phyaddr, MII_AN_ADVERT); 1338 1339 anar &= ~(MII_ABILITY_100BASE_T4 | 1340 MII_ABILITY_100BASE_TX_FD | MII_ABILITY_100BASE_TX | 1341 MII_ABILITY_10BASE_T_FD | MII_ABILITY_10BASE_T); 1342 1343 /* disable modes not supported in hardware */ 1344 if (!(bmsr & MII_STATUS_100_BASE_T4)) { 1345 mxfep->mxfe_adv_100T4 = 0; 1346 mxfep->mxfe_cap_100T4 = 0; 1347 } 1348 if (!(bmsr & MII_STATUS_100_BASEX_FD)) { 1349 mxfep->mxfe_adv_100fdx = 0; 1350 mxfep->mxfe_cap_100fdx = 0; 1351 } 1352 if (!(bmsr & MII_STATUS_100_BASEX)) { 1353 mxfep->mxfe_adv_100hdx = 0; 1354 mxfep->mxfe_cap_100hdx = 0; 1355 } 1356 if (!(bmsr & MII_STATUS_10_FD)) { 1357 mxfep->mxfe_adv_10fdx = 0; 1358 mxfep->mxfe_cap_10fdx = 0; 1359 } 1360 if (!(bmsr & MII_STATUS_10)) { 1361 mxfep->mxfe_adv_10hdx = 0; 1362 mxfep->mxfe_cap_10hdx = 0; 1363 } 1364 if (!(bmsr & MII_STATUS_CANAUTONEG)) { 1365 mxfep->mxfe_adv_aneg = 0; 1366 mxfep->mxfe_cap_aneg = 0; 1367 } 1368 1369 cnt = 0; 1370 if (mxfep->mxfe_adv_100T4) { 1371 anar |= MII_ABILITY_100BASE_T4; 1372 cnt++; 1373 } 1374 if (mxfep->mxfe_adv_100fdx) { 1375 anar |= MII_ABILITY_100BASE_TX_FD; 1376 cnt++; 1377 } 1378 if (mxfep->mxfe_adv_100hdx) { 1379 anar |= MII_ABILITY_100BASE_TX; 1380 cnt++; 1381 } 1382 if (mxfep->mxfe_adv_10fdx) { 1383 anar |= MII_ABILITY_10BASE_T_FD; 1384 cnt++; 1385 } 1386 if (mxfep->mxfe_adv_10hdx) { 1387 anar |= MII_ABILITY_10BASE_T; 1388 cnt++; 1389 } 1390 1391 /* 1392 * Make certain at least one valid link mode is selected. 1393 */ 1394 if (!cnt) { 1395 mxfe_error(mxfep->mxfe_dip, "No valid link mode selected."); 1396 mxfe_error(mxfep->mxfe_dip, "Powering down PHY."); 1397 mxfe_stopphy(mxfep); 1398 mxfep->mxfe_linkup = LINK_STATE_DOWN; 1399 if (mxfep->mxfe_flags & MXFE_RUNNING) 1400 mxfe_reportlink(mxfep); 1401 return; 1402 } 1403 1404 if ((mxfep->mxfe_adv_aneg) && (bmsr & MII_STATUS_CANAUTONEG)) { 1405 DBG(DPHY, "using autoneg mode"); 1406 bmcr = (MII_CONTROL_ANE | MII_CONTROL_RSAN); 1407 } else { 1408 DBG(DPHY, "using forced mode"); 1409 if (mxfep->mxfe_adv_100fdx) { 1410 bmcr = (MII_CONTROL_100MB | MII_CONTROL_FDUPLEX); 1411 } else if (mxfep->mxfe_adv_100hdx) { 1412 bmcr = MII_CONTROL_100MB; 1413 } else if (mxfep->mxfe_adv_10fdx) { 1414 bmcr = MII_CONTROL_FDUPLEX; 1415 } else { 1416 /* 10HDX */ 1417 bmcr = 0; 1418 } 1419 } 1420 1421 DBG(DPHY, "programming anar to 0x%x", anar); 1422 mxfe_miiwrite(mxfep, phyaddr, MII_AN_ADVERT, anar); 1423 DBG(DPHY, "programming bmcr to 0x%x", bmcr); 1424 mxfe_miiwrite(mxfep, phyaddr, MII_CONTROL, bmcr); 1425 1426 /* 1427 * schedule a query of the link status 1428 */ 1429 PUTCSR(mxfep, CSR_TIMER, TIMER_LOOP | 1430 (MXFE_LINKTIMER * 1000 / TIMER_USEC)); 1431 } 1432 1433 void 1434 mxfe_reportlink(mxfe_t *mxfep) 1435 { 1436 int changed = 0; 1437 1438 if (mxfep->mxfe_ifspeed != mxfep->mxfe_lastifspeed) { 1439 mxfep->mxfe_lastifspeed = mxfep->mxfe_ifspeed; 1440 changed++; 1441 } 1442 if (mxfep->mxfe_duplex != mxfep->mxfe_lastduplex) { 1443 mxfep->mxfe_lastduplex = mxfep->mxfe_duplex; 1444 changed++; 1445 } 1446 if (mxfep->mxfe_linkup != mxfep->mxfe_lastlinkup) { 1447 mxfep->mxfe_lastlinkup = mxfep->mxfe_linkup; 1448 changed++; 1449 } 1450 if (changed) 1451 mac_link_update(mxfep->mxfe_mh, mxfep->mxfe_linkup); 1452 } 1453 1454 void 1455 mxfe_checklink(mxfe_t *mxfep) 1456 { 1457 if ((mxfep->mxfe_flags & MXFE_RUNNING) == 0) 1458 return; 1459 1460 if ((mxfep->mxfe_txstall_time != 0) && 1461 (gethrtime() > mxfep->mxfe_txstall_time) && 1462 (mxfep->mxfe_txavail != MXFE_TXRING)) { 1463 mxfep->mxfe_txstall_time = 0; 1464 mxfe_error(mxfep->mxfe_dip, "TX stall detected!"); 1465 mxfe_resetall(mxfep); 1466 return; 1467 } 1468 1469 switch (MXFE_MODEL(mxfep)) { 1470 case MXFE_98713A: 1471 mxfe_checklinkmii(mxfep); 1472 break; 1473 default: 1474 mxfe_checklinknway(mxfep); 1475 } 1476 } 1477 1478 void 1479 mxfe_checklinkmii(mxfe_t *mxfep) 1480 { 1481 /* read MII state registers */ 1482 uint16_t bmsr; 1483 uint16_t bmcr; 1484 uint16_t anar; 1485 uint16_t anlpar; 1486 uint16_t aner; 1487 1488 /* read this twice, to clear latched link state */ 1489 bmsr = mxfe_miiread(mxfep, mxfep->mxfe_phyaddr, MII_STATUS); 1490 bmsr = mxfe_miiread(mxfep, mxfep->mxfe_phyaddr, MII_STATUS); 1491 bmcr = mxfe_miiread(mxfep, mxfep->mxfe_phyaddr, MII_CONTROL); 1492 anar = mxfe_miiread(mxfep, mxfep->mxfe_phyaddr, MII_AN_ADVERT); 1493 anlpar = mxfe_miiread(mxfep, mxfep->mxfe_phyaddr, MII_AN_LPABLE); 1494 aner = mxfe_miiread(mxfep, mxfep->mxfe_phyaddr, MII_AN_EXPANSION); 1495 1496 mxfep->mxfe_bmsr = bmsr; 1497 mxfep->mxfe_anlpar = anlpar; 1498 mxfep->mxfe_aner = aner; 1499 1500 if (bmsr & MII_STATUS_REMFAULT) { 1501 mxfe_error(mxfep->mxfe_dip, "Remote fault detected."); 1502 } 1503 if (bmsr & MII_STATUS_JABBERING) { 1504 mxfe_error(mxfep->mxfe_dip, "Jabber condition detected."); 1505 } 1506 if ((bmsr & MII_STATUS_LINKUP) == 0) { 1507 /* no link */ 1508 mxfep->mxfe_ifspeed = 0; 1509 mxfep->mxfe_duplex = LINK_DUPLEX_UNKNOWN; 1510 mxfep->mxfe_linkup = LINK_STATE_DOWN; 1511 mxfe_reportlink(mxfep); 1512 return; 1513 } 1514 1515 DBG(DCHATTY, "link up!"); 1516 mxfep->mxfe_linkup = LINK_STATE_UP; 1517 1518 if (!(bmcr & MII_CONTROL_ANE)) { 1519 /* forced mode */ 1520 if (bmcr & MII_CONTROL_100MB) { 1521 mxfep->mxfe_ifspeed = 100000000; 1522 } else { 1523 mxfep->mxfe_ifspeed = 10000000; 1524 } 1525 if (bmcr & MII_CONTROL_FDUPLEX) { 1526 mxfep->mxfe_duplex = LINK_DUPLEX_FULL; 1527 } else { 1528 mxfep->mxfe_duplex = LINK_DUPLEX_HALF; 1529 } 1530 } else if ((!(bmsr & MII_STATUS_CANAUTONEG)) || 1531 (!(bmsr & MII_STATUS_ANDONE))) { 1532 mxfep->mxfe_ifspeed = 0; 1533 mxfep->mxfe_duplex = LINK_DUPLEX_UNKNOWN; 1534 } else if (anar & anlpar & MII_ABILITY_100BASE_TX_FD) { 1535 mxfep->mxfe_ifspeed = 100000000; 1536 mxfep->mxfe_duplex = LINK_DUPLEX_FULL; 1537 } else if (anar & anlpar & MII_ABILITY_100BASE_T4) { 1538 mxfep->mxfe_ifspeed = 100000000; 1539 mxfep->mxfe_duplex = LINK_DUPLEX_HALF; 1540 } else if (anar & anlpar & MII_ABILITY_100BASE_TX) { 1541 mxfep->mxfe_ifspeed = 100000000; 1542 mxfep->mxfe_duplex = LINK_DUPLEX_HALF; 1543 } else if (anar & anlpar & MII_ABILITY_10BASE_T_FD) { 1544 mxfep->mxfe_ifspeed = 10000000; 1545 mxfep->mxfe_duplex = LINK_DUPLEX_FULL; 1546 } else if (anar & anlpar & MII_ABILITY_10BASE_T) { 1547 mxfep->mxfe_ifspeed = 10000000; 1548 mxfep->mxfe_duplex = LINK_DUPLEX_HALF; 1549 } else { 1550 mxfep->mxfe_ifspeed = 0; 1551 mxfep->mxfe_duplex = LINK_DUPLEX_UNKNOWN; 1552 } 1553 1554 mxfe_reportlink(mxfep); 1555 } 1556 1557 void 1558 mxfe_miitristate(mxfe_t *mxfep) 1559 { 1560 unsigned val = SPR_SROM_WRITE | SPR_MII_CTRL; 1561 PUTCSR(mxfep, CSR_SPR, val); 1562 drv_usecwait(1); 1563 PUTCSR(mxfep, CSR_SPR, val | SPR_MII_CLOCK); 1564 drv_usecwait(1); 1565 } 1566 1567 void 1568 mxfe_miiwritebit(mxfe_t *mxfep, uint8_t bit) 1569 { 1570 unsigned val = bit ? SPR_MII_DOUT : 0; 1571 PUTCSR(mxfep, CSR_SPR, val); 1572 drv_usecwait(1); 1573 PUTCSR(mxfep, CSR_SPR, val | SPR_MII_CLOCK); 1574 drv_usecwait(1); 1575 } 1576 1577 uint8_t 1578 mxfe_miireadbit(mxfe_t *mxfep) 1579 { 1580 unsigned val = SPR_MII_CTRL | SPR_SROM_READ; 1581 uint8_t bit; 1582 PUTCSR(mxfep, CSR_SPR, val); 1583 drv_usecwait(1); 1584 bit = (GETCSR(mxfep, CSR_SPR) & SPR_MII_DIN) ? 1 : 0; 1585 PUTCSR(mxfep, CSR_SPR, val | SPR_MII_CLOCK); 1586 drv_usecwait(1); 1587 return (bit); 1588 } 1589 1590 uint16_t 1591 mxfe_miiread(mxfe_t *mxfep, int phy, int reg) 1592 { 1593 switch (MXFE_MODEL(mxfep)) { 1594 case MXFE_98713A: 1595 return (mxfe_miiread98713(mxfep, phy, reg)); 1596 default: 1597 return (0xffff); 1598 } 1599 } 1600 1601 uint16_t 1602 mxfe_miireadgeneral(mxfe_t *mxfep, int phy, int reg) 1603 { 1604 uint16_t value = 0; 1605 int i; 1606 1607 /* send the 32 bit preamble */ 1608 for (i = 0; i < 32; i++) { 1609 mxfe_miiwritebit(mxfep, 1); 1610 } 1611 1612 /* send the start code - 01b */ 1613 mxfe_miiwritebit(mxfep, 0); 1614 mxfe_miiwritebit(mxfep, 1); 1615 1616 /* send the opcode for read, - 10b */ 1617 mxfe_miiwritebit(mxfep, 1); 1618 mxfe_miiwritebit(mxfep, 0); 1619 1620 /* next we send the 5 bit phy address */ 1621 for (i = 0x10; i > 0; i >>= 1) { 1622 mxfe_miiwritebit(mxfep, (phy & i) ? 1 : 0); 1623 } 1624 1625 /* the 5 bit register address goes next */ 1626 for (i = 0x10; i > 0; i >>= 1) { 1627 mxfe_miiwritebit(mxfep, (reg & i) ? 1 : 0); 1628 } 1629 1630 /* turnaround - tristate followed by logic 0 */ 1631 mxfe_miitristate(mxfep); 1632 mxfe_miiwritebit(mxfep, 0); 1633 1634 /* read the 16 bit register value */ 1635 for (i = 0x8000; i > 0; i >>= 1) { 1636 value <<= 1; 1637 value |= mxfe_miireadbit(mxfep); 1638 } 1639 mxfe_miitristate(mxfep); 1640 return (value); 1641 } 1642 1643 uint16_t 1644 mxfe_miiread98713(mxfe_t *mxfep, int phy, int reg) 1645 { 1646 unsigned nar; 1647 uint16_t retval; 1648 /* 1649 * like an ordinary MII, but we have to turn off portsel while 1650 * we read it. 1651 */ 1652 nar = GETCSR(mxfep, CSR_NAR); 1653 PUTCSR(mxfep, CSR_NAR, nar & ~NAR_PORTSEL); 1654 retval = mxfe_miireadgeneral(mxfep, phy, reg); 1655 PUTCSR(mxfep, CSR_NAR, nar); 1656 return (retval); 1657 } 1658 1659 void 1660 mxfe_miiwrite(mxfe_t *mxfep, int phy, int reg, uint16_t val) 1661 { 1662 switch (MXFE_MODEL(mxfep)) { 1663 case MXFE_98713A: 1664 mxfe_miiwrite98713(mxfep, phy, reg, val); 1665 break; 1666 default: 1667 break; 1668 } 1669 } 1670 1671 void 1672 mxfe_miiwritegeneral(mxfe_t *mxfep, int phy, int reg, uint16_t val) 1673 { 1674 int i; 1675 1676 /* send the 32 bit preamble */ 1677 for (i = 0; i < 32; i++) { 1678 mxfe_miiwritebit(mxfep, 1); 1679 } 1680 1681 /* send the start code - 01b */ 1682 mxfe_miiwritebit(mxfep, 0); 1683 mxfe_miiwritebit(mxfep, 1); 1684 1685 /* send the opcode for write, - 01b */ 1686 mxfe_miiwritebit(mxfep, 0); 1687 mxfe_miiwritebit(mxfep, 1); 1688 1689 /* next we send the 5 bit phy address */ 1690 for (i = 0x10; i > 0; i >>= 1) { 1691 mxfe_miiwritebit(mxfep, (phy & i) ? 1 : 0); 1692 } 1693 1694 /* the 5 bit register address goes next */ 1695 for (i = 0x10; i > 0; i >>= 1) { 1696 mxfe_miiwritebit(mxfep, (reg & i) ? 1 : 0); 1697 } 1698 1699 /* turnaround - tristate followed by logic 0 */ 1700 mxfe_miitristate(mxfep); 1701 mxfe_miiwritebit(mxfep, 0); 1702 1703 /* now write out our data (16 bits) */ 1704 for (i = 0x8000; i > 0; i >>= 1) { 1705 mxfe_miiwritebit(mxfep, (val & i) ? 1 : 0); 1706 } 1707 1708 /* idle mode */ 1709 mxfe_miitristate(mxfep); 1710 } 1711 1712 void 1713 mxfe_miiwrite98713(mxfe_t *mxfep, int phy, int reg, uint16_t val) 1714 { 1715 unsigned nar; 1716 /* 1717 * like an ordinary MII, but we have to turn off portsel while 1718 * we read it. 1719 */ 1720 nar = GETCSR(mxfep, CSR_NAR); 1721 PUTCSR(mxfep, CSR_NAR, nar & ~NAR_PORTSEL); 1722 mxfe_miiwritegeneral(mxfep, phy, reg, val); 1723 PUTCSR(mxfep, CSR_NAR, nar); 1724 } 1725 1726 int 1727 mxfe_m_start(void *arg) 1728 { 1729 mxfe_t *mxfep = arg; 1730 1731 /* grab exclusive access to the card */ 1732 mutex_enter(&mxfep->mxfe_intrlock); 1733 mutex_enter(&mxfep->mxfe_xmtlock); 1734 1735 mxfe_startall(mxfep); 1736 mxfep->mxfe_flags |= MXFE_RUNNING; 1737 1738 mutex_exit(&mxfep->mxfe_xmtlock); 1739 mutex_exit(&mxfep->mxfe_intrlock); 1740 return (0); 1741 } 1742 1743 void 1744 mxfe_m_stop(void *arg) 1745 { 1746 mxfe_t *mxfep = arg; 1747 1748 /* exclusive access to the hardware! */ 1749 mutex_enter(&mxfep->mxfe_intrlock); 1750 mutex_enter(&mxfep->mxfe_xmtlock); 1751 1752 mxfe_stopall(mxfep); 1753 mxfep->mxfe_flags &= ~MXFE_RUNNING; 1754 1755 mutex_exit(&mxfep->mxfe_xmtlock); 1756 mutex_exit(&mxfep->mxfe_intrlock); 1757 } 1758 1759 void 1760 mxfe_startmac(mxfe_t *mxfep) 1761 { 1762 /* verify exclusive access to the card */ 1763 ASSERT(mutex_owned(&mxfep->mxfe_intrlock)); 1764 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock)); 1765 1766 /* start the card */ 1767 SETBIT(mxfep, CSR_NAR, NAR_TX_ENABLE | NAR_RX_ENABLE); 1768 1769 if (mxfep->mxfe_txavail != MXFE_TXRING) 1770 PUTCSR(mxfep, CSR_TDR, 0); 1771 1772 /* tell the mac that we are ready to go! */ 1773 if (mxfep->mxfe_flags & MXFE_RUNNING) 1774 mac_tx_update(mxfep->mxfe_mh); 1775 } 1776 1777 void 1778 mxfe_stopmac(mxfe_t *mxfep) 1779 { 1780 int i; 1781 1782 /* exclusive access to the hardware! */ 1783 ASSERT(mutex_owned(&mxfep->mxfe_intrlock)); 1784 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock)); 1785 1786 CLRBIT(mxfep, CSR_NAR, NAR_TX_ENABLE | NAR_RX_ENABLE); 1787 1788 /* 1789 * A 1518 byte frame at 10Mbps takes about 1.2 msec to drain. 1790 * We just add up to the nearest msec (2), which should be 1791 * plenty to complete. 1792 * 1793 * Note that some chips never seem to indicate the transition to 1794 * the stopped state properly. Experience shows that we can safely 1795 * proceed anyway, after waiting the requisite timeout. 1796 */ 1797 for (i = 2000; i != 0; i -= 10) { 1798 if ((GETCSR(mxfep, CSR_SR) & (SR_TX_STATE | SR_RX_STATE)) == 0) 1799 break; 1800 drv_usecwait(10); 1801 } 1802 1803 /* prevent an interrupt */ 1804 PUTCSR(mxfep, CSR_SR, INT_RXSTOPPED | INT_TXSTOPPED); 1805 } 1806 1807 void 1808 mxfe_resetrings(mxfe_t *mxfep) 1809 { 1810 int i; 1811 1812 /* now we need to reset the pointers... */ 1813 PUTCSR(mxfep, CSR_RDB, 0); 1814 PUTCSR(mxfep, CSR_TDB, 0); 1815 1816 /* reset the descriptor ring pointers */ 1817 mxfep->mxfe_rxhead = 0; 1818 mxfep->mxfe_txreclaim = 0; 1819 mxfep->mxfe_txsend = 0; 1820 mxfep->mxfe_txavail = MXFE_TXRING; 1821 1822 /* set up transmit descriptor ring */ 1823 for (i = 0; i < MXFE_TXRING; i++) { 1824 mxfe_desc_t *tmdp = &mxfep->mxfe_txdescp[i]; 1825 unsigned control = 0; 1826 if (i == (MXFE_TXRING - 1)) { 1827 control |= TXCTL_ENDRING; 1828 } 1829 PUTTXDESC(mxfep, tmdp->desc_status, 0); 1830 PUTTXDESC(mxfep, tmdp->desc_control, control); 1831 PUTTXDESC(mxfep, tmdp->desc_buffer1, 0); 1832 PUTTXDESC(mxfep, tmdp->desc_buffer2, 0); 1833 SYNCTXDESC(mxfep, i, DDI_DMA_SYNC_FORDEV); 1834 } 1835 PUTCSR(mxfep, CSR_TDB, mxfep->mxfe_txdesc_paddr); 1836 1837 /* make the receive buffers available */ 1838 for (i = 0; i < MXFE_RXRING; i++) { 1839 mxfe_rxbuf_t *rxb = mxfep->mxfe_rxbufs[i]; 1840 mxfe_desc_t *rmdp = &mxfep->mxfe_rxdescp[i]; 1841 unsigned control; 1842 1843 control = MXFE_BUFSZ & RXCTL_BUFLEN1; 1844 if (i == (MXFE_RXRING - 1)) { 1845 control |= RXCTL_ENDRING; 1846 } 1847 PUTRXDESC(mxfep, rmdp->desc_buffer1, rxb->rxb_paddr); 1848 PUTRXDESC(mxfep, rmdp->desc_buffer2, 0); 1849 PUTRXDESC(mxfep, rmdp->desc_control, control); 1850 PUTRXDESC(mxfep, rmdp->desc_status, RXSTAT_OWN); 1851 SYNCRXDESC(mxfep, i, DDI_DMA_SYNC_FORDEV); 1852 } 1853 PUTCSR(mxfep, CSR_RDB, mxfep->mxfe_rxdesc_paddr); 1854 } 1855 1856 void 1857 mxfe_stopall(mxfe_t *mxfep) 1858 { 1859 mxfe_disableinterrupts(mxfep); 1860 1861 mxfe_stopmac(mxfep); 1862 1863 /* stop the phy */ 1864 mxfe_stopphy(mxfep); 1865 } 1866 1867 void 1868 mxfe_startall(mxfe_t *mxfep) 1869 { 1870 ASSERT(mutex_owned(&mxfep->mxfe_intrlock)); 1871 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock)); 1872 1873 /* make sure interrupts are disabled to begin */ 1874 mxfe_disableinterrupts(mxfep); 1875 1876 /* initialize the chip */ 1877 (void) mxfe_initialize(mxfep); 1878 1879 /* now we can enable interrupts */ 1880 mxfe_enableinterrupts(mxfep); 1881 1882 /* start up the phy */ 1883 mxfe_startphy(mxfep); 1884 1885 /* start up the mac */ 1886 mxfe_startmac(mxfep); 1887 } 1888 1889 void 1890 mxfe_resetall(mxfe_t *mxfep) 1891 { 1892 mxfep->mxfe_resetting = B_TRUE; 1893 mxfe_stopall(mxfep); 1894 mxfep->mxfe_resetting = B_FALSE; 1895 mxfe_startall(mxfep); 1896 } 1897 1898 mxfe_txbuf_t * 1899 mxfe_alloctxbuf(mxfe_t *mxfep) 1900 { 1901 ddi_dma_cookie_t dmac; 1902 unsigned ncookies; 1903 mxfe_txbuf_t *txb; 1904 size_t len; 1905 1906 txb = kmem_zalloc(sizeof (*txb), KM_SLEEP); 1907 1908 if (ddi_dma_alloc_handle(mxfep->mxfe_dip, &mxfe_dma_txattr, 1909 DDI_DMA_SLEEP, NULL, &txb->txb_dmah) != DDI_SUCCESS) { 1910 return (NULL); 1911 } 1912 1913 if (ddi_dma_mem_alloc(txb->txb_dmah, MXFE_BUFSZ, &mxfe_bufattr, 1914 DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, &txb->txb_buf, 1915 &len, &txb->txb_acch) != DDI_SUCCESS) { 1916 return (NULL); 1917 } 1918 if (ddi_dma_addr_bind_handle(txb->txb_dmah, NULL, txb->txb_buf, 1919 len, DDI_DMA_WRITE | DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, 1920 &dmac, &ncookies) != DDI_DMA_MAPPED) { 1921 return (NULL); 1922 } 1923 txb->txb_paddr = dmac.dmac_address; 1924 1925 return (txb); 1926 } 1927 1928 void 1929 mxfe_destroytxbuf(mxfe_txbuf_t *txb) 1930 { 1931 if (txb != NULL) { 1932 if (txb->txb_paddr) 1933 (void) ddi_dma_unbind_handle(txb->txb_dmah); 1934 if (txb->txb_acch) 1935 ddi_dma_mem_free(&txb->txb_acch); 1936 if (txb->txb_dmah) 1937 ddi_dma_free_handle(&txb->txb_dmah); 1938 kmem_free(txb, sizeof (*txb)); 1939 } 1940 } 1941 1942 mxfe_rxbuf_t * 1943 mxfe_allocrxbuf(mxfe_t *mxfep) 1944 { 1945 mxfe_rxbuf_t *rxb; 1946 size_t len; 1947 unsigned ccnt; 1948 ddi_dma_cookie_t dmac; 1949 1950 rxb = kmem_zalloc(sizeof (*rxb), KM_SLEEP); 1951 1952 if (ddi_dma_alloc_handle(mxfep->mxfe_dip, &mxfe_dma_attr, 1953 DDI_DMA_SLEEP, NULL, &rxb->rxb_dmah) != DDI_SUCCESS) { 1954 kmem_free(rxb, sizeof (*rxb)); 1955 return (NULL); 1956 } 1957 if (ddi_dma_mem_alloc(rxb->rxb_dmah, MXFE_BUFSZ, &mxfe_bufattr, 1958 DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, 1959 &rxb->rxb_buf, &len, &rxb->rxb_acch) != DDI_SUCCESS) { 1960 ddi_dma_free_handle(&rxb->rxb_dmah); 1961 kmem_free(rxb, sizeof (*rxb)); 1962 return (NULL); 1963 } 1964 if (ddi_dma_addr_bind_handle(rxb->rxb_dmah, NULL, rxb->rxb_buf, len, 1965 DDI_DMA_READ | DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, &dmac, 1966 &ccnt) != DDI_DMA_MAPPED) { 1967 ddi_dma_mem_free(&rxb->rxb_acch); 1968 ddi_dma_free_handle(&rxb->rxb_dmah); 1969 kmem_free(rxb, sizeof (*rxb)); 1970 return (NULL); 1971 } 1972 rxb->rxb_paddr = dmac.dmac_address; 1973 1974 return (rxb); 1975 } 1976 1977 void 1978 mxfe_destroyrxbuf(mxfe_rxbuf_t *rxb) 1979 { 1980 if (rxb != NULL) { 1981 (void) ddi_dma_unbind_handle(rxb->rxb_dmah); 1982 ddi_dma_mem_free(&rxb->rxb_acch); 1983 ddi_dma_free_handle(&rxb->rxb_dmah); 1984 kmem_free(rxb, sizeof (*rxb)); 1985 } 1986 } 1987 1988 /* 1989 * Allocate receive resources. 1990 */ 1991 int 1992 mxfe_allocrxring(mxfe_t *mxfep) 1993 { 1994 int rval; 1995 int i; 1996 size_t size; 1997 size_t len; 1998 ddi_dma_cookie_t dmac; 1999 unsigned ncookies; 2000 caddr_t kaddr; 2001 2002 size = MXFE_RXRING * sizeof (mxfe_desc_t); 2003 2004 rval = ddi_dma_alloc_handle(mxfep->mxfe_dip, &mxfe_dma_attr, 2005 DDI_DMA_SLEEP, NULL, &mxfep->mxfe_rxdesc_dmah); 2006 if (rval != DDI_SUCCESS) { 2007 mxfe_error(mxfep->mxfe_dip, 2008 "unable to allocate DMA handle for rx descriptors"); 2009 return (DDI_FAILURE); 2010 } 2011 2012 rval = ddi_dma_mem_alloc(mxfep->mxfe_rxdesc_dmah, size, &mxfe_devattr, 2013 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &kaddr, &len, 2014 &mxfep->mxfe_rxdesc_acch); 2015 if (rval != DDI_SUCCESS) { 2016 mxfe_error(mxfep->mxfe_dip, 2017 "unable to allocate DMA memory for rx descriptors"); 2018 return (DDI_FAILURE); 2019 } 2020 2021 rval = ddi_dma_addr_bind_handle(mxfep->mxfe_rxdesc_dmah, NULL, kaddr, 2022 size, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 2023 &dmac, &ncookies); 2024 if (rval != DDI_DMA_MAPPED) { 2025 mxfe_error(mxfep->mxfe_dip, 2026 "unable to bind DMA for rx descriptors"); 2027 return (DDI_FAILURE); 2028 } 2029 2030 /* because of mxfe_dma_attr */ 2031 ASSERT(ncookies == 1); 2032 2033 /* we take the 32-bit physical address out of the cookie */ 2034 mxfep->mxfe_rxdesc_paddr = dmac.dmac_address; 2035 mxfep->mxfe_rxdescp = (void *)kaddr; 2036 2037 /* allocate buffer pointers (not the buffers themselves, yet) */ 2038 mxfep->mxfe_rxbufs = kmem_zalloc(MXFE_RXRING * sizeof (mxfe_rxbuf_t *), 2039 KM_SLEEP); 2040 2041 /* now allocate rx buffers */ 2042 for (i = 0; i < MXFE_RXRING; i++) { 2043 mxfe_rxbuf_t *rxb = mxfe_allocrxbuf(mxfep); 2044 if (rxb == NULL) 2045 return (DDI_FAILURE); 2046 mxfep->mxfe_rxbufs[i] = rxb; 2047 } 2048 2049 return (DDI_SUCCESS); 2050 } 2051 2052 /* 2053 * Allocate transmit resources. 2054 */ 2055 int 2056 mxfe_alloctxring(mxfe_t *mxfep) 2057 { 2058 int rval; 2059 int i; 2060 size_t size; 2061 size_t len; 2062 ddi_dma_cookie_t dmac; 2063 unsigned ncookies; 2064 caddr_t kaddr; 2065 2066 size = MXFE_TXRING * sizeof (mxfe_desc_t); 2067 2068 rval = ddi_dma_alloc_handle(mxfep->mxfe_dip, &mxfe_dma_attr, 2069 DDI_DMA_SLEEP, NULL, &mxfep->mxfe_txdesc_dmah); 2070 if (rval != DDI_SUCCESS) { 2071 mxfe_error(mxfep->mxfe_dip, 2072 "unable to allocate DMA handle for tx descriptors"); 2073 return (DDI_FAILURE); 2074 } 2075 2076 rval = ddi_dma_mem_alloc(mxfep->mxfe_txdesc_dmah, size, &mxfe_devattr, 2077 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &kaddr, &len, 2078 &mxfep->mxfe_txdesc_acch); 2079 if (rval != DDI_SUCCESS) { 2080 mxfe_error(mxfep->mxfe_dip, 2081 "unable to allocate DMA memory for tx descriptors"); 2082 return (DDI_FAILURE); 2083 } 2084 2085 rval = ddi_dma_addr_bind_handle(mxfep->mxfe_txdesc_dmah, NULL, kaddr, 2086 size, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 2087 &dmac, &ncookies); 2088 if (rval != DDI_DMA_MAPPED) { 2089 mxfe_error(mxfep->mxfe_dip, 2090 "unable to bind DMA for tx descriptors"); 2091 return (DDI_FAILURE); 2092 } 2093 2094 /* because of mxfe_dma_attr */ 2095 ASSERT(ncookies == 1); 2096 2097 /* we take the 32-bit physical address out of the cookie */ 2098 mxfep->mxfe_txdesc_paddr = dmac.dmac_address; 2099 mxfep->mxfe_txdescp = (void *)kaddr; 2100 2101 /* allocate buffer pointers (not the buffers themselves, yet) */ 2102 mxfep->mxfe_txbufs = kmem_zalloc(MXFE_TXRING * sizeof (mxfe_txbuf_t *), 2103 KM_SLEEP); 2104 2105 /* now allocate tx buffers */ 2106 for (i = 0; i < MXFE_TXRING; i++) { 2107 mxfe_txbuf_t *txb = mxfe_alloctxbuf(mxfep); 2108 if (txb == NULL) 2109 return (DDI_FAILURE); 2110 /* stick it in the stack */ 2111 mxfep->mxfe_txbufs[i] = txb; 2112 } 2113 2114 return (DDI_SUCCESS); 2115 } 2116 2117 void 2118 mxfe_freerxring(mxfe_t *mxfep) 2119 { 2120 int i; 2121 2122 for (i = 0; i < MXFE_RXRING; i++) { 2123 mxfe_destroyrxbuf(mxfep->mxfe_rxbufs[i]); 2124 } 2125 2126 if (mxfep->mxfe_rxbufs) { 2127 kmem_free(mxfep->mxfe_rxbufs, 2128 MXFE_RXRING * sizeof (mxfe_rxbuf_t *)); 2129 } 2130 2131 if (mxfep->mxfe_rxdesc_paddr) 2132 (void) ddi_dma_unbind_handle(mxfep->mxfe_rxdesc_dmah); 2133 if (mxfep->mxfe_rxdesc_acch) 2134 ddi_dma_mem_free(&mxfep->mxfe_rxdesc_acch); 2135 if (mxfep->mxfe_rxdesc_dmah) 2136 ddi_dma_free_handle(&mxfep->mxfe_rxdesc_dmah); 2137 } 2138 2139 void 2140 mxfe_freetxring(mxfe_t *mxfep) 2141 { 2142 int i; 2143 2144 for (i = 0; i < MXFE_TXRING; i++) { 2145 mxfe_destroytxbuf(mxfep->mxfe_txbufs[i]); 2146 } 2147 2148 if (mxfep->mxfe_txbufs) { 2149 kmem_free(mxfep->mxfe_txbufs, 2150 MXFE_TXRING * sizeof (mxfe_txbuf_t *)); 2151 } 2152 if (mxfep->mxfe_txdesc_paddr) 2153 (void) ddi_dma_unbind_handle(mxfep->mxfe_txdesc_dmah); 2154 if (mxfep->mxfe_txdesc_acch) 2155 ddi_dma_mem_free(&mxfep->mxfe_txdesc_acch); 2156 if (mxfep->mxfe_txdesc_dmah) 2157 ddi_dma_free_handle(&mxfep->mxfe_txdesc_dmah); 2158 } 2159 2160 /* 2161 * Interrupt service routine. 2162 */ 2163 unsigned 2164 mxfe_intr(caddr_t arg) 2165 { 2166 mxfe_t *mxfep = (void *)arg; 2167 uint32_t status; 2168 mblk_t *mp = NULL; 2169 boolean_t error = B_FALSE; 2170 2171 mutex_enter(&mxfep->mxfe_intrlock); 2172 2173 if (mxfep->mxfe_flags & MXFE_SUSPENDED) { 2174 /* we cannot receive interrupts! */ 2175 mutex_exit(&mxfep->mxfe_intrlock); 2176 return (DDI_INTR_UNCLAIMED); 2177 } 2178 2179 /* check interrupt status bits, did we interrupt? */ 2180 status = GETCSR(mxfep, CSR_SR) & INT_ALL; 2181 2182 if (status == 0) { 2183 KIOIP->intrs[KSTAT_INTR_SPURIOUS]++; 2184 mutex_exit(&mxfep->mxfe_intrlock); 2185 return (DDI_INTR_UNCLAIMED); 2186 } 2187 /* ack the interrupt */ 2188 PUTCSR(mxfep, CSR_SR, status); 2189 KIOIP->intrs[KSTAT_INTR_HARD]++; 2190 2191 if (!(mxfep->mxfe_flags & MXFE_RUNNING)) { 2192 /* not running, don't touch anything */ 2193 mutex_exit(&mxfep->mxfe_intrlock); 2194 return (DDI_INTR_CLAIMED); 2195 } 2196 2197 if (status & INT_RXOK) { 2198 /* receive packets */ 2199 if (mxfe_receive(mxfep, &mp)) { 2200 error = B_TRUE; 2201 } 2202 } 2203 2204 if (status & INT_TXOK) { 2205 /* transmit completed */ 2206 mutex_enter(&mxfep->mxfe_xmtlock); 2207 mxfe_reclaim(mxfep); 2208 mutex_exit(&mxfep->mxfe_xmtlock); 2209 } 2210 2211 if (((status & (INT_TIMER|INT_ANEG)) != 0) || 2212 ((mxfep->mxfe_linkup == LINK_STATE_UP) && 2213 ((status & (INT_10LINK|INT_100LINK)) != 0))) { 2214 /* rescan the link */ 2215 mutex_enter(&mxfep->mxfe_xmtlock); 2216 mxfe_checklink(mxfep); 2217 mutex_exit(&mxfep->mxfe_xmtlock); 2218 } 2219 2220 if (status & (INT_RXSTOPPED|INT_TXSTOPPED|INT_RXNOBUF| 2221 INT_RXJABBER|INT_TXJABBER|INT_TXUNDERFLOW)) { 2222 2223 if (status & (INT_RXJABBER | INT_TXJABBER)) { 2224 mxfep->mxfe_jabber++; 2225 } 2226 DBG(DWARN, "error interrupt: status %x", status); 2227 error = B_TRUE; 2228 } 2229 2230 if (status & INT_BUSERR) { 2231 switch (status & SR_BERR_TYPE) { 2232 case SR_BERR_PARITY: 2233 mxfe_error(mxfep->mxfe_dip, "PCI parity error"); 2234 break; 2235 case SR_BERR_TARGET_ABORT: 2236 mxfe_error(mxfep->mxfe_dip, "PCI target abort"); 2237 break; 2238 case SR_BERR_MASTER_ABORT: 2239 mxfe_error(mxfep->mxfe_dip, "PCI master abort"); 2240 break; 2241 default: 2242 mxfe_error(mxfep->mxfe_dip, "Unknown PCI error"); 2243 break; 2244 } 2245 2246 error = B_TRUE; 2247 } 2248 2249 if (error) { 2250 /* reset the chip in an attempt to fix things */ 2251 mutex_enter(&mxfep->mxfe_xmtlock); 2252 mxfe_resetall(mxfep); 2253 mutex_exit(&mxfep->mxfe_xmtlock); 2254 } 2255 2256 mutex_exit(&mxfep->mxfe_intrlock); 2257 2258 /* 2259 * Send up packets. We do this outside of the intrlock. 2260 */ 2261 if (mp) { 2262 mac_rx(mxfep->mxfe_mh, NULL, mp); 2263 } 2264 2265 return (DDI_INTR_CLAIMED); 2266 } 2267 2268 void 2269 mxfe_enableinterrupts(mxfe_t *mxfep) 2270 { 2271 unsigned mask = INT_WANTED; 2272 2273 if (mxfep->mxfe_wantw) 2274 mask |= INT_TXOK; 2275 2276 if (MXFE_MODEL(mxfep) != MXFE_98713A) 2277 mask |= INT_LINKSTATUS; 2278 2279 DBG(DINTR, "setting int mask to 0x%x", mask); 2280 PUTCSR(mxfep, CSR_IER, mask); 2281 } 2282 2283 void 2284 mxfe_disableinterrupts(mxfe_t *mxfep) 2285 { 2286 /* disable further interrupts */ 2287 PUTCSR(mxfep, CSR_IER, 0); 2288 2289 /* clear any pending interrupts */ 2290 PUTCSR(mxfep, CSR_SR, INT_ALL); 2291 } 2292 2293 void 2294 mxfe_send_setup(mxfe_t *mxfep) 2295 { 2296 mxfe_txbuf_t *txb; 2297 mxfe_desc_t *tmdp; 2298 2299 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock)); 2300 2301 /* setup frame -- must be at head of list -- guaranteed by caller! */ 2302 ASSERT(mxfep->mxfe_txsend == 0); 2303 2304 txb = mxfep->mxfe_txbufs[0]; 2305 tmdp = &mxfep->mxfe_txdescp[0]; 2306 2307 bzero(txb->txb_buf, MXFE_SETUP_LEN); 2308 2309 /* program the unicast address */ 2310 txb->txb_buf[156] = mxfep->mxfe_curraddr[0]; 2311 txb->txb_buf[157] = mxfep->mxfe_curraddr[1]; 2312 txb->txb_buf[160] = mxfep->mxfe_curraddr[2]; 2313 txb->txb_buf[161] = mxfep->mxfe_curraddr[3]; 2314 txb->txb_buf[164] = mxfep->mxfe_curraddr[4]; 2315 txb->txb_buf[165] = mxfep->mxfe_curraddr[5]; 2316 2317 /* make sure that the hardware can see it */ 2318 SYNCTXBUF(txb, MXFE_SETUP_LEN, DDI_DMA_SYNC_FORDEV); 2319 2320 PUTTXDESC(mxfep, tmdp->desc_control, 2321 TXCTL_FIRST | TXCTL_LAST | TXCTL_INTCMPLTE | TXCTL_HASHPERF | 2322 TXCTL_SETUP | MXFE_SETUP_LEN); 2323 2324 PUTTXDESC(mxfep, tmdp->desc_buffer1, txb->txb_paddr); 2325 PUTTXDESC(mxfep, tmdp->desc_buffer2, 0); 2326 PUTTXDESC(mxfep, tmdp->desc_status, TXSTAT_OWN); 2327 2328 /* sync the descriptor out to the device */ 2329 SYNCTXDESC(mxfep, 0, DDI_DMA_SYNC_FORDEV); 2330 2331 /* 2332 * wake up the chip ... inside the lock to protect against DR suspend, 2333 * etc. 2334 */ 2335 PUTCSR(mxfep, CSR_TDR, 0); 2336 mxfep->mxfe_txsend++; 2337 mxfep->mxfe_txavail--; 2338 2339 /* 2340 * Program promiscuous mode. 2341 */ 2342 if (mxfep->mxfe_promisc) { 2343 SETBIT(mxfep, CSR_NAR, NAR_RX_PROMISC); 2344 } else { 2345 CLRBIT(mxfep, CSR_NAR, NAR_RX_PROMISC); 2346 } 2347 } 2348 2349 boolean_t 2350 mxfe_send(mxfe_t *mxfep, mblk_t *mp) 2351 { 2352 size_t len; 2353 mxfe_txbuf_t *txb; 2354 mxfe_desc_t *tmd; 2355 uint32_t control; 2356 int txsend; 2357 2358 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock)); 2359 ASSERT(mp != NULL); 2360 2361 len = msgsize(mp); 2362 if (len > ETHERVLANMTU) { 2363 DBG(DXMIT, "frame too long: %d", len); 2364 mxfep->mxfe_macxmt_errors++; 2365 freemsg(mp); 2366 return (B_TRUE); 2367 } 2368 2369 if (mxfep->mxfe_txavail < MXFE_TXRECLAIM) 2370 mxfe_reclaim(mxfep); 2371 2372 if (mxfep->mxfe_txavail == 0) { 2373 /* no more tmds */ 2374 mxfep->mxfe_wantw = B_TRUE; 2375 /* enable TX interrupt */ 2376 mxfe_enableinterrupts(mxfep); 2377 return (B_FALSE); 2378 } 2379 2380 txsend = mxfep->mxfe_txsend; 2381 2382 /* 2383 * For simplicity, we just do a copy into a preallocated 2384 * DMA buffer. 2385 */ 2386 2387 txb = mxfep->mxfe_txbufs[txsend]; 2388 mcopymsg(mp, txb->txb_buf); /* frees mp! */ 2389 2390 /* 2391 * Statistics. 2392 */ 2393 mxfep->mxfe_opackets++; 2394 mxfep->mxfe_obytes += len; 2395 if (txb->txb_buf[0] & 0x1) { 2396 if (bcmp(txb->txb_buf, mxfe_broadcast, ETHERADDRL) != 0) 2397 mxfep->mxfe_multixmt++; 2398 else 2399 mxfep->mxfe_brdcstxmt++; 2400 } 2401 2402 /* note len is already known to be a small unsigned */ 2403 control = len | TXCTL_FIRST | TXCTL_LAST | TXCTL_INTCMPLTE; 2404 2405 if (txsend == (MXFE_TXRING - 1)) 2406 control |= TXCTL_ENDRING; 2407 2408 tmd = &mxfep->mxfe_txdescp[txsend]; 2409 2410 SYNCTXBUF(txb, len, DDI_DMA_SYNC_FORDEV); 2411 PUTTXDESC(mxfep, tmd->desc_control, control); 2412 PUTTXDESC(mxfep, tmd->desc_buffer1, txb->txb_paddr); 2413 PUTTXDESC(mxfep, tmd->desc_buffer2, 0); 2414 PUTTXDESC(mxfep, tmd->desc_status, TXSTAT_OWN); 2415 /* sync the descriptor out to the device */ 2416 SYNCTXDESC(mxfep, txsend, DDI_DMA_SYNC_FORDEV); 2417 2418 /* 2419 * Note the new values of txavail and txsend. 2420 */ 2421 mxfep->mxfe_txavail--; 2422 mxfep->mxfe_txsend = (txsend + 1) % MXFE_TXRING; 2423 2424 /* 2425 * It should never, ever take more than 5 seconds to drain 2426 * the ring. If it happens, then we are stuck! 2427 */ 2428 mxfep->mxfe_txstall_time = gethrtime() + (5 * 1000000000ULL); 2429 2430 /* 2431 * wake up the chip ... inside the lock to protect against DR suspend, 2432 * etc. 2433 */ 2434 PUTCSR(mxfep, CSR_TDR, 0); 2435 2436 return (B_TRUE); 2437 } 2438 2439 /* 2440 * Reclaim buffers that have completed transmission. 2441 */ 2442 void 2443 mxfe_reclaim(mxfe_t *mxfep) 2444 { 2445 mxfe_desc_t *tmdp; 2446 2447 while (mxfep->mxfe_txavail != MXFE_TXRING) { 2448 uint32_t status; 2449 uint32_t control; 2450 int index = mxfep->mxfe_txreclaim; 2451 2452 tmdp = &mxfep->mxfe_txdescp[index]; 2453 2454 /* sync it before we read it */ 2455 SYNCTXDESC(mxfep, index, DDI_DMA_SYNC_FORKERNEL); 2456 2457 control = GETTXDESC(mxfep, tmdp->desc_control); 2458 status = GETTXDESC(mxfep, tmdp->desc_status); 2459 2460 if (status & TXSTAT_OWN) { 2461 /* chip is still working on it, we're done */ 2462 break; 2463 } 2464 2465 mxfep->mxfe_txavail++; 2466 mxfep->mxfe_txreclaim = (index + 1) % MXFE_TXRING; 2467 2468 /* in the most common successful case, all bits are clear */ 2469 if (status == 0) 2470 continue; 2471 2472 if (((control & TXCTL_SETUP) != 0) || 2473 ((control & TXCTL_LAST) == 0)) { 2474 /* no interesting statistics here */ 2475 continue; 2476 } 2477 2478 if (status & TXSTAT_TXERR) { 2479 mxfep->mxfe_errxmt++; 2480 2481 if (status & TXSTAT_JABBER) { 2482 /* transmit jabber timeout */ 2483 mxfep->mxfe_macxmt_errors++; 2484 } 2485 if (status & (TXSTAT_CARRLOST | TXSTAT_NOCARR)) { 2486 mxfep->mxfe_carrier_errors++; 2487 } 2488 if (status & TXSTAT_UFLOW) { 2489 mxfep->mxfe_underflow++; 2490 } 2491 if (status & TXSTAT_LATECOL) { 2492 mxfep->mxfe_tx_late_collisions++; 2493 } 2494 if (status & TXSTAT_EXCOLL) { 2495 mxfep->mxfe_ex_collisions++; 2496 mxfep->mxfe_collisions += 16; 2497 } 2498 } 2499 2500 if (status & TXSTAT_DEFER) { 2501 mxfep->mxfe_defer_xmts++; 2502 } 2503 2504 /* collision counting */ 2505 if (TXCOLLCNT(status) == 1) { 2506 mxfep->mxfe_collisions++; 2507 mxfep->mxfe_first_collisions++; 2508 } else if (TXCOLLCNT(status)) { 2509 mxfep->mxfe_collisions += TXCOLLCNT(status); 2510 mxfep->mxfe_multi_collisions += TXCOLLCNT(status); 2511 } 2512 } 2513 2514 if (mxfep->mxfe_txavail >= MXFE_TXRESCHED) { 2515 if (mxfep->mxfe_wantw) { 2516 /* 2517 * we were able to reclaim some packets, so 2518 * disable tx interrupts 2519 */ 2520 mxfep->mxfe_wantw = B_FALSE; 2521 mxfe_enableinterrupts(mxfep); 2522 mac_tx_update(mxfep->mxfe_mh); 2523 } 2524 } 2525 } 2526 2527 boolean_t 2528 mxfe_receive(mxfe_t *mxfep, mblk_t **rxchain) 2529 { 2530 unsigned len; 2531 mxfe_rxbuf_t *rxb; 2532 mxfe_desc_t *rmd; 2533 uint32_t status; 2534 mblk_t *mpchain, **mpp, *mp; 2535 int head, cnt; 2536 boolean_t error = B_FALSE; 2537 2538 mpchain = NULL; 2539 mpp = &mpchain; 2540 head = mxfep->mxfe_rxhead; 2541 2542 /* limit the number of packets we process to a ring size */ 2543 for (cnt = 0; cnt < MXFE_RXRING; cnt++) { 2544 2545 DBG(DRECV, "receive at index %d", head); 2546 2547 rmd = &mxfep->mxfe_rxdescp[head]; 2548 rxb = mxfep->mxfe_rxbufs[head]; 2549 2550 SYNCRXDESC(mxfep, head, DDI_DMA_SYNC_FORKERNEL); 2551 status = GETRXDESC(mxfep, rmd->desc_status); 2552 if (status & RXSTAT_OWN) { 2553 /* chip is still chewing on it */ 2554 break; 2555 } 2556 2557 /* discard the ethernet frame checksum */ 2558 len = RXLENGTH(status) - ETHERFCSL; 2559 2560 DBG(DRECV, "recv length %d, status %x", len, status); 2561 2562 if ((status & (RXSTAT_ERRS | RXSTAT_FIRST | RXSTAT_LAST)) != 2563 (RXSTAT_FIRST | RXSTAT_LAST)) { 2564 2565 mxfep->mxfe_errrcv++; 2566 2567 /* 2568 * Abnormal status bits detected, analyze further. 2569 */ 2570 if ((status & (RXSTAT_LAST|RXSTAT_FIRST)) != 2571 (RXSTAT_LAST|RXSTAT_FIRST)) { 2572 /* someone trying to send jumbo frames? */ 2573 DBG(DRECV, "rx packet overspill"); 2574 if (status & RXSTAT_FIRST) { 2575 mxfep->mxfe_toolong_errors++; 2576 } 2577 } else if (status & RXSTAT_DESCERR) { 2578 /* this should never occur! */ 2579 mxfep->mxfe_macrcv_errors++; 2580 error = B_TRUE; 2581 2582 } else if (status & RXSTAT_RUNT) { 2583 mxfep->mxfe_runt++; 2584 2585 } else if (status & RXSTAT_COLLSEEN) { 2586 /* this should really be rx_late_collisions */ 2587 mxfep->mxfe_macrcv_errors++; 2588 2589 } else if (status & RXSTAT_DRIBBLE) { 2590 mxfep->mxfe_align_errors++; 2591 2592 } else if (status & RXSTAT_CRCERR) { 2593 mxfep->mxfe_fcs_errors++; 2594 2595 } else if (status & RXSTAT_OFLOW) { 2596 /* this is a MAC FIFO error, need to reset */ 2597 mxfep->mxfe_overflow++; 2598 error = B_TRUE; 2599 } 2600 } 2601 2602 else if (len > ETHERVLANMTU) { 2603 mxfep->mxfe_errrcv++; 2604 mxfep->mxfe_toolong_errors++; 2605 } 2606 2607 /* 2608 * At this point, the chip thinks the packet is OK. 2609 */ 2610 else { 2611 mp = allocb(len + MXFE_HEADROOM, 0); 2612 if (mp == NULL) { 2613 mxfep->mxfe_errrcv++; 2614 mxfep->mxfe_norcvbuf++; 2615 goto skip; 2616 } 2617 2618 /* sync the buffer before we look at it */ 2619 SYNCRXBUF(rxb, len, DDI_DMA_SYNC_FORKERNEL); 2620 mp->b_rptr += MXFE_HEADROOM; 2621 mp->b_wptr = mp->b_rptr + len; 2622 bcopy((char *)rxb->rxb_buf, mp->b_rptr, len); 2623 2624 mxfep->mxfe_ipackets++; 2625 mxfep->mxfe_rbytes += len; 2626 if (status & RXSTAT_GROUP) { 2627 if (bcmp(mp->b_rptr, mxfe_broadcast, 2628 ETHERADDRL) == 0) 2629 mxfep->mxfe_brdcstrcv++; 2630 else 2631 mxfep->mxfe_multircv++; 2632 } 2633 *mpp = mp; 2634 mpp = &mp->b_next; 2635 } 2636 2637 skip: 2638 /* return ring entry to the hardware */ 2639 PUTRXDESC(mxfep, rmd->desc_status, RXSTAT_OWN); 2640 SYNCRXDESC(mxfep, head, DDI_DMA_SYNC_FORDEV); 2641 2642 /* advance to next RMD */ 2643 head = (head + 1) % MXFE_RXRING; 2644 } 2645 2646 mxfep->mxfe_rxhead = head; 2647 2648 *rxchain = mpchain; 2649 return (error); 2650 } 2651 2652 int 2653 mxfe_m_stat(void *arg, uint_t stat, uint64_t *val) 2654 { 2655 mxfe_t *mxfep = arg; 2656 2657 mutex_enter(&mxfep->mxfe_xmtlock); 2658 if ((mxfep->mxfe_flags & (MXFE_RUNNING|MXFE_SUSPENDED)) == MXFE_RUNNING) 2659 mxfe_reclaim(mxfep); 2660 mutex_exit(&mxfep->mxfe_xmtlock); 2661 2662 switch (stat) { 2663 case MAC_STAT_IFSPEED: 2664 *val = mxfep->mxfe_ifspeed; 2665 break; 2666 2667 case MAC_STAT_MULTIRCV: 2668 *val = mxfep->mxfe_multircv; 2669 break; 2670 2671 case MAC_STAT_BRDCSTRCV: 2672 *val = mxfep->mxfe_brdcstrcv; 2673 break; 2674 2675 case MAC_STAT_MULTIXMT: 2676 *val = mxfep->mxfe_multixmt; 2677 break; 2678 2679 case MAC_STAT_BRDCSTXMT: 2680 *val = mxfep->mxfe_brdcstxmt; 2681 break; 2682 2683 case MAC_STAT_IPACKETS: 2684 *val = mxfep->mxfe_ipackets; 2685 break; 2686 2687 case MAC_STAT_RBYTES: 2688 *val = mxfep->mxfe_rbytes; 2689 break; 2690 2691 case MAC_STAT_OPACKETS: 2692 *val = mxfep->mxfe_opackets; 2693 break; 2694 2695 case MAC_STAT_OBYTES: 2696 *val = mxfep->mxfe_obytes; 2697 break; 2698 2699 case MAC_STAT_NORCVBUF: 2700 *val = mxfep->mxfe_norcvbuf; 2701 break; 2702 2703 case MAC_STAT_NOXMTBUF: 2704 *val = mxfep->mxfe_noxmtbuf; 2705 break; 2706 2707 case MAC_STAT_COLLISIONS: 2708 *val = mxfep->mxfe_collisions; 2709 break; 2710 2711 case MAC_STAT_IERRORS: 2712 *val = mxfep->mxfe_errrcv; 2713 break; 2714 2715 case MAC_STAT_OERRORS: 2716 *val = mxfep->mxfe_errxmt; 2717 break; 2718 2719 case ETHER_STAT_LINK_DUPLEX: 2720 *val = mxfep->mxfe_duplex; 2721 break; 2722 2723 case ETHER_STAT_ALIGN_ERRORS: 2724 *val = mxfep->mxfe_align_errors; 2725 break; 2726 2727 case ETHER_STAT_FCS_ERRORS: 2728 *val = mxfep->mxfe_fcs_errors; 2729 break; 2730 2731 case ETHER_STAT_SQE_ERRORS: 2732 *val = mxfep->mxfe_sqe_errors; 2733 break; 2734 2735 case ETHER_STAT_DEFER_XMTS: 2736 *val = mxfep->mxfe_defer_xmts; 2737 break; 2738 2739 case ETHER_STAT_FIRST_COLLISIONS: 2740 *val = mxfep->mxfe_first_collisions; 2741 break; 2742 2743 case ETHER_STAT_MULTI_COLLISIONS: 2744 *val = mxfep->mxfe_multi_collisions; 2745 break; 2746 2747 case ETHER_STAT_TX_LATE_COLLISIONS: 2748 *val = mxfep->mxfe_tx_late_collisions; 2749 break; 2750 2751 case ETHER_STAT_EX_COLLISIONS: 2752 *val = mxfep->mxfe_ex_collisions; 2753 break; 2754 2755 case ETHER_STAT_MACXMT_ERRORS: 2756 *val = mxfep->mxfe_macxmt_errors; 2757 break; 2758 2759 case ETHER_STAT_CARRIER_ERRORS: 2760 *val = mxfep->mxfe_carrier_errors; 2761 break; 2762 2763 case ETHER_STAT_TOOLONG_ERRORS: 2764 *val = mxfep->mxfe_toolong_errors; 2765 break; 2766 2767 case ETHER_STAT_MACRCV_ERRORS: 2768 *val = mxfep->mxfe_macrcv_errors; 2769 break; 2770 2771 case MAC_STAT_OVERFLOWS: 2772 *val = mxfep->mxfe_overflow; 2773 break; 2774 2775 case MAC_STAT_UNDERFLOWS: 2776 *val = mxfep->mxfe_underflow; 2777 break; 2778 2779 case ETHER_STAT_TOOSHORT_ERRORS: 2780 *val = mxfep->mxfe_runt; 2781 break; 2782 2783 case ETHER_STAT_JABBER_ERRORS: 2784 *val = mxfep->mxfe_jabber; 2785 break; 2786 2787 case ETHER_STAT_ADV_CAP_100T4: 2788 *val = mxfep->mxfe_adv_100T4; 2789 break; 2790 2791 case ETHER_STAT_LP_CAP_100T4: 2792 *val = (mxfep->mxfe_anlpar & MII_ABILITY_100BASE_T4) ? 1 : 0; 2793 break; 2794 2795 case ETHER_STAT_CAP_100T4: 2796 *val = mxfep->mxfe_cap_100T4; 2797 break; 2798 2799 case ETHER_STAT_CAP_100FDX: 2800 *val = mxfep->mxfe_cap_100fdx; 2801 break; 2802 2803 case ETHER_STAT_CAP_100HDX: 2804 *val = mxfep->mxfe_cap_100hdx; 2805 break; 2806 2807 case ETHER_STAT_CAP_10FDX: 2808 *val = mxfep->mxfe_cap_10fdx; 2809 break; 2810 2811 case ETHER_STAT_CAP_10HDX: 2812 *val = mxfep->mxfe_cap_10hdx; 2813 break; 2814 2815 case ETHER_STAT_CAP_AUTONEG: 2816 *val = mxfep->mxfe_cap_aneg; 2817 break; 2818 2819 case ETHER_STAT_LINK_AUTONEG: 2820 *val = ((mxfep->mxfe_adv_aneg != 0) && 2821 ((mxfep->mxfe_aner & MII_AN_EXP_LPCANAN) != 0)); 2822 break; 2823 2824 case ETHER_STAT_ADV_CAP_100FDX: 2825 *val = mxfep->mxfe_adv_100fdx; 2826 break; 2827 2828 case ETHER_STAT_ADV_CAP_100HDX: 2829 *val = mxfep->mxfe_adv_100hdx; 2830 break; 2831 2832 case ETHER_STAT_ADV_CAP_10FDX: 2833 *val = mxfep->mxfe_adv_10fdx; 2834 break; 2835 2836 case ETHER_STAT_ADV_CAP_10HDX: 2837 *val = mxfep->mxfe_adv_10hdx; 2838 break; 2839 2840 case ETHER_STAT_ADV_CAP_AUTONEG: 2841 *val = mxfep->mxfe_adv_aneg; 2842 break; 2843 2844 case ETHER_STAT_LP_CAP_100FDX: 2845 *val = (mxfep->mxfe_anlpar & MII_ABILITY_100BASE_TX_FD) ? 1 : 0; 2846 break; 2847 2848 case ETHER_STAT_LP_CAP_100HDX: 2849 *val = (mxfep->mxfe_anlpar & MII_ABILITY_100BASE_TX) ? 1 : 0; 2850 break; 2851 2852 case ETHER_STAT_LP_CAP_10FDX: 2853 *val = (mxfep->mxfe_anlpar & MII_ABILITY_10BASE_T_FD) ? 1 : 0; 2854 break; 2855 2856 case ETHER_STAT_LP_CAP_10HDX: 2857 *val = (mxfep->mxfe_anlpar & MII_ABILITY_10BASE_T) ? 1 : 0; 2858 break; 2859 2860 case ETHER_STAT_LP_CAP_AUTONEG: 2861 *val = (mxfep->mxfe_aner & MII_AN_EXP_LPCANAN) ? 1 : 0; 2862 break; 2863 2864 case ETHER_STAT_XCVR_ADDR: 2865 *val = mxfep->mxfe_phyaddr; 2866 break; 2867 2868 case ETHER_STAT_XCVR_ID: 2869 *val = mxfep->mxfe_phyid; 2870 break; 2871 2872 case ETHER_STAT_XCVR_INUSE: 2873 *val = mxfep->mxfe_phyinuse; 2874 break; 2875 2876 default: 2877 return (ENOTSUP); 2878 } 2879 return (0); 2880 } 2881 2882 /*ARGSUSED*/ 2883 int 2884 mxfe_m_getprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz, 2885 void *val) 2886 { 2887 mxfe_t *mxfep = arg; 2888 int err = 0; 2889 2890 switch (num) { 2891 case MAC_PROP_DUPLEX: 2892 ASSERT(sz >= sizeof (link_duplex_t)); 2893 bcopy(&mxfep->mxfe_duplex, val, sizeof (link_duplex_t)); 2894 break; 2895 2896 case MAC_PROP_SPEED: 2897 ASSERT(sz >= sizeof (uint64_t)); 2898 bcopy(&mxfep->mxfe_ifspeed, val, sizeof (uint64_t)); 2899 break; 2900 2901 case MAC_PROP_AUTONEG: 2902 *(uint8_t *)val = mxfep->mxfe_adv_aneg; 2903 break; 2904 2905 case MAC_PROP_ADV_100FDX_CAP: 2906 case MAC_PROP_EN_100FDX_CAP: 2907 *(uint8_t *)val = mxfep->mxfe_adv_100fdx; 2908 break; 2909 2910 case MAC_PROP_ADV_100HDX_CAP: 2911 case MAC_PROP_EN_100HDX_CAP: 2912 *(uint8_t *)val = mxfep->mxfe_adv_100hdx; 2913 break; 2914 2915 case MAC_PROP_ADV_10FDX_CAP: 2916 case MAC_PROP_EN_10FDX_CAP: 2917 *(uint8_t *)val = mxfep->mxfe_adv_10fdx; 2918 break; 2919 2920 case MAC_PROP_ADV_10HDX_CAP: 2921 case MAC_PROP_EN_10HDX_CAP: 2922 *(uint8_t *)val = mxfep->mxfe_adv_10hdx; 2923 break; 2924 2925 case MAC_PROP_ADV_100T4_CAP: 2926 case MAC_PROP_EN_100T4_CAP: 2927 *(uint8_t *)val = mxfep->mxfe_adv_100T4; 2928 break; 2929 2930 default: 2931 err = ENOTSUP; 2932 } 2933 2934 return (err); 2935 } 2936 2937 /*ARGSUSED*/ 2938 int 2939 mxfe_m_setprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz, 2940 const void *val) 2941 { 2942 mxfe_t *mxfep = arg; 2943 uint8_t *advp; 2944 uint8_t *capp; 2945 2946 switch (num) { 2947 case MAC_PROP_EN_100FDX_CAP: 2948 advp = &mxfep->mxfe_adv_100fdx; 2949 capp = &mxfep->mxfe_cap_100fdx; 2950 break; 2951 2952 case MAC_PROP_EN_100HDX_CAP: 2953 advp = &mxfep->mxfe_adv_100hdx; 2954 capp = &mxfep->mxfe_cap_100hdx; 2955 break; 2956 2957 case MAC_PROP_EN_10FDX_CAP: 2958 advp = &mxfep->mxfe_adv_10fdx; 2959 capp = &mxfep->mxfe_cap_10fdx; 2960 break; 2961 2962 case MAC_PROP_EN_10HDX_CAP: 2963 advp = &mxfep->mxfe_adv_10hdx; 2964 capp = &mxfep->mxfe_cap_10hdx; 2965 break; 2966 2967 case MAC_PROP_EN_100T4_CAP: 2968 advp = &mxfep->mxfe_adv_100T4; 2969 capp = &mxfep->mxfe_cap_100T4; 2970 break; 2971 2972 case MAC_PROP_AUTONEG: 2973 advp = &mxfep->mxfe_adv_aneg; 2974 capp = &mxfep->mxfe_cap_aneg; 2975 break; 2976 2977 default: 2978 return (ENOTSUP); 2979 } 2980 2981 if (*capp == 0) /* ensure phy can support value */ 2982 return (ENOTSUP); 2983 2984 mutex_enter(&mxfep->mxfe_intrlock); 2985 mutex_enter(&mxfep->mxfe_xmtlock); 2986 2987 if (*advp != *(const uint8_t *)val) { 2988 *advp = *(const uint8_t *)val; 2989 2990 if ((mxfep->mxfe_flags & (MXFE_RUNNING|MXFE_SUSPENDED)) == 2991 MXFE_RUNNING) { 2992 /* 2993 * This re-initializes the phy, but it also 2994 * restarts transmit and receive rings. 2995 * Needless to say, changing the link 2996 * parameters is destructive to traffic in 2997 * progress. 2998 */ 2999 mxfe_resetall(mxfep); 3000 } 3001 } 3002 mutex_exit(&mxfep->mxfe_xmtlock); 3003 mutex_exit(&mxfep->mxfe_intrlock); 3004 3005 return (0); 3006 } 3007 3008 static void 3009 mxfe_m_propinfo(void *arg, const char *name, mac_prop_id_t num, 3010 mac_prop_info_handle_t mph) 3011 { 3012 mxfe_t *mxfep = arg; 3013 3014 _NOTE(ARGUNUSED(name)); 3015 3016 switch (num) { 3017 case MAC_PROP_DUPLEX: 3018 case MAC_PROP_SPEED: 3019 case MAC_PROP_ADV_100FDX_CAP: 3020 case MAC_PROP_ADV_100HDX_CAP: 3021 case MAC_PROP_ADV_10FDX_CAP: 3022 case MAC_PROP_ADV_10HDX_CAP: 3023 case MAC_PROP_ADV_100T4_CAP: 3024 mac_prop_info_set_perm(mph, MAC_PROP_PERM_READ); 3025 break; 3026 3027 case MAC_PROP_AUTONEG: 3028 mac_prop_info_set_default_uint8(mph, mxfep->mxfe_cap_aneg); 3029 break; 3030 3031 case MAC_PROP_EN_100FDX_CAP: 3032 mac_prop_info_set_default_uint8(mph, mxfep->mxfe_cap_100fdx); 3033 break; 3034 3035 case MAC_PROP_EN_100HDX_CAP: 3036 mac_prop_info_set_default_uint8(mph, mxfep->mxfe_cap_100hdx); 3037 break; 3038 3039 case MAC_PROP_EN_10FDX_CAP: 3040 mac_prop_info_set_default_uint8(mph, mxfep->mxfe_cap_10fdx); 3041 break; 3042 3043 case MAC_PROP_EN_10HDX_CAP: 3044 mac_prop_info_set_default_uint8(mph, mxfep->mxfe_cap_10hdx); 3045 break; 3046 3047 case MAC_PROP_EN_100T4_CAP: 3048 mac_prop_info_set_default_uint8(mph, mxfep->mxfe_cap_100T4); 3049 break; 3050 } 3051 } 3052 3053 /* 3054 * Debugging and error reporting. 3055 */ 3056 void 3057 mxfe_error(dev_info_t *dip, char *fmt, ...) 3058 { 3059 va_list ap; 3060 char buf[256]; 3061 3062 va_start(ap, fmt); 3063 (void) vsnprintf(buf, sizeof (buf), fmt, ap); 3064 va_end(ap); 3065 3066 if (dip) { 3067 cmn_err(CE_WARN, "%s%d: %s", 3068 ddi_driver_name(dip), ddi_get_instance(dip), buf); 3069 } else { 3070 cmn_err(CE_WARN, "mxfe: %s", buf); 3071 } 3072 } 3073 3074 #ifdef DEBUG 3075 3076 void 3077 mxfe_dprintf(mxfe_t *mxfep, const char *func, int level, char *fmt, ...) 3078 { 3079 va_list ap; 3080 3081 va_start(ap, fmt); 3082 if (mxfe_debug & level) { 3083 char tag[64]; 3084 char buf[256]; 3085 3086 if (mxfep && mxfep->mxfe_dip) { 3087 (void) snprintf(tag, sizeof (tag), 3088 "%s%d", ddi_driver_name(mxfep->mxfe_dip), 3089 ddi_get_instance(mxfep->mxfe_dip)); 3090 } else { 3091 (void) snprintf(tag, sizeof (tag), "mxfe"); 3092 } 3093 3094 (void) snprintf(buf, sizeof (buf), "%s: %s: %s\n", tag, 3095 func, fmt); 3096 3097 vcmn_err(CE_CONT, buf, ap); 3098 } 3099 va_end(ap); 3100 } 3101 3102 #endif 3103