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 * Copyright (c) 2009, Pyun YongHyeon <yongari@FreeBSD.org> 30 * All rights reserved. 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 1. Redistributions of source code must retain the above copyright 36 * notice unmodified, this list of conditions, and the following 37 * disclaimer. 38 * 2. Redistributions in binary form must reproduce the above copyright 39 * notice, this list of conditions and the following disclaimer in the 40 * documentation and/or other materials provided with the distribution. 41 * 42 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 43 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 45 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 46 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 47 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 48 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 50 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 51 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52 * SUCH DAMAGE. 53 */ 54 55 #include <sys/types.h> 56 #include <sys/stream.h> 57 #include <sys/strsun.h> 58 #include <sys/stat.h> 59 #include <sys/modctl.h> 60 #include <sys/ethernet.h> 61 #include <sys/debug.h> 62 #include <sys/conf.h> 63 #include <sys/mii.h> 64 #include <sys/miiregs.h> 65 #include <sys/sysmacros.h> 66 #include <sys/dditypes.h> 67 #include <sys/ddi.h> 68 #include <sys/sunddi.h> 69 #include <sys/byteorder.h> 70 #include <sys/note.h> 71 #include <sys/vlan.h> 72 #include <sys/stream.h> 73 74 #include "atge.h" 75 #include "atge_l1c_reg.h" 76 #include "atge_cmn_reg.h" 77 78 static ddi_dma_attr_t atge_l1c_dma_attr_tx_desc = { 79 DMA_ATTR_V0, /* dma_attr_version */ 80 0, /* dma_attr_addr_lo */ 81 0x0000ffffffffull, /* dma_attr_addr_hi */ 82 0x0000ffffffffull, /* dma_attr_count_max */ 83 L1C_TX_RING_ALIGN, /* dma_attr_align */ 84 0x0000fffc, /* dma_attr_burstsizes */ 85 1, /* dma_attr_minxfer */ 86 0x0000ffffffffull, /* dma_attr_maxxfer */ 87 0x0000ffffffffull, /* dma_attr_seg */ 88 1, /* dma_attr_sgllen */ 89 1, /* dma_attr_granular */ 90 0 /* dma_attr_flags */ 91 }; 92 93 static ddi_dma_attr_t atge_l1c_dma_attr_rx_desc = { 94 DMA_ATTR_V0, /* dma_attr_version */ 95 0, /* dma_attr_addr_lo */ 96 0x0000ffffffffull, /* dma_attr_addr_hi */ 97 0x0000ffffffffull, /* dma_attr_count_max */ 98 L1C_RX_RING_ALIGN, /* dma_attr_align */ 99 0x0000fffc, /* dma_attr_burstsizes */ 100 1, /* dma_attr_minxfer */ 101 0x0000ffffffffull, /* dma_attr_maxxfer */ 102 0x0000ffffffffull, /* dma_attr_seg */ 103 1, /* dma_attr_sgllen */ 104 1, /* dma_attr_granular */ 105 0 /* dma_attr_flags */ 106 }; 107 108 static ddi_dma_attr_t atge_l1c_dma_attr_cmb = { 109 DMA_ATTR_V0, /* dma_attr_version */ 110 0, /* dma_attr_addr_lo */ 111 0x0000ffffffffull, /* dma_attr_addr_hi */ 112 0x0000ffffffffull, /* dma_attr_count_max */ 113 L1C_CMB_ALIGN, /* dma_attr_align */ 114 0x0000fffc, /* dma_attr_burstsizes */ 115 1, /* dma_attr_minxfer */ 116 0x0000ffffffffull, /* dma_attr_maxxfer */ 117 0x0000ffffffffull, /* dma_attr_seg */ 118 1, /* dma_attr_sgllen */ 119 1, /* dma_attr_granular */ 120 0 /* dma_attr_flags */ 121 }; 122 123 static ddi_dma_attr_t atge_l1c_dma_attr_smb = { 124 DMA_ATTR_V0, /* dma_attr_version */ 125 0, /* dma_attr_addr_lo */ 126 0x0000ffffffffull, /* dma_attr_addr_hi */ 127 0x0000ffffffffull, /* dma_attr_count_max */ 128 L1C_SMB_ALIGN, /* dma_attr_align */ 129 0x0000fffc, /* dma_attr_burstsizes */ 130 1, /* dma_attr_minxfer */ 131 0x0000ffffffffull, /* dma_attr_maxxfer */ 132 0x0000ffffffffull, /* dma_attr_seg */ 133 1, /* dma_attr_sgllen */ 134 1, /* dma_attr_granular */ 135 0 /* dma_attr_flags */ 136 }; 137 138 static ddi_dma_attr_t atge_l1c_dma_attr_rr = { 139 DMA_ATTR_V0, /* dma_attr_version */ 140 0, /* dma_attr_addr_lo */ 141 0x0000ffffffffull, /* dma_attr_addr_hi */ 142 0x0000ffffffffull, /* dma_attr_count_max */ 143 L1C_RR_RING_ALIGN, /* dma_attr_align */ 144 0x0000fffc, /* dma_attr_burstsizes */ 145 1, /* dma_attr_minxfer */ 146 0x0000ffffffffull, /* dma_attr_maxxfer */ 147 0x0000ffffffffull, /* dma_attr_seg */ 148 1, /* dma_attr_sgllen */ 149 1, /* dma_attr_granular */ 150 0 /* dma_attr_flags */ 151 }; 152 153 int 154 atge_l1c_alloc_dma(atge_t *atgep) 155 { 156 atge_l1c_data_t *l1c; 157 atge_dma_t *dma; 158 int err; 159 160 l1c = kmem_zalloc(sizeof (atge_l1c_data_t), KM_SLEEP); 161 atgep->atge_private_data = l1c; 162 163 /* 164 * Allocate TX ring descriptor. 165 */ 166 atgep->atge_tx_buf_len = atgep->atge_mtu + 167 sizeof (struct ether_header) + VLAN_TAGSZ + ETHERFCSL; 168 atgep->atge_tx_ring = kmem_alloc(sizeof (atge_ring_t), KM_SLEEP); 169 atgep->atge_tx_ring->r_atge = atgep; 170 atgep->atge_tx_ring->r_desc_ring = NULL; 171 dma = atge_alloc_a_dma_blk(atgep, &atge_l1c_dma_attr_tx_desc, 172 ATGE_TX_RING_SZ, DDI_DMA_RDWR); 173 if (dma == NULL) { 174 atge_error(atgep->atge_dip, "DMA allocation failed for TX" 175 " desc ring"); 176 return (DDI_FAILURE); 177 } 178 atgep->atge_tx_ring->r_desc_ring = dma; 179 180 /* 181 * Allocate DMA buffers for TX ring. 182 */ 183 err = atge_alloc_buffers(atgep->atge_tx_ring, ATGE_TX_RING_CNT, 184 atgep->atge_tx_buf_len, DDI_DMA_WRITE); 185 if (err != DDI_SUCCESS) { 186 atge_error(atgep->atge_dip, "DMA allocation failed for" 187 " TX Ring"); 188 return (err); 189 } 190 191 /* 192 * Allocate RX ring. 193 */ 194 atgep->atge_rx_buf_len = atgep->atge_mtu + 195 sizeof (struct ether_header) + VLAN_TAGSZ + ETHERFCSL; 196 l1c->atge_rx_ring = kmem_alloc(sizeof (atge_ring_t), KM_SLEEP); 197 l1c->atge_rx_ring->r_atge = atgep; 198 l1c->atge_rx_ring->r_desc_ring = NULL; 199 dma = atge_alloc_a_dma_blk(atgep, &atge_l1c_dma_attr_rx_desc, 200 L1C_RX_RING_SZ, DDI_DMA_RDWR); 201 if (dma == NULL) { 202 atge_error(atgep->atge_dip, "DMA allocation failed" 203 " for RX Ring"); 204 return (DDI_FAILURE); 205 } 206 l1c->atge_rx_ring->r_desc_ring = dma; 207 208 /* 209 * Allocate DMA buffers for RX ring. 210 */ 211 err = atge_alloc_buffers(l1c->atge_rx_ring, L1C_RX_RING_CNT, 212 atgep->atge_rx_buf_len, DDI_DMA_READ); 213 if (err != DDI_SUCCESS) { 214 atge_error(atgep->atge_dip, "DMA allocation failed for" 215 " RX buffers"); 216 return (err); 217 } 218 219 /* 220 * Allocate CMB used for fetching interrupt status data. 221 */ 222 ATGE_DB(("%s: %s() L1C_CMB_BLOCK_SZ : 0x%x", atgep->atge_name, 223 __func__, L1C_CMB_BLOCK_SZ)); 224 225 dma = atge_alloc_a_dma_blk(atgep, &atge_l1c_dma_attr_cmb, 226 L1C_CMB_BLOCK_SZ, DDI_DMA_RDWR); 227 l1c->atge_l1c_cmb = dma; 228 if (dma == NULL) { 229 atge_error(atgep->atge_dip, "DMA allocation failed for CMB"); 230 return (DDI_FAILURE); 231 } 232 233 /* 234 * RR ring (Return Ring for RX and TX). 235 */ 236 ATGE_DB(("%s: %s() L1C_RR_RING_SZ : 0x%x", atgep->atge_name, 237 __func__, L1C_RR_RING_SZ)); 238 239 dma = atge_alloc_a_dma_blk(atgep, &atge_l1c_dma_attr_rr, 240 L1C_RR_RING_SZ, DDI_DMA_RDWR); 241 l1c->atge_l1c_rr = dma; 242 if (dma == NULL) { 243 atge_error(atgep->atge_dip, "DMA allocation failed" 244 " for RX RR ring"); 245 return (DDI_FAILURE); 246 } 247 248 /* 249 * SMB for statistics. 250 */ 251 ATGE_DB(("%s: %s() L1C_SMB_BLOCK_SZ : 0x%x", atgep->atge_name, 252 __func__, L1C_SMB_BLOCK_SZ)); 253 254 dma = atge_alloc_a_dma_blk(atgep, &atge_l1c_dma_attr_smb, 255 L1C_SMB_BLOCK_SZ, DDI_DMA_RDWR); 256 l1c->atge_l1c_smb = dma; 257 if (dma == NULL) { 258 atge_error(atgep->atge_dip, "DMA allocation failed for SMB"); 259 return (DDI_FAILURE); 260 } 261 262 atgep->atge_hw_stats = kmem_zalloc(sizeof (atge_l1c_smb_t), KM_SLEEP); 263 264 return (DDI_SUCCESS); 265 } 266 267 void 268 atge_l1c_free_dma(atge_t *atgep) 269 { 270 atge_l1c_data_t *l1c; 271 272 l1c = atgep->atge_private_data; 273 274 /* 275 * Free TX ring. 276 */ 277 if (atgep->atge_tx_ring != NULL) { 278 atge_free_buffers(atgep->atge_tx_ring, ATGE_TX_RING_CNT); 279 280 if (atgep->atge_tx_ring->r_desc_ring != NULL) { 281 atge_free_a_dma_blk(atgep->atge_tx_ring->r_desc_ring); 282 } 283 284 kmem_free(atgep->atge_tx_ring, sizeof (atge_ring_t)); 285 atgep->atge_tx_ring = NULL; 286 } 287 288 if (l1c && l1c->atge_l1c_cmb != NULL) { 289 atge_free_a_dma_blk(l1c->atge_l1c_cmb); 290 l1c->atge_l1c_cmb = NULL; 291 } 292 293 if (l1c && l1c->atge_l1c_rr != NULL) { 294 atge_free_a_dma_blk(l1c->atge_l1c_rr); 295 l1c->atge_l1c_rr = NULL; 296 } 297 298 if (l1c && l1c->atge_l1c_smb != NULL) { 299 atge_free_a_dma_blk(l1c->atge_l1c_smb); 300 l1c->atge_l1c_smb = NULL; 301 } 302 303 /* 304 * Free RX ring. 305 */ 306 if (l1c && l1c->atge_rx_ring != NULL) { 307 atge_free_buffers(l1c->atge_rx_ring, L1C_RX_RING_CNT); 308 309 if (l1c->atge_rx_ring->r_desc_ring != NULL) { 310 atge_free_a_dma_blk(l1c->atge_rx_ring->r_desc_ring); 311 } 312 313 kmem_free(l1c->atge_rx_ring, sizeof (atge_ring_t)); 314 l1c->atge_rx_ring = NULL; 315 } 316 317 /* 318 * Free the memory allocated for gathering hw stats. 319 */ 320 if (atgep->atge_hw_stats != NULL) { 321 kmem_free(atgep->atge_hw_stats, sizeof (atge_l1c_smb_t)); 322 atgep->atge_hw_stats = NULL; 323 } 324 325 /* 326 * Free the private area. 327 */ 328 if (l1c != NULL) { 329 kmem_free(l1c, sizeof (atge_l1c_data_t)); 330 atgep->atge_private_data = NULL; 331 } 332 } 333 334 void 335 atge_l1c_init_rx_ring(atge_t *atgep) 336 { 337 atge_l1c_data_t *l1c; 338 atge_dma_t *dma; 339 l1c_rx_desc_t *rx; 340 int i; 341 342 l1c = atgep->atge_private_data; 343 l1c->atge_rx_ring->r_consumer = L1C_RX_RING_CNT - 1; 344 dma = l1c->atge_rx_ring->r_desc_ring; 345 bzero(dma->addr, L1C_RX_RING_SZ); 346 347 for (i = 0; i < L1C_RX_RING_CNT; i++) { 348 rx = (l1c_rx_desc_t *)(dma->addr + 349 (i * sizeof (l1c_rx_desc_t))); 350 351 ATGE_PUT64(dma, &rx->addr, 352 l1c->atge_rx_ring->r_buf_tbl[i]->cookie.dmac_laddress); 353 /* No length field. */ 354 } 355 356 DMA_SYNC(dma, 0, 0, DDI_DMA_SYNC_FORDEV); 357 /* Let controller know availability of new Rx buffers. */ 358 OUTL(atgep, ATGE_MBOX_RD0_PROD_IDX, l1c->atge_rx_ring->r_consumer); 359 } 360 361 void 362 atge_l1c_init_tx_ring(atge_t *atgep) 363 { 364 atgep->atge_tx_ring->r_producer = 0; 365 atgep->atge_tx_ring->r_consumer = 0; 366 atgep->atge_tx_ring->r_avail_desc = ATGE_TX_RING_CNT; 367 368 bzero(atgep->atge_tx_ring->r_desc_ring->addr, ATGE_TX_RING_SZ); 369 DMA_SYNC(atgep->atge_tx_ring->r_desc_ring, 0, 0, DDI_DMA_SYNC_FORDEV); 370 } 371 372 void 373 atge_l1c_init_rr_ring(atge_t *atgep) 374 { 375 atge_l1c_data_t *l1c; 376 atge_dma_t *dma; 377 378 l1c = atgep->atge_private_data; 379 l1c->atge_l1c_rr_consumers = 0; 380 381 dma = l1c->atge_l1c_rr; 382 bzero(dma->addr, L1C_RR_RING_SZ); 383 DMA_SYNC(dma, 0, 0, DDI_DMA_SYNC_FORDEV); 384 } 385 386 void 387 atge_l1c_init_smb(atge_t *atgep) 388 { 389 atge_l1c_data_t *l1c; 390 atge_dma_t *dma; 391 392 l1c = atgep->atge_private_data; 393 dma = l1c->atge_l1c_smb; 394 bzero(dma->addr, L1C_SMB_BLOCK_SZ); 395 DMA_SYNC(dma, 0, 0, DDI_DMA_SYNC_FORDEV); 396 } 397 398 void 399 atge_l1c_init_cmb(atge_t *atgep) 400 { 401 atge_l1c_data_t *l1c; 402 atge_dma_t *dma; 403 404 l1c = atgep->atge_private_data; 405 dma = l1c->atge_l1c_cmb; 406 bzero(dma->addr, L1C_CMB_BLOCK_SZ); 407 DMA_SYNC(dma, 0, 0, DDI_DMA_SYNC_FORDEV); 408 } 409 410 void 411 atge_l1c_program_dma(atge_t *atgep) 412 { 413 atge_l1c_data_t *l1c; 414 atge_ring_t *r; 415 uint32_t reg; 416 417 l1c = atgep->atge_private_data; 418 419 /* 420 * Clear WOL status and disable all WOL feature as WOL 421 * would interfere Rx operation under normal environments. 422 */ 423 (void) INL(atgep, ATGE_WOL_CFG); 424 OUTL(atgep, ATGE_WOL_CFG, 0); 425 426 /* TX */ 427 r = atgep->atge_tx_ring; 428 OUTL(atgep, L1C_TX_BASE_ADDR_HI, 429 ATGE_ADDR_HI(r->r_desc_ring->cookie.dmac_laddress)); 430 OUTL(atgep, L1C_TDL_HEAD_ADDR_LO, 431 ATGE_ADDR_LO(r->r_desc_ring->cookie.dmac_laddress)); 432 /* We don't use high priority ring. */ 433 OUTL(atgep, L1C_TDH_HEAD_ADDR_LO, 0); 434 435 /* RX */ 436 r = l1c->atge_rx_ring; 437 OUTL(atgep, L1C_RX_BASE_ADDR_HI, 438 ATGE_ADDR_HI(r->r_desc_ring->cookie.dmac_laddress)); 439 OUTL(atgep, L1C_RD0_HEAD_ADDR_LO, 440 ATGE_ADDR_LO(r->r_desc_ring->cookie.dmac_laddress)); 441 /* We use one Rx ring. */ 442 OUTL(atgep, L1C_RD1_HEAD_ADDR_LO, 0); 443 OUTL(atgep, L1C_RD2_HEAD_ADDR_LO, 0); 444 OUTL(atgep, L1C_RD3_HEAD_ADDR_LO, 0); 445 446 /* RR Ring */ 447 /* 448 * Let hardware split jumbo frames into alc_max_buf_sized chunks. 449 * if it do not fit the buffer size. Rx return descriptor holds 450 * a counter that indicates how many fragments were made by the 451 * hardware. The buffer size should be multiple of 8 bytes. 452 * Since hardware has limit on the size of buffer size, always 453 * use the maximum value. 454 * For strict-alignment architectures make sure to reduce buffer 455 * size by 8 bytes to make room for alignment fixup. 456 */ 457 OUTL(atgep, L1C_RX_BUF_SIZE, RX_BUF_SIZE_MAX); /* XXX */ 458 459 /* Set Rx return descriptor base addresses. */ 460 OUTL(atgep, L1C_RRD0_HEAD_ADDR_LO, 461 ATGE_ADDR_LO(l1c->atge_l1c_rr->cookie.dmac_laddress)); 462 /* We use one Rx return ring. */ 463 OUTL(atgep, L1C_RRD1_HEAD_ADDR_LO, 0); 464 OUTL(atgep, L1C_RRD2_HEAD_ADDR_LO, 0); 465 OUTL(atgep, L1C_RRD3_HEAD_ADDR_LO, 0); 466 467 /* CMB */ 468 OUTL(atgep, L1C_CMB_BASE_ADDR_LO, 469 ATGE_ADDR_LO(l1c->atge_l1c_cmb->cookie.dmac_laddress)); 470 471 /* SMB */ 472 OUTL(atgep, L1C_SMB_BASE_ADDR_HI, 473 ATGE_ADDR_HI(l1c->atge_l1c_smb->cookie.dmac_laddress)); 474 OUTL(atgep, L1C_SMB_BASE_ADDR_LO, 475 ATGE_ADDR_LO(l1c->atge_l1c_smb->cookie.dmac_laddress)); 476 477 /* 478 * Set RX return ring (RR) counter. 479 */ 480 /* Set Rx descriptor counter. */ 481 OUTL(atgep, L1C_RD_RING_CNT, 482 (L1C_RX_RING_CNT << RD_RING_CNT_SHIFT) & RD_RING_CNT_MASK); 483 /* Set Rx return descriptor counter. */ 484 OUTL(atgep, L1C_RRD_RING_CNT, 485 (L1C_RR_RING_CNT << RRD_RING_CNT_SHIFT) & RRD_RING_CNT_MASK); 486 487 /* 488 * Set TX descriptor counter. 489 */ 490 OUTL(atgep, L1C_TD_RING_CNT, 491 (ATGE_TX_RING_CNT << TD_RING_CNT_SHIFT) & TD_RING_CNT_MASK); 492 493 switch (ATGE_DID(atgep)) { 494 case ATGE_CHIP_AR8152V1_DEV_ID: 495 /* Reconfigure SRAM - Vendor magic. */ 496 OUTL(atgep, L1C_SRAM_RX_FIFO_LEN, 0x000002A0); 497 OUTL(atgep, L1C_SRAM_TX_FIFO_LEN, 0x00000100); 498 OUTL(atgep, L1C_SRAM_RX_FIFO_ADDR, 0x029F0000); 499 OUTL(atgep, L1C_SRAM_RD_ADDR, 0x02BF02A0); 500 OUTL(atgep, L1C_SRAM_TX_FIFO_ADDR, 0x03BF02C0); 501 OUTL(atgep, L1C_SRAM_TRD_ADDR, 0x03DF03C0); 502 OUTL(atgep, L1C_TXF_WATER_MARK, 0x00000000); 503 OUTL(atgep, L1C_RD_DMA_CFG, 0x00000000); 504 break; 505 } 506 507 /* 508 * Inform hardware that we have loaded DMA registers. 509 */ 510 OUTL(atgep, ATGE_DMA_BLOCK, DMA_BLOCK_LOAD); 511 512 /* Configure interrupt moderation timer. */ 513 reg = ATGE_USECS(atgep->atge_int_rx_mod) << IM_TIMER_RX_SHIFT; 514 reg |= ATGE_USECS(atgep->atge_int_tx_mod) << IM_TIMER_TX_SHIFT; 515 OUTL(atgep, ATGE_IM_TIMER, reg); 516 /* 517 * We don't want to automatic interrupt clear as task queue 518 * for the interrupt should know interrupt status. 519 */ 520 reg = 0; 521 if (ATGE_USECS(atgep->atge_int_rx_mod) != 0) 522 reg |= MASTER_IM_RX_TIMER_ENB; 523 if (ATGE_USECS(atgep->atge_int_tx_mod) != 0) 524 reg |= MASTER_IM_TX_TIMER_ENB; 525 OUTL(atgep, ATGE_MASTER_CFG, reg); 526 } 527 528 void 529 atge_l1c_clear_stats(atge_t *atgep) 530 { 531 atge_l1c_smb_t smb; 532 uint32_t *reg; 533 int i; 534 535 /* 536 * Clear RX stats first. 537 */ 538 i = 0; 539 reg = &smb.rx_frames; 540 while (reg++ <= &smb.rx_pkts_filtered) { 541 (void) INL(atgep, ATGE_RX_MIB_BASE + i); 542 i += sizeof (uint32_t); 543 } 544 545 /* 546 * Clear TX stats. 547 */ 548 i = 0; 549 reg = &smb.tx_frames; 550 while (reg++ <= &smb.tx_mcast_bytes) { 551 (void) INL(atgep, ATGE_TX_MIB_BASE + i); 552 i += sizeof (uint32_t); 553 } 554 } 555 556 void 557 atge_l1c_gather_stats(atge_t *atgep) 558 { 559 atge_l1c_data_t *l1c; 560 atge_dma_t *dma; 561 atge_l1c_smb_t *stat; 562 atge_l1c_smb_t *smb; 563 564 ASSERT(atgep != NULL); 565 566 l1c = atgep->atge_private_data; 567 dma = l1c->atge_l1c_smb; 568 DMA_SYNC(dma, 0, 0, DDI_DMA_SYNC_FORKERNEL); 569 stat = (atge_l1c_smb_t *)atgep->atge_hw_stats; 570 smb = (atge_l1c_smb_t *)dma->addr; 571 572 /* Rx stats. */ 573 stat->rx_frames += smb->rx_frames; 574 stat->rx_bcast_frames += smb->rx_bcast_frames; 575 stat->rx_mcast_frames += smb->rx_mcast_frames; 576 stat->rx_pause_frames += smb->rx_pause_frames; 577 stat->rx_control_frames += smb->rx_control_frames; 578 stat->rx_crcerrs += smb->rx_crcerrs; 579 stat->rx_lenerrs += smb->rx_lenerrs; 580 stat->rx_bytes += smb->rx_bytes; 581 stat->rx_runts += smb->rx_runts; 582 stat->rx_fragments += smb->rx_fragments; 583 stat->rx_pkts_64 += smb->rx_pkts_64; 584 stat->rx_pkts_65_127 += smb->rx_pkts_65_127; 585 stat->rx_pkts_128_255 += smb->rx_pkts_128_255; 586 stat->rx_pkts_256_511 += smb->rx_pkts_256_511; 587 stat->rx_pkts_512_1023 += smb->rx_pkts_512_1023; 588 stat->rx_pkts_1024_1518 += smb->rx_pkts_1024_1518; 589 stat->rx_pkts_1519_max += smb->rx_pkts_1519_max; 590 stat->rx_pkts_truncated += smb->rx_pkts_truncated; 591 stat->rx_fifo_oflows += smb->rx_fifo_oflows; 592 stat->rx_alignerrs += smb->rx_alignerrs; 593 stat->rx_bcast_bytes += smb->rx_bcast_bytes; 594 stat->rx_mcast_bytes += smb->rx_mcast_bytes; 595 stat->rx_pkts_filtered += smb->rx_pkts_filtered; 596 597 /* Tx stats. */ 598 stat->tx_frames += smb->tx_frames; 599 stat->tx_bcast_frames += smb->tx_bcast_frames; 600 stat->tx_mcast_frames += smb->tx_mcast_frames; 601 stat->tx_pause_frames += smb->tx_pause_frames; 602 stat->tx_excess_defer += smb->tx_excess_defer; 603 stat->tx_control_frames += smb->tx_control_frames; 604 stat->tx_deferred += smb->tx_deferred; 605 stat->tx_bytes += smb->tx_bytes; 606 stat->tx_pkts_64 += smb->tx_pkts_64; 607 stat->tx_pkts_65_127 += smb->tx_pkts_65_127; 608 stat->tx_pkts_128_255 += smb->tx_pkts_128_255; 609 stat->tx_pkts_256_511 += smb->tx_pkts_256_511; 610 stat->tx_pkts_512_1023 += smb->tx_pkts_512_1023; 611 stat->tx_pkts_1024_1518 += smb->tx_pkts_1024_1518; 612 stat->tx_pkts_1519_max += smb->tx_pkts_1519_max; 613 stat->tx_single_colls += smb->tx_single_colls; 614 stat->tx_multi_colls += smb->tx_multi_colls; 615 stat->tx_late_colls += smb->tx_late_colls; 616 stat->tx_excess_colls += smb->tx_excess_colls; 617 stat->tx_underrun += smb->tx_underrun; 618 stat->tx_desc_underrun += smb->tx_desc_underrun; 619 stat->tx_lenerrs += smb->tx_lenerrs; 620 stat->tx_pkts_truncated += smb->tx_pkts_truncated; 621 stat->tx_bcast_bytes += smb->tx_bcast_bytes; 622 stat->tx_mcast_bytes += smb->tx_mcast_bytes; 623 624 /* 625 * Update global counters in atge_t. 626 */ 627 atgep->atge_brdcstrcv += smb->rx_bcast_frames; 628 atgep->atge_multircv += smb->rx_mcast_frames; 629 atgep->atge_multixmt += smb->tx_mcast_frames; 630 atgep->atge_brdcstxmt += smb->tx_bcast_frames; 631 632 atgep->atge_align_errors += smb->rx_alignerrs; 633 atgep->atge_fcs_errors += smb->rx_crcerrs; 634 atgep->atge_defer_xmts += smb->tx_deferred; 635 atgep->atge_first_collisions += smb->tx_single_colls; 636 atgep->atge_multi_collisions += smb->tx_multi_colls * 2; 637 atgep->atge_tx_late_collisions += smb->tx_late_colls; 638 atgep->atge_ex_collisions += smb->tx_excess_colls; 639 atgep->atge_toolong_errors += smb->rx_lenerrs; 640 atgep->atge_overflow += smb->rx_fifo_oflows; 641 atgep->atge_underflow += (smb->tx_underrun + smb->tx_desc_underrun); 642 atgep->atge_runt += smb->rx_runts; 643 644 645 atgep->atge_collisions += smb->tx_single_colls + 646 smb->tx_multi_colls * 2 + smb->tx_late_colls; 647 648 /* 649 * tx_pkts_truncated counter looks suspicious. It constantly 650 * increments with no sign of Tx errors. Hence we don't factor it. 651 */ 652 atgep->atge_macxmt_errors += smb->tx_late_colls + smb->tx_underrun; 653 654 atgep->atge_macrcv_errors += smb->rx_crcerrs + smb->rx_lenerrs + 655 smb->rx_runts + smb->rx_pkts_truncated + 656 smb->rx_alignerrs; 657 658 smb->updated = 0; 659 DMA_SYNC(dma, 0, 0, DDI_DMA_SYNC_FORDEV); 660 } 661 662 void 663 atge_l1c_stop_tx_mac(atge_t *atgep) 664 { 665 uint32_t reg; 666 int t; 667 668 ATGE_DB(("%s: %s() called", atgep->atge_name, __func__)); 669 670 reg = INL(atgep, ATGE_MAC_CFG); 671 if ((reg & ATGE_CFG_TX_ENB) != 0) { 672 reg &= ~ATGE_CFG_TX_ENB; 673 OUTL(atgep, ATGE_MAC_CFG, reg); 674 } 675 676 /* Stop TX DMA engine. */ 677 reg = INL(atgep, ATGE_DMA_CFG); 678 if ((reg & DMA_CFG_RD_ENB) != 0) { 679 reg &= ~DMA_CFG_RD_ENB; 680 OUTL(atgep, ATGE_DMA_CFG, reg); 681 } 682 683 for (t = ATGE_RESET_TIMEOUT; t > 0; t--) { 684 if ((INL(atgep, ATGE_IDLE_STATUS) & 685 (IDLE_STATUS_TXMAC | IDLE_STATUS_DMARD)) == 0) 686 break; 687 688 drv_usecwait(10); 689 } 690 691 if (t == 0) { 692 /* This should be an FMA event. */ 693 atge_error(atgep->atge_dip, "stopping TX DMA Engine timeout"); 694 } 695 } 696 697 void 698 atge_l1c_stop_rx_mac(atge_t *atgep) 699 { 700 uint32_t reg; 701 int t; 702 703 ATGE_DB(("%s: %s() called", atgep->atge_name, __func__)); 704 705 reg = INL(atgep, ATGE_MAC_CFG); 706 if ((reg & ATGE_CFG_RX_ENB) != 0) { 707 reg &= ~ATGE_CFG_RX_ENB; 708 OUTL(atgep, ATGE_MAC_CFG, reg); 709 } 710 711 /* Stop RX DMA engine. */ 712 reg = INL(atgep, ATGE_DMA_CFG); 713 if ((reg & DMA_CFG_WR_ENB) != 0) { 714 reg &= ~DMA_CFG_WR_ENB; 715 OUTL(atgep, ATGE_DMA_CFG, reg); 716 } 717 718 for (t = ATGE_RESET_TIMEOUT; t > 0; t--) { 719 if ((INL(atgep, ATGE_IDLE_STATUS) & 720 (IDLE_STATUS_RXMAC | IDLE_STATUS_DMAWR)) == 0) 721 break; 722 drv_usecwait(10); 723 } 724 725 if (t == 0) { 726 /* This should be an FMA event. */ 727 atge_error(atgep->atge_dip, " stopping RX DMA Engine timeout"); 728 } 729 } 730 731 /* 732 * Receives (consumes) packets. 733 */ 734 static mblk_t * 735 atge_l1c_rx(atge_t *atgep) 736 { 737 atge_l1c_data_t *l1c; 738 mblk_t *mp = NULL, *rx_head = NULL, *rx_tail = NULL; 739 l1c_rx_rdesc_t *rx_rr; 740 uint32_t rdinfo, status, totlen, pktlen, slotlen; 741 int nsegs, rx_cons = 0, cnt; 742 atge_dma_t *buf; 743 uchar_t *bufp; 744 int sync = 0; 745 746 l1c = atgep->atge_private_data; 747 ASSERT(l1c != NULL); 748 749 DMA_SYNC(l1c->atge_l1c_rr, 0, 0, DDI_DMA_SYNC_FORKERNEL); 750 for (;;) { 751 rx_rr = (l1c_rx_rdesc_t *)(l1c->atge_l1c_rr->addr + 752 (l1c->atge_l1c_rr_consumers * sizeof (l1c_rx_rdesc_t))); 753 754 rdinfo = ATGE_GET32(l1c->atge_l1c_rr, &rx_rr->rdinfo); 755 status = ATGE_GET32(l1c->atge_l1c_rr, &rx_rr->status); 756 757 rx_cons = L1C_RRD_RD_IDX(rdinfo); 758 nsegs = L1C_RRD_RD_CNT(rdinfo); 759 totlen = L1C_RRD_BYTES(status); 760 761 ATGE_DB(("%s: %s() PKT -- rdinfo : 0x%x," 762 "status : 0x%x, totlen : %d," 763 " rx_cons : %d, nsegs : %d", atgep->atge_name, __func__, 764 rdinfo, status, totlen, rx_cons, nsegs)); 765 766 if ((status & L1C_RRD_VALID) == 0) { 767 break; 768 } 769 770 if ((status & (L1C_RRD_ERR_CRC | L1C_RRD_ERR_ALIGN | 771 L1C_RRD_ERR_TRUNC | L1C_RRD_ERR_RUNT | 772 L1C_RRD_ERR_ICMP | L1C_RRD_ERR_LENGTH)) != 0) { 773 atge_error(atgep->atge_dip, "errored pkt"); 774 775 l1c->atge_rx_ring->r_consumer += nsegs; 776 l1c->atge_rx_ring->r_consumer %= L1C_RX_RING_CNT; 777 break; 778 } 779 780 ASSERT(rx_cons >= 0 && rx_cons <= L1C_RX_RING_CNT); 781 782 mp = allocb(totlen + L1C_HEADROOM, BPRI_MED); 783 if (mp != NULL) { 784 mp->b_rptr += L1C_HEADROOM; 785 bufp = mp->b_rptr; 786 mp->b_wptr = bufp + totlen; 787 mp->b_next = NULL; 788 789 atgep->atge_ipackets++; 790 atgep->atge_rbytes += totlen; 791 792 /* 793 * If there are more than one segments, then the first 794 * segment should be of size MTU. We couldn't verify 795 * this as our driver does not support changing MTU 796 * or Jumbo Frames. 797 */ 798 if (nsegs > 1) { 799 slotlen = atgep->atge_mtu; 800 } else { 801 slotlen = totlen; 802 } 803 } else { 804 ATGE_DB(("%s: %s() PKT mp == NULL totlen : %d", 805 atgep->atge_name, __func__, totlen)); 806 807 if (slotlen > atgep->atge_rx_buf_len) { 808 atgep->atge_toolong_errors++; 809 } else if (mp == NULL) { 810 atgep->atge_norcvbuf++; 811 } 812 813 rx_rr->status = 0; 814 break; 815 } 816 817 for (cnt = 0, pktlen = 0; cnt < nsegs; cnt++) { 818 buf = l1c->atge_rx_ring->r_buf_tbl[rx_cons]; 819 820 slotlen = min(atgep->atge_max_frame_size, totlen); 821 822 bcopy(buf->addr, (bufp + pktlen), slotlen); 823 pktlen += slotlen; 824 totlen -= slotlen; 825 826 ATGE_DB(("%s: %s() len : %d, rxcons : %d, pktlen : %d", 827 atgep->atge_name, __func__, slotlen, rx_cons, 828 pktlen)); 829 830 ATGE_INC_SLOT(rx_cons, L1C_RX_RING_CNT); 831 } 832 833 if (rx_tail == NULL) { 834 rx_head = rx_tail = mp; 835 } else { 836 rx_tail->b_next = mp; 837 rx_tail = mp; 838 } 839 840 if (cnt != nsegs) { 841 l1c->atge_rx_ring->r_consumer += nsegs; 842 l1c->atge_rx_ring->r_consumer %= L1C_RX_RING_CNT; 843 } else { 844 l1c->atge_rx_ring->r_consumer = rx_cons; 845 } 846 847 /* 848 * Tell the chip that this RR can be reused. 849 */ 850 rx_rr->status = 0; 851 852 ATGE_INC_SLOT(l1c->atge_l1c_rr_consumers, L1C_RR_RING_CNT); 853 sync++; 854 } 855 856 if (sync) { 857 DMA_SYNC(l1c->atge_rx_ring->r_desc_ring, 0, 0, 858 DDI_DMA_SYNC_FORDEV); 859 860 DMA_SYNC(l1c->atge_l1c_rr, 0, 0, DDI_DMA_SYNC_FORDEV); 861 /* 862 * Let controller know availability of new Rx buffers. 863 */ 864 OUTL(atgep, ATGE_MBOX_RD0_PROD_IDX, 865 l1c->atge_rx_ring->r_consumer); 866 867 ATGE_DB(("%s: %s() PKT Recved -> r_consumer : %d, rx_cons : %d" 868 " atge_l1c_rr_consumers : %d", 869 atgep->atge_name, __func__, l1c->atge_rx_ring->r_consumer, 870 rx_cons, l1c->atge_l1c_rr_consumers)); 871 } 872 873 874 return (rx_head); 875 } 876 877 /* 878 * The interrupt handler for L1C chip. 879 */ 880 /*ARGSUSED*/ 881 uint_t 882 atge_l1c_interrupt(caddr_t arg1, caddr_t arg2) 883 { 884 atge_t *atgep = (void *)arg1; 885 mblk_t *rx_head = NULL; 886 uint32_t status; 887 int resched = 0; 888 889 ASSERT(atgep != NULL); 890 891 mutex_enter(&atgep->atge_intr_lock); 892 893 if (atgep->atge_chip_state & ATGE_CHIP_SUSPENDED) { 894 mutex_exit(&atgep->atge_intr_lock); 895 return (DDI_INTR_UNCLAIMED); 896 } 897 898 status = INL(atgep, ATGE_INTR_STATUS); 899 if (status == 0 || (status & atgep->atge_intrs) == 0) { 900 mutex_exit(&atgep->atge_intr_lock); 901 902 if (atgep->atge_flags & ATGE_FIXED_TYPE) 903 return (DDI_INTR_UNCLAIMED); 904 905 return (DDI_INTR_CLAIMED); 906 } 907 908 ATGE_DB(("%s: %s() entry status : %x", 909 atgep->atge_name, __func__, status)); 910 911 /* 912 * Disable interrupts. 913 */ 914 if (status & L1C_INTR_GPHY) { 915 /* clear PHY interrupt source before we ack interrupts */ 916 (void) atge_mii_read(atgep, 917 atgep->atge_phyaddr, ATGE_ISR_ACK_GPHY); 918 } 919 920 OUTL(atgep, ATGE_INTR_STATUS, status | L1C_INTR_DIS_INT); 921 FLUSH(atgep, ATGE_INTR_STATUS); 922 923 /* 924 * Check if chip is running, only then do the work. 925 */ 926 if (atgep->atge_chip_state & ATGE_CHIP_RUNNING) { 927 atge_l1c_data_t *l1c; 928 929 l1c = atgep->atge_private_data; 930 931 ATGE_DB(("%s: %s() atge_l1c_intr_status : %x, " 932 "atge_l1c_rx_prod_cons : %d, atge_l1c_tx_prod_cons : %d" 933 " atge_l1c_rr_consumers : %d", 934 atgep->atge_name, __func__, l1c->atge_l1c_intr_status, 935 l1c->atge_l1c_rx_prod_cons, l1c->atge_l1c_tx_prod_cons, 936 l1c->atge_l1c_rr_consumers)); 937 938 if (status & L1C_INTR_SMB) 939 atge_l1c_gather_stats(atgep); 940 941 /* 942 * Check for errors. 943 */ 944 if (status & (L1C_INTR_DMA_RD_TO_RST | 945 L1C_INTR_DMA_WR_TO_RST | L1C_INTR_TXQ_TO_RST)) { 946 /* This should be an FMA event. */ 947 atge_error(atgep->atge_dip, 948 "L1C chip detected a fatal error, " 949 "interrupt status: %x", status); 950 951 if (status & L1C_INTR_DMA_RD_TO_RST) { 952 atge_error(atgep->atge_dip, 953 "DMA read error"); 954 } 955 if (status & L1C_INTR_DMA_WR_TO_RST) { 956 atge_error(atgep->atge_dip, 957 "DMA write error"); 958 } 959 if (status & L1C_INTR_TXQ_TO_RST) { 960 atge_error(atgep->atge_dip, 961 "Transmit queue error"); 962 } 963 964 /* This should be an FMA event. */ 965 atge_device_stop(atgep); 966 /* 967 * Device has failed fatally. 968 * It will not be restarted by the driver. 969 */ 970 goto done; 971 972 } 973 974 rx_head = atge_l1c_rx(atgep); 975 if (status & L1C_INTR_TX_PKT) { 976 int cons; 977 978 mutex_enter(&atgep->atge_tx_lock); 979 cons = INL(atgep, ATGE_MBOX_TD_CONS_IDX) >> 16; 980 atge_tx_reclaim(atgep, cons); 981 if (atgep->atge_tx_resched) { 982 atgep->atge_tx_resched = 0; 983 resched = 1; 984 } 985 986 mutex_exit(&atgep->atge_tx_lock); 987 } 988 } 989 990 /* Re-enable interrupts. */ 991 OUTL(atgep, ATGE_INTR_STATUS, 0); 992 993 done: 994 mutex_exit(&atgep->atge_intr_lock); 995 996 if (status & L1C_INTR_GPHY) { 997 /* link down */ 998 ATGE_DB(("%s: %s() MII_CHECK Performed", 999 atgep->atge_name, __func__)); 1000 mii_check(atgep->atge_mii); 1001 } 1002 1003 /* 1004 * Pass the list of packets received from chip to MAC layer. 1005 */ 1006 if (rx_head) { 1007 mac_rx(atgep->atge_mh, 0, rx_head); 1008 } 1009 1010 /* 1011 * Let MAC start sending pkts if the downstream was asked to pause. 1012 */ 1013 if (resched) 1014 mac_tx_update(atgep->atge_mh); 1015 1016 return (DDI_INTR_CLAIMED); 1017 } 1018 1019 void 1020 atge_l1c_send_packet(atge_ring_t *r) 1021 { 1022 atge_t *atgep; 1023 1024 atgep = r->r_atge; 1025 1026 mutex_enter(&atgep->atge_mbox_lock); 1027 /* Sync descriptors. */ 1028 DMA_SYNC(atgep->atge_tx_ring->r_desc_ring, 0, 0, DDI_DMA_SYNC_FORDEV); 1029 /* Kick. Assume we're using normal Tx priority queue. */ 1030 OUTL(atgep, ATGE_MBOX_TD_PROD_IDX, 1031 (atgep->atge_tx_ring->r_producer << MBOX_TD_PROD_LO_IDX_SHIFT) & 1032 MBOX_TD_PROD_LO_IDX_MASK); 1033 mutex_exit(&atgep->atge_mbox_lock); 1034 } 1035