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_l1_reg.h" 48 #include "atge_cmn_reg.h" 49 50 static ddi_dma_attr_t atge_l1_dma_attr_tx_desc = { 51 DMA_ATTR_V0, /* dma_attr_version */ 52 0, /* dma_attr_addr_lo */ 53 0x0000ffffffffull, /* dma_attr_addr_hi */ 54 0x0000ffffffffull, /* dma_attr_count_max */ 55 L1_TX_RING_ALIGN, /* dma_attr_align */ 56 0x0000fffc, /* dma_attr_burstsizes */ 57 1, /* dma_attr_minxfer */ 58 0x0000ffffffffull, /* dma_attr_maxxfer */ 59 0x0000ffffffffull, /* dma_attr_seg */ 60 1, /* dma_attr_sgllen */ 61 1, /* dma_attr_granular */ 62 0 /* dma_attr_flags */ 63 }; 64 65 static ddi_dma_attr_t atge_l1_dma_attr_rx_desc = { 66 DMA_ATTR_V0, /* dma_attr_version */ 67 0, /* dma_attr_addr_lo */ 68 0x0000ffffffffull, /* dma_attr_addr_hi */ 69 0x0000ffffffffull, /* dma_attr_count_max */ 70 L1_RX_RING_ALIGN, /* dma_attr_align */ 71 0x0000fffc, /* dma_attr_burstsizes */ 72 1, /* dma_attr_minxfer */ 73 0x0000ffffffffull, /* dma_attr_maxxfer */ 74 0x0000ffffffffull, /* dma_attr_seg */ 75 1, /* dma_attr_sgllen */ 76 1, /* dma_attr_granular */ 77 0 /* dma_attr_flags */ 78 }; 79 80 static ddi_dma_attr_t atge_l1_dma_attr_cmb = { 81 DMA_ATTR_V0, /* dma_attr_version */ 82 0, /* dma_attr_addr_lo */ 83 0x0000ffffffffull, /* dma_attr_addr_hi */ 84 0x0000ffffffffull, /* dma_attr_count_max */ 85 L1_CMB_ALIGN, /* dma_attr_align */ 86 0x0000fffc, /* dma_attr_burstsizes */ 87 1, /* dma_attr_minxfer */ 88 0x0000ffffffffull, /* dma_attr_maxxfer */ 89 0x0000ffffffffull, /* dma_attr_seg */ 90 1, /* dma_attr_sgllen */ 91 1, /* dma_attr_granular */ 92 0 /* dma_attr_flags */ 93 }; 94 95 static ddi_dma_attr_t atge_l1_dma_attr_smb = { 96 DMA_ATTR_V0, /* dma_attr_version */ 97 0, /* dma_attr_addr_lo */ 98 0x0000ffffffffull, /* dma_attr_addr_hi */ 99 0x0000ffffffffull, /* dma_attr_count_max */ 100 L1_SMB_ALIGN, /* dma_attr_align */ 101 0x0000fffc, /* dma_attr_burstsizes */ 102 1, /* dma_attr_minxfer */ 103 0x0000ffffffffull, /* dma_attr_maxxfer */ 104 0x0000ffffffffull, /* dma_attr_seg */ 105 1, /* dma_attr_sgllen */ 106 1, /* dma_attr_granular */ 107 0 /* dma_attr_flags */ 108 }; 109 110 static ddi_dma_attr_t atge_l1_dma_attr_rr = { 111 DMA_ATTR_V0, /* dma_attr_version */ 112 0, /* dma_attr_addr_lo */ 113 0x0000ffffffffull, /* dma_attr_addr_hi */ 114 0x0000ffffffffull, /* dma_attr_count_max */ 115 L1_RR_RING_ALIGN, /* dma_attr_align */ 116 0x0000fffc, /* dma_attr_burstsizes */ 117 1, /* dma_attr_minxfer */ 118 0x0000ffffffffull, /* dma_attr_maxxfer */ 119 0x0000ffffffffull, /* dma_attr_seg */ 120 1, /* dma_attr_sgllen */ 121 1, /* dma_attr_granular */ 122 0 /* dma_attr_flags */ 123 }; 124 125 int 126 atge_l1_alloc_dma(atge_t *atgep) 127 { 128 atge_l1_data_t *l1; 129 atge_dma_t *dma; 130 int err; 131 132 l1 = kmem_zalloc(sizeof (atge_l1_data_t), KM_SLEEP); 133 atgep->atge_private_data = l1; 134 135 /* 136 * Allocate TX ring descriptor. 137 */ 138 atgep->atge_tx_buf_len = atgep->atge_mtu + 139 sizeof (struct ether_header) + VLAN_TAGSZ + ETHERFCSL; 140 atgep->atge_tx_ring = kmem_alloc(sizeof (atge_ring_t), KM_SLEEP); 141 atgep->atge_tx_ring->r_atge = atgep; 142 atgep->atge_tx_ring->r_desc_ring = NULL; 143 dma = atge_alloc_a_dma_blk(atgep, &atge_l1_dma_attr_tx_desc, 144 ATGE_TX_RING_SZ, DDI_DMA_RDWR); 145 if (dma == NULL) { 146 atge_error(atgep->atge_dip, "DMA allocation failed for TX" 147 " desc ring"); 148 return (DDI_FAILURE); 149 } 150 atgep->atge_tx_ring->r_desc_ring = dma; 151 152 /* 153 * Allocate DMA buffers for TX ring. 154 */ 155 err = atge_alloc_buffers(atgep->atge_tx_ring, ATGE_TX_RING_CNT, 156 atgep->atge_tx_buf_len, DDI_DMA_WRITE); 157 if (err != DDI_SUCCESS) { 158 atge_error(atgep->atge_dip, "DMA allocation failed for" 159 " TX Ring"); 160 return (err); 161 } 162 163 /* 164 * Allocate RX ring. 165 */ 166 atgep->atge_rx_buf_len = atgep->atge_mtu + 167 sizeof (struct ether_header) + VLAN_TAGSZ + ETHERFCSL; 168 l1->atge_rx_ring = kmem_alloc(sizeof (atge_ring_t), KM_SLEEP); 169 l1->atge_rx_ring->r_atge = atgep; 170 l1->atge_rx_ring->r_desc_ring = NULL; 171 dma = atge_alloc_a_dma_blk(atgep, &atge_l1_dma_attr_rx_desc, 172 L1_RX_RING_SZ, DDI_DMA_RDWR); 173 if (dma == NULL) { 174 atge_error(atgep->atge_dip, "DMA allocation failed" 175 " for RX Ring"); 176 return (DDI_FAILURE); 177 } 178 l1->atge_rx_ring->r_desc_ring = dma; 179 180 /* 181 * Allocate DMA buffers for RX ring. 182 */ 183 err = atge_alloc_buffers(l1->atge_rx_ring, L1_RX_RING_CNT, 184 atgep->atge_rx_buf_len, DDI_DMA_WRITE); 185 if (err != DDI_SUCCESS) { 186 atge_error(atgep->atge_dip, "DMA allocation failed for" 187 " RX buffers"); 188 return (err); 189 } 190 191 /* 192 * Allocate CMB used for fetching interrupt status data. 193 */ 194 ATGE_DB(("%s: %s() L1_CMB_BLOCK_SZ : %x", atgep->atge_name, 195 __func__, L1_CMB_BLOCK_SZ)); 196 197 dma = atge_alloc_a_dma_blk(atgep, &atge_l1_dma_attr_cmb, 198 L1_CMB_BLOCK_SZ, DDI_DMA_RDWR); 199 l1->atge_l1_cmb = dma; 200 if (dma == NULL) { 201 atge_error(atgep->atge_dip, "DMA allocation failed for CMB"); 202 return (DDI_FAILURE); 203 } 204 205 /* 206 * RR ring (Return Ring for RX and TX). 207 */ 208 ATGE_DB(("%s: %s() L1_RR_RING_SZ : %x", atgep->atge_name, 209 __func__, L1_RR_RING_SZ)); 210 211 dma = atge_alloc_a_dma_blk(atgep, &atge_l1_dma_attr_rr, 212 L1_RR_RING_SZ, DDI_DMA_RDWR); 213 l1->atge_l1_rr = dma; 214 if (dma == NULL) { 215 atge_error(atgep->atge_dip, "DMA allocation failed" 216 " for RX RR ring"); 217 return (DDI_FAILURE); 218 } 219 220 /* 221 * SMB for statistics. 222 */ 223 ATGE_DB(("%s: %s() L1_SMB_BLOCK_SZ : %x", atgep->atge_name, 224 __func__, L1_SMB_BLOCK_SZ)); 225 226 dma = atge_alloc_a_dma_blk(atgep, &atge_l1_dma_attr_smb, 227 L1_SMB_BLOCK_SZ, DDI_DMA_RDWR); 228 l1->atge_l1_smb = dma; 229 if (dma == NULL) { 230 atge_error(atgep->atge_dip, "DMA allocation failed for SMB"); 231 return (DDI_FAILURE); 232 } 233 234 atgep->atge_hw_stats = kmem_zalloc(sizeof (atge_l1_smb_t), KM_SLEEP); 235 236 return (DDI_SUCCESS); 237 } 238 239 void 240 atge_l1_free_dma(atge_t *atgep) 241 { 242 atge_l1_data_t *l1; 243 244 l1 = atgep->atge_private_data; 245 246 /* 247 * Free TX ring. 248 */ 249 if (atgep->atge_tx_ring != NULL) { 250 atge_free_buffers(atgep->atge_tx_ring, ATGE_TX_RING_CNT); 251 252 if (atgep->atge_tx_ring->r_desc_ring != NULL) { 253 atge_free_a_dma_blk(atgep->atge_tx_ring->r_desc_ring); 254 } 255 256 kmem_free(atgep->atge_tx_ring, sizeof (atge_ring_t)); 257 atgep->atge_tx_ring = NULL; 258 } 259 260 if (l1 && l1->atge_l1_cmb != NULL) { 261 atge_free_a_dma_blk(l1->atge_l1_cmb); 262 l1->atge_l1_cmb = NULL; 263 } 264 265 if (l1 && l1->atge_l1_rr != NULL) { 266 atge_free_a_dma_blk(l1->atge_l1_rr); 267 l1->atge_l1_rr = NULL; 268 } 269 270 if (l1 && l1->atge_l1_smb != NULL) { 271 atge_free_a_dma_blk(l1->atge_l1_smb); 272 l1->atge_l1_smb = NULL; 273 } 274 275 /* 276 * Free RX ring. 277 */ 278 if (l1 && l1->atge_rx_ring != NULL) { 279 atge_free_buffers(l1->atge_rx_ring, L1_RX_RING_CNT); 280 281 if (l1->atge_rx_ring->r_desc_ring != NULL) { 282 atge_free_a_dma_blk(l1->atge_rx_ring->r_desc_ring); 283 } 284 285 kmem_free(l1->atge_rx_ring, sizeof (atge_ring_t)); 286 l1->atge_rx_ring = NULL; 287 } 288 289 /* 290 * Free the memory allocated for gathering hw stats. 291 */ 292 if (atgep->atge_hw_stats != NULL) { 293 kmem_free(atgep->atge_hw_stats, sizeof (atge_l1_smb_t)); 294 atgep->atge_hw_stats = NULL; 295 } 296 } 297 298 void 299 atge_l1_init_rx_ring(atge_t *atgep) 300 { 301 atge_l1_data_t *l1; 302 atge_dma_t *dma; 303 l1_rx_desc_t *rx; 304 int i; 305 306 l1 = atgep->atge_private_data; 307 l1->atge_rx_ring->r_consumer = L1_RX_RING_CNT - 1; 308 dma = l1->atge_rx_ring->r_desc_ring; 309 bzero(dma->addr, L1_RX_RING_SZ); 310 311 for (i = 0; i < L1_RX_RING_CNT; i++) { 312 rx = (l1_rx_desc_t *)(dma->addr + (i * sizeof (l1_rx_desc_t))); 313 314 ATGE_PUT64(dma, &rx->addr, 315 l1->atge_rx_ring->r_buf_tbl[i]->cookie.dmac_laddress); 316 ATGE_PUT32(dma, &rx->len, 317 (l1->atge_rx_ring->r_buf_tbl[i]->len & L1_RD_LEN_MASK) << 318 L1_RD_LEN_SHIFT); 319 } 320 321 DMA_SYNC(dma, 0, L1_RX_RING_SZ, DDI_DMA_SYNC_FORDEV); 322 } 323 324 void 325 atge_l1_init_tx_ring(atge_t *atgep) 326 { 327 atgep->atge_tx_ring->r_producer = 0; 328 atgep->atge_tx_ring->r_consumer = 0; 329 atgep->atge_tx_ring->r_avail_desc = ATGE_TX_RING_CNT; 330 331 bzero(atgep->atge_tx_ring->r_desc_ring->addr, ATGE_TX_RING_SZ); 332 DMA_SYNC(atgep->atge_tx_ring->r_desc_ring, 0, ATGE_TX_RING_SZ, 333 DDI_DMA_SYNC_FORDEV); 334 } 335 336 void 337 atge_l1_init_rr_ring(atge_t *atgep) 338 { 339 atge_l1_data_t *l1; 340 atge_dma_t *dma; 341 342 l1 = atgep->atge_private_data; 343 l1->atge_l1_rr_consumers = 0; 344 345 dma = l1->atge_l1_rr; 346 bzero(dma->addr, L1_RR_RING_SZ); 347 DMA_SYNC(dma, 0, L1_RR_RING_SZ, DDI_DMA_SYNC_FORDEV); 348 } 349 350 void 351 atge_l1_init_smb(atge_t *atgep) 352 { 353 atge_l1_data_t *l1; 354 atge_dma_t *dma; 355 356 l1 = atgep->atge_private_data; 357 dma = l1->atge_l1_smb; 358 bzero(dma->addr, L1_SMB_BLOCK_SZ); 359 DMA_SYNC(dma, 0, L1_SMB_BLOCK_SZ, DDI_DMA_SYNC_FORDEV); 360 } 361 362 void 363 atge_l1_init_cmb(atge_t *atgep) 364 { 365 atge_l1_data_t *l1; 366 atge_dma_t *dma; 367 368 l1 = atgep->atge_private_data; 369 dma = l1->atge_l1_cmb; 370 bzero(dma->addr, L1_CMB_BLOCK_SZ); 371 DMA_SYNC(dma, 0, L1_CMB_BLOCK_SZ, DDI_DMA_SYNC_FORDEV); 372 } 373 374 void 375 atge_l1_sync_mbox(atge_t *atgep) 376 { 377 atge_l1_data_t *l1; 378 379 l1 = atgep->atge_private_data; 380 381 mutex_enter(&atgep->atge_mbox_lock); 382 OUTL(atgep, ATGE_MBOX, 383 ((l1->atge_rx_ring->r_consumer << MBOX_RD_PROD_IDX_SHIFT) & 384 MBOX_RD_PROD_IDX_MASK) | 385 ((l1->atge_l1_rr_consumers << 386 MBOX_RRD_CONS_IDX_SHIFT) & MBOX_RRD_CONS_IDX_MASK) | 387 ((atgep->atge_tx_ring->r_producer << MBOX_TD_PROD_IDX_SHIFT) & 388 MBOX_TD_PROD_IDX_MASK)); 389 mutex_exit(&atgep->atge_mbox_lock); 390 } 391 392 void 393 atge_l1_program_dma(atge_t *atgep) 394 { 395 atge_l1_data_t *l1; 396 atge_ring_t *r; 397 398 l1 = atgep->atge_private_data; 399 400 /* TX */ 401 r = atgep->atge_tx_ring; 402 OUTL(atgep, ATGE_DESC_ADDR_HI, 403 ATGE_ADDR_HI(r->r_desc_ring->cookie.dmac_laddress)); 404 OUTL(atgep, ATGE_DESC_TPD_ADDR_LO, 405 ATGE_ADDR_LO(r->r_desc_ring->cookie.dmac_laddress)); 406 407 /* RX */ 408 r = l1->atge_rx_ring; 409 OUTL(atgep, ATGE_DESC_RD_ADDR_LO, 410 ATGE_ADDR_LO(r->r_desc_ring->cookie.dmac_laddress)); 411 412 /* RR Ring */ 413 OUTL(atgep, ATGE_DESC_RRD_ADDR_LO, 414 ATGE_ADDR_LO(l1->atge_l1_rr->cookie.dmac_laddress)); 415 416 /* CMB */ 417 OUTL(atgep, ATGE_DESC_CMB_ADDR_LO, 418 ATGE_ADDR_LO(l1->atge_l1_cmb->cookie.dmac_laddress)); 419 420 /* SMB */ 421 OUTL(atgep, ATGE_DESC_SMB_ADDR_LO, 422 ATGE_ADDR_LO(l1->atge_l1_smb->cookie.dmac_laddress)); 423 424 /* 425 * Set RX return ring (RR) counter. 426 */ 427 OUTL(atgep, ATGE_DESC_RRD_RD_CNT, 428 ((L1_RR_RING_CNT << DESC_RRD_CNT_SHIFT) & 429 DESC_RRD_CNT_MASK) | 430 ((L1_RX_RING_CNT << DESC_RD_CNT_SHIFT) & DESC_RD_CNT_MASK)); 431 432 /* 433 * Set TX descriptor counter. 434 */ 435 OUTL(atgep, ATGE_DESC_TPD_CNT, 436 (ATGE_TX_RING_CNT << DESC_TPD_CNT_SHIFT) & DESC_TPD_CNT_MASK); 437 438 /* 439 * Inform hardware that we have loaded DMA registers. 440 */ 441 OUTL(atgep, ATGE_DMA_BLOCK, DMA_BLOCK_LOAD); 442 443 /* 444 * Initialize mailbox register (mbox). 445 */ 446 atge_l1_sync_mbox(atgep); 447 } 448 449 void 450 atge_l1_gather_stats(atge_t *atgep) 451 { 452 atge_l1_data_t *l1; 453 atge_dma_t *dma; 454 atge_l1_smb_t *stat; 455 atge_l1_smb_t *smb; 456 457 ASSERT(atgep != NULL); 458 459 l1 = atgep->atge_private_data; 460 dma = l1->atge_l1_smb; 461 DMA_SYNC(dma, 0, L1_SMB_BLOCK_SZ, DDI_DMA_SYNC_FORKERNEL); 462 stat = (atge_l1_smb_t *)atgep->atge_hw_stats; 463 smb = (atge_l1_smb_t *)dma->addr; 464 465 /* Rx stats. */ 466 stat->rx_frames += smb->rx_frames; 467 stat->rx_bcast_frames += smb->rx_bcast_frames; 468 stat->rx_mcast_frames += smb->rx_mcast_frames; 469 stat->rx_pause_frames += smb->rx_pause_frames; 470 stat->rx_control_frames += smb->rx_control_frames; 471 stat->rx_crcerrs += smb->rx_crcerrs; 472 stat->rx_lenerrs += smb->rx_lenerrs; 473 stat->rx_bytes += smb->rx_bytes; 474 stat->rx_runts += smb->rx_runts; 475 stat->rx_fragments += smb->rx_fragments; 476 stat->rx_pkts_64 += smb->rx_pkts_64; 477 stat->rx_pkts_65_127 += smb->rx_pkts_65_127; 478 stat->rx_pkts_128_255 += smb->rx_pkts_128_255; 479 stat->rx_pkts_256_511 += smb->rx_pkts_256_511; 480 stat->rx_pkts_512_1023 += smb->rx_pkts_512_1023; 481 stat->rx_pkts_1024_1518 += smb->rx_pkts_1024_1518; 482 stat->rx_pkts_1519_max += smb->rx_pkts_1519_max; 483 stat->rx_pkts_truncated += smb->rx_pkts_truncated; 484 stat->rx_fifo_oflows += smb->rx_fifo_oflows; 485 stat->rx_alignerrs += smb->rx_alignerrs; 486 stat->rx_bcast_bytes += smb->rx_bcast_bytes; 487 stat->rx_mcast_bytes += smb->rx_mcast_bytes; 488 stat->rx_pkts_filtered += smb->rx_pkts_filtered; 489 490 /* Tx stats. */ 491 stat->tx_frames += smb->tx_frames; 492 stat->tx_bcast_frames += smb->tx_bcast_frames; 493 stat->tx_mcast_frames += smb->tx_mcast_frames; 494 stat->tx_pause_frames += smb->tx_pause_frames; 495 stat->tx_excess_defer += smb->tx_excess_defer; 496 stat->tx_control_frames += smb->tx_control_frames; 497 stat->tx_deferred += smb->tx_deferred; 498 stat->tx_bytes += smb->tx_bytes; 499 stat->tx_pkts_64 += smb->tx_pkts_64; 500 stat->tx_pkts_65_127 += smb->tx_pkts_65_127; 501 stat->tx_pkts_128_255 += smb->tx_pkts_128_255; 502 stat->tx_pkts_256_511 += smb->tx_pkts_256_511; 503 stat->tx_pkts_512_1023 += smb->tx_pkts_512_1023; 504 stat->tx_pkts_1024_1518 += smb->tx_pkts_1024_1518; 505 stat->tx_pkts_1519_max += smb->tx_pkts_1519_max; 506 stat->tx_single_colls += smb->tx_single_colls; 507 stat->tx_multi_colls += smb->tx_multi_colls; 508 stat->tx_late_colls += smb->tx_late_colls; 509 stat->tx_excess_colls += smb->tx_excess_colls; 510 stat->tx_underrun += smb->tx_underrun; 511 stat->tx_desc_underrun += smb->tx_desc_underrun; 512 stat->tx_lenerrs += smb->tx_lenerrs; 513 stat->tx_pkts_truncated += smb->tx_pkts_truncated; 514 stat->tx_bcast_bytes += smb->tx_bcast_bytes; 515 stat->tx_mcast_bytes += smb->tx_mcast_bytes; 516 517 /* 518 * Update global counters in atge_t. 519 */ 520 atgep->atge_brdcstrcv += smb->rx_bcast_frames; 521 atgep->atge_multircv += smb->rx_mcast_frames; 522 atgep->atge_multixmt += smb->tx_mcast_frames; 523 atgep->atge_brdcstxmt += smb->tx_bcast_frames; 524 525 atgep->atge_align_errors += smb->rx_alignerrs; 526 atgep->atge_fcs_errors += smb->rx_crcerrs; 527 atgep->atge_defer_xmts += smb->tx_deferred; 528 atgep->atge_first_collisions += smb->tx_single_colls; 529 atgep->atge_multi_collisions += smb->tx_multi_colls * 2; 530 atgep->atge_tx_late_collisions += smb->tx_late_colls; 531 atgep->atge_ex_collisions += smb->tx_excess_colls; 532 atgep->atge_toolong_errors += smb->rx_lenerrs; 533 atgep->atge_overflow += smb->rx_fifo_oflows; 534 atgep->atge_underflow += (smb->tx_underrun + smb->tx_desc_underrun); 535 atgep->atge_runt += smb->rx_runts; 536 537 538 atgep->atge_collisions += smb->tx_single_colls + 539 smb->tx_multi_colls * 2 + smb->tx_late_colls; 540 541 /* 542 * tx_pkts_truncated counter looks suspicious. It constantly 543 * increments with no sign of Tx errors. Hence we don't factor it. 544 */ 545 atgep->atge_macxmt_errors += smb->tx_late_colls + smb->tx_underrun; 546 547 atgep->atge_macrcv_errors += smb->rx_crcerrs + smb->rx_lenerrs + 548 smb->rx_runts + smb->rx_pkts_truncated + 549 smb->rx_alignerrs; 550 551 smb->updated = 0; 552 DMA_SYNC(dma, 0, L1_SMB_BLOCK_SZ, DDI_DMA_SYNC_FORDEV); 553 } 554 555 void 556 atge_l1_stop_tx_mac(atge_t *atgep) 557 { 558 uint32_t reg; 559 int t; 560 561 ATGE_DB(("%s: %s() called", atgep->atge_name, __func__)); 562 563 reg = INL(atgep, ATGE_MAC_CFG); 564 if ((reg & ATGE_CFG_TX_ENB) != 0) { 565 reg &= ~ATGE_CFG_TX_ENB; 566 OUTL(atgep, ATGE_MAC_CFG, reg); 567 } 568 569 /* Stop TX DMA engine. */ 570 reg = INL(atgep, ATGE_DMA_CFG); 571 if ((reg & DMA_CFG_RD_ENB) != 0) { 572 reg &= ~DMA_CFG_RD_ENB; 573 OUTL(atgep, ATGE_DMA_CFG, reg); 574 } 575 576 for (t = ATGE_RESET_TIMEOUT; t > 0; t--) { 577 if ((INL(atgep, ATGE_IDLE_STATUS) & 578 (IDLE_STATUS_TXMAC | IDLE_STATUS_DMARD)) == 0) 579 break; 580 581 drv_usecwait(10); 582 } 583 584 if (t == 0) { 585 atge_error(atgep->atge_dip, "stopping TX DMA Engine timeout"); 586 } 587 } 588 589 void 590 atge_l1_stop_rx_mac(atge_t *atgep) 591 { 592 uint32_t reg; 593 int t; 594 595 ATGE_DB(("%s: %s() called", atgep->atge_name, __func__)); 596 597 reg = INL(atgep, ATGE_MAC_CFG); 598 if ((reg & ATGE_CFG_RX_ENB) != 0) { 599 reg &= ~ATGE_CFG_RX_ENB; 600 OUTL(atgep, ATGE_MAC_CFG, reg); 601 } 602 603 /* Stop RX DMA engine. */ 604 reg = INL(atgep, ATGE_DMA_CFG); 605 if ((reg & DMA_CFG_WR_ENB) != 0) { 606 reg &= ~DMA_CFG_WR_ENB; 607 OUTL(atgep, ATGE_DMA_CFG, reg); 608 } 609 610 for (t = ATGE_RESET_TIMEOUT; t > 0; t--) { 611 if ((INL(atgep, ATGE_IDLE_STATUS) & 612 (IDLE_STATUS_RXMAC | IDLE_STATUS_DMAWR)) == 0) 613 break; 614 drv_usecwait(10); 615 } 616 617 if (t == 0) { 618 atge_error(atgep->atge_dip, " stopping RX DMA Engine timeout"); 619 } 620 } 621 622 /* 623 * Receives (consumes) packets. 624 */ 625 static mblk_t * 626 atge_l1_rx(atge_t *atgep) 627 { 628 atge_l1_data_t *l1; 629 mblk_t *mp = NULL, *rx_head = NULL, *rx_tail = NULL; 630 l1_rx_rdesc_t *rx_rr; 631 l1_rx_desc_t *rxd; 632 uint32_t index, flags, totlen, pktlen, slotlen; 633 int nsegs, rx_cons = 0, cnt; 634 atge_dma_t *buf; 635 uchar_t *bufp; 636 int sync = 0; 637 638 l1 = atgep->atge_private_data; 639 ASSERT(l1 != NULL); 640 641 DMA_SYNC(l1->atge_l1_rr, 0, L1_RR_RING_SZ, DDI_DMA_SYNC_FORKERNEL); 642 643 while (l1->atge_l1_rr_consumers != l1->atge_l1_rx_prod_cons) { 644 rx_rr = (l1_rx_rdesc_t *)(l1->atge_l1_rr->addr + 645 (l1->atge_l1_rr_consumers * sizeof (l1_rx_rdesc_t))); 646 647 index = ATGE_GET32(l1->atge_l1_rr, &rx_rr->index); 648 flags = ATGE_GET32(l1->atge_l1_rr, &rx_rr->flags); 649 totlen = L1_RX_BYTES(ATGE_GET32(l1->atge_l1_rr, &rx_rr->len)); 650 651 rx_cons = L1_RX_CONS(index); 652 nsegs = L1_RX_NSEGS(index); 653 654 ATGE_DB(("%s: %s() PKT -- index : %d, flags : %x, totlen : %d," 655 " rx_cons : %d, nsegs : %d", atgep->atge_name, __func__, 656 index, flags, totlen, rx_cons, nsegs)); 657 658 if (nsegs == 0) 659 break; 660 661 if ((flags & L1_RRD_ERROR) && 662 (flags & (L1_RRD_CRC | L1_RRD_CODE | L1_RRD_DRIBBLE | 663 L1_RRD_RUNT | L1_RRD_OFLOW | L1_RRD_TRUNC)) != 0) { 664 atge_error(atgep->atge_dip, "errored pkt"); 665 666 l1->atge_rx_ring->r_consumer += nsegs; 667 l1->atge_rx_ring->r_consumer %= L1_RX_RING_CNT; 668 break; 669 } 670 671 ASSERT(rx_cons >= 0 && rx_cons <= L1_RX_RING_CNT); 672 673 mp = allocb(totlen + VLAN_TAGSZ, BPRI_MED); 674 if (mp != NULL) { 675 mp->b_rptr += VLAN_TAGSZ; 676 bufp = mp->b_rptr; 677 mp->b_wptr = bufp + totlen; 678 mp->b_next = NULL; 679 680 atgep->atge_ipackets++; 681 atgep->atge_rbytes += totlen; 682 683 /* 684 * If there are more than one segments, then the first 685 * segment should be of size MTU. We couldn't verify 686 * this as our driver does not support changing MTU 687 * or Jumbo Frames. 688 */ 689 if (nsegs > 1) { 690 slotlen = atgep->atge_mtu; 691 } else { 692 slotlen = totlen; 693 } 694 } else { 695 ATGE_DB(("%s: %s() PKT mp == NULL totlen : %d", 696 atgep->atge_name, __func__, totlen)); 697 698 if (slotlen > atgep->atge_rx_buf_len) { 699 atgep->atge_toolong_errors++; 700 } else if (mp == NULL) { 701 atgep->atge_norcvbuf++; 702 } 703 704 rx_rr->index = 0; 705 break; 706 } 707 708 for (cnt = 0, pktlen = 0; cnt < nsegs; cnt++) { 709 buf = l1->atge_rx_ring->r_buf_tbl[rx_cons]; 710 rxd = (l1_rx_desc_t *)( 711 l1->atge_rx_ring->r_desc_ring->addr + 712 (rx_cons * sizeof (l1_rx_desc_t))); 713 714 if (cnt != 0) { 715 slotlen = L1_RX_BYTES(ATGE_GET32( 716 l1->atge_rx_ring->r_desc_ring, &rxd->len)); 717 } 718 719 bcopy(buf->addr, (bufp + pktlen), slotlen); 720 pktlen += slotlen; 721 722 ATGE_DB(("%s: %s() len : %d, rxcons : %d, pktlen : %d", 723 atgep->atge_name, __func__, slotlen, rx_cons, 724 pktlen)); 725 726 ATGE_INC_SLOT(rx_cons, L1_RX_RING_CNT); 727 } 728 729 if (rx_tail == NULL) { 730 rx_head = rx_tail = mp; 731 } else { 732 rx_tail->b_next = mp; 733 rx_tail = mp; 734 } 735 736 if (cnt != nsegs) { 737 l1->atge_rx_ring->r_consumer += nsegs; 738 l1->atge_rx_ring->r_consumer %= L1_RX_RING_CNT; 739 } else { 740 l1->atge_rx_ring->r_consumer = rx_cons; 741 } 742 743 /* 744 * Tell the chip that this RR can be reused. 745 */ 746 rx_rr->index = 0; 747 748 ATGE_INC_SLOT(l1->atge_l1_rr_consumers, L1_RR_RING_CNT); 749 sync++; 750 } 751 752 if (sync) { 753 DMA_SYNC(l1->atge_rx_ring->r_desc_ring, 0, L1_RX_RING_SZ, 754 DDI_DMA_SYNC_FORDEV); 755 756 DMA_SYNC(l1->atge_l1_rr, 0, L1_RR_RING_SZ, DDI_DMA_SYNC_FORDEV); 757 atge_l1_sync_mbox(atgep); 758 759 ATGE_DB(("%s: %s() PKT Recved -> r_consumer : %d, rx_cons : %d" 760 " atge_l1_rr_consumers : %d", 761 atgep->atge_name, __func__, l1->atge_rx_ring->r_consumer, 762 rx_cons, l1->atge_l1_rr_consumers)); 763 } 764 765 766 return (rx_head); 767 } 768 769 /* 770 * The interrupt handler for L1 chip. 771 */ 772 /*ARGSUSED*/ 773 uint_t 774 atge_l1_interrupt(caddr_t arg1, caddr_t arg2) 775 { 776 atge_t *atgep = (void *)arg1; 777 mblk_t *rx_head = NULL, *rx_head1 = NULL; 778 uint32_t status; 779 int resched = 0; 780 781 ASSERT(atgep != NULL); 782 783 mutex_enter(&atgep->atge_intr_lock); 784 785 if (atgep->atge_chip_state & ATGE_CHIP_SUSPENDED) { 786 mutex_exit(&atgep->atge_intr_lock); 787 return (DDI_INTR_UNCLAIMED); 788 } 789 790 status = INL(atgep, ATGE_INTR_STATUS); 791 if (status == 0 || (status & atgep->atge_intrs) == 0) { 792 mutex_exit(&atgep->atge_intr_lock); 793 794 if (atgep->atge_flags & ATGE_FIXED_TYPE) 795 return (DDI_INTR_UNCLAIMED); 796 797 return (DDI_INTR_CLAIMED); 798 } 799 800 ATGE_DB(("%s: %s() entry status : %x", 801 atgep->atge_name, __func__, status)); 802 803 /* 804 * Disable interrupts. 805 */ 806 OUTL(atgep, ATGE_INTR_STATUS, status | INTR_DIS_INT); 807 FLUSH(atgep, ATGE_INTR_STATUS); 808 809 /* 810 * Check if chip is running, only then do the work. 811 */ 812 if (atgep->atge_chip_state & ATGE_CHIP_RUNNING) { 813 atge_l1_data_t *l1; 814 l1_cmb_t *cmb; 815 816 l1 = atgep->atge_private_data; 817 818 DMA_SYNC(l1->atge_l1_cmb, 0, L1_CMB_BLOCK_SZ, 819 DDI_DMA_SYNC_FORKERNEL); 820 821 cmb = (l1_cmb_t *)l1->atge_l1_cmb->addr; 822 l1->atge_l1_intr_status = 823 ATGE_GET32(l1->atge_l1_cmb, &cmb->intr_status); 824 l1->atge_l1_rx_prod_cons = 825 (ATGE_GET32(l1->atge_l1_cmb, &cmb->rx_prod_cons) & 826 RRD_PROD_MASK) >> RRD_PROD_SHIFT; 827 l1->atge_l1_tx_prod_cons = 828 (ATGE_GET32(l1->atge_l1_cmb, &cmb->tx_prod_cons) & 829 TPD_CONS_MASK) >> TPD_CONS_SHIFT; 830 831 ATGE_DB(("%s: %s() atge_l1_intr_status : %x, " 832 "atge_l1_rx_prod_cons : %d, atge_l1_tx_prod_cons : %d" 833 " atge_l1_rr_consumers : %d", 834 atgep->atge_name, __func__, l1->atge_l1_intr_status, 835 l1->atge_l1_rx_prod_cons, l1->atge_l1_tx_prod_cons, 836 l1->atge_l1_rr_consumers)); 837 838 /* 839 * Inform the hardware that CMB was served. 840 */ 841 cmb->intr_status = 0; 842 DMA_SYNC(l1->atge_l1_cmb, 0, L1_CMB_BLOCK_SZ, 843 DDI_DMA_SYNC_FORDEV); 844 845 /* 846 * We must check for RX Overflow condition and restart the 847 * chip. This needs to be done only when producer and consumer 848 * counters are same for the RR ring (Return RX). 849 */ 850 if ((l1->atge_l1_intr_status & (INTR_CMB_RX | INTR_MAC_RX)) && 851 (l1->atge_l1_intr_status & 852 (INTR_RX_FIFO_OFLOW | INTR_RRD_OFLOW) && 853 (l1->atge_l1_rr_consumers == l1->atge_l1_rx_prod_cons))) { 854 855 ATGE_DB(("%s: %s() RX OVERFLOW :" 856 " atge_l1_rx_prod_cons : %d," 857 " l1->atge_l1_rr_consumers : %d", 858 atgep->atge_name, __func__, 859 l1->atge_l1_rx_prod_cons, 860 l1->atge_l1_rr_consumers)); 861 862 mutex_enter(&atgep->atge_tx_lock); 863 atge_device_restart(atgep); 864 mutex_exit(&atgep->atge_tx_lock); 865 goto done; 866 } 867 868 rx_head = atge_l1_rx(atgep); 869 870 if (l1->atge_l1_intr_status & INTR_SMB) 871 atge_l1_gather_stats(atgep); 872 873 if (l1->atge_l1_intr_status & (INTR_CMB_TX | INTR_MAC_TX)) { 874 mutex_enter(&atgep->atge_tx_lock); 875 atge_tx_reclaim(atgep, l1->atge_l1_tx_prod_cons); 876 if (atgep->atge_tx_resched) { 877 atgep->atge_tx_resched = 0; 878 resched = 1; 879 } 880 881 mutex_exit(&atgep->atge_tx_lock); 882 } 883 884 if ((status & (INTR_DMA_RD_TO_RST | INTR_DMA_WR_TO_RST)) != 0) { 885 atge_error(atgep->atge_dip, 886 "DMA transfer error"); 887 888 ATGE_DB(("%s: %s() DMA transfer error", 889 atgep->atge_name, __func__)); 890 891 atge_device_stop(atgep); 892 goto done; 893 } 894 } 895 896 done: 897 898 OUTL(atgep, ATGE_INTR_STATUS, INTR_DIS_DMA | INTR_DIS_SM); 899 mutex_exit(&atgep->atge_intr_lock); 900 901 if (status & INTR_GPHY || atgep->atge_flags & ATGE_MII_CHECK) { 902 ATGE_DB(("%s: %s() MII_CHECK Requested", 903 atgep->atge_name, __func__)); 904 905 if (status & INTR_GPHY) { 906 (void) atge_mii_read(atgep, 907 atgep->atge_phyaddr, ATGE_ISR_ACK_GPHY); 908 } 909 910 atgep->atge_flags &= ~ATGE_MII_CHECK; 911 mii_reset(atgep->atge_mii); 912 } 913 914 /* 915 * Pass the list of packets received from chip to MAC layer. 916 */ 917 if (rx_head) { 918 mac_rx(atgep->atge_mh, 0, rx_head); 919 } 920 921 if (rx_head1) { 922 mac_rx(atgep->atge_mh, 0, rx_head1); 923 } 924 925 /* 926 * Let MAC start sending pkts if the downstream was asked to pause. 927 */ 928 if (resched) 929 mac_tx_update(atgep->atge_mh); 930 931 return (DDI_INTR_CLAIMED); 932 } 933 934 void 935 atge_l1_send_packet(atge_ring_t *r) 936 { 937 atge_l1_sync_mbox(r->r_atge); 938 } 939