1 /* 2 * sfe_util.c: general ethernet mac driver framework version 2.6 3 * 4 * Copyright (c) 2002-2007 Masayuki Murayama. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * 3. Neither the name of the author nor the names of its contributors may be 17 * used to endorse or promote products derived from this software without 18 * specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 31 * DAMAGE. 32 */ 33 34 #pragma ident "%Z%%M% %I% %E% SMI" /* sfe device driver */ 35 36 /* 37 * System Header files. 38 */ 39 #include <sys/types.h> 40 #include <sys/conf.h> 41 #include <sys/debug.h> 42 #include <sys/kmem.h> 43 #include <sys/vtrace.h> 44 #include <sys/ethernet.h> 45 #include <sys/modctl.h> 46 #include <sys/errno.h> 47 #include <sys/ddi.h> 48 #include <sys/sunddi.h> 49 #include <sys/stream.h> /* required for MBLK* */ 50 #include <sys/strsun.h> /* required for mionack() */ 51 #include <sys/byteorder.h> 52 #include <sys/pci.h> 53 #include <inet/common.h> 54 #include <inet/led.h> 55 #include <inet/mi.h> 56 #include <inet/nd.h> 57 #include <sys/crc32.h> 58 59 #include <sys/note.h> 60 61 #include "sfe_mii.h" 62 #include "sfe_util.h" 63 64 65 66 extern char ident[]; 67 68 /* Debugging support */ 69 #ifdef GEM_DEBUG_LEVEL 70 static int gem_debug = GEM_DEBUG_LEVEL; 71 #define DPRINTF(n, args) if (gem_debug > (n)) cmn_err args 72 #else 73 #define DPRINTF(n, args) 74 #undef ASSERT 75 #define ASSERT(x) 76 #endif 77 78 #define IOC_LINESIZE 0x40 /* Is it right for amd64? */ 79 80 /* 81 * Useful macros and typedefs 82 */ 83 #define ROUNDUP(x, a) (((x) + (a) - 1) & ~((a) - 1)) 84 85 #define GET_NET16(p) ((((uint8_t *)(p))[0] << 8)| ((uint8_t *)(p))[1]) 86 #define GET_ETHERTYPE(p) GET_NET16(((uint8_t *)(p)) + ETHERADDRL*2) 87 88 #define GET_IPTYPEv4(p) (((uint8_t *)(p))[sizeof (struct ether_header) + 9]) 89 #define GET_IPTYPEv6(p) (((uint8_t *)(p))[sizeof (struct ether_header) + 6]) 90 91 92 #ifndef INT32_MAX 93 #define INT32_MAX 0x7fffffff 94 #endif 95 96 #define VTAG_OFF (ETHERADDRL*2) 97 #ifndef VTAG_SIZE 98 #define VTAG_SIZE 4 99 #endif 100 #ifndef VTAG_TPID 101 #define VTAG_TPID 0x8100U 102 #endif 103 104 #define GET_TXBUF(dp, sn) \ 105 &(dp)->tx_buf[SLOT((dp)->tx_slots_base + (sn), (dp)->gc.gc_tx_buf_size)] 106 107 #ifndef offsetof 108 #define offsetof(t, m) ((long)&(((t *) 0)->m)) 109 #endif 110 #define TXFLAG_VTAG(flag) \ 111 (((flag) & GEM_TXFLAG_VTAG) >> GEM_TXFLAG_VTAG_SHIFT) 112 113 #define MAXPKTBUF(dp) \ 114 ((dp)->mtu + sizeof (struct ether_header) + VTAG_SIZE + ETHERFCSL) 115 116 #define WATCH_INTERVAL_FAST drv_usectohz(100*1000) /* 100mS */ 117 #define BOOLEAN(x) ((x) ? 1 : 0) 118 119 /* 120 * Macros to distinct chip generation. 121 */ 122 123 /* 124 * Private functions 125 */ 126 static void gem_mii_start(struct gem_dev *); 127 static void gem_mii_stop(struct gem_dev *); 128 129 /* local buffer management */ 130 static void gem_nd_setup(struct gem_dev *dp); 131 static void gem_nd_cleanup(struct gem_dev *dp); 132 static int gem_alloc_memory(struct gem_dev *); 133 static void gem_free_memory(struct gem_dev *); 134 static void gem_init_rx_ring(struct gem_dev *); 135 static void gem_init_tx_ring(struct gem_dev *); 136 __INLINE__ static void gem_append_rxbuf(struct gem_dev *, struct rxbuf *); 137 138 static void gem_tx_timeout(struct gem_dev *); 139 static void gem_mii_link_watcher(struct gem_dev *dp); 140 static int gem_mac_init(struct gem_dev *dp); 141 static int gem_mac_start(struct gem_dev *dp); 142 static int gem_mac_stop(struct gem_dev *dp, uint_t flags); 143 static void gem_mac_ioctl(struct gem_dev *dp, queue_t *wq, mblk_t *mp); 144 145 static struct ether_addr gem_etherbroadcastaddr = { 146 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 147 }; 148 149 int gem_speed_value[] = {10, 100, 1000}; 150 151 /* ============================================================== */ 152 /* 153 * Misc runtime routines 154 */ 155 /* ============================================================== */ 156 /* 157 * Ether CRC calculation according to 21143 data sheet 158 */ 159 uint32_t 160 gem_ether_crc_le(const uint8_t *addr, int len) 161 { 162 uint32_t crc; 163 164 CRC32(crc, addr, ETHERADDRL, 0xffffffffU, crc32_table); 165 return (crc); 166 } 167 168 uint32_t 169 gem_ether_crc_be(const uint8_t *addr, int len) 170 { 171 int idx; 172 int bit; 173 uint_t data; 174 uint32_t crc; 175 #define CRC32_POLY_BE 0x04c11db7 176 177 crc = 0xffffffff; 178 for (idx = 0; idx < len; idx++) { 179 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) { 180 crc = (crc << 1) 181 ^ ((((crc >> 31) ^ data) & 1) ? CRC32_POLY_BE : 0); 182 } 183 } 184 return (crc); 185 #undef CRC32_POLY_BE 186 } 187 188 int 189 gem_prop_get_int(struct gem_dev *dp, char *prop_template, int def_val) 190 { 191 char propname[32]; 192 193 (void) sprintf(propname, prop_template, dp->name); 194 195 return (ddi_prop_get_int(DDI_DEV_T_ANY, dp->dip, 196 DDI_PROP_DONTPASS, propname, def_val)); 197 } 198 199 static int 200 gem_population(uint32_t x) 201 { 202 int i; 203 int cnt; 204 205 cnt = 0; 206 for (i = 0; i < 32; i++) { 207 if (x & (1 << i)) { 208 cnt++; 209 } 210 } 211 return (cnt); 212 } 213 214 215 /* ============================================================== */ 216 /* 217 * vlan tag operations 218 */ 219 /* ============================================================== */ 220 221 __INLINE__ 222 static void 223 gem_add_vtag(mblk_t *mp, int vtag) 224 { 225 uint32_t *bp; 226 227 /* we must have enough room to insert vtag before b_rptr */ 228 ASSERT((long)mp->b_rptr - (long)mp->b_datap->db_base >= VTAG_SIZE); 229 230 bp = (void *)mp->b_rptr; 231 mp->b_rptr = (uint8_t *)bp - VTAG_SIZE; 232 233 switch (3ull & (long)bp) { 234 case 3: 235 ((uint8_t *)bp)[VTAG_OFF-3] = ((uint8_t *)bp)[VTAG_OFF+1]; 236 /* FALLTHROUGH */ 237 case 2: 238 ((uint8_t *)bp)[VTAG_OFF-2] = ((uint8_t *)bp)[VTAG_OFF+2]; 239 /* FALLTHROUGH */ 240 case 1: 241 ((uint8_t *)bp)[VTAG_OFF-1] = ((uint8_t *)bp)[VTAG_OFF+3]; 242 break; 243 } 244 ((uint8_t *)bp)[VTAG_OFF + 0] = (uint8_t)(VTAG_TPID >> 8); 245 ((uint8_t *)bp)[VTAG_OFF + 1] = (uint8_t)VTAG_TPID; 246 ((uint8_t *)bp)[VTAG_OFF + 2] = (uint8_t)(vtag >> 8); 247 ((uint8_t *)bp)[VTAG_OFF + 3] = (uint8_t)vtag; 248 bp = (void *)(long)((~3ull) & (long)bp); 249 bp[0] = bp[1]; 250 bp[1] = bp[2]; 251 bp[2] = bp[3]; 252 } 253 #pragma inline(gem_add_vtag) 254 /* ============================================================== */ 255 /* 256 * IO cache flush 257 */ 258 /* ============================================================== */ 259 __INLINE__ void 260 gem_rx_desc_dma_sync(struct gem_dev *dp, int head, int nslot, int how) 261 { 262 int n; 263 int m; 264 int rx_desc_unit_shift = dp->gc.gc_rx_desc_unit_shift; 265 266 /* sync active descriptors */ 267 if (rx_desc_unit_shift < 0 || nslot == 0) { 268 /* no rx descriptor ring */ 269 return; 270 } 271 272 n = dp->gc.gc_rx_ring_size - head; 273 if ((m = nslot - n) > 0) { 274 (void) ddi_dma_sync(dp->desc_dma_handle, 275 (off_t)0, 276 (size_t)(m << rx_desc_unit_shift), 277 how); 278 nslot = n; 279 } 280 281 (void) ddi_dma_sync(dp->desc_dma_handle, 282 (off_t)(head << rx_desc_unit_shift), 283 (size_t)(nslot << rx_desc_unit_shift), 284 how); 285 } 286 287 __INLINE__ void 288 gem_tx_desc_dma_sync(struct gem_dev *dp, int head, int nslot, int how) 289 { 290 int n; 291 int m; 292 int tx_desc_unit_shift = dp->gc.gc_tx_desc_unit_shift; 293 294 /* sync active descriptors */ 295 if (tx_desc_unit_shift < 0 || nslot == 0) { 296 /* no tx descriptor ring */ 297 return; 298 } 299 300 n = dp->gc.gc_tx_ring_size - head; 301 if ((m = nslot - n) > 0) { 302 (void) ddi_dma_sync(dp->desc_dma_handle, 303 (off_t)(dp->tx_ring_dma - dp->rx_ring_dma), 304 (size_t)(m << tx_desc_unit_shift), 305 how); 306 nslot = n; 307 } 308 309 (void) ddi_dma_sync(dp->desc_dma_handle, 310 (off_t)((head << tx_desc_unit_shift) 311 + (dp->tx_ring_dma - dp->rx_ring_dma)), 312 (size_t)(nslot << tx_desc_unit_shift), 313 how); 314 } 315 316 static void 317 gem_rx_start_default(struct gem_dev *dp, int head, int nslot) 318 { 319 gem_rx_desc_dma_sync(dp, 320 SLOT(head, dp->gc.gc_rx_ring_size), nslot, 321 DDI_DMA_SYNC_FORDEV); 322 } 323 324 /* ============================================================== */ 325 /* 326 * Buffer management 327 */ 328 /* ============================================================== */ 329 static void 330 gem_dump_txbuf(struct gem_dev *dp, int level, const char *title) 331 { 332 cmn_err(level, 333 "!%s: %s: tx_active: %d[%d] %d[%d] (+%d), " 334 "tx_softq: %d[%d] %d[%d] (+%d), " 335 "tx_free: %d[%d] %d[%d] (+%d), " 336 "tx_desc: %d[%d] %d[%d] (+%d), " 337 "intr: %d[%d] (+%d)", 338 dp->name, title, 339 dp->tx_active_head, 340 SLOT(dp->tx_active_head, dp->gc.gc_tx_buf_size), 341 dp->tx_active_tail, 342 SLOT(dp->tx_active_tail, dp->gc.gc_tx_buf_size), 343 dp->tx_active_tail - dp->tx_active_head, 344 dp->tx_softq_head, 345 SLOT(dp->tx_softq_head, dp->gc.gc_tx_buf_size), 346 dp->tx_softq_tail, 347 SLOT(dp->tx_softq_tail, dp->gc.gc_tx_buf_size), 348 dp->tx_softq_tail - dp->tx_softq_head, 349 dp->tx_free_head, 350 SLOT(dp->tx_free_head, dp->gc.gc_tx_buf_size), 351 dp->tx_free_tail, 352 SLOT(dp->tx_free_tail, dp->gc.gc_tx_buf_size), 353 dp->tx_free_tail - dp->tx_free_head, 354 dp->tx_desc_head, 355 SLOT(dp->tx_desc_head, dp->gc.gc_tx_ring_size), 356 dp->tx_desc_tail, 357 SLOT(dp->tx_desc_tail, dp->gc.gc_tx_ring_size), 358 dp->tx_desc_tail - dp->tx_desc_head, 359 dp->tx_desc_intr, 360 SLOT(dp->tx_desc_intr, dp->gc.gc_tx_ring_size), 361 dp->tx_desc_intr - dp->tx_desc_head); 362 } 363 364 static void 365 gem_free_rxbuf(struct rxbuf *rbp) 366 { 367 struct gem_dev *dp; 368 369 dp = rbp->rxb_devp; 370 ASSERT(mutex_owned(&dp->intrlock)); 371 rbp->rxb_next = dp->rx_buf_freelist; 372 dp->rx_buf_freelist = rbp; 373 dp->rx_buf_freecnt++; 374 } 375 376 /* 377 * gem_get_rxbuf: supply a receive buffer which have been mapped into 378 * DMA space. 379 */ 380 struct rxbuf * 381 gem_get_rxbuf(struct gem_dev *dp, int cansleep) 382 { 383 struct rxbuf *rbp; 384 uint_t count = 0; 385 int i; 386 int err; 387 388 ASSERT(mutex_owned(&dp->intrlock)); 389 390 DPRINTF(3, (CE_CONT, "!gem_get_rxbuf: called freecnt:%d", 391 dp->rx_buf_freecnt)); 392 /* 393 * Get rx buffer management structure 394 */ 395 rbp = dp->rx_buf_freelist; 396 if (rbp) { 397 /* get one from the recycle list */ 398 ASSERT(dp->rx_buf_freecnt > 0); 399 400 dp->rx_buf_freelist = rbp->rxb_next; 401 dp->rx_buf_freecnt--; 402 rbp->rxb_next = NULL; 403 return (rbp); 404 } 405 406 /* 407 * Allocate a rx buffer management structure 408 */ 409 rbp = kmem_zalloc(sizeof (*rbp), cansleep ? KM_SLEEP : KM_NOSLEEP); 410 if (rbp == NULL) { 411 /* no memory */ 412 return (NULL); 413 } 414 415 /* 416 * Prepare a back pointer to the device structure which will be 417 * refered on freeing the buffer later. 418 */ 419 rbp->rxb_devp = dp; 420 421 /* allocate a dma handle for rx data buffer */ 422 if ((err = ddi_dma_alloc_handle(dp->dip, 423 &dp->gc.gc_dma_attr_rxbuf, 424 (cansleep ? DDI_DMA_SLEEP : DDI_DMA_DONTWAIT), 425 NULL, &rbp->rxb_dh)) != DDI_SUCCESS) { 426 427 cmn_err(CE_WARN, 428 "!%s: %s: ddi_dma_alloc_handle:1 failed, err=%d", 429 dp->name, __func__, err); 430 431 kmem_free(rbp, sizeof (struct rxbuf)); 432 return (NULL); 433 } 434 435 /* allocate a bounce buffer for rx */ 436 if ((err = ddi_dma_mem_alloc(rbp->rxb_dh, 437 ROUNDUP(dp->rx_buf_len, IOC_LINESIZE), 438 &dp->gc.gc_buf_attr, 439 /* 440 * if the nic requires a header at the top of receive buffers, 441 * it may access the rx buffer randomly. 442 */ 443 (dp->gc.gc_rx_header_len > 0) 444 ? DDI_DMA_CONSISTENT : DDI_DMA_STREAMING, 445 cansleep ? DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, 446 NULL, 447 &rbp->rxb_buf, &rbp->rxb_buf_len, 448 &rbp->rxb_bah)) != DDI_SUCCESS) { 449 450 cmn_err(CE_WARN, 451 "!%s: %s: ddi_dma_mem_alloc: failed, err=%d", 452 dp->name, __func__, err); 453 454 ddi_dma_free_handle(&rbp->rxb_dh); 455 kmem_free(rbp, sizeof (struct rxbuf)); 456 return (NULL); 457 } 458 459 /* Mapin the bounce buffer into the DMA space */ 460 if ((err = ddi_dma_addr_bind_handle(rbp->rxb_dh, 461 NULL, rbp->rxb_buf, dp->rx_buf_len, 462 ((dp->gc.gc_rx_header_len > 0) 463 ?(DDI_DMA_RDWR | DDI_DMA_CONSISTENT) 464 :(DDI_DMA_READ | DDI_DMA_STREAMING)), 465 cansleep ? DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, 466 NULL, 467 rbp->rxb_dmacookie, 468 &count)) != DDI_DMA_MAPPED) { 469 470 ASSERT(err != DDI_DMA_INUSE); 471 DPRINTF(0, (CE_WARN, 472 "!%s: ddi_dma_addr_bind_handle: failed, err=%d", 473 dp->name, __func__, err)); 474 475 /* 476 * we failed to allocate a dma resource 477 * for the rx bounce buffer. 478 */ 479 ddi_dma_mem_free(&rbp->rxb_bah); 480 ddi_dma_free_handle(&rbp->rxb_dh); 481 kmem_free(rbp, sizeof (struct rxbuf)); 482 return (NULL); 483 } 484 485 /* correct the rest of the DMA mapping */ 486 for (i = 1; i < count; i++) { 487 ddi_dma_nextcookie(rbp->rxb_dh, &rbp->rxb_dmacookie[i]); 488 } 489 rbp->rxb_nfrags = count; 490 491 /* Now we successfully prepared an rx buffer */ 492 dp->rx_buf_allocated++; 493 494 return (rbp); 495 } 496 497 /* ============================================================== */ 498 /* 499 * memory resource management 500 */ 501 /* ============================================================== */ 502 static int 503 gem_alloc_memory(struct gem_dev *dp) 504 { 505 caddr_t ring; 506 caddr_t buf; 507 size_t req_size; 508 size_t ring_len; 509 size_t buf_len; 510 ddi_dma_cookie_t ring_cookie; 511 ddi_dma_cookie_t buf_cookie; 512 uint_t count; 513 int i; 514 int err; 515 struct txbuf *tbp; 516 int tx_buf_len; 517 ddi_dma_attr_t dma_attr_txbounce; 518 519 DPRINTF(1, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 520 521 dp->desc_dma_handle = NULL; 522 req_size = dp->rx_desc_size + dp->tx_desc_size + dp->gc.gc_io_area_size; 523 524 if (req_size > 0) { 525 /* 526 * Alloc RX/TX descriptors and a io area. 527 */ 528 if ((err = ddi_dma_alloc_handle(dp->dip, 529 &dp->gc.gc_dma_attr_desc, 530 DDI_DMA_SLEEP, NULL, 531 &dp->desc_dma_handle)) != DDI_SUCCESS) { 532 cmn_err(CE_WARN, 533 "!%s: %s: ddi_dma_alloc_handle failed: %d", 534 dp->name, __func__, err); 535 return (ENOMEM); 536 } 537 538 if ((err = ddi_dma_mem_alloc(dp->desc_dma_handle, 539 req_size, &dp->gc.gc_desc_attr, 540 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 541 &ring, &ring_len, 542 &dp->desc_acc_handle)) != DDI_SUCCESS) { 543 cmn_err(CE_WARN, 544 "!%s: %s: ddi_dma_mem_alloc failed: " 545 "ret %d, request size: %d", 546 dp->name, __func__, err, (int)req_size); 547 ddi_dma_free_handle(&dp->desc_dma_handle); 548 return (ENOMEM); 549 } 550 551 if ((err = ddi_dma_addr_bind_handle(dp->desc_dma_handle, 552 NULL, ring, ring_len, 553 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 554 DDI_DMA_SLEEP, NULL, 555 &ring_cookie, &count)) != DDI_SUCCESS) { 556 ASSERT(err != DDI_DMA_INUSE); 557 cmn_err(CE_WARN, 558 "!%s: %s: ddi_dma_addr_bind_handle failed: %d", 559 dp->name, __func__, err); 560 ddi_dma_mem_free(&dp->desc_acc_handle); 561 ddi_dma_free_handle(&dp->desc_dma_handle); 562 return (ENOMEM); 563 } 564 ASSERT(count == 1); 565 566 /* set base of rx descriptor ring */ 567 dp->rx_ring = ring; 568 dp->rx_ring_dma = ring_cookie.dmac_laddress; 569 570 /* set base of tx descriptor ring */ 571 dp->tx_ring = dp->rx_ring + dp->rx_desc_size; 572 dp->tx_ring_dma = dp->rx_ring_dma + dp->rx_desc_size; 573 574 /* set base of io area */ 575 dp->io_area = dp->tx_ring + dp->tx_desc_size; 576 dp->io_area_dma = dp->tx_ring_dma + dp->tx_desc_size; 577 } 578 579 /* 580 * Prepare DMA resources for tx packets 581 */ 582 ASSERT(dp->gc.gc_tx_buf_size > 0); 583 584 /* Special dma attribute for tx bounce buffers */ 585 dma_attr_txbounce = dp->gc.gc_dma_attr_txbuf; 586 dma_attr_txbounce.dma_attr_sgllen = 1; 587 dma_attr_txbounce.dma_attr_align = 588 max(dma_attr_txbounce.dma_attr_align, IOC_LINESIZE); 589 590 /* Size for tx bounce buffers must be max tx packet size. */ 591 tx_buf_len = MAXPKTBUF(dp); 592 tx_buf_len = ROUNDUP(tx_buf_len, IOC_LINESIZE); 593 594 ASSERT(tx_buf_len >= ETHERMAX+ETHERFCSL); 595 596 for (i = 0, tbp = dp->tx_buf; 597 i < dp->gc.gc_tx_buf_size; i++, tbp++) { 598 599 /* setup bounce buffers for tx packets */ 600 if ((err = ddi_dma_alloc_handle(dp->dip, 601 &dma_attr_txbounce, 602 DDI_DMA_SLEEP, NULL, 603 &tbp->txb_bdh)) != DDI_SUCCESS) { 604 605 cmn_err(CE_WARN, 606 "!%s: %s ddi_dma_alloc_handle for bounce buffer failed:" 607 " err=%d, i=%d", 608 dp->name, __func__, err, i); 609 goto err_alloc_dh; 610 } 611 612 if ((err = ddi_dma_mem_alloc(tbp->txb_bdh, 613 tx_buf_len, 614 &dp->gc.gc_buf_attr, 615 DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, 616 &buf, &buf_len, 617 &tbp->txb_bah)) != DDI_SUCCESS) { 618 cmn_err(CE_WARN, 619 "!%s: %s: ddi_dma_mem_alloc for bounce buffer failed" 620 "ret %d, request size %d", 621 dp->name, __func__, err, tx_buf_len); 622 ddi_dma_free_handle(&tbp->txb_bdh); 623 goto err_alloc_dh; 624 } 625 626 if ((err = ddi_dma_addr_bind_handle(tbp->txb_bdh, 627 NULL, buf, buf_len, 628 DDI_DMA_WRITE | DDI_DMA_STREAMING, 629 DDI_DMA_SLEEP, NULL, 630 &buf_cookie, &count)) != DDI_SUCCESS) { 631 ASSERT(err != DDI_DMA_INUSE); 632 cmn_err(CE_WARN, 633 "!%s: %s: ddi_dma_addr_bind_handle for bounce buffer failed: %d", 634 dp->name, __func__, err); 635 ddi_dma_mem_free(&tbp->txb_bah); 636 ddi_dma_free_handle(&tbp->txb_bdh); 637 goto err_alloc_dh; 638 } 639 ASSERT(count == 1); 640 tbp->txb_buf = buf; 641 tbp->txb_buf_dma = buf_cookie.dmac_laddress; 642 } 643 644 return (0); 645 646 err_alloc_dh: 647 if (dp->gc.gc_tx_buf_size > 0) { 648 while (i-- > 0) { 649 (void) ddi_dma_unbind_handle(dp->tx_buf[i].txb_bdh); 650 ddi_dma_mem_free(&dp->tx_buf[i].txb_bah); 651 ddi_dma_free_handle(&dp->tx_buf[i].txb_bdh); 652 } 653 } 654 655 if (dp->desc_dma_handle) { 656 (void) ddi_dma_unbind_handle(dp->desc_dma_handle); 657 ddi_dma_mem_free(&dp->desc_acc_handle); 658 ddi_dma_free_handle(&dp->desc_dma_handle); 659 dp->desc_dma_handle = NULL; 660 } 661 662 return (ENOMEM); 663 } 664 665 static void 666 gem_free_memory(struct gem_dev *dp) 667 { 668 int i; 669 struct rxbuf *rbp; 670 struct txbuf *tbp; 671 672 DPRINTF(1, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 673 674 /* Free TX/RX descriptors and tx padding buffer */ 675 if (dp->desc_dma_handle) { 676 (void) ddi_dma_unbind_handle(dp->desc_dma_handle); 677 ddi_dma_mem_free(&dp->desc_acc_handle); 678 ddi_dma_free_handle(&dp->desc_dma_handle); 679 dp->desc_dma_handle = NULL; 680 } 681 682 /* Free dma handles for Tx */ 683 for (i = dp->gc.gc_tx_buf_size, tbp = dp->tx_buf; i--; tbp++) { 684 /* Free bounce buffer associated to each txbuf */ 685 (void) ddi_dma_unbind_handle(tbp->txb_bdh); 686 ddi_dma_mem_free(&tbp->txb_bah); 687 ddi_dma_free_handle(&tbp->txb_bdh); 688 } 689 690 /* Free rx buffer */ 691 while ((rbp = dp->rx_buf_freelist) != NULL) { 692 693 ASSERT(dp->rx_buf_freecnt > 0); 694 695 dp->rx_buf_freelist = rbp->rxb_next; 696 dp->rx_buf_freecnt--; 697 698 /* release DMA mapping */ 699 ASSERT(rbp->rxb_dh != NULL); 700 701 /* free dma handles for rx bbuf */ 702 /* it has dma mapping always */ 703 ASSERT(rbp->rxb_nfrags > 0); 704 (void) ddi_dma_unbind_handle(rbp->rxb_dh); 705 706 /* free the associated bounce buffer and dma handle */ 707 ASSERT(rbp->rxb_bah != NULL); 708 ddi_dma_mem_free(&rbp->rxb_bah); 709 /* free the associated dma handle */ 710 ddi_dma_free_handle(&rbp->rxb_dh); 711 712 /* free the base memory of rx buffer management */ 713 kmem_free(rbp, sizeof (struct rxbuf)); 714 } 715 } 716 717 /* ============================================================== */ 718 /* 719 * Rx/Tx descriptor slot management 720 */ 721 /* ============================================================== */ 722 /* 723 * Initialize an empty rx ring. 724 */ 725 static void 726 gem_init_rx_ring(struct gem_dev *dp) 727 { 728 int i; 729 int rx_ring_size = dp->gc.gc_rx_ring_size; 730 731 DPRINTF(1, (CE_CONT, "!%s: %s ring_size:%d, buf_max:%d", 732 dp->name, __func__, 733 rx_ring_size, dp->gc.gc_rx_buf_max)); 734 735 /* make a physical chain of rx descriptors */ 736 for (i = 0; i < rx_ring_size; i++) { 737 (*dp->gc.gc_rx_desc_init)(dp, i); 738 } 739 gem_rx_desc_dma_sync(dp, 0, rx_ring_size, DDI_DMA_SYNC_FORDEV); 740 741 dp->rx_active_head = (seqnum_t)0; 742 dp->rx_active_tail = (seqnum_t)0; 743 744 ASSERT(dp->rx_buf_head == (struct rxbuf *)NULL); 745 ASSERT(dp->rx_buf_tail == (struct rxbuf *)NULL); 746 } 747 748 /* 749 * Prepare rx buffers and put them into the rx buffer/descriptor ring. 750 */ 751 static void 752 gem_prepare_rx_buf(struct gem_dev *dp) 753 { 754 int i; 755 int nrbuf; 756 struct rxbuf *rbp; 757 758 ASSERT(mutex_owned(&dp->intrlock)); 759 760 /* Now we have no active buffers in rx ring */ 761 762 nrbuf = min(dp->gc.gc_rx_ring_size, dp->gc.gc_rx_buf_max); 763 for (i = 0; i < nrbuf; i++) { 764 if ((rbp = gem_get_rxbuf(dp, B_TRUE)) == NULL) { 765 break; 766 } 767 gem_append_rxbuf(dp, rbp); 768 } 769 770 gem_rx_desc_dma_sync(dp, 771 0, dp->gc.gc_rx_ring_size, DDI_DMA_SYNC_FORDEV); 772 } 773 774 /* 775 * Reclaim active rx buffers in rx buffer ring. 776 */ 777 static void 778 gem_clean_rx_buf(struct gem_dev *dp) 779 { 780 int i; 781 struct rxbuf *rbp; 782 int rx_ring_size = dp->gc.gc_rx_ring_size; 783 #ifdef GEM_DEBUG_LEVEL 784 int total; 785 #endif 786 ASSERT(mutex_owned(&dp->intrlock)); 787 788 DPRINTF(2, (CE_CONT, "!%s: %s: %d buffers are free", 789 dp->name, __func__, dp->rx_buf_freecnt)); 790 /* 791 * clean up HW descriptors 792 */ 793 for (i = 0; i < rx_ring_size; i++) { 794 (*dp->gc.gc_rx_desc_clean)(dp, i); 795 } 796 gem_rx_desc_dma_sync(dp, 0, rx_ring_size, DDI_DMA_SYNC_FORDEV); 797 798 #ifdef GEM_DEBUG_LEVEL 799 total = 0; 800 #endif 801 /* 802 * Reclaim allocated rx buffers 803 */ 804 while ((rbp = dp->rx_buf_head) != NULL) { 805 #ifdef GEM_DEBUG_LEVEL 806 total++; 807 #endif 808 /* remove the first one from rx buffer list */ 809 dp->rx_buf_head = rbp->rxb_next; 810 811 /* recycle the rxbuf */ 812 gem_free_rxbuf(rbp); 813 } 814 dp->rx_buf_tail = (struct rxbuf *)NULL; 815 816 DPRINTF(2, (CE_CONT, 817 "!%s: %s: %d buffers freeed, total: %d free", 818 dp->name, __func__, total, dp->rx_buf_freecnt)); 819 } 820 821 /* 822 * Initialize an empty transmit buffer/descriptor ring 823 */ 824 static void 825 gem_init_tx_ring(struct gem_dev *dp) 826 { 827 int i; 828 int tx_buf_size = dp->gc.gc_tx_buf_size; 829 int tx_ring_size = dp->gc.gc_tx_ring_size; 830 831 DPRINTF(2, (CE_CONT, "!%s: %s: ring_size:%d, buf_size:%d", 832 dp->name, __func__, 833 dp->gc.gc_tx_ring_size, dp->gc.gc_tx_buf_size)); 834 835 ASSERT(!dp->mac_active); 836 837 /* initialize active list and free list */ 838 dp->tx_slots_base = 839 SLOT(dp->tx_slots_base + dp->tx_softq_head, tx_buf_size); 840 dp->tx_softq_tail -= dp->tx_softq_head; 841 dp->tx_softq_head = (seqnum_t)0; 842 843 dp->tx_active_head = dp->tx_softq_head; 844 dp->tx_active_tail = dp->tx_softq_head; 845 846 dp->tx_free_head = dp->tx_softq_tail; 847 dp->tx_free_tail = dp->gc.gc_tx_buf_limit; 848 849 dp->tx_desc_head = (seqnum_t)0; 850 dp->tx_desc_tail = (seqnum_t)0; 851 dp->tx_desc_intr = (seqnum_t)0; 852 853 for (i = 0; i < tx_ring_size; i++) { 854 (*dp->gc.gc_tx_desc_init)(dp, i); 855 } 856 gem_tx_desc_dma_sync(dp, 0, tx_ring_size, DDI_DMA_SYNC_FORDEV); 857 } 858 859 __INLINE__ 860 static void 861 gem_txbuf_free_dma_resources(struct txbuf *tbp) 862 { 863 if (tbp->txb_mp) { 864 freemsg(tbp->txb_mp); 865 tbp->txb_mp = NULL; 866 } 867 tbp->txb_nfrags = 0; 868 } 869 #pragma inline(gem_txbuf_free_dma_resources) 870 871 /* 872 * reclaim active tx buffers and reset positions in tx rings. 873 */ 874 static void 875 gem_clean_tx_buf(struct gem_dev *dp) 876 { 877 int i; 878 seqnum_t head; 879 seqnum_t tail; 880 seqnum_t sn; 881 struct txbuf *tbp; 882 int tx_ring_size = dp->gc.gc_tx_ring_size; 883 #ifdef GEM_DEBUG_LEVEL 884 int err; 885 #endif 886 887 ASSERT(!dp->mac_active); 888 ASSERT(dp->tx_busy == 0); 889 ASSERT(dp->tx_softq_tail == dp->tx_free_head); 890 891 /* 892 * clean up all HW descriptors 893 */ 894 for (i = 0; i < tx_ring_size; i++) { 895 (*dp->gc.gc_tx_desc_clean)(dp, i); 896 } 897 gem_tx_desc_dma_sync(dp, 0, tx_ring_size, DDI_DMA_SYNC_FORDEV); 898 899 /* dequeue all active and loaded buffers */ 900 head = dp->tx_active_head; 901 tail = dp->tx_softq_tail; 902 903 ASSERT(dp->tx_free_head - head >= 0); 904 tbp = GET_TXBUF(dp, head); 905 for (sn = head; sn != tail; sn++) { 906 gem_txbuf_free_dma_resources(tbp); 907 ASSERT(tbp->txb_mp == NULL); 908 dp->stats.errxmt++; 909 tbp = tbp->txb_next; 910 } 911 912 #ifdef GEM_DEBUG_LEVEL 913 /* ensure no dma resources for tx are not in use now */ 914 err = 0; 915 while (sn != head + dp->gc.gc_tx_buf_size) { 916 if (tbp->txb_mp || tbp->txb_nfrags) { 917 DPRINTF(0, (CE_CONT, 918 "%s: %s: sn:%d[%d] mp:%p nfrags:%d", 919 dp->name, __func__, 920 sn, SLOT(sn, dp->gc.gc_tx_buf_size), 921 tbp->txb_mp, tbp->txb_nfrags)); 922 err = 1; 923 } 924 sn++; 925 tbp = tbp->txb_next; 926 } 927 928 if (err) { 929 gem_dump_txbuf(dp, CE_WARN, 930 "gem_clean_tx_buf: tbp->txb_mp != NULL"); 931 } 932 #endif 933 /* recycle buffers, now no active tx buffers in the ring */ 934 dp->tx_free_tail += tail - head; 935 ASSERT(dp->tx_free_tail == dp->tx_free_head + dp->gc.gc_tx_buf_limit); 936 937 /* fix positions in tx buffer rings */ 938 dp->tx_active_head = dp->tx_free_head; 939 dp->tx_active_tail = dp->tx_free_head; 940 dp->tx_softq_head = dp->tx_free_head; 941 dp->tx_softq_tail = dp->tx_free_head; 942 } 943 944 /* 945 * Reclaim transmitted buffers from tx buffer/descriptor ring. 946 */ 947 __INLINE__ int 948 gem_reclaim_txbuf(struct gem_dev *dp) 949 { 950 struct txbuf *tbp; 951 uint_t txstat; 952 int err = GEM_SUCCESS; 953 seqnum_t head; 954 seqnum_t tail; 955 seqnum_t sn; 956 seqnum_t desc_head; 957 int tx_ring_size = dp->gc.gc_tx_ring_size; 958 uint_t (*tx_desc_stat)(struct gem_dev *dp, 959 int slot, int ndesc) = dp->gc.gc_tx_desc_stat; 960 #if GEM_DEBUG_LEVEL > 4 961 clock_t now = ddi_get_lbolt(); 962 #endif 963 964 mutex_enter(&dp->xmitlock); 965 966 head = dp->tx_active_head; 967 tail = dp->tx_active_tail; 968 969 #if GEM_DEBUG_LEVEL > 2 970 if (head != tail) { 971 cmn_err(CE_CONT, "!%s: %s: " 972 "testing active_head:%d[%d], active_tail:%d[%d]", 973 dp->name, __func__, 974 head, SLOT(head, dp->gc.gc_tx_buf_size), 975 tail, SLOT(tail, dp->gc.gc_tx_buf_size)); 976 } 977 #endif 978 #ifdef DEBUG 979 if (dp->tx_reclaim_busy == 0) { 980 /* check tx buffer management consistency */ 981 ASSERT(dp->tx_free_tail - dp->tx_active_head 982 == dp->gc.gc_tx_buf_limit); 983 /* EMPTY */ 984 } 985 #endif 986 dp->tx_reclaim_busy++; 987 988 /* sync all active HW descriptors */ 989 gem_tx_desc_dma_sync(dp, 990 SLOT(dp->tx_desc_head, tx_ring_size), 991 dp->tx_desc_tail - dp->tx_desc_head, 992 DDI_DMA_SYNC_FORKERNEL); 993 994 tbp = GET_TXBUF(dp, head); 995 desc_head = dp->tx_desc_head; 996 for (sn = head; sn != tail; 997 dp->tx_active_head = (++sn), tbp = tbp->txb_next) { 998 int ndescs; 999 1000 ASSERT(tbp->txb_desc == desc_head); 1001 1002 ndescs = tbp->txb_ndescs; 1003 txstat = (*tx_desc_stat)(dp, 1004 SLOT(tbp->txb_desc, tx_ring_size), ndescs); 1005 1006 if (txstat == 0) { 1007 /* not transmitted yet */ 1008 break; 1009 } 1010 1011 ASSERT(txstat & (GEM_TX_DONE | GEM_TX_ERR)); 1012 1013 if (txstat & GEM_TX_ERR) { 1014 err = GEM_FAILURE; 1015 cmn_err(CE_WARN, "!%s: tx error at desc %d[%d]", 1016 dp->name, sn, SLOT(sn, tx_ring_size)); 1017 } 1018 #if GEM_DEBUG_LEVEL > 4 1019 if (now - tbp->txb_stime >= 50) { 1020 cmn_err(CE_WARN, "!%s: tx delay while %d mS", 1021 dp->name, (now - tbp->txb_stime)*10); 1022 } 1023 #endif 1024 /* free transmitted descriptors */ 1025 desc_head += ndescs; 1026 } 1027 1028 if (dp->tx_desc_head != desc_head) { 1029 /* we have reclaimed one or more tx buffers */ 1030 dp->tx_desc_head = desc_head; 1031 1032 /* If we passed the next interrupt position, update it */ 1033 if (desc_head - dp->tx_desc_intr >= 0) { 1034 dp->tx_desc_intr = desc_head; 1035 } 1036 } 1037 mutex_exit(&dp->xmitlock); 1038 1039 /* free dma mapping resources associated with transmitted tx buffers */ 1040 tbp = GET_TXBUF(dp, head); 1041 tail = sn; 1042 #if GEM_DEBUG_LEVEL > 2 1043 if (head != tail) { 1044 cmn_err(CE_CONT, "%s: freeing head:%d[%d], tail:%d[%d]", 1045 __func__, 1046 head, SLOT(head, dp->gc.gc_tx_buf_size), 1047 tail, SLOT(tail, dp->gc.gc_tx_buf_size)); 1048 } 1049 #endif 1050 for (sn = head; sn != tail; sn++, tbp = tbp->txb_next) { 1051 gem_txbuf_free_dma_resources(tbp); 1052 } 1053 1054 /* recycle the tx buffers */ 1055 mutex_enter(&dp->xmitlock); 1056 if (--dp->tx_reclaim_busy == 0) { 1057 /* we are the last thread who can update free tail */ 1058 #if GEM_DEBUG_LEVEL > 4 1059 /* check all resouces have been deallocated */ 1060 sn = dp->tx_free_tail; 1061 tbp = GET_TXBUF(dp, new_tail); 1062 while (sn != dp->tx_active_head + dp->gc.gc_tx_buf_limit) { 1063 if (tbp->txb_nfrags) { 1064 /* in use */ 1065 break; 1066 } 1067 ASSERT(tbp->txb_mp == NULL); 1068 tbp = tbp->txb_next; 1069 sn++; 1070 } 1071 ASSERT(dp->tx_active_head + dp->gc.gc_tx_buf_limit == sn); 1072 #endif 1073 dp->tx_free_tail = 1074 dp->tx_active_head + dp->gc.gc_tx_buf_limit; 1075 } 1076 if (!dp->mac_active) { 1077 /* someone may be waiting for me. */ 1078 cv_broadcast(&dp->tx_drain_cv); 1079 } 1080 #if GEM_DEBUG_LEVEL > 2 1081 cmn_err(CE_CONT, "!%s: %s: called, " 1082 "free_head:%d free_tail:%d(+%d) added:%d", 1083 dp->name, __func__, 1084 dp->tx_free_head, dp->tx_free_tail, 1085 dp->tx_free_tail - dp->tx_free_head, tail - head); 1086 #endif 1087 mutex_exit(&dp->xmitlock); 1088 1089 return (err); 1090 } 1091 #pragma inline(gem_reclaim_txbuf) 1092 1093 1094 /* 1095 * Make tx descriptors in out-of-order manner 1096 */ 1097 static void 1098 gem_tx_load_descs_oo(struct gem_dev *dp, 1099 seqnum_t start_slot, seqnum_t end_slot, seqnum_t intr_slot, 1100 uint64_t flags) 1101 { 1102 seqnum_t sn; 1103 struct txbuf *tbp; 1104 int tx_ring_size = dp->gc.gc_tx_ring_size; 1105 int (*tx_desc_write) 1106 (struct gem_dev *dp, int slot, 1107 ddi_dma_cookie_t *dmacookie, 1108 int frags, uint64_t flag) = dp->gc.gc_tx_desc_write; 1109 clock_t now = ddi_get_lbolt(); 1110 1111 sn = start_slot; 1112 tbp = GET_TXBUF(dp, sn); 1113 do { 1114 if (sn == intr_slot) { 1115 flags |= GEM_TXFLAG_INTR; 1116 } 1117 #if GEM_DEBUG_LEVEL > 1 1118 if (dp->tx_cnt < 100) { 1119 dp->tx_cnt++; 1120 flags |= GEM_TXFLAG_INTR; 1121 } 1122 #endif 1123 /* write a tx descriptor */ 1124 tbp->txb_desc = sn; 1125 tbp->txb_ndescs = (*tx_desc_write)(dp, 1126 SLOT(sn, tx_ring_size), 1127 tbp->txb_dmacookie, 1128 tbp->txb_nfrags, flags | tbp->txb_flag); 1129 tbp->txb_stime = now; 1130 ASSERT(tbp->txb_ndescs == 1); 1131 1132 flags = 0; 1133 sn++; 1134 tbp = tbp->txb_next; 1135 } while (sn != end_slot); 1136 } 1137 1138 1139 __INLINE__ 1140 static void 1141 gem_setup_txbuf_copy(struct gem_dev *dp, mblk_t *mp, struct txbuf *tbp) 1142 { 1143 size_t min_pkt; 1144 caddr_t bp; 1145 size_t off; 1146 mblk_t *tp; 1147 size_t len; 1148 uint64_t flag; 1149 1150 ASSERT(tbp->txb_mp == NULL); 1151 1152 /* we use bounce buffer for the packet */ 1153 min_pkt = ETHERMIN; 1154 bp = tbp->txb_buf; 1155 off = 0; 1156 tp = mp; 1157 1158 flag = tbp->txb_flag; 1159 if (flag & GEM_TXFLAG_SWVTAG) { 1160 /* need to increase min packet size */ 1161 min_pkt += VTAG_SIZE; 1162 ASSERT((flag & GEM_TXFLAG_VTAG) == 0); 1163 } else if (flag & GEM_TXFLAG_VTAG) { 1164 size_t rest; 1165 /* we use hardware capability to add vlan tag. */ 1166 1167 /* copy until VTAG + VTAG_SIZE */ 1168 for (rest = VTAG_OFF + VTAG_SIZE; ; tp = tp->b_cont) { 1169 ASSERT(tp != NULL); 1170 len = min((long)tp->b_wptr - (long)tp->b_rptr, rest); 1171 bcopy(tp->b_rptr, &bp[off], len); 1172 off += len; 1173 rest -= len; 1174 if (rest == 0) { 1175 tp->b_rptr += len; 1176 break; 1177 } 1178 } 1179 /* we have just copied vlan tag, see it. */ 1180 ASSERT(GET_NET16(&bp[off - VTAG_SIZE]) == VTAG_TPID); 1181 1182 /* remove the vlan tag */ 1183 off -= VTAG_SIZE; 1184 } 1185 1186 /* copy the rest */ 1187 for (; tp; tp = tp->b_cont) { 1188 if ((len = (long)tp->b_wptr - (long)tp->b_rptr) > 0) { 1189 bcopy(tp->b_rptr, &bp[off], len); 1190 off += len; 1191 } 1192 } 1193 1194 if (off < min_pkt && 1195 (min_pkt > ETHERMIN || !dp->gc.gc_tx_auto_pad)) { 1196 /* 1197 * Extend explicitly the packet to minimum packet size. 1198 * For software vlan packets, we shouldn't use tx autopad 1199 * function because nics may not be aware of vlan, that 1200 * we must keep 46 octet of payload even if we use vlan. 1201 */ 1202 bzero(&bp[off], min_pkt - off); 1203 off = min_pkt; 1204 } 1205 1206 (void) ddi_dma_sync(tbp->txb_bdh, (off_t)0, off, DDI_DMA_SYNC_FORDEV); 1207 1208 tbp->txb_dmacookie[0].dmac_laddress = tbp->txb_buf_dma; 1209 tbp->txb_dmacookie[0].dmac_size = off; 1210 1211 DPRINTF(2, (CE_CONT, 1212 "!%s: %s: copy: addr:0x%llx len:0x%x, vtag:0x%04x, min_pkt:%d", 1213 dp->name, __func__, 1214 tbp->txb_dmacookie[0].dmac_laddress, 1215 tbp->txb_dmacookie[0].dmac_size, 1216 (flag & GEM_TXFLAG_VTAG) >> GEM_TXFLAG_VTAG_SHIFT, 1217 min_pkt)); 1218 1219 /* save misc info */ 1220 tbp->txb_mp = mp; 1221 tbp->txb_nfrags = 1; 1222 #ifdef DEBUG_MULTIFRAGS 1223 if (dp->gc.gc_tx_max_frags >= 3 && 1224 tbp->txb_dmacookie[0].dmac_size > 16*3) { 1225 tbp->txb_dmacookie[1].dmac_laddress = 1226 tbp->txb_dmacookie[0].dmac_laddress + 16; 1227 tbp->txb_dmacookie[2].dmac_laddress = 1228 tbp->txb_dmacookie[1].dmac_laddress + 16; 1229 1230 tbp->txb_dmacookie[2].dmac_size = 1231 tbp->txb_dmacookie[0].dmac_size - 16*2; 1232 tbp->txb_dmacookie[1].dmac_size = 16; 1233 tbp->txb_dmacookie[0].dmac_size = 16; 1234 tbp->txb_nfrags = 3; 1235 } 1236 #endif 1237 } 1238 #pragma inline(gem_setup_txbuf_copy) 1239 1240 __INLINE__ 1241 static void 1242 gem_tx_start_unit(struct gem_dev *dp) 1243 { 1244 seqnum_t head; 1245 seqnum_t tail; 1246 struct txbuf *tbp_head; 1247 struct txbuf *tbp_tail; 1248 1249 /* update HW descriptors from soft queue */ 1250 ASSERT(mutex_owned(&dp->xmitlock)); 1251 ASSERT(dp->tx_softq_head == dp->tx_active_tail); 1252 1253 head = dp->tx_softq_head; 1254 tail = dp->tx_softq_tail; 1255 1256 DPRINTF(1, (CE_CONT, 1257 "%s: %s: called, softq %d %d[+%d], desc %d %d[+%d]", 1258 dp->name, __func__, head, tail, tail - head, 1259 dp->tx_desc_head, dp->tx_desc_tail, 1260 dp->tx_desc_tail - dp->tx_desc_head)); 1261 1262 ASSERT(tail - head > 0); 1263 1264 dp->tx_desc_tail = tail; 1265 1266 tbp_head = GET_TXBUF(dp, head); 1267 tbp_tail = GET_TXBUF(dp, tail - 1); 1268 1269 ASSERT(tbp_tail->txb_desc + tbp_tail->txb_ndescs == dp->tx_desc_tail); 1270 1271 dp->gc.gc_tx_start(dp, 1272 SLOT(tbp_head->txb_desc, dp->gc.gc_tx_ring_size), 1273 tbp_tail->txb_desc + tbp_tail->txb_ndescs - tbp_head->txb_desc); 1274 1275 /* advance softq head and active tail */ 1276 dp->tx_softq_head = dp->tx_active_tail = tail; 1277 } 1278 #pragma inline(gem_tx_start_unit) 1279 1280 #ifdef GEM_DEBUG_LEVEL 1281 static int gem_send_cnt[10]; 1282 #endif 1283 1284 /* 1285 * gem_send_common is an exported function because hw depend routines may 1286 * use it for sending control frames like setup frames for 2114x chipset. 1287 */ 1288 mblk_t * 1289 gem_send_common(struct gem_dev *dp, mblk_t *mp_head, uint32_t flags) 1290 { 1291 int nmblk; 1292 int avail; 1293 mblk_t *tp; 1294 mblk_t *mp; 1295 int i = 0; 1296 struct txbuf *tbp; 1297 seqnum_t head; 1298 seqnum_t intr; 1299 uint64_t load_flags; 1300 uint64_t len_total = 0; 1301 uint64_t packets = 0; 1302 uint32_t vtag; 1303 1304 ASSERT(mp_head != NULL); 1305 1306 mp = mp_head; 1307 nmblk = 1; 1308 while ((mp = mp->b_next) != NULL) { 1309 nmblk++; 1310 } 1311 #ifdef GEM_DEBUG_LEVEL 1312 gem_send_cnt[0]++; 1313 gem_send_cnt[min(nmblk, 9)]++; 1314 #endif 1315 /* 1316 * Aquire resources 1317 */ 1318 mutex_enter(&dp->xmitlock); 1319 1320 if (dp->mac_suspended) { 1321 mutex_exit(&dp->xmitlock); 1322 mp = mp_head; 1323 while (mp) { 1324 tp = mp->b_next; 1325 freemsg(mp); 1326 mp = tp; 1327 } 1328 return (NULL); 1329 } 1330 1331 if (!dp->mac_active && (flags & GEM_SEND_CTRL) == 0) { 1332 /* don't send data packets while mac isn't active */ 1333 mutex_exit(&dp->xmitlock); 1334 return (mp_head); 1335 } 1336 1337 /* allocate free slots */ 1338 head = dp->tx_free_head; 1339 avail = dp->tx_free_tail - head; 1340 1341 DPRINTF(2, (CE_CONT, 1342 "!%s: %s: called, free_head:%d free_tail:%d(+%d) req:%d", 1343 dp->name, __func__, 1344 dp->tx_free_head, dp->tx_free_tail, avail, nmblk)); 1345 1346 if ((dp->misc_flag & GEM_CTRL_PKT) && 1347 (flags & GEM_SEND_CTRL) == 0 && avail > 0) { 1348 /* reserve a txbuffer for sending control packets */ 1349 avail--; 1350 } 1351 1352 if (nmblk > avail) { 1353 if (avail == 0) { 1354 /* no resources; short cut */ 1355 DPRINTF(2, (CE_CONT, "!%s: no resources", __func__)); 1356 goto done; 1357 } 1358 nmblk = avail; 1359 } 1360 1361 dp->tx_free_head = head + nmblk; 1362 load_flags = ((dp->tx_busy++) == 0) ? GEM_TXFLAG_HEAD : 0; 1363 1364 /* calculate next interrupt position */ 1365 intr = head + avail; /* free tail */ 1366 1367 /* 1368 * update interrupt position if it is in the range of 1369 * allcated tx buffers and we are using out of order way. 1370 */ 1371 if ((head + nmblk) - intr >= 0 && 1372 intr - dp->tx_desc_intr > 0) { 1373 dp->tx_desc_intr = intr; 1374 } 1375 mutex_exit(&dp->xmitlock); 1376 1377 tbp = GET_TXBUF(dp, head); 1378 1379 i = nmblk; 1380 do { 1381 size_t len; 1382 uint8_t *bp; 1383 #define PKT_MIN_SIZE (sizeof (struct ether_header) + 10 + VTAG_SIZE) 1384 1385 /* remove one from the mblk list */ 1386 ASSERT(mp_head != NULL); 1387 mp = mp_head; 1388 mp_head = mp_head->b_next; 1389 mp->b_next = NULL; 1390 1391 /* save misc info */ 1392 tbp->txb_flag = 1393 (flags & GEM_SEND_CTRL) << GEM_TXFLAG_PRIVATE_SHIFT; 1394 1395 /* 1396 * prepare the header of the packet for further analysis 1397 */ 1398 if ((long)mp->b_wptr - (long)mp->b_rptr < PKT_MIN_SIZE) { 1399 int off; 1400 1401 /* we use bounce buffer for the packet */ 1402 bp = (uint8_t *)tbp->txb_buf; 1403 for (tp = mp, off = 0; 1404 tp && (off < PKT_MIN_SIZE); 1405 tp = tp->b_cont, off += len) { 1406 len = min((long)tp->b_wptr - (long)tp->b_rptr, 1407 PKT_MIN_SIZE - off); 1408 bcopy(tp->b_rptr, &bp[off], len); 1409 } 1410 } else { 1411 bp = mp->b_rptr; 1412 } 1413 #undef PKT_MIN_SIZE 1414 1415 if ((bp[0] & 1) && (flags & GEM_SEND_CTRL) == 0) { 1416 /* statistics for non-unicast packets */ 1417 if (bcmp(bp, gem_etherbroadcastaddr.ether_addr_octet, 1418 ETHERADDRL) == 0) { 1419 dp->stats.obcast++; 1420 } else { 1421 dp->stats.omcast++; 1422 } 1423 } 1424 1425 /* process vlan tag for GLD v3 */ 1426 if (GET_NET16(&bp[VTAG_OFF]) == VTAG_TPID) { 1427 if (dp->misc_flag & GEM_VLAN_HARD) { 1428 vtag = GET_NET16(&bp[VTAG_OFF + 2]); 1429 ASSERT(vtag); 1430 tbp->txb_flag |= vtag << GEM_TXFLAG_VTAG_SHIFT; 1431 } else { 1432 tbp->txb_flag |= GEM_TXFLAG_SWVTAG; 1433 } 1434 } 1435 1436 gem_setup_txbuf_copy(dp, mp, tbp); 1437 tbp = tbp->txb_next; 1438 } while (--i > 0); 1439 1440 (void) gem_tx_load_descs_oo(dp, 1441 head, head + nmblk, intr - 1, load_flags); 1442 1443 /* Append the tbp at the tail of the active tx buffer list */ 1444 mutex_enter(&dp->xmitlock); 1445 1446 if ((--dp->tx_busy) == 0) { 1447 /* extend the tail of softq, as new packets have been ready. */ 1448 dp->tx_softq_tail = dp->tx_free_head; 1449 1450 if (!dp->mac_active && (flags & GEM_SEND_CTRL) == 0) { 1451 /* 1452 * The device status has changed while we are 1453 * preparing tx buf. 1454 * As we are the last one that make tx non-busy. 1455 * wake up someone who may wait for us. 1456 */ 1457 cv_broadcast(&dp->tx_drain_cv); 1458 } else { 1459 ASSERT(dp->tx_softq_tail - dp->tx_softq_head > 0); 1460 gem_tx_start_unit(dp); 1461 } 1462 } 1463 dp->stats.obytes += len_total; 1464 dp->stats.opackets += packets; 1465 1466 done: 1467 if (mp_head) { 1468 /* 1469 * We mark the tx side as blocked. The state will be 1470 * kept until we'll unblock tx side explicitly. 1471 */ 1472 dp->tx_blocked = B_TRUE; 1473 } 1474 mutex_exit(&dp->xmitlock); 1475 1476 return (mp_head); 1477 } 1478 1479 /* ========================================================== */ 1480 /* 1481 * error detection and restart routines 1482 */ 1483 /* ========================================================== */ 1484 int 1485 gem_restart_nic(struct gem_dev *dp, uint_t flags) 1486 { 1487 ASSERT(mutex_owned(&dp->intrlock)); 1488 1489 DPRINTF(1, (CE_CONT, "!%s: %s: called: tx_desc:%d %d %d", 1490 dp->name, __func__, 1491 dp->tx_active_head, dp->tx_active_tail, dp->tx_desc_intr)); 1492 1493 if (dp->mac_suspended) { 1494 /* should we return GEM_FAILURE ? */ 1495 return (GEM_FAILURE); 1496 } 1497 1498 /* 1499 * We should avoid calling any routines except xxx_chip_reset 1500 * when we are resuming the system. 1501 */ 1502 if (dp->mac_active) { 1503 if (flags & GEM_RESTART_KEEP_BUF) { 1504 /* stop rx gracefully */ 1505 dp->rxmode &= ~RXMODE_ENABLE; 1506 (void) (*dp->gc.gc_set_rx_filter)(dp); 1507 } 1508 (void) gem_mac_stop(dp, flags); 1509 } 1510 1511 /* reset the chip. */ 1512 if ((*dp->gc.gc_reset_chip)(dp) != GEM_SUCCESS) { 1513 cmn_err(CE_WARN, "%s: %s: failed to reset chip", 1514 dp->name, __func__); 1515 goto err; 1516 } 1517 1518 if (gem_mac_init(dp) != GEM_SUCCESS) { 1519 goto err; 1520 } 1521 1522 /* setup media mode if the link have been up */ 1523 if (dp->mii_state == MII_STATE_LINKUP) { 1524 if ((dp->gc.gc_set_media)(dp) != GEM_SUCCESS) { 1525 goto err; 1526 } 1527 } 1528 1529 /* setup mac address and enable rx filter */ 1530 dp->rxmode |= RXMODE_ENABLE; 1531 if ((*dp->gc.gc_set_rx_filter)(dp) != GEM_SUCCESS) { 1532 goto err; 1533 } 1534 1535 /* 1536 * XXX - a panic happended because of linkdown. 1537 * We must check mii_state here, because the link can be down just 1538 * before the restart event happen. If the link is down now, 1539 * gem_mac_start() will be called from gem_mii_link_check() when 1540 * the link become up later. 1541 */ 1542 if (dp->mii_state == MII_STATE_LINKUP) { 1543 /* restart the nic */ 1544 ASSERT(!dp->mac_active); 1545 (void) gem_mac_start(dp); 1546 } 1547 return (GEM_SUCCESS); 1548 err: 1549 return (GEM_FAILURE); 1550 } 1551 1552 1553 static void 1554 gem_tx_timeout(struct gem_dev *dp) 1555 { 1556 clock_t now; 1557 boolean_t tx_sched; 1558 struct txbuf *tbp; 1559 1560 mutex_enter(&dp->intrlock); 1561 1562 tx_sched = B_FALSE; 1563 now = ddi_get_lbolt(); 1564 1565 mutex_enter(&dp->xmitlock); 1566 if (!dp->mac_active || dp->mii_state != MII_STATE_LINKUP) { 1567 mutex_exit(&dp->xmitlock); 1568 goto schedule_next; 1569 } 1570 mutex_exit(&dp->xmitlock); 1571 1572 /* reclaim transmitted buffers to check the trasmitter hangs or not. */ 1573 if (gem_reclaim_txbuf(dp) != GEM_SUCCESS) { 1574 /* tx error happened, reset transmitter in the chip */ 1575 (void) gem_restart_nic(dp, 0); 1576 tx_sched = B_TRUE; 1577 dp->tx_blocked = B_FALSE; 1578 1579 goto schedule_next; 1580 } 1581 1582 mutex_enter(&dp->xmitlock); 1583 /* check if the transmitter is stuck */ 1584 if (dp->tx_active_head == dp->tx_active_tail) { 1585 /* no tx buffer is loaded to the nic */ 1586 mutex_exit(&dp->xmitlock); 1587 goto schedule_next; 1588 } 1589 1590 tbp = GET_TXBUF(dp, dp->tx_active_head); 1591 if (now - tbp->txb_stime < dp->gc.gc_tx_timeout) { 1592 mutex_exit(&dp->xmitlock); 1593 goto schedule_next; 1594 } 1595 mutex_exit(&dp->xmitlock); 1596 1597 gem_dump_txbuf(dp, CE_WARN, __func__); 1598 1599 /* discard untransmitted packet and restart tx. */ 1600 (void) gem_restart_nic(dp, 0); 1601 tx_sched = B_TRUE; 1602 dp->tx_blocked = B_FALSE; 1603 1604 schedule_next: 1605 mutex_exit(&dp->intrlock); 1606 1607 /* restart the downstream if needed */ 1608 if (tx_sched) { 1609 mac_tx_update(dp->mh); 1610 } 1611 1612 DPRINTF(4, (CE_CONT, 1613 "!%s: blocked:%d desc_head:%d desc_tail:%d desc_intr:%d", 1614 dp->name, dp->tx_blocked, 1615 dp->tx_active_head, dp->tx_active_tail, dp->tx_desc_intr)); 1616 dp->timeout_id = 1617 timeout((void (*)(void *))gem_tx_timeout, 1618 (void *)dp, dp->gc.gc_tx_timeout_interval); 1619 } 1620 1621 /* ================================================================== */ 1622 /* 1623 * Interrupt handler 1624 */ 1625 /* ================================================================== */ 1626 __INLINE__ 1627 static void 1628 gem_append_rxbuf(struct gem_dev *dp, struct rxbuf *rbp_head) 1629 { 1630 struct rxbuf *rbp; 1631 seqnum_t tail; 1632 int rx_ring_size = dp->gc.gc_rx_ring_size; 1633 1634 ASSERT(rbp_head != NULL); 1635 ASSERT(mutex_owned(&dp->intrlock)); 1636 1637 DPRINTF(3, (CE_CONT, "!%s: %s: slot_head:%d, slot_tail:%d", 1638 dp->name, __func__, dp->rx_active_head, dp->rx_active_tail)); 1639 1640 /* 1641 * Add new buffers into active rx buffer list 1642 */ 1643 if (dp->rx_buf_head == NULL) { 1644 dp->rx_buf_head = rbp_head; 1645 ASSERT(dp->rx_buf_tail == NULL); 1646 } else { 1647 dp->rx_buf_tail->rxb_next = rbp_head; 1648 } 1649 1650 tail = dp->rx_active_tail; 1651 for (rbp = rbp_head; rbp; rbp = rbp->rxb_next) { 1652 /* need to notify the tail for the lower layer */ 1653 dp->rx_buf_tail = rbp; 1654 1655 dp->gc.gc_rx_desc_write(dp, 1656 SLOT(tail, rx_ring_size), 1657 rbp->rxb_dmacookie, 1658 rbp->rxb_nfrags); 1659 1660 dp->rx_active_tail = tail = tail + 1; 1661 } 1662 } 1663 #pragma inline(gem_append_rxbuf) 1664 1665 mblk_t * 1666 gem_get_packet_default(struct gem_dev *dp, struct rxbuf *rbp, size_t len) 1667 { 1668 int rx_header_len = dp->gc.gc_rx_header_len; 1669 uint8_t *bp; 1670 mblk_t *mp; 1671 1672 /* allocate a new mblk */ 1673 if (mp = allocb(len + VTAG_SIZE, BPRI_MED)) { 1674 ASSERT(mp->b_next == NULL); 1675 ASSERT(mp->b_cont == NULL); 1676 1677 mp->b_rptr += VTAG_SIZE; 1678 bp = mp->b_rptr; 1679 mp->b_wptr = bp + len; 1680 1681 (void) ddi_dma_sync(rbp->rxb_dh, rx_header_len, 1682 len, DDI_DMA_SYNC_FORKERNEL); 1683 1684 bcopy(rbp->rxb_buf + rx_header_len, bp, len); 1685 } 1686 return (mp); 1687 } 1688 1689 #ifdef GEM_DEBUG_LEVEL 1690 uint_t gem_rx_pkts[17]; 1691 #endif 1692 1693 1694 int 1695 gem_receive(struct gem_dev *dp) 1696 { 1697 uint64_t len_total = 0; 1698 struct rxbuf *rbp; 1699 mblk_t *mp; 1700 int cnt = 0; 1701 uint64_t rxstat; 1702 struct rxbuf *newbufs; 1703 struct rxbuf **newbufs_tailp; 1704 mblk_t *rx_head; 1705 mblk_t **rx_tailp; 1706 int rx_ring_size = dp->gc.gc_rx_ring_size; 1707 seqnum_t active_head; 1708 uint64_t (*rx_desc_stat)(struct gem_dev *dp, 1709 int slot, int ndesc); 1710 uint16_t vtag; 1711 int ethermin = ETHERMIN; 1712 int ethermax = dp->mtu + sizeof (struct ether_header); 1713 1714 ASSERT(mutex_owned(&dp->intrlock)); 1715 1716 DPRINTF(3, (CE_CONT, "!%s: gem_receive: rx_buf_head:%p", 1717 dp->name, dp->rx_buf_head)); 1718 1719 rx_desc_stat = dp->gc.gc_rx_desc_stat; 1720 newbufs_tailp = &newbufs; 1721 rx_tailp = &rx_head; 1722 for (active_head = dp->rx_active_head; 1723 (rbp = dp->rx_buf_head) != NULL; active_head++) { 1724 int len; 1725 if (cnt == 0) { 1726 cnt = max(dp->poll_pkt_delay*2, 10); 1727 cnt = min(cnt, 1728 dp->rx_active_tail - active_head); 1729 gem_rx_desc_dma_sync(dp, 1730 SLOT(active_head, rx_ring_size), 1731 cnt, 1732 DDI_DMA_SYNC_FORKERNEL); 1733 } 1734 if (((rxstat = (*rx_desc_stat)(dp, 1735 SLOT(active_head, rx_ring_size), 1736 rbp->rxb_nfrags)) 1737 & (GEM_RX_DONE | GEM_RX_ERR)) == 0) { 1738 /* not received yet */ 1739 break; 1740 } 1741 1742 /* Remove the head of the rx buffer list */ 1743 dp->rx_buf_head = rbp->rxb_next; 1744 cnt--; 1745 1746 1747 if (rxstat & GEM_RX_ERR) { 1748 goto next; 1749 } 1750 1751 len = rxstat & GEM_RX_LEN; 1752 DPRINTF(3, (CE_CONT, "!%s: %s: rxstat:0x%llx, len:0x%x", 1753 dp->name, __func__, rxstat, len)); 1754 1755 /* 1756 * Copy the packet 1757 */ 1758 if ((mp = dp->gc.gc_get_packet(dp, rbp, len)) == NULL) { 1759 /* no memory, discard the packet */ 1760 dp->stats.norcvbuf++; 1761 goto next; 1762 } 1763 1764 /* 1765 * Process VLAN tag 1766 */ 1767 ethermin = ETHERMIN; 1768 ethermax = dp->mtu + sizeof (struct ether_header); 1769 vtag = (rxstat & GEM_RX_VTAG) >> GEM_RX_VTAG_SHIFT; 1770 if (vtag) { 1771 /* insert vlan vtag extracted by the hardware */ 1772 gem_add_vtag(mp, vtag); 1773 len += VTAG_SIZE; 1774 ethermax += VTAG_SIZE; 1775 } else if (GET_NET16(mp->b_rptr + VTAG_OFF) == VTAG_TPID) { 1776 1777 ethermax += VTAG_SIZE; 1778 } 1779 1780 /* check packet size */ 1781 if (len < ethermin) { 1782 dp->stats.errrcv++; 1783 dp->stats.runt++; 1784 freemsg(mp); 1785 goto next; 1786 } 1787 1788 if (len > ethermax) { 1789 dp->stats.errrcv++; 1790 dp->stats.frame_too_long++; 1791 freemsg(mp); 1792 goto next; 1793 } 1794 1795 len_total += len; 1796 1797 /* append received packet to temporaly rx buffer list */ 1798 *rx_tailp = mp; 1799 rx_tailp = &mp->b_next; 1800 1801 if (mp->b_rptr[0] & 1) { 1802 if (bcmp(mp->b_rptr, 1803 gem_etherbroadcastaddr.ether_addr_octet, 1804 ETHERADDRL) == 0) { 1805 dp->stats.rbcast++; 1806 } else { 1807 dp->stats.rmcast++; 1808 } 1809 } 1810 next: 1811 ASSERT(rbp != NULL); 1812 1813 /* append new one to temporal new buffer list */ 1814 *newbufs_tailp = rbp; 1815 newbufs_tailp = &rbp->rxb_next; 1816 } 1817 1818 /* advance rx_active_head */ 1819 if ((cnt = active_head - dp->rx_active_head) > 0) { 1820 dp->stats.rbytes += len_total; 1821 dp->stats.rpackets += cnt; 1822 } 1823 dp->rx_active_head = active_head; 1824 1825 /* terminate the working list */ 1826 *newbufs_tailp = NULL; 1827 *rx_tailp = NULL; 1828 1829 if (dp->rx_buf_head == NULL) { 1830 dp->rx_buf_tail = NULL; 1831 } 1832 1833 DPRINTF(4, (CE_CONT, "%s: %s: cnt:%d, rx_head:%p", 1834 dp->name, __func__, cnt, rx_head)); 1835 1836 if (newbufs) { 1837 /* 1838 * fillfull rx list with new buffers 1839 */ 1840 seqnum_t head; 1841 1842 /* save current tail */ 1843 head = dp->rx_active_tail; 1844 gem_append_rxbuf(dp, newbufs); 1845 1846 /* call hw depend start routine if we have. */ 1847 dp->gc.gc_rx_start(dp, 1848 SLOT(head, rx_ring_size), dp->rx_active_tail - head); 1849 } 1850 1851 if (rx_head) { 1852 /* 1853 * send up received packets 1854 */ 1855 mutex_exit(&dp->intrlock); 1856 mac_rx(dp->mh, dp->mac_rx_ring_ha, rx_head); 1857 mutex_enter(&dp->intrlock); 1858 } 1859 1860 #ifdef GEM_DEBUG_LEVEL 1861 gem_rx_pkts[min(cnt, sizeof (gem_rx_pkts)/sizeof (uint_t)-1)]++; 1862 #endif 1863 return (cnt); 1864 } 1865 1866 boolean_t 1867 gem_tx_done(struct gem_dev *dp) 1868 { 1869 boolean_t tx_sched = B_FALSE; 1870 1871 if (gem_reclaim_txbuf(dp) != GEM_SUCCESS) { 1872 (void) gem_restart_nic(dp, GEM_RESTART_KEEP_BUF); 1873 DPRINTF(2, (CE_CONT, "!%s: gem_tx_done: tx_desc: %d %d", 1874 dp->name, dp->tx_active_head, dp->tx_active_tail)); 1875 tx_sched = B_TRUE; 1876 goto x; 1877 } 1878 1879 mutex_enter(&dp->xmitlock); 1880 1881 /* XXX - for oo, we must not have any packets in soft queue */ 1882 ASSERT((!dp->gc.gc_tx_desc_write_oo) || 1883 dp->tx_softq_head == dp->tx_softq_tail); 1884 /* 1885 * if we won't have chance to get more free tx buffers, and blocked, 1886 * it is worth to reschedule the downstream i.e. tx side. 1887 */ 1888 if (dp->tx_blocked && (dp->tx_desc_intr == dp->tx_desc_head)) { 1889 /* 1890 * As no further tx-done interrupts are scheduled, this 1891 * is the last chance to kick tx side, which may be 1892 * blocked now, otherwise the tx side never works again. 1893 */ 1894 tx_sched = B_TRUE; 1895 dp->tx_blocked = B_FALSE; 1896 } 1897 1898 mutex_exit(&dp->xmitlock); 1899 1900 DPRINTF(3, (CE_CONT, "!%s: gem_tx_done: ret: blocked:%d", 1901 dp->name, dp->tx_blocked)); 1902 x: 1903 return (tx_sched); 1904 } 1905 1906 static uint_t 1907 gem_intr(struct gem_dev *dp) 1908 { 1909 uint_t ret; 1910 1911 mutex_enter(&dp->intrlock); 1912 if (dp->mac_suspended) { 1913 mutex_exit(&dp->intrlock); 1914 return (DDI_INTR_UNCLAIMED); 1915 } 1916 dp->intr_busy = B_TRUE; 1917 1918 ret = (*dp->gc.gc_interrupt)(dp); 1919 1920 if (ret == DDI_INTR_UNCLAIMED) { 1921 dp->intr_busy = B_FALSE; 1922 mutex_exit(&dp->intrlock); 1923 return (ret); 1924 } 1925 1926 if (!dp->mac_active) { 1927 cv_broadcast(&dp->tx_drain_cv); 1928 } 1929 1930 1931 dp->stats.intr++; 1932 dp->intr_busy = B_FALSE; 1933 1934 mutex_exit(&dp->intrlock); 1935 1936 if (ret & INTR_RESTART_TX) { 1937 DPRINTF(4, (CE_CONT, "!%s: calling mac_tx_update", dp->name)); 1938 mac_tx_update(dp->mh); 1939 ret &= ~INTR_RESTART_TX; 1940 } 1941 return (ret); 1942 } 1943 1944 static void 1945 gem_intr_watcher(struct gem_dev *dp) 1946 { 1947 (void) gem_intr(dp); 1948 1949 /* schedule next call of tu_intr_watcher */ 1950 dp->intr_watcher_id = 1951 timeout((void (*)(void *))gem_intr_watcher, (void *)dp, 1); 1952 } 1953 1954 /* ======================================================================== */ 1955 /* 1956 * MII support routines 1957 */ 1958 /* ======================================================================== */ 1959 static void 1960 gem_choose_forcedmode(struct gem_dev *dp) 1961 { 1962 /* choose media mode */ 1963 if (dp->anadv_1000fdx || dp->anadv_1000hdx) { 1964 dp->speed = GEM_SPD_1000; 1965 dp->full_duplex = dp->anadv_1000fdx; 1966 } else if (dp->anadv_100fdx || dp->anadv_100t4) { 1967 dp->speed = GEM_SPD_100; 1968 dp->full_duplex = B_TRUE; 1969 } else if (dp->anadv_100hdx) { 1970 dp->speed = GEM_SPD_100; 1971 dp->full_duplex = B_FALSE; 1972 } else { 1973 dp->speed = GEM_SPD_10; 1974 dp->full_duplex = dp->anadv_10fdx; 1975 } 1976 } 1977 1978 uint16_t 1979 gem_mii_read(struct gem_dev *dp, uint_t reg) 1980 { 1981 if ((dp->mii_status & MII_STATUS_MFPRMBLSUPR) == 0) { 1982 (*dp->gc.gc_mii_sync)(dp); 1983 } 1984 return ((*dp->gc.gc_mii_read)(dp, reg)); 1985 } 1986 1987 void 1988 gem_mii_write(struct gem_dev *dp, uint_t reg, uint16_t val) 1989 { 1990 if ((dp->mii_status & MII_STATUS_MFPRMBLSUPR) == 0) { 1991 (*dp->gc.gc_mii_sync)(dp); 1992 } 1993 (*dp->gc.gc_mii_write)(dp, reg, val); 1994 } 1995 1996 #define fc_cap_decode(x) \ 1997 ((((x) & MII_ABILITY_PAUSE) ? 1 : 0) | \ 1998 (((x) & MII_ABILITY_ASM_DIR) ? 2 : 0)) 1999 2000 int 2001 gem_mii_config_default(struct gem_dev *dp) 2002 { 2003 uint16_t mii_stat; 2004 uint16_t val; 2005 static uint16_t fc_cap_encode[4] = { 2006 /* none */ 0, 2007 /* symmetric */ MII_ABILITY_PAUSE, 2008 /* tx */ MII_ABILITY_ASM_DIR, 2009 /* rx-symmetric */ MII_ABILITY_PAUSE | MII_ABILITY_ASM_DIR, 2010 }; 2011 2012 DPRINTF(1, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 2013 2014 /* 2015 * Configure bits in advertisement register 2016 */ 2017 mii_stat = dp->mii_status; 2018 2019 DPRINTF(1, (CE_CONT, "!%s: %s: MII_STATUS reg:%b", 2020 dp->name, __func__, mii_stat, MII_STATUS_BITS)); 2021 2022 if ((mii_stat & MII_STATUS_ABILITY_TECH) == 0) { 2023 /* it's funny */ 2024 cmn_err(CE_WARN, "!%s: wrong ability bits: mii_status:%b", 2025 dp->name, mii_stat, MII_STATUS_BITS); 2026 return (GEM_FAILURE); 2027 } 2028 2029 /* Do not change the rest of the ability bits in the advert reg */ 2030 val = gem_mii_read(dp, MII_AN_ADVERT) & ~MII_ABILITY_ALL; 2031 2032 DPRINTF(0, (CE_CONT, 2033 "!%s: %s: 100T4:%d 100F:%d 100H:%d 10F:%d 10H:%d", 2034 dp->name, __func__, 2035 dp->anadv_100t4, dp->anadv_100fdx, dp->anadv_100hdx, 2036 dp->anadv_10fdx, dp->anadv_10hdx)); 2037 2038 if (dp->anadv_100t4) { 2039 val |= MII_ABILITY_100BASE_T4; 2040 } 2041 if (dp->anadv_100fdx) { 2042 val |= MII_ABILITY_100BASE_TX_FD; 2043 } 2044 if (dp->anadv_100hdx) { 2045 val |= MII_ABILITY_100BASE_TX; 2046 } 2047 if (dp->anadv_10fdx) { 2048 val |= MII_ABILITY_10BASE_T_FD; 2049 } 2050 if (dp->anadv_10hdx) { 2051 val |= MII_ABILITY_10BASE_T; 2052 } 2053 2054 /* set flow control capability */ 2055 val |= fc_cap_encode[dp->anadv_flow_control]; 2056 2057 DPRINTF(0, (CE_CONT, 2058 "!%s: %s: setting MII_AN_ADVERT reg:%b, mii_mode:%d, fc:%d", 2059 dp->name, __func__, val, MII_ABILITY_BITS, dp->gc.gc_mii_mode, 2060 dp->anadv_flow_control)); 2061 2062 gem_mii_write(dp, MII_AN_ADVERT, val); 2063 2064 if (mii_stat & MII_STATUS_XSTATUS) { 2065 /* 2066 * 1000Base-T GMII support 2067 */ 2068 if (!dp->anadv_autoneg) { 2069 /* enable manual configuration */ 2070 val = MII_1000TC_CFG_EN; 2071 } else { 2072 val = 0; 2073 if (dp->anadv_1000fdx) { 2074 val |= MII_1000TC_ADV_FULL; 2075 } 2076 if (dp->anadv_1000hdx) { 2077 val |= MII_1000TC_ADV_HALF; 2078 } 2079 } 2080 DPRINTF(0, (CE_CONT, 2081 "!%s: %s: setting MII_1000TC reg:%b", 2082 dp->name, __func__, val, MII_1000TC_BITS)); 2083 2084 gem_mii_write(dp, MII_1000TC, val); 2085 } 2086 2087 return (GEM_SUCCESS); 2088 } 2089 2090 #define GEM_LINKUP(dp) mac_link_update((dp)->mh, LINK_STATE_UP) 2091 #define GEM_LINKDOWN(dp) mac_link_update((dp)->mh, LINK_STATE_DOWN) 2092 2093 static uint8_t gem_fc_result[4 /* my cap */ ][4 /* lp cap */] = { 2094 /* none symm tx rx/symm */ 2095 /* none */ 2096 {FLOW_CONTROL_NONE, 2097 FLOW_CONTROL_NONE, 2098 FLOW_CONTROL_NONE, 2099 FLOW_CONTROL_NONE}, 2100 /* sym */ 2101 {FLOW_CONTROL_NONE, 2102 FLOW_CONTROL_SYMMETRIC, 2103 FLOW_CONTROL_NONE, 2104 FLOW_CONTROL_SYMMETRIC}, 2105 /* tx */ 2106 {FLOW_CONTROL_NONE, 2107 FLOW_CONTROL_NONE, 2108 FLOW_CONTROL_NONE, 2109 FLOW_CONTROL_TX_PAUSE}, 2110 /* rx/symm */ 2111 {FLOW_CONTROL_NONE, 2112 FLOW_CONTROL_SYMMETRIC, 2113 FLOW_CONTROL_RX_PAUSE, 2114 FLOW_CONTROL_SYMMETRIC}, 2115 }; 2116 2117 static char *gem_fc_type[] = { 2118 "without", 2119 "with symmetric", 2120 "with tx", 2121 "with rx", 2122 }; 2123 2124 boolean_t 2125 gem_mii_link_check(struct gem_dev *dp) 2126 { 2127 uint16_t old_mii_state; 2128 boolean_t tx_sched = B_FALSE; 2129 uint16_t status; 2130 uint16_t advert; 2131 uint16_t lpable; 2132 uint16_t exp; 2133 uint16_t ctl1000; 2134 uint16_t stat1000; 2135 uint16_t val; 2136 clock_t now; 2137 clock_t diff; 2138 int linkdown_action; 2139 boolean_t fix_phy = B_FALSE; 2140 2141 now = ddi_get_lbolt(); 2142 old_mii_state = dp->mii_state; 2143 2144 DPRINTF(3, (CE_CONT, "!%s: %s: time:%d state:%d", 2145 dp->name, __func__, now, dp->mii_state)); 2146 2147 diff = now - dp->mii_last_check; 2148 dp->mii_last_check = now; 2149 2150 next_nowait: 2151 switch (dp->mii_state) { 2152 case MII_STATE_UNKNOWN: 2153 /* power-up, DP83840 requires 32 sync bits */ 2154 (*dp->gc.gc_mii_sync)(dp); 2155 goto reset_phy; 2156 2157 case MII_STATE_RESETTING: 2158 dp->mii_timer -= diff; 2159 if (dp->mii_timer > 0) { 2160 /* don't read phy registers in resetting */ 2161 dp->mii_interval = WATCH_INTERVAL_FAST; 2162 goto next; 2163 } 2164 2165 /* Timer expired, ensure reset bit is not set */ 2166 2167 if (dp->mii_status & MII_STATUS_MFPRMBLSUPR) { 2168 /* some phys need sync bits after reset */ 2169 (*dp->gc.gc_mii_sync)(dp); 2170 } 2171 val = gem_mii_read(dp, MII_CONTROL); 2172 if (val & MII_CONTROL_RESET) { 2173 cmn_err(CE_NOTE, 2174 "!%s: time:%ld resetting phy not complete." 2175 " mii_control:0x%b", 2176 dp->name, ddi_get_lbolt(), 2177 val, MII_CONTROL_BITS); 2178 } 2179 2180 /* ensure neither isolated nor pwrdown nor auto-nego mode */ 2181 /* XXX -- this operation is required for NS DP83840A. */ 2182 gem_mii_write(dp, MII_CONTROL, 0); 2183 2184 /* As resetting PHY has completed, configure PHY registers */ 2185 if ((*dp->gc.gc_mii_config)(dp) != GEM_SUCCESS) { 2186 /* we failed to configure PHY. */ 2187 goto reset_phy; 2188 } 2189 2190 /* mii_config may disable autonegatiation */ 2191 gem_choose_forcedmode(dp); 2192 2193 dp->mii_lpable = 0; 2194 dp->mii_advert = 0; 2195 dp->mii_exp = 0; 2196 dp->mii_ctl1000 = 0; 2197 dp->mii_stat1000 = 0; 2198 dp->flow_control = FLOW_CONTROL_NONE; 2199 2200 if (!dp->anadv_autoneg) { 2201 /* skip auto-negotiation phase */ 2202 dp->mii_state = MII_STATE_MEDIA_SETUP; 2203 dp->mii_timer = 0; 2204 dp->mii_interval = 0; 2205 goto next_nowait; 2206 } 2207 2208 /* Issue auto-negotiation command */ 2209 goto autonego; 2210 2211 case MII_STATE_AUTONEGOTIATING: 2212 /* 2213 * Autonegotiation is in progress 2214 */ 2215 dp->mii_timer -= diff; 2216 if (dp->mii_timer - 2217 (dp->gc.gc_mii_an_timeout 2218 - dp->gc.gc_mii_an_wait) > 0) { 2219 /* 2220 * wait for a while, typically autonegotiation 2221 * completes in 2.3 - 2.5 sec. 2222 */ 2223 dp->mii_interval = WATCH_INTERVAL_FAST; 2224 goto next; 2225 } 2226 2227 /* read PHY status */ 2228 status = gem_mii_read(dp, MII_STATUS); 2229 DPRINTF(4, (CE_CONT, 2230 "!%s: %s: called: mii_state:%d MII_STATUS reg:%b", 2231 dp->name, __func__, dp->mii_state, 2232 status, MII_STATUS_BITS)); 2233 2234 if (status & MII_STATUS_REMFAULT) { 2235 /* 2236 * The link parnert told me something wrong happend. 2237 * What do we do ? 2238 */ 2239 cmn_err(CE_CONT, 2240 "!%s: auto-negotiation failed: remote fault", 2241 dp->name); 2242 goto autonego; 2243 } 2244 2245 if ((status & MII_STATUS_ANDONE) == 0) { 2246 if (dp->mii_timer <= 0) { 2247 /* 2248 * Auto-negotiation was timed out, 2249 * try again w/o resetting phy. 2250 */ 2251 if (!dp->mii_supress_msg) { 2252 cmn_err(CE_WARN, 2253 "!%s: auto-negotiation failed: timeout", 2254 dp->name); 2255 dp->mii_supress_msg = B_TRUE; 2256 } 2257 goto autonego; 2258 } 2259 /* 2260 * Auto-negotiation is in progress. Wait. 2261 */ 2262 dp->mii_interval = dp->gc.gc_mii_an_watch_interval; 2263 goto next; 2264 } 2265 2266 /* 2267 * Auto-negotiation have completed. 2268 * Assume linkdown and fall through. 2269 */ 2270 dp->mii_supress_msg = B_FALSE; 2271 dp->mii_state = MII_STATE_AN_DONE; 2272 DPRINTF(0, (CE_CONT, 2273 "!%s: auto-negotiation completed, MII_STATUS:%b", 2274 dp->name, status, MII_STATUS_BITS)); 2275 2276 if (dp->gc.gc_mii_an_delay > 0) { 2277 dp->mii_timer = dp->gc.gc_mii_an_delay; 2278 dp->mii_interval = drv_usectohz(20*1000); 2279 goto next; 2280 } 2281 2282 dp->mii_timer = 0; 2283 diff = 0; 2284 goto next_nowait; 2285 2286 case MII_STATE_AN_DONE: 2287 /* 2288 * Auto-negotiation have done. Now we can set up media. 2289 */ 2290 dp->mii_timer -= diff; 2291 if (dp->mii_timer > 0) { 2292 /* wait for a while */ 2293 dp->mii_interval = WATCH_INTERVAL_FAST; 2294 goto next; 2295 } 2296 2297 /* 2298 * set up the result of auto negotiation 2299 */ 2300 2301 /* 2302 * Read registers required to determin current 2303 * duplex mode and media speed. 2304 */ 2305 if (dp->gc.gc_mii_an_delay > 0) { 2306 /* 2307 * As the link watcher context has been suspended, 2308 * 'status' is invalid. We must status register here 2309 */ 2310 status = gem_mii_read(dp, MII_STATUS); 2311 } 2312 advert = gem_mii_read(dp, MII_AN_ADVERT); 2313 lpable = gem_mii_read(dp, MII_AN_LPABLE); 2314 exp = gem_mii_read(dp, MII_AN_EXPANSION); 2315 if (exp == 0xffff) { 2316 /* some phys don't have exp register */ 2317 exp = 0; 2318 } 2319 ctl1000 = 0; 2320 stat1000 = 0; 2321 if (dp->mii_status & MII_STATUS_XSTATUS) { 2322 ctl1000 = gem_mii_read(dp, MII_1000TC); 2323 stat1000 = gem_mii_read(dp, MII_1000TS); 2324 } 2325 dp->mii_lpable = lpable; 2326 dp->mii_advert = advert; 2327 dp->mii_exp = exp; 2328 dp->mii_ctl1000 = ctl1000; 2329 dp->mii_stat1000 = stat1000; 2330 2331 cmn_err(CE_CONT, 2332 "!%s: auto-negotiation done, advert:%b, lpable:%b, exp:%b", 2333 dp->name, 2334 advert, MII_ABILITY_BITS, 2335 lpable, MII_ABILITY_BITS, 2336 exp, MII_AN_EXP_BITS); 2337 2338 if (dp->mii_status & MII_STATUS_XSTATUS) { 2339 cmn_err(CE_CONT, 2340 "! MII_1000TC:%b, MII_1000TS:%b", 2341 ctl1000, MII_1000TC_BITS, 2342 stat1000, MII_1000TS_BITS); 2343 } 2344 2345 if (gem_population(lpable) <= 1 && 2346 (exp & MII_AN_EXP_LPCANAN) == 0) { 2347 if ((advert & MII_ABILITY_TECH) != lpable) { 2348 cmn_err(CE_WARN, 2349 "!%s: but the link partnar doesn't seem" 2350 " to have auto-negotiation capability." 2351 " please check the link configuration.", 2352 dp->name); 2353 } 2354 /* 2355 * it should be result of pararell detection, which 2356 * cannot detect duplex mode. 2357 */ 2358 if (lpable & MII_ABILITY_100BASE_TX) { 2359 /* 2360 * we prefer full duplex mode for 100Mbps 2361 * connection, if we can. 2362 */ 2363 lpable |= advert & MII_ABILITY_100BASE_TX_FD; 2364 } 2365 2366 if ((advert & lpable) == 0 && 2367 lpable & MII_ABILITY_10BASE_T) { 2368 lpable |= advert & MII_ABILITY_10BASE_T_FD; 2369 } 2370 /* 2371 * as the link partnar isn't auto-negotiatable, use 2372 * fixed mode temporally. 2373 */ 2374 fix_phy = B_TRUE; 2375 } else if (lpable == 0) { 2376 cmn_err(CE_WARN, "!%s: wrong lpable.", dp->name); 2377 goto reset_phy; 2378 } 2379 /* 2380 * configure current link mode according to AN priority. 2381 */ 2382 val = advert & lpable; 2383 if ((ctl1000 & MII_1000TC_ADV_FULL) && 2384 (stat1000 & MII_1000TS_LP_FULL)) { 2385 /* 1000BaseT & full duplex */ 2386 dp->speed = GEM_SPD_1000; 2387 dp->full_duplex = B_TRUE; 2388 } else if ((ctl1000 & MII_1000TC_ADV_HALF) && 2389 (stat1000 & MII_1000TS_LP_HALF)) { 2390 /* 1000BaseT & half duplex */ 2391 dp->speed = GEM_SPD_1000; 2392 dp->full_duplex = B_FALSE; 2393 } else if (val & MII_ABILITY_100BASE_TX_FD) { 2394 /* 100BaseTx & full duplex */ 2395 dp->speed = GEM_SPD_100; 2396 dp->full_duplex = B_TRUE; 2397 } else if (val & MII_ABILITY_100BASE_T4) { 2398 /* 100BaseT4 & full duplex */ 2399 dp->speed = GEM_SPD_100; 2400 dp->full_duplex = B_TRUE; 2401 } else if (val & MII_ABILITY_100BASE_TX) { 2402 /* 100BaseTx & half duplex */ 2403 dp->speed = GEM_SPD_100; 2404 dp->full_duplex = B_FALSE; 2405 } else if (val & MII_ABILITY_10BASE_T_FD) { 2406 /* 10BaseT & full duplex */ 2407 dp->speed = GEM_SPD_10; 2408 dp->full_duplex = B_TRUE; 2409 } else if (val & MII_ABILITY_10BASE_T) { 2410 /* 10BaseT & half duplex */ 2411 dp->speed = GEM_SPD_10; 2412 dp->full_duplex = B_FALSE; 2413 } else { 2414 /* 2415 * It seems that the link partnar doesn't have 2416 * auto-negotiation capability and our PHY 2417 * could not report the correct current mode. 2418 * We guess current mode by mii_control register. 2419 */ 2420 val = gem_mii_read(dp, MII_CONTROL); 2421 2422 /* select 100m full or 10m half */ 2423 dp->speed = (val & MII_CONTROL_100MB) ? 2424 GEM_SPD_100 : GEM_SPD_10; 2425 dp->full_duplex = dp->speed != GEM_SPD_10; 2426 fix_phy = B_TRUE; 2427 2428 cmn_err(CE_NOTE, 2429 "!%s: auto-negotiation done but " 2430 "common ability not found.\n" 2431 "PHY state: control:%b advert:%b lpable:%b\n" 2432 "guessing %d Mbps %s duplex mode", 2433 dp->name, 2434 val, MII_CONTROL_BITS, 2435 advert, MII_ABILITY_BITS, 2436 lpable, MII_ABILITY_BITS, 2437 gem_speed_value[dp->speed], 2438 dp->full_duplex ? "full" : "half"); 2439 } 2440 2441 if (dp->full_duplex) { 2442 dp->flow_control = 2443 gem_fc_result[fc_cap_decode(advert)] 2444 [fc_cap_decode(lpable)]; 2445 } else { 2446 dp->flow_control = FLOW_CONTROL_NONE; 2447 } 2448 dp->mii_state = MII_STATE_MEDIA_SETUP; 2449 /* FALLTHROUGH */ 2450 2451 case MII_STATE_MEDIA_SETUP: 2452 dp->mii_state = MII_STATE_LINKDOWN; 2453 dp->mii_timer = dp->gc.gc_mii_linkdown_timeout; 2454 DPRINTF(2, (CE_CONT, "!%s: setup midia mode done", dp->name)); 2455 dp->mii_supress_msg = B_FALSE; 2456 2457 /* use short interval */ 2458 dp->mii_interval = WATCH_INTERVAL_FAST; 2459 2460 if ((!dp->anadv_autoneg) || 2461 dp->gc.gc_mii_an_oneshot || fix_phy) { 2462 2463 /* 2464 * write specified mode to phy. 2465 */ 2466 val = gem_mii_read(dp, MII_CONTROL); 2467 val &= ~(MII_CONTROL_SPEED | MII_CONTROL_FDUPLEX | 2468 MII_CONTROL_ANE | MII_CONTROL_RSAN); 2469 2470 if (dp->full_duplex) { 2471 val |= MII_CONTROL_FDUPLEX; 2472 } 2473 2474 switch (dp->speed) { 2475 case GEM_SPD_1000: 2476 val |= MII_CONTROL_1000MB; 2477 break; 2478 2479 case GEM_SPD_100: 2480 val |= MII_CONTROL_100MB; 2481 break; 2482 2483 default: 2484 cmn_err(CE_WARN, "%s: unknown speed:%d", 2485 dp->name, dp->speed); 2486 /* FALLTHROUGH */ 2487 case GEM_SPD_10: 2488 /* for GEM_SPD_10, do nothing */ 2489 break; 2490 } 2491 2492 if (dp->mii_status & MII_STATUS_XSTATUS) { 2493 gem_mii_write(dp, 2494 MII_1000TC, MII_1000TC_CFG_EN); 2495 } 2496 gem_mii_write(dp, MII_CONTROL, val); 2497 } 2498 2499 if (dp->nic_state >= NIC_STATE_INITIALIZED) { 2500 /* notify the result of auto-negotiation to mac */ 2501 (*dp->gc.gc_set_media)(dp); 2502 } 2503 2504 if ((void *)dp->gc.gc_mii_tune_phy) { 2505 /* for built-in sis900 */ 2506 /* XXX - this code should be removed. */ 2507 (*dp->gc.gc_mii_tune_phy)(dp); 2508 } 2509 2510 goto next_nowait; 2511 2512 case MII_STATE_LINKDOWN: 2513 status = gem_mii_read(dp, MII_STATUS); 2514 if (status & MII_STATUS_LINKUP) { 2515 /* 2516 * Link going up 2517 */ 2518 dp->mii_state = MII_STATE_LINKUP; 2519 dp->mii_supress_msg = B_FALSE; 2520 2521 DPRINTF(0, (CE_CONT, 2522 "!%s: link up detected: mii_stat:%b", 2523 dp->name, status, MII_STATUS_BITS)); 2524 2525 /* 2526 * MII_CONTROL_100MB and MII_CONTROL_FDUPLEX are 2527 * ignored when MII_CONTROL_ANE is set. 2528 */ 2529 cmn_err(CE_CONT, 2530 "!%s: Link up: %d Mbps %s duplex %s flow control", 2531 dp->name, 2532 gem_speed_value[dp->speed], 2533 dp->full_duplex ? "full" : "half", 2534 gem_fc_type[dp->flow_control]); 2535 2536 dp->mii_interval = dp->gc.gc_mii_link_watch_interval; 2537 2538 /* XXX - we need other timer to watch statictics */ 2539 if (dp->gc.gc_mii_hw_link_detection && 2540 dp->nic_state == NIC_STATE_ONLINE) { 2541 dp->mii_interval = 0; 2542 } 2543 2544 if (dp->nic_state == NIC_STATE_ONLINE) { 2545 if (!dp->mac_active) { 2546 (void) gem_mac_start(dp); 2547 } 2548 tx_sched = B_TRUE; 2549 if (dp->tx_blocked) { 2550 dp->tx_blocked = B_FALSE; 2551 } 2552 } 2553 goto next; 2554 } 2555 2556 dp->mii_supress_msg = B_TRUE; 2557 if (dp->anadv_autoneg) { 2558 dp->mii_timer -= diff; 2559 if (dp->mii_timer <= 0) { 2560 /* 2561 * link down timer expired. 2562 * need to restart auto-negotiation. 2563 */ 2564 linkdown_action = 2565 dp->gc.gc_mii_linkdown_timeout_action; 2566 goto restart_autonego; 2567 } 2568 } 2569 /* don't change mii_state */ 2570 break; 2571 2572 case MII_STATE_LINKUP: 2573 status = gem_mii_read(dp, MII_STATUS); 2574 if ((status & MII_STATUS_LINKUP) == 0) { 2575 /* 2576 * Link going down 2577 */ 2578 cmn_err(CE_NOTE, 2579 "!%s: link down detected: mii_stat:%b", 2580 dp->name, status, MII_STATUS_BITS); 2581 2582 if (dp->nic_state == NIC_STATE_ONLINE && 2583 dp->mac_active && 2584 dp->gc.gc_mii_stop_mac_on_linkdown) { 2585 (void) gem_mac_stop(dp, 0); 2586 } 2587 2588 if (dp->anadv_autoneg) { 2589 /* need to restart auto-negotiation */ 2590 linkdown_action = dp->gc.gc_mii_linkdown_action; 2591 goto restart_autonego; 2592 } 2593 2594 dp->mii_state = MII_STATE_LINKDOWN; 2595 dp->mii_timer = dp->gc.gc_mii_linkdown_timeout; 2596 2597 if ((void *)dp->gc.gc_mii_tune_phy) { 2598 /* for built-in sis900 */ 2599 (*dp->gc.gc_mii_tune_phy)(dp); 2600 } 2601 dp->mii_interval = dp->gc.gc_mii_link_watch_interval; 2602 goto next; 2603 } 2604 2605 /* don't change mii_state */ 2606 if (dp->gc.gc_mii_hw_link_detection && 2607 dp->nic_state == NIC_STATE_ONLINE) { 2608 dp->mii_interval = 0; 2609 goto next; 2610 } 2611 break; 2612 } 2613 dp->mii_interval = dp->gc.gc_mii_link_watch_interval; 2614 goto next; 2615 2616 /* Actions on the end of state routine */ 2617 2618 restart_autonego: 2619 switch (linkdown_action) { 2620 case MII_ACTION_RESET: 2621 if (!dp->mii_supress_msg) { 2622 cmn_err(CE_CONT, "!%s: resetting PHY", dp->name); 2623 } 2624 dp->mii_supress_msg = B_TRUE; 2625 goto reset_phy; 2626 2627 case MII_ACTION_NONE: 2628 dp->mii_supress_msg = B_TRUE; 2629 if (dp->gc.gc_mii_an_oneshot) { 2630 goto autonego; 2631 } 2632 /* PHY will restart autonego automatically */ 2633 dp->mii_state = MII_STATE_AUTONEGOTIATING; 2634 dp->mii_timer = dp->gc.gc_mii_an_timeout; 2635 dp->mii_interval = dp->gc.gc_mii_an_watch_interval; 2636 goto next; 2637 2638 case MII_ACTION_RSA: 2639 if (!dp->mii_supress_msg) { 2640 cmn_err(CE_CONT, "!%s: restarting auto-negotiation", 2641 dp->name); 2642 } 2643 dp->mii_supress_msg = B_TRUE; 2644 goto autonego; 2645 2646 default: 2647 cmn_err(CE_WARN, "!%s: unknowm linkdown action: %d", 2648 dp->name, dp->gc.gc_mii_linkdown_action); 2649 dp->mii_supress_msg = B_TRUE; 2650 } 2651 /* NOTREACHED */ 2652 2653 reset_phy: 2654 if (!dp->mii_supress_msg) { 2655 cmn_err(CE_CONT, "!%s: resetting PHY", dp->name); 2656 } 2657 dp->mii_state = MII_STATE_RESETTING; 2658 dp->mii_timer = dp->gc.gc_mii_reset_timeout; 2659 if (!dp->gc.gc_mii_dont_reset) { 2660 gem_mii_write(dp, MII_CONTROL, MII_CONTROL_RESET); 2661 } 2662 dp->mii_interval = WATCH_INTERVAL_FAST; 2663 goto next; 2664 2665 autonego: 2666 if (!dp->mii_supress_msg) { 2667 cmn_err(CE_CONT, "!%s: auto-negotiation started", dp->name); 2668 } 2669 dp->mii_state = MII_STATE_AUTONEGOTIATING; 2670 dp->mii_timer = dp->gc.gc_mii_an_timeout; 2671 2672 /* start/restart auto nego */ 2673 val = gem_mii_read(dp, MII_CONTROL) & 2674 ~(MII_CONTROL_ISOLATE | MII_CONTROL_PWRDN | MII_CONTROL_RESET); 2675 2676 if (val & MII_CONTROL_ANE) { 2677 /* restart auto nego */ 2678 gem_mii_write(dp, MII_CONTROL, val | MII_CONTROL_RSAN); 2679 } else { 2680 /* enable auto nego */ 2681 /* XXX - it doesn't work for mx98315 */ 2682 gem_mii_write(dp, MII_CONTROL, val | MII_CONTROL_ANE); 2683 } 2684 2685 dp->mii_interval = dp->gc.gc_mii_an_watch_interval; 2686 2687 next: 2688 if (dp->link_watcher_id == 0 && dp->mii_interval) { 2689 /* we must schedule next mii_watcher */ 2690 dp->link_watcher_id = 2691 timeout((void (*)(void *))& gem_mii_link_watcher, 2692 (void *)dp, dp->mii_interval); 2693 } 2694 2695 if (old_mii_state == MII_STATE_UNKNOWN || 2696 old_mii_state != dp->mii_state) { 2697 /* notify new mii link state */ 2698 if (dp->mii_state == MII_STATE_LINKUP) { 2699 GEM_LINKUP(dp); 2700 } else { 2701 GEM_LINKDOWN(dp); 2702 } 2703 } 2704 return (tx_sched); 2705 } 2706 2707 static void 2708 gem_mii_link_watcher(struct gem_dev *dp) 2709 { 2710 boolean_t tx_sched; 2711 2712 mutex_enter(&dp->intrlock); 2713 2714 dp->link_watcher_id = 0; 2715 tx_sched = gem_mii_link_check(dp); 2716 #if GEM_DEBUG_LEVEL > 2 2717 if (dp->link_watcher_id == 0) { 2718 cmn_err(CE_CONT, "%s: link watcher stopped", dp->name); 2719 } 2720 #endif 2721 mutex_exit(&dp->intrlock); 2722 2723 if (tx_sched) { 2724 /* kick potentially stopped downstream */ 2725 mac_tx_update(dp->mh); 2726 } 2727 } 2728 2729 int 2730 gem_mii_probe_default(struct gem_dev *dp) 2731 { 2732 int8_t phy; 2733 uint16_t status; 2734 uint16_t adv; 2735 uint16_t adv_org; 2736 2737 DPRINTF(3, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 2738 2739 /* 2740 * Scan PHY 2741 */ 2742 /* ensure to send sync bits */ 2743 dp->mii_status = 0; 2744 2745 /* Try default phy first */ 2746 if (dp->mii_phy_addr) { 2747 status = gem_mii_read(dp, MII_STATUS); 2748 if (status != 0xffff && status != 0) { 2749 gem_mii_write(dp, MII_CONTROL, 0); 2750 goto PHY_found; 2751 } 2752 2753 if (dp->mii_phy_addr < 0) { 2754 cmn_err(CE_NOTE, 2755 "!%s: failed to probe default internal and/or non-MII PHY", 2756 dp->name); 2757 return (GEM_FAILURE); 2758 } 2759 2760 cmn_err(CE_NOTE, 2761 "!%s: failed to probe default MII PHY at %d", 2762 dp->name, dp->mii_phy_addr); 2763 } 2764 2765 /* Try all possible address */ 2766 for (phy = dp->gc.gc_mii_addr_min; phy < 32; phy++) { 2767 dp->mii_phy_addr = phy; 2768 status = gem_mii_read(dp, MII_STATUS); 2769 2770 if (status != 0xffff && status != 0) { 2771 gem_mii_write(dp, MII_CONTROL, 0); 2772 goto PHY_found; 2773 } 2774 } 2775 2776 for (phy = dp->gc.gc_mii_addr_min; phy < 32; phy++) { 2777 dp->mii_phy_addr = phy; 2778 gem_mii_write(dp, MII_CONTROL, 0); 2779 status = gem_mii_read(dp, MII_STATUS); 2780 2781 if (status != 0xffff && status != 0) { 2782 goto PHY_found; 2783 } 2784 } 2785 2786 cmn_err(CE_NOTE, "!%s: no MII PHY found", dp->name); 2787 dp->mii_phy_addr = -1; 2788 2789 return (GEM_FAILURE); 2790 2791 PHY_found: 2792 dp->mii_status = status; 2793 dp->mii_phy_id = (gem_mii_read(dp, MII_PHYIDH) << 16) | 2794 gem_mii_read(dp, MII_PHYIDL); 2795 2796 if (dp->mii_phy_addr < 0) { 2797 cmn_err(CE_CONT, "!%s: using internal/non-MII PHY(0x%08x)", 2798 dp->name, dp->mii_phy_id); 2799 } else { 2800 cmn_err(CE_CONT, "!%s: MII PHY (0x%08x) found at %d", 2801 dp->name, dp->mii_phy_id, dp->mii_phy_addr); 2802 } 2803 2804 cmn_err(CE_CONT, "!%s: PHY control:%b, status:%b, advert:%b, lpar:%b", 2805 dp->name, 2806 gem_mii_read(dp, MII_CONTROL), MII_CONTROL_BITS, 2807 status, MII_STATUS_BITS, 2808 gem_mii_read(dp, MII_AN_ADVERT), MII_ABILITY_BITS, 2809 gem_mii_read(dp, MII_AN_LPABLE), MII_ABILITY_BITS); 2810 2811 dp->mii_xstatus = 0; 2812 if (status & MII_STATUS_XSTATUS) { 2813 dp->mii_xstatus = gem_mii_read(dp, MII_XSTATUS); 2814 2815 cmn_err(CE_CONT, "!%s: xstatus:%b", 2816 dp->name, dp->mii_xstatus, MII_XSTATUS_BITS); 2817 } 2818 2819 /* check if the phy can advertize pause abilities */ 2820 adv_org = gem_mii_read(dp, MII_AN_ADVERT); 2821 2822 gem_mii_write(dp, MII_AN_ADVERT, 2823 MII_ABILITY_PAUSE | MII_ABILITY_ASM_DIR); 2824 2825 adv = gem_mii_read(dp, MII_AN_ADVERT); 2826 2827 if ((adv & MII_ABILITY_PAUSE) == 0) { 2828 dp->gc.gc_flow_control &= ~1; 2829 } 2830 2831 if ((adv & MII_ABILITY_ASM_DIR) == 0) { 2832 dp->gc.gc_flow_control &= ~2; 2833 } 2834 2835 gem_mii_write(dp, MII_AN_ADVERT, adv_org); 2836 2837 return (GEM_SUCCESS); 2838 } 2839 2840 static void 2841 gem_mii_start(struct gem_dev *dp) 2842 { 2843 DPRINTF(3, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 2844 2845 /* make a first call of check link */ 2846 dp->mii_state = MII_STATE_UNKNOWN; 2847 dp->mii_last_check = ddi_get_lbolt(); 2848 (void) gem_mii_link_watcher(dp); 2849 } 2850 2851 static void 2852 gem_mii_stop(struct gem_dev *dp) 2853 { 2854 DPRINTF(3, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 2855 2856 /* Ensure timer routine stopped */ 2857 mutex_enter(&dp->intrlock); 2858 if (dp->link_watcher_id) { 2859 while (untimeout(dp->link_watcher_id) == -1) 2860 ; 2861 dp->link_watcher_id = 0; 2862 } 2863 mutex_exit(&dp->intrlock); 2864 } 2865 2866 boolean_t 2867 gem_get_mac_addr_conf(struct gem_dev *dp) 2868 { 2869 char propname[32]; 2870 char *valstr; 2871 uint8_t mac[ETHERADDRL]; 2872 char *cp; 2873 int c; 2874 int i; 2875 int j; 2876 uint8_t v; 2877 uint8_t d; 2878 uint8_t ored; 2879 2880 DPRINTF(3, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 2881 /* 2882 * Get ethernet address from .conf file 2883 */ 2884 (void) sprintf(propname, "mac-addr"); 2885 if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, dp->dip, 2886 DDI_PROP_DONTPASS, propname, &valstr)) != 2887 DDI_PROP_SUCCESS) { 2888 return (B_FALSE); 2889 } 2890 2891 if (strlen(valstr) != ETHERADDRL*3-1) { 2892 goto syntax_err; 2893 } 2894 2895 cp = valstr; 2896 j = 0; 2897 ored = 0; 2898 for (;;) { 2899 v = 0; 2900 for (i = 0; i < 2; i++) { 2901 c = *cp++; 2902 2903 if (c >= 'a' && c <= 'f') { 2904 d = c - 'a' + 10; 2905 } else if (c >= 'A' && c <= 'F') { 2906 d = c - 'A' + 10; 2907 } else if (c >= '0' && c <= '9') { 2908 d = c - '0'; 2909 } else { 2910 goto syntax_err; 2911 } 2912 v = (v << 4) | d; 2913 } 2914 2915 mac[j++] = v; 2916 ored |= v; 2917 if (j == ETHERADDRL) { 2918 /* done */ 2919 break; 2920 } 2921 2922 c = *cp++; 2923 if (c != ':') { 2924 goto syntax_err; 2925 } 2926 } 2927 2928 if (ored == 0) { 2929 goto err; 2930 } 2931 for (i = 0; i < ETHERADDRL; i++) { 2932 dp->dev_addr.ether_addr_octet[i] = mac[i]; 2933 } 2934 ddi_prop_free(valstr); 2935 return (B_TRUE); 2936 2937 syntax_err: 2938 cmn_err(CE_CONT, 2939 "!%s: read mac addr: trying .conf: syntax err %s", 2940 dp->name, valstr); 2941 err: 2942 ddi_prop_free(valstr); 2943 2944 return (B_FALSE); 2945 } 2946 2947 2948 /* ============================================================== */ 2949 /* 2950 * internal start/stop interface 2951 */ 2952 /* ============================================================== */ 2953 static int 2954 gem_mac_set_rx_filter(struct gem_dev *dp) 2955 { 2956 return ((*dp->gc.gc_set_rx_filter)(dp)); 2957 } 2958 2959 /* 2960 * gem_mac_init: cold start 2961 */ 2962 static int 2963 gem_mac_init(struct gem_dev *dp) 2964 { 2965 DPRINTF(1, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 2966 2967 if (dp->mac_suspended) { 2968 return (GEM_FAILURE); 2969 } 2970 2971 dp->mac_active = B_FALSE; 2972 2973 gem_init_rx_ring(dp); 2974 gem_init_tx_ring(dp); 2975 2976 /* reset transmitter state */ 2977 dp->tx_blocked = B_FALSE; 2978 dp->tx_busy = 0; 2979 dp->tx_reclaim_busy = 0; 2980 2981 if ((*dp->gc.gc_init_chip)(dp) != GEM_SUCCESS) { 2982 return (GEM_FAILURE); 2983 } 2984 2985 gem_prepare_rx_buf(dp); 2986 2987 return (GEM_SUCCESS); 2988 } 2989 /* 2990 * gem_mac_start: warm start 2991 */ 2992 static int 2993 gem_mac_start(struct gem_dev *dp) 2994 { 2995 DPRINTF(1, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 2996 2997 ASSERT(mutex_owned(&dp->intrlock)); 2998 ASSERT(dp->nic_state == NIC_STATE_ONLINE); 2999 ASSERT(dp->mii_state == MII_STATE_LINKUP); 3000 3001 /* enable tx and rx */ 3002 mutex_enter(&dp->xmitlock); 3003 if (dp->mac_suspended) { 3004 mutex_exit(&dp->xmitlock); 3005 return (GEM_FAILURE); 3006 } 3007 dp->mac_active = B_TRUE; 3008 mutex_exit(&dp->xmitlock); 3009 3010 if ((*dp->gc.gc_start_chip)(dp) != GEM_SUCCESS) { 3011 cmn_err(CE_WARN, "%s: %s: start_chip: failed", 3012 dp->name, __func__); 3013 return (GEM_FAILURE); 3014 } 3015 3016 /* kick rx */ 3017 dp->gc.gc_rx_start(dp, 3018 SLOT(dp->rx_active_head, dp->gc.gc_rx_ring_size), 3019 dp->rx_active_tail - dp->rx_active_head); 3020 3021 mutex_enter(&dp->xmitlock); 3022 3023 /* load untranmitted packets to the nic */ 3024 ASSERT(dp->tx_softq_tail - dp->tx_softq_head >= 0); 3025 if (dp->tx_softq_tail - dp->tx_softq_head > 0) { 3026 gem_tx_load_descs_oo(dp, 3027 dp->tx_softq_head, dp->tx_softq_tail, 3028 dp->tx_free_tail - 1, 3029 GEM_TXFLAG_HEAD); 3030 /* issue preloaded tx buffers */ 3031 gem_tx_start_unit(dp); 3032 } 3033 3034 mutex_exit(&dp->xmitlock); 3035 3036 return (GEM_SUCCESS); 3037 } 3038 3039 static int 3040 gem_mac_stop(struct gem_dev *dp, uint_t flags) 3041 { 3042 int i; 3043 int wait_time; /* in uS */ 3044 #ifdef GEM_DEBUG_LEVEL 3045 clock_t now; 3046 #endif 3047 int ret = GEM_SUCCESS; 3048 3049 DPRINTF(1, (CE_CONT, "!%s: %s: called, rx_buf_free:%d", 3050 dp->name, __func__, dp->rx_buf_freecnt)); 3051 3052 ASSERT(mutex_owned(&dp->intrlock)); 3053 ASSERT(!mutex_owned(&dp->xmitlock)); 3054 3055 /* 3056 * Block transmits 3057 */ 3058 mutex_enter(&dp->xmitlock); 3059 if (dp->mac_suspended) { 3060 mutex_exit(&dp->xmitlock); 3061 return (GEM_SUCCESS); 3062 } 3063 dp->mac_active = B_FALSE; 3064 3065 while (dp->tx_busy > 0) { 3066 cv_wait(&dp->tx_drain_cv, &dp->xmitlock); 3067 } 3068 mutex_exit(&dp->xmitlock); 3069 3070 if ((flags & GEM_RESTART_NOWAIT) == 0) { 3071 /* 3072 * Wait for all tx buffers sent. 3073 */ 3074 wait_time = 3075 2 * (8 * MAXPKTBUF(dp) / gem_speed_value[dp->speed]) * 3076 (dp->tx_active_tail - dp->tx_active_head); 3077 3078 DPRINTF(0, (CE_CONT, "%s: %s: max drain time: %d uS", 3079 dp->name, __func__, wait_time)); 3080 i = 0; 3081 #ifdef GEM_DEBUG_LEVEL 3082 now = ddi_get_lbolt(); 3083 #endif 3084 while (dp->tx_active_tail != dp->tx_active_head) { 3085 if (i > wait_time) { 3086 /* timeout */ 3087 cmn_err(CE_NOTE, "%s: %s timeout: tx drain", 3088 dp->name, __func__); 3089 break; 3090 } 3091 (void) gem_reclaim_txbuf(dp); 3092 drv_usecwait(100); 3093 i += 100; 3094 } 3095 DPRINTF(0, (CE_NOTE, 3096 "!%s: %s: the nic have drained in %d uS, real %d mS", 3097 dp->name, __func__, i, 3098 10*((int)(ddi_get_lbolt() - now)))); 3099 } 3100 3101 /* 3102 * Now we can stop the nic safely. 3103 */ 3104 if ((*dp->gc.gc_stop_chip)(dp) != GEM_SUCCESS) { 3105 cmn_err(CE_NOTE, "%s: %s: resetting the chip to stop it", 3106 dp->name, __func__); 3107 if ((*dp->gc.gc_reset_chip)(dp) != GEM_SUCCESS) { 3108 cmn_err(CE_WARN, "%s: %s: failed to reset chip", 3109 dp->name, __func__); 3110 } 3111 } 3112 3113 /* 3114 * Clear all rx buffers 3115 */ 3116 if (flags & GEM_RESTART_KEEP_BUF) { 3117 (void) gem_receive(dp); 3118 } 3119 gem_clean_rx_buf(dp); 3120 3121 /* 3122 * Update final statistics 3123 */ 3124 (*dp->gc.gc_get_stats)(dp); 3125 3126 /* 3127 * Clear all pended tx packets 3128 */ 3129 ASSERT(dp->tx_active_tail == dp->tx_softq_head); 3130 ASSERT(dp->tx_softq_tail == dp->tx_free_head); 3131 if (flags & GEM_RESTART_KEEP_BUF) { 3132 /* restore active tx buffers */ 3133 dp->tx_active_tail = dp->tx_active_head; 3134 dp->tx_softq_head = dp->tx_active_head; 3135 } else { 3136 gem_clean_tx_buf(dp); 3137 } 3138 3139 return (ret); 3140 } 3141 3142 static int 3143 gem_add_multicast(struct gem_dev *dp, const uint8_t *ep) 3144 { 3145 int cnt; 3146 int err; 3147 3148 DPRINTF(1, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 3149 3150 mutex_enter(&dp->intrlock); 3151 if (dp->mac_suspended) { 3152 mutex_exit(&dp->intrlock); 3153 return (GEM_FAILURE); 3154 } 3155 3156 if (dp->mc_count_req++ < GEM_MAXMC) { 3157 /* append the new address at the end of the mclist */ 3158 cnt = dp->mc_count; 3159 bcopy(ep, dp->mc_list[cnt].addr.ether_addr_octet, 3160 ETHERADDRL); 3161 if (dp->gc.gc_multicast_hash) { 3162 dp->mc_list[cnt].hash = 3163 (*dp->gc.gc_multicast_hash)(dp, (uint8_t *)ep); 3164 } 3165 dp->mc_count = cnt + 1; 3166 } 3167 3168 if (dp->mc_count_req != dp->mc_count) { 3169 /* multicast address list overflow */ 3170 dp->rxmode |= RXMODE_MULTI_OVF; 3171 } else { 3172 dp->rxmode &= ~RXMODE_MULTI_OVF; 3173 } 3174 3175 /* tell the new multicast list to the hardwaire */ 3176 err = gem_mac_set_rx_filter(dp); 3177 3178 mutex_exit(&dp->intrlock); 3179 3180 return (err); 3181 } 3182 3183 static int 3184 gem_remove_multicast(struct gem_dev *dp, const uint8_t *ep) 3185 { 3186 size_t len; 3187 int i; 3188 int cnt; 3189 int err; 3190 3191 DPRINTF(1, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 3192 3193 mutex_enter(&dp->intrlock); 3194 if (dp->mac_suspended) { 3195 mutex_exit(&dp->intrlock); 3196 return (GEM_FAILURE); 3197 } 3198 3199 dp->mc_count_req--; 3200 cnt = dp->mc_count; 3201 for (i = 0; i < cnt; i++) { 3202 if (bcmp(ep, &dp->mc_list[i].addr, ETHERADDRL)) { 3203 continue; 3204 } 3205 /* shrink the mclist by copying forward */ 3206 len = (cnt - (i + 1)) * sizeof (*dp->mc_list); 3207 if (len > 0) { 3208 bcopy(&dp->mc_list[i+1], &dp->mc_list[i], len); 3209 } 3210 dp->mc_count--; 3211 break; 3212 } 3213 3214 if (dp->mc_count_req != dp->mc_count) { 3215 /* multicast address list overflow */ 3216 dp->rxmode |= RXMODE_MULTI_OVF; 3217 } else { 3218 dp->rxmode &= ~RXMODE_MULTI_OVF; 3219 } 3220 /* In gem v2, don't hold xmitlock on calling set_rx_filter */ 3221 err = gem_mac_set_rx_filter(dp); 3222 3223 mutex_exit(&dp->intrlock); 3224 3225 return (err); 3226 } 3227 3228 /* ============================================================== */ 3229 /* 3230 * ND interface 3231 */ 3232 /* ============================================================== */ 3233 enum { 3234 PARAM_AUTONEG_CAP, 3235 PARAM_PAUSE_CAP, 3236 PARAM_ASYM_PAUSE_CAP, 3237 PARAM_1000FDX_CAP, 3238 PARAM_1000HDX_CAP, 3239 PARAM_100T4_CAP, 3240 PARAM_100FDX_CAP, 3241 PARAM_100HDX_CAP, 3242 PARAM_10FDX_CAP, 3243 PARAM_10HDX_CAP, 3244 3245 PARAM_ADV_AUTONEG_CAP, 3246 PARAM_ADV_PAUSE_CAP, 3247 PARAM_ADV_ASYM_PAUSE_CAP, 3248 PARAM_ADV_1000FDX_CAP, 3249 PARAM_ADV_1000HDX_CAP, 3250 PARAM_ADV_100T4_CAP, 3251 PARAM_ADV_100FDX_CAP, 3252 PARAM_ADV_100HDX_CAP, 3253 PARAM_ADV_10FDX_CAP, 3254 PARAM_ADV_10HDX_CAP, 3255 3256 PARAM_LP_AUTONEG_CAP, 3257 PARAM_LP_PAUSE_CAP, 3258 PARAM_LP_ASYM_PAUSE_CAP, 3259 PARAM_LP_1000FDX_CAP, 3260 PARAM_LP_1000HDX_CAP, 3261 PARAM_LP_100T4_CAP, 3262 PARAM_LP_100FDX_CAP, 3263 PARAM_LP_100HDX_CAP, 3264 PARAM_LP_10FDX_CAP, 3265 PARAM_LP_10HDX_CAP, 3266 3267 PARAM_LINK_STATUS, 3268 PARAM_LINK_SPEED, 3269 PARAM_LINK_DUPLEX, 3270 3271 PARAM_LINK_AUTONEG, 3272 PARAM_LINK_RX_PAUSE, 3273 PARAM_LINK_TX_PAUSE, 3274 3275 PARAM_LOOP_MODE, 3276 PARAM_MSI_CNT, 3277 3278 #ifdef DEBUG_RESUME 3279 PARAM_RESUME_TEST, 3280 #endif 3281 PARAM_COUNT 3282 }; 3283 3284 enum ioc_reply { 3285 IOC_INVAL = -1, /* bad, NAK with EINVAL */ 3286 IOC_DONE, /* OK, reply sent */ 3287 IOC_ACK, /* OK, just send ACK */ 3288 IOC_REPLY, /* OK, just send reply */ 3289 IOC_RESTART_ACK, /* OK, restart & ACK */ 3290 IOC_RESTART_REPLY /* OK, restart & reply */ 3291 }; 3292 3293 struct gem_nd_arg { 3294 struct gem_dev *dp; 3295 int item; 3296 }; 3297 3298 static int 3299 gem_param_get(queue_t *q, mblk_t *mp, caddr_t arg, cred_t *credp) 3300 { 3301 struct gem_dev *dp = ((struct gem_nd_arg *)(void *)arg)->dp; 3302 int item = ((struct gem_nd_arg *)(void *)arg)->item; 3303 long val; 3304 3305 DPRINTF(0, (CE_CONT, "!%s: %s: called, item:%d", 3306 dp->name, __func__, item)); 3307 3308 switch (item) { 3309 case PARAM_AUTONEG_CAP: 3310 val = BOOLEAN(dp->mii_status & MII_STATUS_CANAUTONEG); 3311 DPRINTF(0, (CE_CONT, "autoneg_cap:%d", val)); 3312 break; 3313 3314 case PARAM_PAUSE_CAP: 3315 val = BOOLEAN(dp->gc.gc_flow_control & 1); 3316 break; 3317 3318 case PARAM_ASYM_PAUSE_CAP: 3319 val = BOOLEAN(dp->gc.gc_flow_control & 2); 3320 break; 3321 3322 case PARAM_1000FDX_CAP: 3323 val = (dp->mii_xstatus & MII_XSTATUS_1000BASET_FD) || 3324 (dp->mii_xstatus & MII_XSTATUS_1000BASEX_FD); 3325 break; 3326 3327 case PARAM_1000HDX_CAP: 3328 val = (dp->mii_xstatus & MII_XSTATUS_1000BASET) || 3329 (dp->mii_xstatus & MII_XSTATUS_1000BASEX); 3330 break; 3331 3332 case PARAM_100T4_CAP: 3333 val = BOOLEAN(dp->mii_status & MII_STATUS_100_BASE_T4); 3334 break; 3335 3336 case PARAM_100FDX_CAP: 3337 val = BOOLEAN(dp->mii_status & MII_STATUS_100_BASEX_FD); 3338 break; 3339 3340 case PARAM_100HDX_CAP: 3341 val = BOOLEAN(dp->mii_status & MII_STATUS_100_BASEX); 3342 break; 3343 3344 case PARAM_10FDX_CAP: 3345 val = BOOLEAN(dp->mii_status & MII_STATUS_10_FD); 3346 break; 3347 3348 case PARAM_10HDX_CAP: 3349 val = BOOLEAN(dp->mii_status & MII_STATUS_10); 3350 break; 3351 3352 case PARAM_ADV_AUTONEG_CAP: 3353 val = dp->anadv_autoneg; 3354 break; 3355 3356 case PARAM_ADV_PAUSE_CAP: 3357 val = BOOLEAN(dp->anadv_flow_control & 1); 3358 break; 3359 3360 case PARAM_ADV_ASYM_PAUSE_CAP: 3361 val = BOOLEAN(dp->anadv_flow_control & 2); 3362 break; 3363 3364 case PARAM_ADV_1000FDX_CAP: 3365 val = dp->anadv_1000fdx; 3366 break; 3367 3368 case PARAM_ADV_1000HDX_CAP: 3369 val = dp->anadv_1000hdx; 3370 break; 3371 3372 case PARAM_ADV_100T4_CAP: 3373 val = dp->anadv_100t4; 3374 break; 3375 3376 case PARAM_ADV_100FDX_CAP: 3377 val = dp->anadv_100fdx; 3378 break; 3379 3380 case PARAM_ADV_100HDX_CAP: 3381 val = dp->anadv_100hdx; 3382 break; 3383 3384 case PARAM_ADV_10FDX_CAP: 3385 val = dp->anadv_10fdx; 3386 break; 3387 3388 case PARAM_ADV_10HDX_CAP: 3389 val = dp->anadv_10hdx; 3390 break; 3391 3392 case PARAM_LP_AUTONEG_CAP: 3393 val = BOOLEAN(dp->mii_exp & MII_AN_EXP_LPCANAN); 3394 break; 3395 3396 case PARAM_LP_PAUSE_CAP: 3397 val = BOOLEAN(dp->mii_lpable & MII_ABILITY_PAUSE); 3398 break; 3399 3400 case PARAM_LP_ASYM_PAUSE_CAP: 3401 val = BOOLEAN(dp->mii_lpable & MII_ABILITY_ASM_DIR); 3402 break; 3403 3404 case PARAM_LP_1000FDX_CAP: 3405 val = BOOLEAN(dp->mii_stat1000 & MII_1000TS_LP_FULL); 3406 break; 3407 3408 case PARAM_LP_1000HDX_CAP: 3409 val = BOOLEAN(dp->mii_stat1000 & MII_1000TS_LP_HALF); 3410 break; 3411 3412 case PARAM_LP_100T4_CAP: 3413 val = BOOLEAN(dp->mii_lpable & MII_ABILITY_100BASE_T4); 3414 break; 3415 3416 case PARAM_LP_100FDX_CAP: 3417 val = BOOLEAN(dp->mii_lpable & MII_ABILITY_100BASE_TX_FD); 3418 break; 3419 3420 case PARAM_LP_100HDX_CAP: 3421 val = BOOLEAN(dp->mii_lpable & MII_ABILITY_100BASE_TX); 3422 break; 3423 3424 case PARAM_LP_10FDX_CAP: 3425 val = BOOLEAN(dp->mii_lpable & MII_ABILITY_10BASE_T_FD); 3426 break; 3427 3428 case PARAM_LP_10HDX_CAP: 3429 val = BOOLEAN(dp->mii_lpable & MII_ABILITY_10BASE_T); 3430 break; 3431 3432 case PARAM_LINK_STATUS: 3433 val = (dp->mii_state == MII_STATE_LINKUP); 3434 break; 3435 3436 case PARAM_LINK_SPEED: 3437 val = gem_speed_value[dp->speed]; 3438 break; 3439 3440 case PARAM_LINK_DUPLEX: 3441 val = 0; 3442 if (dp->mii_state == MII_STATE_LINKUP) { 3443 val = dp->full_duplex ? 2 : 1; 3444 } 3445 break; 3446 3447 case PARAM_LINK_AUTONEG: 3448 val = BOOLEAN(dp->mii_exp & MII_AN_EXP_LPCANAN); 3449 break; 3450 3451 case PARAM_LINK_RX_PAUSE: 3452 val = (dp->flow_control == FLOW_CONTROL_SYMMETRIC) || 3453 (dp->flow_control == FLOW_CONTROL_RX_PAUSE); 3454 break; 3455 3456 case PARAM_LINK_TX_PAUSE: 3457 val = (dp->flow_control == FLOW_CONTROL_SYMMETRIC) || 3458 (dp->flow_control == FLOW_CONTROL_TX_PAUSE); 3459 break; 3460 3461 #ifdef DEBUG_RESUME 3462 case PARAM_RESUME_TEST: 3463 val = 0; 3464 break; 3465 #endif 3466 default: 3467 cmn_err(CE_WARN, "%s: unimplemented ndd control (%d)", 3468 dp->name, item); 3469 break; 3470 } 3471 3472 (void) mi_mpprintf(mp, "%ld", val); 3473 3474 return (0); 3475 } 3476 3477 static int 3478 gem_param_set(queue_t *q, mblk_t *mp, char *value, caddr_t arg, cred_t *credp) 3479 { 3480 struct gem_dev *dp = ((struct gem_nd_arg *)(void *)arg)->dp; 3481 int item = ((struct gem_nd_arg *)(void *)arg)->item; 3482 long val; 3483 char *end; 3484 3485 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 3486 if (ddi_strtol(value, &end, 10, &val)) { 3487 return (EINVAL); 3488 } 3489 if (end == value) { 3490 return (EINVAL); 3491 } 3492 3493 switch (item) { 3494 case PARAM_ADV_AUTONEG_CAP: 3495 if (val != 0 && val != 1) { 3496 goto err; 3497 } 3498 if (val && (dp->mii_status & MII_STATUS_CANAUTONEG) == 0) { 3499 goto err; 3500 } 3501 dp->anadv_autoneg = (int)val; 3502 break; 3503 3504 case PARAM_ADV_PAUSE_CAP: 3505 if (val != 0 && val != 1) { 3506 goto err; 3507 } 3508 if (val) { 3509 dp->anadv_flow_control |= 1; 3510 } else { 3511 dp->anadv_flow_control &= ~1; 3512 } 3513 break; 3514 3515 case PARAM_ADV_ASYM_PAUSE_CAP: 3516 if (val != 0 && val != 1) { 3517 goto err; 3518 } 3519 if (val) { 3520 dp->anadv_flow_control |= 2; 3521 } else { 3522 dp->anadv_flow_control &= ~2; 3523 } 3524 break; 3525 3526 case PARAM_ADV_1000FDX_CAP: 3527 if (val != 0 && val != 1) { 3528 goto err; 3529 } 3530 if (val && (dp->mii_xstatus & 3531 (MII_XSTATUS_1000BASET_FD | 3532 MII_XSTATUS_1000BASEX_FD)) == 0) { 3533 goto err; 3534 } 3535 dp->anadv_1000fdx = (int)val; 3536 break; 3537 3538 case PARAM_ADV_1000HDX_CAP: 3539 if (val != 0 && val != 1) { 3540 goto err; 3541 } 3542 if (val && (dp->mii_xstatus & 3543 (MII_XSTATUS_1000BASET | MII_XSTATUS_1000BASEX)) == 0) { 3544 goto err; 3545 } 3546 dp->anadv_1000hdx = (int)val; 3547 break; 3548 3549 case PARAM_ADV_100T4_CAP: 3550 if (val != 0 && val != 1) { 3551 goto err; 3552 } 3553 if (val && (dp->mii_status & MII_STATUS_100_BASE_T4) == 0) { 3554 goto err; 3555 } 3556 dp->anadv_100t4 = (int)val; 3557 break; 3558 3559 case PARAM_ADV_100FDX_CAP: 3560 if (val != 0 && val != 1) { 3561 goto err; 3562 } 3563 if (val && (dp->mii_status & MII_STATUS_100_BASEX_FD) == 0) { 3564 goto err; 3565 } 3566 dp->anadv_100fdx = (int)val; 3567 break; 3568 3569 case PARAM_ADV_100HDX_CAP: 3570 if (val != 0 && val != 1) { 3571 goto err; 3572 } 3573 if (val && (dp->mii_status & MII_STATUS_100_BASEX) == 0) { 3574 goto err; 3575 } 3576 dp->anadv_100hdx = (int)val; 3577 break; 3578 3579 case PARAM_ADV_10FDX_CAP: 3580 if (val != 0 && val != 1) { 3581 goto err; 3582 } 3583 if (val && (dp->mii_status & MII_STATUS_10_FD) == 0) { 3584 goto err; 3585 } 3586 dp->anadv_10fdx = (int)val; 3587 break; 3588 3589 case PARAM_ADV_10HDX_CAP: 3590 if (val != 0 && val != 1) { 3591 goto err; 3592 } 3593 if (val && (dp->mii_status & MII_STATUS_10) == 0) { 3594 goto err; 3595 } 3596 dp->anadv_10hdx = (int)val; 3597 break; 3598 } 3599 3600 /* sync with PHY */ 3601 gem_choose_forcedmode(dp); 3602 3603 dp->mii_state = MII_STATE_UNKNOWN; 3604 if (dp->gc.gc_mii_hw_link_detection && dp->link_watcher_id == 0) { 3605 /* XXX - Can we ignore the return code ? */ 3606 (void) gem_mii_link_check(dp); 3607 } 3608 3609 return (0); 3610 err: 3611 return (EINVAL); 3612 } 3613 3614 static void 3615 gem_nd_load(struct gem_dev *dp, char *name, ndgetf_t gf, ndsetf_t sf, int item) 3616 { 3617 struct gem_nd_arg *arg; 3618 3619 ASSERT(item >= 0); 3620 ASSERT(item < PARAM_COUNT); 3621 3622 arg = &((struct gem_nd_arg *)(void *)dp->nd_arg_p)[item]; 3623 arg->dp = dp; 3624 arg->item = item; 3625 3626 DPRINTF(2, (CE_CONT, "!%s: %s: name:%s, item:%d", 3627 dp->name, __func__, name, item)); 3628 (void *) nd_load(&dp->nd_data_p, name, gf, sf, (caddr_t)arg); 3629 } 3630 3631 static void 3632 gem_nd_setup(struct gem_dev *dp) 3633 { 3634 DPRINTF(0, (CE_CONT, "!%s: %s: called, mii_status:0x%b", 3635 dp->name, __func__, dp->mii_status, MII_STATUS_BITS)); 3636 3637 ASSERT(dp->nd_arg_p == NULL); 3638 3639 dp->nd_arg_p = 3640 kmem_zalloc(sizeof (struct gem_nd_arg) * PARAM_COUNT, KM_SLEEP); 3641 3642 #define SETFUNC(x) ((x) ? gem_param_set : NULL) 3643 3644 gem_nd_load(dp, "autoneg_cap", 3645 gem_param_get, NULL, PARAM_AUTONEG_CAP); 3646 gem_nd_load(dp, "pause_cap", 3647 gem_param_get, NULL, PARAM_PAUSE_CAP); 3648 gem_nd_load(dp, "asym_pause_cap", 3649 gem_param_get, NULL, PARAM_ASYM_PAUSE_CAP); 3650 gem_nd_load(dp, "1000fdx_cap", 3651 gem_param_get, NULL, PARAM_1000FDX_CAP); 3652 gem_nd_load(dp, "1000hdx_cap", 3653 gem_param_get, NULL, PARAM_1000HDX_CAP); 3654 gem_nd_load(dp, "100T4_cap", 3655 gem_param_get, NULL, PARAM_100T4_CAP); 3656 gem_nd_load(dp, "100fdx_cap", 3657 gem_param_get, NULL, PARAM_100FDX_CAP); 3658 gem_nd_load(dp, "100hdx_cap", 3659 gem_param_get, NULL, PARAM_100HDX_CAP); 3660 gem_nd_load(dp, "10fdx_cap", 3661 gem_param_get, NULL, PARAM_10FDX_CAP); 3662 gem_nd_load(dp, "10hdx_cap", 3663 gem_param_get, NULL, PARAM_10HDX_CAP); 3664 3665 /* Our advertised capabilities */ 3666 gem_nd_load(dp, "adv_autoneg_cap", gem_param_get, 3667 SETFUNC(dp->mii_status & MII_STATUS_CANAUTONEG), 3668 PARAM_ADV_AUTONEG_CAP); 3669 gem_nd_load(dp, "adv_pause_cap", gem_param_get, 3670 SETFUNC(dp->gc.gc_flow_control & 1), 3671 PARAM_ADV_PAUSE_CAP); 3672 gem_nd_load(dp, "adv_asym_pause_cap", gem_param_get, 3673 SETFUNC(dp->gc.gc_flow_control & 2), 3674 PARAM_ADV_ASYM_PAUSE_CAP); 3675 gem_nd_load(dp, "adv_1000fdx_cap", gem_param_get, 3676 SETFUNC(dp->mii_xstatus & 3677 (MII_XSTATUS_1000BASEX_FD | MII_XSTATUS_1000BASET_FD)), 3678 PARAM_ADV_1000FDX_CAP); 3679 gem_nd_load(dp, "adv_1000hdx_cap", gem_param_get, 3680 SETFUNC(dp->mii_xstatus & 3681 (MII_XSTATUS_1000BASEX | MII_XSTATUS_1000BASET)), 3682 PARAM_ADV_1000HDX_CAP); 3683 gem_nd_load(dp, "adv_100T4_cap", gem_param_get, 3684 SETFUNC((dp->mii_status & MII_STATUS_100_BASE_T4) && 3685 !dp->mii_advert_ro), 3686 PARAM_ADV_100T4_CAP); 3687 gem_nd_load(dp, "adv_100fdx_cap", gem_param_get, 3688 SETFUNC((dp->mii_status & MII_STATUS_100_BASEX_FD) && 3689 !dp->mii_advert_ro), 3690 PARAM_ADV_100FDX_CAP); 3691 gem_nd_load(dp, "adv_100hdx_cap", gem_param_get, 3692 SETFUNC((dp->mii_status & MII_STATUS_100_BASEX) && 3693 !dp->mii_advert_ro), 3694 PARAM_ADV_100HDX_CAP); 3695 gem_nd_load(dp, "adv_10fdx_cap", gem_param_get, 3696 SETFUNC((dp->mii_status & MII_STATUS_10_FD) && 3697 !dp->mii_advert_ro), 3698 PARAM_ADV_10FDX_CAP); 3699 gem_nd_load(dp, "adv_10hdx_cap", gem_param_get, 3700 SETFUNC((dp->mii_status & MII_STATUS_10) && 3701 !dp->mii_advert_ro), 3702 PARAM_ADV_10HDX_CAP); 3703 3704 /* Partner's advertised capabilities */ 3705 gem_nd_load(dp, "lp_autoneg_cap", 3706 gem_param_get, NULL, PARAM_LP_AUTONEG_CAP); 3707 gem_nd_load(dp, "lp_pause_cap", 3708 gem_param_get, NULL, PARAM_LP_PAUSE_CAP); 3709 gem_nd_load(dp, "lp_asym_pause_cap", 3710 gem_param_get, NULL, PARAM_LP_ASYM_PAUSE_CAP); 3711 gem_nd_load(dp, "lp_1000fdx_cap", 3712 gem_param_get, NULL, PARAM_LP_1000FDX_CAP); 3713 gem_nd_load(dp, "lp_1000hdx_cap", 3714 gem_param_get, NULL, PARAM_LP_1000HDX_CAP); 3715 gem_nd_load(dp, "lp_100T4_cap", 3716 gem_param_get, NULL, PARAM_LP_100T4_CAP); 3717 gem_nd_load(dp, "lp_100fdx_cap", 3718 gem_param_get, NULL, PARAM_LP_100FDX_CAP); 3719 gem_nd_load(dp, "lp_100hdx_cap", 3720 gem_param_get, NULL, PARAM_LP_100HDX_CAP); 3721 gem_nd_load(dp, "lp_10fdx_cap", 3722 gem_param_get, NULL, PARAM_LP_10FDX_CAP); 3723 gem_nd_load(dp, "lp_10hdx_cap", 3724 gem_param_get, NULL, PARAM_LP_10HDX_CAP); 3725 3726 /* Current operating modes */ 3727 gem_nd_load(dp, "link_status", 3728 gem_param_get, NULL, PARAM_LINK_STATUS); 3729 gem_nd_load(dp, "link_speed", 3730 gem_param_get, NULL, PARAM_LINK_SPEED); 3731 gem_nd_load(dp, "link_duplex", 3732 gem_param_get, NULL, PARAM_LINK_DUPLEX); 3733 gem_nd_load(dp, "link_autoneg", 3734 gem_param_get, NULL, PARAM_LINK_AUTONEG); 3735 gem_nd_load(dp, "link_rx_pause", 3736 gem_param_get, NULL, PARAM_LINK_RX_PAUSE); 3737 gem_nd_load(dp, "link_tx_pause", 3738 gem_param_get, NULL, PARAM_LINK_TX_PAUSE); 3739 #ifdef DEBUG_RESUME 3740 gem_nd_load(dp, "resume_test", 3741 gem_param_get, NULL, PARAM_RESUME_TEST); 3742 #endif 3743 #undef SETFUNC 3744 } 3745 3746 static 3747 enum ioc_reply 3748 gem_nd_ioctl(struct gem_dev *dp, queue_t *wq, mblk_t *mp, struct iocblk *iocp) 3749 { 3750 boolean_t ok; 3751 3752 ASSERT(mutex_owned(&dp->intrlock)); 3753 3754 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 3755 3756 switch (iocp->ioc_cmd) { 3757 case ND_GET: 3758 ok = nd_getset(wq, dp->nd_data_p, mp); 3759 DPRINTF(0, (CE_CONT, 3760 "%s: get %s", dp->name, ok ? "OK" : "FAIL")); 3761 return (ok ? IOC_REPLY : IOC_INVAL); 3762 3763 case ND_SET: 3764 ok = nd_getset(wq, dp->nd_data_p, mp); 3765 3766 DPRINTF(0, (CE_CONT, "%s: set %s err %d", 3767 dp->name, ok ? "OK" : "FAIL", iocp->ioc_error)); 3768 3769 if (!ok) { 3770 return (IOC_INVAL); 3771 } 3772 3773 if (iocp->ioc_error) { 3774 return (IOC_REPLY); 3775 } 3776 3777 return (IOC_RESTART_REPLY); 3778 } 3779 3780 cmn_err(CE_WARN, "%s: invalid cmd 0x%x", dp->name, iocp->ioc_cmd); 3781 3782 return (IOC_INVAL); 3783 } 3784 3785 static void 3786 gem_nd_cleanup(struct gem_dev *dp) 3787 { 3788 ASSERT(dp->nd_data_p != NULL); 3789 ASSERT(dp->nd_arg_p != NULL); 3790 3791 nd_free(&dp->nd_data_p); 3792 3793 kmem_free(dp->nd_arg_p, sizeof (struct gem_nd_arg) * PARAM_COUNT); 3794 dp->nd_arg_p = NULL; 3795 } 3796 3797 static void 3798 gem_mac_ioctl(struct gem_dev *dp, queue_t *wq, mblk_t *mp) 3799 { 3800 struct iocblk *iocp; 3801 enum ioc_reply status; 3802 int cmd; 3803 3804 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 3805 3806 /* 3807 * Validate the command before bothering with the mutex ... 3808 */ 3809 iocp = (void *)mp->b_rptr; 3810 iocp->ioc_error = 0; 3811 cmd = iocp->ioc_cmd; 3812 3813 DPRINTF(0, (CE_CONT, "%s: %s cmd:0x%x", dp->name, __func__, cmd)); 3814 3815 mutex_enter(&dp->intrlock); 3816 mutex_enter(&dp->xmitlock); 3817 3818 switch (cmd) { 3819 default: 3820 _NOTE(NOTREACHED) 3821 status = IOC_INVAL; 3822 break; 3823 3824 case ND_GET: 3825 case ND_SET: 3826 status = gem_nd_ioctl(dp, wq, mp, iocp); 3827 break; 3828 } 3829 3830 mutex_exit(&dp->xmitlock); 3831 mutex_exit(&dp->intrlock); 3832 3833 #ifdef DEBUG_RESUME 3834 if (cmd == ND_GET) { 3835 gem_suspend(dp->dip); 3836 gem_resume(dp->dip); 3837 } 3838 #endif 3839 /* 3840 * Finally, decide how to reply 3841 */ 3842 switch (status) { 3843 default: 3844 case IOC_INVAL: 3845 /* 3846 * Error, reply with a NAK and EINVAL or the specified error 3847 */ 3848 miocnak(wq, mp, 0, iocp->ioc_error == 0 ? 3849 EINVAL : iocp->ioc_error); 3850 break; 3851 3852 case IOC_DONE: 3853 /* 3854 * OK, reply already sent 3855 */ 3856 break; 3857 3858 case IOC_RESTART_ACK: 3859 case IOC_ACK: 3860 /* 3861 * OK, reply with an ACK 3862 */ 3863 miocack(wq, mp, 0, 0); 3864 break; 3865 3866 case IOC_RESTART_REPLY: 3867 case IOC_REPLY: 3868 /* 3869 * OK, send prepared reply as ACK or NAK 3870 */ 3871 mp->b_datap->db_type = 3872 iocp->ioc_error == 0 ? M_IOCACK : M_IOCNAK; 3873 qreply(wq, mp); 3874 break; 3875 } 3876 } 3877 3878 #ifndef SYS_MAC_H 3879 #define XCVR_UNDEFINED 0 3880 #define XCVR_NONE 1 3881 #define XCVR_10 2 3882 #define XCVR_100T4 3 3883 #define XCVR_100X 4 3884 #define XCVR_100T2 5 3885 #define XCVR_1000X 6 3886 #define XCVR_1000T 7 3887 #endif 3888 static int 3889 gem_mac_xcvr_inuse(struct gem_dev *dp) 3890 { 3891 int val = XCVR_UNDEFINED; 3892 3893 if ((dp->mii_status & MII_STATUS_XSTATUS) == 0) { 3894 if (dp->mii_status & MII_STATUS_100_BASE_T4) { 3895 val = XCVR_100T4; 3896 } else if (dp->mii_status & 3897 (MII_STATUS_100_BASEX_FD | 3898 MII_STATUS_100_BASEX)) { 3899 val = XCVR_100X; 3900 } else if (dp->mii_status & 3901 (MII_STATUS_100_BASE_T2_FD | 3902 MII_STATUS_100_BASE_T2)) { 3903 val = XCVR_100T2; 3904 } else if (dp->mii_status & 3905 (MII_STATUS_10_FD | MII_STATUS_10)) { 3906 val = XCVR_10; 3907 } 3908 } else if (dp->mii_xstatus & 3909 (MII_XSTATUS_1000BASET_FD | MII_XSTATUS_1000BASET)) { 3910 val = XCVR_1000T; 3911 } else if (dp->mii_xstatus & 3912 (MII_XSTATUS_1000BASEX_FD | MII_XSTATUS_1000BASEX)) { 3913 val = XCVR_1000X; 3914 } 3915 3916 return (val); 3917 } 3918 3919 /* ============================================================== */ 3920 /* 3921 * GLDv3 interface 3922 */ 3923 /* ============================================================== */ 3924 static int gem_m_getstat(void *, uint_t, uint64_t *); 3925 static int gem_m_start(void *); 3926 static void gem_m_stop(void *); 3927 static int gem_m_setpromisc(void *, boolean_t); 3928 static int gem_m_multicst(void *, boolean_t, const uint8_t *); 3929 static int gem_m_unicst(void *, const uint8_t *); 3930 static mblk_t *gem_m_tx(void *, mblk_t *); 3931 static void gem_m_resources(void *); 3932 static void gem_m_ioctl(void *, queue_t *, mblk_t *); 3933 static boolean_t gem_m_getcapab(void *, mac_capab_t, void *); 3934 3935 #define GEM_M_CALLBACK_FLAGS (MC_RESOURCES | MC_IOCTL | MC_GETCAPAB) 3936 3937 static mac_callbacks_t gem_m_callbacks = { 3938 GEM_M_CALLBACK_FLAGS, 3939 gem_m_getstat, 3940 gem_m_start, 3941 gem_m_stop, 3942 gem_m_setpromisc, 3943 gem_m_multicst, 3944 gem_m_unicst, 3945 gem_m_tx, 3946 gem_m_resources, 3947 gem_m_ioctl, 3948 gem_m_getcapab, 3949 }; 3950 3951 static int 3952 gem_m_start(void *arg) 3953 { 3954 int err = 0; 3955 struct gem_dev *dp = arg; 3956 3957 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 3958 3959 mutex_enter(&dp->intrlock); 3960 if (dp->mac_suspended) { 3961 err = EIO; 3962 goto x; 3963 } 3964 if (gem_mac_init(dp) != GEM_SUCCESS) { 3965 err = EIO; 3966 goto x; 3967 } 3968 dp->nic_state = NIC_STATE_INITIALIZED; 3969 3970 /* reset rx filter state */ 3971 dp->mc_count = 0; 3972 dp->mc_count_req = 0; 3973 3974 /* setup media mode if the link have been up */ 3975 if (dp->mii_state == MII_STATE_LINKUP) { 3976 (dp->gc.gc_set_media)(dp); 3977 } 3978 3979 /* setup initial rx filter */ 3980 bcopy(dp->dev_addr.ether_addr_octet, 3981 dp->cur_addr.ether_addr_octet, ETHERADDRL); 3982 dp->rxmode |= RXMODE_ENABLE; 3983 3984 if (gem_mac_set_rx_filter(dp) != GEM_SUCCESS) { 3985 err = EIO; 3986 goto x; 3987 } 3988 3989 dp->nic_state = NIC_STATE_ONLINE; 3990 if (dp->mii_state == MII_STATE_LINKUP) { 3991 if (gem_mac_start(dp) != GEM_SUCCESS) { 3992 err = EIO; 3993 goto x; 3994 } 3995 } 3996 3997 dp->timeout_id = timeout((void (*)(void *))gem_tx_timeout, 3998 (void *)dp, dp->gc.gc_tx_timeout_interval); 3999 mutex_exit(&dp->intrlock); 4000 4001 return (0); 4002 x: 4003 dp->nic_state = NIC_STATE_STOPPED; 4004 mutex_exit(&dp->intrlock); 4005 return (err); 4006 } 4007 4008 static void 4009 gem_m_stop(void *arg) 4010 { 4011 struct gem_dev *dp = arg; 4012 4013 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 4014 4015 /* stop rx */ 4016 mutex_enter(&dp->intrlock); 4017 if (dp->mac_suspended) { 4018 mutex_exit(&dp->intrlock); 4019 return; 4020 } 4021 dp->rxmode &= ~RXMODE_ENABLE; 4022 (void) gem_mac_set_rx_filter(dp); 4023 mutex_exit(&dp->intrlock); 4024 4025 /* stop tx timeout watcher */ 4026 if (dp->timeout_id) { 4027 while (untimeout(dp->timeout_id) == -1) 4028 ; 4029 dp->timeout_id = 0; 4030 } 4031 4032 /* make the nic state inactive */ 4033 mutex_enter(&dp->intrlock); 4034 if (dp->mac_suspended) { 4035 mutex_exit(&dp->intrlock); 4036 return; 4037 } 4038 dp->nic_state = NIC_STATE_STOPPED; 4039 4040 /* we need deassert mac_active due to block interrupt handler */ 4041 mutex_enter(&dp->xmitlock); 4042 dp->mac_active = B_FALSE; 4043 mutex_exit(&dp->xmitlock); 4044 4045 /* block interrupts */ 4046 while (dp->intr_busy) { 4047 cv_wait(&dp->tx_drain_cv, &dp->intrlock); 4048 } 4049 (void) gem_mac_stop(dp, 0); 4050 mutex_exit(&dp->intrlock); 4051 } 4052 4053 static int 4054 gem_m_multicst(void *arg, boolean_t add, const uint8_t *ep) 4055 { 4056 int err; 4057 int ret; 4058 struct gem_dev *dp = arg; 4059 4060 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 4061 4062 if (add) { 4063 ret = gem_add_multicast(dp, ep); 4064 } else { 4065 ret = gem_remove_multicast(dp, ep); 4066 } 4067 4068 err = 0; 4069 if (ret != GEM_SUCCESS) { 4070 err = EIO; 4071 } 4072 4073 return (err); 4074 } 4075 4076 static int 4077 gem_m_setpromisc(void *arg, boolean_t on) 4078 { 4079 int err = 0; /* no error */ 4080 struct gem_dev *dp = arg; 4081 4082 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 4083 4084 mutex_enter(&dp->intrlock); 4085 if (dp->mac_suspended) { 4086 mutex_exit(&dp->intrlock); 4087 return (EIO); 4088 } 4089 if (on) { 4090 dp->rxmode |= RXMODE_PROMISC; 4091 } else { 4092 dp->rxmode &= ~RXMODE_PROMISC; 4093 } 4094 4095 if (gem_mac_set_rx_filter(dp) != GEM_SUCCESS) { 4096 err = EIO; 4097 } 4098 mutex_exit(&dp->intrlock); 4099 4100 return (err); 4101 } 4102 4103 int 4104 gem_m_getstat(void *arg, uint_t stat, uint64_t *valp) 4105 { 4106 struct gem_dev *dp = arg; 4107 struct gem_stats *gstp = &dp->stats; 4108 uint64_t val = 0; 4109 4110 DPRINTF(1, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 4111 4112 mutex_enter(&dp->intrlock); 4113 if (dp->mac_suspended) { 4114 mutex_exit(&dp->intrlock); 4115 return (EIO); 4116 } 4117 mutex_exit(&dp->intrlock); 4118 4119 if ((*dp->gc.gc_get_stats)(dp) != GEM_SUCCESS) { 4120 return (EIO); 4121 } 4122 4123 switch (stat) { 4124 case MAC_STAT_IFSPEED: 4125 val = gem_speed_value[dp->speed] *1000000ull; 4126 break; 4127 4128 case MAC_STAT_MULTIRCV: 4129 val = gstp->rmcast; 4130 break; 4131 4132 case MAC_STAT_BRDCSTRCV: 4133 val = gstp->rbcast; 4134 break; 4135 4136 case MAC_STAT_MULTIXMT: 4137 val = gstp->omcast; 4138 break; 4139 4140 case MAC_STAT_BRDCSTXMT: 4141 val = gstp->obcast; 4142 break; 4143 4144 case MAC_STAT_NORCVBUF: 4145 val = gstp->norcvbuf + gstp->missed; 4146 break; 4147 4148 case MAC_STAT_IERRORS: 4149 val = gstp->errrcv; 4150 break; 4151 4152 case MAC_STAT_NOXMTBUF: 4153 val = gstp->noxmtbuf; 4154 break; 4155 4156 case MAC_STAT_OERRORS: 4157 val = gstp->errxmt; 4158 break; 4159 4160 case MAC_STAT_COLLISIONS: 4161 val = gstp->collisions; 4162 break; 4163 4164 case MAC_STAT_RBYTES: 4165 val = gstp->rbytes; 4166 break; 4167 4168 case MAC_STAT_IPACKETS: 4169 val = gstp->rpackets; 4170 break; 4171 4172 case MAC_STAT_OBYTES: 4173 val = gstp->obytes; 4174 break; 4175 4176 case MAC_STAT_OPACKETS: 4177 val = gstp->opackets; 4178 break; 4179 4180 case MAC_STAT_UNDERFLOWS: 4181 val = gstp->underflow; 4182 break; 4183 4184 case MAC_STAT_OVERFLOWS: 4185 val = gstp->overflow; 4186 break; 4187 4188 case ETHER_STAT_ALIGN_ERRORS: 4189 val = gstp->frame; 4190 break; 4191 4192 case ETHER_STAT_FCS_ERRORS: 4193 val = gstp->crc; 4194 break; 4195 4196 case ETHER_STAT_FIRST_COLLISIONS: 4197 val = gstp->first_coll; 4198 break; 4199 4200 case ETHER_STAT_MULTI_COLLISIONS: 4201 val = gstp->multi_coll; 4202 break; 4203 4204 case ETHER_STAT_SQE_ERRORS: 4205 val = gstp->sqe; 4206 break; 4207 4208 case ETHER_STAT_DEFER_XMTS: 4209 val = gstp->defer; 4210 break; 4211 4212 case ETHER_STAT_TX_LATE_COLLISIONS: 4213 val = gstp->xmtlatecoll; 4214 break; 4215 4216 case ETHER_STAT_EX_COLLISIONS: 4217 val = gstp->excoll; 4218 break; 4219 4220 case ETHER_STAT_MACXMT_ERRORS: 4221 val = gstp->xmit_internal_err; 4222 break; 4223 4224 case ETHER_STAT_CARRIER_ERRORS: 4225 val = gstp->nocarrier; 4226 break; 4227 4228 case ETHER_STAT_TOOLONG_ERRORS: 4229 val = gstp->frame_too_long; 4230 break; 4231 4232 case ETHER_STAT_MACRCV_ERRORS: 4233 val = gstp->rcv_internal_err; 4234 break; 4235 4236 case ETHER_STAT_XCVR_ADDR: 4237 val = dp->mii_phy_addr; 4238 break; 4239 4240 case ETHER_STAT_XCVR_ID: 4241 val = dp->mii_phy_id; 4242 break; 4243 4244 case ETHER_STAT_XCVR_INUSE: 4245 val = gem_mac_xcvr_inuse(dp); 4246 break; 4247 4248 case ETHER_STAT_CAP_1000FDX: 4249 val = (dp->mii_xstatus & MII_XSTATUS_1000BASET_FD) || 4250 (dp->mii_xstatus & MII_XSTATUS_1000BASEX_FD); 4251 break; 4252 4253 case ETHER_STAT_CAP_1000HDX: 4254 val = (dp->mii_xstatus & MII_XSTATUS_1000BASET) || 4255 (dp->mii_xstatus & MII_XSTATUS_1000BASEX); 4256 break; 4257 4258 case ETHER_STAT_CAP_100FDX: 4259 val = BOOLEAN(dp->mii_status & MII_STATUS_100_BASEX_FD); 4260 break; 4261 4262 case ETHER_STAT_CAP_100HDX: 4263 val = BOOLEAN(dp->mii_status & MII_STATUS_100_BASEX); 4264 break; 4265 4266 case ETHER_STAT_CAP_10FDX: 4267 val = BOOLEAN(dp->mii_status & MII_STATUS_10_FD); 4268 break; 4269 4270 case ETHER_STAT_CAP_10HDX: 4271 val = BOOLEAN(dp->mii_status & MII_STATUS_10); 4272 break; 4273 4274 case ETHER_STAT_CAP_ASMPAUSE: 4275 val = BOOLEAN(dp->gc.gc_flow_control & 2); 4276 break; 4277 4278 case ETHER_STAT_CAP_PAUSE: 4279 val = BOOLEAN(dp->gc.gc_flow_control & 1); 4280 break; 4281 4282 case ETHER_STAT_CAP_AUTONEG: 4283 val = dp->anadv_autoneg; 4284 break; 4285 4286 case ETHER_STAT_ADV_CAP_1000FDX: 4287 val = dp->anadv_1000fdx; 4288 break; 4289 4290 case ETHER_STAT_ADV_CAP_1000HDX: 4291 val = dp->anadv_1000hdx; 4292 break; 4293 4294 case ETHER_STAT_ADV_CAP_100FDX: 4295 val = dp->anadv_100fdx; 4296 break; 4297 4298 case ETHER_STAT_ADV_CAP_100HDX: 4299 val = dp->anadv_100hdx; 4300 break; 4301 4302 case ETHER_STAT_ADV_CAP_10FDX: 4303 val = dp->anadv_10fdx; 4304 break; 4305 4306 case ETHER_STAT_ADV_CAP_10HDX: 4307 val = dp->anadv_10hdx; 4308 break; 4309 4310 case ETHER_STAT_ADV_CAP_ASMPAUSE: 4311 val = BOOLEAN(dp->anadv_flow_control & 2); 4312 break; 4313 4314 case ETHER_STAT_ADV_CAP_PAUSE: 4315 val = BOOLEAN(dp->anadv_flow_control & 1); 4316 break; 4317 4318 case ETHER_STAT_ADV_CAP_AUTONEG: 4319 val = dp->anadv_autoneg; 4320 break; 4321 4322 case ETHER_STAT_LP_CAP_1000FDX: 4323 val = BOOLEAN(dp->mii_stat1000 & MII_1000TS_LP_FULL); 4324 break; 4325 4326 case ETHER_STAT_LP_CAP_1000HDX: 4327 val = BOOLEAN(dp->mii_stat1000 & MII_1000TS_LP_HALF); 4328 break; 4329 4330 case ETHER_STAT_LP_CAP_100FDX: 4331 val = BOOLEAN(dp->mii_lpable & MII_ABILITY_100BASE_TX_FD); 4332 break; 4333 4334 case ETHER_STAT_LP_CAP_100HDX: 4335 val = BOOLEAN(dp->mii_lpable & MII_ABILITY_100BASE_TX); 4336 break; 4337 4338 case ETHER_STAT_LP_CAP_10FDX: 4339 val = BOOLEAN(dp->mii_lpable & MII_ABILITY_10BASE_T_FD); 4340 break; 4341 4342 case ETHER_STAT_LP_CAP_10HDX: 4343 val = BOOLEAN(dp->mii_lpable & MII_ABILITY_10BASE_T); 4344 break; 4345 4346 case ETHER_STAT_LP_CAP_ASMPAUSE: 4347 val = BOOLEAN(dp->mii_lpable & MII_ABILITY_ASM_DIR); 4348 break; 4349 4350 case ETHER_STAT_LP_CAP_PAUSE: 4351 val = BOOLEAN(dp->mii_lpable & MII_ABILITY_PAUSE); 4352 break; 4353 4354 case ETHER_STAT_LP_CAP_AUTONEG: 4355 val = BOOLEAN(dp->mii_exp & MII_AN_EXP_LPCANAN); 4356 break; 4357 4358 case ETHER_STAT_LINK_ASMPAUSE: 4359 val = BOOLEAN(dp->flow_control & 2); 4360 break; 4361 4362 case ETHER_STAT_LINK_PAUSE: 4363 val = BOOLEAN(dp->flow_control & 1); 4364 break; 4365 4366 case ETHER_STAT_LINK_AUTONEG: 4367 val = dp->anadv_autoneg && 4368 BOOLEAN(dp->mii_exp & MII_AN_EXP_LPCANAN); 4369 break; 4370 4371 case ETHER_STAT_LINK_DUPLEX: 4372 val = (dp->mii_state == MII_STATE_LINKUP) ? 4373 (dp->full_duplex ? 2 : 1) : 0; 4374 break; 4375 4376 case ETHER_STAT_TOOSHORT_ERRORS: 4377 val = gstp->runt; 4378 break; 4379 case ETHER_STAT_LP_REMFAULT: 4380 val = BOOLEAN(dp->mii_lpable & MII_AN_ADVERT_REMFAULT); 4381 break; 4382 4383 case ETHER_STAT_JABBER_ERRORS: 4384 val = gstp->jabber; 4385 break; 4386 4387 case ETHER_STAT_CAP_100T4: 4388 val = BOOLEAN(dp->mii_status & MII_STATUS_100_BASE_T4); 4389 break; 4390 4391 case ETHER_STAT_ADV_CAP_100T4: 4392 val = dp->anadv_100t4; 4393 break; 4394 4395 case ETHER_STAT_LP_CAP_100T4: 4396 val = BOOLEAN(dp->mii_lpable & MII_ABILITY_100BASE_T4); 4397 break; 4398 4399 default: 4400 #if GEM_DEBUG_LEVEL > 2 4401 cmn_err(CE_WARN, 4402 "%s: unrecognized parameter value = %d", 4403 __func__, stat); 4404 #endif 4405 return (ENOTSUP); 4406 } 4407 4408 *valp = val; 4409 4410 return (0); 4411 } 4412 4413 static int 4414 gem_m_unicst(void *arg, const uint8_t *mac) 4415 { 4416 int err = 0; 4417 struct gem_dev *dp = arg; 4418 4419 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 4420 4421 mutex_enter(&dp->intrlock); 4422 if (dp->mac_suspended) { 4423 mutex_exit(&dp->intrlock); 4424 return (EIO); 4425 } 4426 bcopy(mac, dp->cur_addr.ether_addr_octet, ETHERADDRL); 4427 dp->rxmode |= RXMODE_ENABLE; 4428 4429 if (gem_mac_set_rx_filter(dp) != GEM_SUCCESS) { 4430 err = EIO; 4431 } 4432 mutex_exit(&dp->intrlock); 4433 4434 return (err); 4435 } 4436 4437 /* 4438 * gem_m_tx is used only for sending data packets into ethernet wire. 4439 */ 4440 static mblk_t * 4441 gem_m_tx(void *arg, mblk_t *mp) 4442 { 4443 uint32_t flags = 0; 4444 struct gem_dev *dp = arg; 4445 mblk_t *tp; 4446 4447 DPRINTF(1, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 4448 4449 ASSERT(dp->nic_state == NIC_STATE_ONLINE); 4450 if (dp->mii_state != MII_STATE_LINKUP) { 4451 /* Some nics hate to send packets when the link is down. */ 4452 while (mp) { 4453 tp = mp->b_next; 4454 mp->b_next = NULL; 4455 freemsg(mp); 4456 mp = tp; 4457 } 4458 return (NULL); 4459 } 4460 4461 return (gem_send_common(dp, mp, flags)); 4462 } 4463 4464 static void 4465 gem_set_coalease(void *arg, time_t ticks, uint_t count) 4466 { 4467 struct gem_dev *dp = arg; 4468 DPRINTF(1, (CE_CONT, "%s: %s: ticks:%d count:%d", 4469 dp->name, __func__, ticks, count)); 4470 4471 mutex_enter(&dp->intrlock); 4472 dp->poll_pkt_delay = count; 4473 mutex_exit(&dp->intrlock); 4474 } 4475 4476 static void 4477 gem_m_resources(void *arg) 4478 { 4479 struct gem_dev *dp = arg; 4480 mac_rx_fifo_t mrf; 4481 4482 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 4483 4484 mutex_enter(&dp->intrlock); 4485 mutex_enter(&dp->xmitlock); 4486 4487 /* 4488 * Register Rx rings as resources and save mac 4489 * resource id for future reference 4490 */ 4491 mrf.mrf_type = MAC_RX_FIFO; 4492 mrf.mrf_blank = gem_set_coalease; 4493 mrf.mrf_arg = (void *)dp; 4494 mrf.mrf_normal_blank_time = 128; /* in uS */ 4495 mrf.mrf_normal_pkt_count = dp->poll_pkt_delay; 4496 4497 dp->mac_rx_ring_ha = mac_resource_add(dp->mh, (mac_resource_t *)&mrf); 4498 4499 mutex_exit(&dp->xmitlock); 4500 mutex_exit(&dp->intrlock); 4501 } 4502 4503 static void 4504 gem_m_ioctl(void *arg, queue_t *wq, mblk_t *mp) 4505 { 4506 DPRINTF(0, (CE_CONT, "!%s: %s: called", 4507 ((struct gem_dev *)arg)->name, __func__)); 4508 4509 gem_mac_ioctl((struct gem_dev *)arg, wq, mp); 4510 } 4511 4512 static boolean_t 4513 gem_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 4514 { 4515 boolean_t ret; 4516 4517 ret = B_FALSE; 4518 switch (cap) { 4519 case MAC_CAPAB_POLL: 4520 ret = B_TRUE; 4521 break; 4522 } 4523 return (ret); 4524 } 4525 4526 static void 4527 gem_gld3_init(struct gem_dev *dp, mac_register_t *macp) 4528 { 4529 macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 4530 macp->m_driver = dp; 4531 macp->m_dip = dp->dip; 4532 macp->m_src_addr = dp->dev_addr.ether_addr_octet; 4533 macp->m_callbacks = &gem_m_callbacks; 4534 macp->m_min_sdu = 0; 4535 macp->m_max_sdu = dp->mtu; 4536 } 4537 4538 /* ======================================================================== */ 4539 /* 4540 * attach/detatch support 4541 */ 4542 /* ======================================================================== */ 4543 static void 4544 gem_read_conf(struct gem_dev *dp) 4545 { 4546 char propname[32]; 4547 int val; 4548 4549 DPRINTF(1, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 4550 4551 /* 4552 * Get media mode infomation from .conf file 4553 */ 4554 dp->anadv_autoneg = gem_prop_get_int(dp, "adv_autoneg_cap", 1) != 0; 4555 dp->anadv_1000fdx = gem_prop_get_int(dp, "adv_1000fdx_cap", 1) != 0; 4556 dp->anadv_1000hdx = gem_prop_get_int(dp, "adv_1000hdx_cap", 1) != 0; 4557 dp->anadv_100t4 = gem_prop_get_int(dp, "adv_100T4_cap", 1) != 0; 4558 dp->anadv_100fdx = gem_prop_get_int(dp, "adv_100fdx_cap", 1) != 0; 4559 dp->anadv_100hdx = gem_prop_get_int(dp, "adv_100hdx_cap", 1) != 0; 4560 dp->anadv_10fdx = gem_prop_get_int(dp, "adv_10fdx_cap", 1) != 0; 4561 dp->anadv_10hdx = gem_prop_get_int(dp, "adv_10hdx_cap", 1) != 0; 4562 4563 if ((ddi_prop_exists(DDI_DEV_T_ANY, dp->dip, 4564 DDI_PROP_DONTPASS, "full-duplex"))) { 4565 dp->full_duplex = gem_prop_get_int(dp, "full-duplex", 1) != 0; 4566 dp->anadv_autoneg = B_FALSE; 4567 dp->anadv_1000hdx = B_FALSE; 4568 dp->anadv_100hdx = B_FALSE; 4569 dp->anadv_10hdx = B_FALSE; 4570 } 4571 4572 if ((val = gem_prop_get_int(dp, "speed", 0)) > 0) { 4573 dp->anadv_autoneg = B_FALSE; 4574 switch (val) { 4575 case 1000: 4576 dp->speed = GEM_SPD_1000; 4577 dp->anadv_100t4 = B_FALSE; 4578 dp->anadv_100fdx = B_FALSE; 4579 dp->anadv_100hdx = B_FALSE; 4580 dp->anadv_10fdx = B_FALSE; 4581 dp->anadv_10hdx = B_FALSE; 4582 break; 4583 case 100: 4584 dp->speed = GEM_SPD_100; 4585 dp->anadv_1000fdx = B_FALSE; 4586 dp->anadv_1000hdx = B_FALSE; 4587 dp->anadv_10fdx = B_FALSE; 4588 dp->anadv_10hdx = B_FALSE; 4589 break; 4590 case 10: 4591 dp->speed = GEM_SPD_10; 4592 dp->anadv_1000fdx = B_FALSE; 4593 dp->anadv_1000hdx = B_FALSE; 4594 dp->anadv_100t4 = B_FALSE; 4595 dp->anadv_100fdx = B_FALSE; 4596 dp->anadv_100hdx = B_FALSE; 4597 break; 4598 default: 4599 cmn_err(CE_WARN, 4600 "!%s: property %s: illegal value:%d", 4601 dp->name, propname, val); 4602 dp->anadv_autoneg = B_TRUE; 4603 break; 4604 } 4605 } 4606 4607 val = gem_prop_get_int(dp, "flow-control", dp->gc.gc_flow_control); 4608 if (val > FLOW_CONTROL_RX_PAUSE || val < FLOW_CONTROL_NONE) { 4609 cmn_err(CE_WARN, 4610 "!%s: property %s: illegal value:%d", 4611 dp->name, propname, val); 4612 } else { 4613 val = min(val, dp->gc.gc_flow_control); 4614 } 4615 dp->anadv_flow_control = val; 4616 4617 if (gem_prop_get_int(dp, "nointr", 0)) { 4618 dp->misc_flag |= GEM_NOINTR; 4619 cmn_err(CE_NOTE, "!%s: polling mode enabled", dp->name); 4620 } 4621 4622 dp->mtu = gem_prop_get_int(dp, "mtu", dp->mtu); 4623 dp->txthr = gem_prop_get_int(dp, "txthr", dp->txthr); 4624 dp->rxthr = gem_prop_get_int(dp, "rxthr", dp->rxthr); 4625 dp->txmaxdma = gem_prop_get_int(dp, "txmaxdma", dp->txmaxdma); 4626 dp->rxmaxdma = gem_prop_get_int(dp, "rxmaxdma", dp->rxmaxdma); 4627 dp->poll_pkt_delay = 4628 gem_prop_get_int(dp, "pkt_delay", dp->poll_pkt_delay); 4629 } 4630 4631 4632 /* 4633 * Gem kstat support 4634 */ 4635 4636 #define GEM_LOCAL_DATA_SIZE(gc) \ 4637 (sizeof (struct gem_dev) + \ 4638 sizeof (struct mcast_addr) * GEM_MAXMC + \ 4639 sizeof (struct txbuf) * ((gc)->gc_tx_buf_size) + \ 4640 sizeof (void *) * ((gc)->gc_tx_buf_size)) 4641 4642 struct gem_dev * 4643 gem_do_attach(dev_info_t *dip, int port, 4644 struct gem_conf *gc, void *base, ddi_acc_handle_t *regs_handlep, 4645 void *lp, int lmsize) 4646 { 4647 struct gem_dev *dp; 4648 int i; 4649 ddi_iblock_cookie_t c; 4650 mac_register_t *macp = NULL; 4651 int ret; 4652 int unit; 4653 int nports; 4654 4655 unit = ddi_get_instance(dip); 4656 if ((nports = gc->gc_nports) == 0) { 4657 nports = 1; 4658 } 4659 if (nports == 1) { 4660 ddi_set_driver_private(dip, NULL); 4661 } 4662 4663 DPRINTF(2, (CE_CONT, "!gem%d: gem_do_attach: called cmd:ATTACH", 4664 unit)); 4665 4666 /* 4667 * Allocate soft data structure 4668 */ 4669 dp = kmem_zalloc(GEM_LOCAL_DATA_SIZE(gc), KM_SLEEP); 4670 4671 if ((macp = mac_alloc(MAC_VERSION)) == NULL) { 4672 cmn_err(CE_WARN, "!gem%d: %s: mac_alloc failed", 4673 unit, __func__); 4674 return (NULL); 4675 } 4676 /* ddi_set_driver_private(dip, dp); */ 4677 4678 /* link to private area */ 4679 dp->private = lp; 4680 dp->priv_size = lmsize; 4681 dp->mc_list = (struct mcast_addr *)&dp[1]; 4682 4683 dp->dip = dip; 4684 (void) sprintf(dp->name, gc->gc_name, nports * unit + port); 4685 4686 /* 4687 * Get iblock cookie 4688 */ 4689 if (ddi_get_iblock_cookie(dip, 0, &c) != DDI_SUCCESS) { 4690 cmn_err(CE_CONT, 4691 "!%s: gem_do_attach: ddi_get_iblock_cookie: failed", 4692 dp->name); 4693 goto err_free_private; 4694 } 4695 dp->iblock_cookie = c; 4696 4697 /* 4698 * Initialize mutex's for this device. 4699 */ 4700 mutex_init(&dp->intrlock, NULL, MUTEX_DRIVER, (void *)c); 4701 mutex_init(&dp->xmitlock, NULL, MUTEX_DRIVER, (void *)c); 4702 cv_init(&dp->tx_drain_cv, NULL, CV_DRIVER, NULL); 4703 4704 /* 4705 * configure gem parameter 4706 */ 4707 dp->base_addr = base; 4708 dp->regs_handle = *regs_handlep; 4709 dp->gc = *gc; 4710 gc = &dp->gc; 4711 if (gc->gc_tx_ring_size == 0) { 4712 /* patch for simplify dma resource management */ 4713 gc->gc_tx_max_frags = 1; 4714 gc->gc_tx_max_descs_per_pkt = 1; 4715 gc->gc_tx_ring_size = gc->gc_tx_buf_size; 4716 gc->gc_tx_ring_limit = gc->gc_tx_buf_limit; 4717 gc->gc_tx_desc_write_oo = B_TRUE; 4718 } 4719 if (gc->gc_tx_desc_write_oo) { 4720 /* doublec check for making tx descs in out of order way */ 4721 gc->gc_tx_desc_write_oo = 4722 gc->gc_tx_max_descs_per_pkt == 1 && 4723 gc->gc_tx_buf_size == gc->gc_tx_ring_size && 4724 gc->gc_tx_buf_limit == gc->gc_tx_ring_limit; 4725 } 4726 4727 gc->gc_nports = nports; /* fix nports */ 4728 4729 /* fix copy threadsholds */ 4730 gc->gc_tx_copy_thresh = max(ETHERMIN, gc->gc_tx_copy_thresh); 4731 gc->gc_rx_copy_thresh = max(ETHERMIN, gc->gc_rx_copy_thresh); 4732 4733 /* fix rx buffer boundary for iocache line size */ 4734 ASSERT(gc->gc_dma_attr_txbuf.dma_attr_align-1 == gc->gc_tx_buf_align); 4735 ASSERT(gc->gc_dma_attr_rxbuf.dma_attr_align-1 == gc->gc_rx_buf_align); 4736 gc->gc_rx_buf_align = max(gc->gc_rx_buf_align, IOC_LINESIZE - 1); 4737 gc->gc_dma_attr_rxbuf.dma_attr_align = gc->gc_rx_buf_align + 1; 4738 4739 /* patch get_packet method */ 4740 if (gc->gc_get_packet == NULL) { 4741 gc->gc_get_packet = &gem_get_packet_default; 4742 } 4743 4744 /* patch get_rx_start method */ 4745 if (gc->gc_rx_start == NULL) { 4746 gc->gc_rx_start = &gem_rx_start_default; 4747 } 4748 4749 /* calculate descriptor area */ 4750 if (gc->gc_rx_desc_unit_shift >= 0) { 4751 dp->rx_desc_size = 4752 ROUNDUP(gc->gc_rx_ring_size << gc->gc_rx_desc_unit_shift, 4753 gc->gc_dma_attr_desc.dma_attr_align); 4754 } 4755 if (gc->gc_tx_desc_unit_shift >= 0) { 4756 dp->tx_desc_size = 4757 ROUNDUP(gc->gc_tx_ring_size << gc->gc_tx_desc_unit_shift, 4758 gc->gc_dma_attr_desc.dma_attr_align); 4759 } 4760 4761 dp->mtu = ETHERMTU; 4762 dp->tx_buf = (void *)&dp->mc_list[GEM_MAXMC]; 4763 /* link tx buffers */ 4764 for (i = 0; i < dp->gc.gc_tx_buf_size; i++) { 4765 dp->tx_buf[i].txb_next = 4766 &dp->tx_buf[SLOT(i + 1, dp->gc.gc_tx_buf_size)]; 4767 } 4768 4769 dp->rxmode = 0; 4770 dp->speed = GEM_SPD_10; /* default is 10Mbps */ 4771 dp->full_duplex = B_FALSE; /* default is half */ 4772 dp->flow_control = FLOW_CONTROL_NONE; 4773 dp->poll_pkt_delay = 6; 4774 dp->poll_pkt_hiwat = INT32_MAX; 4775 4776 /* performance tuning parameters */ 4777 dp->txthr = ETHERMAX; /* tx fifo threshold */ 4778 dp->txmaxdma = 16*4; /* tx max dma burst size */ 4779 dp->rxthr = 128; /* rx fifo threshold */ 4780 dp->rxmaxdma = 16*4; /* rx max dma burst size */ 4781 4782 /* 4783 * Get media mode information from .conf file 4784 */ 4785 gem_read_conf(dp); 4786 4787 /* rx_buf_len is required buffer length without padding for alignment */ 4788 dp->rx_buf_len = MAXPKTBUF(dp) + dp->gc.gc_rx_header_len; 4789 4790 /* 4791 * Reset the chip 4792 */ 4793 mutex_enter(&dp->intrlock); 4794 dp->nic_state = NIC_STATE_STOPPED; 4795 ret = (*dp->gc.gc_reset_chip)(dp); 4796 mutex_exit(&dp->intrlock); 4797 if (ret != GEM_SUCCESS) { 4798 goto err_free_regs; 4799 } 4800 4801 /* 4802 * HW dependant paremeter initialization 4803 */ 4804 mutex_enter(&dp->intrlock); 4805 ret = (*dp->gc.gc_attach_chip)(dp); 4806 mutex_exit(&dp->intrlock); 4807 if (ret != GEM_SUCCESS) { 4808 goto err_free_regs; 4809 } 4810 4811 #ifdef DEBUG_MULTIFRAGS 4812 dp->gc.gc_tx_copy_thresh = dp->mtu; 4813 #endif 4814 /* allocate tx and rx resources */ 4815 if (gem_alloc_memory(dp)) { 4816 goto err_free_regs; 4817 } 4818 4819 DPRINTF(0, (CE_CONT, 4820 "!%s: at 0x%x, %02x:%02x:%02x:%02x:%02x:%02x", 4821 dp->name, (long)dp->base_addr, 4822 dp->dev_addr.ether_addr_octet[0], 4823 dp->dev_addr.ether_addr_octet[1], 4824 dp->dev_addr.ether_addr_octet[2], 4825 dp->dev_addr.ether_addr_octet[3], 4826 dp->dev_addr.ether_addr_octet[4], 4827 dp->dev_addr.ether_addr_octet[5])); 4828 4829 /* copy mac address */ 4830 dp->cur_addr = dp->dev_addr; 4831 4832 gem_gld3_init(dp, macp); 4833 4834 /* Probe MII phy (scan phy) */ 4835 dp->mii_lpable = 0; 4836 dp->mii_advert = 0; 4837 dp->mii_exp = 0; 4838 dp->mii_ctl1000 = 0; 4839 dp->mii_stat1000 = 0; 4840 if ((*dp->gc.gc_mii_probe)(dp) != GEM_SUCCESS) { 4841 goto err_free_ring; 4842 } 4843 4844 /* mask unsupported abilities */ 4845 dp->anadv_1000fdx &= 4846 BOOLEAN(dp->mii_xstatus & 4847 (MII_XSTATUS_1000BASEX_FD | MII_XSTATUS_1000BASET_FD)); 4848 dp->anadv_1000hdx &= 4849 BOOLEAN(dp->mii_xstatus & 4850 (MII_XSTATUS_1000BASEX | MII_XSTATUS_1000BASET)); 4851 dp->anadv_100t4 &= BOOLEAN(dp->mii_status & MII_STATUS_100_BASE_T4); 4852 dp->anadv_100fdx &= BOOLEAN(dp->mii_status & MII_STATUS_100_BASEX_FD); 4853 dp->anadv_100hdx &= BOOLEAN(dp->mii_status & MII_STATUS_100_BASEX); 4854 dp->anadv_10fdx &= BOOLEAN(dp->mii_status & MII_STATUS_10_FD); 4855 dp->anadv_10hdx &= BOOLEAN(dp->mii_status & MII_STATUS_10); 4856 4857 gem_choose_forcedmode(dp); 4858 4859 /* initialize MII phy if required */ 4860 if (dp->gc.gc_mii_init) { 4861 if ((*dp->gc.gc_mii_init)(dp) != GEM_SUCCESS) { 4862 goto err_free_ring; 4863 } 4864 } 4865 4866 /* 4867 * initialize kstats including mii statistics 4868 */ 4869 gem_nd_setup(dp); 4870 4871 /* 4872 * Add interrupt to system. 4873 */ 4874 if (ret = mac_register(macp, &dp->mh)) { 4875 cmn_err(CE_WARN, "!%s: mac_register failed, error:%d", 4876 dp->name, ret); 4877 goto err_release_stats; 4878 } 4879 mac_free(macp); 4880 macp = NULL; 4881 4882 if (dp->misc_flag & GEM_SOFTINTR) { 4883 if (ddi_add_softintr(dip, 4884 DDI_SOFTINT_LOW, &dp->soft_id, 4885 NULL, NULL, 4886 (uint_t (*)(caddr_t))gem_intr, 4887 (caddr_t)dp) != DDI_SUCCESS) { 4888 cmn_err(CE_WARN, "!%s: ddi_add_softintr failed", 4889 dp->name); 4890 goto err_unregister; 4891 } 4892 } else if ((dp->misc_flag & GEM_NOINTR) == 0) { 4893 if (ddi_add_intr(dip, 0, NULL, NULL, 4894 (uint_t (*)(caddr_t))gem_intr, 4895 (caddr_t)dp) != DDI_SUCCESS) { 4896 cmn_err(CE_WARN, "!%s: ddi_add_intr failed", dp->name); 4897 goto err_unregister; 4898 } 4899 } else { 4900 /* 4901 * Dont use interrupt. 4902 * schedule first call of gem_intr_watcher 4903 */ 4904 dp->intr_watcher_id = 4905 timeout((void (*)(void *))gem_intr_watcher, 4906 (void *)dp, drv_usectohz(3*1000000)); 4907 } 4908 4909 /* link this device to dev_info */ 4910 dp->next = (struct gem_dev *)ddi_get_driver_private(dip); 4911 ddi_set_driver_private(dip, (caddr_t)dp); 4912 4913 /* reset_mii and start mii link watcher */ 4914 gem_mii_start(dp); 4915 4916 DPRINTF(2, (CE_CONT, "!gem_do_attach: return: success")); 4917 return (dp); 4918 4919 err_unregister: 4920 (void) mac_unregister(dp->mh); 4921 err_release_stats: 4922 /* release NDD resources */ 4923 gem_nd_cleanup(dp); 4924 4925 err_free_ring: 4926 gem_free_memory(dp); 4927 err_free_regs: 4928 ddi_regs_map_free(&dp->regs_handle); 4929 err_free_locks: 4930 mutex_destroy(&dp->xmitlock); 4931 mutex_destroy(&dp->intrlock); 4932 cv_destroy(&dp->tx_drain_cv); 4933 err_free_private: 4934 if (macp) { 4935 mac_free(macp); 4936 } 4937 kmem_free((caddr_t)dp, GEM_LOCAL_DATA_SIZE(gc)); 4938 4939 return (NULL); 4940 } 4941 4942 int 4943 gem_do_detach(dev_info_t *dip) 4944 { 4945 struct gem_dev *dp; 4946 struct gem_dev *tmp; 4947 caddr_t private; 4948 int priv_size; 4949 ddi_acc_handle_t rh; 4950 4951 dp = GEM_GET_DEV(dip); 4952 if (dp == NULL) { 4953 return (DDI_SUCCESS); 4954 } 4955 4956 rh = dp->regs_handle; 4957 private = dp->private; 4958 priv_size = dp->priv_size; 4959 4960 while (dp) { 4961 /* ensure any rx buffers are not used */ 4962 if (dp->rx_buf_allocated != dp->rx_buf_freecnt) { 4963 /* resource is busy */ 4964 cmn_err(CE_PANIC, 4965 "!%s: %s: rxbuf is busy: allocated:%d, freecnt:%d", 4966 dp->name, __func__, 4967 dp->rx_buf_allocated, dp->rx_buf_freecnt); 4968 /* NOT REACHED */ 4969 } 4970 4971 /* stop mii link watcher */ 4972 gem_mii_stop(dp); 4973 4974 /* unregister interrupt handler */ 4975 if (dp->misc_flag & GEM_SOFTINTR) { 4976 ddi_remove_softintr(dp->soft_id); 4977 } else if ((dp->misc_flag & GEM_NOINTR) == 0) { 4978 ddi_remove_intr(dip, 0, dp->iblock_cookie); 4979 } else { 4980 /* stop interrupt watcher */ 4981 if (dp->intr_watcher_id) { 4982 while (untimeout(dp->intr_watcher_id) == -1) 4983 ; 4984 dp->intr_watcher_id = 0; 4985 } 4986 } 4987 4988 /* unregister with gld v3 */ 4989 (void) mac_unregister(dp->mh); 4990 4991 /* release NDD resources */ 4992 gem_nd_cleanup(dp); 4993 /* release buffers, descriptors and dma resources */ 4994 gem_free_memory(dp); 4995 4996 /* release locks and condition variables */ 4997 mutex_destroy(&dp->xmitlock); 4998 mutex_destroy(&dp->intrlock); 4999 cv_destroy(&dp->tx_drain_cv); 5000 5001 /* release basic memory resources */ 5002 tmp = dp->next; 5003 kmem_free((caddr_t)dp, GEM_LOCAL_DATA_SIZE(&dp->gc)); 5004 dp = tmp; 5005 } 5006 5007 /* release common private memory for the nic */ 5008 kmem_free(private, priv_size); 5009 5010 /* release register mapping resources */ 5011 ddi_regs_map_free(&rh); 5012 ddi_set_driver_private(dip, NULL); 5013 5014 DPRINTF(2, (CE_CONT, "!%s%d: gem_do_detach: return: success", 5015 ddi_driver_name(dip), ddi_get_instance(dip))); 5016 5017 return (DDI_SUCCESS); 5018 } 5019 5020 int 5021 gem_suspend(dev_info_t *dip) 5022 { 5023 struct gem_dev *dp; 5024 5025 /* 5026 * stop the device 5027 */ 5028 dp = GEM_GET_DEV(dip); 5029 ASSERT(dp); 5030 5031 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 5032 5033 for (; dp; dp = dp->next) { 5034 5035 /* stop mii link watcher */ 5036 gem_mii_stop(dp); 5037 5038 /* stop interrupt watcher for no-intr mode */ 5039 if (dp->misc_flag & GEM_NOINTR) { 5040 if (dp->intr_watcher_id) { 5041 while (untimeout(dp->intr_watcher_id) == -1) 5042 ; 5043 } 5044 dp->intr_watcher_id = 0; 5045 } 5046 5047 /* stop tx timeout watcher */ 5048 if (dp->timeout_id) { 5049 while (untimeout(dp->timeout_id) == -1) 5050 ; 5051 dp->timeout_id = 0; 5052 } 5053 5054 /* make the nic state inactive */ 5055 mutex_enter(&dp->intrlock); 5056 (void) gem_mac_stop(dp, 0); 5057 ASSERT(!dp->mac_active); 5058 5059 /* no further register access */ 5060 dp->mac_suspended = B_TRUE; 5061 mutex_exit(&dp->intrlock); 5062 } 5063 5064 /* XXX - power down the nic */ 5065 5066 return (DDI_SUCCESS); 5067 } 5068 5069 int 5070 gem_resume(dev_info_t *dip) 5071 { 5072 struct gem_dev *dp; 5073 5074 /* 5075 * restart the device 5076 */ 5077 dp = GEM_GET_DEV(dip); 5078 ASSERT(dp); 5079 5080 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 5081 5082 for (; dp; dp = dp->next) { 5083 5084 /* 5085 * Bring up the nic after power up 5086 */ 5087 5088 /* gem_xxx.c layer to setup power management state. */ 5089 ASSERT(!dp->mac_active); 5090 5091 /* reset the chip, because we are just after power up. */ 5092 mutex_enter(&dp->intrlock); 5093 5094 dp->mac_suspended = B_FALSE; 5095 dp->nic_state = NIC_STATE_STOPPED; 5096 5097 if ((*dp->gc.gc_reset_chip)(dp) != GEM_SUCCESS) { 5098 cmn_err(CE_WARN, "%s: %s: failed to reset chip", 5099 dp->name, __func__); 5100 mutex_exit(&dp->intrlock); 5101 goto err; 5102 } 5103 mutex_exit(&dp->intrlock); 5104 5105 /* initialize mii phy because we are just after power up */ 5106 if (dp->gc.gc_mii_init) { 5107 (void) (*dp->gc.gc_mii_init)(dp); 5108 } 5109 5110 if (dp->misc_flag & GEM_NOINTR) { 5111 /* 5112 * schedule first call of gem_intr_watcher 5113 * instead of interrupts. 5114 */ 5115 dp->intr_watcher_id = 5116 timeout((void (*)(void *))gem_intr_watcher, 5117 (void *)dp, drv_usectohz(3*1000000)); 5118 } 5119 5120 /* restart mii link watcher */ 5121 gem_mii_start(dp); 5122 5123 /* restart mac */ 5124 mutex_enter(&dp->intrlock); 5125 5126 if (gem_mac_init(dp) != GEM_SUCCESS) { 5127 mutex_exit(&dp->intrlock); 5128 goto err_reset; 5129 } 5130 dp->nic_state = NIC_STATE_INITIALIZED; 5131 5132 /* setup media mode if the link have been up */ 5133 if (dp->mii_state == MII_STATE_LINKUP) { 5134 if ((dp->gc.gc_set_media)(dp) != GEM_SUCCESS) { 5135 mutex_exit(&dp->intrlock); 5136 goto err_reset; 5137 } 5138 } 5139 5140 /* enable mac address and rx filter */ 5141 dp->rxmode |= RXMODE_ENABLE; 5142 if ((*dp->gc.gc_set_rx_filter)(dp) != GEM_SUCCESS) { 5143 mutex_exit(&dp->intrlock); 5144 goto err_reset; 5145 } 5146 dp->nic_state = NIC_STATE_ONLINE; 5147 5148 /* restart tx timeout watcher */ 5149 dp->timeout_id = timeout((void (*)(void *))gem_tx_timeout, 5150 (void *)dp, 5151 dp->gc.gc_tx_timeout_interval); 5152 5153 /* now the nic is fully functional */ 5154 if (dp->mii_state == MII_STATE_LINKUP) { 5155 if (gem_mac_start(dp) != GEM_SUCCESS) { 5156 mutex_exit(&dp->intrlock); 5157 goto err_reset; 5158 } 5159 } 5160 mutex_exit(&dp->intrlock); 5161 } 5162 5163 return (DDI_SUCCESS); 5164 5165 err_reset: 5166 if (dp->intr_watcher_id) { 5167 while (untimeout(dp->intr_watcher_id) == -1) 5168 ; 5169 dp->intr_watcher_id = 0; 5170 } 5171 mutex_enter(&dp->intrlock); 5172 (*dp->gc.gc_reset_chip)(dp); 5173 dp->nic_state = NIC_STATE_STOPPED; 5174 mutex_exit(&dp->intrlock); 5175 5176 err: 5177 return (DDI_FAILURE); 5178 } 5179 5180 /* 5181 * misc routines for PCI 5182 */ 5183 uint8_t 5184 gem_search_pci_cap(dev_info_t *dip, 5185 ddi_acc_handle_t conf_handle, uint8_t target) 5186 { 5187 uint8_t pci_cap_ptr; 5188 uint32_t pci_cap; 5189 5190 /* search power management capablities */ 5191 pci_cap_ptr = pci_config_get8(conf_handle, PCI_CONF_CAP_PTR); 5192 while (pci_cap_ptr) { 5193 /* read pci capability header */ 5194 pci_cap = pci_config_get32(conf_handle, pci_cap_ptr); 5195 if ((pci_cap & 0xff) == target) { 5196 /* found */ 5197 break; 5198 } 5199 /* get next_ptr */ 5200 pci_cap_ptr = (pci_cap >> 8) & 0xff; 5201 } 5202 return (pci_cap_ptr); 5203 } 5204 5205 int 5206 gem_pci_set_power_state(dev_info_t *dip, 5207 ddi_acc_handle_t conf_handle, uint_t new_mode) 5208 { 5209 uint8_t pci_cap_ptr; 5210 uint32_t pmcsr; 5211 uint_t unit; 5212 const char *drv_name; 5213 5214 ASSERT(new_mode < 4); 5215 5216 unit = ddi_get_instance(dip); 5217 drv_name = ddi_driver_name(dip); 5218 5219 /* search power management capablities */ 5220 pci_cap_ptr = gem_search_pci_cap(dip, conf_handle, PCI_CAP_ID_PM); 5221 5222 if (pci_cap_ptr == 0) { 5223 cmn_err(CE_CONT, 5224 "!%s%d: doesn't have pci power management capability", 5225 drv_name, unit); 5226 return (DDI_FAILURE); 5227 } 5228 5229 /* read power management capabilities */ 5230 pmcsr = pci_config_get32(conf_handle, pci_cap_ptr + PCI_PMCSR); 5231 5232 DPRINTF(0, (CE_CONT, 5233 "!%s%d: pmc found at 0x%x: pmcsr: 0x%08x", 5234 drv_name, unit, pci_cap_ptr, pmcsr)); 5235 5236 /* 5237 * Is the resuested power mode supported? 5238 */ 5239 /* not yet */ 5240 5241 /* 5242 * move to new mode 5243 */ 5244 pmcsr = (pmcsr & ~PCI_PMCSR_STATE_MASK) | new_mode; 5245 pci_config_put32(conf_handle, pci_cap_ptr + PCI_PMCSR, pmcsr); 5246 5247 return (DDI_SUCCESS); 5248 } 5249 5250 /* 5251 * select suitable register for by specified address space or register 5252 * offset in PCI config space 5253 */ 5254 int 5255 gem_pci_regs_map_setup(dev_info_t *dip, uint32_t which, uint32_t mask, 5256 struct ddi_device_acc_attr *attrp, 5257 caddr_t *basep, ddi_acc_handle_t *hp) 5258 { 5259 struct pci_phys_spec *regs; 5260 uint_t len; 5261 uint_t unit; 5262 uint_t n; 5263 uint_t i; 5264 int ret; 5265 const char *drv_name; 5266 5267 unit = ddi_get_instance(dip); 5268 drv_name = ddi_driver_name(dip); 5269 5270 /* Search IO-range or memory-range to be mapped */ 5271 regs = NULL; 5272 len = 0; 5273 5274 if ((ret = ddi_prop_lookup_int_array( 5275 DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 5276 "reg", (void *)®s, &len)) != DDI_PROP_SUCCESS) { 5277 cmn_err(CE_WARN, 5278 "!%s%d: failed to get reg property (ret:%d)", 5279 drv_name, unit, ret); 5280 return (DDI_FAILURE); 5281 } 5282 n = len / (sizeof (struct pci_phys_spec) / sizeof (int)); 5283 5284 ASSERT(regs != NULL && len > 0); 5285 5286 #if GEM_DEBUG_LEVEL > 0 5287 for (i = 0; i < n; i++) { 5288 cmn_err(CE_CONT, 5289 "!%s%d: regs[%d]: %08x.%08x.%08x.%08x.%08x", 5290 drv_name, unit, i, 5291 regs[i].pci_phys_hi, 5292 regs[i].pci_phys_mid, 5293 regs[i].pci_phys_low, 5294 regs[i].pci_size_hi, 5295 regs[i].pci_size_low); 5296 } 5297 #endif 5298 for (i = 0; i < n; i++) { 5299 if ((regs[i].pci_phys_hi & mask) == which) { 5300 /* it's the requested space */ 5301 ddi_prop_free(regs); 5302 goto address_range_found; 5303 } 5304 } 5305 ddi_prop_free(regs); 5306 return (DDI_FAILURE); 5307 5308 address_range_found: 5309 if ((ret = ddi_regs_map_setup(dip, i, basep, 0, 0, attrp, hp)) 5310 != DDI_SUCCESS) { 5311 cmn_err(CE_CONT, 5312 "!%s%d: ddi_regs_map_setup failed (ret:%d)", 5313 drv_name, unit, ret); 5314 } 5315 5316 return (ret); 5317 } 5318 5319 void 5320 gem_mod_init(struct dev_ops *dop, char *name) 5321 { 5322 mac_init_ops(dop, name); 5323 } 5324 5325 void 5326 gem_mod_fini(struct dev_ops *dop) 5327 { 5328 mac_fini_ops(dop); 5329 } 5330