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