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