cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * CDDL HEADER START
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * The contents of this file are subject to the terms of the
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Common Development and Distribution License (the "License").
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * You may not use this file except in compliance with the License.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * or http://www.opensolaris.org/os/licensing.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * See the License for the specific language governing permissions
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * and limitations under the License.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * When distributing Covered Code, include this CDDL HEADER in each
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * If applicable, add the following below this CDDL HEADER, with the
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * fields enclosed by brackets "[]" replaced with your own identifying
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * information: Portions Copyright [yyyy] [name of copyright owner]
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * CDDL HEADER END
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls -- REALTEK 8139-serials PCI Fast Ethernet Driver, Depends on the
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Generic LAN Driver utility functions in /kernel/misc/mac
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * This product is covered by one or more of the following patents:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * US5,307,459, US5,434,872, US5,732,094, US6,570,884, US6,115,776, and
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * US6,327,625.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Currently supports:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * RTL8139
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/types.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/debug.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/errno.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/stropts.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/stream.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/kmem.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/conf.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/ddi.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/devops.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/ksynch.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/stat.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/conf.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/modctl.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/dlpi.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/ethernet.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/vlan.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/strsun.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/pci.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/sunddi.h>
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore#include <sys/mii.h>
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore#include <sys/miiregs.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/mac_provider.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include <sys/mac_ether.h>
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#include "rtls.h"
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Declarations and Module Linkage
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * This is the string displayed by modinfo, etc.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic char rtls_ident[] = "RealTek 8139 Ethernet driver";
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#ifdef RTLS_DEBUG
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amoreint rtls_debug = 0;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#endif
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Required system entry points
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int rtls_attach(dev_info_t *, ddi_attach_cmd_t);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int rtls_detach(dev_info_t *, ddi_detach_cmd_t);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int rtls_quiesce(dev_info_t *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Required driver entry points for MAC
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int rtls_m_start(void *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void rtls_m_stop(void *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int rtls_m_unicst(void *, const uint8_t *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int rtls_m_multicst(void *, boolean_t, const uint8_t *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int rtls_m_promisc(void *, boolean_t);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic mblk_t *rtls_m_tx(void *, mblk_t *);
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyerstatic int rtls_m_getprop(void *, const char *, mac_prop_id_t, uint_t,
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer void *);
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyerstatic int rtls_m_setprop(void *, const char *, mac_prop_id_t, uint_t,
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer const void *);
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyerstatic void rtls_m_propinfo(void *, const char *, mac_prop_id_t,
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer mac_prop_info_handle_t);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int rtls_m_stat(void *, uint_t, uint64_t *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic uint_t rtls_intr(caddr_t);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore/*
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore * MII entry points
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore */
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amorestatic uint16_t rtls_mii_read(void *, uint8_t, uint8_t);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amorestatic void rtls_mii_write(void *, uint8_t, uint8_t, uint16_t);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amorestatic void rtls_mii_notify(void *, link_state_t);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Internal functions used by the above entry points
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int rtls_chip_reset(rtls_t *, boolean_t);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void rtls_chip_init(rtls_t *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void rtls_chip_stop(rtls_t *rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void rtls_chip_start(rtls_t *rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void rtls_chip_restart(rtls_t *rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void rtls_get_mac_addr(rtls_t *, uint8_t *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void rtls_set_mac_addr(rtls_t *, const uint8_t *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic uint_t rtls_hash_index(const uint8_t *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic boolean_t rtls_send(rtls_t *, mblk_t *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void rtls_receive(rtls_t *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Buffer Management Routines
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int rtls_alloc_bufs(rtls_t *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void rtls_free_bufs(rtls_t *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int rtls_alloc_dma_mem(rtls_t *, size_t, ddi_device_acc_attr_t *,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint_t, dma_area_t *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void rtls_free_dma_mem(dma_area_t *);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#ifdef RTLS_DEBUG
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void rtls_reg_print(rtls_t *); /* debug routine */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#endif
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#define RTLS_DRIVER_NAME "rtls"
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Used for buffers allocated by ddi_dma_mem_alloc()
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic ddi_dma_attr_t dma_attr = {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DMA_ATTR_V0, /* dma_attr version */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore 0, /* dma_attr_addr_lo */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (uint_t)0xFFFFFFFF, /* dma_attr_addr_hi */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore 0x7FFFFFFF, /* dma_attr_count_max */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore 4, /* dma_attr_align */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore 0x3F, /* dma_attr_burstsizes */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore 1, /* dma_attr_minxfer */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (uint_t)0xFFFFFFFF, /* dma_attr_maxxfer */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (uint_t)0xFFFFFFFF, /* dma_attr_seg */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore 1, /* dma_attr_sgllen */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore 1, /* dma_attr_granular */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore 0, /* dma_attr_flags */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore};
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * PIO access attributes for registers
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic ddi_device_acc_attr_t rtls_reg_accattr = {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DDI_DEVICE_ATTR_V0,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DDI_STRUCTURE_LE_ACC,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DDI_STRICTORDER_ACC
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore};
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * DMA access attributes for data
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic ddi_device_acc_attr_t rtls_buf_accattr = {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DDI_DEVICE_ATTR_V0,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DDI_NEVERSWAP_ACC,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DDI_STRICTORDER_ACC
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore};
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amoreuchar_t rtls_broadcastaddr[] = {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore};
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic mac_callbacks_t rtls_m_callbacks = {
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer MC_PROPERTIES,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_m_stat,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_m_start,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_m_stop,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_m_promisc,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_m_multicst,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_m_unicst,
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer rtls_m_tx,
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer NULL,
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer NULL, /* mc_ioctl */
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer NULL, /* mc_getcapab */
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer NULL, /* mc_open */
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer NULL, /* mc_close */
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer rtls_m_setprop,
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer rtls_m_getprop,
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer rtls_m_propinfo
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore};
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amorestatic mii_ops_t rtls_mii_ops = {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore MII_OPS_VERSION,
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_mii_read,
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_mii_write,
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_mii_notify, /* notify */
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore NULL, /* reset */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore};
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'AmoreDDI_DEFINE_STREAM_OPS(rtls_dev_ops, nulldev, nulldev, rtls_attach, rtls_detach,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore nodev, NULL, D_MP, NULL, rtls_quiesce);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Standard module linkage initialization for a MAC driver
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic struct modldrv rtls_modldrv = {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore &mod_driverops, /* type of module. This one is a driver */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_ident, /* short description */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore &rtls_dev_ops /* driver specific ops */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore};
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic struct modlinkage modlinkage = {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore MODREV_1, { (void *)&rtls_modldrv, NULL }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore};
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * ========== RealTek chip register access Routines ==========
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic uint8_t rtls_reg_get8(rtls_t *rtlsp, uint32_t reg);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#pragma inline(rtls_reg_get8)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic uint8_t
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_reg_get8(rtls_t *rtlsp, uint32_t reg)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint8_t *addr;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore addr = REG8(rtlsp->io_reg, reg);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (ddi_get8(rtlsp->io_handle, addr));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic uint16_t rtls_reg_get16(rtls_t *rtlsp, uint32_t reg);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#pragma inline(rtls_reg_get16)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic uint16_t
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_reg_get16(rtls_t *rtlsp, uint32_t reg)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint16_t *addr;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore addr = REG16(rtlsp->io_reg, reg);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (ddi_get16(rtlsp->io_handle, addr));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic uint32_t rtls_reg_get32(rtls_t *rtlsp, uint32_t reg);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#pragma inline(rtls_reg_get32)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic uint32_t
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_reg_get32(rtls_t *rtlsp, uint32_t reg)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t *addr;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore addr = REG32(rtlsp->io_reg, reg);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (ddi_get32(rtlsp->io_handle, addr));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void rtls_reg_set8(rtls_t *rtlsp, uint32_t reg, uint8_t value);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#pragma inline(rtls_reg_set8)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_reg_set8(rtls_t *rtlsp, uint32_t reg, uint8_t value)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint8_t *addr;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore addr = REG8(rtlsp->io_reg, reg);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_put8(rtlsp->io_handle, addr, value);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void rtls_reg_set16(rtls_t *rtlsp, uint32_t reg, uint16_t value);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#pragma inline(rtls_reg_set16)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_reg_set16(rtls_t *rtlsp, uint32_t reg, uint16_t value)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint16_t *addr;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore addr = REG16(rtlsp->io_reg, reg);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_put16(rtlsp->io_handle, addr, value);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void rtls_reg_set32(rtls_t *rtlsp, uint32_t reg, uint32_t value);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#pragma inline(rtls_reg_set32)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_reg_set32(rtls_t *rtlsp, uint32_t reg, uint32_t value)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t *addr;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore addr = REG32(rtlsp->io_reg, reg);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_put32(rtlsp->io_handle, addr, value);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * ========== Module Loading Entry Points ==========
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amoreint
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore_init(void)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore int rv;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mac_init_ops(&rtls_dev_ops, RTLS_DRIVER_NAME);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if ((rv = mod_install(&modlinkage)) != DDI_SUCCESS) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mac_fini_ops(&rtls_dev_ops);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (rv);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amoreint
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore_fini(void)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore int rv;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if ((rv = mod_remove(&modlinkage)) == DDI_SUCCESS) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mac_fini_ops(&rtls_dev_ops);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (rv);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amoreint
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore_info(struct modinfo *modinfop)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (mod_info(&modlinkage, modinfop));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * ========== DDI Entry Points ==========
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * attach(9E) -- Attach a device to the system
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Called once for each board successfully probed.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_t *rtlsp; /* Our private device info */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_acc_handle_t pci_handle;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint16_t pci_commond;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint16_t vendorid;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint16_t deviceid;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t device;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mac_register_t *macp;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore int err;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore switch (cmd) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case DDI_ATTACH:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case DDI_RESUME:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if ((rtlsp = ddi_get_driver_private(devinfo)) == NULL) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Turn on Master Enable (DMA) and IO Enable bits.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Enable PCI Memory Space accesses
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Disable Memory Write/Invalidate
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (pci_config_setup(devinfo, &pci_handle) != DDI_SUCCESS) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore pci_commond = pci_config_get16(pci_handle, PCI_CONF_COMM);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore pci_commond &= ~PCI_COMM_MEMWR_INVAL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore pci_commond |= PCI_COMM_ME | PCI_COMM_MAE | PCI_COMM_IO;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore pci_config_put32(pci_handle, PCI_CONF_COMM, pci_commond);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore pci_config_teardown(&pci_handle);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_chip_restart(rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->chip_error = B_FALSE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->tx_retry = 0;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->rtls_suspended = B_FALSE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore mii_resume(rtlsp->mii);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mac_tx_update(rtlsp->mh);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_SUCCESS);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore default:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * we don't support high level interrupts in the driver
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (ddi_intr_hilevel(devinfo, 0) != 0) {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore cmn_err(CE_WARN, "unsupported high level interrupt");
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Get handle to access pci configuration space
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (pci_config_setup(devinfo, &pci_handle) != DDI_SUCCESS) {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore cmn_err(CE_WARN, "pci_config_setup fail.");
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Make sure we support this particular vendor/device
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore vendorid = pci_config_get16(pci_handle, PCI_CONF_VENID);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore deviceid = pci_config_get16(pci_handle, PCI_CONF_DEVID);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore device = vendorid;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore device = (device << 16) | deviceid; /* combine two id together */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * See if we support this device
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * We do not return for wrong device id. It's user risk.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore switch (device) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore default:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_WARN,
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore "RTLS doesn't support this device: "
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore "vendorID = 0x%x, deviceID = 0x%x",
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore vendorid, deviceid);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case RTLS_SUPPORT_DEVICE_1:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case RTLS_SUPPORT_DEVICE_2:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case RTLS_SUPPORT_DEVICE_3:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case RTLS_SUPPORT_DEVICE_4:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Turn on Master Enable (DMA) and IO Enable bits.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Enable PCI Memory Space accesses
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Disable Memory Write/Invalidate
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore pci_commond = pci_config_get16(pci_handle, PCI_CONF_COMM);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore pci_commond &= ~PCI_COMM_MEMWR_INVAL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore pci_commond |= PCI_COMM_ME | PCI_COMM_MAE | PCI_COMM_IO;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore pci_config_put32(pci_handle, PCI_CONF_COMM, pci_commond);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Free handle to access pci configuration space
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore pci_config_teardown(&pci_handle);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp = kmem_zalloc(sizeof (rtls_t), KM_SLEEP);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_set_driver_private(devinfo, rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->devinfo = devinfo;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->instance = ddi_get_instance(devinfo);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Map operating register
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore err = ddi_regs_map_setup(devinfo, 1, &rtlsp->io_reg,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (offset_t)0, 0, &rtls_reg_accattr, &rtlsp->io_handle);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (err != DDI_SUCCESS) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore kmem_free((caddr_t)rtlsp, sizeof (rtls_t));
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore cmn_err(CE_WARN, "ddi_regs_map_setup fail.");
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Allocate the TX and RX descriptors/buffers
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rtls_alloc_bufs(rtlsp) == DDI_FAILURE) {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore cmn_err(CE_WARN, "DMA buffer allocation fail.");
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore goto fail;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Reset the chip
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore err = rtls_chip_reset(rtlsp, B_FALSE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (err != DDI_SUCCESS)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore goto fail;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Init rtls_t structure
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_get_mac_addr(rtlsp, rtlsp->netaddr);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Add the interrupt handler
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * This will prevent receiving interrupts before device is ready, as
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * we are initializing device after setting the interrupts. So we
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * will not get our interrupt handler invoked by OS while our device
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * is still coming up or timer routines will not start till we are
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * all set to process...
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (ddi_add_intr(devinfo, 0, &rtlsp->iblk, NULL, rtls_intr,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (caddr_t)rtlsp) != DDI_SUCCESS) {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore cmn_err(CE_WARN, "ddi_add_intr fail.");
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore goto late_fail;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore }
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore if ((rtlsp->mii = mii_alloc(rtlsp, devinfo, &rtls_mii_ops)) == NULL) {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore ddi_remove_intr(devinfo, 0, rtlsp->iblk);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore goto late_fail;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore /*
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore * Note: Some models of 8139 can support pause, but we have
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore * not implemented support for it at this time. This might be
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore * an interesting feature to add later.
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore */
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore mii_set_pauseable(rtlsp->mii, B_FALSE, B_FALSE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore cmn_err(CE_WARN, "mac_alloc fail.");
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_remove_intr(devinfo, 0, rtlsp->iblk);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore goto late_fail;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Init mutex
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_init(&rtlsp->rtls_io_lock, NULL, MUTEX_DRIVER, rtlsp->iblk);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_init(&rtlsp->rtls_tx_lock, NULL, MUTEX_DRIVER, rtlsp->iblk);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_init(&rtlsp->rtls_rx_lock, NULL, MUTEX_DRIVER, rtlsp->iblk);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Initialize pointers to device specific functions which will be
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * used by the generic layer.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore macp->m_driver = rtlsp;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore macp->m_dip = devinfo;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore macp->m_src_addr = rtlsp->netaddr;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore macp->m_callbacks = &rtls_m_callbacks;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore macp->m_min_sdu = 0;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore macp->m_max_sdu = ETHERMTU;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore macp->m_margin = VLAN_TAGSZ;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (mac_register(macp, &rtlsp->mh) != 0) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_remove_intr(devinfo, 0, rtlsp->iblk);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_destroy(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_destroy(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_destroy(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore goto late_fail;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mac_free(macp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_SUCCESS);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorelate_fail:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (macp)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mac_free(macp);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore if (rtlsp->mii)
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore mii_free(rtlsp->mii);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorefail:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_regs_map_free(&rtlsp->io_handle);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_free_bufs(rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore kmem_free(rtlsp, sizeof (rtls_t));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * detach(9E) -- Detach a device from the system
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_t *rtlsp; /* our private device info */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Get the driver private structure
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if ((rtlsp = ddi_get_driver_private(devinfo)) == NULL) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore switch (cmd) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case DDI_DETACH:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case DDI_SUSPEND:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore mii_suspend(rtlsp->mii);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->rtls_suspended = B_TRUE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_chip_stop(rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_SUCCESS);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore default:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (mac_unregister(rtlsp->mh) != 0) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /* device busy */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_remove_intr(devinfo, 0, rtlsp->iblk);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore mii_free(rtlsp->mii);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_destroy(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_destroy(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_destroy(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_regs_map_free(&rtlsp->io_handle);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_free_bufs(rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore kmem_free(rtlsp, sizeof (rtls_t));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_SUCCESS);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * quiesce(9E) entry point.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * This function is called when the system is single-threaded at high
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * PIL with preemption disabled. Therefore, this function must not be
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * blocked.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * DDI_FAILURE indicates an error condition and should almost never happen.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_quiesce(dev_info_t *devinfo)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_t *rtlsp; /* our private device info */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Get the driver private structure
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if ((rtlsp = ddi_get_driver_private(devinfo)) == NULL) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (rtls_chip_reset(rtlsp, B_TRUE));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * ========== MAC Entry Points ==========
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_m_start() -- start the board receiving and allow transmits
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_m_start(void *arg)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_t *rtlsp = (rtls_t *)arg;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (!rtlsp->rtls_suspended)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_chip_restart(rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->rtls_running = B_TRUE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore drv_usecwait(100);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore mii_start(rtlsp->mii);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (0);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_m_stop() -- stop board receiving and transmits
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_m_stop(void *arg)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_t *rtlsp = (rtls_t *)arg;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore mii_stop(rtlsp->mii);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (!rtlsp->rtls_suspended)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_chip_stop(rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->rtls_running = B_FALSE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_m_unicst() -- set the physical network address
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * on the board
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_m_unicst(void *arg, const uint8_t *macaddr)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_t *rtlsp = arg;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore bcopy(macaddr, rtlsp->netaddr, ETHERADDRL);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (!rtlsp->rtls_suspended)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_set_mac_addr(rtlsp, rtlsp->netaddr);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (0);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_m_multicst() -- set(enable) or disable a multicast address
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Program the hardware to enable/disable the multicast address in "mcast".
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_m_multicst(void *arg, boolean_t enable, const uint8_t *mcast)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_t *rtlsp = (rtls_t *)arg;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint_t index;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t *hashp;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore hashp = rtlsp->multi_hash;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore index = rtls_hash_index(mcast);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /* index value is between 0 and 63 */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (enable) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rtlsp->multicast_cnt[index]++) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (0);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore hashp[index/32] |= 1<< (index % 32);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore } else {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (--rtlsp->multicast_cnt[index]) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (0);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore hashp[index/32] &= ~(1<< (index % 32));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Set multicast register
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (!rtlsp->rtls_suspended) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, MULTICAST_0_REG, hashp[0]);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, MULTICAST_4_REG, hashp[1]);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (0);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_hash_index() -- a hashing function used for setting the
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * node address or a multicast address
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic uint_t
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_hash_index(const uint8_t *address)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t crc = (ulong_t)RTLS_HASH_CRC;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t const POLY = RTLS_HASH_POLY;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t msb;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore int bytes;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uchar_t currentbyte;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint_t index;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore int bit;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore for (bytes = 0; bytes < ETHERADDRL; bytes++) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore currentbyte = address[bytes];
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore for (bit = 0; bit < 8; bit++) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore msb = crc >> 31;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore crc <<= 1;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (msb ^ (currentbyte & 1)) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore crc ^= POLY;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore crc |= 0x00000001;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore currentbyte >>= 1;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore index = crc >> 26;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (index);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_m_promisc() -- set or reset promiscuous mode on the board
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_m_promisc(void *arg, boolean_t on)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_t *rtlsp = arg;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->promisc = on;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (!rtlsp->rtls_suspended) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t val32 = rtls_reg_get32(rtlsp, RX_CONFIG_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (on) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 |= RX_ACCEPT_ALL_PACKET;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore } else {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 &= ~RX_ACCEPT_ALL_PACKET;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, RX_CONFIG_REG, val32);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (0);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_m_stat() -- retrieve statistic
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * MAC calls this routine just before it reads the driver's statistics
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * structure. If your board maintains statistics, this is the time to
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * read them in and update the values in the structure. If the driver
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * maintains statistics continuously, this routine need do nothing.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_m_stat(void *arg, uint_t stat, uint64_t *val)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_t *rtlsp = arg;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore if (mii_m_getstat(rtlsp->mii, stat, val) == 0) {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore return (0);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore switch (stat) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case MAC_STAT_IPACKETS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.ipackets;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case MAC_STAT_RBYTES:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.rbytes;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case MAC_STAT_OPACKETS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.opackets;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case MAC_STAT_OBYTES:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.obytes;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case MAC_STAT_IERRORS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.rcv_err;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case MAC_STAT_OERRORS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.xmt_err;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case MAC_STAT_MULTIRCV:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.multi_rcv;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case MAC_STAT_BRDCSTRCV:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.brdcst_rcv;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case MAC_STAT_MULTIXMT:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.multi_xmt;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case MAC_STAT_BRDCSTXMT:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.brdcst_xmt;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case MAC_STAT_UNDERFLOWS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.underflow;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case MAC_STAT_OVERFLOWS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.overflow;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case MAC_STAT_NORCVBUF:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.no_rcvbuf;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case MAC_STAT_COLLISIONS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.collisions;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case ETHER_STAT_FCS_ERRORS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.crc_err;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case ETHER_STAT_ALIGN_ERRORS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.frame_err;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case ETHER_STAT_DEFER_XMTS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.defer;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case ETHER_STAT_TX_LATE_COLLISIONS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.xmt_latecoll;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case ETHER_STAT_TOOLONG_ERRORS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.too_long;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case ETHER_STAT_TOOSHORT_ERRORS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.in_short;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case ETHER_STAT_CARRIER_ERRORS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.no_carrier;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case ETHER_STAT_FIRST_COLLISIONS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.firstcol;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore case ETHER_STAT_MULTI_COLLISIONS:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *val = rtlsp->stats.multicol;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore default:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (ENOTSUP);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * RTL8139 don't support MII statistics,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * these values are maintained by the driver software.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#ifdef RTLS_DEBUG
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rtls_debug & RTLS_TRACE)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_print(rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#endif
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (0);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyerint
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyerrtls_m_getprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz,
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer void *val)
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer{
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer rtls_t *rtlsp = arg;
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer return (mii_m_getprop(rtlsp->mii, name, num, sz, val));
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer}
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyerint
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyerrtls_m_setprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz,
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer const void *val)
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer{
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer rtls_t *rtlsp = arg;
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer return (mii_m_setprop(rtlsp->mii, name, num, sz, val));
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer}
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyerstatic void
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyerrtls_m_propinfo(void *arg, const char *name, mac_prop_id_t num,
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer mac_prop_info_handle_t prh)
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer{
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer rtls_t *rtlsp = arg;
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer mii_m_propinfo(rtlsp->mii, name, num, prh);
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer}
ace3c3ff753a94432e3a936c2931b81a66cd03d1Venugopal Iyer
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_send() -- send a packet
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Called when a packet is ready to be transmitted. A pointer to an
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * M_DATA message that contains the packet is passed to this routine.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * The complete LLC header is contained in the message's first message
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * block, and the remainder of the packet is contained within
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * additional M_DATA message blocks linked to the first message block.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Returns B_TRUE if the packet was properly disposed of, or B_FALSE if
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * if the packet is being deferred and should be tried again later.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic boolean_t
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_send(rtls_t *rtlsp, mblk_t *mp)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore int totlen;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore int ncc;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint16_t cur_desc;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t tx_status;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ASSERT(mp != NULL);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ASSERT(rtlsp->rtls_running);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rtlsp->rtls_suspended) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (B_FALSE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * If chip error ...
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rtlsp->chip_error) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#ifdef RTLS_DEBUG
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_WARN,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore "%s: send fail--CHIP ERROR!",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#endif
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore freemsg(mp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (B_TRUE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore * If chip link down ... Note that experimentation shows that
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore * the device seems not to care about whether or not we have
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore * this check, but if we don't add the check here, it might
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore * not be properly reported as a carrier error.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore if (rtls_reg_get8(rtlsp, MEDIA_STATUS_REG) & MEDIA_STATUS_LINK) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#ifdef RTLS_DEBUG
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_WARN,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore "%s: send fail--LINK DOWN!",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#endif
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.no_carrier++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore freemsg(mp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (B_TRUE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Current transmit descriptor
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cur_desc = rtlsp->tx_current_desc;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ASSERT(cur_desc < RTLS_MAX_TX_DESC);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * RealTek 8139 has 4 tx descriptor for transmit. In the first tx loop
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * of transmit,we needn't judge transmit status.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rtlsp->tx_first_loop < RTLS_MAX_TX_DESC) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->tx_first_loop++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore goto tx_ready;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * If it's not the first tx loop, we need judge whether the chip is
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * busy or not. Otherwise, we have to reschedule send and wait...
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore tx_status = rtls_reg_get32(rtlsp, TX_STATUS_DESC0_REG + 4 * cur_desc);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * H/W doesn't complete packet transmit
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (!(tx_status & TX_COMPLETE_FLAG)) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#ifdef RTLS_DEBUG
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rtls_debug & RTLS_SEND) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_NOTE,
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok "%s: rtls_send: need_sched", mac_name(rtlsp->mh));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#endif
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Through test, we find RTL8139 tx status might be
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * not-completing all along. We have to reset chip
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * to make RTL8139 tansmit re-work.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rtlsp->tx_retry++ > RTLS_TX_RETRY_NUM) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Wait transmit h/w more time...
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore RTLS_TX_WAIT_TIMEOUT; /* 100 ms */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Judge tx status again, if it remains not-completing,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * we can confirm RTL8139 is in chip error state
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * and must reset it.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore tx_status = rtls_reg_get32(rtlsp,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore TX_STATUS_DESC0_REG + 4 * cur_desc);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (!(tx_status & TX_COMPLETE_FLAG)) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#ifdef RTLS_DEBUG
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_NOTE, "%s: tx chip_error = 0x%x",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), tx_status);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#endif
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->tx_retry = 0;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->chip_error = B_TRUE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.xmt_err++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.mac_xmt_err++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore freemsg(mp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (B_TRUE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore } else {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.defer++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->need_sched = B_TRUE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (B_FALSE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Transmit error?
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (tx_status & TX_ERR_FLAG) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#ifdef RTLS_DEBUG
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rtls_debug & RTLS_SEND) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_NOTE, "%s: transmit error, status = 0x%x",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), tx_status);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#endif
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.xmt_err++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (tx_status & TX_STATUS_TX_UNDERRUN)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.underflow++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (tx_status & TX_STATUS_CS_LOST)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.no_carrier++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (tx_status & TX_STATUS_OWC)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.xmt_latecoll++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ncc = ((tx_status & TX_STATUS_NCC) >> TX_STATUS_NCC_SHIFT);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (ncc != 0) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.collisions += ncc;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.firstcol++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.multicol += ncc - 1;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amoretx_ready:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Initialize variable
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->tx_retry = 0;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore totlen = 0;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Copy packet to tx descriptor buffer
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore totlen = msgsize(mp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (totlen > (ETHERMAX + 4)) { /* 4 bytes for VLAN header */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_NOTE,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore "%s: rtls_send: try to send large %d packet",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), totlen);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.mac_xmt_err++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.xmt_err++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore freemsg(mp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (B_TRUE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /* this will free the mblk */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mcopymsg(mp, rtlsp->tx_buf[cur_desc]);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /* update stats */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (*rtlsp->tx_buf[cur_desc] & 0x1) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint16_t *ptr = (void *)rtlsp->tx_buf[cur_desc];
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if ((ptr[0] == 0xffff) &&
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (ptr[1] == 0xffff) &&
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (ptr[2] == 0xffff)) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.brdcst_xmt++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore } else {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.multi_xmt++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.opackets++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.obytes += totlen;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (totlen < ETHERMIN) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore bzero(rtlsp->tx_buf[cur_desc] + totlen, ETHERMIN - totlen);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore totlen = ETHERMIN;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /* make sure caches are flushed */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (void) ddi_dma_sync(rtlsp->dma_area_tx[cur_desc].dma_hdl, 0, totlen,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DDI_DMA_SYNC_FORDEV);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Start transmit
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * set transmit FIFO threshhold to 0x30*32 = 1536 bytes
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * to avoid tx underrun.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, TX_STATUS_DESC0_REG + 4 * cur_desc,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore totlen | (0x30 << TX_STATUS_TX_THRESHOLD_SHIFT));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Update the value of current tx descriptor
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cur_desc++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cur_desc %= RTLS_MAX_TX_DESC;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->tx_current_desc = cur_desc;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (B_TRUE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_m_tx() -- send a chain of packets, linked by mp->b_next.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic mblk_t *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_m_tx(void *arg, mblk_t *mp)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_t *rtlsp = arg;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mblk_t *next;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore while (mp != NULL) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore next = mp->b_next;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mp->b_next = NULL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (!rtls_send(rtlsp, mp)) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mp->b_next = next;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mp = next;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (mp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_receive() -- receive packets
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Called when receive interrupts detected
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_receive(rtls_t *rtlsp)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mblk_t *head = NULL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mblk_t **mpp;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mblk_t *mp;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint16_t rx_status;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint16_t packet_len;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore int wrap_size;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t cur_rx;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint8_t *rx_ptr;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mpp = &head;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rtlsp->rtls_suspended) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore while ((rtls_reg_get8(rtlsp, RT_COMMAND_REG)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore & RT_COMMAND_BUFF_EMPTY) == 0) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Chip error state
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rtlsp->chip_error) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#ifdef RTLS_DEBUG
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_WARN,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore "%s: receive fail--CHIP ERROR!",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#endif
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cur_rx = rtlsp->cur_rx;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rx_ptr = rtlsp->rx_ring + cur_rx;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore packet_len = (rx_ptr[3] << 8) | (rx_ptr[2]);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rx_status = rx_ptr[0];
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * DMA still in progress
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (packet_len == RX_STATUS_DMA_BUSY) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_NOTE, "%s: Rx DMA still in progress",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Check receive status
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if ((rx_status & RX_ERR_FLAGS) ||
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (!(rx_status & RX_HEADER_STATUS_ROK)) ||
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (packet_len < (ETHERMIN + ETHERFCSL)) ||
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (packet_len > (ETHERMAX + ETHERFCSL + 4))) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#ifdef RTLS_DEBUG
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_NOTE,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore "%s: receive error, status = 0x%x, length = %d",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), rx_status, packet_len);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#endif
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Rx error statistics
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if ((rx_status & RX_HEADER_STATUS_RUNT) ||
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (packet_len < (ETHERMIN + ETHERFCSL)))
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.in_short++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore else if (packet_len > (ETHERMAX + ETHERFCSL + 4))
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.too_long++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore else if (rx_status & RX_HEADER_STATUS_CRC)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.crc_err++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore else if (rx_status & RX_HEADER_STATUS_FAE)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.frame_err++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Set chip_error flag to reset chip:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * (suggested in RealTek programming guide.)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->chip_error = B_TRUE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * We need not up-send ETHERFCSL bytes of receive packet
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore packet_len -= ETHERFCSL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Allocate buffer to receive this good packet
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mp = allocb(packet_len, 0);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Copy the data found into the new cluster, we have (+4)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * to get us past the packet head data that the rtl chip
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * places at the start of the message
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if ((cur_rx + packet_len + RX_HEADER_SIZE)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore > RTLS_RX_BUF_RING) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore wrap_size = cur_rx + packet_len + RX_HEADER_SIZE
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore - RTLS_RX_BUF_RING;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#ifdef RTLS_DEBUG
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rtls_debug & RTLS_RECV) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_NOTE,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore "%s: Rx: packet_len = %d, wrap_size = %d",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), packet_len, wrap_size);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#endif
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (mp != NULL) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /* Flush caches */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (void) ddi_dma_sync(rtlsp->dma_area_rx.dma_hdl,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cur_rx + RX_HEADER_SIZE,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore packet_len - wrap_size,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DDI_DMA_SYNC_FORKERNEL);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (void) ddi_dma_sync(rtlsp->dma_area_rx.dma_hdl,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore 0, wrap_size,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DDI_DMA_SYNC_FORKERNEL);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Copy in first section of message as stored
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * at the end of the ring buffer
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore bcopy(rx_ptr + RX_HEADER_SIZE,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mp->b_wptr, packet_len - wrap_size);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mp->b_wptr += packet_len - wrap_size;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore bcopy(rtlsp->rx_ring, mp->b_wptr, wrap_size);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mp->b_wptr += wrap_size;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *mpp = mp;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mpp = &mp->b_next;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.ipackets++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rx_status & RX_HEADER_STATUS_BCAST)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.brdcst_rcv++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rx_status & RX_HEADER_STATUS_MULTI)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.multi_rcv++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.rbytes += packet_len;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore } else {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.no_rcvbuf++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cur_rx = RTLS_RX_ADDR_ALIGNED(wrap_size + ETHERFCSL);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /* 4-byte aligned */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore } else {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (mp != NULL) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /* Flush caches */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (void) ddi_dma_sync(rtlsp->dma_area_rx.dma_hdl,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cur_rx + RX_HEADER_SIZE, packet_len,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DDI_DMA_SYNC_FORKERNEL);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore bcopy(rx_ptr + RX_HEADER_SIZE, mp->b_wptr,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore packet_len);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mp->b_wptr += packet_len;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore *mpp = mp;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mpp = &mp->b_next;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.ipackets++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rx_status & RX_HEADER_STATUS_BCAST)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.brdcst_rcv++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rx_status & RX_HEADER_STATUS_MULTI)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.multi_rcv++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.rbytes += packet_len;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore } else {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.no_rcvbuf++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cur_rx += packet_len + RX_HEADER_SIZE + ETHERFCSL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cur_rx = RTLS_RX_ADDR_ALIGNED(cur_rx);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /* 4-byte aligned */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Update rx buffer ring read pointer:
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * give us a little leeway to ensure no overflow
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->cur_rx = cur_rx;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set16(rtlsp, RX_CURRENT_READ_ADDR_REG,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cur_rx - READ_ADDR_GAP);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Upsend packet
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (head) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mac_rx(rtlsp->mh, NULL, head);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_intr() -- interrupt from board to inform us that a receive or
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * link change.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic uint_t
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_intr(caddr_t arg)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_t *rtlsp = (void *)arg;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t int_status;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t val32;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore boolean_t resched = B_FALSE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_io_lock);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore if (rtlsp->rtls_suspended) {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore mutex_exit(&rtlsp->rtls_io_lock);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore return (DDI_INTR_UNCLAIMED);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Was this interrupt caused by our device...
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore int_status = rtls_reg_get16(rtlsp, RT_INT_STATUS_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (!(int_status & rtlsp->int_mask)) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_INTR_UNCLAIMED);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /* indicate it wasn't our interrupt */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Clear interrupt
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set16(rtlsp, RT_INT_STATUS_REG, int_status);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * If chip error, restart chip...
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rtlsp->chip_error) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_enter(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_chip_restart(rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->chip_error = B_FALSE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->tx_retry = 0;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_tx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_rx_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_INTR_CLAIMED);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /* no need to hand other interrupts */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Transmit error interrupt
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (int_status & TX_ERR_INT) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = rtls_reg_get32(rtlsp, TX_CONFIG_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 |= TX_CLEAR_ABORT;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, TX_CONFIG_REG, val32);
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok cmn_err(CE_WARN, "%s: transmit abort!!!", mac_name(rtlsp->mh));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Trigger mac_tx_update
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore if (rtlsp->need_sched) {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtlsp->need_sched = B_FALSE;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore resched = B_TRUE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mutex_exit(&rtlsp->rtls_io_lock);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Receive interrupt
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (int_status & RTLS_RX_INT) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (int_status & RX_OVERFLOW_INT) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.overflow++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->stats.rcv_err++;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_receive(rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore /*
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore * Link change interrupt.
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore */
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore if (int_status & LINK_CHANGE_INT) {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore mii_check(rtlsp->mii);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore if (resched) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore mac_tx_update(rtlsp->mh);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore return (DDI_INTR_CLAIMED); /* indicate it was our interrupt */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * ========== Buffer Management Routines ==========
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_alloc_dma_mem() -- allocate an area of memory and a DMA handle
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * for accessing it
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_alloc_dma_mem(rtls_t *rtlsp, size_t memsize,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_device_acc_attr_t *attr_p, uint_t dma_flags, dma_area_t *dma_p)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore caddr_t vaddr;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore int err;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Allocate handle
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore err = ddi_dma_alloc_handle(rtlsp->devinfo, &dma_attr,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (err != DDI_SUCCESS) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_WARN,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore "%s: rtls_alloc_dma_mem: ddi_dma_alloc_handle failed: %d",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), err);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore dma_p->dma_hdl = NULL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Allocate memory
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore dma_flags & (DDI_DMA_CONSISTENT | DDI_DMA_STREAMING),
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DDI_DMA_SLEEP, NULL, &vaddr, &dma_p->alength, &dma_p->acc_hdl);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (err != DDI_SUCCESS) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_WARN,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore "%s: rtls_alloc_dma_mem: ddi_dma_mem_alloc failed: %d",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), err);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_dma_free_handle(&dma_p->dma_hdl);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore dma_p->dma_hdl = NULL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore dma_p->acc_hdl = NULL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Bind the two together
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore dma_p->mem_va = vaddr;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore vaddr, dma_p->alength, dma_flags, DDI_DMA_SLEEP, NULL,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore &dma_p->cookie, &dma_p->ncookies);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (err != DDI_DMA_MAPPED || dma_p->ncookies != 1) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_WARN,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore "%s: rtls_alloc_dma_mem: "
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore "ddi_dma_addr_bind_handle failed: %d",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), err);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_dma_mem_free(&dma_p->acc_hdl);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_dma_free_handle(&dma_p->dma_hdl);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore dma_p->acc_hdl = NULL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore dma_p->dma_hdl = NULL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_SUCCESS);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_free_dma_mem() -- free one allocated area of DMAable memory
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_free_dma_mem(dma_area_t *dma_p)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (dma_p->dma_hdl != NULL) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (dma_p->ncookies) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (void) ddi_dma_unbind_handle(dma_p->dma_hdl);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore dma_p->ncookies = 0;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_dma_free_handle(&dma_p->dma_hdl);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore dma_p->dma_hdl = NULL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (dma_p->acc_hdl != NULL) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore ddi_dma_mem_free(&dma_p->acc_hdl);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore dma_p->acc_hdl = NULL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_alloc_bufs() -- allocate descriptors/buffers for this device instance
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_alloc_bufs(rtls_t *rtlsp)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore int i;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore int err;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Allocate memory & handle for Tx buffers
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore for (i = 0; i < RTLS_MAX_TX_DESC; i++) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore err = rtls_alloc_dma_mem(rtlsp,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore RTLS_TX_BUF_SIZE,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore &rtls_buf_accattr,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DDI_DMA_WRITE | DDI_DMA_STREAMING,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore &rtlsp->dma_area_tx[i]);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (err != DDI_SUCCESS)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->tx_buf[i] = (uint8_t *)rtlsp->dma_area_tx[i].mem_va;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Allocate memory & handle for Rx buffers
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore err = rtls_alloc_dma_mem(rtlsp,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore RTLS_RX_BUF_SIZE,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore &rtls_buf_accattr,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore DDI_DMA_READ | DDI_DMA_STREAMING,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore &rtlsp->dma_area_rx);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (err != DDI_SUCCESS)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->rx_ring = (uint8_t *)rtlsp->dma_area_rx.mem_va;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_SUCCESS);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_free_bufs() -- free descriptors/buffers allocated for this
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * device instance.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_free_bufs(rtls_t *rtlsp)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore int i;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore for (i = 0; i < RTLS_MAX_TX_DESC; i++) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_free_dma_mem(&rtlsp->dma_area_tx[i]);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->tx_buf[i] = NULL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_free_dma_mem(&rtlsp->dma_area_rx);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->rx_ring = NULL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * ========== Chip H/W Operation Routines ==========
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_chip_reset() -- reset chip
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic int
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_chip_reset(rtls_t *rtlsp, boolean_t quiesce)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore int i;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint16_t val16;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint8_t val8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Chip should be in STOP state
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val8 = rtls_reg_get8(rtlsp, RT_COMMAND_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val8 &= ~(RT_COMMAND_RX_ENABLE | RT_COMMAND_TX_ENABLE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set8(rtlsp, RT_COMMAND_REG, val8);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Disable interrupt
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val16 = rtls_reg_get16(rtlsp, RT_INT_MASK_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set16(rtlsp, RT_INT_MASK_REG, val16 & (~RTLS_INT_MASK_ALL));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->int_mask = RTLS_INT_MASK_NONE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Clear pended interrupt
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val16 = rtls_reg_get16(rtlsp, RT_INT_STATUS_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set16(rtlsp, RT_INT_STATUS_REG, val16);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Reset chip
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val8 = rtls_reg_get8(rtlsp, RT_COMMAND_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set8(rtlsp, RT_COMMAND_REG, val8 | RT_COMMAND_RESET);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Wait for reset success
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore i = 0;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore while (rtls_reg_get8(rtlsp, RT_COMMAND_REG) & RT_COMMAND_RESET) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (++i > RTLS_RESET_WAIT_NUM) {
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * At quiesce path we can't call cmn_err(), as
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * it might block
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (!quiesce)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_WARN,
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok "%s: chip reset fail.",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_FAILURE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore RTLS_RESET_WAIT_INTERVAL;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore return (DDI_SUCCESS);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_chip_init() -- initialize the specified network board short of
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * actually starting the board. Call after rtls_chip_reset().
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_chip_init(rtls_t *rtlsp)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t val32;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint16_t val16;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint8_t val8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Initialize internal data structures
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->cur_rx = 0;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->tx_current_desc = 0;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->tx_first_loop = 0;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Set DMA physical rx/tx buffer address to register
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, RX_BUFF_ADDR_REG,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (ulong_t)rtlsp->dma_area_rx.cookie.dmac_address);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, TX_ADDR_DESC0_REG,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (ulong_t)rtlsp->dma_area_tx[0].cookie.dmac_address);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, TX_ADDR_DESC1_REG,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (ulong_t)rtlsp->dma_area_tx[1].cookie.dmac_address);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, TX_ADDR_DESC2_REG,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (ulong_t)rtlsp->dma_area_tx[2].cookie.dmac_address);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, TX_ADDR_DESC3_REG,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (ulong_t)rtlsp->dma_area_tx[3].cookie.dmac_address);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Start transmit/receive before set tx/rx configuration register
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val8 = rtls_reg_get8(rtlsp, RT_COMMAND_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set8(rtlsp, RT_COMMAND_REG,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val8 | RT_COMMAND_RX_ENABLE | RT_COMMAND_TX_ENABLE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Set transmit configuration register
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = rtls_reg_get32(rtlsp, TX_CONFIG_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 &= TX_CONSIG_REG_RESERVE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, TX_CONFIG_REG, val32 | TX_CONFIG_DEFAULT);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Set receive configuration register
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = rtls_reg_get32(rtlsp, RX_CONFIG_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 &= RX_CONSIG_REG_RESERVE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore if (rtlsp->promisc)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 |= RX_ACCEPT_ALL_PACKET;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, RX_CONFIG_REG, val32 | RX_CONFIG_DEFAULT);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Set multicast register
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, MULTICAST_0_REG, rtlsp->multi_hash[0]);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, MULTICAST_4_REG, rtlsp->multi_hash[1]);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Set unicast address
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_set_mac_addr(rtlsp, rtlsp->netaddr);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Set current address of packet read
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set16(rtlsp, RX_CURRENT_READ_ADDR_REG, RX_READ_RESET_VAL);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * No early-rx interrupts
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val16 = rtls_reg_get16(rtlsp, RT_MUL_INTSEL_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val16 &= ~RT_MUL_INTSEL_BITS;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set16(rtlsp, RT_MUL_INTSEL_REG, val16);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_chip_start() -- start chip
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_chip_start(rtls_t *rtlsp)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint16_t val16;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint8_t val8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Start transmit/receive
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val8 = rtls_reg_get8(rtlsp, RT_COMMAND_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set8(rtlsp, RT_COMMAND_REG,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val8 | RT_COMMAND_RX_ENABLE | RT_COMMAND_TX_ENABLE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Enable interrupt
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val16 = rtls_reg_get16(rtlsp, RT_INT_MASK_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set16(rtlsp, RT_INT_MASK_REG, val16 | RTLS_INT_MASK);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->int_mask = RTLS_INT_MASK;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_chip_restart() -- restart chip
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_chip_restart(rtls_t *rtlsp)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (void) rtls_chip_reset(rtlsp, B_FALSE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_chip_init(rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_chip_start(rtlsp);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_chip_stop() -- stop board receiving
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_chip_stop(rtls_t *rtlsp)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint16_t val16;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint8_t val8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Disable interrupt
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val16 = rtls_reg_get16(rtlsp, RT_INT_MASK_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set16(rtlsp, RT_INT_MASK_REG, val16 & (~RTLS_INT_MASK_ALL));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtlsp->int_mask = RTLS_INT_MASK_NONE;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Clear pended interrupt
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val16 = rtls_reg_get16(rtlsp, RT_INT_STATUS_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set16(rtlsp, RT_INT_STATUS_REG, val16);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Stop the board and disable transmit/receive
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val8 = rtls_reg_get8(rtlsp, RT_COMMAND_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val8 &= ~(RT_COMMAND_RX_ENABLE | RT_COMMAND_TX_ENABLE);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set8(rtlsp, RT_COMMAND_REG, val8);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_get_mac_addr() -- get the physical network address on the board
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_get_mac_addr(rtls_t *rtlsp, uint8_t *macaddr)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t val32;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Read first 4-byte of mac address
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = rtls_reg_get32(rtlsp, ID_0_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore macaddr[0] = val32 & 0xff;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = val32 >> 8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore macaddr[1] = val32 & 0xff;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = val32 >> 8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore macaddr[2] = val32 & 0xff;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = val32 >> 8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore macaddr[3] = val32 & 0xff;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Read last 2-byte of mac address
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = rtls_reg_get32(rtlsp, ID_4_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore macaddr[4] = val32 & 0xff;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = val32 >> 8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore macaddr[5] = val32 & 0xff;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_set_mac_addr(rtls_t *rtlsp, const uint8_t *macaddr)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t val32;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint8_t val8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Change to config register write enable mode
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore val8 = rtls_reg_get8(rtlsp, RT_93c46_COMMAND_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val8 |= RT_93c46_MODE_CONFIG;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_reg_set8(rtlsp, RT_93c46_COMMAND_REG, val8);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Get first 4 bytes of mac address
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = macaddr[3];
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = val32 << 8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 |= macaddr[2];
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = val32 << 8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 |= macaddr[1];
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = val32 << 8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 |= macaddr[0];
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Set first 4 bytes of mac address
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, ID_0_REG, val32);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Get last 2 bytes of mac address
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = macaddr[5];
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = val32 << 8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 |= macaddr[4];
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Set last 2 bytes of mac address
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 |= rtls_reg_get32(rtlsp, ID_4_REG) & ~0xffff;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore rtls_reg_set32(rtlsp, ID_4_REG, val32);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * Return to normal network/host communication mode
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val8 &= ~RT_93c46_MODE_CONFIG;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_reg_set8(rtlsp, RT_93c46_COMMAND_REG, val8);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amorestatic uint16_t
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amorertls_mii_read(void *arg, uint8_t phy, uint8_t reg)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_t *rtlsp = arg;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore uint16_t val;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore if (phy != 1) {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore return (0xffff);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore switch (reg) {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_CONTROL:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore val = rtls_reg_get16(rtlsp, BASIC_MODE_CONTROL_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_STATUS:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore val = rtls_reg_get16(rtlsp, BASIC_MODE_STATUS_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_AN_ADVERT:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore val = rtls_reg_get16(rtlsp, AUTO_NEGO_AD_REG);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore break;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_AN_LPABLE:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore val = rtls_reg_get16(rtlsp, AUTO_NEGO_LP_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_AN_EXPANSION:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore val = rtls_reg_get16(rtlsp, AUTO_NEGO_EXP_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_VENDOR(0):
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore /*
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore * We "simulate" a vendor private register so that the
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore * PHY layer can access it to determine detected link
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore * speed/duplex.
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore val = rtls_reg_get8(rtlsp, MEDIA_STATUS_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_PHYIDH:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_PHYIDL:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore default:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore val = 0;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore break;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore }
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore return (val);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amorevoid
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amorertls_mii_write(void *arg, uint8_t phy, uint8_t reg, uint16_t val)
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore{
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_t *rtlsp = arg;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore uint8_t val8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore if (phy != 1) {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore return;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore }
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore switch (reg) {
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_CONTROL:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore /* Enable writes to all bits of BMCR */
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore val8 = rtls_reg_get8(rtlsp, RT_93c46_COMMAND_REG);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore val8 |= RT_93c46_MODE_CONFIG;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_reg_set8(rtlsp, RT_93c46_COMMAND_REG, val8);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore /* write out the value */
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_reg_set16(rtlsp, BASIC_MODE_CONTROL_REG, val);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore /* Return to normal network/host communication mode */
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore val8 &= ~RT_93c46_MODE_CONFIG;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_reg_set8(rtlsp, RT_93c46_COMMAND_REG, val8);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore return;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_STATUS:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_reg_set16(rtlsp, BASIC_MODE_STATUS_REG, val);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore break;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_AN_ADVERT:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_reg_set16(rtlsp, AUTO_NEGO_AD_REG, val);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore break;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_AN_LPABLE:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_reg_set16(rtlsp, AUTO_NEGO_LP_REG, val);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore break;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_AN_EXPANSION:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_reg_set16(rtlsp, AUTO_NEGO_EXP_REG, val);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore break;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_PHYIDH:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore case MII_PHYIDL:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore default:
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore /* these are not writable */
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore break;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore }
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amorevoid
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amorertls_mii_notify(void *arg, link_state_t link)
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore{
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore rtls_t *rtlsp = arg;
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore mac_link_update(rtlsp->mh, link);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#ifdef RTLS_DEBUG
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore/*
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore * rtls_reg_print() -- print out reg value(for debug use only)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore */
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorestatic void
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amorertls_reg_print(rtls_t *rtlsp)
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore{
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint8_t val8;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint16_t val16;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore uint32_t val32;
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val8 = rtls_reg_get8(rtlsp, RT_COMMAND_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_NOTE, "%s: RT_COMMAND_REG = 0x%x",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), val8);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore delay(drv_usectohz(1000));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val16 = rtls_reg_get16(rtlsp, RT_INT_STATUS_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_NOTE, "%s: RT_INT_STATUS_REG = 0x%x",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), val16);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore delay(drv_usectohz(1000));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val16 = rtls_reg_get16(rtlsp, RT_INT_MASK_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_NOTE, "%s: RT_INT_MASK_REG = 0x%x",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), val16);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore delay(drv_usectohz(1000));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = rtls_reg_get32(rtlsp, RX_CONFIG_REG);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore cmn_err(CE_NOTE, "%s: RX_CONFIG_REG = 0x%x",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), val32);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore delay(drv_usectohz(1000));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val16 = rtls_reg_get16(rtlsp, TX_DESC_STAUS_REG);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore cmn_err(CE_NOTE, "%s: TX_DESC_STAUS_REG = 0x%x, cur_desc = %d",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), val16, rtlsp->tx_current_desc);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore delay(drv_usectohz(1000));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = rtls_reg_get32(rtlsp, TX_STATUS_DESC0_REG);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore cmn_err(CE_NOTE, "%s: TX_STATUS_DESC0_REG = 0x%x",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), val32);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore delay(drv_usectohz(1000));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = rtls_reg_get32(rtlsp, TX_STATUS_DESC1_REG);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore cmn_err(CE_NOTE, "%s: TX_STATUS_DESC1_REG = 0x%x",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), val32);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore delay(drv_usectohz(1000));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = rtls_reg_get32(rtlsp, TX_STATUS_DESC2_REG);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore cmn_err(CE_NOTE, "%s: TX_STATUS_DESC2_REG = 0x%x",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), val32);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore delay(drv_usectohz(1000));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore val32 = rtls_reg_get32(rtlsp, TX_STATUS_DESC3_REG);
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore cmn_err(CE_NOTE, "%s: TX_STATUS_DESC3_REG = 0x%x",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh), val32);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore delay(drv_usectohz(1000));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore
bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2ebGarrett D'Amore cmn_err(CE_NOTE, "%s: in = %llu, multicast = %llu, broadcast = %llu",
2c6a6ad1e812de6043502f2f52d21711033ab43eIlya Yanok mac_name(rtlsp->mh),
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (unsigned long long)rtlsp->stats.ipackets,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (unsigned long long)rtlsp->stats.multi_rcv,
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore (unsigned long long)rtlsp->stats.brdcst_rcv);
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore delay(drv_usectohz(1000));
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore}
cde2885fdf538266ee2a3b08dee2d5075ce8fa2bGarrett D'Amore#endif