1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 /* 28 * SunOS MT STREAMS FEPS(SBus)/Cheerio(PCI) 10/100Mb Ethernet Device Driver 29 */ 30 31 #include <sys/types.h> 32 #include <sys/debug.h> 33 #include <sys/stream.h> 34 #include <sys/cmn_err.h> 35 #include <sys/kmem.h> 36 #include <sys/crc32.h> 37 #include <sys/modctl.h> 38 #include <sys/conf.h> 39 #include <sys/strsun.h> 40 #include <sys/kstat.h> 41 #include <sys/pattr.h> 42 #include <sys/dlpi.h> 43 #include <sys/strsubr.h> 44 #include <sys/mac_provider.h> 45 #include <sys/mac_ether.h> 46 #include <sys/mii.h> 47 #include <sys/ethernet.h> 48 #include <sys/vlan.h> 49 #include <sys/pci.h> 50 #include <sys/policy.h> 51 #include <sys/ddi.h> 52 #include <sys/sunddi.h> 53 #include <sys/byteorder.h> 54 #include "hme_phy.h" 55 #include "hme_mac.h" 56 #include "hme.h" 57 58 typedef void (*fptrv_t)(); 59 60 typedef enum { 61 NO_MSG = 0, 62 AUTOCONFIG_MSG, 63 DISPLAY_MSG, 64 INIT_MSG, 65 UNINIT_MSG, 66 CONFIG_MSG, 67 MII_MSG, 68 FATAL_ERR_MSG, 69 NFATAL_ERR_MSG, 70 XCVR_MSG, 71 NOXCVR_MSG, 72 ERX_MSG, 73 DDI_MSG, 74 } msg_t; 75 76 msg_t hme_debug_level = NO_MSG; 77 78 static char *msg_string[] = { 79 "NONE ", 80 "AUTOCONFIG ", 81 "DISPLAY " 82 "INIT ", 83 "UNINIT ", 84 "CONFIG ", 85 "MII ", 86 "FATAL_ERR ", 87 "NFATAL_ERR ", 88 "XCVR ", 89 "NOXCVR ", 90 "ERX ", 91 "DDI ", 92 }; 93 94 #define SEVERITY_NONE 0 95 #define SEVERITY_LOW 0 96 #define SEVERITY_MID 1 97 #define SEVERITY_HIGH 2 98 #define SEVERITY_UNKNOWN 99 99 100 #define FEPS_URUN_BUG 101 #define HME_CODEVIOL_BUG 102 103 #define KIOIP KSTAT_INTR_PTR(hmep->hme_intrstats) 104 105 /* 106 * The following variables are used for checking fixes in Sbus/FEPS 2.0 107 */ 108 static int hme_urun_fix = 0; /* Bug fixed in Sbus/FEPS 2.0 */ 109 110 /* 111 * The following variables are used for configuring various features 112 */ 113 static int hme_64bit_enable = 1; /* Use 64-bit sbus transfers */ 114 static int hme_reject_own = 1; /* Reject packets with own SA */ 115 static int hme_ngu_enable = 0; /* Never Give Up mode */ 116 117 char *hme_priv_prop[] = { 118 "_ipg0", 119 "_ipg1", 120 "_ipg2", 121 "_lance_mode", 122 NULL 123 }; 124 125 static int hme_lance_mode = 1; /* to enable lance mode */ 126 static int hme_ipg0 = 16; 127 static int hme_ipg1 = 8; 128 static int hme_ipg2 = 4; 129 130 /* 131 * The following parameters may be configured by the user. If they are not 132 * configured by the user, the values will be based on the capabilities of 133 * the transceiver. 134 * The value "HME_NOTUSR" is ORed with the parameter value to indicate values 135 * which are NOT configured by the user. 136 */ 137 138 #define HME_NOTUSR 0x0f000000 139 #define HME_MASK_1BIT 0x1 140 #define HME_MASK_5BIT 0x1f 141 #define HME_MASK_8BIT 0xff 142 143 /* 144 * All strings used by hme messaging functions 145 */ 146 147 static char *no_xcvr_msg = 148 "No transceiver found."; 149 150 static char *burst_size_msg = 151 "Could not identify the burst size"; 152 153 static char *unk_rx_ringsz_msg = 154 "Unknown receive RINGSZ"; 155 156 static char *add_intr_fail_msg = 157 "ddi_add_intr(9F) failed"; 158 159 static char *mregs_4global_reg_fail_msg = 160 "ddi_regs_map_setup(9F) for global reg failed"; 161 162 static char *mregs_4etx_reg_fail_msg = 163 "ddi_map_regs for etx reg failed"; 164 165 static char *mregs_4erx_reg_fail_msg = 166 "ddi_map_regs for erx reg failed"; 167 168 static char *mregs_4bmac_reg_fail_msg = 169 "ddi_map_regs for bmac reg failed"; 170 171 static char *mregs_4mif_reg_fail_msg = 172 "ddi_map_regs for mif reg failed"; 173 174 static char *init_fail_gen_msg = 175 "Failed to initialize hardware/driver"; 176 177 static char *ddi_nregs_fail_msg = 178 "ddi_dev_nregs failed(9F), returned %d"; 179 180 static char *bad_num_regs_msg = 181 "Invalid number of registers."; 182 183 184 /* FATAL ERR msgs */ 185 /* 186 * Function prototypes. 187 */ 188 /* these two are global so that qfe can use them */ 189 int hmeattach(dev_info_t *, ddi_attach_cmd_t); 190 int hmedetach(dev_info_t *, ddi_detach_cmd_t); 191 int hmequiesce(dev_info_t *); 192 static boolean_t hmeinit_xfer_params(struct hme *); 193 static uint_t hmestop(struct hme *); 194 static void hmestatinit(struct hme *); 195 static int hmeallocthings(struct hme *); 196 static void hmefreethings(struct hme *); 197 static int hmeallocbuf(struct hme *, hmebuf_t *, int); 198 static int hmeallocbufs(struct hme *); 199 static void hmefreebufs(struct hme *); 200 static void hmeget_hm_rev_property(struct hme *); 201 static boolean_t hmestart(struct hme *, mblk_t *); 202 static uint_t hmeintr(caddr_t); 203 static void hmereclaim(struct hme *); 204 static int hmeinit(struct hme *); 205 static void hmeuninit(struct hme *hmep); 206 static mblk_t *hmeread(struct hme *, hmebuf_t *, uint32_t); 207 static void hmesavecntrs(struct hme *); 208 static void hme_fatal_err(struct hme *, uint_t); 209 static void hme_nonfatal_err(struct hme *, uint_t); 210 static int hmeburstsizes(struct hme *); 211 static void send_bit(struct hme *, uint16_t); 212 static uint16_t get_bit_std(uint8_t, struct hme *); 213 static uint16_t hme_bb_mii_read(struct hme *, uint8_t, uint8_t); 214 static void hme_bb_mii_write(struct hme *, uint8_t, uint8_t, uint16_t); 215 static void hme_bb_force_idle(struct hme *); 216 static uint16_t hme_mii_read(void *, uint8_t, uint8_t); 217 static void hme_mii_write(void *, uint8_t, uint8_t, uint16_t); 218 static void hme_setup_mac_address(struct hme *, dev_info_t *); 219 static void hme_mii_notify(void *, link_state_t); 220 221 static void hme_fault_msg(struct hme *, uint_t, msg_t, char *, ...); 222 223 static void hme_check_acc_handle(char *, uint_t, struct hme *, 224 ddi_acc_handle_t); 225 226 /* 227 * Nemo (GLDv3) Functions. 228 */ 229 static int hme_m_stat(void *, uint_t, uint64_t *); 230 static int hme_m_start(void *); 231 static void hme_m_stop(void *); 232 static int hme_m_promisc(void *, boolean_t); 233 static int hme_m_multicst(void *, boolean_t, const uint8_t *); 234 static int hme_m_unicst(void *, const uint8_t *); 235 static mblk_t *hme_m_tx(void *, mblk_t *); 236 static boolean_t hme_m_getcapab(void *, mac_capab_t, void *); 237 static int hme_m_getprop(void *, const char *, mac_prop_id_t, uint_t, void *); 238 static void hme_m_propinfo(void *, const char *, mac_prop_id_t, 239 mac_prop_info_handle_t); 240 static int hme_m_setprop(void *, const char *, mac_prop_id_t, uint_t, 241 const void *); 242 243 static mii_ops_t hme_mii_ops = { 244 MII_OPS_VERSION, 245 hme_mii_read, 246 hme_mii_write, 247 hme_mii_notify, 248 NULL 249 }; 250 251 static mac_callbacks_t hme_m_callbacks = { 252 MC_GETCAPAB | MC_SETPROP | MC_GETPROP | MC_PROPINFO, 253 hme_m_stat, 254 hme_m_start, 255 hme_m_stop, 256 hme_m_promisc, 257 hme_m_multicst, 258 hme_m_unicst, 259 hme_m_tx, 260 NULL, 261 NULL, 262 hme_m_getcapab, 263 NULL, 264 NULL, 265 hme_m_setprop, 266 hme_m_getprop, 267 hme_m_propinfo 268 }; 269 270 DDI_DEFINE_STREAM_OPS(hme_dev_ops, nulldev, nulldev, hmeattach, hmedetach, 271 nodev, NULL, D_MP, NULL, hmequiesce); 272 273 #define HME_FAULT_MSG1(p, s, t, f) \ 274 hme_fault_msg((p), (s), (t), (f)); 275 276 #define HME_FAULT_MSG2(p, s, t, f, a) \ 277 hme_fault_msg((p), (s), (t), (f), (a)); 278 279 #define HME_FAULT_MSG3(p, s, t, f, a, b) \ 280 hme_fault_msg((p), (s), (t), (f), (a), (b)); 281 282 #define HME_FAULT_MSG4(p, s, t, f, a, b, c) \ 283 hme_fault_msg((p), (s), (t), (f), (a), (b), (c)); 284 285 #define CHECK_MIFREG() \ 286 hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_mifregh) 287 #define CHECK_ETXREG() \ 288 hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_etxregh) 289 #define CHECK_ERXREG() \ 290 hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_erxregh) 291 #define CHECK_MACREG() \ 292 hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_bmacregh) 293 #define CHECK_GLOBREG() \ 294 hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_globregh) 295 296 /* 297 * Claim the device is ultra-capable of burst in the beginning. Use 298 * the value returned by ddi_dma_burstsizes() to actually set the HME 299 * global configuration register later. 300 * 301 * Sbus/FEPS supports burst sizes of 16, 32 and 64 bytes. Also, it supports 302 * 32-bit and 64-bit Sbus transfers. Hence the dlim_burstsizes field contains 303 * the the burstsizes in both the lo and hi words. 304 */ 305 #define HMELIMADDRLO ((uint64_t)0x00000000) 306 #define HMELIMADDRHI ((uint64_t)0xffffffff) 307 308 /* 309 * Note that rx and tx data buffers can be arbitrarily aligned, but 310 * that the descriptor rings need to be aligned on 2K boundaries, per 311 * the spec. 312 */ 313 static ddi_dma_attr_t hme_dma_attr = { 314 DMA_ATTR_V0, /* version number. */ 315 (uint64_t)HMELIMADDRLO, /* low address */ 316 (uint64_t)HMELIMADDRHI, /* high address */ 317 (uint64_t)0x00ffffff, /* address counter max */ 318 (uint64_t)HME_HMDALIGN, /* alignment */ 319 (uint_t)0x00700070, /* dlim_burstsizes for 32 and 64 bit xfers */ 320 (uint32_t)0x1, /* minimum transfer size */ 321 (uint64_t)0x7fffffff, /* maximum transfer size */ 322 (uint64_t)0x00ffffff, /* maximum segment size */ 323 1, /* scatter/gather list length */ 324 512, /* granularity */ 325 0 /* attribute flags */ 326 }; 327 328 static ddi_device_acc_attr_t hme_buf_attr = { 329 DDI_DEVICE_ATTR_V0, 330 DDI_NEVERSWAP_ACC, 331 DDI_STRICTORDER_ACC, /* probably could allow merging & caching */ 332 DDI_DEFAULT_ACC, 333 }; 334 335 static uchar_t pci_latency_timer = 0; 336 337 /* 338 * Module linkage information for the kernel. 339 */ 340 static struct modldrv modldrv = { 341 &mod_driverops, /* Type of module. This one is a driver */ 342 "Sun HME 10/100 Mb Ethernet", 343 &hme_dev_ops, /* driver ops */ 344 }; 345 346 static struct modlinkage modlinkage = { 347 MODREV_1, &modldrv, NULL 348 }; 349 350 /* <<<<<<<<<<<<<<<<<<<<<< Register operations >>>>>>>>>>>>>>>>>>>>> */ 351 352 #define GET_MIFREG(reg) \ 353 ddi_get32(hmep->hme_mifregh, (uint32_t *)&hmep->hme_mifregp->reg) 354 #define PUT_MIFREG(reg, value) \ 355 ddi_put32(hmep->hme_mifregh, (uint32_t *)&hmep->hme_mifregp->reg, value) 356 357 #define GET_ETXREG(reg) \ 358 ddi_get32(hmep->hme_etxregh, (uint32_t *)&hmep->hme_etxregp->reg) 359 #define PUT_ETXREG(reg, value) \ 360 ddi_put32(hmep->hme_etxregh, (uint32_t *)&hmep->hme_etxregp->reg, value) 361 #define GET_ERXREG(reg) \ 362 ddi_get32(hmep->hme_erxregh, (uint32_t *)&hmep->hme_erxregp->reg) 363 #define PUT_ERXREG(reg, value) \ 364 ddi_put32(hmep->hme_erxregh, (uint32_t *)&hmep->hme_erxregp->reg, value) 365 #define GET_MACREG(reg) \ 366 ddi_get32(hmep->hme_bmacregh, (uint32_t *)&hmep->hme_bmacregp->reg) 367 #define PUT_MACREG(reg, value) \ 368 ddi_put32(hmep->hme_bmacregh, \ 369 (uint32_t *)&hmep->hme_bmacregp->reg, value) 370 #define GET_GLOBREG(reg) \ 371 ddi_get32(hmep->hme_globregh, (uint32_t *)&hmep->hme_globregp->reg) 372 #define PUT_GLOBREG(reg, value) \ 373 ddi_put32(hmep->hme_globregh, \ 374 (uint32_t *)&hmep->hme_globregp->reg, value) 375 #define PUT_TMD(ptr, paddr, len, flags) \ 376 ddi_put32(hmep->hme_tmd_acch, &hmep->hme_tmdp[ptr].tmd_addr, paddr); \ 377 ddi_put32(hmep->hme_tmd_acch, &hmep->hme_tmdp[ptr].tmd_flags, \ 378 len | flags) 379 #define GET_TMD_FLAGS(ptr) \ 380 ddi_get32(hmep->hme_tmd_acch, &hmep->hme_tmdp[ptr].tmd_flags) 381 #define PUT_RMD(ptr, paddr) \ 382 ddi_put32(hmep->hme_rmd_acch, &hmep->hme_rmdp[ptr].rmd_addr, paddr); \ 383 ddi_put32(hmep->hme_rmd_acch, &hmep->hme_rmdp[ptr].rmd_flags, \ 384 (uint32_t)(HMEBUFSIZE << HMERMD_BUFSIZE_SHIFT) | HMERMD_OWN) 385 #define GET_RMD_FLAGS(ptr) \ 386 ddi_get32(hmep->hme_rmd_acch, &hmep->hme_rmdp[ptr].rmd_flags) 387 388 #define GET_ROM8(offset) \ 389 ddi_get8((hmep->hme_romh), (offset)) 390 391 /* 392 * Ether_copy is not endian-correct. Define an endian-correct version. 393 */ 394 #define ether_bcopy(a, b) (bcopy(a, b, 6)) 395 396 /* 397 * Ether-type is specifically big-endian, but data region is unknown endian 398 */ 399 #define get_ether_type(ptr) \ 400 (((((uint8_t *)ptr)[12] << 8) | (((uint8_t *)ptr)[13]))) 401 402 /* <<<<<<<<<<<<<<<<<<<<<< Configuration Parameters >>>>>>>>>>>>>>>>>>>>> */ 403 404 #define BMAC_DEFAULT_JAMSIZE (0x04) /* jamsize equals 4 */ 405 #define BMAC_LONG_JAMSIZE (0x10) /* jamsize equals 0x10 */ 406 static int jamsize = BMAC_DEFAULT_JAMSIZE; 407 408 409 /* 410 * Calculate the bit in the multicast address filter that selects the given 411 * address. 412 */ 413 414 static uint32_t 415 hmeladrf_bit(const uint8_t *addr) 416 { 417 uint32_t crc; 418 419 CRC32(crc, addr, ETHERADDRL, -1U, crc32_table); 420 421 /* 422 * Just want the 6 most significant bits. 423 */ 424 return (crc >> 26); 425 } 426 427 /* <<<<<<<<<<<<<<<<<<<<<<<< Bit Bang Operations >>>>>>>>>>>>>>>>>>>>>>>> */ 428 429 static void 430 send_bit(struct hme *hmep, uint16_t x) 431 { 432 PUT_MIFREG(mif_bbdata, x); 433 PUT_MIFREG(mif_bbclk, HME_BBCLK_LOW); 434 PUT_MIFREG(mif_bbclk, HME_BBCLK_HIGH); 435 } 436 437 438 /* 439 * To read the MII register bits according to the IEEE Standard 440 */ 441 static uint16_t 442 get_bit_std(uint8_t phyad, struct hme *hmep) 443 { 444 uint16_t x; 445 446 PUT_MIFREG(mif_bbclk, HME_BBCLK_LOW); 447 drv_usecwait(1); /* wait for >330 ns for stable data */ 448 if (phyad == HME_INTERNAL_PHYAD) 449 x = (GET_MIFREG(mif_cfg) & HME_MIF_CFGM0) ? 1 : 0; 450 else 451 x = (GET_MIFREG(mif_cfg) & HME_MIF_CFGM1) ? 1 : 0; 452 PUT_MIFREG(mif_bbclk, HME_BBCLK_HIGH); 453 return (x); 454 } 455 456 #define SEND_BIT(x) send_bit(hmep, x) 457 #define GET_BIT_STD(phyad, x) x = get_bit_std(phyad, hmep) 458 459 460 static void 461 hme_bb_mii_write(struct hme *hmep, uint8_t phyad, uint8_t regad, uint16_t data) 462 { 463 int i; 464 465 PUT_MIFREG(mif_bbopenb, 1); /* Enable the MII driver */ 466 (void) hme_bb_force_idle(hmep); 467 SEND_BIT(0); SEND_BIT(1); /* <ST> */ 468 SEND_BIT(0); SEND_BIT(1); /* <OP> */ 469 470 for (i = 4; i >= 0; i--) { /* <AAAAA> */ 471 SEND_BIT((phyad >> i) & 1); 472 } 473 474 for (i = 4; i >= 0; i--) { /* <RRRRR> */ 475 SEND_BIT((regad >> i) & 1); 476 } 477 478 SEND_BIT(1); SEND_BIT(0); /* <TA> */ 479 480 for (i = 0xf; i >= 0; i--) { /* <DDDDDDDDDDDDDDDD> */ 481 SEND_BIT((data >> i) & 1); 482 } 483 484 PUT_MIFREG(mif_bbopenb, 0); /* Disable the MII driver */ 485 CHECK_MIFREG(); 486 } 487 488 /* Return 0 if OK, 1 if error (Transceiver does not talk management) */ 489 static uint16_t 490 hme_bb_mii_read(struct hme *hmep, uint8_t phyad, uint8_t regad) 491 { 492 int i; 493 uint32_t x; 494 uint16_t data = 0; 495 496 PUT_MIFREG(mif_bbopenb, 1); /* Enable the MII driver */ 497 (void) hme_bb_force_idle(hmep); 498 SEND_BIT(0); SEND_BIT(1); /* <ST> */ 499 SEND_BIT(1); SEND_BIT(0); /* <OP> */ 500 for (i = 4; i >= 0; i--) { /* <AAAAA> */ 501 SEND_BIT((phyad >> i) & 1); 502 } 503 for (i = 4; i >= 0; i--) { /* <RRRRR> */ 504 SEND_BIT((regad >> i) & 1); 505 } 506 507 PUT_MIFREG(mif_bbopenb, 0); /* Disable the MII driver */ 508 509 GET_BIT_STD(phyad, x); 510 GET_BIT_STD(phyad, x); /* <TA> */ 511 for (i = 0xf; i >= 0; i--) { /* <DDDDDDDDDDDDDDDD> */ 512 GET_BIT_STD(phyad, x); 513 data += (x << i); 514 } 515 /* 516 * Kludge to get the Transceiver out of hung mode 517 */ 518 GET_BIT_STD(phyad, x); 519 GET_BIT_STD(phyad, x); 520 GET_BIT_STD(phyad, x); 521 CHECK_MIFREG(); 522 return (data); 523 } 524 525 526 static void 527 hme_bb_force_idle(struct hme *hmep) 528 { 529 int i; 530 531 for (i = 0; i < 33; i++) { 532 SEND_BIT(1); 533 } 534 } 535 536 /* <<<<<<<<<<<<<<<<<<<<End of Bit Bang Operations >>>>>>>>>>>>>>>>>>>>>>>> */ 537 538 539 /* <<<<<<<<<<<<< Frame Register used for MII operations >>>>>>>>>>>>>>>>>>>> */ 540 541 /* Return 0 if OK, 1 if error (Transceiver does not talk management) */ 542 static uint16_t 543 hme_mii_read(void *arg, uint8_t phyad, uint8_t regad) 544 { 545 struct hme *hmep = arg; 546 uint32_t frame; 547 uint32_t tmp_mif; 548 uint32_t tmp_xif; 549 550 tmp_mif = GET_MIFREG(mif_cfg); 551 tmp_xif = GET_MACREG(xifc); 552 553 switch (phyad) { 554 case HME_EXTERNAL_PHYAD: 555 PUT_MIFREG(mif_cfg, tmp_mif | HME_MIF_CFGPS); 556 PUT_MACREG(xifc, tmp_xif | BMAC_XIFC_MIIBUFDIS); 557 break; 558 case HME_INTERNAL_PHYAD: 559 PUT_MIFREG(mif_cfg, tmp_mif & ~(HME_MIF_CFGPS)); 560 PUT_MACREG(xifc, tmp_xif & ~(BMAC_XIFC_MIIBUFDIS)); 561 break; 562 default: 563 return (0xffff); 564 } 565 566 if (!hmep->hme_frame_enable) { 567 frame = (hme_bb_mii_read(hmep, phyad, regad)); 568 PUT_MACREG(xifc, tmp_xif); 569 PUT_MIFREG(mif_cfg, tmp_mif); 570 return (frame & 0xffff); 571 } 572 573 PUT_MIFREG(mif_frame, 574 HME_MIF_FRREAD | (phyad << HME_MIF_FRPHYAD_SHIFT) | 575 (regad << HME_MIF_FRREGAD_SHIFT)); 576 /* 577 * HMEDELAY((*framerp & HME_MIF_FRTA0), HMEMAXRSTDELAY); 578 */ 579 HMEDELAY((GET_MIFREG(mif_frame) & HME_MIF_FRTA0), 300); 580 frame = GET_MIFREG(mif_frame); 581 CHECK_MIFREG(); 582 583 PUT_MACREG(xifc, tmp_xif); 584 PUT_MIFREG(mif_cfg, tmp_mif); 585 586 if ((frame & HME_MIF_FRTA0) == 0) { 587 588 589 HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, MII_MSG, 590 "MIF Read failure"); 591 return (0xffff); 592 } 593 return ((uint16_t)(frame & HME_MIF_FRDATA)); 594 } 595 596 static void 597 hme_mii_write(void *arg, uint8_t phyad, uint8_t regad, uint16_t data) 598 { 599 struct hme *hmep = arg; 600 uint32_t frame; 601 uint32_t tmp_mif; 602 uint32_t tmp_xif; 603 604 tmp_mif = GET_MIFREG(mif_cfg); 605 tmp_xif = GET_MACREG(xifc); 606 607 switch (phyad) { 608 case HME_EXTERNAL_PHYAD: 609 PUT_MIFREG(mif_cfg, tmp_mif | HME_MIF_CFGPS); 610 PUT_MACREG(xifc, tmp_xif | BMAC_XIFC_MIIBUFDIS); 611 break; 612 case HME_INTERNAL_PHYAD: 613 PUT_MIFREG(mif_cfg, tmp_mif & ~(HME_MIF_CFGPS)); 614 PUT_MACREG(xifc, tmp_xif & ~(BMAC_XIFC_MIIBUFDIS)); 615 break; 616 default: 617 return; 618 } 619 620 if (!hmep->hme_frame_enable) { 621 hme_bb_mii_write(hmep, phyad, regad, data); 622 PUT_MACREG(xifc, tmp_xif); 623 PUT_MIFREG(mif_cfg, tmp_mif); 624 return; 625 } 626 627 PUT_MIFREG(mif_frame, 628 HME_MIF_FRWRITE | (phyad << HME_MIF_FRPHYAD_SHIFT) | 629 (regad << HME_MIF_FRREGAD_SHIFT) | data); 630 /* 631 * HMEDELAY((*framerp & HME_MIF_FRTA0), HMEMAXRSTDELAY); 632 */ 633 HMEDELAY((GET_MIFREG(mif_frame) & HME_MIF_FRTA0), 300); 634 frame = GET_MIFREG(mif_frame); 635 PUT_MACREG(xifc, tmp_xif); 636 PUT_MIFREG(mif_cfg, tmp_mif); 637 CHECK_MIFREG(); 638 if ((frame & HME_MIF_FRTA0) == 0) { 639 HME_FAULT_MSG1(hmep, SEVERITY_MID, MII_MSG, 640 "MIF Write failure"); 641 } 642 } 643 644 static void 645 hme_mii_notify(void *arg, link_state_t link) 646 { 647 struct hme *hmep = arg; 648 649 if (link == LINK_STATE_UP) { 650 (void) hmeinit(hmep); 651 } 652 mac_link_update(hmep->hme_mh, link); 653 } 654 655 /* <<<<<<<<<<<<<<<<<<<<<<<<<<< LOADABLE ENTRIES >>>>>>>>>>>>>>>>>>>>>>> */ 656 657 int 658 _init(void) 659 { 660 int status; 661 662 mac_init_ops(&hme_dev_ops, "hme"); 663 if ((status = mod_install(&modlinkage)) != 0) { 664 mac_fini_ops(&hme_dev_ops); 665 } 666 return (status); 667 } 668 669 int 670 _fini(void) 671 { 672 int status; 673 674 if ((status = mod_remove(&modlinkage)) == 0) { 675 mac_fini_ops(&hme_dev_ops); 676 } 677 return (status); 678 } 679 680 int 681 _info(struct modinfo *modinfop) 682 { 683 return (mod_info(&modlinkage, modinfop)); 684 } 685 686 /* 687 * ddi_dma_sync() a TMD or RMD descriptor. 688 */ 689 #define HMESYNCRMD(num, who) \ 690 (void) ddi_dma_sync(hmep->hme_rmd_dmah, \ 691 (num * sizeof (struct hme_rmd)), \ 692 sizeof (struct hme_rmd), \ 693 who) 694 695 #define HMESYNCTMD(num, who) \ 696 (void) ddi_dma_sync(hmep->hme_tmd_dmah, \ 697 (num * sizeof (struct hme_tmd)), \ 698 sizeof (struct hme_tmd), \ 699 who) 700 701 /* 702 * Ethernet broadcast address definition. 703 */ 704 static struct ether_addr etherbroadcastaddr = { 705 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 706 }; 707 708 /* 709 * MIB II broadcast/multicast packets 710 */ 711 #define IS_BROADCAST(pkt) (bcmp(pkt, ðerbroadcastaddr, ETHERADDRL) == 0) 712 #define IS_MULTICAST(pkt) ((pkt[0] & 01) == 1) 713 #define BUMP_InNUcast(hmep, pkt) \ 714 if (IS_MULTICAST(pkt)) { \ 715 if (IS_BROADCAST(pkt)) { \ 716 hmep->hme_brdcstrcv++; \ 717 } else { \ 718 hmep->hme_multircv++; \ 719 } \ 720 } 721 #define BUMP_OutNUcast(hmep, pkt) \ 722 if (IS_MULTICAST(pkt)) { \ 723 if (IS_BROADCAST(pkt)) { \ 724 hmep->hme_brdcstxmt++; \ 725 } else { \ 726 hmep->hme_multixmt++; \ 727 } \ 728 } 729 730 static int 731 hme_create_prop_from_kw(dev_info_t *dip, char *vpdname, char *vpdstr) 732 { 733 char propstr[80]; 734 int i, needprop = 0; 735 struct ether_addr local_mac; 736 737 if (strcmp(vpdname, "NA") == 0) { 738 (void) strcpy(propstr, "local-mac-address"); 739 needprop = 1; 740 } else if (strcmp(vpdname, "Z0") == 0) { 741 (void) strcpy(propstr, "model"); 742 needprop = 1; 743 } else if (strcmp(vpdname, "Z1") == 0) { 744 (void) strcpy(propstr, "board-model"); 745 needprop = 1; 746 } 747 748 if (needprop == 1) { 749 750 if (strcmp(propstr, "local-mac-address") == 0) { 751 for (i = 0; i < ETHERADDRL; i++) 752 local_mac.ether_addr_octet[i] = 753 (uchar_t)vpdstr[i]; 754 if (ddi_prop_create(DDI_DEV_T_NONE, dip, 755 DDI_PROP_CANSLEEP, propstr, 756 (char *)local_mac.ether_addr_octet, ETHERADDRL) 757 != DDI_SUCCESS) { 758 return (DDI_FAILURE); 759 } 760 } else { 761 if (ddi_prop_create(DDI_DEV_T_NONE, dip, 762 DDI_PROP_CANSLEEP, propstr, vpdstr, 763 strlen(vpdstr)+1) != DDI_SUCCESS) { 764 return (DDI_FAILURE); 765 } 766 } 767 } 768 return (0); 769 } 770 771 /* 772 * Get properties from old VPD 773 * for PCI cards 774 */ 775 static int 776 hme_get_oldvpd_props(dev_info_t *dip, int vpd_base) 777 { 778 struct hme *hmep; 779 int vpd_start, vpd_len, kw_start, kw_len, kw_ptr; 780 char kw_namestr[3]; 781 char kw_fieldstr[256]; 782 int i; 783 784 hmep = ddi_get_driver_private(dip); 785 786 vpd_start = vpd_base; 787 788 if ((GET_ROM8(&hmep->hme_romp[vpd_start]) & 0xff) != 0x90) { 789 return (1); /* error */ 790 } else { 791 vpd_len = 9; 792 } 793 794 /* Get local-mac-address */ 795 kw_start = vpd_start + 3; /* Location of 1st keyword */ 796 kw_ptr = kw_start; 797 while ((kw_ptr - kw_start) < vpd_len) { /* Get all keywords */ 798 kw_namestr[0] = GET_ROM8(&hmep->hme_romp[kw_ptr]); 799 kw_namestr[1] = GET_ROM8(&hmep->hme_romp[kw_ptr+1]); 800 kw_namestr[2] = '\0'; 801 kw_len = (int)(GET_ROM8(&hmep->hme_romp[kw_ptr+2]) & 0xff); 802 for (i = 0, kw_ptr += 3; i < kw_len; i++) 803 kw_fieldstr[i] = GET_ROM8(&hmep->hme_romp[kw_ptr+i]); 804 kw_fieldstr[i] = '\0'; 805 if (hme_create_prop_from_kw(dip, kw_namestr, kw_fieldstr)) { 806 return (DDI_FAILURE); 807 } 808 kw_ptr += kw_len; 809 } /* next keyword */ 810 811 if (ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP, "model", 812 "SUNW,cheerio", strlen("SUNW,cheerio")+1) != DDI_SUCCESS) { 813 return (DDI_FAILURE); 814 } 815 return (0); 816 } 817 818 819 /* 820 * Get properties from new VPD 821 * for CompactPCI cards 822 */ 823 static int 824 hme_get_newvpd_props(dev_info_t *dip, int vpd_base) 825 { 826 struct hme *hmep; 827 int vpd_start, vpd_len, kw_start, kw_len, kw_ptr; 828 char kw_namestr[3]; 829 char kw_fieldstr[256]; 830 int maxvpdsize, i; 831 832 hmep = ddi_get_driver_private(dip); 833 834 maxvpdsize = 1024; /* Real size not known until after it is read */ 835 836 vpd_start = (int)((GET_ROM8(&(hmep->hme_romp[vpd_base+1])) & 0xff) | 837 ((GET_ROM8(&hmep->hme_romp[vpd_base+2]) & 0xff) << 8)) +3; 838 vpd_start = vpd_base + vpd_start; 839 while (vpd_start < (vpd_base + maxvpdsize)) { /* Get all VPDs */ 840 if ((GET_ROM8(&hmep->hme_romp[vpd_start]) & 0xff) != 0x90) { 841 break; /* no VPD found */ 842 } else { 843 vpd_len = (int)((GET_ROM8(&hmep->hme_romp[vpd_start 844 + 1]) & 0xff) | (GET_ROM8(&hmep->hme_romp[vpd_start 845 + 2]) & 0xff) << 8); 846 } 847 /* Get all keywords in this VPD */ 848 kw_start = vpd_start + 3; /* Location of 1st keyword */ 849 kw_ptr = kw_start; 850 while ((kw_ptr - kw_start) < vpd_len) { /* Get all keywords */ 851 kw_namestr[0] = GET_ROM8(&hmep->hme_romp[kw_ptr]); 852 kw_namestr[1] = GET_ROM8(&hmep->hme_romp[kw_ptr+1]); 853 kw_namestr[2] = '\0'; 854 kw_len = 855 (int)(GET_ROM8(&hmep->hme_romp[kw_ptr+2]) & 0xff); 856 for (i = 0, kw_ptr += 3; i < kw_len; i++) 857 kw_fieldstr[i] = 858 GET_ROM8(&hmep->hme_romp[kw_ptr+i]); 859 kw_fieldstr[i] = '\0'; 860 if (hme_create_prop_from_kw(dip, kw_namestr, 861 kw_fieldstr)) { 862 return (DDI_FAILURE); 863 } 864 kw_ptr += kw_len; 865 } /* next keyword */ 866 vpd_start += (vpd_len + 3); 867 } /* next VPD */ 868 return (0); 869 } 870 871 872 /* 873 * Get properties from VPD 874 */ 875 static int 876 hme_get_vpd_props(dev_info_t *dip) 877 { 878 struct hme *hmep; 879 int v0, v1, vpd_base; 880 int i, epromsrchlimit; 881 882 883 hmep = ddi_get_driver_private(dip); 884 885 v0 = (int)(GET_ROM8(&(hmep->hme_romp[0]))); 886 v1 = (int)(GET_ROM8(&(hmep->hme_romp[1]))); 887 v0 = ((v0 & 0xff) << 8 | v1); 888 889 if ((v0 & 0xffff) != 0x55aa) { 890 cmn_err(CE_NOTE, " Valid pci prom not found \n"); 891 return (1); 892 } 893 894 epromsrchlimit = 4096; 895 for (i = 2; i < epromsrchlimit; i++) { 896 /* "PCIR" */ 897 if (((GET_ROM8(&(hmep->hme_romp[i])) & 0xff) == 'P') && 898 ((GET_ROM8(&(hmep->hme_romp[i+1])) & 0xff) == 'C') && 899 ((GET_ROM8(&(hmep->hme_romp[i+2])) & 0xff) == 'I') && 900 ((GET_ROM8(&(hmep->hme_romp[i+3])) & 0xff) == 'R')) { 901 vpd_base = 902 (int)((GET_ROM8(&(hmep->hme_romp[i+8])) & 0xff) | 903 (GET_ROM8(&(hmep->hme_romp[i+9])) & 0xff) << 8); 904 break; /* VPD pointer found */ 905 } 906 } 907 908 /* No VPD found */ 909 if (vpd_base == 0) { 910 cmn_err(CE_NOTE, " Vital Product Data pointer not found \n"); 911 return (1); 912 } 913 914 v0 = (int)(GET_ROM8(&(hmep->hme_romp[vpd_base]))); 915 if (v0 == 0x82) { 916 if (hme_get_newvpd_props(dip, vpd_base)) 917 return (1); 918 return (0); 919 } else if (v0 == 0x90) { 920 /* If we are are SUNW,qfe card, look for the Nth "NA" descr */ 921 if ((GET_ROM8(&hmep->hme_romp[vpd_base + 12]) != 0x79) && 922 GET_ROM8(&hmep->hme_romp[vpd_base + 4 * 12]) == 0x79) { 923 vpd_base += hmep->hme_devno * 12; 924 } 925 if (hme_get_oldvpd_props(dip, vpd_base)) 926 return (1); 927 return (0); 928 } else 929 return (1); /* unknown start byte in VPD */ 930 } 931 932 /* 933 * For x86, the BIOS doesn't map the PCI Rom register for the qfe 934 * cards, so we have to extract it from the ebus bridge that is 935 * function zero of the same device. This is a bit of an ugly hack. 936 * (The ebus bridge leaves the entire ROM mapped at base address 937 * register 0x10.) 938 */ 939 940 typedef struct { 941 struct hme *hmep; 942 dev_info_t *parent; 943 uint8_t bus, dev; 944 ddi_acc_handle_t acch; 945 caddr_t romp; 946 } ebus_rom_t; 947 948 static int 949 hme_mapebusrom(dev_info_t *dip, void *arg) 950 { 951 int *regs; 952 unsigned nregs; 953 int reg; 954 ebus_rom_t *rom = arg; 955 struct hme *hmep = rom->hmep; 956 957 /* 958 * We only want to look at our peers. Skip our parent. 959 */ 960 if (dip == rom->parent) { 961 return (DDI_WALK_PRUNESIB); 962 } 963 964 if (ddi_get_parent(dip) != rom->parent) 965 return (DDI_WALK_CONTINUE); 966 967 if ((ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, 968 "reg", ®s, &nregs)) != DDI_PROP_SUCCESS) { 969 return (DDI_WALK_PRUNECHILD); 970 } 971 972 if (nregs < 1) { 973 ddi_prop_free(regs); 974 return (DDI_WALK_PRUNECHILD); 975 } 976 reg = regs[0]; 977 ddi_prop_free(regs); 978 979 /* 980 * Look for function 0 on our bus and device. If the device doesn't 981 * match, it might be an alternate peer, in which case we don't want 982 * to examine any of its children. 983 */ 984 if ((PCI_REG_BUS_G(reg) != rom->bus) || 985 (PCI_REG_DEV_G(reg) != rom->dev) || 986 (PCI_REG_FUNC_G(reg) != 0)) { 987 return (DDI_WALK_PRUNECHILD); 988 } 989 990 (void) ddi_regs_map_setup(dip, 1, &rom->romp, 0, 0, &hmep->hme_dev_attr, 991 &rom->acch); 992 /* 993 * If we can't map the registers, the caller will notice that 994 * the acch is NULL. 995 */ 996 return (DDI_WALK_TERMINATE); 997 } 998 999 static int 1000 hmeget_promebus(dev_info_t *dip) 1001 { 1002 ebus_rom_t rom; 1003 int *regs; 1004 unsigned nregs; 1005 struct hme *hmep; 1006 1007 hmep = ddi_get_driver_private(dip); 1008 1009 bzero(&rom, sizeof (rom)); 1010 1011 /* 1012 * For x86, the BIOS doesn't map the PCI Rom register for the qfe 1013 * cards, so we have to extract it from the eBus bridge that is 1014 * function zero. This is a bit of an ugly hack. 1015 */ 1016 if ((ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, 1017 "reg", ®s, &nregs)) != DDI_PROP_SUCCESS) { 1018 return (DDI_FAILURE); 1019 } 1020 1021 if (nregs < 5) { 1022 ddi_prop_free(regs); 1023 return (DDI_FAILURE); 1024 } 1025 rom.hmep = hmep; 1026 rom.bus = PCI_REG_BUS_G(regs[0]); 1027 rom.dev = PCI_REG_DEV_G(regs[0]); 1028 hmep->hme_devno = rom.dev; 1029 rom.parent = ddi_get_parent(dip); 1030 1031 /* 1032 * The implementation of ddi_walk_devs says that we must not 1033 * be called during autoconfiguration. However, it turns out 1034 * that it is safe to call this during our attach routine, 1035 * because we are not a nexus device. 1036 * 1037 * Previously we rooted our search at our immediate parent, 1038 * but this triggered an assertion panic in debug kernels. 1039 */ 1040 ddi_walk_devs(ddi_root_node(), hme_mapebusrom, &rom); 1041 1042 if (rom.acch) { 1043 hmep->hme_romh = rom.acch; 1044 hmep->hme_romp = (unsigned char *)rom.romp; 1045 return (DDI_SUCCESS); 1046 } 1047 return (DDI_FAILURE); 1048 } 1049 1050 static int 1051 hmeget_promprops(dev_info_t *dip) 1052 { 1053 struct hme *hmep; 1054 int rom_bar; 1055 ddi_acc_handle_t cfg_handle; 1056 struct { 1057 uint16_t vendorid; 1058 uint16_t devid; 1059 uint16_t command; 1060 uint16_t status; 1061 uint32_t junk1; 1062 uint8_t cache_line; 1063 uint8_t latency; 1064 uint8_t header; 1065 uint8_t bist; 1066 uint32_t base; 1067 uint32_t base14; 1068 uint32_t base18; 1069 uint32_t base1c; 1070 uint32_t base20; 1071 uint32_t base24; 1072 uint32_t base28; 1073 uint32_t base2c; 1074 uint32_t base30; 1075 } *cfg_ptr; 1076 1077 hmep = ddi_get_driver_private(dip); 1078 1079 1080 /* 1081 * map configuration space 1082 */ 1083 if (ddi_regs_map_setup(hmep->dip, 0, (caddr_t *)&cfg_ptr, 1084 0, 0, &hmep->hme_dev_attr, &cfg_handle)) { 1085 return (DDI_FAILURE); 1086 } 1087 1088 /* 1089 * Enable bus-master and memory accesses 1090 */ 1091 ddi_put16(cfg_handle, &cfg_ptr->command, 1092 PCI_COMM_SERR_ENABLE | PCI_COMM_PARITY_DETECT | 1093 PCI_COMM_MAE | PCI_COMM_ME); 1094 1095 /* 1096 * Enable rom accesses 1097 */ 1098 rom_bar = ddi_get32(cfg_handle, &cfg_ptr->base30); 1099 ddi_put32(cfg_handle, &cfg_ptr->base30, rom_bar | 1); 1100 1101 1102 if ((ddi_regs_map_setup(dip, 2, (caddr_t *)&(hmep->hme_romp), 0, 0, 1103 &hmep->hme_dev_attr, &hmep->hme_romh) != DDI_SUCCESS) && 1104 (hmeget_promebus(dip) != DDI_SUCCESS)) { 1105 1106 if (cfg_ptr) 1107 ddi_regs_map_free(&cfg_handle); 1108 return (DDI_FAILURE); 1109 } else { 1110 if (hme_get_vpd_props(dip)) 1111 return (DDI_FAILURE); 1112 } 1113 if (hmep->hme_romp) 1114 ddi_regs_map_free(&hmep->hme_romh); 1115 if (cfg_ptr) 1116 ddi_regs_map_free(&cfg_handle); 1117 return (DDI_SUCCESS); 1118 1119 } 1120 1121 static void 1122 hmeget_hm_rev_property(struct hme *hmep) 1123 { 1124 int hm_rev; 1125 1126 1127 hm_rev = hmep->asic_rev; 1128 switch (hm_rev) { 1129 case HME_2P1_REVID: 1130 case HME_2P1_REVID_OBP: 1131 HME_FAULT_MSG2(hmep, SEVERITY_NONE, DISPLAY_MSG, 1132 "SBus 2.1 Found (Rev Id = %x)", hm_rev); 1133 hmep->hme_frame_enable = 1; 1134 break; 1135 1136 case HME_2P0_REVID: 1137 HME_FAULT_MSG2(hmep, SEVERITY_NONE, DISPLAY_MSG, 1138 "SBus 2.0 Found (Rev Id = %x)", hm_rev); 1139 break; 1140 1141 case HME_1C0_REVID: 1142 HME_FAULT_MSG2(hmep, SEVERITY_NONE, DISPLAY_MSG, 1143 "PCI IO 1.0 Found (Rev Id = %x)", hm_rev); 1144 break; 1145 1146 default: 1147 HME_FAULT_MSG3(hmep, SEVERITY_NONE, DISPLAY_MSG, 1148 "%s (Rev Id = %x) Found", 1149 (hm_rev == HME_2C0_REVID) ? "PCI IO 2.0" : "Sbus", hm_rev); 1150 hmep->hme_frame_enable = 1; 1151 hmep->hme_lance_mode_enable = 1; 1152 hmep->hme_rxcv_enable = 1; 1153 break; 1154 } 1155 } 1156 1157 /* 1158 * Interface exists: make available by filling in network interface 1159 * record. System will initialize the interface when it is ready 1160 * to accept packets. 1161 */ 1162 int 1163 hmeattach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1164 { 1165 struct hme *hmep; 1166 mac_register_t *macp = NULL; 1167 int regno; 1168 int hm_rev = 0; 1169 int prop_len = sizeof (int); 1170 ddi_acc_handle_t cfg_handle; 1171 struct { 1172 uint16_t vendorid; 1173 uint16_t devid; 1174 uint16_t command; 1175 uint16_t status; 1176 uint8_t revid; 1177 uint8_t j1; 1178 uint16_t j2; 1179 } *cfg_ptr; 1180 1181 switch (cmd) { 1182 case DDI_ATTACH: 1183 break; 1184 1185 case DDI_RESUME: 1186 if ((hmep = ddi_get_driver_private(dip)) == NULL) 1187 return (DDI_FAILURE); 1188 1189 hmep->hme_flags &= ~HMESUSPENDED; 1190 1191 mii_resume(hmep->hme_mii); 1192 1193 if (hmep->hme_started) 1194 (void) hmeinit(hmep); 1195 return (DDI_SUCCESS); 1196 1197 default: 1198 return (DDI_FAILURE); 1199 } 1200 1201 /* 1202 * Allocate soft device data structure 1203 */ 1204 hmep = kmem_zalloc(sizeof (*hmep), KM_SLEEP); 1205 1206 /* 1207 * Might as well set up elements of data structure 1208 */ 1209 hmep->dip = dip; 1210 hmep->instance = ddi_get_instance(dip); 1211 hmep->pagesize = ddi_ptob(dip, (ulong_t)1); /* IOMMU PSize */ 1212 1213 /* 1214 * Might as well setup the driver private 1215 * structure as part of the dip. 1216 */ 1217 ddi_set_driver_private(dip, hmep); 1218 1219 /* 1220 * Reject this device if it's in a slave-only slot. 1221 */ 1222 if (ddi_slaveonly(dip) == DDI_SUCCESS) { 1223 HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG, 1224 "Dev not used - dev in slave only slot"); 1225 goto error_state; 1226 } 1227 1228 /* 1229 * Map in the device registers. 1230 * 1231 * Reg # 0 is the Global register set 1232 * Reg # 1 is the ETX register set 1233 * Reg # 2 is the ERX register set 1234 * Reg # 3 is the BigMAC register set. 1235 * Reg # 4 is the MIF register set 1236 */ 1237 if (ddi_dev_nregs(dip, ®no) != (DDI_SUCCESS)) { 1238 HME_FAULT_MSG2(hmep, SEVERITY_HIGH, INIT_MSG, 1239 ddi_nregs_fail_msg, regno); 1240 goto error_state; 1241 } 1242 1243 switch (regno) { 1244 case 5: 1245 hmep->hme_cheerio_mode = 0; 1246 break; 1247 case 2: 1248 case 3: /* for hot swap/plug, there will be 3 entries in "reg" prop */ 1249 hmep->hme_cheerio_mode = 1; 1250 break; 1251 default: 1252 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 1253 bad_num_regs_msg); 1254 goto error_state; 1255 } 1256 1257 /* Initialize device attributes structure */ 1258 hmep->hme_dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 1259 1260 if (hmep->hme_cheerio_mode) 1261 hmep->hme_dev_attr.devacc_attr_endian_flags = 1262 DDI_STRUCTURE_LE_ACC; 1263 else 1264 hmep->hme_dev_attr.devacc_attr_endian_flags = 1265 DDI_STRUCTURE_BE_ACC; 1266 1267 hmep->hme_dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 1268 1269 if (hmep->hme_cheerio_mode) { 1270 uint8_t oldLT; 1271 uint8_t newLT = 0; 1272 dev_info_t *pdip; 1273 const char *pdrvname; 1274 1275 /* 1276 * Map the PCI config space 1277 */ 1278 if (pci_config_setup(dip, &hmep->pci_config_handle) != 1279 DDI_SUCCESS) { 1280 HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG, 1281 "pci_config_setup() failed.."); 1282 goto error_state; 1283 } 1284 1285 if (ddi_regs_map_setup(dip, 1, 1286 (caddr_t *)&(hmep->hme_globregp), 0, 0, 1287 &hmep->hme_dev_attr, &hmep->hme_globregh)) { 1288 HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG, 1289 mregs_4global_reg_fail_msg); 1290 goto error_unmap; 1291 } 1292 hmep->hme_etxregh = hmep->hme_erxregh = hmep->hme_bmacregh = 1293 hmep->hme_mifregh = hmep->hme_globregh; 1294 1295 hmep->hme_etxregp = 1296 (void *)(((caddr_t)hmep->hme_globregp) + 0x2000); 1297 hmep->hme_erxregp = 1298 (void *)(((caddr_t)hmep->hme_globregp) + 0x4000); 1299 hmep->hme_bmacregp = 1300 (void *)(((caddr_t)hmep->hme_globregp) + 0x6000); 1301 hmep->hme_mifregp = 1302 (void *)(((caddr_t)hmep->hme_globregp) + 0x7000); 1303 1304 /* 1305 * Get parent pci bridge info. 1306 */ 1307 pdip = ddi_get_parent(dip); 1308 pdrvname = ddi_driver_name(pdip); 1309 1310 oldLT = pci_config_get8(hmep->pci_config_handle, 1311 PCI_CONF_LATENCY_TIMER); 1312 /* 1313 * Honor value set in /etc/system 1314 * "set hme:pci_latency_timer=0xYY" 1315 */ 1316 if (pci_latency_timer) 1317 newLT = pci_latency_timer; 1318 /* 1319 * Modify LT for simba 1320 */ 1321 else if (strcmp("simba", pdrvname) == 0) 1322 newLT = 0xf0; 1323 /* 1324 * Ensure minimum cheerio latency timer of 0x50 1325 * Usually OBP or pci bridge should set this value 1326 * based on cheerio 1327 * min_grant * 8(33MHz) = 0x50 = 0xa * 0x8 1328 * Some system set cheerio LT at 0x40 1329 */ 1330 else if (oldLT < 0x40) 1331 newLT = 0x50; 1332 1333 /* 1334 * Now program cheerio's pci latency timer with newLT 1335 */ 1336 if (newLT) 1337 pci_config_put8(hmep->pci_config_handle, 1338 PCI_CONF_LATENCY_TIMER, (uchar_t)newLT); 1339 } else { /* Map register sets */ 1340 if (ddi_regs_map_setup(dip, 0, 1341 (caddr_t *)&(hmep->hme_globregp), 0, 0, 1342 &hmep->hme_dev_attr, &hmep->hme_globregh)) { 1343 HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG, 1344 mregs_4global_reg_fail_msg); 1345 goto error_state; 1346 } 1347 if (ddi_regs_map_setup(dip, 1, 1348 (caddr_t *)&(hmep->hme_etxregp), 0, 0, 1349 &hmep->hme_dev_attr, &hmep->hme_etxregh)) { 1350 HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG, 1351 mregs_4etx_reg_fail_msg); 1352 goto error_unmap; 1353 } 1354 if (ddi_regs_map_setup(dip, 2, 1355 (caddr_t *)&(hmep->hme_erxregp), 0, 0, 1356 &hmep->hme_dev_attr, &hmep->hme_erxregh)) { 1357 HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG, 1358 mregs_4erx_reg_fail_msg); 1359 goto error_unmap; 1360 } 1361 if (ddi_regs_map_setup(dip, 3, 1362 (caddr_t *)&(hmep->hme_bmacregp), 0, 0, 1363 &hmep->hme_dev_attr, &hmep->hme_bmacregh)) { 1364 HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG, 1365 mregs_4bmac_reg_fail_msg); 1366 goto error_unmap; 1367 } 1368 1369 if (ddi_regs_map_setup(dip, 4, 1370 (caddr_t *)&(hmep->hme_mifregp), 0, 0, 1371 &hmep->hme_dev_attr, &hmep->hme_mifregh)) { 1372 HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG, 1373 mregs_4mif_reg_fail_msg); 1374 goto error_unmap; 1375 } 1376 } /* Endif cheerio_mode */ 1377 1378 /* 1379 * Based on the hm-rev, set some capabilities 1380 * Set up default capabilities for HM 2.0 1381 */ 1382 hmep->hme_frame_enable = 0; 1383 hmep->hme_lance_mode_enable = 0; 1384 hmep->hme_rxcv_enable = 0; 1385 1386 /* NEW routine to get the properties */ 1387 1388 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, hmep->dip, 0, "hm-rev", 1389 (caddr_t)&hm_rev, &prop_len) == DDI_PROP_SUCCESS) { 1390 1391 hmep->asic_rev = hm_rev; 1392 hmeget_hm_rev_property(hmep); 1393 } else { 1394 /* 1395 * hm_rev property not found so, this is 1396 * case of hot insertion of card without interpreting fcode. 1397 * Get it from revid in config space after mapping it. 1398 */ 1399 if (ddi_regs_map_setup(hmep->dip, 0, (caddr_t *)&cfg_ptr, 1400 0, 0, &hmep->hme_dev_attr, &cfg_handle)) { 1401 return (DDI_FAILURE); 1402 } 1403 /* 1404 * Since this is cheerio-based PCI card, we write 0xC in the 1405 * top 4 bits(4-7) of hm-rev and retain the bottom(0-3) bits 1406 * for Cheerio version(1.0 or 2.0 = 0xC0 or 0xC1) 1407 */ 1408 hm_rev = ddi_get8(cfg_handle, &cfg_ptr->revid); 1409 hm_rev = HME_1C0_REVID | (hm_rev & HME_REV_VERS_MASK); 1410 hmep->asic_rev = hm_rev; 1411 if (ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP, 1412 "hm-rev", (caddr_t)&hm_rev, sizeof (hm_rev)) != 1413 DDI_SUCCESS) { 1414 HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, AUTOCONFIG_MSG, 1415 "ddi_prop_create error for hm_rev"); 1416 } 1417 ddi_regs_map_free(&cfg_handle); 1418 1419 hmeget_hm_rev_property(hmep); 1420 1421 /* get info via VPD */ 1422 if (hmeget_promprops(dip) != DDI_SUCCESS) { 1423 HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, AUTOCONFIG_MSG, 1424 "no promprops"); 1425 } 1426 } 1427 1428 if (ddi_intr_hilevel(dip, 0)) { 1429 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, NFATAL_ERR_MSG, 1430 " high-level interrupts are not supported"); 1431 goto error_unmap; 1432 } 1433 1434 /* 1435 * Get intr. block cookie so that mutex locks can be initialized. 1436 */ 1437 if (ddi_get_iblock_cookie(dip, 0, &hmep->hme_cookie) != DDI_SUCCESS) 1438 goto error_unmap; 1439 1440 /* 1441 * Initialize mutex's for this device. 1442 */ 1443 mutex_init(&hmep->hme_xmitlock, NULL, MUTEX_DRIVER, hmep->hme_cookie); 1444 mutex_init(&hmep->hme_intrlock, NULL, MUTEX_DRIVER, hmep->hme_cookie); 1445 1446 /* 1447 * Quiesce the hardware. 1448 */ 1449 (void) hmestop(hmep); 1450 1451 /* 1452 * Add interrupt to system 1453 */ 1454 if (ddi_add_intr(dip, 0, (ddi_iblock_cookie_t *)NULL, 1455 (ddi_idevice_cookie_t *)NULL, hmeintr, (caddr_t)hmep)) { 1456 HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG, 1457 add_intr_fail_msg); 1458 goto error_mutex; 1459 } 1460 1461 /* 1462 * Set up the ethernet mac address. 1463 */ 1464 hme_setup_mac_address(hmep, dip); 1465 1466 if (!hmeinit_xfer_params(hmep)) 1467 goto error_intr; 1468 1469 if (hmeburstsizes(hmep) == DDI_FAILURE) { 1470 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, burst_size_msg); 1471 goto error_intr; 1472 } 1473 1474 if (hmeallocthings(hmep) != DDI_SUCCESS) { 1475 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, CONFIG_MSG, 1476 "resource allocation failed"); 1477 goto error_intr; 1478 } 1479 1480 if (hmeallocbufs(hmep) != DDI_SUCCESS) { 1481 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, CONFIG_MSG, 1482 "buffer allocation failed"); 1483 goto error_intr; 1484 } 1485 1486 hmestatinit(hmep); 1487 1488 /* our external (preferred) PHY is at address 0 */ 1489 (void) ddi_prop_update_int(DDI_DEV_T_NONE, dip, "first-phy", 0); 1490 1491 hmep->hme_mii = mii_alloc(hmep, dip, &hme_mii_ops); 1492 if (hmep->hme_mii == NULL) { 1493 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, CONFIG_MSG, 1494 "mii_alloc failed"); 1495 goto error_intr; 1496 } 1497 /* force a probe for the PHY */ 1498 mii_probe(hmep->hme_mii); 1499 1500 if ((macp = mac_alloc(MAC_VERSION)) == NULL) { 1501 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, CONFIG_MSG, 1502 "mac_alloc failed"); 1503 goto error_intr; 1504 } 1505 macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 1506 macp->m_driver = hmep; 1507 macp->m_dip = dip; 1508 macp->m_src_addr = hmep->hme_ouraddr.ether_addr_octet; 1509 macp->m_callbacks = &hme_m_callbacks; 1510 macp->m_min_sdu = 0; 1511 macp->m_max_sdu = ETHERMTU; 1512 macp->m_margin = VLAN_TAGSZ; 1513 macp->m_priv_props = hme_priv_prop; 1514 if (mac_register(macp, &hmep->hme_mh) != 0) { 1515 mac_free(macp); 1516 goto error_intr; 1517 } 1518 1519 mac_free(macp); 1520 1521 ddi_report_dev(dip); 1522 return (DDI_SUCCESS); 1523 1524 /* 1525 * Failure Exit 1526 */ 1527 1528 error_intr: 1529 if (hmep->hme_cookie) 1530 ddi_remove_intr(dip, 0, (ddi_iblock_cookie_t)0); 1531 1532 if (hmep->hme_mii) 1533 mii_free(hmep->hme_mii); 1534 1535 error_mutex: 1536 mutex_destroy(&hmep->hme_xmitlock); 1537 mutex_destroy(&hmep->hme_intrlock); 1538 1539 error_unmap: 1540 if (hmep->hme_globregh) 1541 ddi_regs_map_free(&hmep->hme_globregh); 1542 if (hmep->hme_cheerio_mode == 0) { 1543 if (hmep->hme_etxregh) 1544 ddi_regs_map_free(&hmep->hme_etxregh); 1545 if (hmep->hme_erxregh) 1546 ddi_regs_map_free(&hmep->hme_erxregh); 1547 if (hmep->hme_bmacregh) 1548 ddi_regs_map_free(&hmep->hme_bmacregh); 1549 if (hmep->hme_mifregh) 1550 ddi_regs_map_free(&hmep->hme_mifregh); 1551 } else { 1552 if (hmep->pci_config_handle) 1553 (void) pci_config_teardown(&hmep->pci_config_handle); 1554 hmep->hme_etxregh = hmep->hme_erxregh = hmep->hme_bmacregh = 1555 hmep->hme_mifregh = hmep->hme_globregh = NULL; 1556 } 1557 1558 error_state: 1559 hmefreethings(hmep); 1560 hmefreebufs(hmep); 1561 1562 if (hmep) { 1563 kmem_free((caddr_t)hmep, sizeof (*hmep)); 1564 ddi_set_driver_private(dip, NULL); 1565 } 1566 1567 return (DDI_FAILURE); 1568 } 1569 1570 int 1571 hmedetach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1572 { 1573 struct hme *hmep; 1574 1575 if ((hmep = ddi_get_driver_private(dip)) == NULL) 1576 return (DDI_FAILURE); 1577 1578 switch (cmd) { 1579 case DDI_DETACH: 1580 break; 1581 1582 case DDI_SUSPEND: 1583 mii_suspend(hmep->hme_mii); 1584 hmep->hme_flags |= HMESUSPENDED; 1585 hmeuninit(hmep); 1586 return (DDI_SUCCESS); 1587 1588 default: 1589 return (DDI_FAILURE); 1590 } 1591 1592 1593 if (mac_unregister(hmep->hme_mh) != 0) { 1594 return (DDI_FAILURE); 1595 } 1596 1597 /* 1598 * Make driver quiescent, we don't want to prevent the 1599 * detach on failure. Note that this should be redundant, 1600 * since mac_stop should already have called hmeuninit(). 1601 */ 1602 if (!(hmep->hme_flags & HMESUSPENDED)) { 1603 (void) hmestop(hmep); 1604 } 1605 1606 if (hmep->hme_mii) 1607 mii_free(hmep->hme_mii); 1608 1609 /* 1610 * Remove instance of the intr 1611 */ 1612 ddi_remove_intr(dip, 0, (ddi_iblock_cookie_t)0); 1613 1614 /* 1615 * Unregister kstats. 1616 */ 1617 if (hmep->hme_ksp != NULL) 1618 kstat_delete(hmep->hme_ksp); 1619 if (hmep->hme_intrstats != NULL) 1620 kstat_delete(hmep->hme_intrstats); 1621 1622 hmep->hme_ksp = NULL; 1623 hmep->hme_intrstats = NULL; 1624 1625 /* 1626 * Destroy all mutexes and data structures allocated during 1627 * attach time. 1628 * 1629 * Note: at this time we should be the only thread accessing 1630 * the structures for this instance. 1631 */ 1632 1633 if (hmep->hme_globregh) 1634 ddi_regs_map_free(&hmep->hme_globregh); 1635 if (hmep->hme_cheerio_mode == 0) { 1636 if (hmep->hme_etxregh) 1637 ddi_regs_map_free(&hmep->hme_etxregh); 1638 if (hmep->hme_erxregh) 1639 ddi_regs_map_free(&hmep->hme_erxregh); 1640 if (hmep->hme_bmacregh) 1641 ddi_regs_map_free(&hmep->hme_bmacregh); 1642 if (hmep->hme_mifregh) 1643 ddi_regs_map_free(&hmep->hme_mifregh); 1644 } else { 1645 if (hmep->pci_config_handle) 1646 (void) pci_config_teardown(&hmep->pci_config_handle); 1647 hmep->hme_etxregh = hmep->hme_erxregh = hmep->hme_bmacregh = 1648 hmep->hme_mifregh = hmep->hme_globregh = NULL; 1649 } 1650 1651 mutex_destroy(&hmep->hme_xmitlock); 1652 mutex_destroy(&hmep->hme_intrlock); 1653 1654 hmefreethings(hmep); 1655 hmefreebufs(hmep); 1656 1657 ddi_set_driver_private(dip, NULL); 1658 kmem_free(hmep, sizeof (struct hme)); 1659 1660 return (DDI_SUCCESS); 1661 } 1662 1663 int 1664 hmequiesce(dev_info_t *dip) 1665 { 1666 struct hme *hmep; 1667 1668 if ((hmep = ddi_get_driver_private(dip)) == NULL) 1669 return (DDI_FAILURE); 1670 1671 (void) hmestop(hmep); 1672 return (DDI_SUCCESS); 1673 } 1674 1675 static boolean_t 1676 hmeinit_xfer_params(struct hme *hmep) 1677 { 1678 int hme_ipg1_conf, hme_ipg2_conf; 1679 int hme_ipg0_conf, hme_lance_mode_conf; 1680 int prop_len = sizeof (int); 1681 dev_info_t *dip; 1682 1683 dip = hmep->dip; 1684 1685 /* 1686 * Set up the start-up values for user-configurable parameters 1687 * Get the values from the global variables first. 1688 * Use the MASK to limit the value to allowed maximum. 1689 */ 1690 hmep->hme_ipg1 = hme_ipg1 & HME_MASK_8BIT; 1691 hmep->hme_ipg2 = hme_ipg2 & HME_MASK_8BIT; 1692 hmep->hme_ipg0 = hme_ipg0 & HME_MASK_5BIT; 1693 1694 /* 1695 * Get the parameter values configured in .conf file. 1696 */ 1697 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg1", 1698 (caddr_t)&hme_ipg1_conf, &prop_len) == DDI_PROP_SUCCESS) { 1699 hmep->hme_ipg1 = hme_ipg1_conf & HME_MASK_8BIT; 1700 } 1701 1702 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg2", 1703 (caddr_t)&hme_ipg2_conf, &prop_len) == DDI_PROP_SUCCESS) { 1704 hmep->hme_ipg2 = hme_ipg2_conf & HME_MASK_8BIT; 1705 } 1706 1707 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg0", 1708 (caddr_t)&hme_ipg0_conf, &prop_len) == DDI_PROP_SUCCESS) { 1709 hmep->hme_ipg0 = hme_ipg0_conf & HME_MASK_5BIT; 1710 } 1711 1712 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "lance_mode", 1713 (caddr_t)&hme_lance_mode_conf, &prop_len) == DDI_PROP_SUCCESS) { 1714 hmep->hme_lance_mode = hme_lance_mode_conf & HME_MASK_1BIT; 1715 } 1716 1717 return (B_TRUE); 1718 } 1719 1720 /* 1721 * Return 0 upon success, 1 on failure. 1722 */ 1723 static uint_t 1724 hmestop(struct hme *hmep) 1725 { 1726 /* 1727 * Disable the Tx dma engine. 1728 */ 1729 PUT_ETXREG(config, (GET_ETXREG(config) & ~HMET_CONFIG_TXDMA_EN)); 1730 HMEDELAY(((GET_ETXREG(state_mach) & 0x1f) == 0x1), HMEMAXRSTDELAY); 1731 1732 /* 1733 * Disable the Rx dma engine. 1734 */ 1735 PUT_ERXREG(config, (GET_ERXREG(config) & ~HMER_CONFIG_RXDMA_EN)); 1736 HMEDELAY(((GET_ERXREG(state_mach) & 0x3f) == 0), HMEMAXRSTDELAY); 1737 1738 /* 1739 * By this time all things should be quiet, so hit the 1740 * chip with a reset. 1741 */ 1742 PUT_GLOBREG(reset, HMEG_RESET_GLOBAL); 1743 1744 HMEDELAY((GET_GLOBREG(reset) == 0), HMEMAXRSTDELAY); 1745 if (GET_GLOBREG(reset)) { 1746 return (1); 1747 } 1748 1749 CHECK_GLOBREG(); 1750 return (0); 1751 } 1752 1753 static int 1754 hmestat_kstat_update(kstat_t *ksp, int rw) 1755 { 1756 struct hme *hmep; 1757 struct hmekstat *hkp; 1758 1759 hmep = (struct hme *)ksp->ks_private; 1760 hkp = (struct hmekstat *)ksp->ks_data; 1761 1762 if (rw != KSTAT_READ) 1763 return (EACCES); 1764 1765 /* 1766 * Update all the stats by reading all the counter registers. 1767 * Counter register stats are not updated till they overflow 1768 * and interrupt. 1769 */ 1770 1771 mutex_enter(&hmep->hme_xmitlock); 1772 if (hmep->hme_flags & HMERUNNING) { 1773 hmereclaim(hmep); 1774 hmesavecntrs(hmep); 1775 } 1776 mutex_exit(&hmep->hme_xmitlock); 1777 1778 hkp->hk_cvc.value.ul = hmep->hme_cvc; 1779 hkp->hk_lenerr.value.ul = hmep->hme_lenerr; 1780 hkp->hk_buff.value.ul = hmep->hme_buff; 1781 hkp->hk_missed.value.ul = hmep->hme_missed; 1782 hkp->hk_allocbfail.value.ul = hmep->hme_allocbfail; 1783 hkp->hk_babl.value.ul = hmep->hme_babl; 1784 hkp->hk_tmder.value.ul = hmep->hme_tmder; 1785 hkp->hk_txlaterr.value.ul = hmep->hme_txlaterr; 1786 hkp->hk_rxlaterr.value.ul = hmep->hme_rxlaterr; 1787 hkp->hk_slvparerr.value.ul = hmep->hme_slvparerr; 1788 hkp->hk_txparerr.value.ul = hmep->hme_txparerr; 1789 hkp->hk_rxparerr.value.ul = hmep->hme_rxparerr; 1790 hkp->hk_slverrack.value.ul = hmep->hme_slverrack; 1791 hkp->hk_txerrack.value.ul = hmep->hme_txerrack; 1792 hkp->hk_rxerrack.value.ul = hmep->hme_rxerrack; 1793 hkp->hk_txtagerr.value.ul = hmep->hme_txtagerr; 1794 hkp->hk_rxtagerr.value.ul = hmep->hme_rxtagerr; 1795 hkp->hk_eoperr.value.ul = hmep->hme_eoperr; 1796 hkp->hk_notmds.value.ul = hmep->hme_notmds; 1797 hkp->hk_notbufs.value.ul = hmep->hme_notbufs; 1798 hkp->hk_norbufs.value.ul = hmep->hme_norbufs; 1799 1800 /* 1801 * Debug kstats 1802 */ 1803 hkp->hk_inits.value.ul = hmep->inits; 1804 hkp->hk_phyfail.value.ul = hmep->phyfail; 1805 1806 /* 1807 * xcvr kstats 1808 */ 1809 hkp->hk_asic_rev.value.ul = hmep->asic_rev; 1810 1811 return (0); 1812 } 1813 1814 static void 1815 hmestatinit(struct hme *hmep) 1816 { 1817 struct kstat *ksp; 1818 struct hmekstat *hkp; 1819 const char *driver; 1820 int instance; 1821 char buf[16]; 1822 1823 instance = hmep->instance; 1824 driver = ddi_driver_name(hmep->dip); 1825 1826 if ((ksp = kstat_create(driver, instance, 1827 "driver_info", "net", KSTAT_TYPE_NAMED, 1828 sizeof (struct hmekstat) / sizeof (kstat_named_t), 0)) == NULL) { 1829 HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, INIT_MSG, 1830 "kstat_create failed"); 1831 return; 1832 } 1833 1834 (void) snprintf(buf, sizeof (buf), "%sc%d", driver, instance); 1835 hmep->hme_intrstats = kstat_create(driver, instance, buf, "controller", 1836 KSTAT_TYPE_INTR, 1, KSTAT_FLAG_PERSISTENT); 1837 if (hmep->hme_intrstats) 1838 kstat_install(hmep->hme_intrstats); 1839 1840 hmep->hme_ksp = ksp; 1841 hkp = (struct hmekstat *)ksp->ks_data; 1842 kstat_named_init(&hkp->hk_cvc, "code_violations", 1843 KSTAT_DATA_ULONG); 1844 kstat_named_init(&hkp->hk_lenerr, "len_errors", 1845 KSTAT_DATA_ULONG); 1846 kstat_named_init(&hkp->hk_buff, "buff", 1847 KSTAT_DATA_ULONG); 1848 kstat_named_init(&hkp->hk_missed, "missed", 1849 KSTAT_DATA_ULONG); 1850 kstat_named_init(&hkp->hk_nocanput, "nocanput", 1851 KSTAT_DATA_ULONG); 1852 kstat_named_init(&hkp->hk_allocbfail, "allocbfail", 1853 KSTAT_DATA_ULONG); 1854 kstat_named_init(&hkp->hk_babl, "babble", 1855 KSTAT_DATA_ULONG); 1856 kstat_named_init(&hkp->hk_tmder, "tmd_error", 1857 KSTAT_DATA_ULONG); 1858 kstat_named_init(&hkp->hk_txlaterr, "tx_late_error", 1859 KSTAT_DATA_ULONG); 1860 kstat_named_init(&hkp->hk_rxlaterr, "rx_late_error", 1861 KSTAT_DATA_ULONG); 1862 kstat_named_init(&hkp->hk_slvparerr, "slv_parity_error", 1863 KSTAT_DATA_ULONG); 1864 kstat_named_init(&hkp->hk_txparerr, "tx_parity_error", 1865 KSTAT_DATA_ULONG); 1866 kstat_named_init(&hkp->hk_rxparerr, "rx_parity_error", 1867 KSTAT_DATA_ULONG); 1868 kstat_named_init(&hkp->hk_slverrack, "slv_error_ack", 1869 KSTAT_DATA_ULONG); 1870 kstat_named_init(&hkp->hk_txerrack, "tx_error_ack", 1871 KSTAT_DATA_ULONG); 1872 kstat_named_init(&hkp->hk_rxerrack, "rx_error_ack", 1873 KSTAT_DATA_ULONG); 1874 kstat_named_init(&hkp->hk_txtagerr, "tx_tag_error", 1875 KSTAT_DATA_ULONG); 1876 kstat_named_init(&hkp->hk_rxtagerr, "rx_tag_error", 1877 KSTAT_DATA_ULONG); 1878 kstat_named_init(&hkp->hk_eoperr, "eop_error", 1879 KSTAT_DATA_ULONG); 1880 kstat_named_init(&hkp->hk_notmds, "no_tmds", 1881 KSTAT_DATA_ULONG); 1882 kstat_named_init(&hkp->hk_notbufs, "no_tbufs", 1883 KSTAT_DATA_ULONG); 1884 kstat_named_init(&hkp->hk_norbufs, "no_rbufs", 1885 KSTAT_DATA_ULONG); 1886 1887 /* 1888 * Debugging kstats 1889 */ 1890 kstat_named_init(&hkp->hk_inits, "inits", 1891 KSTAT_DATA_ULONG); 1892 kstat_named_init(&hkp->hk_phyfail, "phy_failures", 1893 KSTAT_DATA_ULONG); 1894 1895 /* 1896 * xcvr kstats 1897 */ 1898 kstat_named_init(&hkp->hk_asic_rev, "asic_rev", 1899 KSTAT_DATA_ULONG); 1900 1901 ksp->ks_update = hmestat_kstat_update; 1902 ksp->ks_private = (void *) hmep; 1903 kstat_install(ksp); 1904 } 1905 1906 int 1907 hme_m_getprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz, 1908 void *val) 1909 { 1910 struct hme *hmep = arg; 1911 int value; 1912 int rv; 1913 1914 rv = mii_m_getprop(hmep->hme_mii, name, num, sz, val); 1915 if (rv != ENOTSUP) 1916 return (rv); 1917 1918 switch (num) { 1919 case MAC_PROP_PRIVATE: 1920 break; 1921 default: 1922 return (ENOTSUP); 1923 } 1924 1925 if (strcmp(name, "_ipg0") == 0) { 1926 value = hmep->hme_ipg0; 1927 } else if (strcmp(name, "_ipg1") == 0) { 1928 value = hmep->hme_ipg1; 1929 } else if (strcmp(name, "_ipg2") == 0) { 1930 value = hmep->hme_ipg2; 1931 } else if (strcmp(name, "_lance_mode") == 0) { 1932 value = hmep->hme_lance_mode; 1933 } else { 1934 return (ENOTSUP); 1935 } 1936 (void) snprintf(val, sz, "%d", value); 1937 return (0); 1938 } 1939 1940 static void 1941 hme_m_propinfo(void *arg, const char *name, mac_prop_id_t num, 1942 mac_prop_info_handle_t mph) 1943 { 1944 struct hme *hmep = arg; 1945 1946 mii_m_propinfo(hmep->hme_mii, name, num, mph); 1947 1948 switch (num) { 1949 case MAC_PROP_PRIVATE: { 1950 char valstr[64]; 1951 int default_val; 1952 1953 if (strcmp(name, "_ipg0") == 0) { 1954 default_val = hme_ipg0; 1955 } else if (strcmp(name, "_ipg1") == 0) { 1956 default_val = hme_ipg1; 1957 } else if (strcmp(name, "_ipg2") == 0) { 1958 default_val = hme_ipg2; 1959 } if (strcmp(name, "_lance_mode") == 0) { 1960 default_val = hme_lance_mode; 1961 } else { 1962 return; 1963 } 1964 1965 (void) snprintf(valstr, sizeof (valstr), "%d", default_val); 1966 mac_prop_info_set_default_str(mph, valstr); 1967 break; 1968 } 1969 } 1970 } 1971 1972 int 1973 hme_m_setprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz, 1974 const void *val) 1975 { 1976 struct hme *hmep = arg; 1977 int rv; 1978 long lval; 1979 boolean_t init = B_FALSE; 1980 1981 rv = mii_m_setprop(hmep->hme_mii, name, num, sz, val); 1982 if (rv != ENOTSUP) 1983 return (rv); 1984 rv = 0; 1985 1986 switch (num) { 1987 case MAC_PROP_PRIVATE: 1988 break; 1989 default: 1990 return (ENOTSUP); 1991 } 1992 1993 (void) ddi_strtol(val, NULL, 0, &lval); 1994 1995 if (strcmp(name, "_ipg1") == 0) { 1996 if ((lval >= 0) && (lval <= 255)) { 1997 hmep->hme_ipg1 = lval & 0xff; 1998 init = B_TRUE; 1999 } else { 2000 return (EINVAL); 2001 } 2002 2003 } else if (strcmp(name, "_ipg2") == 0) { 2004 if ((lval >= 0) && (lval <= 255)) { 2005 hmep->hme_ipg2 = lval & 0xff; 2006 init = B_TRUE; 2007 } else { 2008 return (EINVAL); 2009 } 2010 2011 } else if (strcmp(name, "_ipg0") == 0) { 2012 if ((lval >= 0) && (lval <= 31)) { 2013 hmep->hme_ipg0 = lval & 0xff; 2014 init = B_TRUE; 2015 } else { 2016 return (EINVAL); 2017 } 2018 } else if (strcmp(name, "_lance_mode") == 0) { 2019 if ((lval >= 0) && (lval <= 1)) { 2020 hmep->hme_lance_mode = lval & 0xff; 2021 init = B_TRUE; 2022 } else { 2023 return (EINVAL); 2024 } 2025 2026 } else { 2027 rv = ENOTSUP; 2028 } 2029 2030 if (init) { 2031 (void) hmeinit(hmep); 2032 } 2033 return (rv); 2034 } 2035 2036 2037 /*ARGSUSED*/ 2038 static boolean_t 2039 hme_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 2040 { 2041 switch (cap) { 2042 case MAC_CAPAB_HCKSUM: 2043 *(uint32_t *)cap_data = HCKSUM_INET_PARTIAL; 2044 return (B_TRUE); 2045 default: 2046 return (B_FALSE); 2047 } 2048 } 2049 2050 static int 2051 hme_m_promisc(void *arg, boolean_t on) 2052 { 2053 struct hme *hmep = arg; 2054 2055 hmep->hme_promisc = on; 2056 (void) hmeinit(hmep); 2057 return (0); 2058 } 2059 2060 static int 2061 hme_m_unicst(void *arg, const uint8_t *macaddr) 2062 { 2063 struct hme *hmep = arg; 2064 2065 /* 2066 * Set new interface local address and re-init device. 2067 * This is destructive to any other streams attached 2068 * to this device. 2069 */ 2070 mutex_enter(&hmep->hme_intrlock); 2071 bcopy(macaddr, &hmep->hme_ouraddr, ETHERADDRL); 2072 mutex_exit(&hmep->hme_intrlock); 2073 (void) hmeinit(hmep); 2074 return (0); 2075 } 2076 2077 static int 2078 hme_m_multicst(void *arg, boolean_t add, const uint8_t *macaddr) 2079 { 2080 struct hme *hmep = arg; 2081 uint32_t ladrf_bit; 2082 boolean_t doinit = B_FALSE; 2083 2084 /* 2085 * If this address's bit was not already set in the local address 2086 * filter, add it and re-initialize the Hardware. 2087 */ 2088 ladrf_bit = hmeladrf_bit(macaddr); 2089 2090 mutex_enter(&hmep->hme_intrlock); 2091 if (add) { 2092 hmep->hme_ladrf_refcnt[ladrf_bit]++; 2093 if (hmep->hme_ladrf_refcnt[ladrf_bit] == 1) { 2094 hmep->hme_ladrf[ladrf_bit >> 4] |= 2095 1 << (ladrf_bit & 0xf); 2096 hmep->hme_multi++; 2097 doinit = B_TRUE; 2098 } 2099 } else { 2100 hmep->hme_ladrf_refcnt[ladrf_bit]--; 2101 if (hmep->hme_ladrf_refcnt[ladrf_bit] == 0) { 2102 hmep->hme_ladrf[ladrf_bit >> 4] &= 2103 ~(1 << (ladrf_bit & 0xf)); 2104 doinit = B_TRUE; 2105 } 2106 } 2107 mutex_exit(&hmep->hme_intrlock); 2108 2109 if (doinit) { 2110 (void) hmeinit(hmep); 2111 } 2112 2113 return (0); 2114 } 2115 2116 static int 2117 hme_m_start(void *arg) 2118 { 2119 struct hme *hmep = arg; 2120 2121 if (hmeinit(hmep) != 0) { 2122 /* initialization failed -- really want DL_INITFAILED */ 2123 return (EIO); 2124 } else { 2125 hmep->hme_started = B_TRUE; 2126 mii_start(hmep->hme_mii); 2127 return (0); 2128 } 2129 } 2130 2131 static void 2132 hme_m_stop(void *arg) 2133 { 2134 struct hme *hmep = arg; 2135 2136 mii_stop(hmep->hme_mii); 2137 hmep->hme_started = B_FALSE; 2138 hmeuninit(hmep); 2139 } 2140 2141 static int 2142 hme_m_stat(void *arg, uint_t stat, uint64_t *val) 2143 { 2144 struct hme *hmep = arg; 2145 2146 mutex_enter(&hmep->hme_xmitlock); 2147 if (hmep->hme_flags & HMERUNNING) { 2148 hmereclaim(hmep); 2149 hmesavecntrs(hmep); 2150 } 2151 mutex_exit(&hmep->hme_xmitlock); 2152 2153 2154 if (mii_m_getstat(hmep->hme_mii, stat, val) == 0) { 2155 return (0); 2156 } 2157 switch (stat) { 2158 case MAC_STAT_IPACKETS: 2159 *val = hmep->hme_ipackets; 2160 break; 2161 case MAC_STAT_RBYTES: 2162 *val = hmep->hme_rbytes; 2163 break; 2164 case MAC_STAT_IERRORS: 2165 *val = hmep->hme_ierrors; 2166 break; 2167 case MAC_STAT_OPACKETS: 2168 *val = hmep->hme_opackets; 2169 break; 2170 case MAC_STAT_OBYTES: 2171 *val = hmep->hme_obytes; 2172 break; 2173 case MAC_STAT_OERRORS: 2174 *val = hmep->hme_oerrors; 2175 break; 2176 case MAC_STAT_MULTIRCV: 2177 *val = hmep->hme_multircv; 2178 break; 2179 case MAC_STAT_MULTIXMT: 2180 *val = hmep->hme_multixmt; 2181 break; 2182 case MAC_STAT_BRDCSTRCV: 2183 *val = hmep->hme_brdcstrcv; 2184 break; 2185 case MAC_STAT_BRDCSTXMT: 2186 *val = hmep->hme_brdcstxmt; 2187 break; 2188 case MAC_STAT_UNDERFLOWS: 2189 *val = hmep->hme_uflo; 2190 break; 2191 case MAC_STAT_OVERFLOWS: 2192 *val = hmep->hme_oflo; 2193 break; 2194 case MAC_STAT_COLLISIONS: 2195 *val = hmep->hme_coll; 2196 break; 2197 case MAC_STAT_NORCVBUF: 2198 *val = hmep->hme_norcvbuf; 2199 break; 2200 case MAC_STAT_NOXMTBUF: 2201 *val = hmep->hme_noxmtbuf; 2202 break; 2203 case ETHER_STAT_LINK_DUPLEX: 2204 *val = hmep->hme_duplex; 2205 break; 2206 case ETHER_STAT_ALIGN_ERRORS: 2207 *val = hmep->hme_align_errors; 2208 break; 2209 case ETHER_STAT_FCS_ERRORS: 2210 *val = hmep->hme_fcs_errors; 2211 break; 2212 case ETHER_STAT_EX_COLLISIONS: 2213 *val = hmep->hme_excol; 2214 break; 2215 case ETHER_STAT_DEFER_XMTS: 2216 *val = hmep->hme_defer_xmts; 2217 break; 2218 case ETHER_STAT_SQE_ERRORS: 2219 *val = hmep->hme_sqe_errors; 2220 break; 2221 case ETHER_STAT_FIRST_COLLISIONS: 2222 *val = hmep->hme_fstcol; 2223 break; 2224 case ETHER_STAT_TX_LATE_COLLISIONS: 2225 *val = hmep->hme_tlcol; 2226 break; 2227 case ETHER_STAT_TOOLONG_ERRORS: 2228 *val = hmep->hme_toolong_errors; 2229 break; 2230 case ETHER_STAT_TOOSHORT_ERRORS: 2231 *val = hmep->hme_runt; 2232 break; 2233 case ETHER_STAT_CARRIER_ERRORS: 2234 *val = hmep->hme_carrier_errors; 2235 break; 2236 default: 2237 return (EINVAL); 2238 } 2239 return (0); 2240 } 2241 2242 static mblk_t * 2243 hme_m_tx(void *arg, mblk_t *mp) 2244 { 2245 struct hme *hmep = arg; 2246 mblk_t *next; 2247 2248 while (mp != NULL) { 2249 next = mp->b_next; 2250 mp->b_next = NULL; 2251 if (!hmestart(hmep, mp)) { 2252 mp->b_next = next; 2253 break; 2254 } 2255 mp = next; 2256 } 2257 return (mp); 2258 } 2259 2260 /* 2261 * Software IP checksum, for the edge cases that the 2262 * hardware can't handle. See hmestart for more info. 2263 */ 2264 static uint16_t 2265 hme_cksum(void *data, int len) 2266 { 2267 uint16_t *words = data; 2268 int i, nwords = len / 2; 2269 uint32_t sum = 0; 2270 2271 /* just add up the words */ 2272 for (i = 0; i < nwords; i++) { 2273 sum += *words++; 2274 } 2275 2276 /* pick up residual byte ... assume even half-word allocations */ 2277 if (len % 2) { 2278 sum += (*words & htons(0xff00)); 2279 } 2280 2281 sum = (sum >> 16) + (sum & 0xffff); 2282 sum = (sum >> 16) + (sum & 0xffff); 2283 2284 return (~(sum & 0xffff)); 2285 } 2286 2287 static boolean_t 2288 hmestart(struct hme *hmep, mblk_t *mp) 2289 { 2290 uint32_t len; 2291 boolean_t retval = B_TRUE; 2292 hmebuf_t *tbuf; 2293 uint32_t txptr; 2294 2295 uint32_t csflags = 0; 2296 uint32_t flags; 2297 uint32_t start_offset; 2298 uint32_t stuff_offset; 2299 2300 mac_hcksum_get(mp, &start_offset, &stuff_offset, NULL, NULL, &flags); 2301 2302 if (flags & HCK_PARTIALCKSUM) { 2303 if (get_ether_type(mp->b_rptr) == ETHERTYPE_VLAN) { 2304 start_offset += sizeof (struct ether_header) + 4; 2305 stuff_offset += sizeof (struct ether_header) + 4; 2306 } else { 2307 start_offset += sizeof (struct ether_header); 2308 stuff_offset += sizeof (struct ether_header); 2309 } 2310 csflags = HMETMD_CSENABL | 2311 (start_offset << HMETMD_CSSTART_SHIFT) | 2312 (stuff_offset << HMETMD_CSSTUFF_SHIFT); 2313 } 2314 2315 mutex_enter(&hmep->hme_xmitlock); 2316 2317 if (hmep->hme_flags & HMESUSPENDED) { 2318 hmep->hme_carrier_errors++; 2319 hmep->hme_oerrors++; 2320 goto bad; 2321 } 2322 2323 if (hmep->hme_txindex != hmep->hme_txreclaim) { 2324 hmereclaim(hmep); 2325 } 2326 if ((hmep->hme_txindex - HME_TMDMAX) == hmep->hme_txreclaim) 2327 goto notmds; 2328 txptr = hmep->hme_txindex % HME_TMDMAX; 2329 tbuf = &hmep->hme_tbuf[txptr]; 2330 2331 /* 2332 * Note that for checksum offload, the hardware cannot 2333 * generate correct checksums if the packet is smaller than 2334 * 64-bytes. In such a case, we bcopy the packet and use 2335 * a software checksum. 2336 */ 2337 2338 len = msgsize(mp); 2339 if (len < 64) { 2340 /* zero fill the padding */ 2341 bzero(tbuf->kaddr, 64); 2342 } 2343 mcopymsg(mp, tbuf->kaddr); 2344 2345 if ((csflags != 0) && (len < 64)) { 2346 uint16_t sum; 2347 sum = hme_cksum(tbuf->kaddr + start_offset, 2348 len - start_offset); 2349 bcopy(&sum, tbuf->kaddr + stuff_offset, sizeof (sum)); 2350 csflags = 0; 2351 } 2352 2353 if (ddi_dma_sync(tbuf->dmah, 0, len, DDI_DMA_SYNC_FORDEV) == 2354 DDI_FAILURE) { 2355 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, DDI_MSG, 2356 "ddi_dma_sync failed"); 2357 } 2358 2359 /* 2360 * update MIB II statistics 2361 */ 2362 BUMP_OutNUcast(hmep, tbuf->kaddr); 2363 2364 PUT_TMD(txptr, tbuf->paddr, len, 2365 HMETMD_OWN | HMETMD_SOP | HMETMD_EOP | csflags); 2366 2367 HMESYNCTMD(txptr, DDI_DMA_SYNC_FORDEV); 2368 hmep->hme_txindex++; 2369 2370 PUT_ETXREG(txpend, HMET_TXPEND_TDMD); 2371 CHECK_ETXREG(); 2372 2373 mutex_exit(&hmep->hme_xmitlock); 2374 2375 hmep->hme_starts++; 2376 return (B_TRUE); 2377 2378 bad: 2379 mutex_exit(&hmep->hme_xmitlock); 2380 freemsg(mp); 2381 return (B_TRUE); 2382 2383 notmds: 2384 hmep->hme_notmds++; 2385 hmep->hme_wantw = B_TRUE; 2386 hmereclaim(hmep); 2387 retval = B_FALSE; 2388 done: 2389 mutex_exit(&hmep->hme_xmitlock); 2390 2391 return (retval); 2392 } 2393 2394 /* 2395 * Initialize channel. 2396 * Return 0 on success, nonzero on error. 2397 * 2398 * The recommended sequence for initialization is: 2399 * 1. Issue a Global Reset command to the Ethernet Channel. 2400 * 2. Poll the Global_Reset bits until the execution of the reset has been 2401 * completed. 2402 * 2(a). Use the MIF Frame/Output register to reset the transceiver. 2403 * Poll Register 0 to till the Resetbit is 0. 2404 * 2(b). Use the MIF Frame/Output register to set the PHY in in Normal-Op, 2405 * 100Mbps and Non-Isolated mode. The main point here is to bring the 2406 * PHY out of Isolate mode so that it can generate the rx_clk and tx_clk 2407 * to the MII interface so that the Bigmac core can correctly reset 2408 * upon a software reset. 2409 * 2(c). Issue another Global Reset command to the Ethernet Channel and poll 2410 * the Global_Reset bits till completion. 2411 * 3. Set up all the data structures in the host memory. 2412 * 4. Program the TX_MAC registers/counters (excluding the TX_MAC Configuration 2413 * Register). 2414 * 5. Program the RX_MAC registers/counters (excluding the RX_MAC Configuration 2415 * Register). 2416 * 6. Program the Transmit Descriptor Ring Base Address in the ETX. 2417 * 7. Program the Receive Descriptor Ring Base Address in the ERX. 2418 * 8. Program the Global Configuration and the Global Interrupt Mask Registers. 2419 * 9. Program the ETX Configuration register (enable the Transmit DMA channel). 2420 * 10. Program the ERX Configuration register (enable the Receive DMA channel). 2421 * 11. Program the XIF Configuration Register (enable the XIF). 2422 * 12. Program the RX_MAC Configuration Register (Enable the RX_MAC). 2423 * 13. Program the TX_MAC Configuration Register (Enable the TX_MAC). 2424 */ 2425 2426 2427 #ifdef FEPS_URUN_BUG 2428 static int hme_palen = 32; 2429 #endif 2430 2431 static int 2432 hmeinit(struct hme *hmep) 2433 { 2434 uint32_t i; 2435 int ret; 2436 boolean_t fdx; 2437 int phyad; 2438 2439 /* 2440 * Lock sequence: 2441 * hme_intrlock, hme_xmitlock. 2442 */ 2443 mutex_enter(&hmep->hme_intrlock); 2444 2445 /* 2446 * Don't touch the hardware if we are suspended. But don't 2447 * fail either. Some time later we may be resumed, and then 2448 * we'll be back here to program the device using the settings 2449 * in the soft state. 2450 */ 2451 if (hmep->hme_flags & HMESUSPENDED) { 2452 mutex_exit(&hmep->hme_intrlock); 2453 return (0); 2454 } 2455 2456 /* 2457 * This should prevent us from clearing any interrupts that 2458 * may occur by temporarily stopping interrupts from occurring 2459 * for a short time. We need to update the interrupt mask 2460 * later in this function. 2461 */ 2462 PUT_GLOBREG(intmask, ~HMEG_MASK_MIF_INTR); 2463 2464 2465 /* 2466 * Rearranged the mutex acquisition order to solve the deadlock 2467 * situation as described in bug ID 4065896. 2468 */ 2469 2470 mutex_enter(&hmep->hme_xmitlock); 2471 2472 hmep->hme_flags = 0; 2473 hmep->hme_wantw = B_FALSE; 2474 2475 if (hmep->inits) 2476 hmesavecntrs(hmep); 2477 2478 /* 2479 * Perform Global reset of the Sbus/FEPS ENET channel. 2480 */ 2481 (void) hmestop(hmep); 2482 2483 /* 2484 * Clear all descriptors. 2485 */ 2486 bzero(hmep->hme_rmdp, HME_RMDMAX * sizeof (struct hme_rmd)); 2487 bzero(hmep->hme_tmdp, HME_TMDMAX * sizeof (struct hme_tmd)); 2488 2489 /* 2490 * Hang out receive buffers. 2491 */ 2492 for (i = 0; i < HME_RMDMAX; i++) { 2493 PUT_RMD(i, hmep->hme_rbuf[i].paddr); 2494 } 2495 2496 /* 2497 * DMA sync descriptors. 2498 */ 2499 (void) ddi_dma_sync(hmep->hme_rmd_dmah, 0, 0, DDI_DMA_SYNC_FORDEV); 2500 (void) ddi_dma_sync(hmep->hme_tmd_dmah, 0, 0, DDI_DMA_SYNC_FORDEV); 2501 2502 /* 2503 * Reset RMD and TMD 'walking' pointers. 2504 */ 2505 hmep->hme_rxindex = 0; 2506 hmep->hme_txindex = hmep->hme_txreclaim = 0; 2507 2508 /* 2509 * This is the right place to initialize MIF !!! 2510 */ 2511 2512 PUT_MIFREG(mif_imask, HME_MIF_INTMASK); /* mask all interrupts */ 2513 2514 if (!hmep->hme_frame_enable) 2515 PUT_MIFREG(mif_cfg, GET_MIFREG(mif_cfg) | HME_MIF_CFGBB); 2516 else 2517 PUT_MIFREG(mif_cfg, GET_MIFREG(mif_cfg) & ~HME_MIF_CFGBB); 2518 /* enable frame mode */ 2519 2520 /* 2521 * Depending on the transceiver detected, select the source 2522 * of the clocks for the MAC. Without the clocks, TX_MAC does 2523 * not reset. When the Global Reset is issued to the Sbus/FEPS 2524 * ASIC, it selects Internal by default. 2525 */ 2526 2527 switch ((phyad = mii_get_addr(hmep->hme_mii))) { 2528 case -1: 2529 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, XCVR_MSG, no_xcvr_msg); 2530 goto init_fail; /* abort initialization */ 2531 2532 case HME_INTERNAL_PHYAD: 2533 PUT_MACREG(xifc, 0); 2534 break; 2535 case HME_EXTERNAL_PHYAD: 2536 /* Isolate the Int. xcvr */ 2537 PUT_MACREG(xifc, BMAC_XIFC_MIIBUFDIS); 2538 break; 2539 } 2540 2541 hmep->inits++; 2542 2543 /* 2544 * Initialize BigMAC registers. 2545 * First set the tx enable bit in tx config reg to 0 and poll on 2546 * it till it turns to 0. Same for rx config, hash and address 2547 * filter reg. 2548 * Here is the sequence per the spec. 2549 * MADD2 - MAC Address 2 2550 * MADD1 - MAC Address 1 2551 * MADD0 - MAC Address 0 2552 * HASH3, HASH2, HASH1, HASH0 for group address 2553 * AFR2, AFR1, AFR0 and AFMR for address filter mask 2554 * Program RXMIN and RXMAX for packet length if not 802.3 2555 * RXCFG - Rx config for not stripping CRC 2556 * XXX Anything else to hme configured in RXCFG 2557 * IPG1, IPG2, ALIMIT, SLOT, PALEN, PAPAT, TXSFD, JAM, TXMAX, TXMIN 2558 * if not 802.3 compliant 2559 * XIF register for speed selection 2560 * MASK - Interrupt mask 2561 * Set bit 0 of TXCFG 2562 * Set bit 0 of RXCFG 2563 */ 2564 2565 /* 2566 * Initialize the TX_MAC registers 2567 * Initialization of jamsize to work around rx crc bug 2568 */ 2569 PUT_MACREG(jam, jamsize); 2570 2571 #ifdef FEPS_URUN_BUG 2572 if (hme_urun_fix) 2573 PUT_MACREG(palen, hme_palen); 2574 #endif 2575 2576 PUT_MACREG(ipg1, hmep->hme_ipg1); 2577 PUT_MACREG(ipg2, hmep->hme_ipg2); 2578 2579 PUT_MACREG(rseed, 2580 ((hmep->hme_ouraddr.ether_addr_octet[0] << 8) & 0x3) | 2581 hmep->hme_ouraddr.ether_addr_octet[1]); 2582 2583 /* Initialize the RX_MAC registers */ 2584 2585 /* 2586 * Program BigMAC with local individual ethernet address. 2587 */ 2588 PUT_MACREG(madd2, (hmep->hme_ouraddr.ether_addr_octet[4] << 8) | 2589 hmep->hme_ouraddr.ether_addr_octet[5]); 2590 PUT_MACREG(madd1, (hmep->hme_ouraddr.ether_addr_octet[2] << 8) | 2591 hmep->hme_ouraddr.ether_addr_octet[3]); 2592 PUT_MACREG(madd0, (hmep->hme_ouraddr.ether_addr_octet[0] << 8) | 2593 hmep->hme_ouraddr.ether_addr_octet[1]); 2594 2595 /* 2596 * Set up multicast address filter by passing all multicast 2597 * addresses through a crc generator, and then using the 2598 * low order 6 bits as a index into the 64 bit logical 2599 * address filter. The high order three bits select the word, 2600 * while the rest of the bits select the bit within the word. 2601 */ 2602 PUT_MACREG(hash0, hmep->hme_ladrf[0]); 2603 PUT_MACREG(hash1, hmep->hme_ladrf[1]); 2604 PUT_MACREG(hash2, hmep->hme_ladrf[2]); 2605 PUT_MACREG(hash3, hmep->hme_ladrf[3]); 2606 2607 /* 2608 * Configure parameters to support VLAN. (VLAN encapsulation adds 2609 * four bytes.) 2610 */ 2611 PUT_MACREG(txmax, ETHERMAX + ETHERFCSL + 4); 2612 PUT_MACREG(rxmax, ETHERMAX + ETHERFCSL + 4); 2613 2614 /* 2615 * Initialize HME Global registers, ETX registers and ERX registers. 2616 */ 2617 2618 PUT_ETXREG(txring, hmep->hme_tmd_paddr); 2619 PUT_ERXREG(rxring, hmep->hme_rmd_paddr); 2620 2621 /* 2622 * ERX registers can be written only if they have even no. of bits set. 2623 * So, if the value written is not read back, set the lsb and write 2624 * again. 2625 * static int hme_erx_fix = 1; : Use the fix for erx bug 2626 */ 2627 { 2628 uint32_t temp; 2629 temp = hmep->hme_rmd_paddr; 2630 2631 if (GET_ERXREG(rxring) != temp) 2632 PUT_ERXREG(rxring, (temp | 4)); 2633 } 2634 2635 PUT_GLOBREG(config, (hmep->hme_config | 2636 (hmep->hme_64bit_xfer << HMEG_CONFIG_64BIT_SHIFT))); 2637 2638 /* 2639 * Significant performance improvements can be achieved by 2640 * disabling transmit interrupt. Thus TMD's are reclaimed only 2641 * when we run out of them in hmestart(). 2642 */ 2643 PUT_GLOBREG(intmask, 2644 HMEG_MASK_INTR | HMEG_MASK_TINT | HMEG_MASK_TX_ALL); 2645 2646 PUT_ETXREG(txring_size, ((HME_TMDMAX -1)>> HMET_RINGSZ_SHIFT)); 2647 PUT_ETXREG(config, (GET_ETXREG(config) | HMET_CONFIG_TXDMA_EN 2648 | HMET_CONFIG_TXFIFOTH)); 2649 /* get the rxring size bits */ 2650 switch (HME_RMDMAX) { 2651 case 32: 2652 i = HMER_CONFIG_RXRINGSZ32; 2653 break; 2654 case 64: 2655 i = HMER_CONFIG_RXRINGSZ64; 2656 break; 2657 case 128: 2658 i = HMER_CONFIG_RXRINGSZ128; 2659 break; 2660 case 256: 2661 i = HMER_CONFIG_RXRINGSZ256; 2662 break; 2663 default: 2664 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 2665 unk_rx_ringsz_msg); 2666 goto init_fail; 2667 } 2668 i |= (HME_FSTBYTE_OFFSET << HMER_CONFIG_FBO_SHIFT) 2669 | HMER_CONFIG_RXDMA_EN; 2670 2671 /* h/w checks start offset in half words */ 2672 i |= ((sizeof (struct ether_header) / 2) << HMER_RX_CSSTART_SHIFT); 2673 2674 PUT_ERXREG(config, i); 2675 2676 /* 2677 * Bug related to the parity handling in ERX. When erxp-config is 2678 * read back. 2679 * Sbus/FEPS drives the parity bit. This value is used while 2680 * writing again. 2681 * This fixes the RECV problem in SS5. 2682 * static int hme_erx_fix = 1; : Use the fix for erx bug 2683 */ 2684 { 2685 uint32_t temp; 2686 temp = GET_ERXREG(config); 2687 PUT_ERXREG(config, i); 2688 2689 if (GET_ERXREG(config) != i) 2690 HME_FAULT_MSG4(hmep, SEVERITY_UNKNOWN, ERX_MSG, 2691 "error:temp = %x erxp->config = %x, should be %x", 2692 temp, GET_ERXREG(config), i); 2693 } 2694 2695 /* 2696 * Set up the rxconfig, txconfig and seed register without enabling 2697 * them the former two at this time 2698 * 2699 * BigMAC strips the CRC bytes by default. Since this is 2700 * contrary to other pieces of hardware, this bit needs to 2701 * enabled to tell BigMAC not to strip the CRC bytes. 2702 * Do not filter this node's own packets. 2703 */ 2704 2705 if (hme_reject_own) { 2706 PUT_MACREG(rxcfg, 2707 ((hmep->hme_promisc ? BMAC_RXCFG_PROMIS : 0) | 2708 BMAC_RXCFG_MYOWN | BMAC_RXCFG_HASH)); 2709 } else { 2710 PUT_MACREG(rxcfg, 2711 ((hmep->hme_promisc ? BMAC_RXCFG_PROMIS : 0) | 2712 BMAC_RXCFG_HASH)); 2713 } 2714 2715 drv_usecwait(10); /* wait after setting Hash Enable bit */ 2716 2717 fdx = (mii_get_duplex(hmep->hme_mii) == LINK_DUPLEX_FULL); 2718 2719 if (hme_ngu_enable) 2720 PUT_MACREG(txcfg, (fdx ? BMAC_TXCFG_FDX : 0) | 2721 BMAC_TXCFG_NGU); 2722 else 2723 PUT_MACREG(txcfg, (fdx ? BMAC_TXCFG_FDX: 0)); 2724 2725 i = 0; 2726 if ((hmep->hme_lance_mode) && (hmep->hme_lance_mode_enable)) 2727 i = ((hmep->hme_ipg0 & HME_MASK_5BIT) << BMAC_XIFC_IPG0_SHIFT) 2728 | BMAC_XIFC_LANCE_ENAB; 2729 if (phyad == HME_INTERNAL_PHYAD) 2730 PUT_MACREG(xifc, i | (BMAC_XIFC_ENAB)); 2731 else 2732 PUT_MACREG(xifc, i | (BMAC_XIFC_ENAB | BMAC_XIFC_MIIBUFDIS)); 2733 2734 PUT_MACREG(rxcfg, GET_MACREG(rxcfg) | BMAC_RXCFG_ENAB); 2735 PUT_MACREG(txcfg, GET_MACREG(txcfg) | BMAC_TXCFG_ENAB); 2736 2737 hmep->hme_flags |= (HMERUNNING | HMEINITIALIZED); 2738 /* 2739 * Update the interrupt mask : this will re-allow interrupts to occur 2740 */ 2741 PUT_GLOBREG(intmask, HMEG_MASK_INTR); 2742 mac_tx_update(hmep->hme_mh); 2743 2744 init_fail: 2745 /* 2746 * Release the locks in reverse order 2747 */ 2748 mutex_exit(&hmep->hme_xmitlock); 2749 mutex_exit(&hmep->hme_intrlock); 2750 2751 ret = !(hmep->hme_flags & HMERUNNING); 2752 if (ret) { 2753 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 2754 init_fail_gen_msg); 2755 } 2756 2757 /* 2758 * Hardware checks. 2759 */ 2760 CHECK_GLOBREG(); 2761 CHECK_MIFREG(); 2762 CHECK_MACREG(); 2763 CHECK_ERXREG(); 2764 CHECK_ETXREG(); 2765 2766 init_exit: 2767 return (ret); 2768 } 2769 2770 /* 2771 * Calculate the dvma burstsize by setting up a dvma temporarily. Return 2772 * 0 as burstsize upon failure as it signifies no burst size. 2773 * Requests for 64-bit transfer setup, if the platform supports it. 2774 * NOTE: Do not use ddi_dma_alloc_handle(9f) then ddi_dma_burstsize(9f), 2775 * sun4u Ultra-2 incorrectly returns a 32bit transfer. 2776 */ 2777 static int 2778 hmeburstsizes(struct hme *hmep) 2779 { 2780 int burstsizes; 2781 ddi_dma_handle_t handle; 2782 2783 if (ddi_dma_alloc_handle(hmep->dip, &hme_dma_attr, 2784 DDI_DMA_DONTWAIT, NULL, &handle)) { 2785 return (0); 2786 } 2787 2788 hmep->hme_burstsizes = burstsizes = ddi_dma_burstsizes(handle); 2789 ddi_dma_free_handle(&handle); 2790 2791 /* 2792 * Use user-configurable parameter for enabling 64-bit transfers 2793 */ 2794 burstsizes = (hmep->hme_burstsizes >> 16); 2795 if (burstsizes) 2796 hmep->hme_64bit_xfer = hme_64bit_enable; /* user config value */ 2797 else 2798 burstsizes = hmep->hme_burstsizes; 2799 2800 if (hmep->hme_cheerio_mode) 2801 hmep->hme_64bit_xfer = 0; /* Disable for cheerio */ 2802 2803 if (burstsizes & 0x40) 2804 hmep->hme_config = HMEG_CONFIG_BURST64; 2805 else if (burstsizes & 0x20) 2806 hmep->hme_config = HMEG_CONFIG_BURST32; 2807 else 2808 hmep->hme_config = HMEG_CONFIG_BURST16; 2809 2810 return (DDI_SUCCESS); 2811 } 2812 2813 static int 2814 hmeallocbuf(struct hme *hmep, hmebuf_t *buf, int dir) 2815 { 2816 ddi_dma_cookie_t dmac; 2817 size_t len; 2818 unsigned ccnt; 2819 2820 if (ddi_dma_alloc_handle(hmep->dip, &hme_dma_attr, 2821 DDI_DMA_DONTWAIT, NULL, &buf->dmah) != DDI_SUCCESS) { 2822 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 2823 "cannot allocate buf dma handle - failed"); 2824 return (DDI_FAILURE); 2825 } 2826 2827 if (ddi_dma_mem_alloc(buf->dmah, ROUNDUP(HMEBUFSIZE, 512), 2828 &hme_buf_attr, DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, NULL, 2829 &buf->kaddr, &len, &buf->acch) != DDI_SUCCESS) { 2830 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 2831 "cannot allocate buf memory - failed"); 2832 return (DDI_FAILURE); 2833 } 2834 2835 if (ddi_dma_addr_bind_handle(buf->dmah, NULL, buf->kaddr, 2836 len, dir | DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, 2837 &dmac, &ccnt) != DDI_DMA_MAPPED) { 2838 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 2839 "cannot map buf for dma - failed"); 2840 return (DDI_FAILURE); 2841 } 2842 buf->paddr = dmac.dmac_address; 2843 2844 /* apparently they don't handle multiple cookies */ 2845 if (ccnt > 1) { 2846 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 2847 "too many buf dma cookies"); 2848 return (DDI_FAILURE); 2849 } 2850 return (DDI_SUCCESS); 2851 } 2852 2853 static int 2854 hmeallocbufs(struct hme *hmep) 2855 { 2856 hmep->hme_tbuf = kmem_zalloc(HME_TMDMAX * sizeof (hmebuf_t), KM_SLEEP); 2857 hmep->hme_rbuf = kmem_zalloc(HME_RMDMAX * sizeof (hmebuf_t), KM_SLEEP); 2858 2859 /* Alloc RX buffers. */ 2860 for (int i = 0; i < HME_RMDMAX; i++) { 2861 if (hmeallocbuf(hmep, &hmep->hme_rbuf[i], DDI_DMA_READ) != 2862 DDI_SUCCESS) { 2863 return (DDI_FAILURE); 2864 } 2865 } 2866 2867 /* Alloc TX buffers. */ 2868 for (int i = 0; i < HME_TMDMAX; i++) { 2869 if (hmeallocbuf(hmep, &hmep->hme_tbuf[i], DDI_DMA_WRITE) != 2870 DDI_SUCCESS) { 2871 return (DDI_FAILURE); 2872 } 2873 } 2874 return (DDI_SUCCESS); 2875 } 2876 2877 static void 2878 hmefreebufs(struct hme *hmep) 2879 { 2880 int i; 2881 2882 if (hmep->hme_rbuf == NULL) 2883 return; 2884 2885 /* 2886 * Free and unload pending xmit and recv buffers. 2887 * Maintaining the 1-to-1 ordered sequence of 2888 * We have written the routine to be idempotent. 2889 */ 2890 2891 for (i = 0; i < HME_TMDMAX; i++) { 2892 hmebuf_t *tbuf = &hmep->hme_tbuf[i]; 2893 if (tbuf->paddr) { 2894 (void) ddi_dma_unbind_handle(tbuf->dmah); 2895 } 2896 if (tbuf->kaddr) { 2897 ddi_dma_mem_free(&tbuf->acch); 2898 } 2899 if (tbuf->dmah) { 2900 ddi_dma_free_handle(&tbuf->dmah); 2901 } 2902 } 2903 for (i = 0; i < HME_RMDMAX; i++) { 2904 hmebuf_t *rbuf = &hmep->hme_rbuf[i]; 2905 if (rbuf->paddr) { 2906 (void) ddi_dma_unbind_handle(rbuf->dmah); 2907 } 2908 if (rbuf->kaddr) { 2909 ddi_dma_mem_free(&rbuf->acch); 2910 } 2911 if (rbuf->dmah) { 2912 ddi_dma_free_handle(&rbuf->dmah); 2913 } 2914 } 2915 kmem_free(hmep->hme_rbuf, HME_RMDMAX * sizeof (hmebuf_t)); 2916 kmem_free(hmep->hme_tbuf, HME_TMDMAX * sizeof (hmebuf_t)); 2917 } 2918 2919 /* 2920 * Un-initialize (STOP) HME channel. 2921 */ 2922 static void 2923 hmeuninit(struct hme *hmep) 2924 { 2925 /* 2926 * Allow up to 'HMEDRAINTIME' for pending xmit's to complete. 2927 */ 2928 HMEDELAY((hmep->hme_txindex == hmep->hme_txreclaim), HMEDRAINTIME); 2929 2930 mutex_enter(&hmep->hme_intrlock); 2931 mutex_enter(&hmep->hme_xmitlock); 2932 2933 hmep->hme_flags &= ~HMERUNNING; 2934 2935 (void) hmestop(hmep); 2936 2937 mutex_exit(&hmep->hme_xmitlock); 2938 mutex_exit(&hmep->hme_intrlock); 2939 } 2940 2941 /* 2942 * Allocate CONSISTENT memory for rmds and tmds with appropriate alignment and 2943 * map it in IO space. Allocate space for transmit and receive ddi_dma_handle 2944 * structures to use the DMA interface. 2945 */ 2946 static int 2947 hmeallocthings(struct hme *hmep) 2948 { 2949 int size; 2950 int rval; 2951 size_t real_len; 2952 uint_t cookiec; 2953 ddi_dma_cookie_t dmac; 2954 dev_info_t *dip = hmep->dip; 2955 2956 /* 2957 * Allocate the TMD and RMD descriptors and extra for page alignment. 2958 */ 2959 2960 rval = ddi_dma_alloc_handle(dip, &hme_dma_attr, DDI_DMA_DONTWAIT, NULL, 2961 &hmep->hme_rmd_dmah); 2962 if (rval != DDI_SUCCESS) { 2963 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 2964 "cannot allocate rmd handle - failed"); 2965 return (DDI_FAILURE); 2966 } 2967 size = HME_RMDMAX * sizeof (struct hme_rmd); 2968 rval = ddi_dma_mem_alloc(hmep->hme_rmd_dmah, size, 2969 &hmep->hme_dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, 2970 &hmep->hme_rmd_kaddr, &real_len, &hmep->hme_rmd_acch); 2971 if (rval != DDI_SUCCESS) { 2972 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 2973 "cannot allocate rmd dma mem - failed"); 2974 return (DDI_FAILURE); 2975 } 2976 hmep->hme_rmdp = (void *)(hmep->hme_rmd_kaddr); 2977 rval = ddi_dma_addr_bind_handle(hmep->hme_rmd_dmah, NULL, 2978 hmep->hme_rmd_kaddr, size, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 2979 DDI_DMA_DONTWAIT, NULL, &dmac, &cookiec); 2980 if (rval != DDI_DMA_MAPPED) { 2981 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 2982 "cannot allocate rmd dma - failed"); 2983 return (DDI_FAILURE); 2984 } 2985 hmep->hme_rmd_paddr = dmac.dmac_address; 2986 if (cookiec != 1) { 2987 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 2988 "too many rmd cookies - failed"); 2989 return (DDI_FAILURE); 2990 } 2991 2992 rval = ddi_dma_alloc_handle(dip, &hme_dma_attr, DDI_DMA_DONTWAIT, NULL, 2993 &hmep->hme_tmd_dmah); 2994 if (rval != DDI_SUCCESS) { 2995 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 2996 "cannot allocate tmd handle - failed"); 2997 return (DDI_FAILURE); 2998 } 2999 size = HME_TMDMAX * sizeof (struct hme_rmd); 3000 rval = ddi_dma_mem_alloc(hmep->hme_tmd_dmah, size, 3001 &hmep->hme_dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, 3002 &hmep->hme_tmd_kaddr, &real_len, &hmep->hme_tmd_acch); 3003 if (rval != DDI_SUCCESS) { 3004 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 3005 "cannot allocate tmd dma mem - failed"); 3006 return (DDI_FAILURE); 3007 } 3008 hmep->hme_tmdp = (void *)(hmep->hme_tmd_kaddr); 3009 rval = ddi_dma_addr_bind_handle(hmep->hme_tmd_dmah, NULL, 3010 hmep->hme_tmd_kaddr, size, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 3011 DDI_DMA_DONTWAIT, NULL, &dmac, &cookiec); 3012 if (rval != DDI_DMA_MAPPED) { 3013 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 3014 "cannot allocate tmd dma - failed"); 3015 return (DDI_FAILURE); 3016 } 3017 hmep->hme_tmd_paddr = dmac.dmac_address; 3018 if (cookiec != 1) { 3019 HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, 3020 "too many tmd cookies - failed"); 3021 return (DDI_FAILURE); 3022 } 3023 3024 return (DDI_SUCCESS); 3025 } 3026 3027 static void 3028 hmefreethings(struct hme *hmep) 3029 { 3030 if (hmep->hme_rmd_paddr) { 3031 (void) ddi_dma_unbind_handle(hmep->hme_rmd_dmah); 3032 hmep->hme_rmd_paddr = 0; 3033 } 3034 if (hmep->hme_rmd_acch) 3035 ddi_dma_mem_free(&hmep->hme_rmd_acch); 3036 if (hmep->hme_rmd_dmah) 3037 ddi_dma_free_handle(&hmep->hme_rmd_dmah); 3038 3039 if (hmep->hme_tmd_paddr) { 3040 (void) ddi_dma_unbind_handle(hmep->hme_tmd_dmah); 3041 hmep->hme_tmd_paddr = 0; 3042 } 3043 if (hmep->hme_tmd_acch) 3044 ddi_dma_mem_free(&hmep->hme_tmd_acch); 3045 if (hmep->hme_tmd_dmah) 3046 ddi_dma_free_handle(&hmep->hme_tmd_dmah); 3047 } 3048 3049 /* 3050 * First check to see if it our device interrupting. 3051 */ 3052 static uint_t 3053 hmeintr(caddr_t arg) 3054 { 3055 struct hme *hmep = (void *)arg; 3056 uint32_t hmesbits; 3057 uint32_t serviced = DDI_INTR_UNCLAIMED; 3058 uint32_t num_reads = 0; 3059 uint32_t rflags; 3060 mblk_t *mp, *head, **tail; 3061 3062 3063 head = NULL; 3064 tail = &head; 3065 3066 mutex_enter(&hmep->hme_intrlock); 3067 3068 /* 3069 * The status register auto-clears on read except for 3070 * MIF Interrupt bit 3071 */ 3072 hmesbits = GET_GLOBREG(status); 3073 CHECK_GLOBREG(); 3074 3075 /* 3076 * Note: TINT is sometimes enabled in thr hmereclaim() 3077 */ 3078 3079 /* 3080 * Bugid 1227832 - to handle spurious interrupts on fusion systems. 3081 * Claim the first interrupt after initialization 3082 */ 3083 if (hmep->hme_flags & HMEINITIALIZED) { 3084 hmep->hme_flags &= ~HMEINITIALIZED; 3085 serviced = DDI_INTR_CLAIMED; 3086 } 3087 3088 if ((hmesbits & (HMEG_STATUS_INTR | HMEG_STATUS_TINT)) == 0) { 3089 /* No interesting interrupt */ 3090 if (hmep->hme_intrstats) { 3091 if (serviced == DDI_INTR_UNCLAIMED) 3092 KIOIP->intrs[KSTAT_INTR_SPURIOUS]++; 3093 else 3094 KIOIP->intrs[KSTAT_INTR_HARD]++; 3095 } 3096 mutex_exit(&hmep->hme_intrlock); 3097 return (serviced); 3098 } 3099 3100 serviced = DDI_INTR_CLAIMED; 3101 3102 if (!(hmep->hme_flags & HMERUNNING)) { 3103 if (hmep->hme_intrstats) 3104 KIOIP->intrs[KSTAT_INTR_HARD]++; 3105 mutex_exit(&hmep->hme_intrlock); 3106 hmeuninit(hmep); 3107 return (serviced); 3108 } 3109 3110 if (hmesbits & (HMEG_STATUS_FATAL_ERR | HMEG_STATUS_NONFATAL_ERR)) { 3111 if (hmesbits & HMEG_STATUS_FATAL_ERR) { 3112 3113 if (hmep->hme_intrstats) 3114 KIOIP->intrs[KSTAT_INTR_HARD]++; 3115 hme_fatal_err(hmep, hmesbits); 3116 3117 mutex_exit(&hmep->hme_intrlock); 3118 (void) hmeinit(hmep); 3119 return (serviced); 3120 } 3121 hme_nonfatal_err(hmep, hmesbits); 3122 } 3123 3124 if (hmesbits & (HMEG_STATUS_TX_ALL | HMEG_STATUS_TINT)) { 3125 mutex_enter(&hmep->hme_xmitlock); 3126 3127 hmereclaim(hmep); 3128 mutex_exit(&hmep->hme_xmitlock); 3129 } 3130 3131 if (hmesbits & HMEG_STATUS_RINT) { 3132 3133 /* 3134 * This dummy PIO is required to flush the SBus 3135 * Bridge buffers in QFE. 3136 */ 3137 (void) GET_GLOBREG(config); 3138 3139 /* 3140 * Loop through each RMD no more than once. 3141 */ 3142 while (num_reads++ < HME_RMDMAX) { 3143 hmebuf_t *rbuf; 3144 int rxptr; 3145 3146 rxptr = hmep->hme_rxindex % HME_RMDMAX; 3147 HMESYNCRMD(rxptr, DDI_DMA_SYNC_FORKERNEL); 3148 3149 rflags = GET_RMD_FLAGS(rxptr); 3150 if (rflags & HMERMD_OWN) { 3151 /* 3152 * Chip still owns it. We're done. 3153 */ 3154 break; 3155 } 3156 3157 /* 3158 * Retrieve the packet. 3159 */ 3160 rbuf = &hmep->hme_rbuf[rxptr]; 3161 mp = hmeread(hmep, rbuf, rflags); 3162 3163 /* 3164 * Return ownership of the RMD. 3165 */ 3166 PUT_RMD(rxptr, rbuf->paddr); 3167 HMESYNCRMD(rxptr, DDI_DMA_SYNC_FORDEV); 3168 3169 if (mp != NULL) { 3170 *tail = mp; 3171 tail = &mp->b_next; 3172 } 3173 3174 /* 3175 * Advance to the next RMD. 3176 */ 3177 hmep->hme_rxindex++; 3178 } 3179 } 3180 3181 if (hmep->hme_intrstats) 3182 KIOIP->intrs[KSTAT_INTR_HARD]++; 3183 3184 mutex_exit(&hmep->hme_intrlock); 3185 3186 if (head != NULL) 3187 mac_rx(hmep->hme_mh, NULL, head); 3188 3189 return (serviced); 3190 } 3191 3192 /* 3193 * Transmit completion reclaiming. 3194 */ 3195 static void 3196 hmereclaim(struct hme *hmep) 3197 { 3198 boolean_t reclaimed = B_FALSE; 3199 3200 /* 3201 * Loop through each TMD. 3202 */ 3203 while (hmep->hme_txindex > hmep->hme_txreclaim) { 3204 3205 int reclaim; 3206 uint32_t flags; 3207 3208 reclaim = hmep->hme_txreclaim % HME_TMDMAX; 3209 HMESYNCTMD(reclaim, DDI_DMA_SYNC_FORKERNEL); 3210 3211 flags = GET_TMD_FLAGS(reclaim); 3212 if (flags & HMETMD_OWN) { 3213 /* 3214 * Chip still owns it. We're done. 3215 */ 3216 break; 3217 } 3218 3219 /* 3220 * Count a chained packet only once. 3221 */ 3222 if (flags & HMETMD_SOP) { 3223 hmep->hme_opackets++; 3224 } 3225 3226 /* 3227 * MIB II 3228 */ 3229 hmep->hme_obytes += flags & HMETMD_BUFSIZE; 3230 3231 reclaimed = B_TRUE; 3232 hmep->hme_txreclaim++; 3233 } 3234 3235 if (reclaimed) { 3236 /* 3237 * we could reclaim some TMDs so turn off interrupts 3238 */ 3239 if (hmep->hme_wantw) { 3240 PUT_GLOBREG(intmask, 3241 HMEG_MASK_INTR | HMEG_MASK_TINT | 3242 HMEG_MASK_TX_ALL); 3243 hmep->hme_wantw = B_FALSE; 3244 mac_tx_update(hmep->hme_mh); 3245 } 3246 } else { 3247 /* 3248 * enable TINTS: so that even if there is no further activity 3249 * hmereclaim will get called 3250 */ 3251 if (hmep->hme_wantw) 3252 PUT_GLOBREG(intmask, 3253 GET_GLOBREG(intmask) & ~HMEG_MASK_TX_ALL); 3254 } 3255 CHECK_GLOBREG(); 3256 } 3257 3258 /* 3259 * Handle interrupts for fatal errors 3260 * Need reinitialization of the ENET channel. 3261 */ 3262 static void 3263 hme_fatal_err(struct hme *hmep, uint_t hmesbits) 3264 { 3265 3266 if (hmesbits & HMEG_STATUS_SLV_PAR_ERR) { 3267 hmep->hme_slvparerr++; 3268 } 3269 3270 if (hmesbits & HMEG_STATUS_SLV_ERR_ACK) { 3271 hmep->hme_slverrack++; 3272 } 3273 3274 if (hmesbits & HMEG_STATUS_TX_TAG_ERR) { 3275 hmep->hme_txtagerr++; 3276 hmep->hme_oerrors++; 3277 } 3278 3279 if (hmesbits & HMEG_STATUS_TX_PAR_ERR) { 3280 hmep->hme_txparerr++; 3281 hmep->hme_oerrors++; 3282 } 3283 3284 if (hmesbits & HMEG_STATUS_TX_LATE_ERR) { 3285 hmep->hme_txlaterr++; 3286 hmep->hme_oerrors++; 3287 } 3288 3289 if (hmesbits & HMEG_STATUS_TX_ERR_ACK) { 3290 hmep->hme_txerrack++; 3291 hmep->hme_oerrors++; 3292 } 3293 3294 if (hmesbits & HMEG_STATUS_EOP_ERR) { 3295 hmep->hme_eoperr++; 3296 } 3297 3298 if (hmesbits & HMEG_STATUS_RX_TAG_ERR) { 3299 hmep->hme_rxtagerr++; 3300 hmep->hme_ierrors++; 3301 } 3302 3303 if (hmesbits & HMEG_STATUS_RX_PAR_ERR) { 3304 hmep->hme_rxparerr++; 3305 hmep->hme_ierrors++; 3306 } 3307 3308 if (hmesbits & HMEG_STATUS_RX_LATE_ERR) { 3309 hmep->hme_rxlaterr++; 3310 hmep->hme_ierrors++; 3311 } 3312 3313 if (hmesbits & HMEG_STATUS_RX_ERR_ACK) { 3314 hmep->hme_rxerrack++; 3315 hmep->hme_ierrors++; 3316 } 3317 } 3318 3319 /* 3320 * Handle interrupts regarding non-fatal errors. 3321 */ 3322 static void 3323 hme_nonfatal_err(struct hme *hmep, uint_t hmesbits) 3324 { 3325 3326 if (hmesbits & HMEG_STATUS_RX_DROP) { 3327 hmep->hme_missed++; 3328 hmep->hme_ierrors++; 3329 } 3330 3331 if (hmesbits & HMEG_STATUS_DEFTIMR_EXP) { 3332 hmep->hme_defer_xmts++; 3333 } 3334 3335 if (hmesbits & HMEG_STATUS_FSTCOLC_EXP) { 3336 hmep->hme_fstcol += 256; 3337 } 3338 3339 if (hmesbits & HMEG_STATUS_LATCOLC_EXP) { 3340 hmep->hme_tlcol += 256; 3341 hmep->hme_oerrors += 256; 3342 } 3343 3344 if (hmesbits & HMEG_STATUS_EXCOLC_EXP) { 3345 hmep->hme_excol += 256; 3346 hmep->hme_oerrors += 256; 3347 } 3348 3349 if (hmesbits & HMEG_STATUS_NRMCOLC_EXP) { 3350 hmep->hme_coll += 256; 3351 } 3352 3353 if (hmesbits & HMEG_STATUS_MXPKTSZ_ERR) { 3354 hmep->hme_babl++; 3355 hmep->hme_oerrors++; 3356 } 3357 3358 /* 3359 * This error is fatal and the board needs to 3360 * be reinitialized. Comments? 3361 */ 3362 if (hmesbits & HMEG_STATUS_TXFIFO_UNDR) { 3363 hmep->hme_uflo++; 3364 hmep->hme_oerrors++; 3365 } 3366 3367 if (hmesbits & HMEG_STATUS_SQE_TST_ERR) { 3368 hmep->hme_sqe_errors++; 3369 } 3370 3371 if (hmesbits & HMEG_STATUS_RCV_CNT_EXP) { 3372 if (hmep->hme_rxcv_enable) { 3373 hmep->hme_cvc += 256; 3374 } 3375 } 3376 3377 if (hmesbits & HMEG_STATUS_RXFIFO_OVFL) { 3378 hmep->hme_oflo++; 3379 hmep->hme_ierrors++; 3380 } 3381 3382 if (hmesbits & HMEG_STATUS_LEN_CNT_EXP) { 3383 hmep->hme_lenerr += 256; 3384 hmep->hme_ierrors += 256; 3385 } 3386 3387 if (hmesbits & HMEG_STATUS_ALN_CNT_EXP) { 3388 hmep->hme_align_errors += 256; 3389 hmep->hme_ierrors += 256; 3390 } 3391 3392 if (hmesbits & HMEG_STATUS_CRC_CNT_EXP) { 3393 hmep->hme_fcs_errors += 256; 3394 hmep->hme_ierrors += 256; 3395 } 3396 } 3397 3398 static mblk_t * 3399 hmeread(struct hme *hmep, hmebuf_t *rbuf, uint32_t rflags) 3400 { 3401 mblk_t *bp; 3402 uint32_t len; 3403 t_uscalar_t type; 3404 3405 len = (rflags & HMERMD_BUFSIZE) >> HMERMD_BUFSIZE_SHIFT; 3406 3407 /* 3408 * Check for short packet 3409 * and check for overflow packet also. The processing is the 3410 * same for both the cases - reuse the buffer. Update the Buffer 3411 * overflow counter. 3412 */ 3413 if ((len < ETHERMIN) || (rflags & HMERMD_OVFLOW) || 3414 (len > (ETHERMAX + 4))) { 3415 if (len < ETHERMIN) 3416 hmep->hme_runt++; 3417 3418 else { 3419 hmep->hme_buff++; 3420 hmep->hme_toolong_errors++; 3421 } 3422 hmep->hme_ierrors++; 3423 return (NULL); 3424 } 3425 3426 /* 3427 * Sync the received buffer before looking at it. 3428 */ 3429 3430 (void) ddi_dma_sync(rbuf->dmah, 0, 0, DDI_DMA_SYNC_FORKERNEL); 3431 3432 /* 3433 * copy the packet data and then recycle the descriptor. 3434 */ 3435 3436 if ((bp = allocb(len + HME_FSTBYTE_OFFSET, BPRI_HI)) == NULL) { 3437 3438 hmep->hme_allocbfail++; 3439 hmep->hme_norcvbuf++; 3440 3441 return (NULL); 3442 } 3443 3444 bcopy(rbuf->kaddr, bp->b_rptr, len + HME_FSTBYTE_OFFSET); 3445 3446 hmep->hme_ipackets++; 3447 3448 /* Add the First Byte offset to the b_rptr and copy */ 3449 bp->b_rptr += HME_FSTBYTE_OFFSET; 3450 bp->b_wptr = bp->b_rptr + len; 3451 3452 /* 3453 * update MIB II statistics 3454 */ 3455 BUMP_InNUcast(hmep, bp->b_rptr); 3456 hmep->hme_rbytes += len; 3457 3458 type = get_ether_type(bp->b_rptr); 3459 3460 /* 3461 * TCP partial checksum in hardware 3462 */ 3463 if (type == ETHERTYPE_IP || type == ETHERTYPE_IPV6) { 3464 uint16_t cksum = ~rflags & HMERMD_CKSUM; 3465 uint_t end = len - sizeof (struct ether_header); 3466 mac_hcksum_set(bp, 0, 0, end, htons(cksum), HCK_PARTIALCKSUM); 3467 } 3468 3469 return (bp); 3470 } 3471 3472 /*VARARGS*/ 3473 static void 3474 hme_fault_msg(struct hme *hmep, uint_t severity, msg_t type, char *fmt, ...) 3475 { 3476 char msg_buffer[255]; 3477 va_list ap; 3478 3479 va_start(ap, fmt); 3480 (void) vsnprintf(msg_buffer, sizeof (msg_buffer), fmt, ap); 3481 3482 if (hmep == NULL) { 3483 cmn_err(CE_NOTE, "hme : %s", msg_buffer); 3484 3485 } else if (type == DISPLAY_MSG) { 3486 cmn_err(CE_CONT, "?%s%d : %s\n", ddi_driver_name(hmep->dip), 3487 hmep->instance, msg_buffer); 3488 } else if (severity == SEVERITY_HIGH) { 3489 cmn_err(CE_WARN, "%s%d : %s, SEVERITY_HIGH, %s\n", 3490 ddi_driver_name(hmep->dip), hmep->instance, 3491 msg_buffer, msg_string[type]); 3492 } else { 3493 cmn_err(CE_CONT, "%s%d : %s\n", ddi_driver_name(hmep->dip), 3494 hmep->instance, msg_buffer); 3495 } 3496 va_end(ap); 3497 } 3498 3499 /* 3500 * if this is the first init do not bother to save the 3501 * counters. They should be 0, but do not count on it. 3502 */ 3503 static void 3504 hmesavecntrs(struct hme *hmep) 3505 { 3506 uint32_t fecnt, aecnt, lecnt, rxcv; 3507 uint32_t ltcnt, excnt; 3508 3509 /* XXX What all gets added in ierrors and oerrors? */ 3510 fecnt = GET_MACREG(fecnt); 3511 PUT_MACREG(fecnt, 0); 3512 3513 aecnt = GET_MACREG(aecnt); 3514 hmep->hme_align_errors += aecnt; 3515 PUT_MACREG(aecnt, 0); 3516 3517 lecnt = GET_MACREG(lecnt); 3518 hmep->hme_lenerr += lecnt; 3519 PUT_MACREG(lecnt, 0); 3520 3521 rxcv = GET_MACREG(rxcv); 3522 #ifdef HME_CODEVIOL_BUG 3523 /* 3524 * Ignore rxcv errors for Sbus/FEPS 2.1 or earlier 3525 */ 3526 if (!hmep->hme_rxcv_enable) { 3527 rxcv = 0; 3528 } 3529 #endif 3530 hmep->hme_cvc += rxcv; 3531 PUT_MACREG(rxcv, 0); 3532 3533 ltcnt = GET_MACREG(ltcnt); 3534 hmep->hme_tlcol += ltcnt; 3535 PUT_MACREG(ltcnt, 0); 3536 3537 excnt = GET_MACREG(excnt); 3538 hmep->hme_excol += excnt; 3539 PUT_MACREG(excnt, 0); 3540 3541 hmep->hme_fcs_errors += fecnt; 3542 hmep->hme_ierrors += (fecnt + aecnt + lecnt); 3543 hmep->hme_oerrors += (ltcnt + excnt); 3544 hmep->hme_coll += (GET_MACREG(nccnt) + ltcnt); 3545 3546 PUT_MACREG(nccnt, 0); 3547 CHECK_MACREG(); 3548 } 3549 3550 /* 3551 * To set up the mac address for the network interface: 3552 * The adapter card may support a local mac address which is published 3553 * in a device node property "local-mac-address". This mac address is 3554 * treated as the factory-installed mac address for DLPI interface. 3555 * If the adapter firmware has used the device for diskless boot 3556 * operation it publishes a property called "mac-address" for use by 3557 * inetboot and the device driver. 3558 * If "mac-address" is not found, the system options property 3559 * "local-mac-address" is used to select the mac-address. If this option 3560 * is set to "true", and "local-mac-address" has been found, then 3561 * local-mac-address is used; otherwise the system mac address is used 3562 * by calling the "localetheraddr()" function. 3563 */ 3564 static void 3565 hme_setup_mac_address(struct hme *hmep, dev_info_t *dip) 3566 { 3567 char *prop; 3568 int prop_len = sizeof (int); 3569 3570 hmep->hme_addrflags = 0; 3571 3572 /* 3573 * Check if it is an adapter with its own local mac address 3574 * If it is present, save it as the "factory-address" 3575 * for this adapter. 3576 */ 3577 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 3578 "local-mac-address", 3579 (caddr_t)&prop, &prop_len) == DDI_PROP_SUCCESS) { 3580 if (prop_len == ETHERADDRL) { 3581 hmep->hme_addrflags = HME_FACTADDR_PRESENT; 3582 ether_bcopy(prop, &hmep->hme_factaddr); 3583 HME_FAULT_MSG2(hmep, SEVERITY_NONE, DISPLAY_MSG, 3584 "Local Ethernet address = %s", 3585 ether_sprintf(&hmep->hme_factaddr)); 3586 } 3587 kmem_free(prop, prop_len); 3588 } 3589 3590 /* 3591 * Check if the adapter has published "mac-address" property. 3592 * If it is present, use it as the mac address for this device. 3593 */ 3594 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 3595 "mac-address", (caddr_t)&prop, &prop_len) == DDI_PROP_SUCCESS) { 3596 if (prop_len >= ETHERADDRL) { 3597 ether_bcopy(prop, &hmep->hme_ouraddr); 3598 kmem_free(prop, prop_len); 3599 return; 3600 } 3601 kmem_free(prop, prop_len); 3602 } 3603 3604 #ifdef __sparc 3605 /* 3606 * On sparc, we might be able to use the mac address from the 3607 * system. However, on all other systems, we need to use the 3608 * address from the PROM. 3609 */ 3610 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, 0, "local-mac-address?", 3611 (caddr_t)&prop, &prop_len) == DDI_PROP_SUCCESS) { 3612 if ((strncmp("true", prop, prop_len) == 0) && 3613 (hmep->hme_addrflags & HME_FACTADDR_PRESENT)) { 3614 hmep->hme_addrflags |= HME_FACTADDR_USE; 3615 ether_bcopy(&hmep->hme_factaddr, &hmep->hme_ouraddr); 3616 kmem_free(prop, prop_len); 3617 HME_FAULT_MSG1(hmep, SEVERITY_NONE, DISPLAY_MSG, 3618 "Using local MAC address"); 3619 return; 3620 } 3621 kmem_free(prop, prop_len); 3622 } 3623 3624 /* 3625 * Get the system ethernet address. 3626 */ 3627 (void) localetheraddr((struct ether_addr *)NULL, &hmep->hme_ouraddr); 3628 #else 3629 ether_bcopy(&hmep->hme_factaddr, &hmep->hme_ouraddr); 3630 #endif 3631 } 3632 3633 /* ARGSUSED */ 3634 static void 3635 hme_check_acc_handle(char *file, uint_t line, struct hme *hmep, 3636 ddi_acc_handle_t handle) 3637 { 3638 } 3639