1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/stream.h> 29 #include <sys/strsun.h> 30 #include <sys/stat.h> 31 #include <sys/modctl.h> 32 #include <sys/ethernet.h> 33 #include <sys/debug.h> 34 #include <sys/conf.h> 35 #include <sys/mii.h> 36 #include <sys/miiregs.h> 37 #include <sys/sysmacros.h> 38 #include <sys/dditypes.h> 39 #include <sys/ddi.h> 40 #include <sys/sunddi.h> 41 #include <sys/byteorder.h> 42 #include <sys/note.h> 43 #include <sys/vlan.h> 44 #include <sys/stream.h> 45 46 #include "atge.h" 47 #include "atge_l1e_reg.h" 48 #include "atge_cmn_reg.h" 49 50 /* 51 * L1E specfic functions. 52 */ 53 void atge_l1e_device_reset(atge_t *); 54 void atge_l1e_stop_rx_mac(atge_t *); 55 void atge_l1e_stop_tx_mac(atge_t *); 56 57 static ddi_dma_attr_t atge_l1e_dma_attr_tx_desc = { 58 DMA_ATTR_V0, /* dma_attr_version */ 59 0, /* dma_attr_addr_lo */ 60 0x0000ffffffffull, /* dma_attr_addr_hi */ 61 0x0000ffffffffull, /* dma_attr_count_max */ 62 L1E_TX_RING_ALIGN, /* dma_attr_align */ 63 0x0000fffc, /* dma_attr_burstsizes */ 64 1, /* dma_attr_minxfer */ 65 0x0000ffffffffull, /* dma_attr_maxxfer */ 66 0x0000ffffffffull, /* dma_attr_seg */ 67 1, /* dma_attr_sgllen */ 68 1, /* dma_attr_granular */ 69 0 /* dma_attr_flags */ 70 }; 71 72 static ddi_dma_attr_t atge_l1e_dma_attr_rx_desc = { 73 DMA_ATTR_V0, /* dma_attr_version */ 74 0, /* dma_attr_addr_lo */ 75 0x0000ffffffffull, /* dma_attr_addr_hi */ 76 0x0000ffffffffull, /* dma_attr_count_max */ 77 L1E_RX_PAGE_ALIGN, /* dma_attr_align */ 78 0x0000fffc, /* dma_attr_burstsizes */ 79 1, /* dma_attr_minxfer */ 80 0x0000ffffffffull, /* dma_attr_maxxfer */ 81 0x0000ffffffffull, /* dma_attr_seg */ 82 1, /* dma_attr_sgllen */ 83 1, /* dma_attr_granular */ 84 0 /* dma_attr_flags */ 85 }; 86 87 static ddi_dma_attr_t atge_l1e_dma_attr_cmb = { 88 DMA_ATTR_V0, /* dma_attr_version */ 89 0, /* dma_attr_addr_lo */ 90 0x0000ffffffffull, /* dma_attr_addr_hi */ 91 0x0000ffffffffull, /* dma_attr_count_max */ 92 L1E_CMB_ALIGN, /* dma_attr_align */ 93 0x0000fffc, /* dma_attr_burstsizes */ 94 1, /* dma_attr_minxfer */ 95 0x0000ffffffffull, /* dma_attr_maxxfer */ 96 0x0000ffffffffull, /* dma_attr_seg */ 97 1, /* dma_attr_sgllen */ 98 1, /* dma_attr_granular */ 99 0 /* dma_attr_flags */ 100 }; 101 102 void atge_l1e_rx_next_pkt(atge_t *, uint32_t); 103 104 void 105 atge_rx_desc_free(atge_t *atgep) 106 { 107 atge_l1e_data_t *l1e; 108 atge_dma_t *dma; 109 int pages; 110 111 l1e = (atge_l1e_data_t *)atgep->atge_private_data; 112 if (l1e == NULL) 113 return; 114 115 if (l1e->atge_l1e_rx_page == NULL) 116 return; 117 118 for (pages = 0; pages < L1E_RX_PAGES; pages++) { 119 dma = l1e->atge_l1e_rx_page[pages]; 120 if (dma != NULL) { 121 (void) ddi_dma_unbind_handle(dma->hdl); 122 ddi_dma_mem_free(&dma->acchdl); 123 ddi_dma_free_handle(&dma->hdl); 124 kmem_free(dma, sizeof (atge_dma_t)); 125 } 126 } 127 128 kmem_free(l1e->atge_l1e_rx_page, L1E_RX_PAGES * sizeof (atge_dma_t *)); 129 l1e->atge_l1e_rx_page = NULL; 130 } 131 132 int 133 atge_l1e_alloc_dma(atge_t *atgep) 134 { 135 atge_dma_t *dma; 136 atge_l1e_data_t *l1e; 137 int err; 138 int pages; 139 int guard_size; 140 141 l1e = kmem_zalloc(sizeof (atge_l1e_data_t), KM_SLEEP); 142 atgep->atge_private_data = l1e; 143 144 /* 145 * Allocate TX ring descriptor. 146 */ 147 atgep->atge_tx_buf_len = atgep->atge_mtu + 148 sizeof (struct ether_header) + VLAN_TAGSZ + ETHERFCSL; 149 atgep->atge_tx_ring = kmem_alloc(sizeof (atge_ring_t), KM_SLEEP); 150 atgep->atge_tx_ring->r_atge = atgep; 151 atgep->atge_tx_ring->r_desc_ring = NULL; 152 dma = atge_alloc_a_dma_blk(atgep, &atge_l1e_dma_attr_tx_desc, 153 ATGE_TX_RING_SZ, DDI_DMA_RDWR); 154 if (dma == NULL) { 155 ATGE_DB(("%s :%s failed", 156 atgep->atge_name, __func__)); 157 return (DDI_FAILURE); 158 } 159 atgep->atge_tx_ring->r_desc_ring = dma; 160 161 /* 162 * Allocate DMA buffers for TX ring. 163 */ 164 err = atge_alloc_buffers(atgep->atge_tx_ring, ATGE_TX_RING_CNT, 165 atgep->atge_tx_buf_len, DDI_DMA_WRITE); 166 if (err != DDI_SUCCESS) { 167 ATGE_DB(("%s :%s() TX buffers failed", 168 atgep->atge_name, __func__)); 169 return (err); 170 } 171 172 /* 173 * Allocate RX pages. 174 */ 175 atgep->atge_rx_buf_len = atgep->atge_mtu + 176 sizeof (struct ether_header) + VLAN_TAGSZ + ETHERFCSL; 177 178 if (atgep->atge_flags & ATGE_FLAG_JUMBO) 179 guard_size = L1E_JUMBO_FRAMELEN; 180 else 181 guard_size = L1E_MAX_FRAMELEN; 182 183 l1e->atge_l1e_pagesize = ROUNDUP(guard_size + L1E_RX_PAGE_SZ, 184 L1E_RX_PAGE_ALIGN); 185 l1e->atge_l1e_rx_page = 186 kmem_zalloc(L1E_RX_PAGES * sizeof (atge_dma_t *), KM_SLEEP); 187 188 ATGE_DB(("%s: %s() atge_l1e_pagesize : %d, L1E_RX_PAGE_SZ : %d", 189 atgep->atge_name, __func__, l1e->atge_l1e_pagesize, 190 L1E_RX_PAGE_SZ)); 191 192 err = DDI_SUCCESS; 193 for (pages = 0; pages < L1E_RX_PAGES; pages++) { 194 dma = atge_alloc_a_dma_blk(atgep, &atge_l1e_dma_attr_rx_desc, 195 l1e->atge_l1e_pagesize, DDI_DMA_READ); 196 197 if (dma == NULL) { 198 err = DDI_FAILURE; 199 break; 200 } 201 202 l1e->atge_l1e_rx_page[pages] = dma; 203 } 204 205 if (err == DDI_FAILURE) { 206 ATGE_DB(("%s :%s RX pages failed", 207 atgep->atge_name, __func__)); 208 return (DDI_FAILURE); 209 } 210 211 /* 212 * Allocate CMB used for fetching interrupt status data. 213 */ 214 ATGE_DB(("%s: %s() L1E_RX_CMB_SZ : %x", atgep->atge_name, 215 __func__, L1E_RX_CMB_SZ)); 216 217 err = DDI_SUCCESS; 218 dma = atge_alloc_a_dma_blk(atgep, &atge_l1e_dma_attr_cmb, 219 L1E_RX_CMB_SZ * L1E_RX_PAGES, DDI_DMA_RDWR); 220 if (dma == NULL) { 221 ATGE_DB(("%s :%s() RX CMB failed", 222 atgep->atge_name, __func__)); 223 return (DDI_FAILURE); 224 } 225 l1e->atge_l1e_rx_cmb = dma; 226 227 if (err == DDI_FAILURE) { 228 ATGE_DB(("%s :%s() RX CMB failed", 229 atgep->atge_name, __func__)); 230 return (DDI_FAILURE); 231 } 232 233 atgep->atge_hw_stats = kmem_zalloc(sizeof (atge_l1e_smb_t), KM_SLEEP); 234 235 return (DDI_SUCCESS); 236 } 237 238 void 239 atge_l1e_free_dma(atge_t *atgep) 240 { 241 atge_l1e_data_t *l1e; 242 243 /* 244 * Free TX ring. 245 */ 246 if (atgep->atge_tx_ring != NULL) { 247 atge_free_buffers(atgep->atge_tx_ring, ATGE_TX_RING_CNT); 248 249 if (atgep->atge_tx_ring->r_desc_ring != NULL) { 250 atge_free_a_dma_blk(atgep->atge_tx_ring->r_desc_ring); 251 } 252 253 kmem_free(atgep->atge_tx_ring, sizeof (atge_ring_t)); 254 atgep->atge_tx_ring = NULL; 255 } 256 257 l1e = atgep->atge_private_data; 258 if (l1e == NULL) 259 return; 260 261 /* 262 * Free RX CMB. 263 */ 264 if (l1e->atge_l1e_rx_cmb != NULL) { 265 atge_free_a_dma_blk(l1e->atge_l1e_rx_cmb); 266 l1e->atge_l1e_rx_cmb = NULL; 267 } 268 269 /* 270 * Free RX buffers and RX ring. 271 */ 272 atge_rx_desc_free(atgep); 273 274 /* 275 * Free the memory allocated for gathering hw stats. 276 */ 277 if (atgep->atge_hw_stats != NULL) { 278 kmem_free(atgep->atge_hw_stats, sizeof (atge_l1e_smb_t)); 279 atgep->atge_hw_stats = NULL; 280 } 281 } 282 283 void 284 atge_l1e_init_rx_pages(atge_t *atgep) 285 { 286 atge_l1e_data_t *l1e; 287 atge_dma_t *dma; 288 int pages; 289 290 ASSERT(atgep != NULL); 291 l1e = atgep->atge_private_data; 292 293 ASSERT(l1e != NULL); 294 295 l1e->atge_l1e_proc_max = L1E_RX_PAGE_SZ / ETHERMIN; 296 l1e->atge_l1e_rx_curp = 0; 297 l1e->atge_l1e_rx_seqno = 0; 298 299 for (pages = 0; pages < L1E_RX_PAGES; pages++) { 300 l1e->atge_l1e_rx_page_cons = 0; 301 l1e->atge_l1e_rx_page_prods[pages] = 0; 302 303 304 dma = l1e->atge_l1e_rx_page[pages]; 305 ASSERT(dma != NULL); 306 bzero(dma->addr, l1e->atge_l1e_pagesize); 307 DMA_SYNC(dma, 0, l1e->atge_l1e_pagesize, DDI_DMA_SYNC_FORDEV); 308 } 309 310 dma = l1e->atge_l1e_rx_cmb; 311 ASSERT(dma != NULL); 312 bzero(dma->addr, L1E_RX_CMB_SZ * L1E_RX_PAGES); 313 DMA_SYNC(dma, 0, L1E_RX_CMB_SZ * L1E_RX_PAGES, DDI_DMA_SYNC_FORDEV); 314 } 315 316 void 317 atge_l1e_init_tx_ring(atge_t *atgep) 318 { 319 ASSERT(atgep != NULL); 320 ASSERT(atgep->atge_tx_ring != NULL); 321 ASSERT(atgep->atge_tx_ring->r_desc_ring != NULL); 322 323 atgep->atge_tx_ring->r_producer = 0; 324 atgep->atge_tx_ring->r_consumer = 0; 325 atgep->atge_tx_ring->r_avail_desc = ATGE_TX_RING_CNT; 326 327 bzero(atgep->atge_tx_ring->r_desc_ring->addr, ATGE_TX_RING_SZ); 328 329 DMA_SYNC(atgep->atge_tx_ring->r_desc_ring, 0, ATGE_TX_RING_SZ, 330 DDI_DMA_SYNC_FORDEV); 331 } 332 333 void 334 atge_l1e_program_dma(atge_t *atgep) 335 { 336 atge_l1e_data_t *l1e; 337 uint64_t paddr; 338 uint32_t reg; 339 340 l1e = (atge_l1e_data_t *)atgep->atge_private_data; 341 342 /* 343 * Clear WOL status and disable all WOL feature as WOL 344 * would interfere Rx operation under normal environments. 345 */ 346 (void) INL(atgep, ATGE_WOL_CFG); 347 OUTL(atgep, ATGE_WOL_CFG, 0); 348 349 /* 350 * Set Tx descriptor/RXF0/CMB base addresses. They share 351 * the same high address part of DMAable region. 352 */ 353 paddr = atgep->atge_tx_ring->r_desc_ring->cookie.dmac_laddress; 354 OUTL(atgep, ATGE_DESC_ADDR_HI, ATGE_ADDR_HI(paddr)); 355 OUTL(atgep, ATGE_DESC_TPD_ADDR_LO, ATGE_ADDR_LO(paddr)); 356 OUTL(atgep, ATGE_DESC_TPD_CNT, 357 (ATGE_TX_RING_CNT << DESC_TPD_CNT_SHIFT) & DESC_TPD_CNT_MASK); 358 359 /* Set Rx page base address, note we use single queue. */ 360 paddr = l1e->atge_l1e_rx_page[0]->cookie.dmac_laddress; 361 OUTL(atgep, L1E_RXF0_PAGE0_ADDR_LO, ATGE_ADDR_LO(paddr)); 362 paddr = l1e->atge_l1e_rx_page[1]->cookie.dmac_laddress; 363 OUTL(atgep, L1E_RXF0_PAGE1_ADDR_LO, ATGE_ADDR_LO(paddr)); 364 365 /* Set Tx/Rx CMB addresses. */ 366 paddr = l1e->atge_l1e_rx_cmb->cookie.dmac_laddress; 367 OUTL(atgep, L1E_RXF0_CMB0_ADDR_LO, ATGE_ADDR_LO(paddr)); 368 paddr = l1e->atge_l1e_rx_cmb->cookie.dmac_laddress + sizeof (uint32_t); 369 OUTL(atgep, L1E_RXF0_CMB1_ADDR_LO, ATGE_ADDR_LO(paddr)); 370 371 /* Mark RXF0 valid. */ 372 OUTB(atgep, L1E_RXF0_PAGE0, RXF_VALID); /* 0 */ 373 OUTB(atgep, L1E_RXF0_PAGE1, RXF_VALID); /* 1 */ 374 OUTB(atgep, L1E_RXF0_PAGE0 + 2, 0); 375 OUTB(atgep, L1E_RXF0_PAGE0 + 3, 0); 376 OUTB(atgep, L1E_RXF0_PAGE0 + 4, 0); 377 OUTB(atgep, L1E_RXF0_PAGE0 + 5, 0); 378 OUTB(atgep, L1E_RXF0_PAGE0 + 6, 0); 379 OUTB(atgep, L1E_RXF0_PAGE0 + 6, 0); 380 381 /* Set Rx page size, excluding guard frame size. */ 382 OUTL(atgep, L1E_RXF_PAGE_SIZE, L1E_RX_PAGE_SZ); 383 384 /* Tell hardware that we're ready to load DMA blocks. */ 385 OUTL(atgep, ATGE_DMA_BLOCK, DMA_BLOCK_LOAD); 386 387 /* Set Rx/Tx interrupt trigger threshold. */ 388 OUTL(atgep, L1E_INT_TRIG_THRESH, (1 << INT_TRIG_RX_THRESH_SHIFT) | 389 (4 << INT_TRIG_TX_THRESH_SHIFT)); 390 391 /* 392 * Set interrupt trigger timer, its purpose and relation 393 * with interrupt moderation mechanism is not clear yet. 394 */ 395 OUTL(atgep, L1E_INT_TRIG_TIMER, 396 ((ATGE_USECS(10) << INT_TRIG_RX_TIMER_SHIFT) | 397 (ATGE_USECS(1000) << INT_TRIG_TX_TIMER_SHIFT))); 398 399 reg = ATGE_USECS(ATGE_IM_RX_TIMER_DEFAULT) << IM_TIMER_RX_SHIFT; 400 reg |= ATGE_USECS(ATGE_IM_TX_TIMER_DEFAULT) << IM_TIMER_TX_SHIFT; 401 OUTL(atgep, ATGE_IM_TIMER, reg); 402 403 reg = INL(atgep, ATGE_MASTER_CFG); 404 reg &= ~(MASTER_CHIP_REV_MASK | MASTER_CHIP_ID_MASK); 405 reg &= ~(MASTER_IM_RX_TIMER_ENB | MASTER_IM_TX_TIMER_ENB); 406 reg |= MASTER_IM_RX_TIMER_ENB; 407 reg |= MASTER_IM_TX_TIMER_ENB; 408 OUTL(atgep, ATGE_MASTER_CFG, reg); 409 410 OUTW(atgep, RX_COALSC_PKT_1e, 0); 411 OUTW(atgep, RX_COALSC_TO_1e, 0); 412 OUTW(atgep, TX_COALSC_PKT_1e, 1); 413 OUTW(atgep, TX_COALSC_TO_1e, 4000/2); /* 4mS */ 414 } 415 416 mblk_t * 417 atge_l1e_receive(atge_t *atgep) 418 { 419 atge_l1e_data_t *l1e; 420 atge_dma_t *dma_rx_page; 421 atge_dma_t *dma_rx_cmb; 422 uint32_t *ptr; 423 uint32_t cons, current_page; 424 uchar_t *pageaddr, *bufp; 425 rx_rs_t *rs; 426 int prog; 427 uint32_t seqno, len, flags; 428 mblk_t *mp = NULL, *rx_head, *rx_tail; 429 static uint32_t gen = 0; 430 431 l1e = atgep->atge_private_data; 432 433 ASSERT(MUTEX_HELD(&atgep->atge_intr_lock)); 434 ASSERT(l1e != NULL); 435 436 rx_tail = NULL; 437 rx_head = NULL; 438 439 current_page = l1e->atge_l1e_rx_curp; 440 441 /* Sync CMB first */ 442 dma_rx_cmb = l1e->atge_l1e_rx_cmb; 443 DMA_SYNC(dma_rx_cmb, 0, L1E_RX_CMB_SZ * L1E_RX_PAGES, 444 DDI_DMA_SYNC_FORKERNEL); 445 446 dma_rx_page = l1e->atge_l1e_rx_page[current_page]; 447 448 /* 449 * Get the producer offset from CMB. 450 */ 451 ptr = (void *)dma_rx_cmb->addr; 452 453 l1e->atge_l1e_rx_page_prods[current_page] = 454 ATGE_GET32(dma_rx_cmb, ptr + current_page); 455 456 /* Sync current RX Page as well */ 457 DMA_SYNC(dma_rx_page, l1e->atge_l1e_rx_page_cons, 458 l1e->atge_l1e_rx_page_prods[current_page], DDI_DMA_SYNC_FORKERNEL); 459 460 ATGE_DB(("%s: %s() prod : %d, cons : %d, curr page : %d, gen : (%d)" 461 " cmb[0,1] : %d, %d", 462 atgep->atge_name, __func__, 463 l1e->atge_l1e_rx_page_prods[current_page], 464 l1e->atge_l1e_rx_page_cons, l1e->atge_l1e_rx_curp, gen, 465 ATGE_GET32(dma_rx_cmb, ptr), ATGE_GET32(dma_rx_cmb, ptr + 1))); 466 467 for (prog = 0; prog <= l1e->atge_l1e_proc_max; prog++) { 468 cons = l1e->atge_l1e_rx_page_cons; 469 if (cons >= l1e->atge_l1e_rx_page_prods[l1e->atge_l1e_rx_curp]) 470 break; 471 472 dma_rx_page = l1e->atge_l1e_rx_page[l1e->atge_l1e_rx_curp]; 473 pageaddr = (uchar_t *)dma_rx_page->addr; 474 pageaddr = pageaddr + cons; 475 rs = (rx_rs_t *)pageaddr; 476 477 seqno = ATGE_GET32(dma_rx_page, &(rs->seqno)); 478 seqno = L1E_RX_SEQNO(seqno); 479 480 len = ATGE_GET32(dma_rx_page, &(rs->length)); 481 len = L1E_RX_BYTES(len); 482 483 flags = ATGE_GET32(dma_rx_page, &(rs->flags)); 484 485 if (seqno != l1e->atge_l1e_rx_seqno) { 486 /* 487 * We have not seen this happening but we 488 * must restart the chip if that happens. 489 */ 490 ATGE_DB(("%s: %s() MISS-MATCH in seqno :%d," 491 " atge_l1e_rx_seqno : %d, length : %d, flags : %x", 492 atgep->atge_name, __func__, seqno, 493 l1e->atge_l1e_rx_seqno, len, flags)); 494 495 mutex_enter(&atgep->atge_tx_lock); 496 atge_device_restart(atgep); 497 mutex_exit(&atgep->atge_tx_lock); 498 499 /* 500 * Return all the pkts received before restarting 501 * the chip. 502 */ 503 return (rx_head); 504 } else { 505 l1e->atge_l1e_rx_seqno++; 506 } 507 508 /* 509 * We will pass the pkt to upper layer provided it's clear 510 * from any error. 511 */ 512 if ((flags & L1E_RD_ERROR) != 0) { 513 if ((flags & (L1E_RD_CRC | L1E_RD_CODE | 514 L1E_RD_DRIBBLE | L1E_RD_RUNT | L1E_RD_OFLOW | 515 L1E_RD_TRUNC)) != 0) { 516 ATGE_DB(("%s: %s() ERRORED PKT : %x", 517 atgep->atge_name, __func__, flags)); 518 atge_l1e_rx_next_pkt(atgep, len); 519 atgep->atge_errrcv++; 520 continue; 521 } 522 } 523 524 /* 525 * So we have received a frame/pkt. 526 */ 527 if (len == 0 || len > atgep->atge_rx_buf_len) { 528 ATGE_DB(("%s: %s() PKT len > error : %d", 529 atgep->atge_name, __func__, len)); 530 atge_l1e_rx_next_pkt(atgep, len); 531 continue; 532 } 533 534 mp = allocb(len + VLAN_TAGSZ, BPRI_MED); 535 if (mp != NULL) { 536 mp->b_rptr += VLAN_TAGSZ; 537 bufp = mp->b_rptr; 538 mp->b_wptr = bufp + len; 539 mp->b_next = NULL; 540 541 bcopy(pageaddr + sizeof (rx_rs_t), bufp, len); 542 543 if (rx_tail == NULL) 544 rx_head = rx_tail = mp; 545 else { 546 rx_tail->b_next = mp; 547 rx_tail = mp; 548 } 549 550 atgep->atge_ipackets++; 551 atgep->atge_rbytes += len; 552 } else { 553 ATGE_DB(("%s: %s() PKT mp == NULL len : %d", 554 atgep->atge_name, __func__, len)); 555 556 if (len > atgep->atge_rx_buf_len) { 557 atgep->atge_toolong_errors++; 558 } else if (mp == NULL) { 559 atgep->atge_norcvbuf++; 560 } 561 } 562 563 atge_l1e_rx_next_pkt(atgep, len); 564 565 ATGE_DB(("%s: %s() seqno :%d, atge_l1e_rx_seqno :" 566 " %d, length : %d," 567 " flags : %x, cons : %d, prod : %d", 568 atgep->atge_name, __func__, seqno, 569 l1e->atge_l1e_rx_seqno, len, flags, 570 l1e->atge_l1e_rx_page_cons, 571 l1e->atge_l1e_rx_page_prods[l1e->atge_l1e_rx_curp])); 572 } 573 574 ATGE_DB(("%s: %s() receive completed (gen : %d) : cons : %d," 575 " prod :%d, L1E_RX_PAGE_SZ : %d (prog:%d)", 576 atgep->atge_name, __func__, gen, 577 l1e->atge_l1e_rx_page_cons, 578 l1e->atge_l1e_rx_page_prods[l1e->atge_l1e_rx_curp], 579 L1E_RX_PAGE_SZ, prog)); 580 581 gen++; 582 return (rx_head); 583 } 584 585 void 586 atge_l1e_rx_next_pkt(atge_t *atgep, uint32_t len) 587 { 588 atge_l1e_data_t *l1e = atgep->atge_private_data; 589 atge_dma_t *dma_rx_page; 590 atge_dma_t *dma_rx_cmb; 591 int curr = l1e->atge_l1e_rx_curp; 592 uint32_t *p; 593 594 /* 595 * Update consumer position. 596 */ 597 l1e->atge_l1e_rx_page_cons += 598 ROUNDUP(len + sizeof (rx_rs_t), L1E_RX_PAGE_ALIGN); 599 600 /* 601 * If we need to flip to the other page. Note that we use only two 602 * pages. 603 */ 604 if (l1e->atge_l1e_rx_page_cons >= L1E_RX_PAGE_SZ) { 605 ATGE_DB(("%s: %s() cons : %d, prod :%d, L1E_RX_PAGE_SZ : %d", 606 atgep->atge_name, __func__, l1e->atge_l1e_rx_page_cons, 607 l1e->atge_l1e_rx_page_prods[curr], L1E_RX_PAGE_SZ)); 608 609 /* 610 * Clear the producer. 611 */ 612 dma_rx_cmb = l1e->atge_l1e_rx_cmb; 613 p = (void *)dma_rx_cmb->addr; 614 p = p + curr; 615 *p = 0; 616 DMA_SYNC(dma_rx_cmb, curr * L1E_RX_CMB_SZ, 617 L1E_RX_CMB_SZ, DDI_DMA_SYNC_FORDEV); 618 619 /* 620 * Notify the NIC that the current RX page is available again. 621 */ 622 OUTB(atgep, L1E_RXF0_PAGE0 + curr, RXF_VALID); 623 624 /* 625 * End of Rx page reached, let hardware reuse this page. 626 */ 627 l1e->atge_l1e_rx_page_cons = 0; 628 l1e->atge_l1e_rx_page_prods[curr] = 0; 629 630 /* 631 * Switch to alternate Rx page. 632 */ 633 curr ^= 1; 634 l1e->atge_l1e_rx_curp = curr; 635 636 /* 637 * Page flipped, sync CMB and then Rx page. 638 */ 639 DMA_SYNC(dma_rx_cmb, 0, L1E_RX_PAGES * L1E_RX_CMB_SZ, 640 DDI_DMA_SYNC_FORKERNEL); 641 p = (void *)dma_rx_cmb->addr; 642 l1e->atge_l1e_rx_page_prods[curr] = 643 ATGE_GET32(dma_rx_cmb, p + curr); 644 645 dma_rx_page = l1e->atge_l1e_rx_page[curr]; 646 DMA_SYNC(dma_rx_page, 0, l1e->atge_l1e_rx_page_prods[curr], 647 DDI_DMA_SYNC_FORKERNEL); 648 649 ATGE_DB(("%s: %s() PAGE FLIPPED -> %d, producer[0,1]: %d, %d", 650 atgep->atge_name, __func__, curr, 651 ATGE_GET32(dma_rx_cmb, p), ATGE_GET32(dma_rx_cmb, p + 1))); 652 } 653 } 654 655 void 656 atge_l1e_send_packet(atge_ring_t *r) 657 { 658 /* 659 * Ask chip to send the packet now. 660 */ 661 OUTL(r->r_atge, ATGE_MBOX, r->r_producer); 662 } 663 664 void 665 atge_l1e_clear_stats(atge_t *atgep) 666 { 667 atge_l1e_smb_t smb; 668 uint32_t *reg; 669 int i; 670 671 /* 672 * Clear RX stats first. 673 */ 674 i = 0; 675 reg = &smb.rx_frames; 676 while (reg++ <= &smb.rx_pkts_filtered) { 677 (void) INL(atgep, L1E_RX_MIB_BASE + i); 678 i += sizeof (uint32_t); 679 } 680 681 /* 682 * Clear TX stats. 683 */ 684 i = 0; 685 reg = &smb.tx_frames; 686 while (reg++ <= &smb.tx_mcast_bytes) { 687 (void) INL(atgep, L1E_TX_MIB_BASE + i); 688 i += sizeof (uint32_t); 689 } 690 } 691 692 void 693 atge_l1e_gather_stats(atge_t *atgep) 694 { 695 atge_l1e_smb_t *stat; 696 atge_l1e_smb_t *smb; 697 atge_l1e_smb_t local_smb; 698 uint32_t *reg; 699 int i; 700 701 ASSERT(atgep != NULL); 702 703 stat = (atge_l1e_smb_t *)atgep->atge_hw_stats; 704 705 bzero(&local_smb, sizeof (atge_l1e_smb_t)); 706 smb = &local_smb; 707 708 /* Read Rx statistics. */ 709 i = 0; 710 reg = &smb->rx_frames; 711 while (reg++ <= &smb->rx_pkts_filtered) { 712 *reg = INL(atgep, L1E_RX_MIB_BASE + i); 713 i += sizeof (uint32_t); 714 } 715 716 /* Read Tx statistics. */ 717 i = 0; 718 reg = &smb->tx_frames; 719 while (reg++ <= &smb->tx_mcast_bytes) { 720 *reg = INL(atgep, L1E_TX_MIB_BASE + i); 721 i += sizeof (uint32_t); 722 } 723 724 /* 725 * SMB is cleared everytime we read; hence we always do '+='. 726 */ 727 728 /* Rx stats. */ 729 stat->rx_frames += smb->rx_frames; 730 stat->rx_bcast_frames += smb->rx_bcast_frames; 731 stat->rx_mcast_frames += smb->rx_mcast_frames; 732 stat->rx_pause_frames += smb->rx_pause_frames; 733 stat->rx_control_frames += smb->rx_control_frames; 734 stat->rx_crcerrs += smb->rx_crcerrs; 735 stat->rx_lenerrs += smb->rx_lenerrs; 736 stat->rx_bytes += smb->rx_bytes; 737 stat->rx_runts += smb->rx_runts; 738 stat->rx_fragments += smb->rx_fragments; 739 stat->rx_pkts_64 += smb->rx_pkts_64; 740 stat->rx_pkts_65_127 += smb->rx_pkts_65_127; 741 stat->rx_pkts_128_255 += smb->rx_pkts_128_255; 742 stat->rx_pkts_256_511 += smb->rx_pkts_256_511; 743 stat->rx_pkts_512_1023 += smb->rx_pkts_512_1023; 744 stat->rx_pkts_1024_1518 += smb->rx_pkts_1024_1518; 745 stat->rx_pkts_1519_max += smb->rx_pkts_1519_max; 746 stat->rx_pkts_truncated += smb->rx_pkts_truncated; 747 stat->rx_fifo_oflows += smb->rx_fifo_oflows; 748 stat->rx_rrs_errs += smb->rx_rrs_errs; 749 stat->rx_alignerrs += smb->rx_alignerrs; 750 stat->rx_bcast_bytes += smb->rx_bcast_bytes; 751 stat->rx_mcast_bytes += smb->rx_mcast_bytes; 752 stat->rx_pkts_filtered += smb->rx_pkts_filtered; 753 754 /* Tx stats. */ 755 stat->tx_frames += smb->tx_frames; 756 stat->tx_bcast_frames += smb->tx_bcast_frames; 757 stat->tx_mcast_frames += smb->tx_mcast_frames; 758 stat->tx_pause_frames += smb->tx_pause_frames; 759 stat->tx_excess_defer += smb->tx_excess_defer; 760 stat->tx_control_frames += smb->tx_control_frames; 761 stat->tx_deferred += smb->tx_deferred; 762 stat->tx_bytes += smb->tx_bytes; 763 stat->tx_pkts_64 += smb->tx_pkts_64; 764 stat->tx_pkts_65_127 += smb->tx_pkts_65_127; 765 stat->tx_pkts_128_255 += smb->tx_pkts_128_255; 766 stat->tx_pkts_256_511 += smb->tx_pkts_256_511; 767 stat->tx_pkts_512_1023 += smb->tx_pkts_512_1023; 768 stat->tx_pkts_1024_1518 += smb->tx_pkts_1024_1518; 769 stat->tx_pkts_1519_max += smb->tx_pkts_1519_max; 770 stat->tx_single_colls += smb->tx_single_colls; 771 stat->tx_multi_colls += smb->tx_multi_colls; 772 stat->tx_late_colls += smb->tx_late_colls; 773 stat->tx_excess_colls += smb->tx_excess_colls; 774 stat->tx_abort += smb->tx_abort; 775 stat->tx_underrun += smb->tx_underrun; 776 stat->tx_desc_underrun += smb->tx_desc_underrun; 777 stat->tx_lenerrs += smb->tx_lenerrs; 778 stat->tx_pkts_truncated += smb->tx_pkts_truncated; 779 stat->tx_bcast_bytes += smb->tx_bcast_bytes; 780 stat->tx_mcast_bytes += smb->tx_mcast_bytes; 781 782 /* 783 * Update global counters in atge_t. 784 */ 785 atgep->atge_brdcstrcv += smb->rx_bcast_frames; 786 atgep->atge_multircv += smb->rx_mcast_frames; 787 atgep->atge_multixmt += smb->tx_mcast_frames; 788 atgep->atge_brdcstxmt += smb->tx_bcast_frames; 789 790 atgep->atge_align_errors += smb->rx_alignerrs; 791 atgep->atge_fcs_errors += smb->rx_crcerrs; 792 atgep->atge_sqe_errors += smb->rx_rrs_errs; 793 atgep->atge_defer_xmts += smb->tx_deferred; 794 atgep->atge_first_collisions += smb->tx_single_colls; 795 atgep->atge_multi_collisions += smb->tx_multi_colls * 2; 796 atgep->atge_tx_late_collisions += smb->tx_late_colls; 797 atgep->atge_ex_collisions += smb->tx_excess_colls; 798 atgep->atge_macxmt_errors += smb->tx_abort; 799 atgep->atge_toolong_errors += smb->rx_lenerrs; 800 atgep->atge_overflow += smb->rx_fifo_oflows; 801 atgep->atge_underflow += (smb->tx_underrun + smb->tx_desc_underrun); 802 atgep->atge_runt += smb->rx_runts; 803 804 805 atgep->atge_collisions += smb->tx_single_colls + 806 smb->tx_multi_colls * 2 + smb->tx_late_colls + 807 smb->tx_abort * HDPX_CFG_RETRY_DEFAULT; 808 809 /* 810 * tx_pkts_truncated counter looks suspicious. It constantly 811 * increments with no sign of Tx errors. Hence we don't factor it. 812 */ 813 atgep->atge_macxmt_errors += smb->tx_abort + smb->tx_late_colls + 814 smb->tx_underrun; 815 816 atgep->atge_macrcv_errors += smb->rx_crcerrs + smb->rx_lenerrs + 817 smb->rx_runts + smb->rx_pkts_truncated + 818 smb->rx_fifo_oflows + smb->rx_rrs_errs + 819 smb->rx_alignerrs; 820 } 821 822 void 823 atge_l1e_stop_mac(atge_t *atgep) 824 { 825 uint32_t reg; 826 827 reg = INL(atgep, ATGE_MAC_CFG); 828 ATGE_DB(("%s: %s() reg : %x", atgep->atge_name, __func__, reg)); 829 830 if ((reg & (ATGE_CFG_TX_ENB | ATGE_CFG_RX_ENB)) != 0) { 831 reg &= ~ATGE_CFG_TX_ENB | ATGE_CFG_RX_ENB; 832 OUTL(atgep, ATGE_MAC_CFG, reg); 833 ATGE_DB(("%s: %s() mac stopped", atgep->atge_name, __func__)); 834 } 835 } 836 837 /* 838 * The interrupt handler for L1E/L2E 839 */ 840 /*ARGSUSED*/ 841 uint_t 842 atge_l1e_interrupt(caddr_t arg1, caddr_t arg2) 843 { 844 atge_t *atgep = (void *)arg1; 845 mblk_t *rx_head = NULL; 846 uint32_t status; 847 int resched = 0; 848 849 ASSERT(atgep != NULL); 850 851 mutex_enter(&atgep->atge_intr_lock); 852 853 if (atgep->atge_chip_state & ATGE_CHIP_SUSPENDED) { 854 mutex_exit(&atgep->atge_intr_lock); 855 return (DDI_INTR_UNCLAIMED); 856 } 857 858 status = INL(atgep, ATGE_INTR_STATUS); 859 if (status == 0 || (status & atgep->atge_intrs) == 0) { 860 mutex_exit(&atgep->atge_intr_lock); 861 862 if (atgep->atge_flags & ATGE_FIXED_TYPE) 863 return (DDI_INTR_UNCLAIMED); 864 865 return (DDI_INTR_CLAIMED); 866 } 867 868 ATGE_DB(("%s: %s() entry status : %x", 869 atgep->atge_name, __func__, status)); 870 871 872 /* 873 * Disable interrupts. 874 */ 875 OUTL(atgep, ATGE_INTR_STATUS, status | INTR_DIS_INT); 876 FLUSH(atgep, ATGE_INTR_STATUS); 877 878 /* 879 * Check if chip is running, only then do the work. 880 */ 881 if (atgep->atge_chip_state & ATGE_CHIP_RUNNING) { 882 if (status & INTR_SMB) { 883 atge_l1e_gather_stats(atgep); 884 } 885 886 /* 887 * Check for errors. 888 */ 889 if (status & L1E_INTR_ERRORS) { 890 atge_error(atgep->atge_dip, 891 "L1E chip found an error intr status : %x", 892 status); 893 894 if (status & 895 (INTR_DMA_RD_TO_RST | INTR_DMA_WR_TO_RST)) { 896 atge_error(atgep->atge_dip, "DMA transfer err"); 897 898 atge_device_stop(atgep); 899 goto done; 900 } 901 902 if (status & INTR_TX_FIFO_UNDERRUN) { 903 atge_error(atgep->atge_dip, "TX FIFO underrun"); 904 } 905 } 906 907 rx_head = atge_l1e_receive(atgep); 908 909 if (status & INTR_TX_PKT) { 910 int cons; 911 912 mutex_enter(&atgep->atge_tx_lock); 913 cons = INW(atgep, L1E_TPD_CONS_IDX); 914 atge_tx_reclaim(atgep, cons); 915 if (atgep->atge_tx_resched) { 916 atgep->atge_tx_resched = 0; 917 resched = 1; 918 } 919 920 mutex_exit(&atgep->atge_tx_lock); 921 } 922 } 923 924 /* 925 * Enable interrupts. 926 */ 927 OUTL(atgep, ATGE_INTR_STATUS, 0); 928 929 done: 930 931 mutex_exit(&atgep->atge_intr_lock); 932 933 if (status & INTR_GPHY) { 934 /* 935 * Ack interrupts from PHY 936 */ 937 (void) atge_mii_read(atgep, 938 atgep->atge_phyaddr, ATGE_ISR_ACK_GPHY); 939 940 mii_check(atgep->atge_mii); 941 } 942 943 /* 944 * Pass the list of packets received from chip to MAC layer. 945 */ 946 if (rx_head) { 947 mac_rx(atgep->atge_mh, 0, rx_head); 948 } 949 950 /* 951 * Let MAC start sending pkts if the downstream was asked to pause. 952 */ 953 if (resched) 954 mac_tx_update(atgep->atge_mh); 955 956 return (DDI_INTR_CLAIMED); 957 } 958