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 *
9d8d9e1151895fac86a2e3216647dd2a020ecf71Garrett D'Amore * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
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 */
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/kstat.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/ethernet.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/devops.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/mac.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/mac_provider.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/mac_ether.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/strsubr.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/crc32.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/sdt.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/pci.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include <sys/pci_cap.h>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include "atge.h"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include "atge_cmn_reg.h"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#include "atge_l1c_reg.h"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#include "atge_l1e_reg.h"
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra#include "atge_l1_reg.h"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Atheros/Attansic Ethernet chips are of four types - L1, L2, L1E and L1C.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * This driver is for L1E/L1/L1C but can be extended to support other chips.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * L1E comes in 1Gigabit and Fast Ethernet flavors. L1 comes in 1Gigabit
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * flavors only. L1C comes in both flavours.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Atheros/Attansic Ethernet controllers have descriptor based TX and RX
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * with an exception of L1E. L1E's RX side is not descriptor based ring.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * The L1E's RX uses pages (not to be confused with MMU pages) for
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * receiving pkts. The header has four fields :
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * uint32_t seqno; Sequence number of the frame.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * uint32_t length; Length of the frame.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * uint32_t flags; Flags
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * uint32_t vtag; We don't use hardware VTAG.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * We use only one queue for RX (each queue can have two pages) and each
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * page is L1E_RX_PAGE_SZ large in bytes. That's the reason we don't
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * use zero-copy RX because we are limited to two pages and each page
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * accomodates large number of pkts.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * The TX side on all three chips is descriptor based ring; and all the
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * more reason to have one driver for these chips.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * We use two locks - atge_intr_lock and atge_tx_lock. Both the locks
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * should be held if the operation has impact on the driver instance.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * All the three chips have hash-based multicast filter.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * We use CMB (Coalescing Message Block) for RX but not for TX as there
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * are some issues with TX. RX CMB is used to get the last descriptor
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * posted by the chip. Each CMB is for a RX page (one queue can have two
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * pages) and are uint32_t (4 bytes) long.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * The descriptor table should have 32-bit physical address limit due to
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * the limitation of having same high address for TX/RX/SMB/CMB. The
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * TX/RX buffers can be 64-bit.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Every DMA memory in atge is represented by atge_dma_t be it TX/RX Buffers
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * or TX/RX descriptor table or SMB/CMB. To keep the code simple, we have
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * kept sgl as 1 so that we get contingous pages from root complex.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra *
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * L1 chip (0x1048) uses descriptor based TX and RX ring. Most of registers are
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * common with L1E chip (0x1026).
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Function Prototypes for debugging.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_error(dev_info_t *, char *, ...);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_debug_func(char *, ...);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Function Prototypes for driver operations.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int atge_resume(dev_info_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int atge_add_intr(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int atge_alloc_dma(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic void atge_remove_intr(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic void atge_free_dma(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic void atge_device_reset(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic void atge_device_init(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic void atge_device_start(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic void atge_disable_intrs(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_dma_t *atge_alloc_a_dma_blk(atge_t *, ddi_dma_attr_t *, int, int);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_free_a_dma_blk(atge_dma_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic void atge_rxfilter(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic void atge_device_reset_l1_l1e(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_program_ether(atge_t *atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_device_restart(atge_t *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misravoid atge_device_stop(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int atge_send_a_packet(atge_t *, mblk_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic uint32_t atge_ether_crc(const uint8_t *, int);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * L1E/L2E specific functions.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_l1e_device_reset(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_l1e_stop_mac(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint atge_l1e_alloc_dma(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_l1e_free_dma(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_l1e_init_tx_ring(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_l1e_init_rx_pages(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_l1e_program_dma(atge_t *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misravoid atge_l1e_send_packet(atge_ring_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misramblk_t *atge_l1e_receive(atge_t *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misrauint_t atge_l1e_interrupt(caddr_t, caddr_t);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_l1e_gather_stats(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_l1e_clear_stats(atge_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra/*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * L1 specific functions.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misraint atge_l1_alloc_dma(atge_t *);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1_free_dma(atge_t *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misravoid atge_l1_init_tx_ring(atge_t *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misravoid atge_l1_init_rx_ring(atge_t *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misravoid atge_l1_init_rr_ring(atge_t *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misravoid atge_l1_init_cmb(atge_t *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misravoid atge_l1_init_smb(atge_t *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misravoid atge_l1_program_dma(atge_t *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misravoid atge_l1_stop_tx_mac(atge_t *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misravoid atge_l1_stop_rx_mac(atge_t *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misrauint_t atge_l1_interrupt(caddr_t, caddr_t);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misravoid atge_l1_send_packet(atge_ring_t *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills/*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * L1C specific functions.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsint atge_l1c_alloc_dma(atge_t *);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1c_free_dma(atge_t *);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1c_init_tx_ring(atge_t *);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1c_init_rx_ring(atge_t *);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1c_init_rr_ring(atge_t *);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1c_init_cmb(atge_t *);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1c_init_smb(atge_t *);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1c_program_dma(atge_t *);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1c_stop_tx_mac(atge_t *);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1c_stop_rx_mac(atge_t *);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsuint_t atge_l1c_interrupt(caddr_t, caddr_t);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1c_send_packet(atge_ring_t *);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1c_gather_stats(atge_t *);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1c_clear_stats(atge_t *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Function prototyps for MII operations.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrauint16_t atge_mii_read(void *, uint8_t, uint8_t);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_mii_write(void *, uint8_t, uint8_t, uint16_t);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsuint16_t atge_l1c_mii_read(void *, uint8_t, uint8_t);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1c_mii_write(void *, uint8_t, uint8_t, uint16_t);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid atge_l1e_mii_reset(void *);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misravoid atge_l1_mii_reset(void *);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid atge_l1c_mii_reset(void *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic void atge_mii_notify(void *, link_state_t);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misravoid atge_tx_reclaim(atge_t *atgep, int cons);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra/*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * L1E/L2E chip.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic mii_ops_t atge_l1e_mii_ops = {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra MII_OPS_VERSION,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_mii_read,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_mii_write,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_mii_notify,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_mii_reset
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra};
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra/*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * L1 chip.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misrastatic mii_ops_t atge_l1_mii_ops = {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra MII_OPS_VERSION,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_mii_read,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_mii_write,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_mii_notify,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1_mii_reset
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra};
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills/*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * L1C chip.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsstatic mii_ops_t atge_l1c_mii_ops = {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills MII_OPS_VERSION,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_mii_read,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_mii_write,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_mii_notify,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills NULL
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills};
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Function Prototypes for MAC callbacks.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int atge_m_stat(void *, uint_t, uint64_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int atge_m_start(void *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic void atge_m_stop(void *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int atge_m_getprop(void *, const char *, mac_prop_id_t, uint_t,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer void *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int atge_m_setprop(void *, const char *, mac_prop_id_t, uint_t,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra const void *);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyerstatic void atge_m_propinfo(void *, const char *, mac_prop_id_t,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_prop_info_handle_t);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int atge_m_unicst(void *, const uint8_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int atge_m_multicst(void *, boolean_t, const uint8_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int atge_m_promisc(void *, boolean_t);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic mblk_t *atge_m_tx(void *, mblk_t *);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic mac_callbacks_t atge_m_callbacks = {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer MC_SETPROP | MC_GETPROP | MC_PROPINFO,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_m_stat,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_m_start,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_m_stop,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_m_promisc,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_m_multicst,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_m_unicst,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_m_tx,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer NULL, /* mc_reserved */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra NULL, /* mc_ioctl */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra NULL, /* mc_getcapab */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra NULL, /* mc_open */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra NULL, /* mc_close */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_m_setprop,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_m_getprop,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer atge_m_propinfo
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra};
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * DMA Data access requirements.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic struct ddi_device_acc_attr atge_dev_attr = {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_DEVICE_ATTR_V0,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_STRUCTURE_LE_ACC,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_STRICTORDER_ACC
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra};
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Buffers should be native endianness.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic struct ddi_device_acc_attr atge_buf_attr = {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_DEVICE_ATTR_V0,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_NEVERSWAP_ACC, /* native endianness */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_STRICTORDER_ACC
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra};
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * DMA device attributes. Buffer can be 64-bit.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic ddi_dma_attr_t atge_dma_attr_buf = {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DMA_ATTR_V0, /* dma_attr_version */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0, /* dma_attr_addr_lo */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x00ffffffffffull, /* dma_attr_addr_hi */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x000000003fffull, /* dma_attr_count_max */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 8, /* dma_attr_align */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x00003ffc, /* dma_attr_burstsizes */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 1, /* dma_attr_minxfer */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra 0x0000000027ffull, /* 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 Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Table of supported devices.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#define ATGE_VENDOR_ID 0x1969
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#define ATGE_L1_STR "Attansic L1"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#define ATGE_L1CG_STR "Atheros AR8131 Gigabit Ethernet"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#define ATGE_L1CF_STR "Atheros AR8132 Fast Ethernet"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#define ATGE_L1E_STR "Atheros AR8121/8113/8114"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#define ATGE_AR8151V1_STR "Atheros AR8151 v1.0 Gigabit Ethernet"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#define ATGE_AR8151V2_STR "Atheros AR8151 v2.0 Gigabit Ethernet"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#define ATGE_AR8152V1_STR "Atheros AR8152 v1.1 Fast Ethernet"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills#define ATGE_AR8152V2_STR "Atheros AR8152 v2.0 Fast Ethernet"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic atge_cards_t atge_cards[] = {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills {ATGE_VENDOR_ID, ATGE_CHIP_AR8151V2_DEV_ID, ATGE_AR8151V2_STR,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_CHIP_L1C},
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills {ATGE_VENDOR_ID, ATGE_CHIP_AR8151V1_DEV_ID, ATGE_AR8151V1_STR,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_CHIP_L1C},
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills {ATGE_VENDOR_ID, ATGE_CHIP_AR8152V2_DEV_ID, ATGE_AR8152V2_STR,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_CHIP_L1C},
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills {ATGE_VENDOR_ID, ATGE_CHIP_AR8152V1_DEV_ID, ATGE_AR8152V1_STR,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_CHIP_L1C},
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills {ATGE_VENDOR_ID, ATGE_CHIP_L1CG_DEV_ID, ATGE_L1CG_STR, ATGE_CHIP_L1C},
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills {ATGE_VENDOR_ID, ATGE_CHIP_L1CF_DEV_ID, ATGE_L1CF_STR, ATGE_CHIP_L1C},
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra {ATGE_VENDOR_ID, ATGE_CHIP_L1E_DEV_ID, ATGE_L1E_STR, ATGE_CHIP_L1E},
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills {ATGE_VENDOR_ID, ATGE_CHIP_L1_DEV_ID, ATGE_L1_STR, ATGE_CHIP_L1},
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra};
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Global Debugging flag. Developer level debugging is done only in DEBUG mode.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint atge_debug = 1;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Debugging and error reporting.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_debug_func(char *fmt, ...)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra va_list ap;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra char buf[256];
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra va_start(ap, fmt);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) vsnprintf(buf, sizeof (buf), fmt, ap);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra va_end(ap);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DTRACE_PROBE1(atge__debug, char *, buf);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsstatic
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_message(dev_info_t *dip, int level, char *fmt, va_list ap)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra char buf[256];
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills char *p = "!%s%d: %s";
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills char *q = "!atge: %s";
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) vsnprintf(buf, sizeof (buf), fmt, ap);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (level != CE_NOTE) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills p++;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills q++;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (dip) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills cmn_err(level, p,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ddi_driver_name(dip), ddi_get_instance(dip), buf);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra } else {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills cmn_err(level, q, buf);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_notice(dev_info_t *dip, char *fmt, ...)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills va_list ap;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills va_start(ap, fmt);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (void) atge_message(dip, CE_NOTE, fmt, ap);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills va_end(ap);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsvoid
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Millsatge_error(dev_info_t *dip, char *fmt, ...)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills va_list ap;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills va_start(ap, fmt);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (void) atge_message(dip, CE_WARN, fmt, ap);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills va_end(ap);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills}
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_mac_config(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t reg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int speed;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra link_duplex_t ld;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Re-enable TX/RX MACs */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = INL(atgep, ATGE_MAC_CFG);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg &= ~(ATGE_CFG_FULL_DUPLEX | ATGE_CFG_TX_FC | ATGE_CFG_RX_FC |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_CFG_SPEED_MASK);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_DID(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8151V2_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8151V1_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8152V2_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg |= ATGE_CFG_HASH_ALG_CRC32 | ATGE_CFG_SPEED_MODE_SW;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra speed = mii_get_speed(atgep->atge_mii);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra switch (speed) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case 10:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case 100:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg |= ATGE_CFG_SPEED_10_100;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case 1000:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg |= ATGE_CFG_SPEED_1000;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ld = mii_get_duplex(atgep->atge_mii);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (ld == LINK_DUPLEX_FULL)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg |= ATGE_CFG_FULL_DUPLEX;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* Re-enable TX/RX MACs */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra reg |= ATGE_CFG_TX_ENB | ATGE_CFG_RX_ENB | ATGE_CFG_RX_FC;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra reg |= ATGE_CFG_TX_ENB | ATGE_CFG_RX_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_MAC_CFG, reg);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = ATGE_USECS(ATGE_IM_RX_TIMER_DEFAULT) << IM_TIMER_RX_SHIFT;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg |= ATGE_USECS(ATGE_IM_TX_TIMER_DEFAULT) <<
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra IM_TIMER_TX_SHIFT;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_IM_TIMER, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
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 break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() mac_cfg is : %x",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, INL(atgep, ATGE_MAC_CFG)));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic void
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_mii_notify(void *arg, link_state_t link)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_t *atgep = arg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() LINK STATUS CHANGED from %x -> %x",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, atgep->atge_link_state, link));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mac_link_update(atgep->atge_mh, link);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Reconfigure MAC if link status is UP now.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (link == LINK_STATE_UP) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_link_state = LINK_STATE_UP;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_mac_config(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_tx_resched = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra } else {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_link_state = LINK_STATE_DOWN;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atgep->atge_flags |= ATGE_MII_CHECK;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (link == LINK_STATE_UP)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mac_tx_update(atgep->atge_mh);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misravoid
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misraatge_tx_reclaim(atge_t *atgep, int end)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_tx_desc_t *txd;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_ring_t *r = atgep->atge_tx_ring;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra uchar_t *c;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra int start;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ASSERT(MUTEX_HELD(&atgep->atge_tx_lock));
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ASSERT(r != NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra start = r->r_consumer;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (start == end)
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra while (start != end) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra r->r_avail_desc++;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (r->r_avail_desc > ATGE_TX_RING_CNT) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra "Reclaim : TX descriptor error");
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (r->r_avail_desc > (ATGE_TX_RING_CNT + 5)) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_stop(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra c = (uchar_t *)r->r_desc_ring->addr;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra c += (sizeof (atge_tx_desc_t) * start);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra txd = (atge_tx_desc_t *)c;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * Clearing TX descriptor helps in debugging some strange
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * problems.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra txd->addr = 0;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra txd->len = 0;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra txd->flags = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ATGE_INC_SLOT(start, ATGE_TX_RING_CNT);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atgep->atge_tx_ring->r_consumer = start;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra DMA_SYNC(r->r_desc_ring, 0, ATGE_TX_RING_SZ, DDI_DMA_SYNC_FORDEV);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Adds interrupt handler depending upon the type of interrupt supported by
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * the chip.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_add_intr_handler(atge_t *atgep, int intr_type)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int err;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int count = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int avail = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int i;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int flag;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (intr_type != DDI_INTR_TYPE_FIXED) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_intr_get_nintrs(atgep->atge_dip, intr_type, &count);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra "ddi_intr_get_nintrs failed : %d", err);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() count : %d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, count));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_intr_get_navail(atgep->atge_dip, intr_type, &avail);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra "ddi_intr_get_navail failed : %d", err);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (avail < count) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip, "count :%d,"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " avail : %d", count, avail);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra flag = DDI_INTR_ALLOC_STRICT;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra } else {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * DDI_INTR_TYPE_FIXED case.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra count = 1;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra avail = 1;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra flag = DDI_INTR_ALLOC_NORMAL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_intr_size = avail * sizeof (ddi_intr_handle_t);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_intr_handle = kmem_zalloc(atgep->atge_intr_size, KM_SLEEP);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() avail:%d, count : %d, type : %d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, avail, count,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra intr_type));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_intr_alloc(atgep->atge_dip, atgep->atge_intr_handle,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra intr_type, 0, avail, &atgep->atge_intr_cnt, flag);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip, "ddi_intr_alloc failed : %d", err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra kmem_free(atgep->atge_intr_handle, atgep->atge_intr_size);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: atge_add_intr_handler() after alloc count"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " :%d, avail : %d", atgep->atge_name, count, avail));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_intr_get_pri(atgep->atge_intr_handle[0],
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra &atgep->atge_intr_pri);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip, "ddi_intr_get_pri failed:%d", err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (i = 0; i < atgep->atge_intr_cnt; i++) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) ddi_intr_free(atgep->atge_intr_handle[i]);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra kmem_free(atgep->atge_intr_handle, atgep->atge_intr_size);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Add interrupt handler now.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (i = 0; i < atgep->atge_intr_cnt; i++) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra err = ddi_intr_add_handler(atgep->atge_intr_handle[i],
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1e_interrupt, atgep, (caddr_t)(uintptr_t)i);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra err = ddi_intr_add_handler(atgep->atge_intr_handle[i],
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1_interrupt, atgep, (caddr_t)(uintptr_t)i);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills err = ddi_intr_add_handler(atgep->atge_intr_handle[i],
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_interrupt, atgep, (caddr_t)(uintptr_t)i);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra "ddi_intr_add_handler failed : %d", err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) ddi_intr_free(atgep->atge_intr_handle[i]);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra while (--i >= 0) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) ddi_intr_remove_handler(
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_intr_handle[i]);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) ddi_intr_free(
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_intr_handle[i]);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra kmem_free(atgep->atge_intr_handle,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_intr_size);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_intr_get_cap(atgep->atge_intr_handle[0],
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra &atgep->atge_intr_cap);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra "ddi_intr_get_cap failed : %d", err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_remove_intr(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (intr_type == DDI_INTR_TYPE_FIXED)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_flags |= ATGE_FIXED_TYPE;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra else if (intr_type == DDI_INTR_TYPE_MSI)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_flags |= ATGE_MSI_TYPE;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra else if (intr_type == DDI_INTR_TYPE_MSIX)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_flags |= ATGE_MSIX_TYPE;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_SUCCESS);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_remove_intr(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int i;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int cap = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_intr_handle == NULL)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_intr_cap & DDI_INTR_FLAG_BLOCK) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) ddi_intr_block_disable(atgep->atge_intr_handle,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_intr_cnt);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra cap = 1;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (i = 0; i < atgep->atge_intr_cnt; i++) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (cap == 0)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) ddi_intr_disable(atgep->atge_intr_handle[i]);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) ddi_intr_remove_handler(atgep->atge_intr_handle[i]);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) ddi_intr_free(atgep->atge_intr_handle[i]);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra kmem_free(atgep->atge_intr_handle, atgep->atge_intr_size);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_enable_intrs(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int err;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int i;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_intr_cap & DDI_INTR_FLAG_BLOCK) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Do block enable.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_intr_block_enable(atgep->atge_intr_handle,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_intr_cnt);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra "Failed to block enable intrs %d", err);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra err = DDI_FAILURE;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra } else {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra err = DDI_SUCCESS;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra } else {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Call ddi_intr_enable() for MSI non-block enable.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (i = 0; i < atgep->atge_intr_cnt; i++) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_intr_enable(atgep->atge_intr_handle[i]);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra "Failed to enable intrs on %d with : %d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra i, err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err == DDI_SUCCESS)
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra err = DDI_SUCCESS;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra else
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra err = DDI_FAILURE;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Adds interrupt handler depending on the supported interrupt type by the
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * chip.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_add_intr(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int err;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Get the supported interrupt types.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_intr_get_supported_types(atgep->atge_dip,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra &atgep->atge_intr_types);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra "ddi_intr_get_supported_types failed : %d", err);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: ddi_intr_get_supported_types() returned : %d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, atgep->atge_intr_types));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_intr_types & DDI_INTR_TYPE_MSIX) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = atge_add_intr_handler(atgep, DDI_INTR_TYPE_MSIX);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (err == DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: Using MSIx for interrupt",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_intr_types & DDI_INTR_TYPE_MSI) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = atge_add_intr_handler(atgep, DDI_INTR_TYPE_MSI);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (err == DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: Using MSI for interrupt",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra err = DDI_FAILURE;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_intr_types & DDI_INTR_TYPE_FIXED) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = atge_add_intr_handler(atgep, DDI_INTR_TYPE_FIXED);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (err == DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: Using FIXED type for interrupt",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_identify_hardware(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint16_t vid, did;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int i;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra vid = pci_config_get16(atgep->atge_conf_handle, PCI_CONF_VENID);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra did = pci_config_get16(atgep->atge_conf_handle, PCI_CONF_DEVID);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_model = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (i = 0; i < (sizeof (atge_cards) / sizeof (atge_cards_t)); i++) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atge_cards[i].vendor_id == vid &&
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_cards[i].device_id == did) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_model = atge_cards[i].model;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_vid = vid;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_did = did;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_revid =
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra pci_config_get8(atgep->atge_conf_handle,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra PCI_CONF_REVID);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_notice(atgep->atge_dip, "PCI-ID pci%x,%x,%x: %s",
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills vid, did, atgep->atge_revid,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_cards[i].cardname);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s : PCI-ID pci%x,%x and model : %d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, vid, did,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_model));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_SUCCESS);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip, "atge driver is attaching to unknown"
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills " pci%x,%x vendor/device-id card", vid, did);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Assume it's L1C chip.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_model = ATGE_CHIP_L1C;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_vid = vid;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_did = did;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_revid = pci_config_get8(atgep->atge_conf_handle,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra PCI_CONF_REVID);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * We will leave the decision to caller.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_get_macaddr(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t reg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = INL(atgep, ATGE_SPI_CTRL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((reg & SPI_VPD_ENB) != 0) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Get VPD stored in TWSI EEPROM.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg &= ~SPI_VPD_ENB;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_SPI_CTRL, reg);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s called Get VPD", atgep->atge_name, __func__));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_ether_addr[5] = INB(atgep, ATGE_PAR0 + 0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_ether_addr[4] = INB(atgep, ATGE_PAR0 + 1);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_ether_addr[3] = INB(atgep, ATGE_PAR0 + 2);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_ether_addr[2] = INB(atgep, ATGE_PAR0 + 3);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_ether_addr[1] = INB(atgep, ATGE_PAR1 + 0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_ether_addr[0] = INB(atgep, ATGE_PAR1 + 1);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() Station Address - %x:%x:%x:%x:%x:%x",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_ether_addr[0],
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_ether_addr[1],
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_ether_addr[2],
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_ether_addr[3],
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_ether_addr[4],
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_ether_addr[5]));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra bcopy(atgep->atge_ether_addr, atgep->atge_dev_addr, ETHERADDRL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_SUCCESS);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Reset functionality for L1, L1E, and L1C. It's same.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic void
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_device_reset(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_reset_l1_l1e(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_device_reset_l1_l1e(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t reg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int t;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_MASTER_CFG, MASTER_RESET | 0x40);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills default:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_MASTER_CFG, MASTER_RESET);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = INL(atgep, ATGE_MASTER_CFG);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (t = ATGE_RESET_TIMEOUT; t > 0; t--) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra drv_usecwait(10);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = INL(atgep, ATGE_MASTER_CFG);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((reg & MASTER_RESET) == 0)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (t == 0) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip, " master reset timeout reg : %x",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (t = ATGE_RESET_TIMEOUT; t > 0; t--) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((reg = INL(atgep, ATGE_IDLE_STATUS)) == 0)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra drv_usecwait(10);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (t == 0) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip, "device reset timeout reg : %x",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Initialize PCIe module. These values came from FreeBSD and
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * we don't know the meaning of it.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_LTSSM_ID_CFG, 0x6500);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = INL(atgep, 0x1008) | 0x8000;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, 0x1008, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Get chip revision.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_chip_rev = INL(atgep, ATGE_MASTER_CFG) >>
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra MASTER_CHIP_REV_SHIFT;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s reset successfully rev : %x", atgep->atge_name,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra __func__, atgep->atge_chip_rev));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * DMA allocation for L1 and L1E is bit different since L1E uses RX pages
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * instead of descriptor based RX model.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_alloc_dma(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra int err = DDI_FAILURE;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = atge_l1e_alloc_dma(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra err = atge_l1_alloc_dma(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills err = atge_l1c_alloc_dma(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic void
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_free_dma(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_free_dma(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1_free_dma(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_free_dma(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Attach entry point in the driver.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_t *atgep;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mac_register_t *macreg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int instance;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint16_t cap_ptr;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint16_t burst;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int err;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mii_ops_t *mii_ops;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra instance = ddi_get_instance(devinfo);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra switch (cmd) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case DDI_RESUME:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (atge_resume(devinfo));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case DDI_ATTACH:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ddi_set_driver_private(devinfo, NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills default:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills return (DDI_FAILURE);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep = kmem_zalloc(sizeof (atge_t), KM_SLEEP);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ddi_set_driver_private(devinfo, atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_dip = devinfo;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Setup name and instance number to be used for debugging and
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * error reporting.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) snprintf(atgep->atge_name, sizeof (atgep->atge_name), "%s%d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra "atge", instance);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Map PCI config space.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = pci_config_setup(devinfo, &atgep->atge_conf_handle);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(devinfo, "pci_config_setup() failed");
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra goto fail1;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) atge_identify_hardware(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Map Device registers.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_regs_map_setup(devinfo, ATGE_PCI_REG_NUMBER,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra &atgep->atge_io_regs, 0, 0, &atge_dev_attr, &atgep->atge_io_handle);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(devinfo, "ddi_regs_map_setup() failed");
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra goto fail2;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Add interrupt and its associated handler.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = atge_add_intr(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(devinfo, "Failed to add interrupt handler");
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra goto fail3;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_init(&atgep->atge_intr_lock, NULL, MUTEX_DRIVER,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_INTR_PRI(atgep->atge_intr_pri));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_init(&atgep->atge_tx_lock, NULL, MUTEX_DRIVER,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_INTR_PRI(atgep->atge_intr_pri));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_init(&atgep->atge_rx_lock, NULL, MUTEX_DRIVER,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_INTR_PRI(atgep->atge_intr_pri));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_init(&atgep->atge_mii_lock, NULL, MUTEX_DRIVER, NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * Used to lock down MBOX register on L1 chip since RX consumer,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * TX producer and RX return ring consumer are shared.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mutex_init(&atgep->atge_mbox_lock, NULL, MUTEX_DRIVER,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra DDI_INTR_PRI(atgep->atge_intr_pri));
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_link_state = LINK_STATE_DOWN;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_mtu = ETHERMTU;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (atgep->atge_revid > 0xF0) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /* L2E Rev. B. AR8114 */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_flags |= ATGE_FLAG_FASTETHER;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra } else {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if ((INL(atgep, L1E_PHY_STATUS) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra PHY_STATUS_100M) != 0) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /* L1E AR8121 */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atgep->atge_flags |= ATGE_FLAG_JUMBO;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra } else {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /* L2E Rev. A. AR8113 */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atgep->atge_flags |= ATGE_FLAG_FASTETHER;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * One odd thing is AR8132 uses the same PHY hardware(F1
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * gigabit PHY) of AR8131. So atphy(4) of AR8132 reports
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * the PHY supports 1000Mbps but that's not true. The PHY
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * used in AR8132 can't establish gigabit link even if it
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * shows the same PHY model/revision number of AR8131.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills *
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * It seems that AR813x/AR815x has silicon bug for SMB. In
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * addition, Atheros said that enabling SMB wouldn't improve
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * performance. However I think it's bad to access lots of
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * registers to extract MAC statistics.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills *
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Don't use Tx CMB. It is known to have silicon bug.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_DID(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8152V2_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8152V1_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_flags |= ATGE_FLAG_APS |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_FLAG_FASTETHER |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_FLAG_ASPM_MON | ATGE_FLAG_JUMBO |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_FLAG_SMB_BUG | ATGE_FLAG_CMB_BUG;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8151V2_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8151V1_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_flags |= ATGE_FLAG_APS |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_FLAG_ASPM_MON | ATGE_FLAG_JUMBO |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_FLAG_SMB_BUG | ATGE_FLAG_CMB_BUG;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1CF_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_flags |= ATGE_FLAG_FASTETHER;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1CG_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Get DMA parameters from PCIe device control register.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = PCI_CAP_LOCATE(atgep->atge_conf_handle, PCI_CAP_ID_PCI_E,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra &cap_ptr);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err == DDI_FAILURE) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_dma_rd_burst = DMA_CFG_RD_BURST_128;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_dma_wr_burst = DMA_CFG_WR_BURST_128;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra } else {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_flags |= ATGE_FLAG_PCIE;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra burst = pci_config_get16(atgep->atge_conf_handle,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra cap_ptr + 0x08);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Max read request size.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_dma_rd_burst = ((burst >> 12) & 0x07) <<
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DMA_CFG_RD_BURST_SHIFT;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Max Payload Size.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_dma_wr_burst = ((burst >> 5) & 0x07) <<
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DMA_CFG_WR_BURST_SHIFT;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() MRR : %d, MPS : %d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (128 << ((burst >> 12) & 0x07)),
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (128 << ((burst >> 5) & 0x07))));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Clear data link and flow-control protocol error. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL_AND(atgep, ATGE_PEX_UNC_ERR_SEV,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ~(PEX_UNC_ERR_SEV_UC | PEX_UNC_ERR_SEV_FCP));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL_AND(atgep, ATGE_LTSSM_ID_CFG, ~LTSSM_ID_WRO_ENB);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL_OR(atgep, ATGE_PCIE_PHYMISC, PCIE_PHYMISC_FORCE_RCV_DET);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Allocate DMA resources.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = atge_alloc_dma(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(devinfo, "Failed to allocate DMA resources");
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra goto fail4;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Get station address.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) atge_get_macaddr(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Setup MII.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mii_ops = &atge_l1e_mii_ops;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mii_ops = &atge_l1_mii_ops;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills mii_ops = &atge_l1c_mii_ops;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((atgep->atge_mii = mii_alloc(atgep, devinfo,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mii_ops)) == NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(devinfo, "mii_alloc() failed");
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra goto fail4;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Register with MAC layer.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((macreg = mac_alloc(MAC_VERSION)) == NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(devinfo, "mac_alloc() failed due to version");
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra goto fail4;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra macreg->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra macreg->m_driver = atgep;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra macreg->m_dip = devinfo;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra macreg->m_instance = instance;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra macreg->m_src_addr = atgep->atge_ether_addr;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra macreg->m_callbacks = &atge_m_callbacks;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra macreg->m_min_sdu = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra macreg->m_max_sdu = atgep->atge_mtu;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra macreg->m_margin = VLAN_TAGSZ;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((err = mac_register(macreg, &atgep->atge_mh)) != 0) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(devinfo, "mac_register() failed with :%d", err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mac_free(macreg);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra goto fail4;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mac_free(macreg);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() driver attached successfully",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_reset(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_chip_state = ATGE_CHIP_INITIALIZED;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * At last - enable interrupts.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = atge_enable_intrs(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (err == DDI_FAILURE) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra goto fail5;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Reset the PHY before starting.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_mii_reset(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1_mii_reset(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_mii_reset(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Let the PHY run.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mii_start(atgep->atge_mii);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (DDI_SUCCESS);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrafail5:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void) mac_unregister(atgep->atge_mh);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_stop(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mii_stop(atgep->atge_mii);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mii_free(atgep->atge_mii);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrafail4:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_free_dma(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_destroy(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_destroy(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_destroy(&atgep->atge_rx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_remove_intr(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrafail3:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ddi_regs_map_free(&atgep->atge_io_handle);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrafail2:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra pci_config_teardown(&atgep->atge_conf_handle);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrafail1:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra kmem_free(atgep, sizeof (atge_t));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_t *atgep;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep = ddi_get_driver_private(dip);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep == NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(dip, "No soft state in detach");
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra switch (cmd) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case DDI_DETACH:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * First unregister with MAC layer before stopping DMA
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
9d8d9e1151895fac86a2e3216647dd2a020ecf71Garrett D'Amore if (mac_disable(atgep->atge_mh) != DDI_SUCCESS)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
9d8d9e1151895fac86a2e3216647dd2a020ecf71Garrett D'Amore mii_stop(atgep->atge_mii);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_stop(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mii_free(atgep->atge_mii);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_free_dma(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ddi_regs_map_free(&atgep->atge_io_handle);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_remove_intr(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra pci_config_teardown(&atgep->atge_conf_handle);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
9d8d9e1151895fac86a2e3216647dd2a020ecf71Garrett D'Amore (void) mac_unregister(atgep->atge_mh);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_destroy(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_destroy(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_destroy(&atgep->atge_rx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra kmem_free(atgep, sizeof (atge_t));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ddi_set_driver_private(dip, NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (DDI_SUCCESS);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case DDI_SUSPEND:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() is being suspended",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Suspend monitoring MII.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mii_suspend(atgep->atge_mii);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_chip_state |= ATGE_CHIP_SUSPENDED;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_stop(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (DDI_SUCCESS);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra default:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_alloc_buffers(atge_ring_t *r, size_t rcnt, size_t buflen, int f)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_dma_t *dma;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_dma_t **tbl;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra int err = DDI_SUCCESS;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int i;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra tbl = kmem_zalloc(rcnt * sizeof (atge_dma_t *), KM_SLEEP);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra r->r_buf_tbl = tbl;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (i = 0; i < rcnt; i++) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma = atge_buf_alloc(r->r_atge, buflen, f);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (dma == NULL) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra err = DDI_FAILURE;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra tbl[i] = dma;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_free_buffers(atge_ring_t *r, size_t rcnt)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_dma_t **tbl;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int i;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (r == NULL || r->r_buf_tbl == NULL)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra tbl = r->r_buf_tbl;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (i = 0; i < rcnt; i++) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (tbl[i] != NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_buf_free(tbl[i]);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra kmem_free(tbl, rcnt * sizeof (atge_dma_t *));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_dma_t *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_alloc_a_dma_blk(atge_t *atgep, ddi_dma_attr_t *attr, int size, int d)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int err;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_dma_t *dma;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma = kmem_zalloc(sizeof (atge_dma_t), KM_SLEEP);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_dma_alloc_handle(atgep->atge_dip, attr,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_DMA_SLEEP, NULL, &dma->hdl);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip, "%s() : failed"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " in ddi_dma_alloc_handle() : %d", __func__, err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra goto fail;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_dma_mem_alloc(dma->hdl,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra size, &atge_buf_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra &dma->addr, &dma->len, &dma->acchdl);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip, "%s() : failed"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " in ddi_dma_mem_alloc() : %d", __func__, err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ddi_dma_free_handle(&dma->hdl);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra goto fail;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_dma_addr_bind_handle(dma->hdl, NULL, dma->addr,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma->len, d | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra NULL, &dma->cookie, &dma->count);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip, "%s() : failed"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " in ddi_dma_addr_bind_handle() : %d", __func__, err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ddi_dma_mem_free(&dma->acchdl);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ddi_dma_free_handle(&dma->hdl);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra goto fail;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (dma);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrafail:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra kmem_free(dma, sizeof (atge_dma_t));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_free_a_dma_blk(atge_dma_t *dma)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
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 Misraatge_dma_t *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_buf_alloc(atge_t *atgep, size_t len, int f)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_dma_t *dma = NULL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int err;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra dma = kmem_zalloc(sizeof (atge_dma_t), KM_SLEEP);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_dma_alloc_handle(atgep->atge_dip, &atge_dma_attr_buf,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_DMA_SLEEP, NULL, &dma->hdl);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip, "%s() : failed"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " in %s() : %d", __func__, err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra goto fail;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_dma_mem_alloc(dma->hdl, len, &atge_buf_attr,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, &dma->addr,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra &dma->len, &dma->acchdl);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip, "%s() : failed"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " in %s() : %d", __func__, err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ddi_dma_free_handle(&dma->hdl);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra goto fail;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra err = ddi_dma_addr_bind_handle(dma->hdl, NULL, dma->addr, dma->len,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (f | DDI_DMA_CONSISTENT), DDI_DMA_SLEEP, NULL, &dma->cookie,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra &dma->count);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (err != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip, "%s() : failed"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " in %s() : %d", __func__, err);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ddi_dma_mem_free(&dma->acchdl);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ddi_dma_free_handle(&dma->hdl);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra goto fail;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Number of return'ed cookie should be one.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(dma->count == 1);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (dma);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrafail:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra kmem_free(dma, sizeof (atge_dma_t));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_buf_free(atge_dma_t *dma)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(dma != NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
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 Misrastatic int
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_resume(dev_info_t *dip)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_t *atgep;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((atgep = ddi_get_driver_private(dip)) == NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_chip_state &= ~ATGE_CHIP_SUSPENDED;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_chip_state & ATGE_CHIP_RUNNING) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_restart(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra } else {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_reset(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Reset the PHY before resuming MII.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_mii_reset(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mii_resume(atgep->atge_mii);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* kick-off downstream */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mac_tx_update(atgep->atge_mh);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (DDI_SUCCESS);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_quiesce(dev_info_t *dip)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_t *atgep;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((atgep = ddi_get_driver_private(dip)) == NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_stop(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (DDI_SUCCESS);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_add_multicst(atge_t *atgep, uint8_t *macaddr)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t crc;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int bit;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(MUTEX_HELD(&atgep->atge_intr_lock));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(MUTEX_HELD(&atgep->atge_tx_lock));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() %x:%x:%x:%x:%x:%x",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, macaddr[0], macaddr[1], macaddr[2],
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra macaddr[3], macaddr[4], macaddr[5]));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra crc = atge_ether_crc(macaddr, ETHERADDRL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra bit = (crc >> 26);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_mchash_ref_cnt[bit]++;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_mchash |= (1ULL << (crc >> 26));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() mchash :%llx, bit : %d,"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " atge_mchash_ref_cnt[bit] :%d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, atgep->atge_mchash, bit,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_mchash_ref_cnt[bit]));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_remove_multicst(atge_t *atgep, uint8_t *macaddr)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t crc;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int bit;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(MUTEX_HELD(&atgep->atge_intr_lock));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(MUTEX_HELD(&atgep->atge_tx_lock));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() %x:%x:%x:%x:%x:%x",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, macaddr[0], macaddr[1], macaddr[2],
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra macaddr[3], macaddr[4], macaddr[5]));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra crc = atge_ether_crc(macaddr, ETHERADDRL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra bit = (crc >> 26);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_mchash_ref_cnt[bit]--;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_mchash_ref_cnt[bit] == 0)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_mchash &= ~(1ULL << (crc >> 26));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() mchash :%llx, bit : %d,"
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra " atge_mchash_ref_cnt[bit] :%d",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, atgep->atge_mchash, bit,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_mchash_ref_cnt[bit]));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_m_multicst(void *arg, boolean_t add, const uint8_t *macaddr)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_t *atgep = arg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (add) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_add_multicst(atgep, (uint8_t *)macaddr);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra } else {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_remove_multicst(atgep, (uint8_t *)macaddr);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_rxfilter(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_m_promisc(void *arg, boolean_t on)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_t *atgep = arg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (on) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_filter_flags |= ATGE_PROMISC;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra } else {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_filter_flags &= ~ATGE_PROMISC;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_chip_state & ATGE_CHIP_RUNNING) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_rxfilter(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_m_unicst(void *arg, const uint8_t *macaddr)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_t *atgep = arg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra bcopy(macaddr, atgep->atge_ether_addr, ETHERADDRL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_program_ether(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_rxfilter(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misramblk_t *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_m_tx(void *arg, mblk_t *mp)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_t *atgep = arg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mblk_t *nmp;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * This NIC does not like us to send pkt when link is down.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (!(atgep->atge_link_state & LINK_STATE_UP)) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_tx_resched = 1;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (mp);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Don't send a pkt if chip isn't running or in suspended state.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((atgep->atge_chip_state & ATGE_CHIP_RUNNING) == 0 ||
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_chip_state & ATGE_CHIP_SUSPENDED) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_carrier_errors++;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_tx_resched = 1;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (mp);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra while (mp != NULL) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra nmp = mp->b_next;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mp->b_next = NULL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (atge_send_a_packet(atgep, mp) == DDI_FAILURE) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mp->b_next = nmp;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mp = nmp;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (mp);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_m_start(void *arg)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_t *atgep = arg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int started = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(atgep != NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mii_stop(atgep->atge_mii);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (!(atgep->atge_chip_state & ATGE_CHIP_SUSPENDED)) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_restart(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra started = 1;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mii_start(atgep->atge_mii);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /* kick-off downstream */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (started)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mac_tx_update(atgep->atge_mh);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_m_stop(void *arg)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_t *atgep = arg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mii_stop(atgep->atge_mii);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Cancel any pending I/O.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_enter(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_chip_state &= ~ATGE_CHIP_RUNNING;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (!(atgep->atge_chip_state & ATGE_CHIP_SUSPENDED))
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_stop(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mutex_exit(&atgep->atge_intr_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_m_stat(void *arg, uint_t stat, uint64_t *val)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_t *atgep = arg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (mii_m_getstat(atgep->atge_mii, stat, val) == 0) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra switch (stat) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_MULTIRCV:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_multircv;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_BRDCSTRCV:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_brdcstrcv;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_MULTIXMT:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_multixmt;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_BRDCSTXMT:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_brdcstxmt;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_IPACKETS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_ipackets;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_RBYTES:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_rbytes;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_OPACKETS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_opackets;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_OBYTES:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_obytes;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_NORCVBUF:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_norcvbuf;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_NOXMTBUF:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_COLLISIONS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_collisions;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_IERRORS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_errrcv;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_OERRORS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_errxmt;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case ETHER_STAT_ALIGN_ERRORS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_align_errors;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case ETHER_STAT_FCS_ERRORS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_fcs_errors;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case ETHER_STAT_SQE_ERRORS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_sqe_errors;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case ETHER_STAT_DEFER_XMTS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_defer_xmts;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case ETHER_STAT_FIRST_COLLISIONS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_first_collisions;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case ETHER_STAT_MULTI_COLLISIONS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_multi_collisions;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case ETHER_STAT_TX_LATE_COLLISIONS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_tx_late_collisions;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case ETHER_STAT_EX_COLLISIONS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_ex_collisions;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case ETHER_STAT_MACXMT_ERRORS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_macxmt_errors;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case ETHER_STAT_CARRIER_ERRORS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_carrier_errors;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case ETHER_STAT_TOOLONG_ERRORS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_toolong_errors;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case ETHER_STAT_MACRCV_ERRORS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_macrcv_errors;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_OVERFLOWS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_overflow;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case MAC_STAT_UNDERFLOWS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_underflow;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case ETHER_STAT_TOOSHORT_ERRORS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_runt;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra case ETHER_STAT_JABBER_ERRORS:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *val = atgep->atge_jabber;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra default:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (ENOTSUP);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyeratge_m_getprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer void *val)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_t *atgep = arg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer return (mii_m_getprop(atgep->atge_mii, name, num, sz, val));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_m_setprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra const void *val)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_t *atgep = arg;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra int r;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra r = mii_m_setprop(atgep->atge_mii, name, num, sz, val);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (r == 0) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mutex_enter(&atgep->atge_intr_lock);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mutex_enter(&atgep->atge_tx_lock);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (atgep->atge_chip_state & ATGE_CHIP_RUNNING) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_device_restart(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mutex_exit(&atgep->atge_tx_lock);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra mutex_exit(&atgep->atge_intr_lock);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (r);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyerstatic void
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyeratge_m_propinfo(void *arg, const char *name, mac_prop_id_t num,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_prop_info_handle_t prh)
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer{
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer atge_t *atgep = arg;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mii_m_propinfo(atgep->atge_mii, name, num, prh);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_program_ether(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ether_addr_t e;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Reprogram the Station address.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra bcopy(atgep->atge_ether_addr, e, ETHERADDRL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_PAR0,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ((e[2] << 24) | (e[3] << 16) | (e[4] << 8) | e[5]));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_PAR1, (e[0] << 8) | e[1]);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Device specific operations.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_device_start(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra uint32_t rxf_hi, rxf_lo, rrd_hi, rrd_lo;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t reg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t fsize;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Reprogram the Station address.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_program_ether(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_program_dma(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1_program_dma(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_program_dma(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() dma, counters programmed ", atgep->atge_name,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra __func__));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTW(atgep, ATGE_INTR_CLR_TIMER, 1*1000/2);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Disable interrupt re-trigger timer. We don't want automatic
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * re-triggering of un-ACKed interrupts.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_INTR_RETRIG_TIMER, ATGE_USECS(0));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Configure CMB. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_CMB_TX_TIMER, ATGE_USECS(0));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Hardware can be configured to issue SMB interrupt based
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * on programmed interval. Since there is a callout that is
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * invoked for every hz in driver we use that instead of
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * relying on periodic SMB interrupt.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_SMB_STAT_TIMER, ATGE_USECS(0));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Clear MAC statistics. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_clear_stats(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * Set Maximum frame size but don't let MTU be less than ETHER_MTU.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_mtu < ETHERMTU)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_max_frame_size = ETHERMTU;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra else
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_max_frame_size = atgep->atge_mtu;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_max_frame_size += sizeof (struct ether_header) +
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra VLAN_TAGSZ + ETHERFCSL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_FRAME_SIZE, atgep->atge_max_frame_size);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Disable header split(?) */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_HDS_CFG, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Configure IPG/IFG parameters.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_IPG_IFG_CFG,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ((IPG_IFG_IPG2_DEFAULT << IPG_IFG_IPG2_SHIFT) & IPG_IFG_IPG2_MASK) |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ((IPG_IFG_IPG1_DEFAULT << IPG_IFG_IPG1_SHIFT) & IPG_IFG_IPG1_MASK) |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ((IPG_IFG_MIFG_DEFAULT << IPG_IFG_MIFG_SHIFT) & IPG_IFG_MIFG_MASK) |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ((IPG_IFG_IPGT_DEFAULT << IPG_IFG_IPGT_SHIFT) & IPG_IFG_IPGT_MASK));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Set parameters for half-duplex media.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_HDPX_CFG,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ((HDPX_CFG_LCOL_DEFAULT << HDPX_CFG_LCOL_SHIFT) &
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra HDPX_CFG_LCOL_MASK) |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ((HDPX_CFG_RETRY_DEFAULT << HDPX_CFG_RETRY_SHIFT) &
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra HDPX_CFG_RETRY_MASK) | HDPX_CFG_EXC_DEF_EN |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ((HDPX_CFG_ABEBT_DEFAULT << HDPX_CFG_ABEBT_SHIFT) &
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra HDPX_CFG_ABEBT_MASK) |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ((HDPX_CFG_JAMIPG_DEFAULT << HDPX_CFG_JAMIPG_SHIFT) &
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra HDPX_CFG_JAMIPG_MASK));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Configure jumbo frame.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (atgep->atge_flags & ATGE_FLAG_JUMBO) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if (atgep->atge_mtu < ETHERMTU)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = atgep->atge_max_frame_size;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills else if (atgep->atge_mtu < 6 * 1024)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = (atgep->atge_max_frame_size * 2) / 3;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills else
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = atgep->atge_max_frame_size / 2;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1E_TX_JUMBO_THRESH,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ROUNDUP(reg, TX_JUMBO_THRESH_UNIT) >>
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills TX_JUMBO_THRESH_UNIT_SHIFT);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra fsize = ROUNDUP(atgep->atge_max_frame_size, sizeof (uint64_t));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_RXQ_JUMBO_CFG,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (((fsize / sizeof (uint64_t)) <<
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra RXQ_JUMBO_CFG_SZ_THRESH_SHIFT) &
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra RXQ_JUMBO_CFG_SZ_THRESH_MASK) |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ((RXQ_JUMBO_CFG_LKAH_DEFAULT <<
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra RXQ_JUMBO_CFG_LKAH_SHIFT) & RXQ_JUMBO_CFG_LKAH_MASK) |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ((ATGE_USECS(8) << RXQ_JUMBO_CFG_RRD_TIMER_SHIFT) &
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra RXQ_JUMBO_CFG_RRD_TIMER_MASK));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Configure flow-control parameters.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if ((atgep->atge_flags & ATGE_FLAG_PCIE) != 0) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Some hardware version require this magic.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_LTSSM_ID_CFG, 0x6500);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = INL(atgep, 0x1008);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, 0x1008, reg | 0x8000);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * These are all magic parameters which came from FreeBSD.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = INL(atgep, L1E_SRAM_RX_FIFO_LEN);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rxf_hi = (reg * 4) / 5;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rxf_lo = reg/ 5;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_RXQ_FIFO_PAUSE_THRESH,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ((rxf_lo << RXQ_FIFO_PAUSE_THRESH_LO_SHIFT) &
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills RXQ_FIFO_PAUSE_THRESH_LO_MASK) |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ((rxf_hi << RXQ_FIFO_PAUSE_THRESH_HI_SHIFT) &
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills RXQ_FIFO_PAUSE_THRESH_HI_MASK));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra switch (atgep->atge_chip_rev) {
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra case 0x8001:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra case 0x9001:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra case 0x9002:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra case 0x9003:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra rxf_hi = L1_RX_RING_CNT / 16;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra rxf_lo = (L1_RX_RING_CNT * 7) / 8;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra rrd_hi = (L1_RR_RING_CNT * 7) / 8;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra rrd_lo = L1_RR_RING_CNT / 16;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra break;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra default:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra reg = INL(atgep, L1_SRAM_RX_FIFO_LEN);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra rxf_lo = reg / 16;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (rxf_lo > 192)
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra rxf_lo = 192;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra rxf_hi = (reg * 7) / 8;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (rxf_hi < rxf_lo)
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra rxf_hi = rxf_lo + 16;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra reg = INL(atgep, L1_SRAM_RRD_LEN);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra rrd_lo = reg / 8;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra rrd_hi = (reg * 7) / 8;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (rrd_lo > 2)
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra rrd_lo = 2;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra if (rrd_hi < rrd_lo)
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra rrd_hi = rrd_lo + 3;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra break;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra OUTL(atgep, ATGE_RXQ_FIFO_PAUSE_THRESH,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ((rxf_lo << RXQ_FIFO_PAUSE_THRESH_LO_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra RXQ_FIFO_PAUSE_THRESH_LO_MASK) |
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ((rxf_hi << RXQ_FIFO_PAUSE_THRESH_HI_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra RXQ_FIFO_PAUSE_THRESH_HI_MASK));
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra OUTL(atgep, L1_RXQ_RRD_PAUSE_THRESH,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ((rrd_lo << RXQ_RRD_PAUSE_THRESH_LO_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra RXQ_RRD_PAUSE_THRESH_LO_MASK) |
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ((rrd_hi << RXQ_RRD_PAUSE_THRESH_HI_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra RXQ_RRD_PAUSE_THRESH_HI_MASK));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_DID(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8151V2_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8152V1_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_SERDES_LOCK,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills INL(atgep, ATGE_SERDES_LOCK) |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills SERDES_MAC_CLK_SLOWDOWN |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills SERDES_PHY_CLK_SLOWDOWN);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1CG_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1CF_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Configure flow control parameters.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * XON : 80% of Rx FIFO
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * XOFF : 30% of Rx FIFO
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = INL(atgep, L1C_SRAM_RX_FIFO_LEN);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rxf_hi = (reg * 8) / 10;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills rxf_lo = (reg * 3) / 10;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_RXQ_FIFO_PAUSE_THRESH,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ((rxf_lo << RXQ_FIFO_PAUSE_THRESH_LO_SHIFT) &
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills RXQ_FIFO_PAUSE_THRESH_LO_MASK) |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ((rxf_hi << RXQ_FIFO_PAUSE_THRESH_HI_SHIFT) &
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills RXQ_FIFO_PAUSE_THRESH_HI_MASK));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Configure RxQ. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = RXQ_CFG_ALIGN_32 | RXQ_CFG_CUT_THROUGH_ENB |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills RXQ_CFG_IPV6_CSUM_VERIFY | RXQ_CFG_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_RXQ_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Configure TxQ.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = (128 <<
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (atgep->atge_dma_rd_burst >> DMA_CFG_RD_BURST_SHIFT)) <<
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills TXQ_CFG_TX_FIFO_BURST_SHIFT;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg |= (TXQ_CFG_TPD_BURST_DEFAULT << TXQ_CFG_TPD_BURST_SHIFT) &
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills TXQ_CFG_TPD_BURST_MASK;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg |= TXQ_CFG_ENHANCED_MODE | TXQ_CFG_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_TXQ_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Disable RSS. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1E_RSS_IDT_TABLE0, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1E_RSS_CPU, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Configure DMA parameters.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Don't use Tx CMB. It is known to cause RRS update failure
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * under certain circumstances. Typical phenomenon of the
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * issue would be unexpected sequence number encountered in
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Rx handler. Hence we don't set DMA_CFG_TXCMB_ENB.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_DMA_CFG,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_CFG_OUT_ORDER | DMA_CFG_RD_REQ_PRI | DMA_CFG_RCB_64 |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_dma_rd_burst | atgep->atge_dma_wr_burst |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_CFG_RXCMB_ENB |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ((DMA_CFG_RD_DELAY_CNT_DEFAULT <<
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_CFG_RD_DELAY_CNT_SHIFT) & DMA_CFG_RD_DELAY_CNT_MASK) |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ((DMA_CFG_WR_DELAY_CNT_DEFAULT <<
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_CFG_WR_DELAY_CNT_SHIFT) & DMA_CFG_WR_DELAY_CNT_MASK));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Enable CMB/SMB timer.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1E_SMB_STAT_TIMER, 100000);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1e_clear_stats(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Configure RxQ. */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra reg =
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ((RXQ_CFG_RD_BURST_DEFAULT << RXQ_CFG_RD_BURST_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra RXQ_CFG_RD_BURST_MASK) |
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ((RXQ_CFG_RRD_BURST_THRESH_DEFAULT <<
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra RXQ_CFG_RRD_BURST_THRESH_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra RXQ_CFG_RRD_BURST_THRESH_MASK) |
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ((RXQ_CFG_RD_PREF_MIN_IPG_DEFAULT <<
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra RXQ_CFG_RD_PREF_MIN_IPG_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra RXQ_CFG_RD_PREF_MIN_IPG_MASK) |
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra RXQ_CFG_CUT_THROUGH_ENB | RXQ_CFG_ENB;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra OUTL(atgep, ATGE_RXQ_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Configure TxQ.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra reg =
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra (((TXQ_CFG_TPD_BURST_DEFAULT << TXQ_CFG_TPD_BURST_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra TXQ_CFG_TPD_BURST_MASK) |
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ((TXQ_CFG_TX_FIFO_BURST_DEFAULT <<
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra TXQ_CFG_TX_FIFO_BURST_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra TXQ_CFG_TX_FIFO_BURST_MASK) |
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ((TXQ_CFG_TPD_FETCH_DEFAULT <<
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra TXQ_CFG_TPD_FETCH_THRESH_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra TXQ_CFG_TPD_FETCH_THRESH_MASK) |
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra TXQ_CFG_ENB);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra OUTL(atgep, ATGE_TXQ_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Jumbo frames */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra OUTL(atgep, L1_TX_JUMBO_TPD_TH_IPG,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra (((fsize / sizeof (uint64_t) << TX_JUMBO_TPD_TH_SHIFT)) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra TX_JUMBO_TPD_TH_MASK) |
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ((TX_JUMBO_TPD_IPG_DEFAULT << TX_JUMBO_TPD_IPG_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra TX_JUMBO_TPD_IPG_MASK));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Configure DMA parameters.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra OUTL(atgep, ATGE_DMA_CFG,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra DMA_CFG_ENH_ORDER | DMA_CFG_RCB_64 |
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atgep->atge_dma_rd_burst | DMA_CFG_RD_ENB |
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atgep->atge_dma_wr_burst | DMA_CFG_WR_ENB);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /* Configure CMB DMA write threshold. */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra OUTL(atgep, L1_CMB_WR_THRESH,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ((CMB_WR_THRESH_RRD_DEFAULT << CMB_WR_THRESH_RRD_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra CMB_WR_THRESH_RRD_MASK) |
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ((CMB_WR_THRESH_TPD_DEFAULT << CMB_WR_THRESH_TPD_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra CMB_WR_THRESH_TPD_MASK));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Enable CMB/SMB timer.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /* Set CMB/SMB timer and enable them. */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra OUTL(atgep, L1_CMB_WR_TIMER,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ((ATGE_USECS(2) << CMB_WR_TIMER_TX_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra CMB_WR_TIMER_TX_MASK) |
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ((ATGE_USECS(2) << CMB_WR_TIMER_RX_SHIFT) &
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra CMB_WR_TIMER_RX_MASK));
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /* Request SMB updates for every seconds. */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra OUTL(atgep, L1_SMB_TIMER, ATGE_USECS(1000 * 1000));
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra OUTL(atgep, L1_CSMB_CTRL,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra CSMB_CTRL_SMB_ENB | CSMB_CTRL_CMB_ENB);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Configure RxQ. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg =
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills RXQ_CFG_RD_BURST_DEFAULT << L1C_RXQ_CFG_RD_BURST_SHIFT |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills RXQ_CFG_IPV6_CSUM_VERIFY | RXQ_CFG_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills if ((atgep->atge_flags & ATGE_FLAG_ASPM_MON) != 0)
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg |= RXQ_CFG_ASPM_THROUGHPUT_LIMIT_1M;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_RXQ_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Configure TxQ.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = (128 <<
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills (atgep->atge_dma_rd_burst >> DMA_CFG_RD_BURST_SHIFT)) <<
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills TXQ_CFG_TX_FIFO_BURST_SHIFT;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_DID(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8152V2_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8152V1_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg >>= 1;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg |= (L1C_TXQ_CFG_TPD_BURST_DEFAULT <<
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills TXQ_CFG_TPD_BURST_SHIFT) & TXQ_CFG_TPD_BURST_MASK;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg |= TXQ_CFG_ENHANCED_MODE | TXQ_CFG_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_TXQ_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Disable RSS until I understand L1C/L2C's RSS logic. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RSS_IDT_TABLE0, 0xe4e4e4e4);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_RSS_CPU, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Configure DMA parameters.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_DMA_CFG,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_CFG_SMB_DIS |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_CFG_OUT_ORDER | DMA_CFG_RD_REQ_PRI | DMA_CFG_RCB_64 |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_CFG_RD_DELAY_CNT_DEFAULT << DMA_CFG_RD_DELAY_CNT_SHIFT |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills DMA_CFG_WR_DELAY_CNT_DEFAULT << DMA_CFG_WR_DELAY_CNT_SHIFT |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_dma_rd_burst | DMA_CFG_RD_ENB |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_dma_wr_burst | DMA_CFG_WR_ENB);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Configure CMB DMA write threshold not required. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Set CMB/SMB timer and enable them not required. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Disable all WOL bits as WOL can interfere normal Rx
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * operation.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_WOL_CFG, 0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Configure Tx/Rx MACs.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * - Auto-padding for short frames.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * - Enable CRC generation.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra *
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Start with full-duplex/1000Mbps media. Actual reconfiguration
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * of MAC is followed after link establishment.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = (ATGE_CFG_TX_CRC_ENB | ATGE_CFG_TX_AUTO_PAD |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_CFG_FULL_DUPLEX |
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ((ATGE_CFG_PREAMBLE_DEFAULT << ATGE_CFG_PREAMBLE_SHIFT) &
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_CFG_PREAMBLE_MASK));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * AR813x/AR815x always does checksum computation regardless
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * of MAC_CFG_RXCSUM_ENB bit. Also the controller is known to
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * have bug in protocol field in Rx return structure so
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * these controllers can't handle fragmented frames. Disable
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Rx checksum offloading until there is a newer controller
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * that has sane implementation.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_DID(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8151V2_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8151V1_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_AR8152V2_DEV_ID:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg |= ATGE_CFG_HASH_ALG_CRC32 | ATGE_CFG_SPEED_MODE_SW;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((atgep->atge_flags & ATGE_FLAG_FASTETHER) != 0) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg |= ATGE_CFG_SPEED_10_100;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() Fast Ethernet", atgep->atge_name, __func__));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra } else {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg |= ATGE_CFG_SPEED_1000;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() 1G speed", atgep->atge_name, __func__));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg |= L1C_CFG_SINGLE_PAUSE_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_MAC_CFG, reg);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_chip_state |= ATGE_CHIP_RUNNING;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Set up the receive filter.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_rxfilter(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * Acknowledge all pending interrupts and clear it.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_INTR_MASK, L1E_INTRS);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_INTR_STATUS, 0xFFFFFFFF);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_INTR_STATUS, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_INTR_STATUS, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_INTR_MASK, atgep->atge_intrs);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_mac_config(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() device started", atgep->atge_name, __func__));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Generic functions.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra#define CRC32_POLY_BE 0x04c11db7
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrauint32_t
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_ether_crc(const uint8_t *addr, int len)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int idx;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int bit;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint_t data;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t crc;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra crc = 0xffffffff;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (idx = 0; idx < len; idx++) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra crc = (crc << 1)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ^ ((((crc >> 31) ^ data) & 1) ? CRC32_POLY_BE : 0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (crc);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Programs RX filter. We use a link-list to keep track of all multicast
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * addressess.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_rxfilter(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t rxcfg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint64_t mchash;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra rxcfg = INL(atgep, ATGE_MAC_CFG);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra rxcfg &= ~(ATGE_CFG_ALLMULTI | ATGE_CFG_PROMISC);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Accept broadcast frames.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra rxcfg |= ATGE_CFG_BCAST;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * We don't use Hardware VLAN tagging.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra rxcfg &= ~ATGE_CFG_VLAN_TAG_STRIP;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_filter_flags & (ATGE_PROMISC | ATGE_ALL_MULTICST)) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mchash = ~0ULL;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_filter_flags & ATGE_PROMISC)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra rxcfg |= ATGE_CFG_PROMISC;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (atgep->atge_filter_flags & ATGE_ALL_MULTICST)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra rxcfg |= ATGE_CFG_ALLMULTI;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra } else {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mchash = atgep->atge_mchash;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_program_ether(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_MAR0, (uint32_t)mchash);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_MAR1, (uint32_t)(mchash >> 32));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_MAC_CFG, rxcfg);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() mac_cfg is : %x, mchash : %llx",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__, rxcfg, mchash));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_device_stop(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uint32_t reg;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int t;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * If the chip is being suspended, then don't touch the state. Caller
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * will take care of setting the correct state.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (!(atgep->atge_chip_state & ATGE_CHIP_SUSPENDED)) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_chip_state |= ATGE_CHIP_STOPPED;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_chip_state &= ~ATGE_CHIP_RUNNING;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Collect stats for L1E. L1 chip's stats are collected by interrupt.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_gather_stats(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Disable interrupts.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_disable_intrs(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Clear CTRL not required. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Stop DMA Engine not required. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Disable queue processing.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Stop TxQ */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = INL(atgep, ATGE_TXQ_CFG);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = reg & ~TXQ_CFG_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_TXQ_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Stop RxQ */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = INL(atgep, ATGE_RXQ_CFG);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = reg & ~RXQ_CFG_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_RXQ_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Stop DMA */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = INL(atgep, ATGE_DMA_CFG);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = reg & ~(DMA_CFG_TXCMB_ENB | DMA_CFG_RXCMB_ENB);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_DMA_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills drv_usecwait(1000);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1e_stop_mac(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_INTR_STATUS, 0xFFFFFFFF);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Clear CTRL. */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra OUTL(atgep, L1_CSMB_CTRL, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Stop DMA Engine */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1_stop_tx_mac(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1_stop_rx_mac(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra reg = INL(atgep, ATGE_DMA_CFG);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra reg &= ~(DMA_CFG_RD_ENB | DMA_CFG_WR_ENB);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra OUTL(atgep, ATGE_DMA_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Disable queue processing.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Stop TxQ */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = INL(atgep, ATGE_TXQ_CFG);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = reg & ~TXQ_CFG_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_TXQ_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Stop RxQ */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = INL(atgep, ATGE_RXQ_CFG);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = reg & ~RXQ_CFG_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_RXQ_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Clear CTRL not required. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Stop DMA Engine */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_stop_tx_mac(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_stop_rx_mac(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra reg = INL(atgep, ATGE_DMA_CFG);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg &= ~(DMA_CFG_RD_ENB | DMA_CFG_WR_ENB);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_DMA_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /*
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills * Disable queue processing.
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Stop TxQ */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = INL(atgep, L1C_TXQ_CFG);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = reg & ~TXQ_CFG_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, L1C_TXQ_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Stop RxQ */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = INL(atgep, ATGE_RXQ_CFG);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills reg = reg & ~RXQ_CFG_ENB;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_RXQ_CFG, reg);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra for (t = ATGE_RESET_TIMEOUT; t > 0; t--) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((reg = INL(atgep, ATGE_IDLE_STATUS)) == 0)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra drv_usecwait(10);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (t == 0) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_error(atgep->atge_dip, "%s() stopping TX/RX MAC timeout",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra __func__);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_disable_intrs(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_INTR_MASK, 0);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra OUTL(atgep, ATGE_INTR_STATUS, 0xFFFFFFFF);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_device_init(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_intrs = L1E_INTRS;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_int_mod = ATGE_IM_TIMER_DEFAULT;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_init_tx_ring(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_l1e_init_rx_pages(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atgep->atge_intrs = L1_INTRS | INTR_GPHY | INTR_PHY_LINK_DOWN |
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra INTR_LINK_CHG;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atgep->atge_int_mod = ATGE_IM_TIMER_DEFAULT;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1_init_tx_ring(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1_init_rx_ring(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1_init_rr_ring(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1_init_cmb(atgep);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1_init_smb(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_intrs = L1C_INTRS | L1C_INTR_GPHY |
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills L1C_INTR_PHY_LINK_DOWN;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_int_rx_mod = 400/2;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atgep->atge_int_tx_mod = 2000/1;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_init_tx_ring(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_init_rx_ring(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_init_rr_ring(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_init_cmb(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_init_smb(atgep);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills /* Enable all clocks. */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills OUTL(atgep, ATGE_CLK_GATING_CFG, 0);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misravoid
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_device_restart(atge_t *atgep)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(MUTEX_HELD(&atgep->atge_intr_lock));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(MUTEX_HELD(&atgep->atge_tx_lock));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Cancel any pending I/O.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_stop(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Reset the chip to a known state.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_reset(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Initialize the ring and other descriptor like CMB/SMB/Rx return.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_init(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Start the chip.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_device_start(atgep);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic int
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraatge_send_a_packet(atge_t *atgep, mblk_t *mp)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra uchar_t *c;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra uint32_t cflags = 0;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atge_ring_t *r;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra size_t pktlen;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra uchar_t *buf;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int start;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(MUTEX_HELD(&atgep->atge_tx_lock));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ASSERT(mp != NULL);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra pktlen = msgsize(mp);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (pktlen > atgep->atge_tx_buf_len) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_macxmt_errors++;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra ATGE_DB(("%s: %s() pktlen (%d) > rx_buf_len (%d)",
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_name, __func__,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra pktlen, atgep->atge_rx_buf_len));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra freemsg(mp);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_SUCCESS);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra r = atgep->atge_tx_ring;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if (r->r_avail_desc <= 1) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_noxmtbuf++;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra atgep->atge_tx_resched = 1;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ATGE_DB(("%s: %s() No transmit buf",
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atgep->atge_name, __func__));
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_FAILURE);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra start = r->r_producer;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Get the DMA buffer to hold a packet.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra buf = (uchar_t *)r->r_buf_tbl[start]->addr;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Copy the msg and free mp
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mcopymsg(mp, buf);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra r->r_avail_desc--;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra c = (uchar_t *)r->r_desc_ring->addr;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills l1c_tx_desc_t *txd;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills c += (sizeof (l1c_tx_desc_t) * start);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills txd = (l1c_tx_desc_t *)c;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_PUT64(r->r_desc_ring, &txd->addr,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills r->r_buf_tbl[start]->cookie.dmac_laddress);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_PUT32(r->r_desc_ring, &txd->len, L1C_TX_BYTES(pktlen));
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills cflags |= L1C_TD_EOP;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_PUT32(r->r_desc_ring, &txd->flags, cflags);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills default:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_tx_desc_t *txd;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills c += (sizeof (atge_tx_desc_t) * start);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills txd = (atge_tx_desc_t *)c;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_PUT64(r->r_desc_ring, &txd->addr,
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills r->r_buf_tbl[start]->cookie.dmac_laddress);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_PUT32(r->r_desc_ring, &txd->len, ATGE_TX_BYTES(pktlen));
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills cflags |= ATGE_TD_EOP;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills ATGE_PUT32(r->r_desc_ring, &txd->flags, cflags);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills }
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * Sync buffer first.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra DMA_SYNC(r->r_buf_tbl[start], 0, pktlen, DDI_DMA_SYNC_FORDEV);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * Increment TX producer count by one.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ATGE_INC_SLOT(r->r_producer, ATGE_TX_RING_CNT);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra /*
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra * Sync descriptor table.
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra */
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra DMA_SYNC(r->r_desc_ring, 0, ATGE_TX_RING_SZ, DDI_DMA_SYNC_FORDEV);
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra /*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Program TX descriptor to send a packet.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills switch (ATGE_MODEL(atgep)) {
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1E:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1e_send_packet(r);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1:
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra atge_l1_send_packet(r);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills case ATGE_CHIP_L1C:
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills atge_l1c_send_packet(r);
5e8715b93d1d651ab2805b5e6e98b17df49fa92fGary Mills break;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra r->r_atge->atge_opackets++;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra r->r_atge->atge_obytes += pktlen;
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra ATGE_DB(("%s: %s() pktlen : %d, avail_desc : %d, producer :%d, "
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra "consumer : %d", atgep->atge_name, __func__, pktlen,
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra r->r_avail_desc, r->r_producer, r->r_consumer));
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra
0eb090a7674ebcdcb1c35501097edeb5f2395459Saurabh Misra return (DDI_SUCCESS);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Stream Information.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh MisraDDI_DEFINE_STREAM_OPS(atge_devops, nulldev, nulldev, atge_attach, atge_detach,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra nodev, NULL, D_MP, NULL, atge_quiesce);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * Module linkage information.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic struct modldrv atge_modldrv = {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra &mod_driverops, /* Type of Module */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra "Atheros/Attansic Gb Ethernet", /* Description */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra &atge_devops /* drv_dev_ops */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra};
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misrastatic struct modlinkage atge_modlinkage = {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra MODREV_1, /* ml_rev */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra (void *)&atge_modldrv,
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra NULL
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra};
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra/*
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra * DDI Entry points.
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra */
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra_init(void)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int r;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mac_init_ops(&atge_devops, "atge");
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((r = mod_install(&atge_modlinkage)) != DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mac_fini_ops(&atge_devops);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (r);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra_fini(void)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra int r;
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra if ((r = mod_remove(&atge_modlinkage)) == DDI_SUCCESS) {
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra mac_fini_ops(&atge_devops);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra }
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (r);
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misraint
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra_info(struct modinfo *modinfop)
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra{
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra return (mod_info(&atge_modlinkage, modinfop));
015a6ef6781cc3ceba8ad3bfbae98449b6002a1fSaurabh Misra}