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