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