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