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