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