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