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