015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * CDDL HEADER START
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * The contents of this file are subject to the terms of the
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Common Development and Distribution License (the "License").
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * You may not use this file except in compliance with the License.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * or http://www.opensolaris.org/os/licensing.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * See the License for the specific language governing permissions
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * and limitations under the License.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * When distributing Covered Code, include this CDDL HEADER in each
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * If applicable, add the following below this CDDL HEADER, with the
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * fields enclosed by brackets "[]" replaced with your own identifying
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * information: Portions Copyright [yyyy] [name of copyright owner]
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * CDDL HEADER END
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Copyright (c) 2012 Gary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Use is subject to license terms.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/types.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/stream.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/strsun.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/stat.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/modctl.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/ethernet.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/debug.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/conf.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/mii.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/miiregs.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/sysmacros.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/dditypes.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/ddi.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/sunddi.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/byteorder.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/note.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/vlan.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/stream.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include "atge.h"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include "atge_l1e_reg.h"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include "atge_cmn_reg.h"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * L1E specfic functions.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_l1e_device_reset(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_l1e_stop_rx_mac(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_l1e_stop_tx_mac(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic ddi_dma_attr_t atge_l1e_dma_attr_tx_desc = {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DMA_ATTR_V0, /* dma_attr_version */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0, /* dma_attr_addr_lo */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000ffffffffull, /* dma_attr_addr_hi */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000ffffffffull, /* dma_attr_count_max */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra L1E_TX_RING_ALIGN, /* dma_attr_align */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000fffc, /* dma_attr_burstsizes */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 1, /* dma_attr_minxfer */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000ffffffffull, /* dma_attr_maxxfer */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000ffffffffull, /* dma_attr_seg */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 1, /* dma_attr_sgllen */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 1, /* dma_attr_granular */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0 /* dma_attr_flags */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra};
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic ddi_dma_attr_t atge_l1e_dma_attr_rx_desc = {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DMA_ATTR_V0, /* dma_attr_version */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0, /* dma_attr_addr_lo */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000ffffffffull, /* dma_attr_addr_hi */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000ffffffffull, /* dma_attr_count_max */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra L1E_RX_PAGE_ALIGN, /* dma_attr_align */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000fffc, /* dma_attr_burstsizes */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 1, /* dma_attr_minxfer */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000ffffffffull, /* dma_attr_maxxfer */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000ffffffffull, /* dma_attr_seg */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 1, /* dma_attr_sgllen */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 1, /* dma_attr_granular */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0 /* dma_attr_flags */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra};
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic ddi_dma_attr_t atge_l1e_dma_attr_cmb = {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DMA_ATTR_V0, /* dma_attr_version */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0, /* dma_attr_addr_lo */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000ffffffffull, /* dma_attr_addr_hi */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000ffffffffull, /* dma_attr_count_max */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra L1E_CMB_ALIGN, /* dma_attr_align */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000fffc, /* dma_attr_burstsizes */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 1, /* dma_attr_minxfer */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000ffffffffull, /* dma_attr_maxxfer */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000ffffffffull, /* dma_attr_seg */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 1, /* dma_attr_sgllen */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 1, /* dma_attr_granular */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0 /* dma_attr_flags */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra};
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_l1e_rx_next_pkt(atge_t *, uint32_t);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_rx_desc_free(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_data_t *l1e;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_dma_t *dma;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int pages;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e = (atge_l1e_data_t *)atgep->atge_private_data;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (l1e == NULL)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (l1e->atge_l1e_rx_page == NULL)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (pages = 0; pages < L1E_RX_PAGES; pages++) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma = l1e->atge_l1e_rx_page[pages];
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (dma != NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) ddi_dma_unbind_handle(dma->hdl);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ddi_dma_mem_free(&dma->acchdl);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ddi_dma_free_handle(&dma->hdl);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra kmem_free(dma, sizeof (atge_dma_t));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra kmem_free(l1e->atge_l1e_rx_page, L1E_RX_PAGES * sizeof (atge_dma_t *));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page = NULL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_l1e_alloc_dma(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_dma_t *dma;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_data_t *l1e;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int err;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int pages;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int guard_size;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e = kmem_zalloc(sizeof (atge_l1e_data_t), KM_SLEEP);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_private_data = l1e;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Allocate TX ring descriptor.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_tx_buf_len = atgep->atge_mtu +
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra sizeof (struct ether_header) + VLAN_TAGSZ + ETHERFCSL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_tx_ring = kmem_alloc(sizeof (atge_ring_t), KM_SLEEP);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_tx_ring->r_atge = atgep;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_tx_ring->r_desc_ring = NULL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma = atge_alloc_a_dma_blk(atgep, &atge_l1e_dma_attr_tx_desc,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ATGE_TX_RING_SZ, DDI_DMA_RDWR);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (dma == NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s :%s failed",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__));
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_tx_ring->r_desc_ring = dma;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Allocate DMA buffers for TX ring.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra err = atge_alloc_buffers(atgep->atge_tx_ring, ATGE_TX_RING_CNT,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_tx_buf_len, DDI_DMA_WRITE);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s :%s() TX buffers failed",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Allocate RX pages.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_rx_buf_len = atgep->atge_mtu +
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra sizeof (struct ether_header) + VLAN_TAGSZ + ETHERFCSL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_flags & ATGE_FLAG_JUMBO)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra guard_size = L1E_JUMBO_FRAMELEN;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra else
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra guard_size = L1E_MAX_FRAMELEN;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_pagesize = ROUNDUP(guard_size + L1E_RX_PAGE_SZ,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra L1E_RX_PAGE_ALIGN);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page =
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra kmem_zalloc(L1E_RX_PAGES * sizeof (atge_dma_t *), KM_SLEEP);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() atge_l1e_pagesize : %d, L1E_RX_PAGE_SZ : %d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, l1e->atge_l1e_pagesize,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra L1E_RX_PAGE_SZ));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra err = DDI_SUCCESS;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (pages = 0; pages < L1E_RX_PAGES; pages++) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma = atge_alloc_a_dma_blk(atgep, &atge_l1e_dma_attr_rx_desc,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_pagesize, DDI_DMA_READ);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (dma == NULL) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra err = DDI_FAILURE;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page[pages] = dma;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (err == DDI_FAILURE) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s :%s RX pages failed",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__));
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Allocate CMB used for fetching interrupt status data.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() L1E_RX_CMB_SZ : %x", atgep->atge_name,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra __func__, L1E_RX_CMB_SZ));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra err = DDI_SUCCESS;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma = atge_alloc_a_dma_blk(atgep, &atge_l1e_dma_attr_cmb,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra L1E_RX_CMB_SZ * L1E_RX_PAGES, DDI_DMA_RDWR);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (dma == NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s :%s() RX CMB failed",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__));
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_cmb = dma;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (err == DDI_FAILURE) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s :%s() RX CMB failed",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__));
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_hw_stats = kmem_zalloc(sizeof (atge_l1e_smb_t), KM_SLEEP);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_SUCCESS);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_l1e_free_dma(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_data_t *l1e;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Free TX ring.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_tx_ring != NULL) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_free_buffers(atgep->atge_tx_ring, ATGE_TX_RING_CNT);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_tx_ring->r_desc_ring != NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_free_a_dma_blk(atgep->atge_tx_ring->r_desc_ring);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra kmem_free(atgep->atge_tx_ring, sizeof (atge_ring_t));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_tx_ring = NULL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e = atgep->atge_private_data;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (l1e == NULL)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Free RX CMB.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (l1e->atge_l1e_rx_cmb != NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_free_a_dma_blk(l1e->atge_l1e_rx_cmb);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_cmb = NULL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Free RX buffers and RX ring.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_rx_desc_free(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Free the memory allocated for gathering hw stats.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_hw_stats != NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra kmem_free(atgep->atge_hw_stats, sizeof (atge_l1e_smb_t));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_hw_stats = NULL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_l1e_init_rx_pages(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_data_t *l1e;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_dma_t *dma;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int pages;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(atgep != NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e = atgep->atge_private_data;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(l1e != NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_proc_max = L1E_RX_PAGE_SZ / ETHERMIN;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_curp = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_seqno = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (pages = 0; pages < L1E_RX_PAGES; pages++) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_cons = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_prods[pages] = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma = l1e->atge_l1e_rx_page[pages];
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(dma != NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra bzero(dma->addr, l1e->atge_l1e_pagesize);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DMA_SYNC(dma, 0, l1e->atge_l1e_pagesize, DDI_DMA_SYNC_FORDEV);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma = l1e->atge_l1e_rx_cmb;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(dma != NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra bzero(dma->addr, L1E_RX_CMB_SZ * L1E_RX_PAGES);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DMA_SYNC(dma, 0, L1E_RX_CMB_SZ * L1E_RX_PAGES, DDI_DMA_SYNC_FORDEV);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_l1e_init_tx_ring(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(atgep != NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(atgep->atge_tx_ring != NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(atgep->atge_tx_ring->r_desc_ring != NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_tx_ring->r_producer = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_tx_ring->r_consumer = 0;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atgep->atge_tx_ring->r_avail_desc = ATGE_TX_RING_CNT;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra bzero(atgep->atge_tx_ring->r_desc_ring->addr, ATGE_TX_RING_SZ);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra DMA_SYNC(atgep->atge_tx_ring->r_desc_ring, 0, ATGE_TX_RING_SZ,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_DMA_SYNC_FORDEV);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_l1e_program_dma(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_data_t *l1e;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint64_t paddr;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t reg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e = (atge_l1e_data_t *)atgep->atge_private_data;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Clear WOL status and disable all WOL feature as WOL
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * would interfere Rx operation under normal environments.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) INL(atgep, ATGE_WOL_CFG);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_WOL_CFG, 0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Set Tx descriptor/RXF0/CMB base addresses. They share
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * the same high address part of DMAable region.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra paddr = atgep->atge_tx_ring->r_desc_ring->cookie.dmac_laddress;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_DESC_ADDR_HI, ATGE_ADDR_HI(paddr));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_DESC_TPD_ADDR_LO, ATGE_ADDR_LO(paddr));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_DESC_TPD_CNT,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra (ATGE_TX_RING_CNT << DESC_TPD_CNT_SHIFT) & DESC_TPD_CNT_MASK);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* Set Rx page base address, note we use single queue. */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra paddr = l1e->atge_l1e_rx_page[0]->cookie.dmac_laddress;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, L1E_RXF0_PAGE0_ADDR_LO, ATGE_ADDR_LO(paddr));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra paddr = l1e->atge_l1e_rx_page[1]->cookie.dmac_laddress;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, L1E_RXF0_PAGE1_ADDR_LO, ATGE_ADDR_LO(paddr));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* Set Tx/Rx CMB addresses. */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra paddr = l1e->atge_l1e_rx_cmb->cookie.dmac_laddress;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, L1E_RXF0_CMB0_ADDR_LO, ATGE_ADDR_LO(paddr));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra paddr = l1e->atge_l1e_rx_cmb->cookie.dmac_laddress + sizeof (uint32_t);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, L1E_RXF0_CMB1_ADDR_LO, ATGE_ADDR_LO(paddr));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* Mark RXF0 valid. */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTB(atgep, L1E_RXF0_PAGE0, RXF_VALID); /* 0 */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTB(atgep, L1E_RXF0_PAGE1, RXF_VALID); /* 1 */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTB(atgep, L1E_RXF0_PAGE0 + 2, 0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTB(atgep, L1E_RXF0_PAGE0 + 3, 0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTB(atgep, L1E_RXF0_PAGE0 + 4, 0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTB(atgep, L1E_RXF0_PAGE0 + 5, 0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTB(atgep, L1E_RXF0_PAGE0 + 6, 0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTB(atgep, L1E_RXF0_PAGE0 + 6, 0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* Set Rx page size, excluding guard frame size. */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, L1E_RXF_PAGE_SIZE, L1E_RX_PAGE_SZ);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* Tell hardware that we're ready to load DMA blocks. */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_DMA_BLOCK, DMA_BLOCK_LOAD);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* Set Rx/Tx interrupt trigger threshold. */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, L1E_INT_TRIG_THRESH, (1 << INT_TRIG_RX_THRESH_SHIFT) |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (4 << INT_TRIG_TX_THRESH_SHIFT));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Set interrupt trigger timer, its purpose and relation
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * with interrupt moderation mechanism is not clear yet.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, L1E_INT_TRIG_TIMER,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ((ATGE_USECS(10) << INT_TRIG_RX_TIMER_SHIFT) |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (ATGE_USECS(1000) << INT_TRIG_TX_TIMER_SHIFT)));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = ATGE_USECS(ATGE_IM_RX_TIMER_DEFAULT) << IM_TIMER_RX_SHIFT;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg |= ATGE_USECS(ATGE_IM_TX_TIMER_DEFAULT) << IM_TIMER_TX_SHIFT;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_IM_TIMER, reg);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = INL(atgep, ATGE_MASTER_CFG);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg &= ~(L1E_MASTER_CHIP_REV_MASK | L1E_MASTER_CHIP_ID_MASK);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg &= ~(L1E_MASTER_IM_RX_TIMER_ENB | L1E_MASTER_IM_TX_TIMER_ENB);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg |= L1E_MASTER_IM_RX_TIMER_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg |= L1E_MASTER_IM_TX_TIMER_ENB;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_MASTER_CFG, reg);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTW(atgep, RX_COALSC_PKT_1e, 0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTW(atgep, RX_COALSC_TO_1e, 0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTW(atgep, TX_COALSC_PKT_1e, 1);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTW(atgep, TX_COALSC_TO_1e, 4000/2); /* 4mS */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misramblk_t *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_l1e_receive(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_data_t *l1e;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_dma_t *dma_rx_page;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_dma_t *dma_rx_cmb;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t *ptr;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t cons, current_page;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uchar_t *pageaddr, *bufp;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra rx_rs_t *rs;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int prog;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t seqno, len, flags;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mblk_t *mp = NULL, *rx_head, *rx_tail;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra static uint32_t gen = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e = atgep->atge_private_data;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(MUTEX_HELD(&atgep->atge_intr_lock));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(l1e != NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra rx_tail = NULL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra rx_head = NULL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra current_page = l1e->atge_l1e_rx_curp;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* Sync CMB first */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma_rx_cmb = l1e->atge_l1e_rx_cmb;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DMA_SYNC(dma_rx_cmb, 0, L1E_RX_CMB_SZ * L1E_RX_PAGES,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_DMA_SYNC_FORKERNEL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma_rx_page = l1e->atge_l1e_rx_page[current_page];
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Get the producer offset from CMB.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ptr = (void *)dma_rx_cmb->addr;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_prods[current_page] =
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_GET32(dma_rx_cmb, ptr + current_page);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* Sync current RX Page as well */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DMA_SYNC(dma_rx_page, l1e->atge_l1e_rx_page_cons,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_prods[current_page], DDI_DMA_SYNC_FORKERNEL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() prod : %d, cons : %d, curr page : %d, gen : (%d)"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " cmb[0,1] : %d, %d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_prods[current_page],
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_cons, l1e->atge_l1e_rx_curp, gen,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_GET32(dma_rx_cmb, ptr), ATGE_GET32(dma_rx_cmb, ptr + 1)));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (prog = 0; prog <= l1e->atge_l1e_proc_max; prog++) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra cons = l1e->atge_l1e_rx_page_cons;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (cons >= l1e->atge_l1e_rx_page_prods[l1e->atge_l1e_rx_curp])
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma_rx_page = l1e->atge_l1e_rx_page[l1e->atge_l1e_rx_curp];
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra pageaddr = (uchar_t *)dma_rx_page->addr;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra pageaddr = pageaddr + cons;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra rs = (rx_rs_t *)pageaddr;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra seqno = ATGE_GET32(dma_rx_page, &(rs->seqno));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra seqno = L1E_RX_SEQNO(seqno);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra len = ATGE_GET32(dma_rx_page, &(rs->length));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra len = L1E_RX_BYTES(len);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra flags = ATGE_GET32(dma_rx_page, &(rs->flags));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (seqno != l1e->atge_l1e_rx_seqno) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * We have not seen this happening but we
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * must restart the chip if that happens.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() MISS-MATCH in seqno :%d,"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " atge_l1e_rx_seqno : %d, length : %d, flags : %x",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, seqno,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_seqno, len, flags));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_restart(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Return all the pkts received before restarting
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * the chip.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (rx_head);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra } else {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_seqno++;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * We will pass the pkt to upper layer provided it's clear
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * from any error.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((flags & L1E_RD_ERROR) != 0) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((flags & (L1E_RD_CRC | L1E_RD_CODE |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra L1E_RD_DRIBBLE | L1E_RD_RUNT | L1E_RD_OFLOW |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra L1E_RD_TRUNC)) != 0) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() ERRORED PKT : %x",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, flags));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_rx_next_pkt(atgep, len);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_errrcv++;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra continue;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * So we have received a frame/pkt.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (len == 0 || len > atgep->atge_rx_buf_len) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() PKT len > error : %d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, len));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_rx_next_pkt(atgep, len);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra continue;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mp = allocb(len + VLAN_TAGSZ, BPRI_MED);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (mp != NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mp->b_rptr += VLAN_TAGSZ;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra bufp = mp->b_rptr;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mp->b_wptr = bufp + len;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mp->b_next = NULL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra bcopy(pageaddr + sizeof (rx_rs_t), bufp, len);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (rx_tail == NULL)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra rx_head = rx_tail = mp;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra else {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra rx_tail->b_next = mp;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra rx_tail = mp;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_ipackets++;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_rbytes += len;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra } else {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() PKT mp == NULL len : %d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, len));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (len > atgep->atge_rx_buf_len) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_toolong_errors++;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra } else if (mp == NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_norcvbuf++;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_rx_next_pkt(atgep, len);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() seqno :%d, atge_l1e_rx_seqno :"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " %d, length : %d,"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " flags : %x, cons : %d, prod : %d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, seqno,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_seqno, len, flags,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_cons,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_prods[l1e->atge_l1e_rx_curp]));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() receive completed (gen : %d) : cons : %d,"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " prod :%d, L1E_RX_PAGE_SZ : %d (prog:%d)",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, gen,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_cons,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_prods[l1e->atge_l1e_rx_curp],
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra L1E_RX_PAGE_SZ, prog));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra gen++;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (rx_head);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_l1e_rx_next_pkt(atge_t *atgep, uint32_t len)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_data_t *l1e = atgep->atge_private_data;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_dma_t *dma_rx_page;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_dma_t *dma_rx_cmb;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int curr = l1e->atge_l1e_rx_curp;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t *p;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Update consumer position.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_cons +=
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ROUNDUP(len + sizeof (rx_rs_t), L1E_RX_PAGE_ALIGN);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * If we need to flip to the other page. Note that we use only two
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * pages.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (l1e->atge_l1e_rx_page_cons >= L1E_RX_PAGE_SZ) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() cons : %d, prod :%d, L1E_RX_PAGE_SZ : %d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, l1e->atge_l1e_rx_page_cons,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_prods[curr], L1E_RX_PAGE_SZ));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Clear the producer.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma_rx_cmb = l1e->atge_l1e_rx_cmb;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra p = (void *)dma_rx_cmb->addr;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra p = p + curr;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *p = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DMA_SYNC(dma_rx_cmb, curr * L1E_RX_CMB_SZ,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra L1E_RX_CMB_SZ, DDI_DMA_SYNC_FORDEV);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Notify the NIC that the current RX page is available again.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTB(atgep, L1E_RXF0_PAGE0 + curr, RXF_VALID);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * End of Rx page reached, let hardware reuse this page.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_cons = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_prods[curr] = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Switch to alternate Rx page.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra curr ^= 1;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_curp = curr;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Page flipped, sync CMB and then Rx page.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DMA_SYNC(dma_rx_cmb, 0, L1E_RX_PAGES * L1E_RX_CMB_SZ,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_DMA_SYNC_FORKERNEL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra p = (void *)dma_rx_cmb->addr;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra l1e->atge_l1e_rx_page_prods[curr] =
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_GET32(dma_rx_cmb, p + curr);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma_rx_page = l1e->atge_l1e_rx_page[curr];
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DMA_SYNC(dma_rx_page, 0, l1e->atge_l1e_rx_page_prods[curr],
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_DMA_SYNC_FORKERNEL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() PAGE FLIPPED -> %d, producer[0,1]: %d, %d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, curr,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_GET32(dma_rx_cmb, p), ATGE_GET32(dma_rx_cmb, p + 1)));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misraatge_l1e_send_packet(atge_ring_t *r)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Ask chip to send the packet now.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(r->r_atge, ATGE_MBOX, r->r_producer);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_l1e_clear_stats(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_smb_t smb;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t *reg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int i;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Clear RX stats first.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra i = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = &smb.rx_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra while (reg++ <= &smb.rx_pkts_filtered) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) INL(atgep, L1E_RX_MIB_BASE + i);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra i += sizeof (uint32_t);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Clear TX stats.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra i = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = &smb.tx_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra while (reg++ <= &smb.tx_mcast_bytes) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) INL(atgep, L1E_TX_MIB_BASE + i);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra i += sizeof (uint32_t);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_l1e_gather_stats(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_smb_t *stat;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_smb_t *smb;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_smb_t local_smb;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t *reg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int i;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(atgep != NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat = (atge_l1e_smb_t *)atgep->atge_hw_stats;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra bzero(&local_smb, sizeof (atge_l1e_smb_t));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra smb = &local_smb;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* Read Rx statistics. */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra i = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = &smb->rx_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra while (reg++ <= &smb->rx_pkts_filtered) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *reg = INL(atgep, L1E_RX_MIB_BASE + i);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra i += sizeof (uint32_t);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* Read Tx statistics. */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra i = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = &smb->tx_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra while (reg++ <= &smb->tx_mcast_bytes) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *reg = INL(atgep, L1E_TX_MIB_BASE + i);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra i += sizeof (uint32_t);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * SMB is cleared everytime we read; hence we always do '+='.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* Rx stats. */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_frames += smb->rx_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_bcast_frames += smb->rx_bcast_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_mcast_frames += smb->rx_mcast_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_pause_frames += smb->rx_pause_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_control_frames += smb->rx_control_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_crcerrs += smb->rx_crcerrs;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_lenerrs += smb->rx_lenerrs;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_bytes += smb->rx_bytes;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_runts += smb->rx_runts;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_fragments += smb->rx_fragments;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_pkts_64 += smb->rx_pkts_64;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_pkts_65_127 += smb->rx_pkts_65_127;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_pkts_128_255 += smb->rx_pkts_128_255;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_pkts_256_511 += smb->rx_pkts_256_511;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_pkts_512_1023 += smb->rx_pkts_512_1023;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_pkts_1024_1518 += smb->rx_pkts_1024_1518;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_pkts_1519_max += smb->rx_pkts_1519_max;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_pkts_truncated += smb->rx_pkts_truncated;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_fifo_oflows += smb->rx_fifo_oflows;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_rrs_errs += smb->rx_rrs_errs;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_alignerrs += smb->rx_alignerrs;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_bcast_bytes += smb->rx_bcast_bytes;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_mcast_bytes += smb->rx_mcast_bytes;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->rx_pkts_filtered += smb->rx_pkts_filtered;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* Tx stats. */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_frames += smb->tx_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_bcast_frames += smb->tx_bcast_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_mcast_frames += smb->tx_mcast_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_pause_frames += smb->tx_pause_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_excess_defer += smb->tx_excess_defer;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_control_frames += smb->tx_control_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_deferred += smb->tx_deferred;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_bytes += smb->tx_bytes;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_pkts_64 += smb->tx_pkts_64;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_pkts_65_127 += smb->tx_pkts_65_127;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_pkts_128_255 += smb->tx_pkts_128_255;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_pkts_256_511 += smb->tx_pkts_256_511;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_pkts_512_1023 += smb->tx_pkts_512_1023;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_pkts_1024_1518 += smb->tx_pkts_1024_1518;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_pkts_1519_max += smb->tx_pkts_1519_max;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_single_colls += smb->tx_single_colls;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_multi_colls += smb->tx_multi_colls;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_late_colls += smb->tx_late_colls;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_excess_colls += smb->tx_excess_colls;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_abort += smb->tx_abort;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_underrun += smb->tx_underrun;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_desc_underrun += smb->tx_desc_underrun;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_lenerrs += smb->tx_lenerrs;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_pkts_truncated += smb->tx_pkts_truncated;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_bcast_bytes += smb->tx_bcast_bytes;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra stat->tx_mcast_bytes += smb->tx_mcast_bytes;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Update global counters in atge_t.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_brdcstrcv += smb->rx_bcast_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_multircv += smb->rx_mcast_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_multixmt += smb->tx_mcast_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_brdcstxmt += smb->tx_bcast_frames;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_align_errors += smb->rx_alignerrs;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_fcs_errors += smb->rx_crcerrs;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_sqe_errors += smb->rx_rrs_errs;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_defer_xmts += smb->tx_deferred;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_first_collisions += smb->tx_single_colls;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_multi_collisions += smb->tx_multi_colls * 2;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_tx_late_collisions += smb->tx_late_colls;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_ex_collisions += smb->tx_excess_colls;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_macxmt_errors += smb->tx_abort;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_toolong_errors += smb->rx_lenerrs;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_overflow += smb->rx_fifo_oflows;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_underflow += (smb->tx_underrun + smb->tx_desc_underrun);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_runt += smb->rx_runts;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_collisions += smb->tx_single_colls +
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra smb->tx_multi_colls * 2 + smb->tx_late_colls +
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra smb->tx_abort * HDPX_CFG_RETRY_DEFAULT;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * tx_pkts_truncated counter looks suspicious. It constantly
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * increments with no sign of Tx errors. Hence we don't factor it.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_macxmt_errors += smb->tx_abort + smb->tx_late_colls +
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra smb->tx_underrun;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_macrcv_errors += smb->rx_crcerrs + smb->rx_lenerrs +
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra smb->rx_runts + smb->rx_pkts_truncated +
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra smb->rx_fifo_oflows + smb->rx_rrs_errs +
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra smb->rx_alignerrs;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_l1e_stop_mac(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t reg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = INL(atgep, ATGE_MAC_CFG);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() reg : %x", atgep->atge_name, __func__, reg));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((reg & (ATGE_CFG_TX_ENB | ATGE_CFG_RX_ENB)) != 0) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg &= ~ATGE_CFG_TX_ENB | ATGE_CFG_RX_ENB;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_MAC_CFG, reg);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() mac stopped", atgep->atge_name, __func__));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra/*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * The interrupt handler for L1E/L2E
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra/*ARGSUSED*/
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misrauint_t
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misraatge_l1e_interrupt(caddr_t arg1, caddr_t arg2)
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra{
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_t *atgep = (void *)arg1;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mblk_t *rx_head = NULL;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra uint32_t status;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra int resched = 0;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ASSERT(atgep != NULL);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mutex_enter(&atgep->atge_intr_lock);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (atgep->atge_chip_state & ATGE_CHIP_SUSPENDED) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mutex_exit(&atgep->atge_intr_lock);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_INTR_UNCLAIMED);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra status = INL(atgep, ATGE_INTR_STATUS);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (status == 0 || (status & atgep->atge_intrs) == 0) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mutex_exit(&atgep->atge_intr_lock);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (atgep->atge_flags & ATGE_FIXED_TYPE)
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_INTR_UNCLAIMED);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_INTR_CLAIMED);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ATGE_DB(("%s: %s() entry status : %x",
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atgep->atge_name, __func__, status));
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * Disable interrupts.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra OUTL(atgep, ATGE_INTR_STATUS, status | INTR_DIS_INT);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra FLUSH(atgep, ATGE_INTR_STATUS);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * Check if chip is running, only then do the work.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (atgep->atge_chip_state & ATGE_CHIP_RUNNING) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (status & INTR_SMB) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1e_gather_stats(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * Check for errors.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (status & L1E_INTR_ERRORS) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_error(atgep->atge_dip,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra "L1E chip found an error intr status : %x",
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra status);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (status &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra (INTR_DMA_RD_TO_RST | INTR_DMA_WR_TO_RST)) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_error(atgep->atge_dip, "DMA transfer err");
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_device_stop(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra goto done;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (status & INTR_TX_FIFO_UNDERRUN) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_error(atgep->atge_dip, "TX FIFO underrun");
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra rx_head = atge_l1e_receive(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (status & INTR_TX_PKT) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra int cons;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mutex_enter(&atgep->atge_tx_lock);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra cons = INW(atgep, L1E_TPD_CONS_IDX);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_tx_reclaim(atgep, cons);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (atgep->atge_tx_resched) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atgep->atge_tx_resched = 0;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra resched = 1;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mutex_exit(&atgep->atge_tx_lock);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * Enable interrupts.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra OUTL(atgep, ATGE_INTR_STATUS, 0);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misradone:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mutex_exit(&atgep->atge_intr_lock);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (status & INTR_GPHY) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * Ack interrupts from PHY
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra (void) atge_mii_read(atgep,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atgep->atge_phyaddr, ATGE_ISR_ACK_GPHY);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mii_check(atgep->atge_mii);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * Pass the list of packets received from chip to MAC layer.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (rx_head) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mac_rx(atgep->atge_mh, 0, rx_head);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * Let MAC start sending pkts if the downstream was asked to pause.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (resched)
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mac_tx_update(atgep->atge_mh);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_INTR_CLAIMED);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra}