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 #pragma ident "%Z%%M% %I% %E% SMI" 33 34 #include <sys/varargs.h> 35 #include <sys/types.h> 36 #include <sys/modctl.h> 37 #include <sys/conf.h> 38 #include <sys/devops.h> 39 #include <sys/stream.h> 40 #include <sys/strsun.h> 41 #include <sys/cmn_err.h> 42 #include <sys/dlpi.h> 43 #include <sys/ethernet.h> 44 #include <sys/kmem.h> 45 #include <sys/time.h> 46 #include <sys/miiregs.h> 47 #include <sys/strsun.h> 48 #include <sys/priv.h> 49 #include <sys/policy.h> 50 #include <sys/cred.h> 51 #include <sys/mac.h> 52 #include <sys/mac_ether.h> 53 #include <sys/ddi.h> 54 #include <sys/sunddi.h> 55 56 #include "mxfe.h" 57 #include "mxfeimpl.h" 58 59 /* 60 * Driver globals. 61 */ 62 63 /* patchable debug flag ... must not be static! */ 64 #ifdef DEBUG 65 unsigned mxfe_debug = DWARN; 66 #endif 67 68 /* table of supported devices */ 69 static mxfe_card_t mxfe_cards[] = { 70 71 /* 72 * Lite-On products 73 */ 74 { 0x11ad, 0xc115, 0, 0, "Lite-On LC82C115", MXFE_PNICII }, 75 76 /* 77 * Macronix chips 78 */ 79 { 0x10d9, 0x0531, 0x25, 0xff, "Macronix MX98715AEC", MXFE_98715AEC }, 80 { 0x10d9, 0x0531, 0x20, 0xff, "Macronix MX98715A", MXFE_98715A }, 81 { 0x10d9, 0x0531, 0x60, 0xff, "Macronix MX98715B", MXFE_98715B }, 82 { 0x10d9, 0x0531, 0x30, 0xff, "Macronix MX98725", MXFE_98725 }, 83 { 0x10d9, 0x0531, 0x00, 0xff, "Macronix MX98715", MXFE_98715 }, 84 { 0x10d9, 0x0512, 0, 0, "Macronix MX98713", MXFE_98713 }, 85 86 /* 87 * Compex (relabeled Macronix products) 88 */ 89 { 0x11fc, 0x9881, 0x00, 0x00, "Compex 9881", MXFE_98713 }, 90 { 0x11fc, 0x9881, 0x10, 0xff, "Compex 9881A", MXFE_98713A }, 91 /* 92 * Models listed here 93 */ 94 { 0x11ad, 0xc001, 0, 0, "Linksys LNE100TX", MXFE_PNICII }, 95 { 0x2646, 0x000b, 0, 0, "Kingston KNE111TX", MXFE_PNICII }, 96 { 0x1154, 0x0308, 0, 0, "Buffalo LGY-PCI-TXL", MXFE_98715AEC }, 97 }; 98 99 #define ETHERVLANMTU (ETHERMAX + 4) 100 101 /* 102 * Function prototypes 103 */ 104 static int mxfe_attach(dev_info_t *, ddi_attach_cmd_t); 105 static int mxfe_detach(dev_info_t *, ddi_detach_cmd_t); 106 static int mxfe_resume(dev_info_t *); 107 static int mxfe_m_unicst(void *, const uint8_t *); 108 static int mxfe_m_multicst(void *, boolean_t, const uint8_t *); 109 static int mxfe_m_promisc(void *, boolean_t); 110 static mblk_t *mxfe_m_tx(void *, mblk_t *); 111 static int mxfe_m_stat(void *, uint_t, uint64_t *); 112 static int mxfe_m_start(void *); 113 static void mxfe_m_stop(void *); 114 static void mxfe_m_ioctl(void *, queue_t *, mblk_t *); 115 static unsigned mxfe_intr(caddr_t); 116 static void mxfe_startmac(mxfe_t *); 117 static void mxfe_stopmac(mxfe_t *); 118 static void mxfe_resetrings(mxfe_t *); 119 static boolean_t mxfe_initialize(mxfe_t *); 120 static void mxfe_startall(mxfe_t *); 121 static void mxfe_stopall(mxfe_t *); 122 static void mxfe_resetall(mxfe_t *); 123 static mxfe_txbuf_t *mxfe_alloctxbuf(mxfe_t *); 124 static void mxfe_destroytxbuf(mxfe_txbuf_t *); 125 static mxfe_rxbuf_t *mxfe_allocrxbuf(mxfe_t *); 126 static void mxfe_destroyrxbuf(mxfe_rxbuf_t *); 127 static void mxfe_send_setup(mxfe_t *); 128 static boolean_t mxfe_send(mxfe_t *, mblk_t *); 129 static int mxfe_allocrxring(mxfe_t *); 130 static void mxfe_freerxring(mxfe_t *); 131 static int mxfe_alloctxring(mxfe_t *); 132 static void mxfe_freetxring(mxfe_t *); 133 static void mxfe_error(dev_info_t *, char *, ...); 134 static uint8_t mxfe_sromwidth(mxfe_t *); 135 static uint16_t mxfe_readsromword(mxfe_t *, unsigned); 136 static void mxfe_readsrom(mxfe_t *, unsigned, unsigned, void *); 137 static void mxfe_getfactaddr(mxfe_t *, uchar_t *); 138 static int mxfe_miireadbit(mxfe_t *); 139 static void mxfe_miiwritebit(mxfe_t *, int); 140 static void mxfe_miitristate(mxfe_t *); 141 static unsigned mxfe_miiread(mxfe_t *, int, int); 142 static void mxfe_miiwrite(mxfe_t *, int, int, uint16_t); 143 static unsigned mxfe_miireadgeneral(mxfe_t *, int, int); 144 static void mxfe_miiwritegeneral(mxfe_t *, int, int, uint16_t); 145 static unsigned mxfe_miiread98713(mxfe_t *, int, int); 146 static void mxfe_miiwrite98713(mxfe_t *, int, int, uint16_t); 147 static void mxfe_startphy(mxfe_t *); 148 static void mxfe_stopphy(mxfe_t *); 149 static void mxfe_startphymii(mxfe_t *); 150 static void mxfe_startphynway(mxfe_t *); 151 static void mxfe_startnway(mxfe_t *); 152 static void mxfe_reportlink(mxfe_t *); 153 static void mxfe_checklink(mxfe_t *); 154 static void mxfe_checklinkmii(mxfe_t *); 155 static void mxfe_checklinknway(mxfe_t *); 156 static void mxfe_disableinterrupts(mxfe_t *); 157 static void mxfe_enableinterrupts(mxfe_t *); 158 static void mxfe_reclaim(mxfe_t *); 159 static mblk_t *mxfe_receive(mxfe_t *); 160 static int mxfe_ndaddbytes(mblk_t *, char *, int); 161 static int mxfe_ndaddstr(mblk_t *, char *, int); 162 static void mxfe_ndparsestring(mblk_t *, char *, int); 163 static int mxfe_ndparselen(mblk_t *); 164 static int mxfe_ndparseint(mblk_t *); 165 static void mxfe_ndget(mxfe_t *, queue_t *, mblk_t *); 166 static void mxfe_ndset(mxfe_t *, queue_t *, mblk_t *); 167 static void mxfe_ndfini(mxfe_t *); 168 static void mxfe_ndinit(mxfe_t *); 169 static int mxfe_ndquestion(mxfe_t *, mblk_t *, mxfe_nd_t *); 170 static int mxfe_ndgetint(mxfe_t *, mblk_t *, mxfe_nd_t *); 171 static int mxfe_ndgetbit(mxfe_t *, mblk_t *, mxfe_nd_t *); 172 static int mxfe_ndsetadv(mxfe_t *, mblk_t *, mxfe_nd_t *); 173 static mxfe_nd_t *mxfe_ndfind(mxfe_t *, char *); 174 static void mxfe_ndempty(mblk_t *); 175 static void mxfe_ndadd(mxfe_t *, char *, mxfe_nd_pf_t, mxfe_nd_pf_t, 176 intptr_t, intptr_t); 177 178 #ifdef DEBUG 179 static void mxfe_dprintf(mxfe_t *, const char *, int, char *, ...); 180 #endif 181 182 #define KIOIP KSTAT_INTR_PTR(mxfep->mxfe_intrstat) 183 184 static mac_callbacks_t mxfe_m_callbacks = { 185 MC_IOCTL, 186 mxfe_m_stat, 187 mxfe_m_start, 188 mxfe_m_stop, 189 mxfe_m_promisc, 190 mxfe_m_multicst, 191 mxfe_m_unicst, 192 mxfe_m_tx, 193 NULL, 194 mxfe_m_ioctl, 195 NULL, /* m_getcapab */ 196 }; 197 198 /* 199 * Stream information 200 */ 201 DDI_DEFINE_STREAM_OPS(mxfe_devops, nulldev, nulldev, mxfe_attach, mxfe_detach, 202 nodev, NULL, D_MP, NULL); 203 204 /* 205 * Module linkage information. 206 */ 207 208 static struct modldrv mxfe_modldrv = { 209 &mod_driverops, /* drv_modops */ 210 "Macronix Fast Ethernet", /* drv_linkinfo */ 211 &mxfe_devops /* drv_dev_ops */ 212 }; 213 214 static struct modlinkage mxfe_modlinkage = { 215 MODREV_1, /* ml_rev */ 216 { &mxfe_modldrv, NULL } /* ml_linkage */ 217 }; 218 219 /* 220 * Device attributes. 221 */ 222 static ddi_device_acc_attr_t mxfe_devattr = { 223 DDI_DEVICE_ATTR_V0, 224 DDI_STRUCTURE_LE_ACC, 225 DDI_STRICTORDER_ACC 226 }; 227 228 static ddi_device_acc_attr_t mxfe_bufattr = { 229 DDI_DEVICE_ATTR_V0, 230 DDI_NEVERSWAP_ACC, 231 DDI_STRICTORDER_ACC 232 }; 233 234 static ddi_dma_attr_t mxfe_dma_attr = { 235 DMA_ATTR_V0, /* dma_attr_version */ 236 0, /* dma_attr_addr_lo */ 237 0xFFFFFFFFU, /* dma_attr_addr_hi */ 238 0x7FFFFFFFU, /* dma_attr_count_max */ 239 4, /* dma_attr_align */ 240 0x3F, /* dma_attr_burstsizes */ 241 1, /* dma_attr_minxfer */ 242 0xFFFFFFFFU, /* dma_attr_maxxfer */ 243 0xFFFFFFFFU, /* dma_attr_seg */ 244 1, /* dma_attr_sgllen */ 245 1, /* dma_attr_granular */ 246 0 /* dma_attr_flags */ 247 }; 248 249 /* 250 * Tx buffers can be arbitrarily aligned. Additionally, they can 251 * cross a page boundary, so we use the two buffer addresses of the 252 * chip to provide a two-entry scatter-gather list. 253 */ 254 static ddi_dma_attr_t mxfe_dma_txattr = { 255 DMA_ATTR_V0, /* dma_attr_version */ 256 0, /* dma_attr_addr_lo */ 257 0xFFFFFFFFU, /* dma_attr_addr_hi */ 258 0x7FFFFFFFU, /* dma_attr_count_max */ 259 1, /* dma_attr_align */ 260 0x3F, /* dma_attr_burstsizes */ 261 1, /* dma_attr_minxfer */ 262 0xFFFFFFFFU, /* dma_attr_maxxfer */ 263 0xFFFFFFFFU, /* dma_attr_seg */ 264 2, /* dma_attr_sgllen */ 265 1, /* dma_attr_granular */ 266 0 /* dma_attr_flags */ 267 }; 268 269 /* 270 * Ethernet addresses. 271 */ 272 static uchar_t mxfe_broadcast[ETHERADDRL] = { 273 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 274 }; 275 276 /* 277 * DDI entry points. 278 */ 279 int 280 _init(void) 281 { 282 int rv; 283 mac_init_ops(&mxfe_devops, "mxfe"); 284 if ((rv = mod_install(&mxfe_modlinkage)) != DDI_SUCCESS) { 285 mac_fini_ops(&mxfe_devops); 286 } 287 return (rv); 288 } 289 290 int 291 _fini(void) 292 { 293 int rv; 294 if ((rv = mod_remove(&mxfe_modlinkage)) == DDI_SUCCESS) { 295 mac_fini_ops(&mxfe_devops); 296 } 297 return (rv); 298 } 299 300 int 301 _info(struct modinfo *modinfop) 302 { 303 return (mod_info(&mxfe_modlinkage, modinfop)); 304 } 305 306 int 307 mxfe_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 308 { 309 mxfe_t *mxfep; 310 mac_register_t *macp; 311 int inst = ddi_get_instance(dip); 312 ddi_acc_handle_t pci; 313 uint16_t venid; 314 uint16_t devid; 315 uint16_t revid; 316 uint16_t svid; 317 uint16_t ssid; 318 uint16_t cachesize; 319 mxfe_card_t *cardp; 320 int i; 321 322 switch (cmd) { 323 case DDI_RESUME: 324 return (mxfe_resume(dip)); 325 326 case DDI_ATTACH: 327 break; 328 329 default: 330 return (DDI_FAILURE); 331 } 332 333 /* this card is a bus master, reject any slave-only slot */ 334 if (ddi_slaveonly(dip) == DDI_SUCCESS) { 335 mxfe_error(dip, "slot does not support PCI bus-master"); 336 return (DDI_FAILURE); 337 } 338 /* PCI devices shouldn't generate hilevel interrupts */ 339 if (ddi_intr_hilevel(dip, 0) != 0) { 340 mxfe_error(dip, "hilevel interrupts not supported"); 341 return (DDI_FAILURE); 342 } 343 if (pci_config_setup(dip, &pci) != DDI_SUCCESS) { 344 mxfe_error(dip, "unable to setup PCI config handle"); 345 return (DDI_FAILURE); 346 } 347 348 venid = pci_config_get16(pci, PCI_VID); 349 devid = pci_config_get16(pci, PCI_DID); 350 revid = pci_config_get16(pci, PCI_RID); 351 svid = pci_config_get16(pci, PCI_SVID); 352 ssid = pci_config_get16(pci, PCI_SSID); 353 354 /* 355 * the last entry in the card table matches every possible 356 * card, so the for-loop always terminates properly. 357 */ 358 cardp = NULL; 359 for (i = 0; i < (sizeof (mxfe_cards) / sizeof (mxfe_card_t)); i++) { 360 if ((venid == mxfe_cards[i].card_venid) && 361 (devid == mxfe_cards[i].card_devid) && 362 ((revid & mxfe_cards[i].card_revmask) == 363 mxfe_cards[i].card_revid)) { 364 cardp = &mxfe_cards[i]; 365 } 366 if ((svid == mxfe_cards[i].card_venid) && 367 (ssid == mxfe_cards[i].card_devid) && 368 ((revid & mxfe_cards[i].card_revmask) == 369 mxfe_cards[i].card_revid)) { 370 cardp = &mxfe_cards[i]; 371 break; 372 } 373 } 374 375 if (cardp == NULL) { 376 pci_config_teardown(&pci); 377 mxfe_error(dip, "Unable to identify PCI card"); 378 return (DDI_FAILURE); 379 } 380 381 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, "model", 382 cardp->card_cardname) != DDI_PROP_SUCCESS) { 383 pci_config_teardown(&pci); 384 mxfe_error(dip, "Unable to create model property"); 385 return (DDI_FAILURE); 386 } 387 388 /* 389 * Grab the PCI cachesize -- we use this to program the 390 * cache-optimization bus access bits. 391 */ 392 cachesize = pci_config_get8(pci, PCI_CLS); 393 394 /* this cannot fail */ 395 mxfep = kmem_zalloc(sizeof (mxfe_t), KM_SLEEP); 396 ddi_set_driver_private(dip, mxfep); 397 398 /* get the interrupt block cookie */ 399 if (ddi_get_iblock_cookie(dip, 0, &mxfep->mxfe_icookie) 400 != DDI_SUCCESS) { 401 mxfe_error(dip, "ddi_get_iblock_cookie failed"); 402 pci_config_teardown(&pci); 403 kmem_free(mxfep, sizeof (mxfe_t)); 404 return (DDI_FAILURE); 405 } 406 407 mxfep->mxfe_dip = dip; 408 mxfep->mxfe_cardp = cardp; 409 mxfep->mxfe_phyaddr = -1; 410 mxfep->mxfe_cachesize = cachesize; 411 412 /* default properties */ 413 mxfep->mxfe_adv_aneg = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 414 "adv_autoneg_cap", 1); 415 mxfep->mxfe_adv_100T4 = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 416 "adv_100T4_cap", 1); 417 mxfep->mxfe_adv_100fdx = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 418 "adv_100fdx_cap", 1); 419 mxfep->mxfe_adv_100hdx = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 420 "adv_100hdx_cap", 1); 421 mxfep->mxfe_adv_10fdx = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 422 "adv_10fdx_cap", 1); 423 mxfep->mxfe_adv_10hdx = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 424 "adv_10hdx_cap", 1); 425 426 DBG(DPCI, "PCI vendor id = %x", venid); 427 DBG(DPCI, "PCI device id = %x", devid); 428 DBG(DPCI, "PCI revision id = %x", revid); 429 DBG(DPCI, "PCI cachesize = %d", cachesize); 430 DBG(DPCI, "PCI COMM = %x", pci_config_get8(pci, PCI_CMD)); 431 DBG(DPCI, "PCI STAT = %x", pci_config_get8(pci, PCI_STAT)); 432 433 mutex_init(&mxfep->mxfe_xmtlock, NULL, MUTEX_DRIVER, 434 mxfep->mxfe_icookie); 435 mutex_init(&mxfep->mxfe_intrlock, NULL, MUTEX_DRIVER, 436 mxfep->mxfe_icookie); 437 438 mxfe_ndinit(mxfep); 439 440 /* 441 * Enable bus master, IO space, and memory space accesses. 442 */ 443 pci_config_put16(pci, PCI_CMD, 444 pci_config_get16(pci, PCI_CMD) | 445 PCI_CMD_BME | PCI_CMD_MAE | PCI_CMD_MWIE); 446 447 /* we're done with this now, drop it */ 448 pci_config_teardown(&pci); 449 450 /* 451 * Initialize interrupt kstat. This should not normally fail, since 452 * we don't use a persistent stat. We do it this way to avoid having 453 * to test for it at run time on the hot path. 454 */ 455 mxfep->mxfe_intrstat = kstat_create("mxfe", inst, "intr", "controller", 456 KSTAT_TYPE_INTR, 1, 0); 457 if (mxfep->mxfe_intrstat == NULL) { 458 mxfe_error(dip, "kstat_create failed"); 459 goto failed; 460 } 461 kstat_install(mxfep->mxfe_intrstat); 462 463 /* 464 * Map in the device registers. 465 */ 466 if (ddi_regs_map_setup(dip, 1, (caddr_t *)&mxfep->mxfe_regs, 467 0, 0, &mxfe_devattr, &mxfep->mxfe_regshandle)) { 468 mxfe_error(dip, "ddi_regs_map_setup failed"); 469 goto failed; 470 } 471 472 /* 473 * Allocate DMA resources (descriptor rings and buffers). 474 */ 475 if ((mxfe_allocrxring(mxfep) != DDI_SUCCESS) || 476 (mxfe_alloctxring(mxfep) != DDI_SUCCESS)) { 477 mxfe_error(dip, "unable to allocate DMA resources"); 478 goto failed; 479 } 480 481 /* Initialize the chip. */ 482 mutex_enter(&mxfep->mxfe_intrlock); 483 mutex_enter(&mxfep->mxfe_xmtlock); 484 if (!mxfe_initialize(mxfep)) { 485 mutex_exit(&mxfep->mxfe_xmtlock); 486 mutex_exit(&mxfep->mxfe_intrlock); 487 goto failed; 488 } 489 mutex_exit(&mxfep->mxfe_xmtlock); 490 mutex_exit(&mxfep->mxfe_intrlock); 491 492 /* Determine the number of address bits to our EEPROM. */ 493 mxfep->mxfe_sromwidth = mxfe_sromwidth(mxfep); 494 495 /* 496 * Get the factory ethernet address. This becomes the current 497 * ethernet address (it can be overridden later via ifconfig). 498 */ 499 mxfe_getfactaddr(mxfep, mxfep->mxfe_curraddr); 500 mxfep->mxfe_promisc = B_FALSE; 501 502 /* 503 * Establish interrupt handler. 504 */ 505 if (ddi_add_intr(dip, 0, NULL, NULL, mxfe_intr, (caddr_t)mxfep) != 506 DDI_SUCCESS) { 507 mxfe_error(dip, "unable to add interrupt"); 508 goto failed; 509 } 510 511 /* TODO: do the power management stuff */ 512 513 if ((macp = mac_alloc(MAC_VERSION)) == NULL) { 514 mxfe_error(dip, "mac_alloc failed"); 515 goto failed; 516 } 517 518 macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 519 macp->m_driver = mxfep; 520 macp->m_dip = dip; 521 macp->m_src_addr = mxfep->mxfe_curraddr; 522 macp->m_callbacks = &mxfe_m_callbacks; 523 macp->m_min_sdu = 0; 524 macp->m_max_sdu = ETHERMTU; 525 526 if (mac_register(macp, &mxfep->mxfe_mh) == DDI_SUCCESS) { 527 mac_free(macp); 528 return (DDI_SUCCESS); 529 } 530 531 /* failed to register with MAC */ 532 mac_free(macp); 533 failed: 534 if (mxfep->mxfe_icookie != NULL) { 535 ddi_remove_intr(dip, 0, mxfep->mxfe_icookie); 536 } 537 if (mxfep->mxfe_intrstat) { 538 kstat_delete(mxfep->mxfe_intrstat); 539 } 540 mxfe_ndfini(mxfep); 541 mutex_destroy(&mxfep->mxfe_intrlock); 542 mutex_destroy(&mxfep->mxfe_xmtlock); 543 544 mxfe_freerxring(mxfep); 545 mxfe_freetxring(mxfep); 546 547 if (mxfep->mxfe_regshandle != NULL) { 548 ddi_regs_map_free(&mxfep->mxfe_regshandle); 549 } 550 kmem_free(mxfep, sizeof (mxfe_t)); 551 return (DDI_FAILURE); 552 } 553 554 int 555 mxfe_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 556 { 557 mxfe_t *mxfep; 558 559 mxfep = ddi_get_driver_private(dip); 560 if (mxfep == NULL) { 561 mxfe_error(dip, "no soft state in detach!"); 562 return (DDI_FAILURE); 563 } 564 565 switch (cmd) { 566 case DDI_DETACH: 567 568 if (mac_unregister(mxfep->mxfe_mh) != 0) { 569 return (DDI_FAILURE); 570 } 571 572 /* make sure hardware is quiesced */ 573 mutex_enter(&mxfep->mxfe_intrlock); 574 mutex_enter(&mxfep->mxfe_xmtlock); 575 mxfep->mxfe_flags &= ~MXFE_RUNNING; 576 mxfe_stopall(mxfep); 577 mutex_exit(&mxfep->mxfe_xmtlock); 578 mutex_exit(&mxfep->mxfe_intrlock); 579 580 /* clean up and shut down device */ 581 ddi_remove_intr(dip, 0, mxfep->mxfe_icookie); 582 583 /* clean up kstats */ 584 kstat_delete(mxfep->mxfe_intrstat); 585 586 ddi_prop_remove_all(dip); 587 588 /* free up any left over buffers or DMA resources */ 589 mxfe_freerxring(mxfep); 590 mxfe_freetxring(mxfep); 591 592 mxfe_ndfini(mxfep); 593 ddi_regs_map_free(&mxfep->mxfe_regshandle); 594 mutex_destroy(&mxfep->mxfe_intrlock); 595 mutex_destroy(&mxfep->mxfe_xmtlock); 596 597 kmem_free(mxfep, sizeof (mxfe_t)); 598 return (DDI_SUCCESS); 599 600 case DDI_SUSPEND: 601 /* quiesce the hardware */ 602 mutex_enter(&mxfep->mxfe_intrlock); 603 mutex_enter(&mxfep->mxfe_xmtlock); 604 mxfep->mxfe_flags |= MXFE_SUSPENDED; 605 mxfe_stopall(mxfep); 606 mutex_exit(&mxfep->mxfe_xmtlock); 607 mutex_exit(&mxfep->mxfe_intrlock); 608 return (DDI_SUCCESS); 609 default: 610 return (DDI_FAILURE); 611 } 612 } 613 614 int 615 mxfe_resume(dev_info_t *dip) 616 { 617 mxfe_t *mxfep; 618 619 if ((mxfep = ddi_get_driver_private(dip)) == NULL) { 620 return (DDI_FAILURE); 621 } 622 623 mutex_enter(&mxfep->mxfe_intrlock); 624 mutex_enter(&mxfep->mxfe_xmtlock); 625 626 mxfep->mxfe_flags &= ~MXFE_SUSPENDED; 627 628 /* re-initialize chip */ 629 if (!mxfe_initialize(mxfep)) { 630 mxfe_error(mxfep->mxfe_dip, "unable to resume chip!"); 631 mxfep->mxfe_flags |= MXFE_SUSPENDED; 632 mutex_exit(&mxfep->mxfe_intrlock); 633 mutex_exit(&mxfep->mxfe_xmtlock); 634 return (DDI_SUCCESS); 635 } 636 637 /* start the chip */ 638 if (mxfep->mxfe_flags & MXFE_RUNNING) { 639 mxfe_startall(mxfep); 640 } 641 642 /* drop locks */ 643 mutex_exit(&mxfep->mxfe_xmtlock); 644 mutex_exit(&mxfep->mxfe_intrlock); 645 646 return (DDI_SUCCESS); 647 } 648 649 void 650 mxfe_m_ioctl(void *arg, queue_t *wq, mblk_t *mp) 651 { 652 mxfe_t *mxfep = arg; 653 654 switch (*(int *)(void *)(mp->b_rptr)) { 655 656 case NDIOC_GET: 657 mxfe_ndget(mxfep, wq, mp); 658 break; 659 660 case NDIOC_SET: 661 mxfe_ndset(mxfep, wq, mp); 662 break; 663 664 default: 665 miocnak(wq, mp, 0, EINVAL); 666 break; 667 } 668 } 669 670 /*ARGSUSED*/ 671 int 672 mxfe_m_multicst(void *arg, boolean_t add, const uint8_t *macaddr) 673 { 674 /* we already receive all multicast frames */ 675 return (0); 676 } 677 678 int 679 mxfe_m_promisc(void *arg, boolean_t on) 680 { 681 mxfe_t *mxfep = arg; 682 683 /* exclusive access to the card while we reprogram it */ 684 mutex_enter(&mxfep->mxfe_intrlock); 685 mutex_enter(&mxfep->mxfe_xmtlock); 686 /* save current promiscuous mode state for replay in resume */ 687 mxfep->mxfe_promisc = on; 688 689 if ((mxfep->mxfe_flags & (MXFE_RUNNING|MXFE_SUSPENDED)) == 690 MXFE_RUNNING) { 691 if (on) 692 SETBIT(mxfep, CSR_NAR, NAR_RX_PROMISC); 693 else 694 CLRBIT(mxfep, CSR_NAR, NAR_RX_PROMISC); 695 } 696 697 mutex_exit(&mxfep->mxfe_xmtlock); 698 mutex_exit(&mxfep->mxfe_intrlock); 699 700 return (0); 701 } 702 703 int 704 mxfe_m_unicst(void *arg, const uint8_t *macaddr) 705 { 706 mxfe_t *mxfep = arg; 707 708 mutex_enter(&mxfep->mxfe_intrlock); 709 mutex_enter(&mxfep->mxfe_xmtlock); 710 bcopy(macaddr, mxfep->mxfe_curraddr, ETHERADDRL); 711 712 mxfe_resetall(mxfep); 713 714 mutex_exit(&mxfep->mxfe_intrlock); 715 mutex_exit(&mxfep->mxfe_xmtlock); 716 717 return (0); 718 } 719 720 mblk_t * 721 mxfe_m_tx(void *arg, mblk_t *mp) 722 { 723 mxfe_t *mxfep = arg; 724 mblk_t *nmp; 725 726 mutex_enter(&mxfep->mxfe_xmtlock); 727 728 if (mxfep->mxfe_flags & MXFE_SUSPENDED) { 729 mutex_exit(&mxfep->mxfe_xmtlock); 730 return (mp); 731 } 732 733 while (mp != NULL) { 734 nmp = mp->b_next; 735 mp->b_next = NULL; 736 737 if (!mxfe_send(mxfep, mp)) { 738 mp->b_next = nmp; 739 break; 740 } 741 mp = nmp; 742 } 743 mutex_exit(&mxfep->mxfe_xmtlock); 744 745 return (mp); 746 } 747 748 /* 749 * Hardware management. 750 */ 751 boolean_t 752 mxfe_initialize(mxfe_t *mxfep) 753 { 754 int i; 755 unsigned val; 756 uint32_t par, nar; 757 758 ASSERT(mutex_owned(&mxfep->mxfe_intrlock)); 759 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock)); 760 761 DBG(DCHATTY, "resetting!"); 762 SETBIT(mxfep, CSR_PAR, PAR_RESET); 763 for (i = 1; i < 10; i++) { 764 drv_usecwait(5); 765 val = GETCSR(mxfep, CSR_PAR); 766 if (!(val & PAR_RESET)) { 767 break; 768 } 769 } 770 if (i == 10) { 771 mxfe_error(mxfep->mxfe_dip, "timed out waiting for reset!"); 772 return (B_FALSE); 773 } 774 775 /* initialize busctl register */ 776 par = PAR_BAR | PAR_MRME | PAR_MRLE | PAR_MWIE; 777 778 /* set the cache alignment if its supported */ 779 switch (mxfep->mxfe_cachesize) { 780 case 8: 781 par |= PAR_CALIGN_8; 782 break; 783 case 16: 784 par |= PAR_CALIGN_16; 785 break; 786 case 32: 787 par |= PAR_CALIGN_32; 788 break; 789 default: 790 par &= ~(PAR_MWIE | PAR_MRME | PAR_MRLE); 791 } 792 793 /* leave the burst length at zero, indicating infinite burst */ 794 PUTCSR(mxfep, CSR_PAR, par); 795 796 mxfe_resetrings(mxfep); 797 798 /* clear the lost packet counter (cleared on read) */ 799 (void) GETCSR(mxfep, CSR_LPC); 800 801 /* a few other NAR bits */ 802 nar = GETCSR(mxfep, CSR_NAR); 803 nar &= ~NAR_RX_HO; /* disable hash only filtering */ 804 nar |= NAR_RX_HP; /* hash perfect forwarding */ 805 nar |= NAR_RX_MULTI; /* receive all multicast */ 806 nar |= NAR_SF; /* store-and-forward */ 807 808 if (mxfep->mxfe_promisc) { 809 nar |= NAR_RX_PROMISC; 810 } else { 811 nar &= ~NAR_RX_PROMISC; 812 } 813 PUTCSR(mxfep, CSR_NAR, nar); 814 815 mxfe_send_setup(mxfep); 816 817 return (B_TRUE); 818 } 819 820 /* 821 * Serial EEPROM access - inspired by the FreeBSD implementation. 822 */ 823 824 uint8_t 825 mxfe_sromwidth(mxfe_t *mxfep) 826 { 827 int i; 828 int eeread; 829 uint8_t addrlen = 8; 830 831 eeread = SPR_SROM_READ | SPR_SROM_SEL | SPR_SROM_CHIP; 832 833 PUTCSR(mxfep, CSR_SPR, eeread & ~SPR_SROM_CHIP); 834 drv_usecwait(1); 835 PUTCSR(mxfep, CSR_SPR, eeread); 836 837 /* command bits first */ 838 for (i = 4; i != 0; i >>= 1) { 839 unsigned val = (SROM_READCMD & i) ? SPR_SROM_DIN : 0; 840 PUTCSR(mxfep, CSR_SPR, eeread | val); 841 drv_usecwait(1); 842 PUTCSR(mxfep, CSR_SPR, eeread | val | SPR_SROM_CLOCK); 843 drv_usecwait(1); 844 } 845 846 PUTCSR(mxfep, CSR_SPR, eeread); 847 848 for (addrlen = 1; addrlen <= 12; addrlen++) { 849 PUTCSR(mxfep, CSR_SPR, eeread | SPR_SROM_CLOCK); 850 drv_usecwait(1); 851 if (!(GETCSR(mxfep, CSR_SPR) & SPR_SROM_DOUT)) { 852 PUTCSR(mxfep, CSR_SPR, eeread); 853 drv_usecwait(1); 854 break; 855 } 856 PUTCSR(mxfep, CSR_SPR, eeread); 857 drv_usecwait(1); 858 } 859 860 /* turn off accesses to the EEPROM */ 861 PUTCSR(mxfep, CSR_SPR, eeread &~ SPR_SROM_CHIP); 862 863 DBG(DSROM, "detected srom width = %d bits", addrlen); 864 865 return ((addrlen < 4 || addrlen > 12) ? 6 : addrlen); 866 } 867 868 /* 869 * The words in EEPROM are stored in little endian order. We 870 * shift bits out in big endian order, though. This requires 871 * a byte swap on some platforms. 872 */ 873 uint16_t 874 mxfe_readsromword(mxfe_t *mxfep, unsigned romaddr) 875 { 876 int i; 877 uint16_t word = 0; 878 uint16_t retval; 879 int eeread; 880 uint8_t addrlen; 881 int readcmd; 882 uchar_t *ptr; 883 884 eeread = SPR_SROM_READ | SPR_SROM_SEL | SPR_SROM_CHIP; 885 addrlen = mxfep->mxfe_sromwidth; 886 readcmd = (SROM_READCMD << addrlen) | romaddr; 887 888 if (romaddr >= (1 << addrlen)) { 889 /* too big to fit! */ 890 return (0); 891 } 892 893 PUTCSR(mxfep, CSR_SPR, eeread & ~SPR_SROM_CHIP); 894 PUTCSR(mxfep, CSR_SPR, eeread); 895 896 /* command and address bits */ 897 for (i = 4 + addrlen; i >= 0; i--) { 898 short val = (readcmd & (1 << i)) ? SPR_SROM_DIN : 0; 899 PUTCSR(mxfep, CSR_SPR, eeread | val); 900 drv_usecwait(1); 901 PUTCSR(mxfep, CSR_SPR, eeread | val | SPR_SROM_CLOCK); 902 drv_usecwait(1); 903 } 904 905 PUTCSR(mxfep, CSR_SPR, eeread); 906 907 for (i = 0; i < 16; i++) { 908 PUTCSR(mxfep, CSR_SPR, eeread | SPR_SROM_CLOCK); 909 drv_usecwait(1); 910 word <<= 1; 911 if (GETCSR(mxfep, CSR_SPR) & SPR_SROM_DOUT) { 912 word |= 1; 913 } 914 PUTCSR(mxfep, CSR_SPR, eeread); 915 drv_usecwait(1); 916 } 917 918 /* turn off accesses to the EEPROM */ 919 PUTCSR(mxfep, CSR_SPR, eeread &~ SPR_SROM_CHIP); 920 921 /* 922 * Fix up the endianness thing. Note that the values 923 * are stored in little endian format on the SROM. 924 */ 925 DBG(DSROM, "got value %d from SROM (before swap)", word); 926 ptr = (uchar_t *)&word; 927 retval = (ptr[1] << 8) | ptr[0]; 928 return (retval); 929 } 930 931 void 932 mxfe_readsrom(mxfe_t *mxfep, unsigned romaddr, unsigned len, void *dest) 933 { 934 char *ptr = dest; 935 int i; 936 uint16_t word; 937 938 for (i = 0; i < len; i++) { 939 word = mxfe_readsromword(mxfep, romaddr + i); 940 bcopy(&word, ptr, 2); 941 ptr += 2; 942 DBG(DSROM, "word at %d is 0x%x", romaddr + i, word); 943 } 944 } 945 946 void 947 mxfe_getfactaddr(mxfe_t *mxfep, uchar_t *eaddr) 948 { 949 uint16_t word; 950 uchar_t *ptr; 951 952 /* first read to get the location of mac address in srom */ 953 word = mxfe_readsromword(mxfep, SROM_ENADDR / 2); 954 ptr = (uchar_t *)&word; 955 word = (ptr[1] << 8) | ptr[0]; 956 957 /* then read the actual mac address */ 958 mxfe_readsrom(mxfep, word / 2, ETHERADDRL / 2, eaddr); 959 DBG(DMACID, 960 "factory ethernet address = %02x:%02x:%02x:%02x:%02x:%02x", 961 eaddr[0], eaddr[1], eaddr[2], eaddr[3], eaddr[4], eaddr[5]); 962 } 963 964 void 965 mxfe_startphy(mxfe_t *mxfep) 966 { 967 switch (MXFE_MODEL(mxfep)) { 968 case MXFE_98713A: 969 mxfe_startphymii(mxfep); 970 break; 971 default: 972 mxfe_startphynway(mxfep); 973 break; 974 } 975 } 976 977 void 978 mxfe_stopphy(mxfe_t *mxfep) 979 { 980 uint32_t nar; 981 int i; 982 983 /* stop the phy timer */ 984 PUTCSR(mxfep, CSR_TIMER, 0); 985 986 switch (MXFE_MODEL(mxfep)) { 987 case MXFE_98713A: 988 for (i = 0; i < 32; i++) { 989 mxfe_miiwrite(mxfep, mxfep->mxfe_phyaddr, MII_CONTROL, 990 MII_CONTROL_PWRDN | MII_CONTROL_ISOLATE); 991 } 992 break; 993 default: 994 DBG(DPHY, "resetting SIA"); 995 PUTCSR(mxfep, CSR_SIA, SIA_RESET); 996 drv_usecwait(500); 997 CLRBIT(mxfep, CSR_TCTL, TCTL_PWR | TCTL_ANE); 998 nar = GETCSR(mxfep, CSR_NAR); 999 nar &= ~(NAR_PORTSEL | NAR_PCS | NAR_SCR | NAR_FDX); 1000 nar |= NAR_SPEED; 1001 PUTCSR(mxfep, CSR_NAR, nar); 1002 break; 1003 } 1004 1005 /* 1006 * mark the link state unknown 1007 */ 1008 if (!mxfep->mxfe_resetting) { 1009 mxfep->mxfe_linkup = LINK_STATE_UNKNOWN; 1010 mxfep->mxfe_ifspeed = 0; 1011 mxfep->mxfe_duplex = LINK_DUPLEX_UNKNOWN; 1012 if (mxfep->mxfe_flags & MXFE_RUNNING) 1013 mxfe_reportlink(mxfep); 1014 } 1015 } 1016 1017 /* 1018 * NWay support. 1019 */ 1020 void 1021 mxfe_startnway(mxfe_t *mxfep) 1022 { 1023 unsigned nar; 1024 unsigned tctl; 1025 unsigned restart; 1026 1027 /* this should not happen in a healthy system */ 1028 if (mxfep->mxfe_linkstate != MXFE_NOLINK) { 1029 DBG(DWARN, "link start called out of state (%x)", 1030 mxfep->mxfe_linkstate); 1031 return; 1032 } 1033 1034 if (mxfep->mxfe_adv_aneg == 0) { 1035 /* not done for forced mode */ 1036 return; 1037 } 1038 1039 nar = GETCSR(mxfep, CSR_NAR); 1040 restart = nar & (NAR_TX_ENABLE | NAR_RX_ENABLE); 1041 nar &= ~restart; 1042 1043 if (restart != 0) 1044 mxfe_stopmac(mxfep); 1045 1046 nar |= NAR_SCR | NAR_PCS | NAR_HBD; 1047 nar &= ~(NAR_FDX); 1048 1049 tctl = GETCSR(mxfep, CSR_TCTL); 1050 tctl &= ~(TCTL_100FDX | TCTL_100HDX | TCTL_HDX); 1051 1052 if (mxfep->mxfe_adv_100fdx) { 1053 tctl |= TCTL_100FDX; 1054 } 1055 if (mxfep->mxfe_adv_100hdx) { 1056 tctl |= TCTL_100HDX; 1057 } 1058 if (mxfep->mxfe_adv_10fdx) { 1059 nar |= NAR_FDX; 1060 } 1061 if (mxfep->mxfe_adv_10hdx) { 1062 tctl |= TCTL_HDX; 1063 } 1064 tctl |= TCTL_PWR | TCTL_ANE | TCTL_LTE | TCTL_RSQ; 1065 1066 /* possibly we should add in support for PAUSE frames */ 1067 DBG(DPHY, "writing nar = 0x%x", nar); 1068 PUTCSR(mxfep, CSR_NAR, nar); 1069 1070 DBG(DPHY, "writing tctl = 0x%x", tctl); 1071 PUTCSR(mxfep, CSR_TCTL, tctl); 1072 1073 /* restart autonegotation */ 1074 DBG(DPHY, "writing tstat = 0x%x", TSTAT_ANS_START); 1075 PUTCSR(mxfep, CSR_TSTAT, TSTAT_ANS_START); 1076 1077 /* restart tx/rx processes... */ 1078 if (restart != 0) 1079 mxfe_startmac(mxfep); 1080 1081 /* Macronix initializations from Bolo Tsai */ 1082 PUTCSR(mxfep, CSR_MXMAGIC, 0x0b2c0000); 1083 PUTCSR(mxfep, CSR_ACOMP, 0x11000); 1084 1085 mxfep->mxfe_linkstate = MXFE_NWAYCHECK; 1086 } 1087 1088 void 1089 mxfe_checklinknway(mxfe_t *mxfep) 1090 { 1091 unsigned tstat, lpar; 1092 1093 DBG(DPHY, "NWay check, state %x", mxfep->mxfe_linkstate); 1094 tstat = GETCSR(mxfep, CSR_TSTAT); 1095 lpar = TSTAT_LPAR(tstat); 1096 1097 mxfep->mxfe_anlpar = lpar; 1098 if (tstat & TSTAT_LPN) { 1099 mxfep->mxfe_aner |= MII_AN_EXP_LPCANAN; 1100 } else { 1101 mxfep->mxfe_aner &= ~(MII_AN_EXP_LPCANAN); 1102 } 1103 1104 DBG(DPHY, "tstat(CSR12) = 0x%x", tstat); 1105 DBG(DPHY, "ANEG state = 0x%x", (tstat & TSTAT_ANS) >> 12); 1106 1107 if ((tstat & TSTAT_ANS) != TSTAT_ANS_OK) { 1108 /* autoneg did not complete */ 1109 mxfep->mxfe_bmsr &= ~MII_STATUS_ANDONE; 1110 } else { 1111 mxfep->mxfe_bmsr |= ~MII_STATUS_ANDONE; 1112 } 1113 1114 if ((tstat & TSTAT_100F) && (tstat & TSTAT_10F)) { 1115 mxfep->mxfe_linkup = LINK_STATE_DOWN; 1116 mxfep->mxfe_ifspeed = 0; 1117 mxfep->mxfe_duplex = LINK_DUPLEX_UNKNOWN; 1118 mxfep->mxfe_linkstate = MXFE_NOLINK; 1119 mxfe_reportlink(mxfep); 1120 mxfe_startnway(mxfep); 1121 return; 1122 } 1123 1124 /* 1125 * if the link is newly up, then we might need to set various 1126 * mode bits, or negotiate for parameters, etc. 1127 */ 1128 if (mxfep->mxfe_adv_aneg) { 1129 1130 uint16_t anlpar; 1131 1132 mxfep->mxfe_linkup = LINK_STATE_UP; 1133 anlpar = mxfep->mxfe_anlpar; 1134 1135 if (tstat & TSTAT_LPN) { 1136 /* partner has NWay */ 1137 1138 if ((anlpar & MII_ABILITY_100BASE_TX_FD) && 1139 mxfep->mxfe_adv_100fdx) { 1140 mxfep->mxfe_ifspeed = 100000000; 1141 mxfep->mxfe_duplex = LINK_DUPLEX_FULL; 1142 } else if ((anlpar & MII_ABILITY_100BASE_TX) && 1143 mxfep->mxfe_adv_100hdx) { 1144 mxfep->mxfe_ifspeed = 100000000; 1145 mxfep->mxfe_duplex = LINK_DUPLEX_HALF; 1146 } else if ((anlpar & MII_ABILITY_10BASE_T_FD) && 1147 mxfep->mxfe_adv_10fdx) { 1148 mxfep->mxfe_ifspeed = 10000000; 1149 mxfep->mxfe_duplex = LINK_DUPLEX_FULL; 1150 } else if ((anlpar & MII_ABILITY_10BASE_T) && 1151 mxfep->mxfe_adv_10hdx) { 1152 mxfep->mxfe_ifspeed = 10000000; 1153 mxfep->mxfe_duplex = LINK_DUPLEX_HALF; 1154 } else { 1155 mxfep->mxfe_ifspeed = 0; 1156 } 1157 } else { 1158 /* link partner does not have NWay */ 1159 /* just assume half duplex, since we can't detect */ 1160 mxfep->mxfe_duplex = LINK_DUPLEX_HALF; 1161 if (!(tstat & TSTAT_100F)) { 1162 DBG(DPHY, "Partner doesn't have NWAY"); 1163 mxfep->mxfe_ifspeed = 100000000; 1164 } else { 1165 mxfep->mxfe_ifspeed = 10000000; 1166 } 1167 } 1168 } else { 1169 /* forced modes */ 1170 mxfep->mxfe_linkup = LINK_STATE_UP; 1171 if (mxfep->mxfe_adv_100fdx) { 1172 mxfep->mxfe_ifspeed = 100000000; 1173 mxfep->mxfe_duplex = LINK_DUPLEX_FULL; 1174 } else if (mxfep->mxfe_adv_100hdx) { 1175 mxfep->mxfe_ifspeed = 100000000; 1176 mxfep->mxfe_duplex = LINK_DUPLEX_HALF; 1177 } else if (mxfep->mxfe_adv_10fdx) { 1178 mxfep->mxfe_ifspeed = 10000000; 1179 mxfep->mxfe_duplex = LINK_DUPLEX_FULL; 1180 } else if (mxfep->mxfe_adv_10hdx) { 1181 mxfep->mxfe_ifspeed = 10000000; 1182 mxfep->mxfe_duplex = LINK_DUPLEX_HALF; 1183 } else { 1184 mxfep->mxfe_ifspeed = 0; 1185 } 1186 } 1187 mxfe_reportlink(mxfep); 1188 mxfep->mxfe_linkstate = MXFE_GOODLINK; 1189 } 1190 1191 void 1192 mxfe_startphynway(mxfe_t *mxfep) 1193 { 1194 /* take NWay and PHY out of reset */ 1195 PUTCSR(mxfep, CSR_SIA, SIA_NRESET); 1196 drv_usecwait(500); 1197 1198 mxfep->mxfe_linkstate = MXFE_NOLINK; 1199 mxfep->mxfe_bmsr = MII_STATUS_CANAUTONEG | 1200 MII_STATUS_100_BASEX_FD | MII_STATUS_100_BASEX | 1201 MII_STATUS_10_FD | MII_STATUS_10; 1202 1203 /* lie about the transceiver... its not really 802.3u compliant */ 1204 mxfep->mxfe_phyaddr = 0; 1205 mxfep->mxfe_phyinuse = XCVR_100X; 1206 mxfep->mxfe_phyid = 0; 1207 1208 /* 100-T4 not supported with NWay */ 1209 mxfep->mxfe_adv_100T4 = 0; 1210 1211 /* make sure at least one valid mode is selected */ 1212 if ((!mxfep->mxfe_adv_100fdx) && 1213 (!mxfep->mxfe_adv_100hdx) && 1214 (!mxfep->mxfe_adv_10fdx) && 1215 (!mxfep->mxfe_adv_10hdx)) { 1216 mxfe_error(mxfep->mxfe_dip, "No valid link mode selected."); 1217 mxfe_error(mxfep->mxfe_dip, "Powering down PHY."); 1218 mxfe_stopphy(mxfep); 1219 mxfep->mxfe_linkup = LINK_STATE_DOWN; 1220 if (mxfep->mxfe_flags & MXFE_RUNNING) 1221 mxfe_reportlink(mxfep); 1222 return; 1223 } 1224 1225 if (mxfep->mxfe_adv_aneg == 0) { 1226 /* forced mode */ 1227 unsigned nar; 1228 unsigned tctl; 1229 1230 nar = GETCSR(mxfep, CSR_NAR); 1231 tctl = GETCSR(mxfep, CSR_TCTL); 1232 1233 ASSERT((nar & (NAR_TX_ENABLE | NAR_RX_ENABLE)) == 0); 1234 1235 nar &= ~(NAR_FDX | NAR_PORTSEL | NAR_SCR | NAR_SPEED); 1236 tctl &= ~TCTL_ANE; 1237 if (mxfep->mxfe_adv_100fdx) { 1238 nar |= NAR_PORTSEL | NAR_PCS | NAR_SCR | NAR_FDX; 1239 } else if (mxfep->mxfe_adv_100hdx) { 1240 nar |= NAR_PORTSEL | NAR_PCS | NAR_SCR; 1241 } else if (mxfep->mxfe_adv_10fdx) { 1242 nar |= NAR_FDX | NAR_SPEED; 1243 } else { /* mxfep->mxfe_adv_10hdx */ 1244 nar |= NAR_SPEED; 1245 } 1246 1247 PUTCSR(mxfep, CSR_NAR, nar); 1248 PUTCSR(mxfep, CSR_TCTL, tctl); 1249 1250 /* Macronix initializations from Bolo Tsai */ 1251 PUTCSR(mxfep, CSR_MXMAGIC, 0x0b2c0000); 1252 PUTCSR(mxfep, CSR_ACOMP, 0x11000); 1253 } else { 1254 mxfe_startnway(mxfep); 1255 } 1256 PUTCSR(mxfep, CSR_TIMER, TIMER_LOOP | 1257 (MXFE_LINKTIMER * 1000 / TIMER_USEC)); 1258 } 1259 1260 /* 1261 * MII management. 1262 */ 1263 void 1264 mxfe_startphymii(mxfe_t *mxfep) 1265 { 1266 unsigned phyaddr; 1267 unsigned bmcr; 1268 unsigned bmsr; 1269 unsigned anar; 1270 unsigned phyidr1; 1271 unsigned phyidr2; 1272 int retries; 1273 int cnt; 1274 1275 mxfep->mxfe_phyaddr = -1; 1276 1277 /* search for first PHY we can find */ 1278 for (phyaddr = 0; phyaddr < 32; phyaddr++) { 1279 bmsr = mxfe_miiread(mxfep, phyaddr, MII_STATUS); 1280 if ((bmsr != 0) && (bmsr != 0xffff)) { 1281 mxfep->mxfe_phyaddr = phyaddr; 1282 break; 1283 } 1284 } 1285 1286 phyidr1 = mxfe_miiread(mxfep, phyaddr, MII_PHYIDH); 1287 phyidr2 = mxfe_miiread(mxfep, phyaddr, MII_PHYIDL); 1288 mxfep->mxfe_phyid = (phyidr1 << 16) | (phyidr2); 1289 1290 /* 1291 * Generally, all Macronix based devices use an internal 1292 * 100BASE-TX internal transceiver. If we ever run into a 1293 * variation on this, then the following logic will need to be 1294 * enhanced. 1295 * 1296 * One could question the value of the XCVR_INUSE field in the 1297 * MII statistics. 1298 */ 1299 if (bmsr & MII_STATUS_100_BASE_T4) { 1300 mxfep->mxfe_phyinuse = XCVR_100T4; 1301 } else { 1302 mxfep->mxfe_phyinuse = XCVR_100X; 1303 } 1304 1305 DBG(DPHY, "phy at %d: %x,%x", phyaddr, phyidr1, phyidr2); 1306 DBG(DPHY, "bmsr = %x", mxfe_miiread(mxfep, 1307 mxfep->mxfe_phyaddr, MII_STATUS)); 1308 DBG(DPHY, "anar = %x", mxfe_miiread(mxfep, 1309 mxfep->mxfe_phyaddr, MII_AN_ADVERT)); 1310 DBG(DPHY, "anlpar = %x", mxfe_miiread(mxfep, 1311 mxfep->mxfe_phyaddr, MII_AN_LPABLE)); 1312 DBG(DPHY, "aner = %x", mxfe_miiread(mxfep, 1313 mxfep->mxfe_phyaddr, MII_AN_EXPANSION)); 1314 1315 DBG(DPHY, "resetting phy"); 1316 1317 /* we reset the phy block */ 1318 mxfe_miiwrite(mxfep, phyaddr, MII_CONTROL, MII_CONTROL_RESET); 1319 /* 1320 * wait for it to complete -- 500usec is still to short to 1321 * bother getting the system clock involved. 1322 */ 1323 drv_usecwait(500); 1324 for (retries = 0; retries < 10; retries++) { 1325 if (mxfe_miiread(mxfep, phyaddr, MII_CONTROL) & 1326 MII_CONTROL_RESET) { 1327 drv_usecwait(500); 1328 continue; 1329 } 1330 break; 1331 } 1332 if (retries == 100) { 1333 mxfe_error(mxfep->mxfe_dip, "timeout waiting on phy to reset"); 1334 return; 1335 } 1336 1337 DBG(DPHY, "phy reset complete"); 1338 1339 bmsr = mxfe_miiread(mxfep, phyaddr, MII_STATUS); 1340 bmcr = mxfe_miiread(mxfep, phyaddr, MII_CONTROL); 1341 anar = mxfe_miiread(mxfep, phyaddr, MII_AN_ADVERT); 1342 1343 anar &= ~(MII_ABILITY_100BASE_T4 | 1344 MII_ABILITY_100BASE_TX_FD | MII_ABILITY_100BASE_TX | 1345 MII_ABILITY_10BASE_T_FD | MII_ABILITY_10BASE_T); 1346 1347 /* disable modes not supported in hardware */ 1348 if (!(bmsr & MII_STATUS_100_BASE_T4)) { 1349 mxfep->mxfe_adv_100T4 = 0; 1350 } 1351 if (!(bmsr & MII_STATUS_100_BASEX_FD)) { 1352 mxfep->mxfe_adv_100fdx = 0; 1353 } 1354 if (!(bmsr & MII_STATUS_100_BASEX)) { 1355 mxfep->mxfe_adv_100hdx = 0; 1356 } 1357 if (!(bmsr & MII_STATUS_10_FD)) { 1358 mxfep->mxfe_adv_10fdx = 0; 1359 } 1360 if (!(bmsr & MII_STATUS_10)) { 1361 mxfep->mxfe_adv_10hdx = 0; 1362 } 1363 if (!(bmsr & MII_STATUS_CANAUTONEG)) { 1364 mxfep->mxfe_adv_aneg = 0; 1365 } 1366 1367 cnt = 0; 1368 if (mxfep->mxfe_adv_100T4) { 1369 anar |= MII_ABILITY_100BASE_T4; 1370 cnt++; 1371 } 1372 if (mxfep->mxfe_adv_100fdx) { 1373 anar |= MII_ABILITY_100BASE_TX_FD; 1374 cnt++; 1375 } 1376 if (mxfep->mxfe_adv_100hdx) { 1377 anar |= MII_ABILITY_100BASE_TX; 1378 cnt++; 1379 } 1380 if (mxfep->mxfe_adv_10fdx) { 1381 anar |= MII_ABILITY_10BASE_T_FD; 1382 cnt++; 1383 } 1384 if (mxfep->mxfe_adv_10hdx) { 1385 anar |= MII_ABILITY_10BASE_T; 1386 cnt++; 1387 } 1388 1389 /* 1390 * Make certain at least one valid link mode is selected. 1391 */ 1392 if (!cnt) { 1393 mxfe_error(mxfep->mxfe_dip, "No valid link mode selected."); 1394 mxfe_error(mxfep->mxfe_dip, "Powering down PHY."); 1395 mxfe_stopphy(mxfep); 1396 mxfep->mxfe_linkup = LINK_STATE_DOWN; 1397 if (mxfep->mxfe_flags & MXFE_RUNNING) 1398 mxfe_reportlink(mxfep); 1399 return; 1400 } 1401 1402 if ((mxfep->mxfe_adv_aneg) && (bmsr & MII_STATUS_CANAUTONEG)) { 1403 DBG(DPHY, "using autoneg mode"); 1404 bmcr = (MII_CONTROL_ANE | MII_CONTROL_RSAN); 1405 } else { 1406 DBG(DPHY, "using forced mode"); 1407 if (mxfep->mxfe_adv_100fdx) { 1408 bmcr = (MII_CONTROL_100MB | MII_CONTROL_FDUPLEX); 1409 } else if (mxfep->mxfe_adv_100hdx) { 1410 bmcr = MII_CONTROL_100MB; 1411 } else if (mxfep->mxfe_adv_10fdx) { 1412 bmcr = MII_CONTROL_FDUPLEX; 1413 } else { 1414 /* 10HDX */ 1415 bmcr = 0; 1416 } 1417 } 1418 1419 mxfep->mxfe_forcephy = 0; 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, int 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 int 1578 mxfe_miireadbit(mxfe_t *mxfep) 1579 { 1580 unsigned val = SPR_MII_CTRL | SPR_SROM_READ; 1581 int 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 unsigned 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 unsigned 1602 mxfe_miireadgeneral(mxfe_t *mxfep, int phy, int reg) 1603 { 1604 unsigned 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 unsigned 1644 mxfe_miiread98713(mxfe_t *mxfep, int phy, int reg) 1645 { 1646 unsigned nar; 1647 unsigned 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 2170 mutex_enter(&mxfep->mxfe_intrlock); 2171 2172 if (mxfep->mxfe_flags & MXFE_SUSPENDED) { 2173 /* we cannot receive interrupts! */ 2174 mutex_exit(&mxfep->mxfe_intrlock); 2175 return (DDI_INTR_UNCLAIMED); 2176 } 2177 2178 /* check interrupt status bits, did we interrupt? */ 2179 status = GETCSR(mxfep, CSR_SR) & INT_ALL; 2180 2181 if (status == 0) { 2182 KIOIP->intrs[KSTAT_INTR_SPURIOUS]++; 2183 mutex_exit(&mxfep->mxfe_intrlock); 2184 return (DDI_INTR_UNCLAIMED); 2185 } 2186 /* ack the interrupt */ 2187 PUTCSR(mxfep, CSR_SR, status); 2188 KIOIP->intrs[KSTAT_INTR_HARD]++; 2189 2190 if (!(mxfep->mxfe_flags & MXFE_RUNNING)) { 2191 /* not running, don't touch anything */ 2192 mutex_exit(&mxfep->mxfe_intrlock); 2193 return (DDI_INTR_CLAIMED); 2194 } 2195 2196 if (status & INT_RXOK) { 2197 /* receive packets */ 2198 mp = mxfe_receive(mxfep); 2199 } 2200 2201 if (status & INT_TXOK) { 2202 /* transmit completed */ 2203 mutex_enter(&mxfep->mxfe_xmtlock); 2204 mxfe_reclaim(mxfep); 2205 mutex_exit(&mxfep->mxfe_xmtlock); 2206 } 2207 2208 if (((status & (INT_TIMER|INT_ANEG)) != 0) || 2209 ((mxfep->mxfe_linkup == LINK_STATE_UP) && 2210 ((status & (INT_10LINK|INT_100LINK)) != 0))) { 2211 /* rescan the link */ 2212 mutex_enter(&mxfep->mxfe_xmtlock); 2213 mxfe_checklink(mxfep); 2214 mutex_exit(&mxfep->mxfe_xmtlock); 2215 } 2216 2217 if (status & (INT_RXSTOPPED|INT_TXSTOPPED|INT_RXNOBUF| 2218 INT_RXJABBER|INT_TXJABBER|INT_TXUNDERFLOW)) { 2219 2220 if (status & (INT_RXJABBER | INT_TXJABBER)) { 2221 mxfep->mxfe_jabber++; 2222 } 2223 DBG(DWARN, "resetting mac, status %x", status); 2224 mutex_enter(&mxfep->mxfe_xmtlock); 2225 mxfe_resetall(mxfep); 2226 mutex_exit(&mxfep->mxfe_xmtlock); 2227 } 2228 2229 if (status & INT_BUSERR) { 2230 switch (status & SR_BERR_TYPE) { 2231 case SR_BERR_PARITY: 2232 mxfe_error(mxfep->mxfe_dip, "PCI parity error"); 2233 break; 2234 case SR_BERR_TARGET_ABORT: 2235 mxfe_error(mxfep->mxfe_dip, "PCI target abort"); 2236 break; 2237 case SR_BERR_MASTER_ABORT: 2238 mxfe_error(mxfep->mxfe_dip, "PCI master abort"); 2239 break; 2240 default: 2241 mxfe_error(mxfep->mxfe_dip, "Unknown PCI error"); 2242 break; 2243 } 2244 2245 /* reset the chip in an attempt to fix things */ 2246 mutex_enter(&mxfep->mxfe_xmtlock); 2247 mxfe_resetall(mxfep); 2248 mutex_exit(&mxfep->mxfe_xmtlock); 2249 } 2250 2251 mutex_exit(&mxfep->mxfe_intrlock); 2252 2253 /* 2254 * Send up packets. We do this outside of the intrlock. 2255 */ 2256 if (mp) { 2257 mac_rx(mxfep->mxfe_mh, NULL, mp); 2258 } 2259 2260 return (DDI_INTR_CLAIMED); 2261 } 2262 2263 void 2264 mxfe_enableinterrupts(mxfe_t *mxfep) 2265 { 2266 unsigned mask = INT_WANTED; 2267 2268 if (mxfep->mxfe_wantw) 2269 mask |= INT_TXOK; 2270 2271 if (MXFE_MODEL(mxfep) != MXFE_98713A) 2272 mask |= INT_LINKSTATUS; 2273 2274 DBG(DINTR, "setting int mask to 0x%x", mask); 2275 PUTCSR(mxfep, CSR_IER, mask); 2276 } 2277 2278 void 2279 mxfe_disableinterrupts(mxfe_t *mxfep) 2280 { 2281 /* disable further interrupts */ 2282 PUTCSR(mxfep, CSR_IER, 0); 2283 2284 /* clear any pending interrupts */ 2285 PUTCSR(mxfep, CSR_SR, INT_ALL); 2286 } 2287 2288 void 2289 mxfe_send_setup(mxfe_t *mxfep) 2290 { 2291 mxfe_txbuf_t *txb; 2292 mxfe_desc_t *tmdp; 2293 2294 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock)); 2295 2296 /* setup frame -- must be at head of list -- guaranteed by caller! */ 2297 ASSERT(mxfep->mxfe_txsend == 0); 2298 2299 txb = mxfep->mxfe_txbufs[0]; 2300 tmdp = &mxfep->mxfe_txdescp[0]; 2301 2302 bzero(txb->txb_buf, MXFE_SETUP_LEN); 2303 2304 /* program the unicast address */ 2305 txb->txb_buf[156] = mxfep->mxfe_curraddr[0]; 2306 txb->txb_buf[157] = mxfep->mxfe_curraddr[1]; 2307 txb->txb_buf[160] = mxfep->mxfe_curraddr[2]; 2308 txb->txb_buf[161] = mxfep->mxfe_curraddr[3]; 2309 txb->txb_buf[164] = mxfep->mxfe_curraddr[4]; 2310 txb->txb_buf[165] = mxfep->mxfe_curraddr[5]; 2311 2312 /* make sure that the hardware can see it */ 2313 SYNCTXBUF(txb, MXFE_SETUP_LEN, DDI_DMA_SYNC_FORDEV); 2314 2315 PUTTXDESC(mxfep, tmdp->desc_control, 2316 TXCTL_FIRST | TXCTL_LAST | TXCTL_INTCMPLTE | TXCTL_HASHPERF | 2317 TXCTL_SETUP | MXFE_SETUP_LEN); 2318 2319 PUTTXDESC(mxfep, tmdp->desc_buffer1, txb->txb_paddr); 2320 PUTTXDESC(mxfep, tmdp->desc_buffer2, 0); 2321 PUTTXDESC(mxfep, tmdp->desc_status, TXSTAT_OWN); 2322 2323 /* sync the descriptor out to the device */ 2324 SYNCTXDESC(mxfep, 0, DDI_DMA_SYNC_FORDEV); 2325 2326 /* 2327 * wake up the chip ... inside the lock to protect against DR suspend, 2328 * etc. 2329 */ 2330 PUTCSR(mxfep, CSR_TDR, 0); 2331 mxfep->mxfe_txsend++; 2332 mxfep->mxfe_txavail--; 2333 2334 /* 2335 * Program promiscuous mode. 2336 */ 2337 if (mxfep->mxfe_promisc) { 2338 SETBIT(mxfep, CSR_NAR, NAR_RX_PROMISC); 2339 } else { 2340 CLRBIT(mxfep, CSR_NAR, NAR_RX_PROMISC); 2341 } 2342 } 2343 2344 boolean_t 2345 mxfe_send(mxfe_t *mxfep, mblk_t *mp) 2346 { 2347 size_t len; 2348 mxfe_txbuf_t *txb; 2349 mxfe_desc_t *tmd; 2350 uint32_t control; 2351 int txsend; 2352 2353 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock)); 2354 ASSERT(mp != NULL); 2355 2356 len = msgsize(mp); 2357 if (len > ETHERVLANMTU) { 2358 DBG(DXMIT, "frame too long: %d", len); 2359 mxfep->mxfe_macxmt_errors++; 2360 freemsg(mp); 2361 return (B_TRUE); 2362 } 2363 2364 if (mxfep->mxfe_txavail < MXFE_TXRECLAIM) 2365 mxfe_reclaim(mxfep); 2366 2367 if (mxfep->mxfe_txavail == 0) { 2368 /* no more tmds */ 2369 mxfep->mxfe_wantw = B_TRUE; 2370 /* enable TX interrupt */ 2371 mxfe_enableinterrupts(mxfep); 2372 return (B_FALSE); 2373 } 2374 2375 txsend = mxfep->mxfe_txsend; 2376 2377 /* 2378 * For simplicity, we just do a copy into a preallocated 2379 * DMA buffer. 2380 */ 2381 2382 txb = mxfep->mxfe_txbufs[txsend]; 2383 mcopymsg(mp, txb->txb_buf); /* frees mp! */ 2384 2385 /* 2386 * Statistics. 2387 */ 2388 mxfep->mxfe_opackets++; 2389 mxfep->mxfe_obytes += len; 2390 if (txb->txb_buf[0] & 0x1) { 2391 if (bcmp(txb->txb_buf, mxfe_broadcast, ETHERADDRL) != 0) 2392 mxfep->mxfe_multixmt++; 2393 else 2394 mxfep->mxfe_brdcstxmt++; 2395 } 2396 2397 /* note len is already known to be a small unsigned */ 2398 control = len | TXCTL_FIRST | TXCTL_LAST | TXCTL_INTCMPLTE; 2399 2400 if (txsend == (MXFE_TXRING - 1)) 2401 control |= TXCTL_ENDRING; 2402 2403 tmd = &mxfep->mxfe_txdescp[txsend]; 2404 2405 SYNCTXBUF(txb, len, DDI_DMA_SYNC_FORDEV); 2406 PUTTXDESC(mxfep, tmd->desc_control, control); 2407 PUTTXDESC(mxfep, tmd->desc_buffer1, txb->txb_paddr); 2408 PUTTXDESC(mxfep, tmd->desc_buffer2, 0); 2409 PUTTXDESC(mxfep, tmd->desc_status, TXSTAT_OWN); 2410 /* sync the descriptor out to the device */ 2411 SYNCTXDESC(mxfep, txsend, DDI_DMA_SYNC_FORDEV); 2412 2413 /* 2414 * Note the new values of txavail and txsend. 2415 */ 2416 mxfep->mxfe_txavail--; 2417 mxfep->mxfe_txsend = (txsend + 1) % MXFE_TXRING; 2418 2419 /* 2420 * It should never, ever take more than 5 seconds to drain 2421 * the ring. If it happens, then we are stuck! 2422 */ 2423 mxfep->mxfe_txstall_time = gethrtime() + (5 * 1000000000ULL); 2424 2425 /* 2426 * wake up the chip ... inside the lock to protect against DR suspend, 2427 * etc. 2428 */ 2429 PUTCSR(mxfep, CSR_TDR, 0); 2430 2431 return (B_TRUE); 2432 } 2433 2434 /* 2435 * Reclaim buffers that have completed transmission. 2436 */ 2437 void 2438 mxfe_reclaim(mxfe_t *mxfep) 2439 { 2440 mxfe_desc_t *tmdp; 2441 2442 while (mxfep->mxfe_txavail != MXFE_TXRING) { 2443 uint32_t status; 2444 uint32_t control; 2445 int index = mxfep->mxfe_txreclaim; 2446 2447 tmdp = &mxfep->mxfe_txdescp[index]; 2448 2449 /* sync it before we read it */ 2450 SYNCTXDESC(mxfep, index, DDI_DMA_SYNC_FORKERNEL); 2451 2452 control = GETTXDESC(mxfep, tmdp->desc_control); 2453 status = GETTXDESC(mxfep, tmdp->desc_status); 2454 2455 if (status & TXSTAT_OWN) { 2456 /* chip is still working on it, we're done */ 2457 break; 2458 } 2459 2460 mxfep->mxfe_txavail++; 2461 mxfep->mxfe_txreclaim = (index + 1) % MXFE_TXRING; 2462 2463 /* in the most common successful case, all bits are clear */ 2464 if (status == 0) 2465 continue; 2466 2467 if (((control & TXCTL_SETUP) != 0) || 2468 ((control & TXCTL_LAST) == 0)) { 2469 /* no interesting statistics here */ 2470 continue; 2471 } 2472 2473 if (status & TXSTAT_TXERR) { 2474 mxfep->mxfe_errxmt++; 2475 2476 if (status & TXSTAT_JABBER) { 2477 /* transmit jabber timeout */ 2478 mxfep->mxfe_macxmt_errors++; 2479 } 2480 if (status & (TXSTAT_CARRLOST | TXSTAT_NOCARR)) { 2481 mxfep->mxfe_carrier_errors++; 2482 } 2483 if (status & TXSTAT_UFLOW) { 2484 mxfep->mxfe_underflow++; 2485 } 2486 if (status & TXSTAT_LATECOL) { 2487 mxfep->mxfe_tx_late_collisions++; 2488 } 2489 if (status & TXSTAT_EXCOLL) { 2490 mxfep->mxfe_ex_collisions++; 2491 mxfep->mxfe_collisions += 16; 2492 } 2493 } 2494 2495 if (status & TXSTAT_DEFER) { 2496 mxfep->mxfe_defer_xmts++; 2497 } 2498 2499 /* collision counting */ 2500 if (TXCOLLCNT(status) == 1) { 2501 mxfep->mxfe_collisions++; 2502 mxfep->mxfe_first_collisions++; 2503 } else if (TXCOLLCNT(status)) { 2504 mxfep->mxfe_collisions += TXCOLLCNT(status); 2505 mxfep->mxfe_multi_collisions += TXCOLLCNT(status); 2506 } 2507 } 2508 2509 if (mxfep->mxfe_txavail >= MXFE_TXRESCHED) { 2510 if (mxfep->mxfe_wantw) { 2511 /* 2512 * we were able to reclaim some packets, so 2513 * disable tx interrupts 2514 */ 2515 mxfep->mxfe_wantw = B_FALSE; 2516 mxfe_enableinterrupts(mxfep); 2517 mac_tx_update(mxfep->mxfe_mh); 2518 } 2519 } 2520 } 2521 2522 mblk_t * 2523 mxfe_receive(mxfe_t *mxfep) 2524 { 2525 unsigned len; 2526 mxfe_rxbuf_t *rxb; 2527 mxfe_desc_t *rmd; 2528 uint32_t status; 2529 mblk_t *mpchain, **mpp, *mp; 2530 int head, cnt; 2531 2532 mpchain = NULL; 2533 mpp = &mpchain; 2534 head = mxfep->mxfe_rxhead; 2535 2536 /* limit the number of packets we process to a ring size */ 2537 for (cnt = 0; cnt < MXFE_RXRING; cnt++) { 2538 2539 DBG(DRECV, "receive at index %d", head); 2540 2541 rmd = &mxfep->mxfe_rxdescp[head]; 2542 rxb = mxfep->mxfe_rxbufs[head]; 2543 2544 SYNCRXDESC(mxfep, head, DDI_DMA_SYNC_FORKERNEL); 2545 status = GETRXDESC(mxfep, rmd->desc_status); 2546 if (status & RXSTAT_OWN) { 2547 /* chip is still chewing on it */ 2548 break; 2549 } 2550 2551 /* discard the ethernet frame checksum */ 2552 len = RXLENGTH(status) - ETHERFCSL; 2553 2554 DBG(DRECV, "recv length %d, status %x", len, status); 2555 2556 if ((status & (RXSTAT_ERRS | RXSTAT_FIRST | RXSTAT_LAST)) != 2557 (RXSTAT_FIRST | RXSTAT_LAST)) { 2558 2559 mxfep->mxfe_errrcv++; 2560 2561 /* 2562 * Abnormal status bits detected, analyze further. 2563 */ 2564 if ((status & (RXSTAT_LAST|RXSTAT_FIRST)) != 2565 (RXSTAT_LAST|RXSTAT_FIRST)) { 2566 DBG(DRECV, "rx packet overspill"); 2567 if (status & RXSTAT_FIRST) { 2568 mxfep->mxfe_toolong_errors++; 2569 } 2570 } else if (status & RXSTAT_DESCERR) { 2571 mxfep->mxfe_macrcv_errors++; 2572 2573 } else if (status & RXSTAT_RUNT) { 2574 mxfep->mxfe_runt++; 2575 2576 } else if (status & RXSTAT_COLLSEEN) { 2577 /* this should really be rx_late_collisions */ 2578 mxfep->mxfe_macrcv_errors++; 2579 2580 } else if (status & RXSTAT_DRIBBLE) { 2581 mxfep->mxfe_align_errors++; 2582 2583 } else if (status & RXSTAT_CRCERR) { 2584 mxfep->mxfe_fcs_errors++; 2585 2586 } else if (status & RXSTAT_OFLOW) { 2587 mxfep->mxfe_overflow++; 2588 } 2589 } 2590 2591 else if (len > ETHERVLANMTU) { 2592 mxfep->mxfe_errrcv++; 2593 mxfep->mxfe_toolong_errors++; 2594 } 2595 2596 /* 2597 * At this point, the chip thinks the packet is OK. 2598 */ 2599 else { 2600 mp = allocb(len + MXFE_HEADROOM, 0); 2601 if (mp == NULL) { 2602 mxfep->mxfe_errrcv++; 2603 mxfep->mxfe_norcvbuf++; 2604 goto skip; 2605 } 2606 2607 /* sync the buffer before we look at it */ 2608 SYNCRXBUF(rxb, len, DDI_DMA_SYNC_FORKERNEL); 2609 mp->b_rptr += MXFE_HEADROOM; 2610 mp->b_wptr = mp->b_rptr + len; 2611 bcopy((char *)rxb->rxb_buf, mp->b_rptr, len); 2612 2613 mxfep->mxfe_ipackets++; 2614 mxfep->mxfe_rbytes += len; 2615 if (status & RXSTAT_GROUP) { 2616 if (bcmp(mp->b_rptr, mxfe_broadcast, 2617 ETHERADDRL) == 0) 2618 mxfep->mxfe_brdcstrcv++; 2619 else 2620 mxfep->mxfe_multircv++; 2621 } 2622 *mpp = mp; 2623 mpp = &mp->b_next; 2624 } 2625 2626 skip: 2627 /* return ring entry to the hardware */ 2628 PUTRXDESC(mxfep, rmd->desc_status, RXSTAT_OWN); 2629 SYNCRXDESC(mxfep, head, DDI_DMA_SYNC_FORDEV); 2630 2631 /* advance to next RMD */ 2632 head = (head + 1) % MXFE_RXRING; 2633 } 2634 2635 mxfep->mxfe_rxhead = head; 2636 2637 return (mpchain); 2638 } 2639 2640 int 2641 mxfe_m_stat(void *arg, uint_t stat, uint64_t *val) 2642 { 2643 mxfe_t *mxfep = arg; 2644 2645 mutex_enter(&mxfep->mxfe_xmtlock); 2646 if ((mxfep->mxfe_flags & (MXFE_RUNNING|MXFE_SUSPENDED)) == MXFE_RUNNING) 2647 mxfe_reclaim(mxfep); 2648 mutex_exit(&mxfep->mxfe_xmtlock); 2649 2650 switch (stat) { 2651 case MAC_STAT_IFSPEED: 2652 *val = mxfep->mxfe_ifspeed; 2653 break; 2654 2655 case MAC_STAT_MULTIRCV: 2656 *val = mxfep->mxfe_multircv; 2657 break; 2658 2659 case MAC_STAT_BRDCSTRCV: 2660 *val = mxfep->mxfe_brdcstrcv; 2661 break; 2662 2663 case MAC_STAT_MULTIXMT: 2664 *val = mxfep->mxfe_multixmt; 2665 break; 2666 2667 case MAC_STAT_BRDCSTXMT: 2668 *val = mxfep->mxfe_brdcstxmt; 2669 break; 2670 2671 case MAC_STAT_IPACKETS: 2672 *val = mxfep->mxfe_ipackets; 2673 break; 2674 2675 case MAC_STAT_RBYTES: 2676 *val = mxfep->mxfe_rbytes; 2677 break; 2678 2679 case MAC_STAT_OPACKETS: 2680 *val = mxfep->mxfe_opackets; 2681 break; 2682 2683 case MAC_STAT_OBYTES: 2684 *val = mxfep->mxfe_obytes; 2685 break; 2686 2687 case MAC_STAT_NORCVBUF: 2688 *val = mxfep->mxfe_norcvbuf; 2689 break; 2690 2691 case MAC_STAT_NOXMTBUF: 2692 *val = mxfep->mxfe_noxmtbuf; 2693 break; 2694 2695 case MAC_STAT_COLLISIONS: 2696 *val = mxfep->mxfe_collisions; 2697 break; 2698 2699 case MAC_STAT_IERRORS: 2700 *val = mxfep->mxfe_errrcv; 2701 break; 2702 2703 case MAC_STAT_OERRORS: 2704 *val = mxfep->mxfe_errxmt; 2705 break; 2706 2707 case ETHER_STAT_LINK_DUPLEX: 2708 *val = mxfep->mxfe_duplex; 2709 break; 2710 2711 case ETHER_STAT_ALIGN_ERRORS: 2712 *val = mxfep->mxfe_align_errors; 2713 break; 2714 2715 case ETHER_STAT_FCS_ERRORS: 2716 *val = mxfep->mxfe_fcs_errors; 2717 break; 2718 2719 case ETHER_STAT_SQE_ERRORS: 2720 *val = mxfep->mxfe_sqe_errors; 2721 break; 2722 2723 case ETHER_STAT_DEFER_XMTS: 2724 *val = mxfep->mxfe_defer_xmts; 2725 break; 2726 2727 case ETHER_STAT_FIRST_COLLISIONS: 2728 *val = mxfep->mxfe_first_collisions; 2729 break; 2730 2731 case ETHER_STAT_MULTI_COLLISIONS: 2732 *val = mxfep->mxfe_multi_collisions; 2733 break; 2734 2735 case ETHER_STAT_TX_LATE_COLLISIONS: 2736 *val = mxfep->mxfe_tx_late_collisions; 2737 break; 2738 2739 case ETHER_STAT_EX_COLLISIONS: 2740 *val = mxfep->mxfe_ex_collisions; 2741 break; 2742 2743 case ETHER_STAT_MACXMT_ERRORS: 2744 *val = mxfep->mxfe_macxmt_errors; 2745 break; 2746 2747 case ETHER_STAT_CARRIER_ERRORS: 2748 *val = mxfep->mxfe_carrier_errors; 2749 break; 2750 2751 case ETHER_STAT_TOOLONG_ERRORS: 2752 *val = mxfep->mxfe_toolong_errors; 2753 break; 2754 2755 case ETHER_STAT_MACRCV_ERRORS: 2756 *val = mxfep->mxfe_macrcv_errors; 2757 break; 2758 2759 case MAC_STAT_OVERFLOWS: 2760 *val = mxfep->mxfe_overflow; 2761 break; 2762 2763 case MAC_STAT_UNDERFLOWS: 2764 *val = mxfep->mxfe_underflow; 2765 break; 2766 2767 case ETHER_STAT_TOOSHORT_ERRORS: 2768 *val = mxfep->mxfe_runt; 2769 break; 2770 2771 case ETHER_STAT_JABBER_ERRORS: 2772 *val = mxfep->mxfe_jabber; 2773 break; 2774 2775 case ETHER_STAT_CAP_100T4: 2776 *val = mxfep->mxfe_bmsr & MII_STATUS_100_BASE_T4 ? 1 : 0; 2777 break; 2778 2779 case ETHER_STAT_ADV_CAP_100T4: 2780 *val = mxfep->mxfe_adv_100T4; 2781 break; 2782 2783 case ETHER_STAT_LP_CAP_100T4: 2784 *val = (mxfep->mxfe_anlpar & MII_ABILITY_100BASE_T4) ? 1 : 0; 2785 break; 2786 2787 case ETHER_STAT_CAP_100FDX: 2788 *val = mxfep->mxfe_bmsr & MII_STATUS_100_BASEX_FD ? 1 : 0; 2789 break; 2790 2791 case ETHER_STAT_CAP_100HDX: 2792 *val = mxfep->mxfe_bmsr & MII_STATUS_100_BASEX ? 1 : 0; 2793 break; 2794 2795 case ETHER_STAT_CAP_10FDX: 2796 *val = mxfep->mxfe_bmsr & MII_STATUS_10_FD ? 1 : 0; 2797 break; 2798 2799 case ETHER_STAT_CAP_10HDX: 2800 *val = mxfep->mxfe_bmsr & MII_STATUS_10 ? 1 : 0; 2801 break; 2802 2803 case ETHER_STAT_CAP_AUTONEG: 2804 *val = mxfep->mxfe_bmsr & MII_STATUS_CANAUTONEG ? 1 : 0; 2805 break; 2806 2807 case ETHER_STAT_LINK_AUTONEG: 2808 *val = ((mxfep->mxfe_adv_aneg != 0) && 2809 ((mxfep->mxfe_aner & MII_AN_EXP_LPCANAN) != 0)); 2810 break; 2811 2812 case ETHER_STAT_ADV_CAP_100FDX: 2813 *val = mxfep->mxfe_adv_100fdx; 2814 break; 2815 2816 case ETHER_STAT_ADV_CAP_100HDX: 2817 *val = mxfep->mxfe_adv_100hdx; 2818 break; 2819 2820 case ETHER_STAT_ADV_CAP_10FDX: 2821 *val = mxfep->mxfe_adv_10fdx; 2822 break; 2823 2824 case ETHER_STAT_ADV_CAP_10HDX: 2825 *val = mxfep->mxfe_adv_10hdx; 2826 break; 2827 2828 case ETHER_STAT_ADV_CAP_AUTONEG: 2829 *val = mxfep->mxfe_adv_aneg; 2830 break; 2831 2832 case ETHER_STAT_LP_CAP_100FDX: 2833 *val = (mxfep->mxfe_anlpar & MII_ABILITY_100BASE_TX_FD) ? 1 : 0; 2834 break; 2835 2836 case ETHER_STAT_LP_CAP_100HDX: 2837 *val = (mxfep->mxfe_anlpar & MII_ABILITY_100BASE_TX) ? 1 : 0; 2838 break; 2839 2840 case ETHER_STAT_LP_CAP_10FDX: 2841 *val = (mxfep->mxfe_anlpar & MII_ABILITY_10BASE_T_FD) ? 1 : 0; 2842 break; 2843 2844 case ETHER_STAT_LP_CAP_10HDX: 2845 *val = (mxfep->mxfe_anlpar & MII_ABILITY_10BASE_T) ? 1 : 0; 2846 break; 2847 2848 case ETHER_STAT_LP_CAP_AUTONEG: 2849 *val = (mxfep->mxfe_aner & MII_AN_EXP_LPCANAN) ? 1 : 0; 2850 break; 2851 2852 case ETHER_STAT_XCVR_ADDR: 2853 *val = mxfep->mxfe_phyaddr; 2854 break; 2855 2856 case ETHER_STAT_XCVR_ID: 2857 *val = mxfep->mxfe_phyid; 2858 break; 2859 2860 case ETHER_STAT_XCVR_INUSE: 2861 *val = mxfep->mxfe_phyinuse; 2862 break; 2863 2864 default: 2865 return (ENOTSUP); 2866 } 2867 return (0); 2868 } 2869 2870 /* 2871 * NDD support. 2872 */ 2873 mxfe_nd_t * 2874 mxfe_ndfind(mxfe_t *mxfep, char *name) 2875 { 2876 mxfe_nd_t *ndp; 2877 2878 for (ndp = mxfep->mxfe_ndp; ndp != NULL; ndp = ndp->nd_next) { 2879 if (strcmp(name, ndp->nd_name) == 0) { 2880 break; 2881 } 2882 } 2883 return (ndp); 2884 } 2885 2886 void 2887 mxfe_ndadd(mxfe_t *mxfep, char *name, mxfe_nd_pf_t get, mxfe_nd_pf_t set, 2888 intptr_t arg1, intptr_t arg2) 2889 { 2890 mxfe_nd_t *newndp; 2891 mxfe_nd_t **ndpp; 2892 2893 newndp = (mxfe_nd_t *)kmem_alloc(sizeof (mxfe_nd_t), KM_SLEEP); 2894 newndp->nd_next = NULL; 2895 newndp->nd_name = name; 2896 newndp->nd_get = get; 2897 newndp->nd_set = set; 2898 newndp->nd_arg1 = arg1; 2899 newndp->nd_arg2 = arg2; 2900 2901 /* seek to the end of the list */ 2902 for (ndpp = &mxfep->mxfe_ndp; *ndpp; ndpp = &(*ndpp)->nd_next) { 2903 } 2904 2905 *ndpp = newndp; 2906 } 2907 2908 void 2909 mxfe_ndempty(mblk_t *mp) 2910 { 2911 while (mp != NULL) { 2912 mp->b_rptr = mp->b_datap->db_base; 2913 mp->b_wptr = mp->b_rptr; 2914 mp = mp->b_cont; 2915 } 2916 } 2917 2918 void 2919 mxfe_ndget(mxfe_t *mxfep, queue_t *wq, mblk_t *mp) 2920 { 2921 mblk_t *nmp = mp->b_cont; 2922 mxfe_nd_t *ndp; 2923 int rv; 2924 char name[128]; 2925 2926 /* assumption, name will fit in first mblk of chain */ 2927 if ((nmp == NULL) || (nmp->b_wptr <= nmp->b_rptr)) { 2928 miocnak(wq, mp, 0, EINVAL); 2929 return; 2930 } 2931 2932 if (mxfe_ndparselen(nmp) >= sizeof (name)) { 2933 miocnak(wq, mp, 0, EINVAL); 2934 return; 2935 } 2936 mxfe_ndparsestring(nmp, name, sizeof (name)); 2937 2938 /* locate variable */ 2939 if ((ndp = mxfe_ndfind(mxfep, name)) == NULL) { 2940 miocnak(wq, mp, 0, EINVAL); 2941 return; 2942 } 2943 2944 /* locate get callback */ 2945 if (ndp->nd_get == NULL) { 2946 miocnak(wq, mp, 0, EACCES); 2947 return; 2948 } 2949 2950 /* clear the result buffer */ 2951 mxfe_ndempty(nmp); 2952 2953 rv = (*ndp->nd_get)(mxfep, nmp, ndp); 2954 if (rv == 0) { 2955 /* add final null bytes */ 2956 rv = mxfe_ndaddbytes(nmp, "\0", 1); 2957 } 2958 2959 if (rv == 0) { 2960 miocack(wq, mp, msgsize(nmp), 0); 2961 } else { 2962 miocnak(wq, mp, 0, rv); 2963 } 2964 } 2965 2966 void 2967 mxfe_ndset(mxfe_t *mxfep, queue_t *wq, mblk_t *mp) 2968 { 2969 struct iocblk *iocp = (void *)mp->b_rptr; 2970 mblk_t *nmp = mp->b_cont; 2971 mxfe_nd_t *ndp; 2972 int rv; 2973 char name[128]; 2974 2975 /* enforce policy */ 2976 if ((rv = priv_getbyname(PRIV_SYS_NET_CONFIG, 0)) < 0) { 2977 /* priv_getbyname returns a negative errno */ 2978 miocnak(wq, mp, 0, -rv); 2979 return; 2980 } 2981 if ((rv = priv_policy(iocp->ioc_cr, rv, B_FALSE, EPERM, NULL)) != 0) { 2982 miocnak(wq, mp, 0, rv); 2983 return; 2984 } 2985 2986 /* assumption, name will fit in first mblk of chain */ 2987 if ((nmp == NULL) || (nmp->b_wptr <= nmp->b_rptr)) { 2988 miocnak(wq, mp, 0, EINVAL); 2989 return; 2990 } 2991 2992 if (mxfe_ndparselen(nmp) >= sizeof (name)) { 2993 miocnak(wq, mp, 0, EINVAL); 2994 return; 2995 } 2996 mxfe_ndparsestring(nmp, name, sizeof (name)); 2997 2998 /* locate variable */ 2999 if ((ndp = mxfe_ndfind(mxfep, name)) == NULL) { 3000 miocnak(wq, mp, 0, EINVAL); 3001 return; 3002 } 3003 3004 /* locate set callback */ 3005 if (ndp->nd_set == NULL) { 3006 miocnak(wq, mp, 0, EACCES); 3007 return; 3008 } 3009 3010 rv = (*ndp->nd_set)(mxfep, nmp, ndp); 3011 3012 if (rv == 0) { 3013 miocack(wq, mp, 0, 0); 3014 } else { 3015 miocnak(wq, mp, 0, rv); 3016 } 3017 } 3018 3019 int 3020 mxfe_ndaddbytes(mblk_t *mp, char *bytes, int cnt) 3021 { 3022 int index; 3023 3024 for (index = 0; index < cnt; index++) { 3025 while (mp && (mp->b_wptr >= DB_LIM(mp))) { 3026 mp = mp->b_cont; 3027 } 3028 if (mp == NULL) { 3029 return (ENOSPC); 3030 } 3031 *(mp->b_wptr) = *bytes; 3032 mp->b_wptr++; 3033 bytes++; 3034 } 3035 return (0); 3036 } 3037 3038 int 3039 mxfe_ndaddstr(mblk_t *mp, char *str, int addnull) 3040 { 3041 /* store the string, plus the terminating null */ 3042 return (mxfe_ndaddbytes(mp, str, strlen(str) + (addnull ? 1 : 0))); 3043 } 3044 3045 int 3046 mxfe_ndparselen(mblk_t *mp) 3047 { 3048 int len = 0; 3049 int done = 0; 3050 uchar_t *ptr; 3051 3052 while (mp && !done) { 3053 for (ptr = mp->b_rptr; ptr < mp->b_wptr; ptr++) { 3054 if (!(*ptr)) { 3055 done = 1; 3056 break; 3057 } 3058 len++; 3059 } 3060 mp = mp->b_cont; 3061 } 3062 return (len); 3063 } 3064 3065 int 3066 mxfe_ndparseint(mblk_t *mp) 3067 { 3068 int done = 0; 3069 int val = 0; 3070 while (mp && !done) { 3071 while (mp->b_rptr < mp->b_wptr) { 3072 uchar_t ch = *(mp->b_rptr); 3073 mp->b_rptr++; 3074 if ((ch >= '0') && (ch <= '9')) { 3075 val *= 10; 3076 val += ch - '0'; 3077 } else if (ch == 0) { 3078 return (val); 3079 } else { 3080 /* parse error, put back rptr */ 3081 mp->b_rptr--; 3082 return (val); 3083 } 3084 } 3085 mp = mp->b_cont; 3086 } 3087 return (val); 3088 } 3089 3090 void 3091 mxfe_ndparsestring(mblk_t *mp, char *buf, int maxlen) 3092 { 3093 int done = 0; 3094 int len = 0; 3095 3096 /* ensure null termination */ 3097 buf[maxlen - 1] = 0; 3098 while (mp && !done) { 3099 while (mp->b_rptr < mp->b_wptr) { 3100 char ch = *((char *)mp->b_rptr); 3101 mp->b_rptr++; 3102 buf[len++] = ch; 3103 if ((ch == 0) || (len == maxlen)) { 3104 return; 3105 } 3106 } 3107 mp = mp->b_cont; 3108 } 3109 } 3110 3111 int 3112 mxfe_ndquestion(mxfe_t *mxfep, mblk_t *mp, mxfe_nd_t *ndp) 3113 { 3114 for (ndp = mxfep->mxfe_ndp; ndp; ndp = ndp->nd_next) { 3115 int rv; 3116 char *s; 3117 if ((rv = mxfe_ndaddstr(mp, ndp->nd_name, 0)) != 0) { 3118 return (rv); 3119 } 3120 if (ndp->nd_get && ndp->nd_set) { 3121 s = " (read and write)"; 3122 } else if (ndp->nd_get) { 3123 s = " (read only)"; 3124 } else if (ndp->nd_set) { 3125 s = " (write only)"; 3126 } else { 3127 s = " (no read or write)"; 3128 } 3129 if ((rv = mxfe_ndaddstr(mp, s, 1)) != 0) { 3130 return (rv); 3131 } 3132 } 3133 return (0); 3134 } 3135 3136 /*ARGSUSED*/ 3137 int 3138 mxfe_ndgetint(mxfe_t *mxfep, mblk_t *mp, mxfe_nd_t *ndp) 3139 { 3140 int val; 3141 char buf[16]; 3142 3143 val = *(int *)ndp->nd_arg1; 3144 3145 (void) snprintf(buf, sizeof (buf), "%d", val); 3146 return (mxfe_ndaddstr(mp, buf, 1)); 3147 } 3148 3149 /*ARGSUSED*/ 3150 int 3151 mxfe_ndgetbit(mxfe_t *mxfep, mblk_t *mp, mxfe_nd_t *ndp) 3152 { 3153 unsigned val; 3154 unsigned mask; 3155 3156 val = *(unsigned *)ndp->nd_arg1; 3157 mask = (unsigned)ndp->nd_arg2; 3158 3159 return (mxfe_ndaddstr(mp, val & mask ? "1" : "0", 1)); 3160 } 3161 3162 int 3163 mxfe_ndsetadv(mxfe_t *mxfep, mblk_t *mp, mxfe_nd_t *ndp) 3164 { 3165 unsigned *ptr = (unsigned *)ndp->nd_arg1; 3166 unsigned oldval, newval; 3167 3168 newval = mxfe_ndparseint(mp) ? 1 : 0; 3169 3170 mutex_enter(&mxfep->mxfe_intrlock); 3171 mutex_enter(&mxfep->mxfe_xmtlock); 3172 3173 oldval = *ptr; 3174 if (oldval != newval) { 3175 *ptr = newval; 3176 if ((mxfep->mxfe_flags & (MXFE_RUNNING|MXFE_SUSPENDED)) == 3177 MXFE_RUNNING) { 3178 /* 3179 * This re-initializes the phy, but it also 3180 * restarts transmit and receive rings. 3181 * Needless to say, changing the link 3182 * parameters is destructive to traffic in 3183 * progress. 3184 */ 3185 mxfe_resetall(mxfep); 3186 } 3187 } 3188 mutex_exit(&mxfep->mxfe_xmtlock); 3189 mutex_exit(&mxfep->mxfe_intrlock); 3190 3191 return (0); 3192 } 3193 3194 void 3195 mxfe_ndfini(mxfe_t *mxfep) 3196 { 3197 mxfe_nd_t *ndp; 3198 3199 while ((ndp = mxfep->mxfe_ndp) != NULL) { 3200 mxfep->mxfe_ndp = ndp->nd_next; 3201 kmem_free(ndp, sizeof (mxfe_nd_t)); 3202 } 3203 } 3204 3205 void 3206 mxfe_ndinit(mxfe_t *mxfep) 3207 { 3208 mxfe_ndadd(mxfep, "?", mxfe_ndquestion, NULL, 0, 0); 3209 mxfe_ndadd(mxfep, "link_status", mxfe_ndgetint, NULL, 3210 (intptr_t)&mxfep->mxfe_linkup, 0); 3211 mxfe_ndadd(mxfep, "link_speed", mxfe_ndgetint, NULL, 3212 (intptr_t)&mxfep->mxfe_ifspeed, 0); 3213 mxfe_ndadd(mxfep, "link_duplex", mxfe_ndgetint, NULL, 3214 (intptr_t)&mxfep->mxfe_duplex, 0); 3215 mxfe_ndadd(mxfep, "adv_autoneg_cap", mxfe_ndgetint, mxfe_ndsetadv, 3216 (intptr_t)&mxfep->mxfe_adv_aneg, 0); 3217 mxfe_ndadd(mxfep, "adv_100T4_cap", mxfe_ndgetint, mxfe_ndsetadv, 3218 (intptr_t)&mxfep->mxfe_adv_100T4, 0); 3219 mxfe_ndadd(mxfep, "adv_100fdx_cap", mxfe_ndgetint, mxfe_ndsetadv, 3220 (intptr_t)&mxfep->mxfe_adv_100fdx, 0); 3221 mxfe_ndadd(mxfep, "adv_100hdx_cap", mxfe_ndgetint, mxfe_ndsetadv, 3222 (intptr_t)&mxfep->mxfe_adv_100hdx, 0); 3223 mxfe_ndadd(mxfep, "adv_10fdx_cap", mxfe_ndgetint, mxfe_ndsetadv, 3224 (intptr_t)&mxfep->mxfe_adv_10fdx, 0); 3225 mxfe_ndadd(mxfep, "adv_10hdx_cap", mxfe_ndgetint, mxfe_ndsetadv, 3226 (intptr_t)&mxfep->mxfe_adv_10hdx, 0); 3227 mxfe_ndadd(mxfep, "autoneg_cap", mxfe_ndgetbit, NULL, 3228 (intptr_t)&mxfep->mxfe_bmsr, MII_STATUS_CANAUTONEG); 3229 mxfe_ndadd(mxfep, "100T4_cap", mxfe_ndgetbit, NULL, 3230 (intptr_t)&mxfep->mxfe_bmsr, MII_STATUS_100_BASE_T4); 3231 mxfe_ndadd(mxfep, "100fdx_cap", mxfe_ndgetbit, NULL, 3232 (intptr_t)&mxfep->mxfe_bmsr, MII_STATUS_100_BASEX_FD); 3233 mxfe_ndadd(mxfep, "100hdx_cap", mxfe_ndgetbit, NULL, 3234 (intptr_t)&mxfep->mxfe_bmsr, MII_STATUS_100_BASEX); 3235 mxfe_ndadd(mxfep, "10fdx_cap", mxfe_ndgetbit, NULL, 3236 (intptr_t)&mxfep->mxfe_bmsr, MII_STATUS_10_FD); 3237 mxfe_ndadd(mxfep, "10hdx_cap", mxfe_ndgetbit, NULL, 3238 (intptr_t)&mxfep->mxfe_bmsr, MII_STATUS_10); 3239 mxfe_ndadd(mxfep, "lp_autoneg_cap", mxfe_ndgetbit, NULL, 3240 (intptr_t)&mxfep->mxfe_aner, MII_AN_EXP_LPCANAN); 3241 mxfe_ndadd(mxfep, "lp_100T4_cap", mxfe_ndgetbit, NULL, 3242 (intptr_t)&mxfep->mxfe_anlpar, MII_ABILITY_100BASE_T4); 3243 mxfe_ndadd(mxfep, "lp_100fdx_cap", mxfe_ndgetbit, NULL, 3244 (intptr_t)&mxfep->mxfe_anlpar, MII_ABILITY_100BASE_TX_FD); 3245 mxfe_ndadd(mxfep, "lp_100hdx_cap", mxfe_ndgetbit, NULL, 3246 (intptr_t)&mxfep->mxfe_anlpar, MII_ABILITY_100BASE_TX); 3247 mxfe_ndadd(mxfep, "lp_10fdx_cap", mxfe_ndgetbit, NULL, 3248 (intptr_t)&mxfep->mxfe_anlpar, MII_ABILITY_10BASE_T_FD); 3249 mxfe_ndadd(mxfep, "lp_10hdx_cap", mxfe_ndgetbit, NULL, 3250 (intptr_t)&mxfep->mxfe_anlpar, MII_ABILITY_10BASE_T); 3251 } 3252 3253 /* 3254 * Debugging and error reporting. 3255 */ 3256 void 3257 mxfe_error(dev_info_t *dip, char *fmt, ...) 3258 { 3259 va_list ap; 3260 char buf[256]; 3261 3262 va_start(ap, fmt); 3263 (void) vsnprintf(buf, sizeof (buf), fmt, ap); 3264 va_end(ap); 3265 3266 if (dip) { 3267 cmn_err(CE_WARN, "%s%d: %s", 3268 ddi_driver_name(dip), ddi_get_instance(dip), buf); 3269 } else { 3270 cmn_err(CE_WARN, "mxfe: %s", buf); 3271 } 3272 } 3273 3274 #ifdef DEBUG 3275 3276 void 3277 mxfe_dprintf(mxfe_t *mxfep, const char *func, int level, char *fmt, ...) 3278 { 3279 va_list ap; 3280 3281 va_start(ap, fmt); 3282 if (mxfe_debug & level) { 3283 char tag[64]; 3284 char buf[256]; 3285 3286 if (mxfep && mxfep->mxfe_dip) { 3287 (void) snprintf(tag, sizeof (tag), 3288 "%s%d", ddi_driver_name(mxfep->mxfe_dip), 3289 ddi_get_instance(mxfep->mxfe_dip)); 3290 } else { 3291 (void) snprintf(tag, sizeof (tag), "mxfe"); 3292 } 3293 3294 (void) snprintf(buf, sizeof (buf), "%s: %s: %s\n", tag, 3295 func, fmt); 3296 3297 vcmn_err(CE_CONT, buf, ap); 3298 } 3299 va_end(ap); 3300 } 3301 3302 #endif 3303