5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills/*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * CDDL HEADER START
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills *
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * The contents of this file are subject to the terms of the
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Common Development and Distribution License (the "License").
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * You may not use this file except in compliance with the License.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills *
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * or http://www.opensolaris.org/os/licensing.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * See the License for the specific language governing permissions
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * and limitations under the License.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills *
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * When distributing Covered Code, include this CDDL HEADER in each
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * If applicable, add the following below this CDDL HEADER, with the
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * fields enclosed by brackets "[]" replaced with your own identifying
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * information: Portions Copyright [yyyy] [name of copyright owner]
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills *
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * CDDL HEADER END
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills/*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Copyright (c) 2012 Gary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills *
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Use is subject to license terms.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills/*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Copyright (c) 2009, Pyun YongHyeon <yongari@FreeBSD.org>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * All rights reserved.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills *
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Redistribution and use in source and binary forms, with or without
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * modification, are permitted provided that the following conditions
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * are met:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * 1. Redistributions of source code must retain the above copyright
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * notice unmodified, this list of conditions, and the following
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * disclaimer.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * 2. Redistributions in binary form must reproduce the above copyright
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * notice, this list of conditions and the following disclaimer in the
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * documentation and/or other materials provided with the distribution.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills *
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * SUCH DAMAGE.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/types.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/stream.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/strsun.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/stat.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/modctl.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/ethernet.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/debug.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/conf.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/mii.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/miiregs.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/sysmacros.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/dditypes.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/ddi.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/sunddi.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/byteorder.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/note.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/vlan.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include <sys/stream.h>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include "atge.h"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include "atge_l1c_reg.h"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include "atge_cmn_reg.h"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsstatic ddi_dma_attr_t atge_l1c_dma_attr_tx_desc = {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_ATTR_V0, /* dma_attr_version */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0, /* dma_attr_addr_lo */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_addr_hi */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_count_max */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills L1C_TX_RING_ALIGN, /* dma_attr_align */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000fffc, /* dma_attr_burstsizes */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_minxfer */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_maxxfer */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_seg */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_sgllen */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_granular */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0 /* dma_attr_flags */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills};
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsstatic ddi_dma_attr_t atge_l1c_dma_attr_rx_desc = {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_ATTR_V0, /* dma_attr_version */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0, /* dma_attr_addr_lo */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_addr_hi */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_count_max */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills L1C_RX_RING_ALIGN, /* dma_attr_align */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000fffc, /* dma_attr_burstsizes */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_minxfer */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_maxxfer */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_seg */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_sgllen */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_granular */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0 /* dma_attr_flags */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills};
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsstatic ddi_dma_attr_t atge_l1c_dma_attr_cmb = {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_ATTR_V0, /* dma_attr_version */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0, /* dma_attr_addr_lo */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_addr_hi */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_count_max */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills L1C_CMB_ALIGN, /* dma_attr_align */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000fffc, /* dma_attr_burstsizes */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_minxfer */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_maxxfer */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_seg */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_sgllen */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_granular */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0 /* dma_attr_flags */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills};
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsstatic ddi_dma_attr_t atge_l1c_dma_attr_smb = {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_ATTR_V0, /* dma_attr_version */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0, /* dma_attr_addr_lo */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_addr_hi */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_count_max */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills L1C_SMB_ALIGN, /* dma_attr_align */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000fffc, /* dma_attr_burstsizes */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_minxfer */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_maxxfer */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_seg */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_sgllen */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_granular */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0 /* dma_attr_flags */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills};
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsstatic ddi_dma_attr_t atge_l1c_dma_attr_rr = {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_ATTR_V0, /* dma_attr_version */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0, /* dma_attr_addr_lo */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_addr_hi */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_count_max */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills L1C_RR_RING_ALIGN, /* dma_attr_align */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000fffc, /* dma_attr_burstsizes */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_minxfer */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_maxxfer */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0x0000ffffffffull, /* dma_attr_seg */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_sgllen */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 1, /* dma_attr_granular */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills 0 /* dma_attr_flags */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills};
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsint
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_alloc_dma(atge_t *atgep)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_data_t *l1c;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_dma_t *dma;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills int err;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c = kmem_zalloc(sizeof (atge_l1c_data_t), KM_SLEEP);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_private_data = l1c;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Allocate TX ring descriptor.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_tx_buf_len = atgep->atge_mtu +
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills sizeof (struct ether_header) + VLAN_TAGSZ + ETHERFCSL;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_tx_ring = kmem_alloc(sizeof (atge_ring_t), KM_SLEEP);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_tx_ring->r_atge = atgep;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_tx_ring->r_desc_ring = NULL;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills dma = atge_alloc_a_dma_blk(atgep, &atge_l1c_dma_attr_tx_desc,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_TX_RING_SZ, DDI_DMA_RDWR);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (dma == NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_error(atgep->atge_dip, "DMA allocation failed for TX"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills " desc ring");
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills return (DDI_FAILURE);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_tx_ring->r_desc_ring = dma;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Allocate DMA buffers for TX ring.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills err = atge_alloc_buffers(atgep->atge_tx_ring, ATGE_TX_RING_CNT,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_tx_buf_len, DDI_DMA_WRITE);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (err != DDI_SUCCESS) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_error(atgep->atge_dip, "DMA allocation failed for"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills " TX Ring");
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills return (err);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Allocate RX ring.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_rx_buf_len = atgep->atge_mtu +
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills sizeof (struct ether_header) + VLAN_TAGSZ + ETHERFCSL;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_rx_ring = kmem_alloc(sizeof (atge_ring_t), KM_SLEEP);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_rx_ring->r_atge = atgep;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_rx_ring->r_desc_ring = NULL;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills dma = atge_alloc_a_dma_blk(atgep, &atge_l1c_dma_attr_rx_desc,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills L1C_RX_RING_SZ, DDI_DMA_RDWR);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (dma == NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_error(atgep->atge_dip, "DMA allocation failed"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills " for RX Ring");
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills return (DDI_FAILURE);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_rx_ring->r_desc_ring = dma;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Allocate DMA buffers for RX ring.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills err = atge_alloc_buffers(l1c->atge_rx_ring, L1C_RX_RING_CNT,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_rx_buf_len, DDI_DMA_READ);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (err != DDI_SUCCESS) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_error(atgep->atge_dip, "DMA allocation failed for"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills " RX buffers");
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills return (err);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Allocate CMB used for fetching interrupt status data.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_DB(("%s: %s() L1C_CMB_BLOCK_SZ : 0x%x", atgep->atge_name,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills __func__, L1C_CMB_BLOCK_SZ));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills dma = atge_alloc_a_dma_blk(atgep, &atge_l1c_dma_attr_cmb,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills L1C_CMB_BLOCK_SZ, DDI_DMA_RDWR);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_l1c_cmb = dma;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (dma == NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_error(atgep->atge_dip, "DMA allocation failed for CMB");
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills return (DDI_FAILURE);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * RR ring (Return Ring for RX and TX).
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_DB(("%s: %s() L1C_RR_RING_SZ : 0x%x", atgep->atge_name,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills __func__, L1C_RR_RING_SZ));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills dma = atge_alloc_a_dma_blk(atgep, &atge_l1c_dma_attr_rr,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills L1C_RR_RING_SZ, DDI_DMA_RDWR);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_l1c_rr = dma;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (dma == NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_error(atgep->atge_dip, "DMA allocation failed"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills " for RX RR ring");
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills return (DDI_FAILURE);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * SMB for statistics.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_DB(("%s: %s() L1C_SMB_BLOCK_SZ : 0x%x", atgep->atge_name,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills __func__, L1C_SMB_BLOCK_SZ));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills dma = atge_alloc_a_dma_blk(atgep, &atge_l1c_dma_attr_smb,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills L1C_SMB_BLOCK_SZ, DDI_DMA_RDWR);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_l1c_smb = dma;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (dma == NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_error(atgep->atge_dip, "DMA allocation failed for SMB");
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills return (DDI_FAILURE);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_hw_stats = kmem_zalloc(sizeof (atge_l1c_smb_t), KM_SLEEP);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills return (DDI_SUCCESS);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_free_dma(atge_t *atgep)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_data_t *l1c;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c = atgep->atge_private_data;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Free TX ring.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (atgep->atge_tx_ring != NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_free_buffers(atgep->atge_tx_ring, ATGE_TX_RING_CNT);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (atgep->atge_tx_ring->r_desc_ring != NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_free_a_dma_blk(atgep->atge_tx_ring->r_desc_ring);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills kmem_free(atgep->atge_tx_ring, sizeof (atge_ring_t));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_tx_ring = NULL;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (l1c && l1c->atge_l1c_cmb != NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_free_a_dma_blk(l1c->atge_l1c_cmb);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_l1c_cmb = NULL;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (l1c && l1c->atge_l1c_rr != NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_free_a_dma_blk(l1c->atge_l1c_rr);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_l1c_rr = NULL;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (l1c && l1c->atge_l1c_smb != NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_free_a_dma_blk(l1c->atge_l1c_smb);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_l1c_smb = NULL;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Free RX ring.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (l1c && l1c->atge_rx_ring != NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_free_buffers(l1c->atge_rx_ring, L1C_RX_RING_CNT);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (l1c->atge_rx_ring->r_desc_ring != NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_free_a_dma_blk(l1c->atge_rx_ring->r_desc_ring);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills kmem_free(l1c->atge_rx_ring, sizeof (atge_ring_t));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_rx_ring = NULL;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Free the memory allocated for gathering hw stats.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (atgep->atge_hw_stats != NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills kmem_free(atgep->atge_hw_stats, sizeof (atge_l1c_smb_t));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_hw_stats = NULL;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Free the private area.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (l1c != NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills kmem_free(l1c, sizeof (atge_l1c_data_t));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_private_data = NULL;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_init_rx_ring(atge_t *atgep)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_data_t *l1c;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_dma_t *dma;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c_rx_desc_t *rx;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills int i;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c = atgep->atge_private_data;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_rx_ring->r_consumer = L1C_RX_RING_CNT - 1;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills dma = l1c->atge_rx_ring->r_desc_ring;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills bzero(dma->addr, L1C_RX_RING_SZ);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills for (i = 0; i < L1C_RX_RING_CNT; i++) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rx = (l1c_rx_desc_t *)(dma->addr +
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (i * sizeof (l1c_rx_desc_t)));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_PUT64(dma, &rx->addr,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_rx_ring->r_buf_tbl[i]->cookie.dmac_laddress);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* No length field. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_SYNC(dma, 0, 0, DDI_DMA_SYNC_FORDEV);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Let controller know availability of new Rx buffers. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_MBOX_RD0_PROD_IDX, l1c->atge_rx_ring->r_consumer);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_init_tx_ring(atge_t *atgep)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_tx_ring->r_producer = 0;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_tx_ring->r_consumer = 0;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_tx_ring->r_avail_desc = ATGE_TX_RING_CNT;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills bzero(atgep->atge_tx_ring->r_desc_ring->addr, ATGE_TX_RING_SZ);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_SYNC(atgep->atge_tx_ring->r_desc_ring, 0, 0, DDI_DMA_SYNC_FORDEV);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_init_rr_ring(atge_t *atgep)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_data_t *l1c;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_dma_t *dma;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c = atgep->atge_private_data;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_l1c_rr_consumers = 0;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills dma = l1c->atge_l1c_rr;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills bzero(dma->addr, L1C_RR_RING_SZ);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_SYNC(dma, 0, 0, DDI_DMA_SYNC_FORDEV);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_init_smb(atge_t *atgep)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_data_t *l1c;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_dma_t *dma;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c = atgep->atge_private_data;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills dma = l1c->atge_l1c_smb;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills bzero(dma->addr, L1C_SMB_BLOCK_SZ);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_SYNC(dma, 0, 0, DDI_DMA_SYNC_FORDEV);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_init_cmb(atge_t *atgep)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_data_t *l1c;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_dma_t *dma;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c = atgep->atge_private_data;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills dma = l1c->atge_l1c_cmb;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills bzero(dma->addr, L1C_CMB_BLOCK_SZ);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_SYNC(dma, 0, 0, DDI_DMA_SYNC_FORDEV);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_program_dma(atge_t *atgep)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_data_t *l1c;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_ring_t *r;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills uint32_t reg;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c = atgep->atge_private_data;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Clear WOL status and disable all WOL feature as WOL
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * would interfere Rx operation under normal environments.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (void) INL(atgep, ATGE_WOL_CFG);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_WOL_CFG, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* TX */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills r = atgep->atge_tx_ring;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_TX_BASE_ADDR_HI,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_ADDR_HI(r->r_desc_ring->cookie.dmac_laddress));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_TDL_HEAD_ADDR_LO,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_ADDR_LO(r->r_desc_ring->cookie.dmac_laddress));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* We don't use high priority ring. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_TDH_HEAD_ADDR_LO, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* RX */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills r = l1c->atge_rx_ring;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RX_BASE_ADDR_HI,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_ADDR_HI(r->r_desc_ring->cookie.dmac_laddress));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RD0_HEAD_ADDR_LO,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_ADDR_LO(r->r_desc_ring->cookie.dmac_laddress));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* We use one Rx ring. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RD1_HEAD_ADDR_LO, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RD2_HEAD_ADDR_LO, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RD3_HEAD_ADDR_LO, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* RR Ring */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Let hardware split jumbo frames into alc_max_buf_sized chunks.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * if it do not fit the buffer size. Rx return descriptor holds
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * a counter that indicates how many fragments were made by the
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * hardware. The buffer size should be multiple of 8 bytes.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Since hardware has limit on the size of buffer size, always
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * use the maximum value.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * For strict-alignment architectures make sure to reduce buffer
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * size by 8 bytes to make room for alignment fixup.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RX_BUF_SIZE, RX_BUF_SIZE_MAX); /* XXX */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Set Rx return descriptor base addresses. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RRD0_HEAD_ADDR_LO,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_ADDR_LO(l1c->atge_l1c_rr->cookie.dmac_laddress));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* We use one Rx return ring. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RRD1_HEAD_ADDR_LO, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RRD2_HEAD_ADDR_LO, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RRD3_HEAD_ADDR_LO, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* CMB */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_CMB_BASE_ADDR_LO,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_ADDR_LO(l1c->atge_l1c_cmb->cookie.dmac_laddress));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* SMB */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_SMB_BASE_ADDR_HI,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_ADDR_HI(l1c->atge_l1c_smb->cookie.dmac_laddress));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_SMB_BASE_ADDR_LO,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_ADDR_LO(l1c->atge_l1c_smb->cookie.dmac_laddress));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Set RX return ring (RR) counter.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Set Rx descriptor counter. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RD_RING_CNT,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (L1C_RX_RING_CNT << RD_RING_CNT_SHIFT) & RD_RING_CNT_MASK);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Set Rx return descriptor counter. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RRD_RING_CNT,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (L1C_RR_RING_CNT << RRD_RING_CNT_SHIFT) & RRD_RING_CNT_MASK);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Set TX descriptor counter.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_TD_RING_CNT,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (ATGE_TX_RING_CNT << TD_RING_CNT_SHIFT) & TD_RING_CNT_MASK);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_DID(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8152V1_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Reconfigure SRAM - Vendor magic. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_SRAM_RX_FIFO_LEN, 0x000002A0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_SRAM_TX_FIFO_LEN, 0x00000100);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_SRAM_RX_FIFO_ADDR, 0x029F0000);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_SRAM_RD_ADDR, 0x02BF02A0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_SRAM_TX_FIFO_ADDR, 0x03BF02C0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_SRAM_TRD_ADDR, 0x03DF03C0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_TXF_WATER_MARK, 0x00000000);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RD_DMA_CFG, 0x00000000);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Inform hardware that we have loaded DMA registers.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_DMA_BLOCK, DMA_BLOCK_LOAD);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Configure interrupt moderation timer. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = ATGE_USECS(atgep->atge_int_rx_mod) << IM_TIMER_RX_SHIFT;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg |= ATGE_USECS(atgep->atge_int_tx_mod) << IM_TIMER_TX_SHIFT;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_IM_TIMER, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * We don't want to automatic interrupt clear as task queue
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * for the interrupt should know interrupt status.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = 0;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (ATGE_USECS(atgep->atge_int_rx_mod) != 0)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg |= MASTER_IM_RX_TIMER_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (ATGE_USECS(atgep->atge_int_tx_mod) != 0)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg |= MASTER_IM_TX_TIMER_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_MASTER_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_clear_stats(atge_t *atgep)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_smb_t smb;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills uint32_t *reg;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills int i;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Clear RX stats first.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills i = 0;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = &smb.rx_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills while (reg++ <= &smb.rx_pkts_filtered) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (void) INL(atgep, ATGE_RX_MIB_BASE + i);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills i += sizeof (uint32_t);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Clear TX stats.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills i = 0;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = &smb.tx_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills while (reg++ <= &smb.tx_mcast_bytes) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (void) INL(atgep, ATGE_TX_MIB_BASE + i);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills i += sizeof (uint32_t);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_gather_stats(atge_t *atgep)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_data_t *l1c;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_dma_t *dma;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_smb_t *stat;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_smb_t *smb;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ASSERT(atgep != NULL);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c = atgep->atge_private_data;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills dma = l1c->atge_l1c_smb;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_SYNC(dma, 0, 0, DDI_DMA_SYNC_FORKERNEL);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat = (atge_l1c_smb_t *)atgep->atge_hw_stats;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills smb = (atge_l1c_smb_t *)dma->addr;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Rx stats. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_frames += smb->rx_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_bcast_frames += smb->rx_bcast_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_mcast_frames += smb->rx_mcast_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_pause_frames += smb->rx_pause_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_control_frames += smb->rx_control_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_crcerrs += smb->rx_crcerrs;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_lenerrs += smb->rx_lenerrs;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_bytes += smb->rx_bytes;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_runts += smb->rx_runts;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_fragments += smb->rx_fragments;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_pkts_64 += smb->rx_pkts_64;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_pkts_65_127 += smb->rx_pkts_65_127;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_pkts_128_255 += smb->rx_pkts_128_255;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_pkts_256_511 += smb->rx_pkts_256_511;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_pkts_512_1023 += smb->rx_pkts_512_1023;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_pkts_1024_1518 += smb->rx_pkts_1024_1518;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_pkts_1519_max += smb->rx_pkts_1519_max;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_pkts_truncated += smb->rx_pkts_truncated;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_fifo_oflows += smb->rx_fifo_oflows;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_alignerrs += smb->rx_alignerrs;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_bcast_bytes += smb->rx_bcast_bytes;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_mcast_bytes += smb->rx_mcast_bytes;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->rx_pkts_filtered += smb->rx_pkts_filtered;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Tx stats. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_frames += smb->tx_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_bcast_frames += smb->tx_bcast_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_mcast_frames += smb->tx_mcast_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_pause_frames += smb->tx_pause_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_excess_defer += smb->tx_excess_defer;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_control_frames += smb->tx_control_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_deferred += smb->tx_deferred;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_bytes += smb->tx_bytes;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_pkts_64 += smb->tx_pkts_64;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_pkts_65_127 += smb->tx_pkts_65_127;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_pkts_128_255 += smb->tx_pkts_128_255;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_pkts_256_511 += smb->tx_pkts_256_511;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_pkts_512_1023 += smb->tx_pkts_512_1023;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_pkts_1024_1518 += smb->tx_pkts_1024_1518;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_pkts_1519_max += smb->tx_pkts_1519_max;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_single_colls += smb->tx_single_colls;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_multi_colls += smb->tx_multi_colls;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_late_colls += smb->tx_late_colls;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_excess_colls += smb->tx_excess_colls;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_underrun += smb->tx_underrun;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_desc_underrun += smb->tx_desc_underrun;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_lenerrs += smb->tx_lenerrs;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_pkts_truncated += smb->tx_pkts_truncated;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_bcast_bytes += smb->tx_bcast_bytes;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills stat->tx_mcast_bytes += smb->tx_mcast_bytes;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Update global counters in atge_t.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_brdcstrcv += smb->rx_bcast_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_multircv += smb->rx_mcast_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_multixmt += smb->tx_mcast_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_brdcstxmt += smb->tx_bcast_frames;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_align_errors += smb->rx_alignerrs;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_fcs_errors += smb->rx_crcerrs;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_defer_xmts += smb->tx_deferred;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_first_collisions += smb->tx_single_colls;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_multi_collisions += smb->tx_multi_colls * 2;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_tx_late_collisions += smb->tx_late_colls;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_ex_collisions += smb->tx_excess_colls;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_toolong_errors += smb->rx_lenerrs;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_overflow += smb->rx_fifo_oflows;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_underflow += (smb->tx_underrun + smb->tx_desc_underrun);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_runt += smb->rx_runts;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_collisions += smb->tx_single_colls +
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills smb->tx_multi_colls * 2 + smb->tx_late_colls;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * tx_pkts_truncated counter looks suspicious. It constantly
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * increments with no sign of Tx errors. Hence we don't factor it.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_macxmt_errors += smb->tx_late_colls + smb->tx_underrun;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_macrcv_errors += smb->rx_crcerrs + smb->rx_lenerrs +
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills smb->rx_runts + smb->rx_pkts_truncated +
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills smb->rx_alignerrs;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills smb->updated = 0;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_SYNC(dma, 0, 0, DDI_DMA_SYNC_FORDEV);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_stop_tx_mac(atge_t *atgep)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills uint32_t reg;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills int t;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_DB(("%s: %s() called", atgep->atge_name, __func__));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = INL(atgep, ATGE_MAC_CFG);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if ((reg & ATGE_CFG_TX_ENB) != 0) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg &= ~ATGE_CFG_TX_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_MAC_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Stop TX DMA engine. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = INL(atgep, ATGE_DMA_CFG);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if ((reg & DMA_CFG_RD_ENB) != 0) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg &= ~DMA_CFG_RD_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_DMA_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills for (t = ATGE_RESET_TIMEOUT; t > 0; t--) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if ((INL(atgep, ATGE_IDLE_STATUS) &
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (IDLE_STATUS_TXMAC | IDLE_STATUS_DMARD)) == 0)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills drv_usecwait(10);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (t == 0) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* This should be an FMA event. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_error(atgep->atge_dip, "stopping TX DMA Engine timeout");
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_stop_rx_mac(atge_t *atgep)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills uint32_t reg;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills int t;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_DB(("%s: %s() called", atgep->atge_name, __func__));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = INL(atgep, ATGE_MAC_CFG);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if ((reg & ATGE_CFG_RX_ENB) != 0) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg &= ~ATGE_CFG_RX_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_MAC_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Stop RX DMA engine. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = INL(atgep, ATGE_DMA_CFG);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if ((reg & DMA_CFG_WR_ENB) != 0) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg &= ~DMA_CFG_WR_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_DMA_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills for (t = ATGE_RESET_TIMEOUT; t > 0; t--) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if ((INL(atgep, ATGE_IDLE_STATUS) &
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (IDLE_STATUS_RXMAC | IDLE_STATUS_DMAWR)) == 0)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills drv_usecwait(10);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (t == 0) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* This should be an FMA event. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_error(atgep->atge_dip, " stopping RX DMA Engine timeout");
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills/*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Receives (consumes) packets.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsstatic mblk_t *
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_rx(atge_t *atgep)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_data_t *l1c;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mblk_t *mp = NULL, *rx_head = NULL, *rx_tail = NULL;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c_rx_rdesc_t *rx_rr;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills uint32_t rdinfo, status, totlen, pktlen, slotlen;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills int nsegs, rx_cons = 0, cnt;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_dma_t *buf;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills uchar_t *bufp;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills int sync = 0;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c = atgep->atge_private_data;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ASSERT(l1c != NULL);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_SYNC(l1c->atge_l1c_rr, 0, 0, DDI_DMA_SYNC_FORKERNEL);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills for (;;) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rx_rr = (l1c_rx_rdesc_t *)(l1c->atge_l1c_rr->addr +
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (l1c->atge_l1c_rr_consumers * sizeof (l1c_rx_rdesc_t)));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rdinfo = ATGE_GET32(l1c->atge_l1c_rr, &rx_rr->rdinfo);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills status = ATGE_GET32(l1c->atge_l1c_rr, &rx_rr->status);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rx_cons = L1C_RRD_RD_IDX(rdinfo);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills nsegs = L1C_RRD_RD_CNT(rdinfo);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills totlen = L1C_RRD_BYTES(status);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_DB(("%s: %s() PKT -- rdinfo : 0x%x,"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills "status : 0x%x, totlen : %d,"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills " rx_cons : %d, nsegs : %d", atgep->atge_name, __func__,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rdinfo, status, totlen, rx_cons, nsegs));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if ((status & L1C_RRD_VALID) == 0) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if ((status & (L1C_RRD_ERR_CRC | L1C_RRD_ERR_ALIGN |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills L1C_RRD_ERR_TRUNC | L1C_RRD_ERR_RUNT |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills L1C_RRD_ERR_ICMP | L1C_RRD_ERR_LENGTH)) != 0) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_error(atgep->atge_dip, "errored pkt");
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_rx_ring->r_consumer += nsegs;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_rx_ring->r_consumer %= L1C_RX_RING_CNT;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ASSERT(rx_cons >= 0 && rx_cons <= L1C_RX_RING_CNT);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mp = allocb(totlen + L1C_HEADROOM, BPRI_MED);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (mp != NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mp->b_rptr += L1C_HEADROOM;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills bufp = mp->b_rptr;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mp->b_wptr = bufp + totlen;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mp->b_next = NULL;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_ipackets++;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_rbytes += totlen;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * If there are more than one segments, then the first
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * segment should be of size MTU. We couldn't verify
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * this as our driver does not support changing MTU
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * or Jumbo Frames.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (nsegs > 1) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills slotlen = atgep->atge_mtu;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills } else {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills slotlen = totlen;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills } else {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_DB(("%s: %s() PKT mp == NULL totlen : %d",
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_name, __func__, totlen));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (slotlen > atgep->atge_rx_buf_len) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_toolong_errors++;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills } else if (mp == NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_norcvbuf++;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rx_rr->status = 0;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills for (cnt = 0, pktlen = 0; cnt < nsegs; cnt++) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills buf = l1c->atge_rx_ring->r_buf_tbl[rx_cons];
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills slotlen = min(atgep->atge_max_frame_size, totlen);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills bcopy(buf->addr, (bufp + pktlen), slotlen);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills pktlen += slotlen;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills totlen -= slotlen;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_DB(("%s: %s() len : %d, rxcons : %d, pktlen : %d",
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_name, __func__, slotlen, rx_cons,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills pktlen));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_INC_SLOT(rx_cons, L1C_RX_RING_CNT);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (rx_tail == NULL) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rx_head = rx_tail = mp;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills } else {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rx_tail->b_next = mp;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rx_tail = mp;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (cnt != nsegs) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_rx_ring->r_consumer += nsegs;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_rx_ring->r_consumer %= L1C_RX_RING_CNT;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills } else {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_rx_ring->r_consumer = rx_cons;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Tell the chip that this RR can be reused.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rx_rr->status = 0;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_INC_SLOT(l1c->atge_l1c_rr_consumers, L1C_RR_RING_CNT);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills sync++;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (sync) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_SYNC(l1c->atge_rx_ring->r_desc_ring, 0, 0,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DDI_DMA_SYNC_FORDEV);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_SYNC(l1c->atge_l1c_rr, 0, 0, DDI_DMA_SYNC_FORDEV);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Let controller know availability of new Rx buffers.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_MBOX_RD0_PROD_IDX,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_rx_ring->r_consumer);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_DB(("%s: %s() PKT Recved -> r_consumer : %d, rx_cons : %d"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills " atge_l1c_rr_consumers : %d",
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_name, __func__, l1c->atge_rx_ring->r_consumer,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rx_cons, l1c->atge_l1c_rr_consumers));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills return (rx_head);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills/*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * The interrupt handler for L1C chip.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills/*ARGSUSED*/
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsuint_t
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_interrupt(caddr_t arg1, caddr_t arg2)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_t *atgep = (void *)arg1;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mblk_t *rx_head = NULL;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills uint32_t status;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills int resched = 0;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ASSERT(atgep != NULL);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mutex_enter(&atgep->atge_intr_lock);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (atgep->atge_chip_state & ATGE_CHIP_SUSPENDED) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mutex_exit(&atgep->atge_intr_lock);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills return (DDI_INTR_UNCLAIMED);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills status = INL(atgep, ATGE_INTR_STATUS);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (status == 0 || (status & atgep->atge_intrs) == 0) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mutex_exit(&atgep->atge_intr_lock);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (atgep->atge_flags & ATGE_FIXED_TYPE)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills return (DDI_INTR_UNCLAIMED);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills return (DDI_INTR_CLAIMED);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_DB(("%s: %s() entry status : %x",
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_name, __func__, status));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Disable interrupts.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (status & L1C_INTR_GPHY) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* clear PHY interrupt source before we ack interrupts */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (void) atge_mii_read(atgep,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_phyaddr, ATGE_ISR_ACK_GPHY);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_INTR_STATUS, status | L1C_INTR_DIS_INT);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills FLUSH(atgep, ATGE_INTR_STATUS);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Check if chip is running, only then do the work.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (atgep->atge_chip_state & ATGE_CHIP_RUNNING) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_data_t *l1c;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c = atgep->atge_private_data;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_DB(("%s: %s() atge_l1c_intr_status : %x, "
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills "atge_l1c_rx_prod_cons : %d, atge_l1c_tx_prod_cons : %d"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills " atge_l1c_rr_consumers : %d",
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_name, __func__, l1c->atge_l1c_intr_status,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_l1c_rx_prod_cons, l1c->atge_l1c_tx_prod_cons,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c->atge_l1c_rr_consumers));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (status & L1C_INTR_SMB)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_gather_stats(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Check for errors.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (status & (L1C_INTR_DMA_RD_TO_RST |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills L1C_INTR_DMA_WR_TO_RST | L1C_INTR_TXQ_TO_RST)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* This should be an FMA event. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_error(atgep->atge_dip,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills "L1C chip detected a fatal error, "
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills "interrupt status: %x", status);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (status & L1C_INTR_DMA_RD_TO_RST) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_error(atgep->atge_dip,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills "DMA read error");
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (status & L1C_INTR_DMA_WR_TO_RST) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_error(atgep->atge_dip,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills "DMA write error");
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (status & L1C_INTR_TXQ_TO_RST) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_error(atgep->atge_dip,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills "Transmit queue error");
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* This should be an FMA event. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_device_stop(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Device has failed fatally.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * It will not be restarted by the driver.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills goto done;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rx_head = atge_l1c_rx(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (status & L1C_INTR_TX_PKT) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills int cons;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mutex_enter(&atgep->atge_tx_lock);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills cons = INL(atgep, ATGE_MBOX_TD_CONS_IDX) >> 16;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_tx_reclaim(atgep, cons);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (atgep->atge_tx_resched) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_tx_resched = 0;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills resched = 1;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mutex_exit(&atgep->atge_tx_lock);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Re-enable interrupts. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_INTR_STATUS, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsdone:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mutex_exit(&atgep->atge_intr_lock);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (status & L1C_INTR_GPHY) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* link down */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_DB(("%s: %s() MII_CHECK Performed",
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_name, __func__));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mii_check(atgep->atge_mii);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Pass the list of packets received from chip to MAC layer.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (rx_head) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mac_rx(atgep->atge_mh, 0, rx_head);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Let MAC start sending pkts if the downstream was asked to pause.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (resched)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mac_tx_update(atgep->atge_mh);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills return (DDI_INTR_CLAIMED);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_l1c_send_packet(atge_ring_t *r)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_t *atgep;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep = r->r_atge;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mutex_enter(&atgep->atge_mbox_lock);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Sync descriptors. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_SYNC(atgep->atge_tx_ring->r_desc_ring, 0, 0, DDI_DMA_SYNC_FORDEV);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Kick. Assume we're using normal Tx priority queue. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_MBOX_TD_PROD_IDX,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (atgep->atge_tx_ring->r_producer << MBOX_TD_PROD_LO_IDX_SHIFT) &
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills MBOX_TD_PROD_LO_IDX_MASK);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mutex_exit(&atgep->atge_mbox_lock);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}