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 }