75ab5f91d942eea4138efe4799ca0589870c3899lh/*
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
75ab5f91d942eea4138efe4799ca0589870c3899lh * Use is subject to license terms.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Copyright (c) 2001-2006 Advanced Micro Devices, Inc. All rights reserved.
75ab5f91d942eea4138efe4799ca0589870c3899lh *
75ab5f91d942eea4138efe4799ca0589870c3899lh * Redistribution and use in source and binary forms, with or without
75ab5f91d942eea4138efe4799ca0589870c3899lh * modification, are permitted provided that the following conditions are met:
75ab5f91d942eea4138efe4799ca0589870c3899lh *
75ab5f91d942eea4138efe4799ca0589870c3899lh * + Redistributions of source code must retain the above copyright notice,
75ab5f91d942eea4138efe4799ca0589870c3899lh * + this list of conditions and the following disclaimer.
75ab5f91d942eea4138efe4799ca0589870c3899lh *
75ab5f91d942eea4138efe4799ca0589870c3899lh * + Redistributions in binary form must reproduce the above copyright
75ab5f91d942eea4138efe4799ca0589870c3899lh * + notice, this list of conditions and the following disclaimer in the
75ab5f91d942eea4138efe4799ca0589870c3899lh * + documentation and/or other materials provided with the distribution.
75ab5f91d942eea4138efe4799ca0589870c3899lh *
75ab5f91d942eea4138efe4799ca0589870c3899lh * + Neither the name of Advanced Micro Devices, Inc. nor the names of its
75ab5f91d942eea4138efe4799ca0589870c3899lh * + contributors may be used to endorse or promote products derived from
75ab5f91d942eea4138efe4799ca0589870c3899lh * + this software without specific prior written permission.
75ab5f91d942eea4138efe4799ca0589870c3899lh *
75ab5f91d942eea4138efe4799ca0589870c3899lh * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
75ab5f91d942eea4138efe4799ca0589870c3899lh * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
75ab5f91d942eea4138efe4799ca0589870c3899lh * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
75ab5f91d942eea4138efe4799ca0589870c3899lh * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75ab5f91d942eea4138efe4799ca0589870c3899lh * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. OR
75ab5f91d942eea4138efe4799ca0589870c3899lh * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
75ab5f91d942eea4138efe4799ca0589870c3899lh * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
75ab5f91d942eea4138efe4799ca0589870c3899lh * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75ab5f91d942eea4138efe4799ca0589870c3899lh * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
75ab5f91d942eea4138efe4799ca0589870c3899lh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
75ab5f91d942eea4138efe4799ca0589870c3899lh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
75ab5f91d942eea4138efe4799ca0589870c3899lh * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
75ab5f91d942eea4138efe4799ca0589870c3899lh * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75ab5f91d942eea4138efe4799ca0589870c3899lh *
75ab5f91d942eea4138efe4799ca0589870c3899lh * Import/Export/Re-Export/Use/Release/Transfer Restrictions and
75ab5f91d942eea4138efe4799ca0589870c3899lh * Compliance with Applicable Laws. Notice is hereby given that
75ab5f91d942eea4138efe4799ca0589870c3899lh * the software may be subject to restrictions on use, release,
75ab5f91d942eea4138efe4799ca0589870c3899lh * transfer, importation, exportation and/or re-exportation under
75ab5f91d942eea4138efe4799ca0589870c3899lh * the laws and regulations of the United States or other
75ab5f91d942eea4138efe4799ca0589870c3899lh * countries ("Applicable Laws"), which include but are not
75ab5f91d942eea4138efe4799ca0589870c3899lh * limited to U.S. export control laws such as the Export
75ab5f91d942eea4138efe4799ca0589870c3899lh * Administration Regulations and national security controls as
75ab5f91d942eea4138efe4799ca0589870c3899lh * defined thereunder, as well as State Department controls under
75ab5f91d942eea4138efe4799ca0589870c3899lh * the U.S. Munitions List. Permission to use and/or
75ab5f91d942eea4138efe4799ca0589870c3899lh * redistribute the software is conditioned upon compliance with
75ab5f91d942eea4138efe4799ca0589870c3899lh * all Applicable Laws, including U.S. export control laws
75ab5f91d942eea4138efe4799ca0589870c3899lh * regarding specifically designated persons, countries and
75ab5f91d942eea4138efe4799ca0589870c3899lh * nationals of countries subject to national security controls.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/* include files */
75ab5f91d942eea4138efe4799ca0589870c3899lh#include <sys/disp.h>
75ab5f91d942eea4138efe4799ca0589870c3899lh#include <sys/atomic.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <sys/vlan.h>
75ab5f91d942eea4138efe4799ca0589870c3899lh#include "amd8111s_main.h"
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/* Global macro Definations */
75ab5f91d942eea4138efe4799ca0589870c3899lh#define ROUNDUP(x, a) (((x) + (a) - 1) & ~((a) - 1))
75ab5f91d942eea4138efe4799ca0589870c3899lh#define INTERFACE_NAME "amd8111s"
75ab5f91d942eea4138efe4799ca0589870c3899lh#define AMD8111S_SPLIT 128
75ab5f91d942eea4138efe4799ca0589870c3899lh#define AMD8111S_SEND_MAX 64
75ab5f91d942eea4138efe4799ca0589870c3899lh
193974072f41a843678abf5f61979c748687e66bSherry Moorestatic char ident[] = "AMD8111 10/100M Ethernet";
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Driver Entry Points
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int amd8111s_attach(dev_info_t *, ddi_attach_cmd_t);
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int amd8111s_detach(dev_info_t *, ddi_detach_cmd_t);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * GLD Entry points prototype
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int amd8111s_m_unicst(void *, const uint8_t *);
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int amd8111s_m_promisc(void *, boolean_t);
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int amd8111s_m_stat(void *, uint_t, uint64_t *);
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void amd8111s_m_ioctl(void *, queue_t *, mblk_t *);
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int amd8111s_m_multicst(void *, boolean_t, const uint8_t *addr);
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int amd8111s_m_start(void *);
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void amd8111s_m_stop(void *);
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic mblk_t *amd8111s_m_tx(void *, mblk_t *mp);
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic uint_t amd8111s_intr(caddr_t);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int amd8111s_unattach(dev_info_t *, struct LayerPointers *);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic boolean_t amd8111s_allocate_buffers(struct LayerPointers *);
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int amd8111s_odlInit(struct LayerPointers *);
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic boolean_t amd8111s_allocate_descriptors(struct LayerPointers *);
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void amd8111s_free_descriptors(struct LayerPointers *);
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic boolean_t amd8111s_alloc_dma_ringbuf(struct LayerPointers *,
75ab5f91d942eea4138efe4799ca0589870c3899lh struct amd8111s_dma_ringbuf *, uint32_t, uint32_t);
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void amd8111s_free_dma_ringbuf(struct amd8111s_dma_ringbuf *);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void amd8111s_log(struct LayerPointers *adapter, int level,
75ab5f91d942eea4138efe4799ca0589870c3899lh char *fmt, ...);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic struct cb_ops amd8111s_cb_ops = {
75ab5f91d942eea4138efe4799ca0589870c3899lh nulldev,
75ab5f91d942eea4138efe4799ca0589870c3899lh nulldev,
75ab5f91d942eea4138efe4799ca0589870c3899lh nodev,
75ab5f91d942eea4138efe4799ca0589870c3899lh nodev,
75ab5f91d942eea4138efe4799ca0589870c3899lh nodev,
75ab5f91d942eea4138efe4799ca0589870c3899lh nodev,
75ab5f91d942eea4138efe4799ca0589870c3899lh nodev,
75ab5f91d942eea4138efe4799ca0589870c3899lh nodev,
75ab5f91d942eea4138efe4799ca0589870c3899lh nodev,
75ab5f91d942eea4138efe4799ca0589870c3899lh nodev,
75ab5f91d942eea4138efe4799ca0589870c3899lh nodev,
75ab5f91d942eea4138efe4799ca0589870c3899lh nochpoll,
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_prop_op,
75ab5f91d942eea4138efe4799ca0589870c3899lh NULL,
75ab5f91d942eea4138efe4799ca0589870c3899lh D_NEW | D_MP,
75ab5f91d942eea4138efe4799ca0589870c3899lh CB_REV, /* cb_rev */
75ab5f91d942eea4138efe4799ca0589870c3899lh nodev, /* cb_aread */
75ab5f91d942eea4138efe4799ca0589870c3899lh nodev /* cb_awrite */
75ab5f91d942eea4138efe4799ca0589870c3899lh};
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic struct dev_ops amd8111s_dev_ops = {
75ab5f91d942eea4138efe4799ca0589870c3899lh DEVO_REV, /* devo_rev */
75ab5f91d942eea4138efe4799ca0589870c3899lh 0, /* devo_refcnt */
75ab5f91d942eea4138efe4799ca0589870c3899lh NULL, /* devo_getinfo */
75ab5f91d942eea4138efe4799ca0589870c3899lh nulldev, /* devo_identify */
75ab5f91d942eea4138efe4799ca0589870c3899lh nulldev, /* devo_probe */
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_attach, /* devo_attach */
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_detach, /* devo_detach */
75ab5f91d942eea4138efe4799ca0589870c3899lh nodev, /* devo_reset */
75ab5f91d942eea4138efe4799ca0589870c3899lh &amd8111s_cb_ops, /* devo_cb_ops */
75ab5f91d942eea4138efe4799ca0589870c3899lh NULL, /* devo_bus_ops */
193974072f41a843678abf5f61979c748687e66bSherry Moore nodev, /* devo_power */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_supported, /* devo_quiesce */
75ab5f91d942eea4138efe4799ca0589870c3899lh};
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstruct modldrv amd8111s_modldrv = {
75ab5f91d942eea4138efe4799ca0589870c3899lh &mod_driverops, /* Type of module. This one is a driver */
75ab5f91d942eea4138efe4799ca0589870c3899lh ident, /* short description */
75ab5f91d942eea4138efe4799ca0589870c3899lh &amd8111s_dev_ops /* driver specific ops */
75ab5f91d942eea4138efe4799ca0589870c3899lh};
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstruct modlinkage amd8111s_modlinkage = {
75ab5f91d942eea4138efe4799ca0589870c3899lh MODREV_1, (void *)&amd8111s_modldrv, NULL
75ab5f91d942eea4138efe4799ca0589870c3899lh};
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Global Variables
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstruct LayerPointers *amd8111sadapter;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic ddi_dma_attr_t pcn_buff_dma_attr_t = {
75ab5f91d942eea4138efe4799ca0589870c3899lh DMA_ATTR_V0, /* dma_attr_version */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint64_t)0, /* dma_attr_addr_lo */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint64_t)0xFFFFFFFF, /* dma_attr_addr_hi */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint64_t)0xFFFFFFFF, /* dma_attr_count_max */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint64_t)1, /* dma_attr_align */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint_t)0x7F, /* dma_attr_burstsizes */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint32_t)1, /* dma_attr_minxfer */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint64_t)0xFFFFFFFF, /* dma_attr_maxxfer */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint64_t)0xFFFFFFFF, /* dma_attr_seg */
75ab5f91d942eea4138efe4799ca0589870c3899lh (int)1, /* dma_attr_sgllen */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint32_t)1, /* granularity */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint_t)0 /* dma_attr_flags */
75ab5f91d942eea4138efe4799ca0589870c3899lh};
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic ddi_dma_attr_t pcn_desc_dma_attr_t = {
75ab5f91d942eea4138efe4799ca0589870c3899lh DMA_ATTR_V0, /* dma_attr_version */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint64_t)0, /* dma_attr_addr_lo */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint64_t)0xFFFFFFFF, /* dma_attr_addr_hi */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint64_t)0x7FFFFFFF, /* dma_attr_count_max */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint64_t)0x10, /* dma_attr_align */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint_t)0xFFFFFFFFU, /* dma_attr_burstsizes */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint32_t)1, /* dma_attr_minxfer */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint64_t)0xFFFFFFFF, /* dma_attr_maxxfer */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint64_t)0xFFFFFFFF, /* dma_attr_seg */
75ab5f91d942eea4138efe4799ca0589870c3899lh (int)1, /* dma_attr_sgllen */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint32_t)1, /* granularity */
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint_t)0 /* dma_attr_flags */
75ab5f91d942eea4138efe4799ca0589870c3899lh};
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/* PIO access attributes for registers */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic ddi_device_acc_attr_t pcn_acc_attr = {
75ab5f91d942eea4138efe4799ca0589870c3899lh DDI_DEVICE_ATTR_V0,
75ab5f91d942eea4138efe4799ca0589870c3899lh DDI_STRUCTURE_LE_ACC,
75ab5f91d942eea4138efe4799ca0589870c3899lh DDI_STRICTORDER_ACC
75ab5f91d942eea4138efe4799ca0589870c3899lh};
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic mac_callbacks_t amd8111s_m_callbacks = {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng MC_IOCTL,
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_m_stat,
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_m_start,
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_m_stop,
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_m_promisc,
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_m_multicst,
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_m_unicst,
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_m_tx,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer NULL,
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_m_ioctl
75ab5f91d942eea4138efe4799ca0589870c3899lh};
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Standard Driver Load Entry Point
75ab5f91d942eea4138efe4799ca0589870c3899lh * It will be called at load time of driver.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhint
75ab5f91d942eea4138efe4799ca0589870c3899lh_init()
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh int status;
75ab5f91d942eea4138efe4799ca0589870c3899lh mac_init_ops(&amd8111s_dev_ops, "amd8111s");
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh status = mod_install(&amd8111s_modlinkage);
75ab5f91d942eea4138efe4799ca0589870c3899lh if (status != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh mac_fini_ops(&amd8111s_dev_ops);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (status);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Standard Driver Entry Point for Query.
75ab5f91d942eea4138efe4799ca0589870c3899lh * It will be called at any time to get Driver info.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhint
75ab5f91d942eea4138efe4799ca0589870c3899lh_info(struct modinfo *modinfop)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh return (mod_info(&amd8111s_modlinkage, modinfop));
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Standard Driver Entry Point for Unload.
75ab5f91d942eea4138efe4799ca0589870c3899lh * It will be called at unload time of driver.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhint
75ab5f91d942eea4138efe4799ca0589870c3899lh_fini()
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh int status;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh status = mod_remove(&amd8111s_modlinkage);
75ab5f91d942eea4138efe4799ca0589870c3899lh if (status == DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh mac_fini_ops(&amd8111s_dev_ops);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (status);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Loopback Support
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic lb_property_t loopmodes[] = {
75ab5f91d942eea4138efe4799ca0589870c3899lh { normal, "normal", AMD8111S_LB_NONE },
75ab5f91d942eea4138efe4799ca0589870c3899lh { external, "100Mbps", AMD8111S_LB_EXTERNAL_100 },
75ab5f91d942eea4138efe4799ca0589870c3899lh { external, "10Mbps", AMD8111S_LB_EXTERNAL_10 },
75ab5f91d942eea4138efe4799ca0589870c3899lh { internal, "MAC", AMD8111S_LB_INTERNAL_MAC }
75ab5f91d942eea4138efe4799ca0589870c3899lh};
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_set_loop_mode(struct LayerPointers *adapter, uint32_t mode)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * If the mode isn't being changed, there's nothing to do ...
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (mode == adapter->pOdl->loopback_mode)
75ab5f91d942eea4138efe4799ca0589870c3899lh return;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Validate the requested mode and prepare a suitable message
75ab5f91d942eea4138efe4799ca0589870c3899lh * to explain the link down/up cycle that the change will
75ab5f91d942eea4138efe4799ca0589870c3899lh * probably induce ...
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh switch (mode) {
75ab5f91d942eea4138efe4799ca0589870c3899lh default:
75ab5f91d942eea4138efe4799ca0589870c3899lh return;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case AMD8111S_LB_NONE:
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlStopChip(adapter);
75ab5f91d942eea4138efe4799ca0589870c3899lh if (adapter->pOdl->loopback_mode == AMD8111S_LB_INTERNAL_MAC) {
75ab5f91d942eea4138efe4799ca0589870c3899lh cmn_err(CE_NOTE, "LB_NONE restored from Interanl LB");
75ab5f91d942eea4138efe4799ca0589870c3899lh WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD2,
75ab5f91d942eea4138efe4799ca0589870c3899lh INLOOP);
75ab5f91d942eea4138efe4799ca0589870c3899lh WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD3,
75ab5f91d942eea4138efe4799ca0589870c3899lh FORCE_FULL_DUPLEX | FORCE_LINK_STATUS);
75ab5f91d942eea4138efe4799ca0589870c3899lh } else {
75ab5f91d942eea4138efe4799ca0589870c3899lh cmn_err(CE_NOTE, "LB_NONE restored from Exteranl LB");
75ab5f91d942eea4138efe4799ca0589870c3899lh WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD2,
75ab5f91d942eea4138efe4799ca0589870c3899lh EXLOOP);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_reset(adapter);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pOdl->LinkStatus = LINK_STATE_DOWN;
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pOdl->rx_fcs_stripped = B_FALSE;
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlStartChip(adapter);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case AMD8111S_LB_EXTERNAL_100:
75ab5f91d942eea4138efe4799ca0589870c3899lh cmn_err(CE_NOTE, "amd8111s_set_loop_mode LB_EXTERNAL_100");
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlStopChip(adapter);
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_reset(adapter);
75ab5f91d942eea4138efe4799ca0589870c3899lh SetIntrCoalesc(adapter, B_FALSE);
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlPHYAutoNegotiation(adapter, PHY_FORCE_FD_100);
75ab5f91d942eea4138efe4799ca0589870c3899lh WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD2,
75ab5f91d942eea4138efe4799ca0589870c3899lh VAL0 | EXLOOP);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pOdl->LinkStatus = LINK_STATE_UP;
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pMdl->Speed = 100;
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pMdl->FullDuplex = B_TRUE;
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Tell GLD the state of the physical link. */
75ab5f91d942eea4138efe4799ca0589870c3899lh mac_link_update(adapter->pOdl->mh, LINK_STATE_UP);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pOdl->rx_fcs_stripped = B_TRUE;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlStartChip(adapter);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case AMD8111S_LB_EXTERNAL_10:
75ab5f91d942eea4138efe4799ca0589870c3899lh cmn_err(CE_NOTE, "amd8111s_set_loop_mode LB_EXTERNAL_10");
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlStopChip(adapter);
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_reset(adapter);
75ab5f91d942eea4138efe4799ca0589870c3899lh SetIntrCoalesc(adapter, B_FALSE);
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlPHYAutoNegotiation(adapter, PHY_FORCE_FD_10);
75ab5f91d942eea4138efe4799ca0589870c3899lh WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD2,
75ab5f91d942eea4138efe4799ca0589870c3899lh VAL0 | EXLOOP);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pOdl->LinkStatus = LINK_STATE_UP;
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pMdl->Speed = 10;
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pMdl->FullDuplex = B_TRUE;
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Tell GLD the state of the physical link. */
75ab5f91d942eea4138efe4799ca0589870c3899lh mac_link_update(adapter->pOdl->mh, LINK_STATE_UP);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pOdl->rx_fcs_stripped = B_TRUE;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlStartChip(adapter);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case AMD8111S_LB_INTERNAL_MAC:
75ab5f91d942eea4138efe4799ca0589870c3899lh cmn_err(CE_NOTE, "amd8111s_set_loop_mode LB_INTERNAL_MAC");
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlStopChip(adapter);
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_reset(adapter);
75ab5f91d942eea4138efe4799ca0589870c3899lh SetIntrCoalesc(adapter, B_FALSE);
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Disable Port Manager */
75ab5f91d942eea4138efe4799ca0589870c3899lh WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD3,
75ab5f91d942eea4138efe4799ca0589870c3899lh EN_PMGR);
75ab5f91d942eea4138efe4799ca0589870c3899lh WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD2,
75ab5f91d942eea4138efe4799ca0589870c3899lh VAL0 | INLOOP);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD3,
75ab5f91d942eea4138efe4799ca0589870c3899lh VAL1 | FORCE_FULL_DUPLEX | FORCE_LINK_STATUS);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pOdl->LinkStatus = LINK_STATE_UP;
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pMdl->FullDuplex = B_TRUE;
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Tell GLD the state of the physical link. */
75ab5f91d942eea4138efe4799ca0589870c3899lh mac_link_update(adapter->pOdl->mh, LINK_STATE_UP);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pOdl->rx_fcs_stripped = B_TRUE;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlStartChip(adapter);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * All OK; tell the caller to reprogram
75ab5f91d942eea4138efe4799ca0589870c3899lh * the PHY and/or MAC for the new mode ...
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pOdl->loopback_mode = mode;
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic enum ioc_reply
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_loopback_ioctl(struct LayerPointers *adapter, struct iocblk *iocp,
75ab5f91d942eea4138efe4799ca0589870c3899lh mblk_t *mp)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh lb_info_sz_t *lbsp;
75ab5f91d942eea4138efe4799ca0589870c3899lh lb_property_t *lbpp;
75ab5f91d942eea4138efe4799ca0589870c3899lh uint32_t *lbmp;
75ab5f91d942eea4138efe4799ca0589870c3899lh int cmd;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Validate format of ioctl
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (mp->b_cont == NULL)
75ab5f91d942eea4138efe4799ca0589870c3899lh return (IOC_INVAL);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh cmd = iocp->ioc_cmd;
75ab5f91d942eea4138efe4799ca0589870c3899lh switch (cmd) {
75ab5f91d942eea4138efe4799ca0589870c3899lh default:
75ab5f91d942eea4138efe4799ca0589870c3899lh /* NOTREACHED */
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(adapter, CE_NOTE,
75ab5f91d942eea4138efe4799ca0589870c3899lh "amd8111s_loop_ioctl: invalid cmd 0x%x", cmd);
75ab5f91d942eea4138efe4799ca0589870c3899lh return (IOC_INVAL);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case LB_GET_INFO_SIZE:
75ab5f91d942eea4138efe4799ca0589870c3899lh if (iocp->ioc_count != sizeof (lb_info_sz_t)) {
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(adapter, CE_NOTE,
75ab5f91d942eea4138efe4799ca0589870c3899lh "wrong LB_GET_INFO_SIZE size");
75ab5f91d942eea4138efe4799ca0589870c3899lh return (IOC_INVAL);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
22eb7cb54d8a6bcf6fe2674cb4b1f0cf2d85cfb6gd lbsp = (void *)mp->b_cont->b_rptr;
75ab5f91d942eea4138efe4799ca0589870c3899lh *lbsp = sizeof (loopmodes);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case LB_GET_INFO:
75ab5f91d942eea4138efe4799ca0589870c3899lh if (iocp->ioc_count != sizeof (loopmodes)) {
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(adapter, CE_NOTE,
75ab5f91d942eea4138efe4799ca0589870c3899lh "Wrong LB_GET_INFO size");
75ab5f91d942eea4138efe4799ca0589870c3899lh return (IOC_INVAL);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
22eb7cb54d8a6bcf6fe2674cb4b1f0cf2d85cfb6gd lbpp = (void *)mp->b_cont->b_rptr;
75ab5f91d942eea4138efe4799ca0589870c3899lh bcopy(loopmodes, lbpp, sizeof (loopmodes));
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case LB_GET_MODE:
75ab5f91d942eea4138efe4799ca0589870c3899lh if (iocp->ioc_count != sizeof (uint32_t)) {
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(adapter, CE_NOTE,
75ab5f91d942eea4138efe4799ca0589870c3899lh "Wrong LB_GET_MODE size");
75ab5f91d942eea4138efe4799ca0589870c3899lh return (IOC_INVAL);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
22eb7cb54d8a6bcf6fe2674cb4b1f0cf2d85cfb6gd lbmp = (void *)mp->b_cont->b_rptr;
75ab5f91d942eea4138efe4799ca0589870c3899lh *lbmp = adapter->pOdl->loopback_mode;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case LB_SET_MODE:
75ab5f91d942eea4138efe4799ca0589870c3899lh if (iocp->ioc_count != sizeof (uint32_t)) {
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(adapter, CE_NOTE,
75ab5f91d942eea4138efe4799ca0589870c3899lh "Wrong LB_SET_MODE size");
75ab5f91d942eea4138efe4799ca0589870c3899lh return (IOC_INVAL);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
22eb7cb54d8a6bcf6fe2674cb4b1f0cf2d85cfb6gd lbmp = (void *)mp->b_cont->b_rptr;
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_set_loop_mode(adapter, *lbmp);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh return (IOC_REPLY);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_m_ioctl(void *arg, queue_t *q, mblk_t *mp)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct iocblk *iocp;
75ab5f91d942eea4138efe4799ca0589870c3899lh struct LayerPointers *adapter;
75ab5f91d942eea4138efe4799ca0589870c3899lh enum ioc_reply status;
75ab5f91d942eea4138efe4799ca0589870c3899lh
22eb7cb54d8a6bcf6fe2674cb4b1f0cf2d85cfb6gd iocp = (void *)mp->b_rptr;
75ab5f91d942eea4138efe4799ca0589870c3899lh iocp->ioc_error = 0;
22eb7cb54d8a6bcf6fe2674cb4b1f0cf2d85cfb6gd adapter = arg;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh ASSERT(adapter);
75ab5f91d942eea4138efe4799ca0589870c3899lh if (adapter == NULL) {
75ab5f91d942eea4138efe4799ca0589870c3899lh miocnak(q, mp, 0, EINVAL);
75ab5f91d942eea4138efe4799ca0589870c3899lh return;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh switch (iocp->ioc_cmd) {
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case LB_GET_INFO_SIZE:
75ab5f91d942eea4138efe4799ca0589870c3899lh case LB_GET_INFO:
75ab5f91d942eea4138efe4799ca0589870c3899lh case LB_GET_MODE:
75ab5f91d942eea4138efe4799ca0589870c3899lh case LB_SET_MODE:
75ab5f91d942eea4138efe4799ca0589870c3899lh status = amd8111s_loopback_ioctl(adapter, iocp, mp);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh default:
75ab5f91d942eea4138efe4799ca0589870c3899lh status = IOC_INVAL;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Decide how to reply
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh switch (status) {
75ab5f91d942eea4138efe4799ca0589870c3899lh default:
75ab5f91d942eea4138efe4799ca0589870c3899lh case IOC_INVAL:
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Error, reply with a NAK and EINVAL or the specified error
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh miocnak(q, mp, 0, iocp->ioc_error == 0 ?
75ab5f91d942eea4138efe4799ca0589870c3899lh EINVAL : iocp->ioc_error);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case IOC_DONE:
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * OK, reply already sent
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case IOC_ACK:
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * OK, reply with an ACK
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh miocack(q, mp, 0, 0);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case IOC_REPLY:
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * OK, send prepared reply as ACK or NAK
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh mp->b_datap->db_type = iocp->ioc_error == 0 ?
75ab5f91d942eea4138efe4799ca0589870c3899lh M_IOCACK : M_IOCNAK;
75ab5f91d942eea4138efe4799ca0589870c3899lh qreply(q, mp);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Copy one packet from dma memory to mblk. Inc dma descriptor pointer.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic boolean_t
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_recv_copy(struct LayerPointers *pLayerPointers, mblk_t **last_mp)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh int length = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh mblk_t *mp;
75ab5f91d942eea4138efe4799ca0589870c3899lh struct rx_desc *descriptor;
75ab5f91d942eea4138efe4799ca0589870c3899lh struct odl *pOdl = pLayerPointers->pOdl;
75ab5f91d942eea4138efe4799ca0589870c3899lh struct amd8111s_statistics *statistics = &pOdl->statistics;
75ab5f91d942eea4138efe4799ca0589870c3899lh struct nonphysical *pNonphysical = pLayerPointers->pMil
75ab5f91d942eea4138efe4799ca0589870c3899lh ->pNonphysical;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh mutex_enter(&pOdl->mdlRcvLock);
75ab5f91d942eea4138efe4799ca0589870c3899lh descriptor = pNonphysical->RxBufDescQRead->descriptor;
75ab5f91d942eea4138efe4799ca0589870c3899lh (void) ddi_dma_sync(pOdl->rx_desc_dma_handle,
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->RxBufDescQRead->descriptor -
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->RxBufDescQStart->descriptor,
75ab5f91d942eea4138efe4799ca0589870c3899lh sizeof (struct rx_desc), DDI_DMA_SYNC_FORCPU);
75ab5f91d942eea4138efe4799ca0589870c3899lh if ((descriptor->Rx_OWN) == 0) {
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * If the frame is received with errors, then set MCNT
75ab5f91d942eea4138efe4799ca0589870c3899lh * of that pkt in ReceiveArray to 0. This packet would
75ab5f91d942eea4138efe4799ca0589870c3899lh * be discarded later and not indicated to OS.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (descriptor->Rx_ERR) {
75ab5f91d942eea4138efe4799ca0589870c3899lh statistics->rx_desc_err ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh descriptor->Rx_ERR = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh if (descriptor->Rx_FRAM == 1) {
75ab5f91d942eea4138efe4799ca0589870c3899lh statistics->rx_desc_err_FRAM ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh descriptor->Rx_FRAM = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh if (descriptor->Rx_OFLO == 1) {
75ab5f91d942eea4138efe4799ca0589870c3899lh statistics->rx_desc_err_OFLO ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh descriptor->Rx_OFLO = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->rx_overflow_counter ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh if ((pOdl->rx_overflow_counter > 5) &&
75ab5f91d942eea4138efe4799ca0589870c3899lh (pOdl->pause_interval == 0)) {
75ab5f91d942eea4138efe4799ca0589870c3899lh statistics->rx_double_overflow ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlSendPause(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->rx_overflow_counter = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->pause_interval = 25;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh if (descriptor->Rx_CRC == 1) {
75ab5f91d942eea4138efe4799ca0589870c3899lh statistics->rx_desc_err_CRC ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh descriptor->Rx_CRC = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh if (descriptor->Rx_BUFF == 1) {
75ab5f91d942eea4138efe4799ca0589870c3899lh statistics->rx_desc_err_BUFF ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh descriptor->Rx_BUFF = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh goto Next_Descriptor;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Length of incoming packet */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pOdl->rx_fcs_stripped) {
75ab5f91d942eea4138efe4799ca0589870c3899lh length = descriptor->Rx_MCNT -4;
75ab5f91d942eea4138efe4799ca0589870c3899lh } else {
75ab5f91d942eea4138efe4799ca0589870c3899lh length = descriptor->Rx_MCNT;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh if (length < 62) {
75ab5f91d942eea4138efe4799ca0589870c3899lh statistics->rx_error_zerosize ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if ((mp = allocb(length, BPRI_MED)) == NULL) {
75ab5f91d942eea4138efe4799ca0589870c3899lh statistics->rx_allocfail ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh goto failed;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Copy from virtual address of incoming packet */
75ab5f91d942eea4138efe4799ca0589870c3899lh bcopy((long *)*(pNonphysical->RxBufDescQRead->USpaceMap),
75ab5f91d942eea4138efe4799ca0589870c3899lh mp->b_rptr, length);
75ab5f91d942eea4138efe4799ca0589870c3899lh mp->b_wptr = mp->b_rptr + length;
75ab5f91d942eea4138efe4799ca0589870c3899lh statistics->rx_ok_packets ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh if (*last_mp == NULL) {
75ab5f91d942eea4138efe4799ca0589870c3899lh *last_mp = mp;
75ab5f91d942eea4138efe4799ca0589870c3899lh } else {
75ab5f91d942eea4138efe4799ca0589870c3899lh (*last_mp)->b_next = mp;
75ab5f91d942eea4138efe4799ca0589870c3899lh *last_mp = mp;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhNext_Descriptor:
75ab5f91d942eea4138efe4799ca0589870c3899lh descriptor->Rx_MCNT = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh descriptor->Rx_SOP = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh descriptor->Rx_EOP = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh descriptor->Rx_PAM = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh descriptor->Rx_BAM = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh descriptor->TT = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh descriptor->Rx_OWN = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->RxBufDescQRead->descriptor++;
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->RxBufDescQRead->USpaceMap++;
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pNonphysical->RxBufDescQRead->descriptor >
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->RxBufDescQEnd->descriptor) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->RxBufDescQRead->descriptor =
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->RxBufDescQStart->descriptor;
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->RxBufDescQRead->USpaceMap =
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->RxBufDescQStart->USpaceMap;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh mutex_exit(&pOdl->mdlRcvLock);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (B_TRUE);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhfailed:
75ab5f91d942eea4138efe4799ca0589870c3899lh mutex_exit(&pOdl->mdlRcvLock);
75ab5f91d942eea4138efe4799ca0589870c3899lh return (B_FALSE);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Get the received packets from NIC card and send them to GLD.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_receive(struct LayerPointers *pLayerPointers)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh int numOfPkts = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh struct odl *pOdl;
75ab5f91d942eea4138efe4799ca0589870c3899lh mblk_t *ret_mp = NULL, *last_mp = NULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl = pLayerPointers->pOdl;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh rw_enter(&pOdl->chip_lock, RW_READER);
75ab5f91d942eea4138efe4799ca0589870c3899lh if (!pLayerPointers->run) {
75ab5f91d942eea4138efe4799ca0589870c3899lh rw_exit(&pOdl->chip_lock);
75ab5f91d942eea4138efe4799ca0589870c3899lh return;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pOdl->pause_interval > 0)
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->pause_interval --;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh while (numOfPkts < RX_RING_SIZE) {
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (!amd8111s_recv_copy(pLayerPointers, &last_mp)) {
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh if (ret_mp == NULL)
75ab5f91d942eea4138efe4799ca0589870c3899lh ret_mp = last_mp;
75ab5f91d942eea4138efe4799ca0589870c3899lh numOfPkts++;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (ret_mp) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_rx(pOdl->mh, NULL, ret_mp);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh (void) ddi_dma_sync(pOdl->rx_desc_dma_handle, 0, 0,
75ab5f91d942eea4138efe4799ca0589870c3899lh DDI_DMA_SYNC_FORDEV);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReceive(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh rw_exit(&pOdl->chip_lock);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Print message in release-version driver.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_log(struct LayerPointers *adapter, int level, char *fmt, ...)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh auto char name[32];
75ab5f91d942eea4138efe4799ca0589870c3899lh auto char buf[256];
75ab5f91d942eea4138efe4799ca0589870c3899lh va_list ap;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (adapter != NULL) {
75ab5f91d942eea4138efe4799ca0589870c3899lh (void) sprintf(name, "amd8111s%d",
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_get_instance(adapter->pOdl->devinfo));
75ab5f91d942eea4138efe4799ca0589870c3899lh } else {
75ab5f91d942eea4138efe4799ca0589870c3899lh (void) sprintf(name, "amd8111s");
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh va_start(ap, fmt);
75ab5f91d942eea4138efe4799ca0589870c3899lh (void) vsprintf(buf, fmt, ap);
75ab5f91d942eea4138efe4799ca0589870c3899lh va_end(ap);
75ab5f91d942eea4138efe4799ca0589870c3899lh cmn_err(level, "%s: %s", name, buf);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * To allocate & initilize all resources.
75ab5f91d942eea4138efe4799ca0589870c3899lh * Called by amd8111s_attach().
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_odlInit(struct LayerPointers *pLayerPointers)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh unsigned long mem_req_array[MEM_REQ_MAX];
75ab5f91d942eea4138efe4799ca0589870c3899lh unsigned long mem_set_array[MEM_REQ_MAX];
75ab5f91d942eea4138efe4799ca0589870c3899lh unsigned long *pmem_req_array;
75ab5f91d942eea4138efe4799ca0589870c3899lh unsigned long *pmem_set_array;
75ab5f91d942eea4138efe4799ca0589870c3899lh int i, size;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh for (i = 0; i < MEM_REQ_MAX; i++) {
75ab5f91d942eea4138efe4799ca0589870c3899lh mem_req_array[i] = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh mem_set_array[i] = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh milRequestResources(mem_req_array);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pmem_req_array = mem_req_array;
75ab5f91d942eea4138efe4799ca0589870c3899lh pmem_set_array = mem_set_array;
75ab5f91d942eea4138efe4799ca0589870c3899lh while (*pmem_req_array) {
75ab5f91d942eea4138efe4799ca0589870c3899lh switch (*pmem_req_array) {
75ab5f91d942eea4138efe4799ca0589870c3899lh case VIRTUAL:
75ab5f91d942eea4138efe4799ca0589870c3899lh *pmem_set_array = VIRTUAL;
75ab5f91d942eea4138efe4799ca0589870c3899lh pmem_req_array++;
75ab5f91d942eea4138efe4799ca0589870c3899lh pmem_set_array++;
75ab5f91d942eea4138efe4799ca0589870c3899lh *(pmem_set_array) = *(pmem_req_array);
75ab5f91d942eea4138efe4799ca0589870c3899lh pmem_set_array++;
75ab5f91d942eea4138efe4799ca0589870c3899lh *(pmem_set_array) = (unsigned long) kmem_zalloc(
75ab5f91d942eea4138efe4799ca0589870c3899lh *(pmem_req_array), KM_NOSLEEP);
75ab5f91d942eea4138efe4799ca0589870c3899lh if (*pmem_set_array == NULL)
75ab5f91d942eea4138efe4799ca0589870c3899lh goto odl_init_failure;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh pmem_req_array++;
75ab5f91d942eea4138efe4799ca0589870c3899lh pmem_set_array++;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Initilize memory on lower layers
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh milSetResources(pLayerPointers, mem_set_array);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Allocate Rx/Tx descriptors */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (amd8111s_allocate_descriptors(pLayerPointers) != B_TRUE) {
75ab5f91d942eea4138efe4799ca0589870c3899lh *pmem_set_array = NULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh goto odl_init_failure;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Allocate Rx buffer for each Rx descriptor. Then call mil layer
75ab5f91d942eea4138efe4799ca0589870c3899lh * routine to fill physical address of Rx buffer into Rx descriptor.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (amd8111s_allocate_buffers(pLayerPointers) == B_FALSE) {
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_free_descriptors(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh *pmem_set_array = NULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh goto odl_init_failure;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh milInitGlbds(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (0);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhodl_init_failure:
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Free All memory allocated so far
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh pmem_req_array = mem_set_array;
75ab5f91d942eea4138efe4799ca0589870c3899lh while ((*pmem_req_array) && (pmem_req_array != pmem_set_array)) {
75ab5f91d942eea4138efe4799ca0589870c3899lh switch (*pmem_req_array) {
75ab5f91d942eea4138efe4799ca0589870c3899lh case VIRTUAL:
75ab5f91d942eea4138efe4799ca0589870c3899lh pmem_req_array++; /* Size */
75ab5f91d942eea4138efe4799ca0589870c3899lh size = *(pmem_req_array);
75ab5f91d942eea4138efe4799ca0589870c3899lh pmem_req_array++; /* Virtual Address */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pmem_req_array == NULL)
75ab5f91d942eea4138efe4799ca0589870c3899lh return (1);
75ab5f91d942eea4138efe4799ca0589870c3899lh kmem_free((int *)*pmem_req_array, size);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh pmem_req_array++;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh return (1);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Allocate and initialize Tx/Rx descriptors
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic boolean_t
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_allocate_descriptors(struct LayerPointers *pLayerPointers)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct odl *pOdl = pLayerPointers->pOdl;
75ab5f91d942eea4138efe4799ca0589870c3899lh struct mil *pMil = pLayerPointers->pMil;
75ab5f91d942eea4138efe4799ca0589870c3899lh dev_info_t *devinfo = pOdl->devinfo;
75ab5f91d942eea4138efe4799ca0589870c3899lh uint_t length, count, i;
75ab5f91d942eea4138efe4799ca0589870c3899lh size_t real_length;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Allocate Rx descriptors
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (ddi_dma_alloc_handle(devinfo, &pcn_desc_dma_attr_t, DDI_DMA_SLEEP,
75ab5f91d942eea4138efe4799ca0589870c3899lh NULL, &pOdl->rx_desc_dma_handle) != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_WARN,
75ab5f91d942eea4138efe4799ca0589870c3899lh "ddi_dma_alloc_handle for Rx desc failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->rx_desc_dma_handle = NULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh return (B_FALSE);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh length = sizeof (struct rx_desc) * RX_RING_SIZE + ALIGNMENT;
75ab5f91d942eea4138efe4799ca0589870c3899lh if (ddi_dma_mem_alloc(pOdl->rx_desc_dma_handle, length,
75ab5f91d942eea4138efe4799ca0589870c3899lh &pcn_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
75ab5f91d942eea4138efe4799ca0589870c3899lh NULL, (caddr_t *)&pMil->Rx_desc_original, &real_length,
75ab5f91d942eea4138efe4799ca0589870c3899lh &pOdl->rx_desc_acc_handle) != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_WARN,
75ab5f91d942eea4138efe4799ca0589870c3899lh "ddi_dma_mem_handle for Rx desc failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_dma_free_handle(&pOdl->rx_desc_dma_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->rx_desc_dma_handle = NULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh return (B_FALSE);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (ddi_dma_addr_bind_handle(pOdl->rx_desc_dma_handle,
75ab5f91d942eea4138efe4799ca0589870c3899lh NULL, (caddr_t)pMil->Rx_desc_original, real_length,
75ab5f91d942eea4138efe4799ca0589870c3899lh DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
75ab5f91d942eea4138efe4799ca0589870c3899lh NULL, &pOdl->rx_desc_dma_cookie,
75ab5f91d942eea4138efe4799ca0589870c3899lh &count) != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_WARN,
75ab5f91d942eea4138efe4799ca0589870c3899lh "ddi_dma_addr_bind_handle for Rx desc failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_dma_mem_free(&pOdl->rx_desc_acc_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_dma_free_handle(&pOdl->rx_desc_dma_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->rx_desc_dma_handle = NULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh return (B_FALSE);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh ASSERT(count == 1);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Initialize Rx descriptors related variables */
75ab5f91d942eea4138efe4799ca0589870c3899lh pMil->Rx_desc = (struct rx_desc *)
75ab5f91d942eea4138efe4799ca0589870c3899lh ((pMil->Rx_desc_original + ALIGNMENT) & ~ALIGNMENT);
75ab5f91d942eea4138efe4799ca0589870c3899lh pMil->Rx_desc_pa = (unsigned int)
75ab5f91d942eea4138efe4799ca0589870c3899lh ((pOdl->rx_desc_dma_cookie.dmac_laddress + ALIGNMENT) & ~ALIGNMENT);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pMdl->init_blk->RDRA = pMil->Rx_desc_pa;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Allocate Tx descriptors
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (ddi_dma_alloc_handle(devinfo, &pcn_desc_dma_attr_t, DDI_DMA_SLEEP,
75ab5f91d942eea4138efe4799ca0589870c3899lh NULL, &pOdl->tx_desc_dma_handle) != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_WARN,
75ab5f91d942eea4138efe4799ca0589870c3899lh "ddi_dma_alloc_handle for Tx desc failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh goto allocate_desc_fail;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh length = sizeof (struct tx_desc) * TX_RING_SIZE + ALIGNMENT;
75ab5f91d942eea4138efe4799ca0589870c3899lh if (ddi_dma_mem_alloc(pOdl->tx_desc_dma_handle, length,
75ab5f91d942eea4138efe4799ca0589870c3899lh &pcn_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
75ab5f91d942eea4138efe4799ca0589870c3899lh NULL, (caddr_t *)&pMil->Tx_desc_original, &real_length,
75ab5f91d942eea4138efe4799ca0589870c3899lh &pOdl->tx_desc_acc_handle) != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_WARN,
75ab5f91d942eea4138efe4799ca0589870c3899lh "ddi_dma_mem_handle for Tx desc failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_dma_free_handle(&pOdl->tx_desc_dma_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh goto allocate_desc_fail;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (ddi_dma_addr_bind_handle(pOdl->tx_desc_dma_handle,
75ab5f91d942eea4138efe4799ca0589870c3899lh NULL, (caddr_t)pMil->Tx_desc_original, real_length,
75ab5f91d942eea4138efe4799ca0589870c3899lh DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
75ab5f91d942eea4138efe4799ca0589870c3899lh NULL, &pOdl->tx_desc_dma_cookie,
75ab5f91d942eea4138efe4799ca0589870c3899lh &count) != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_WARN,
75ab5f91d942eea4138efe4799ca0589870c3899lh "ddi_dma_addr_bind_handle for Tx desc failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_dma_mem_free(&pOdl->tx_desc_acc_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_dma_free_handle(&pOdl->tx_desc_dma_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh goto allocate_desc_fail;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh ASSERT(count == 1);
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Set the DMA area to all zeros */
75ab5f91d942eea4138efe4799ca0589870c3899lh bzero((caddr_t)pMil->Tx_desc_original, length);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Initialize Tx descriptors related variables */
75ab5f91d942eea4138efe4799ca0589870c3899lh pMil->Tx_desc = (struct tx_desc *)
75ab5f91d942eea4138efe4799ca0589870c3899lh ((pMil->Tx_desc_original + ALIGNMENT) & ~ALIGNMENT);
75ab5f91d942eea4138efe4799ca0589870c3899lh pMil->pNonphysical->TxDescQRead = pMil->Tx_desc;
75ab5f91d942eea4138efe4799ca0589870c3899lh pMil->pNonphysical->TxDescQWrite = pMil->Tx_desc;
75ab5f91d942eea4138efe4799ca0589870c3899lh pMil->pNonphysical->TxDescQStart = pMil->Tx_desc;
75ab5f91d942eea4138efe4799ca0589870c3899lh pMil->pNonphysical->TxDescQEnd = &(pMil->Tx_desc[TX_RING_SIZE -1]);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Physical Addr of Tx_desc_original & Tx_desc */
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pMil->Tx_desc_pa =
75ab5f91d942eea4138efe4799ca0589870c3899lh ((pOdl->tx_desc_dma_cookie.dmac_laddress + ALIGNMENT) &
75ab5f91d942eea4138efe4799ca0589870c3899lh ~ALIGNMENT);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Setting the reserved bits in the tx descriptors */
75ab5f91d942eea4138efe4799ca0589870c3899lh for (i = 0; i < TX_RING_SIZE; i++) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pMil->pNonphysical->TxDescQWrite->Tx_RES0 = 0x0f;
75ab5f91d942eea4138efe4799ca0589870c3899lh pMil->pNonphysical->TxDescQWrite->Tx_OWN = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh pMil->pNonphysical->TxDescQWrite++;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh pMil->pNonphysical->TxDescQWrite = pMil->pNonphysical->TxDescQStart;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pMdl->init_blk->TDRA = pMil->Tx_desc_pa;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (B_TRUE);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhallocate_desc_fail:
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->tx_desc_dma_handle = NULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh (void) ddi_dma_unbind_handle(pOdl->rx_desc_dma_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_dma_mem_free(&pOdl->rx_desc_acc_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_dma_free_handle(&pOdl->rx_desc_dma_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->rx_desc_dma_handle = NULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh return (B_FALSE);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Free Tx/Rx descriptors
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_free_descriptors(struct LayerPointers *pLayerPointers)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct odl *pOdl = pLayerPointers->pOdl;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Free Rx descriptors */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pOdl->rx_desc_dma_handle) {
75ab5f91d942eea4138efe4799ca0589870c3899lh (void) ddi_dma_unbind_handle(pOdl->rx_desc_dma_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_dma_mem_free(&pOdl->rx_desc_acc_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_dma_free_handle(&pOdl->rx_desc_dma_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->rx_desc_dma_handle = NULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Free Rx descriptors */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pOdl->tx_desc_dma_handle) {
75ab5f91d942eea4138efe4799ca0589870c3899lh (void) ddi_dma_unbind_handle(pOdl->tx_desc_dma_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_dma_mem_free(&pOdl->tx_desc_acc_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_dma_free_handle(&pOdl->tx_desc_dma_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->tx_desc_dma_handle = NULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Allocate Tx/Rx Ring buffer
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic boolean_t
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_alloc_dma_ringbuf(struct LayerPointers *pLayerPointers,
75ab5f91d942eea4138efe4799ca0589870c3899lh struct amd8111s_dma_ringbuf *pRing,
75ab5f91d942eea4138efe4799ca0589870c3899lh uint32_t ring_size, uint32_t msg_size)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh uint32_t idx, msg_idx = 0, msg_acc;
75ab5f91d942eea4138efe4799ca0589870c3899lh dev_info_t *devinfo = pLayerPointers->pOdl->devinfo;
75ab5f91d942eea4138efe4799ca0589870c3899lh size_t real_length;
75ab5f91d942eea4138efe4799ca0589870c3899lh uint_t count = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh ASSERT(pcn_buff_dma_attr_t.dma_attr_align == 1);
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->dma_buf_sz = msg_size;
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->ring_size = ring_size;
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->trunk_num = AMD8111S_SPLIT;
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->buf_sz = msg_size * ring_size;
75ab5f91d942eea4138efe4799ca0589870c3899lh if (ring_size < pRing->trunk_num)
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->trunk_num = ring_size;
75ab5f91d942eea4138efe4799ca0589870c3899lh ASSERT((pRing->buf_sz % pRing->trunk_num) == 0);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->trunk_sz = pRing->buf_sz / pRing->trunk_num;
75ab5f91d942eea4138efe4799ca0589870c3899lh ASSERT((pRing->trunk_sz % pRing->dma_buf_sz) == 0);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->msg_buf = kmem_zalloc(sizeof (struct amd8111s_msgbuf) *
75ab5f91d942eea4138efe4799ca0589870c3899lh ring_size, KM_NOSLEEP);
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->dma_hdl = kmem_zalloc(sizeof (ddi_dma_handle_t) *
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->trunk_num, KM_NOSLEEP);
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->acc_hdl = kmem_zalloc(sizeof (ddi_acc_handle_t) *
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->trunk_num, KM_NOSLEEP);
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->dma_cookie = kmem_zalloc(sizeof (ddi_dma_cookie_t) *
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->trunk_num, KM_NOSLEEP);
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->trunk_addr = kmem_zalloc(sizeof (caddr_t) *
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->trunk_num, KM_NOSLEEP);
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pRing->msg_buf == NULL || pRing->dma_hdl == NULL ||
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->acc_hdl == NULL || pRing->trunk_addr == NULL ||
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->dma_cookie == NULL) {
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_NOTE,
75ab5f91d942eea4138efe4799ca0589870c3899lh "kmem_zalloc failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh goto failed;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh for (idx = 0; idx < pRing->trunk_num; ++idx) {
75ab5f91d942eea4138efe4799ca0589870c3899lh if (ddi_dma_alloc_handle(devinfo, &pcn_buff_dma_attr_t,
75ab5f91d942eea4138efe4799ca0589870c3899lh DDI_DMA_SLEEP, NULL, &(pRing->dma_hdl[idx]))
75ab5f91d942eea4138efe4799ca0589870c3899lh != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_WARN,
75ab5f91d942eea4138efe4799ca0589870c3899lh "ddi_dma_alloc_handle failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh goto failed;
75ab5f91d942eea4138efe4799ca0589870c3899lh } else if (ddi_dma_mem_alloc(pRing->dma_hdl[idx],
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->trunk_sz, &pcn_acc_attr, DDI_DMA_STREAMING,
75ab5f91d942eea4138efe4799ca0589870c3899lh DDI_DMA_SLEEP, NULL,
75ab5f91d942eea4138efe4799ca0589870c3899lh (caddr_t *)&(pRing->trunk_addr[idx]),
75ab5f91d942eea4138efe4799ca0589870c3899lh (size_t *)(&real_length), &pRing->acc_hdl[idx])
75ab5f91d942eea4138efe4799ca0589870c3899lh != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_WARN,
75ab5f91d942eea4138efe4799ca0589870c3899lh "ddi_dma_mem_alloc failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh goto failed;
75ab5f91d942eea4138efe4799ca0589870c3899lh } else if (real_length != pRing->trunk_sz) {
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_WARN,
75ab5f91d942eea4138efe4799ca0589870c3899lh "ddi_dma_mem_alloc failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh goto failed;
75ab5f91d942eea4138efe4799ca0589870c3899lh } else if (ddi_dma_addr_bind_handle(pRing->dma_hdl[idx],
75ab5f91d942eea4138efe4799ca0589870c3899lh NULL, (caddr_t)pRing->trunk_addr[idx], real_length,
75ab5f91d942eea4138efe4799ca0589870c3899lh DDI_DMA_WRITE | DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL,
75ab5f91d942eea4138efe4799ca0589870c3899lh &pRing->dma_cookie[idx], &count) != DDI_DMA_MAPPED) {
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_WARN,
75ab5f91d942eea4138efe4799ca0589870c3899lh "ddi_dma_addr_bind_handle failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh goto failed;
75ab5f91d942eea4138efe4799ca0589870c3899lh } else {
75ab5f91d942eea4138efe4799ca0589870c3899lh for (msg_acc = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh msg_acc < pRing->trunk_sz / pRing->dma_buf_sz;
75ab5f91d942eea4138efe4799ca0589870c3899lh ++ msg_acc) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->msg_buf[msg_idx].offset =
75ab5f91d942eea4138efe4799ca0589870c3899lh msg_acc * pRing->dma_buf_sz;
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->msg_buf[msg_idx].vir_addr =
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->trunk_addr[idx] +
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->msg_buf[msg_idx].offset;
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->msg_buf[msg_idx].phy_addr =
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->dma_cookie[idx].dmac_laddress +
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->msg_buf[msg_idx].offset;
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->msg_buf[msg_idx].p_hdl =
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->dma_hdl[idx];
75ab5f91d942eea4138efe4799ca0589870c3899lh msg_idx ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->free = pRing->msg_buf;
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->next = pRing->msg_buf;
75ab5f91d942eea4138efe4799ca0589870c3899lh pRing->curr = pRing->msg_buf;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (B_TRUE);
75ab5f91d942eea4138efe4799ca0589870c3899lhfailed:
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_free_dma_ringbuf(pRing);
75ab5f91d942eea4138efe4799ca0589870c3899lh return (B_FALSE);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Free Tx/Rx ring buffer
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_free_dma_ringbuf(struct amd8111s_dma_ringbuf *pRing)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh int idx;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pRing->dma_cookie != NULL) {
75ab5f91d942eea4138efe4799ca0589870c3899lh for (idx = 0; idx < pRing->trunk_num; idx ++) {
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pRing->dma_cookie[idx].dmac_laddress == 0) {
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh (void) ddi_dma_unbind_handle(pRing->dma_hdl[idx]);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh kmem_free(pRing->dma_cookie,
75ab5f91d942eea4138efe4799ca0589870c3899lh sizeof (ddi_dma_cookie_t) * pRing->trunk_num);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pRing->acc_hdl != NULL) {
75ab5f91d942eea4138efe4799ca0589870c3899lh for (idx = 0; idx < pRing->trunk_num; idx ++) {
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pRing->acc_hdl[idx] == NULL)
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_dma_mem_free(&pRing->acc_hdl[idx]);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh kmem_free(pRing->acc_hdl,
75ab5f91d942eea4138efe4799ca0589870c3899lh sizeof (ddi_acc_handle_t) * pRing->trunk_num);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pRing->dma_hdl != NULL) {
75ab5f91d942eea4138efe4799ca0589870c3899lh for (idx = 0; idx < pRing->trunk_num; idx ++) {
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pRing->dma_hdl[idx] == 0) {
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_dma_free_handle(&pRing->dma_hdl[idx]);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh kmem_free(pRing->dma_hdl,
75ab5f91d942eea4138efe4799ca0589870c3899lh sizeof (ddi_dma_handle_t) * pRing->trunk_num);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pRing->msg_buf != NULL) {
75ab5f91d942eea4138efe4799ca0589870c3899lh kmem_free(pRing->msg_buf,
75ab5f91d942eea4138efe4799ca0589870c3899lh sizeof (struct amd8111s_msgbuf) * pRing->ring_size);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pRing->trunk_addr != NULL) {
75ab5f91d942eea4138efe4799ca0589870c3899lh kmem_free(pRing->trunk_addr,
75ab5f91d942eea4138efe4799ca0589870c3899lh sizeof (caddr_t) * pRing->trunk_num);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh bzero(pRing, sizeof (*pRing));
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Allocate all Tx buffer.
75ab5f91d942eea4138efe4799ca0589870c3899lh * Allocate a Rx buffer for each Rx descriptor. Then
75ab5f91d942eea4138efe4799ca0589870c3899lh * call mil routine to fill physical address of Rx
75ab5f91d942eea4138efe4799ca0589870c3899lh * buffer into Rx descriptors
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic boolean_t
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_allocate_buffers(struct LayerPointers *pLayerPointers)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct odl *pOdl = pLayerPointers->pOdl;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Allocate rx Buffers
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (amd8111s_alloc_dma_ringbuf(pLayerPointers, &pOdl->rx_buf,
75ab5f91d942eea4138efe4799ca0589870c3899lh RX_RING_SIZE, RX_BUF_SIZE) == B_FALSE) {
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_WARN,
75ab5f91d942eea4138efe4799ca0589870c3899lh "amd8111s_alloc_dma_ringbuf for tx failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh goto allocate_buf_fail;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Allocate Tx buffers
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (amd8111s_alloc_dma_ringbuf(pLayerPointers, &pOdl->tx_buf,
75ab5f91d942eea4138efe4799ca0589870c3899lh TX_COALESC_SIZE, TX_BUF_SIZE) == B_FALSE) {
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_WARN,
75ab5f91d942eea4138efe4799ca0589870c3899lh "amd8111s_alloc_dma_ringbuf for tx failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh goto allocate_buf_fail;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Initilize the mil Queues
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh milInitGlbds(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh milInitRxQ(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (B_TRUE);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhallocate_buf_fail:
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_WARN,
75ab5f91d942eea4138efe4799ca0589870c3899lh "amd8111s_allocate_buffers failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh return (B_FALSE);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Free all Rx/Tx buffer
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_free_buffers(struct LayerPointers *pLayerPointers)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Free Tx buffers */
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_free_dma_ringbuf(&pLayerPointers->pOdl->tx_buf);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Free Rx Buffers */
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_free_dma_ringbuf(&pLayerPointers->pOdl->rx_buf);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Try to recycle all the descriptors and Tx buffers
75ab5f91d942eea4138efe4799ca0589870c3899lh * which are already freed by hardware.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_recycle_tx(struct LayerPointers *pLayerPointers)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct nonphysical *pNonphysical;
75ab5f91d942eea4138efe4799ca0589870c3899lh uint32_t count = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical = pLayerPointers->pMil->pNonphysical;
75ab5f91d942eea4138efe4799ca0589870c3899lh while (pNonphysical->TxDescQRead->Tx_OWN == 0 &&
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQRead != pNonphysical->TxDescQWrite) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl->tx_buf.free =
75ab5f91d942eea4138efe4799ca0589870c3899lh NEXT(pLayerPointers->pOdl->tx_buf, free);
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQRead++;
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pNonphysical->TxDescQRead > pNonphysical->TxDescQEnd) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQRead = pNonphysical->TxDescQStart;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh count ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pLayerPointers->pMil->tx_reschedule)
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_trigger_softintr(pLayerPointers->pOdl->drain_id);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (count);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Get packets in the Tx buffer, then copy them to the send buffer.
75ab5f91d942eea4138efe4799ca0589870c3899lh * Trigger hardware to send out packets.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_send_serial(struct LayerPointers *pLayerPointers)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct nonphysical *pNonphysical;
75ab5f91d942eea4138efe4799ca0589870c3899lh uint32_t count;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical = pLayerPointers->pMil->pNonphysical;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh mutex_enter(&pLayerPointers->pOdl->mdlSendLock);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh for (count = 0; count < AMD8111S_SEND_MAX; count ++) {
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pLayerPointers->pOdl->tx_buf.curr ==
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl->tx_buf.next) {
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh /* to verify if it needs to recycle the tx Buf */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (((pNonphysical->TxDescQWrite + 1 >
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQEnd) ? pNonphysical->TxDescQStart :
75ab5f91d942eea4138efe4799ca0589870c3899lh (pNonphysical->TxDescQWrite + 1)) ==
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQRead)
75ab5f91d942eea4138efe4799ca0589870c3899lh if (amd8111s_recycle_tx(pLayerPointers) == 0) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl
75ab5f91d942eea4138efe4799ca0589870c3899lh ->statistics.tx_no_descriptor ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Fill packet length */
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQWrite->Tx_BCNT = (uint16_t)pLayerPointers
75ab5f91d942eea4138efe4799ca0589870c3899lh ->pOdl->tx_buf.curr->msg_size;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Fill physical buffer address */
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQWrite->Tx_Base_Addr = (unsigned int)
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl->tx_buf.curr->phy_addr;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQWrite->Tx_SOP = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQWrite->Tx_EOP = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQWrite->Tx_ADD_FCS = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQWrite->Tx_LTINT = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQWrite->Tx_USPACE = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQWrite->Tx_OWN = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQWrite++;
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pNonphysical->TxDescQWrite > pNonphysical->TxDescQEnd) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pNonphysical->TxDescQWrite = pNonphysical->TxDescQStart;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl->tx_buf.curr =
75ab5f91d942eea4138efe4799ca0589870c3899lh NEXT(pLayerPointers->pOdl->tx_buf, curr);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl->statistics.tx_ok_packets += count;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh mutex_exit(&pLayerPointers->pOdl->mdlSendLock);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Call mdlTransmit to send the pkt out on the network */
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlTransmit(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Softintr entrance. try to send out packets in the Tx buffer.
75ab5f91d942eea4138efe4799ca0589870c3899lh * If reschedule is True, call mac_tx_update to re-enable the
75ab5f91d942eea4138efe4799ca0589870c3899lh * transmit
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic uint_t
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_send_drain(caddr_t arg)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
22eb7cb54d8a6bcf6fe2674cb4b1f0cf2d85cfb6gd struct LayerPointers *pLayerPointers = (void *)arg;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_send_serial(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pLayerPointers->pMil->tx_reschedule &&
75ab5f91d942eea4138efe4799ca0589870c3899lh NEXT(pLayerPointers->pOdl->tx_buf, next) !=
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl->tx_buf.free) {
75ab5f91d942eea4138efe4799ca0589870c3899lh mac_tx_update(pLayerPointers->pOdl->mh);
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pMil->tx_reschedule = B_FALSE;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (DDI_INTR_CLAIMED);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Get a Tx buffer
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic struct amd8111s_msgbuf *
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_getTxbuf(struct LayerPointers *pLayerPointers)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct amd8111s_msgbuf *tmp, *next;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh mutex_enter(&pLayerPointers->pOdl->mdlSendLock);
75ab5f91d942eea4138efe4799ca0589870c3899lh next = NEXT(pLayerPointers->pOdl->tx_buf, next);
75ab5f91d942eea4138efe4799ca0589870c3899lh if (next == pLayerPointers->pOdl->tx_buf.free) {
75ab5f91d942eea4138efe4799ca0589870c3899lh tmp = NULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh } else {
75ab5f91d942eea4138efe4799ca0589870c3899lh tmp = pLayerPointers->pOdl->tx_buf.next;
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl->tx_buf.next = next;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh mutex_exit(&pLayerPointers->pOdl->mdlSendLock);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (tmp);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic boolean_t
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_send(struct LayerPointers *pLayerPointers, mblk_t *mp)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct odl *pOdl;
75ab5f91d942eea4138efe4799ca0589870c3899lh size_t frag_len;
75ab5f91d942eea4138efe4799ca0589870c3899lh mblk_t *tmp;
75ab5f91d942eea4138efe4799ca0589870c3899lh struct amd8111s_msgbuf *txBuf;
75ab5f91d942eea4138efe4799ca0589870c3899lh uint8_t *pMsg;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl = pLayerPointers->pOdl;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* alloc send buffer */
75ab5f91d942eea4138efe4799ca0589870c3899lh txBuf = amd8111s_getTxbuf(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh if (txBuf == NULL) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->statistics.tx_no_buffer ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pMil->tx_reschedule = B_TRUE;
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_send_serial(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh return (B_FALSE);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* copy packet to send buffer */
75ab5f91d942eea4138efe4799ca0589870c3899lh txBuf->msg_size = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh pMsg = (uint8_t *)txBuf->vir_addr;
75ab5f91d942eea4138efe4799ca0589870c3899lh for (tmp = mp; tmp; tmp = tmp->b_cont) {
75ab5f91d942eea4138efe4799ca0589870c3899lh frag_len = MBLKL(tmp);
75ab5f91d942eea4138efe4799ca0589870c3899lh bcopy(tmp->b_rptr, pMsg, frag_len);
75ab5f91d942eea4138efe4799ca0589870c3899lh txBuf->msg_size += frag_len;
75ab5f91d942eea4138efe4799ca0589870c3899lh pMsg += frag_len;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh freemsg(mp);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_send_serial(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (B_TRUE);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * (GLD Entry Point) Send the message block to lower layer
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic mblk_t *
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_m_tx(void *arg, mblk_t *mp)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct LayerPointers *pLayerPointers = arg;
75ab5f91d942eea4138efe4799ca0589870c3899lh mblk_t *next;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh rw_enter(&pLayerPointers->pOdl->chip_lock, RW_READER);
75ab5f91d942eea4138efe4799ca0589870c3899lh if (!pLayerPointers->run) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl->statistics.tx_afterunplumb ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh freemsgchain(mp);
75ab5f91d942eea4138efe4799ca0589870c3899lh mp = NULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh while (mp != NULL) {
75ab5f91d942eea4138efe4799ca0589870c3899lh next = mp->b_next;
75ab5f91d942eea4138efe4799ca0589870c3899lh mp->b_next = NULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh if (!amd8111s_send(pLayerPointers, mp)) {
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Send fail */
75ab5f91d942eea4138efe4799ca0589870c3899lh mp->b_next = next;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh mp = next;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh rw_exit(&pLayerPointers->pOdl->chip_lock);
75ab5f91d942eea4138efe4799ca0589870c3899lh return (mp);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * (GLD Entry Point) Interrupt Service Routine
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic uint_t
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_intr(caddr_t arg)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh unsigned int intrCauses;
22eb7cb54d8a6bcf6fe2674cb4b1f0cf2d85cfb6gd struct LayerPointers *pLayerPointers = (void *)arg;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Read the interrupt status from mdl */
75ab5f91d942eea4138efe4799ca0589870c3899lh intrCauses = mdlReadInterrupt(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (intrCauses == 0) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl->statistics.intr_OTHER ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh return (DDI_INTR_UNCLAIMED);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (intrCauses & LCINT) {
75ab5f91d942eea4138efe4799ca0589870c3899lh if (mdlReadLink(pLayerPointers) == LINK_UP) {
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlGetActiveMediaInfo(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Link status changed */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pLayerPointers->pOdl->LinkStatus !=
75ab5f91d942eea4138efe4799ca0589870c3899lh LINK_STATE_UP) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl->LinkStatus =
75ab5f91d942eea4138efe4799ca0589870c3899lh LINK_STATE_UP;
75ab5f91d942eea4138efe4799ca0589870c3899lh mac_link_update(pLayerPointers->pOdl->mh,
75ab5f91d942eea4138efe4799ca0589870c3899lh LINK_STATE_UP);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh } else {
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pLayerPointers->pOdl->LinkStatus !=
75ab5f91d942eea4138efe4799ca0589870c3899lh LINK_STATE_DOWN) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl->LinkStatus =
75ab5f91d942eea4138efe4799ca0589870c3899lh LINK_STATE_DOWN;
75ab5f91d942eea4138efe4799ca0589870c3899lh mac_link_update(pLayerPointers->pOdl->mh,
75ab5f91d942eea4138efe4799ca0589870c3899lh LINK_STATE_DOWN);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * RINT0: Receive Interrupt is set by the controller after the last
75ab5f91d942eea4138efe4799ca0589870c3899lh * descriptor of a receive frame for this ring has been updated by
75ab5f91d942eea4138efe4799ca0589870c3899lh * writing a 0 to the OWNership bit.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (intrCauses & RINT0) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl->statistics.intr_RINT0 ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_receive(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * TINT0: Transmit Interrupt is set by the controller after the OWN bit
75ab5f91d942eea4138efe4799ca0589870c3899lh * in the last descriptor of a transmit frame in this particular ring
75ab5f91d942eea4138efe4799ca0589870c3899lh * has been cleared to indicate the frame has been copied to the
75ab5f91d942eea4138efe4799ca0589870c3899lh * transmit FIFO.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (intrCauses & TINT0) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl->statistics.intr_TINT0 ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * if desc ring is NULL and tx buf is not NULL, it should
75ab5f91d942eea4138efe4799ca0589870c3899lh * drain tx buffer
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_send_serial(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (intrCauses & STINT) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl->statistics.intr_STINT ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (DDI_INTR_CLAIMED);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * To re-initilize data structures.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_sw_reset(struct LayerPointers *pLayerPointers)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Reset all Tx/Rx queues and descriptors */
75ab5f91d942eea4138efe4799ca0589870c3899lh milResetTxQ(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh milInitRxQ(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Send all pending tx packets
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_tx_drain(struct LayerPointers *adapter)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct tx_desc *pTx_desc = adapter->pMil->pNonphysical->TxDescQStart;
75ab5f91d942eea4138efe4799ca0589870c3899lh int i, desc_count = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh for (i = 0; i < 30; i++) {
75ab5f91d942eea4138efe4799ca0589870c3899lh while ((pTx_desc->Tx_OWN == 0) && (desc_count < TX_RING_SIZE)) {
75ab5f91d942eea4138efe4799ca0589870c3899lh /* This packet has been transmitted */
75ab5f91d942eea4138efe4799ca0589870c3899lh pTx_desc ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh desc_count ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh if (desc_count == TX_RING_SIZE) {
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Wait 1 ms */
75ab5f91d942eea4138efe4799ca0589870c3899lh drv_usecwait(1000);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh adapter->pOdl->statistics.tx_draintime = i;
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * (GLD Entry Point) To start card will be called at
75ab5f91d942eea4138efe4799ca0589870c3899lh * ifconfig plumb
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_m_start(void *arg)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct LayerPointers *pLayerPointers = arg;
75ab5f91d942eea4138efe4799ca0589870c3899lh struct odl *pOdl = pLayerPointers->pOdl;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_sw_reset(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlHWReset(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh rw_enter(&pOdl->chip_lock, RW_WRITER);
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->run = B_TRUE;
75ab5f91d942eea4138efe4799ca0589870c3899lh rw_exit(&pOdl->chip_lock);
75ab5f91d942eea4138efe4799ca0589870c3899lh return (0);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * (GLD Entry Point) To stop card will be called at
75ab5f91d942eea4138efe4799ca0589870c3899lh * ifconfig unplumb
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_m_stop(void *arg)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct LayerPointers *pLayerPointers = (struct LayerPointers *)arg;
75ab5f91d942eea4138efe4799ca0589870c3899lh struct odl *pOdl = pLayerPointers->pOdl;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Ensure send all pending tx packets */
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_tx_drain(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Stop the controller and disable the controller interrupt
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh rw_enter(&pOdl->chip_lock, RW_WRITER);
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlStopChip(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->run = B_FALSE;
75ab5f91d942eea4138efe4799ca0589870c3899lh rw_exit(&pOdl->chip_lock);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * To clean up all
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_free_resource(struct LayerPointers *pLayerPointers)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh unsigned long mem_free_array[100];
75ab5f91d942eea4138efe4799ca0589870c3899lh unsigned long *pmem_free_array, size;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Free Rx/Tx descriptors */
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_free_descriptors(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Free memory on lower layers */
75ab5f91d942eea4138efe4799ca0589870c3899lh milFreeResources(pLayerPointers, mem_free_array);
75ab5f91d942eea4138efe4799ca0589870c3899lh pmem_free_array = mem_free_array;
75ab5f91d942eea4138efe4799ca0589870c3899lh while (*pmem_free_array) {
75ab5f91d942eea4138efe4799ca0589870c3899lh switch (*pmem_free_array) {
75ab5f91d942eea4138efe4799ca0589870c3899lh case VIRTUAL:
75ab5f91d942eea4138efe4799ca0589870c3899lh size = *(++pmem_free_array);
75ab5f91d942eea4138efe4799ca0589870c3899lh pmem_free_array++;
75ab5f91d942eea4138efe4799ca0589870c3899lh kmem_free((void *)*(pmem_free_array), size);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh pmem_free_array++;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_free_buffers(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * (GLD Enty pointer) To add/delete multi cast addresses
75ab5f91d942eea4138efe4799ca0589870c3899lh *
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_m_multicst(void *arg, boolean_t add, const uint8_t *addr)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct LayerPointers *pLayerPointers = arg;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (add) {
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Add a multicast entry */
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlAddMulticastAddress(pLayerPointers, (UCHAR *)addr);
75ab5f91d942eea4138efe4799ca0589870c3899lh } else {
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Delete a multicast entry */
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlDeleteMulticastAddress(pLayerPointers, (UCHAR *)addr);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (0);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh#ifdef AMD8111S_DEBUG
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * The size of MIB registers is only 32 bits. Dump them before one
75ab5f91d942eea4138efe4799ca0589870c3899lh * of them overflows.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic void
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_dump_mib(struct LayerPointers *pLayerPointers)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct amd8111s_statistics *adapterStat;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat = &pLayerPointers->pOdl->statistics;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->mib_dump_counter ++;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Rx Counters
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_unicst_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvUniCastPkts);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_multicst_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvMultiCastPkts);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_broadcst_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvBroadCastPkts);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_macctrl_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvMACCtrl);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_flowctrl_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvFlowCtrl);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_bytes +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvOctets);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_good_bytes +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvGoodOctets);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_undersize_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvUndersizePkts);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_oversize_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvOversizePkts);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_drop_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvDropPktsRing0);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_align_err_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvAlignmentErrors);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_fcs_err_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvFCSErrors);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_symbol_err_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvSymbolErrors);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_miss_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvMissPkts);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Tx Counters
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->tx_mib_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtPackets);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->tx_mib_multicst_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtMultiCastPkts);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->tx_mib_broadcst_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtBroadCastPkts);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->tx_mib_flowctrl_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtFlowCtrl);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->tx_mib_bytes +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtOctets);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->tx_mib_defer_trans_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtDeferredTransmit);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->tx_mib_collision_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtCollisions);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->tx_mib_one_coll_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtOneCollision);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->tx_mib_multi_coll_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtMultipleCollision);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->tx_mib_late_coll_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtLateCollision);
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->tx_mib_ex_coll_packets +=
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtExcessiveCollision);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Clear all MIB registers */
75ab5f91d942eea4138efe4799ca0589870c3899lh WRITE_REG16(pLayerPointers, pLayerPointers->pMdl->Mem_Address
75ab5f91d942eea4138efe4799ca0589870c3899lh + MIB_ADDR, MIB_CLEAR);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh#endif
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * (GLD Entry Point) set/unset promiscus mode
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_m_promisc(void *arg, boolean_t on)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct LayerPointers *pLayerPointers = arg;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (on) {
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlSetPromiscuous(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh } else {
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlDisablePromiscuous(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (0);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * (Gld Entry point) Changes the Mac address of card
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_m_unicst(void *arg, const uint8_t *macaddr)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct LayerPointers *pLayerPointers = arg;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlDisableInterrupt(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlSetMacAddress(pLayerPointers, (unsigned char *)macaddr);
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlEnableInterrupt(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (0);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Reset the card
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhvoid
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_reset(struct LayerPointers *pLayerPointers)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_sw_reset(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlHWReset(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * attach(9E) -- Attach a device to the system
75ab5f91d942eea4138efe4799ca0589870c3899lh *
75ab5f91d942eea4138efe4799ca0589870c3899lh * Called once for each board after successfully probed.
75ab5f91d942eea4138efe4799ca0589870c3899lh * will do
75ab5f91d942eea4138efe4799ca0589870c3899lh * a. creating minor device node for the instance.
75ab5f91d942eea4138efe4799ca0589870c3899lh * b. allocate & Initilize four layers (call odlInit)
75ab5f91d942eea4138efe4799ca0589870c3899lh * c. get MAC address
75ab5f91d942eea4138efe4799ca0589870c3899lh * d. initilize pLayerPointers to gld private pointer
75ab5f91d942eea4138efe4799ca0589870c3899lh * e. register with GLD
75ab5f91d942eea4138efe4799ca0589870c3899lh * if any action fails does clean up & returns DDI_FAILURE
75ab5f91d942eea4138efe4799ca0589870c3899lh * else retursn DDI_SUCCESS
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh mac_register_t *macp;
75ab5f91d942eea4138efe4799ca0589870c3899lh struct LayerPointers *pLayerPointers;
75ab5f91d942eea4138efe4799ca0589870c3899lh struct odl *pOdl;
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_acc_handle_t *pci_handle;
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_device_acc_attr_t dev_attr;
75ab5f91d942eea4138efe4799ca0589870c3899lh caddr_t addrp = NULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh switch (cmd) {
75ab5f91d942eea4138efe4799ca0589870c3899lh case DDI_ATTACH:
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh default:
75ab5f91d942eea4138efe4799ca0589870c3899lh return (DDI_FAILURE);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers = (struct LayerPointers *)
75ab5f91d942eea4138efe4799ca0589870c3899lh kmem_zalloc(sizeof (struct LayerPointers), KM_SLEEP);
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111sadapter = pLayerPointers;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Get device instance number */
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->instance = ddi_get_instance(devinfo);
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_set_driver_private(devinfo, (caddr_t)pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl = (struct odl *)kmem_zalloc(sizeof (struct odl), KM_SLEEP);
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pOdl = pOdl;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->devinfo = devinfo;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Here, we only allocate memory for struct odl and initilize it.
75ab5f91d942eea4138efe4799ca0589870c3899lh * All other memory allocation & initilization will be done in odlInit
75ab5f91d942eea4138efe4799ca0589870c3899lh * later on this routine.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (ddi_get_iblock_cookie(devinfo, 0, &pLayerPointers->pOdl->iblock)
75ab5f91d942eea4138efe4799ca0589870c3899lh != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_NOTE,
75ab5f91d942eea4138efe4799ca0589870c3899lh "attach: get iblock cookies failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh goto attach_failure;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh rw_init(&pOdl->chip_lock, NULL, RW_DRIVER, (void *)pOdl->iblock);
75ab5f91d942eea4138efe4799ca0589870c3899lh mutex_init(&pOdl->mdlSendLock, "amd8111s Send Protection Lock",
75ab5f91d942eea4138efe4799ca0589870c3899lh MUTEX_DRIVER, (void *)pOdl->iblock);
75ab5f91d942eea4138efe4799ca0589870c3899lh mutex_init(&pOdl->mdlRcvLock, "amd8111s Rcv Protection Lock",
75ab5f91d942eea4138efe4799ca0589870c3899lh MUTEX_DRIVER, (void *)pOdl->iblock);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Setup PCI space */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pci_config_setup(devinfo, &pOdl->pci_handle) != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh return (DDI_FAILURE);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->attach_progress = AMD8111S_ATTACH_PCI;
75ab5f91d942eea4138efe4799ca0589870c3899lh pci_handle = &pOdl->pci_handle;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->vendor_id = pci_config_get16(*pci_handle, PCI_CONF_VENID);
75ab5f91d942eea4138efe4799ca0589870c3899lh pOdl->device_id = pci_config_get16(*pci_handle, PCI_CONF_DEVID);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Allocate and initialize all resource and map device registers.
75ab5f91d942eea4138efe4799ca0589870c3899lh * If failed, it returns a non-zero value.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (amd8111s_odlInit(pLayerPointers) != 0) {
75ab5f91d942eea4138efe4799ca0589870c3899lh goto attach_failure;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->attach_progress |= AMD8111S_ATTACH_RESOURCE;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
75ab5f91d942eea4138efe4799ca0589870c3899lh dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
75ab5f91d942eea4138efe4799ca0589870c3899lh dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (ddi_regs_map_setup(devinfo, 1, &addrp, 0, 4096, &dev_attr,
75ab5f91d942eea4138efe4799ca0589870c3899lh &(pLayerPointers->pOdl->MemBasehandle)) != 0) {
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_log(pLayerPointers, CE_NOTE,
75ab5f91d942eea4138efe4799ca0589870c3899lh "attach: ddi_regs_map_setup failed");
75ab5f91d942eea4138efe4799ca0589870c3899lh goto attach_failure;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->pMdl->Mem_Address = (unsigned long)addrp;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Initialize HW */
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlOpen(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlGetActiveMediaInfo(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->attach_progress |= AMD8111S_ATTACH_REGS;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Setup the interrupt
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (ddi_add_intr(devinfo, 0, &pOdl->iblock, 0, amd8111s_intr,
75ab5f91d942eea4138efe4799ca0589870c3899lh (caddr_t)pLayerPointers) != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh goto attach_failure;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->attach_progress |= AMD8111S_ATTACH_INTRADDED;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Setup soft intr
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (ddi_add_softintr(devinfo, DDI_SOFTINT_LOW, &pOdl->drain_id,
75ab5f91d942eea4138efe4799ca0589870c3899lh NULL, NULL, amd8111s_send_drain,
75ab5f91d942eea4138efe4799ca0589870c3899lh (caddr_t)pLayerPointers) != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh goto attach_failure;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->attach_progress |= AMD8111S_ATTACH_RESCHED;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Initilize the mac structure
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if ((macp = mac_alloc(MAC_VERSION)) == NULL)
75ab5f91d942eea4138efe4799ca0589870c3899lh goto attach_failure;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
75ab5f91d942eea4138efe4799ca0589870c3899lh macp->m_driver = pLayerPointers;
75ab5f91d942eea4138efe4799ca0589870c3899lh macp->m_dip = devinfo;
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Get MAC address */
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlGetMacAddress(pLayerPointers, (unsigned char *)pOdl->MacAddress);
75ab5f91d942eea4138efe4799ca0589870c3899lh macp->m_src_addr = pOdl->MacAddress;
75ab5f91d942eea4138efe4799ca0589870c3899lh macp->m_callbacks = &amd8111s_m_callbacks;
75ab5f91d942eea4138efe4799ca0589870c3899lh macp->m_min_sdu = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh /* 1518 - 14 (ether header) - 4 (CRC) */
75ab5f91d942eea4138efe4799ca0589870c3899lh macp->m_max_sdu = ETHERMTU;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz macp->m_margin = VLAN_TAGSZ;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Finally, we're ready to register ourselves with the MAC layer
75ab5f91d942eea4138efe4799ca0589870c3899lh * interface; if this succeeds, we're ready to start.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (mac_register(macp, &pOdl->mh) != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh mac_free(macp);
75ab5f91d942eea4138efe4799ca0589870c3899lh goto attach_failure;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh mac_free(macp);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh pLayerPointers->attach_progress |= AMD8111S_ATTACH_MACREGED;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (DDI_SUCCESS);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhattach_failure:
75ab5f91d942eea4138efe4799ca0589870c3899lh (void) amd8111s_unattach(devinfo, pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh return (DDI_FAILURE);
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * detach(9E) -- Detach a device from the system
75ab5f91d942eea4138efe4799ca0589870c3899lh *
75ab5f91d942eea4138efe4799ca0589870c3899lh * It is called for each device instance when the system is preparing to
75ab5f91d942eea4138efe4799ca0589870c3899lh * unload a dynamically unloadable driver.
75ab5f91d942eea4138efe4799ca0589870c3899lh * will Do
75ab5f91d942eea4138efe4799ca0589870c3899lh * a. check if any driver buffers are held by OS.
75ab5f91d942eea4138efe4799ca0589870c3899lh * b. do clean up of all allocated memory if it is not in use by OS.
75ab5f91d942eea4138efe4799ca0589870c3899lh * c. un register with GLD
75ab5f91d942eea4138efe4799ca0589870c3899lh * d. return DDI_SUCCESS on succes full free & unregister
75ab5f91d942eea4138efe4799ca0589870c3899lh * else GLD_FAILURE
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct LayerPointers *pLayerPointers;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh switch (cmd) {
75ab5f91d942eea4138efe4799ca0589870c3899lh case DDI_DETACH:
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh default:
75ab5f91d942eea4138efe4799ca0589870c3899lh return (DDI_FAILURE);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Get the driver private (struct LayerPointers *) structure
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh if ((pLayerPointers = (struct LayerPointers *)ddi_get_driver_private
75ab5f91d942eea4138efe4799ca0589870c3899lh (devinfo)) == NULL) {
75ab5f91d942eea4138efe4799ca0589870c3899lh return (DDI_FAILURE);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (amd8111s_unattach(devinfo, pLayerPointers));
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_unattach(dev_info_t *devinfo, struct LayerPointers *pLayerPointers)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct odl *pOdl = pLayerPointers->pOdl;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pLayerPointers->attach_progress & AMD8111S_ATTACH_MACREGED) {
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Unregister driver from the GLD interface */
75ab5f91d942eea4138efe4799ca0589870c3899lh if (mac_unregister(pOdl->mh) != DDI_SUCCESS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh return (DDI_FAILURE);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pLayerPointers->attach_progress & AMD8111S_ATTACH_INTRADDED) {
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_remove_intr(devinfo, 0, pOdl->iblock);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pLayerPointers->attach_progress & AMD8111S_ATTACH_RESCHED) {
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_remove_softintr(pOdl->drain_id);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pLayerPointers->attach_progress & AMD8111S_ATTACH_REGS) {
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Stop HW */
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlStopChip(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_regs_map_free(&(pOdl->MemBasehandle));
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pLayerPointers->attach_progress & AMD8111S_ATTACH_RESOURCE) {
75ab5f91d942eea4138efe4799ca0589870c3899lh /* Free All memory allocated */
75ab5f91d942eea4138efe4799ca0589870c3899lh amd8111s_free_resource(pLayerPointers);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pLayerPointers->attach_progress & AMD8111S_ATTACH_PCI) {
75ab5f91d942eea4138efe4799ca0589870c3899lh pci_config_teardown(&pOdl->pci_handle);
75ab5f91d942eea4138efe4799ca0589870c3899lh mutex_destroy(&pOdl->mdlSendLock);
75ab5f91d942eea4138efe4799ca0589870c3899lh mutex_destroy(&pOdl->mdlRcvLock);
75ab5f91d942eea4138efe4799ca0589870c3899lh rw_destroy(&pOdl->chip_lock);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh kmem_free(pOdl, sizeof (struct odl));
75ab5f91d942eea4138efe4799ca0589870c3899lh kmem_free(pLayerPointers, sizeof (struct LayerPointers));
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh return (DDI_SUCCESS);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * (GLD Entry Point)GLD will call this entry point perodicaly to
75ab5f91d942eea4138efe4799ca0589870c3899lh * get driver statistices.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhstatic int
75ab5f91d942eea4138efe4799ca0589870c3899lhamd8111s_m_stat(void *arg, uint_t stat, uint64_t *val)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh struct LayerPointers *pLayerPointers = arg;
75ab5f91d942eea4138efe4799ca0589870c3899lh struct amd8111s_statistics *adapterStat;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat = &pLayerPointers->pOdl->statistics;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh switch (stat) {
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Current Status
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh case MAC_STAT_IFSPEED:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = pLayerPointers->pMdl->Speed * 1000000;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_LINK_DUPLEX:
75ab5f91d942eea4138efe4799ca0589870c3899lh if (pLayerPointers->pMdl->FullDuplex) {
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = LINK_DUPLEX_FULL;
75ab5f91d942eea4138efe4799ca0589870c3899lh } else {
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = LINK_DUPLEX_HALF;
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Capabilities
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_CAP_1000FDX:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_CAP_1000HDX:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_CAP_100FDX:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_CAP_100HDX:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_CAP_10FDX:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_CAP_10HDX:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_CAP_ASMPAUSE:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_CAP_PAUSE:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_CAP_AUTONEG:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_ADV_CAP_1000FDX:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_ADV_CAP_1000HDX:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 0;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_ADV_CAP_100FDX:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_ADV_CAP_100HDX:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_ADV_CAP_10FDX:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_ADV_CAP_10HDX:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_ADV_CAP_ASMPAUSE:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_ADV_CAP_PAUSE:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_ADV_CAP_AUTONEG:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = 1;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Rx Counters
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh case MAC_STAT_IPACKETS:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->rx_mib_unicst_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_multicst_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_broadcst_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvUniCastPkts) +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvMultiCastPkts) +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvBroadCastPkts);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case MAC_STAT_RBYTES:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->rx_mib_bytes +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvOctets);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case MAC_STAT_MULTIRCV:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->rx_mib_multicst_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvMultiCastPkts);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case MAC_STAT_BRDCSTRCV:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->rx_mib_broadcst_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvBroadCastPkts);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case MAC_STAT_NORCVBUF:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->rx_allocfail +
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_drop_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvDropPktsRing0);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case MAC_STAT_IERRORS:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->rx_mib_align_err_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_fcs_err_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh adapterStat->rx_mib_symbol_err_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvAlignmentErrors) +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvFCSErrors) +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvSymbolErrors);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_ALIGN_ERRORS:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->rx_mib_align_err_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvAlignmentErrors);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_FCS_ERRORS:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->rx_mib_fcs_err_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, RcvFCSErrors);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh /*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Tx Counters
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lh case MAC_STAT_OPACKETS:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->tx_mib_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtPackets);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case MAC_STAT_OBYTES:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->tx_mib_bytes +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtOctets);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case MAC_STAT_MULTIXMT:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->tx_mib_multicst_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtMultiCastPkts);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case MAC_STAT_BRDCSTXMT:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->tx_mib_broadcst_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtBroadCastPkts);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case MAC_STAT_NOXMTBUF:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->tx_no_descriptor;
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case MAC_STAT_OERRORS:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->tx_mib_ex_coll_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtExcessiveCollision);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case MAC_STAT_COLLISIONS:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->tx_mib_ex_coll_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtCollisions);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_FIRST_COLLISIONS:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->tx_mib_one_coll_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtOneCollision);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_MULTI_COLLISIONS:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->tx_mib_multi_coll_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtMultipleCollision);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_EX_COLLISIONS:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->tx_mib_ex_coll_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtExcessiveCollision);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_TX_LATE_COLLISIONS:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->tx_mib_late_coll_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtLateCollision);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh case ETHER_STAT_DEFER_XMTS:
75ab5f91d942eea4138efe4799ca0589870c3899lh *val = adapterStat->tx_mib_defer_trans_packets +
75ab5f91d942eea4138efe4799ca0589870c3899lh mdlReadMib(pLayerPointers, XmtDeferredTransmit);
75ab5f91d942eea4138efe4799ca0589870c3899lh break;
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh default:
75ab5f91d942eea4138efe4799ca0589870c3899lh return (ENOTSUP);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh return (0);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lh/*
75ab5f91d942eea4138efe4799ca0589870c3899lh * Memory Read Function Used by MDL to set card registers.
75ab5f91d942eea4138efe4799ca0589870c3899lh */
75ab5f91d942eea4138efe4799ca0589870c3899lhunsigned char
75ab5f91d942eea4138efe4799ca0589870c3899lhREAD_REG8(struct LayerPointers *pLayerPointers, long x)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh return (ddi_get8(pLayerPointers->pOdl->MemBasehandle, (uint8_t *)x));
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhint
75ab5f91d942eea4138efe4799ca0589870c3899lhREAD_REG16(struct LayerPointers *pLayerPointers, long x)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh return (ddi_get16(pLayerPointers->pOdl->MemBasehandle,
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint16_t *)(x)));
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhlong
75ab5f91d942eea4138efe4799ca0589870c3899lhREAD_REG32(struct LayerPointers *pLayerPointers, long x)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh return (ddi_get32(pLayerPointers->pOdl->MemBasehandle,
75ab5f91d942eea4138efe4799ca0589870c3899lh (uint32_t *)(x)));
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhvoid
75ab5f91d942eea4138efe4799ca0589870c3899lhWRITE_REG8(struct LayerPointers *pLayerPointers, long x, int y)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_put8(pLayerPointers->pOdl->MemBasehandle, (uint8_t *)(x), y);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhvoid
75ab5f91d942eea4138efe4799ca0589870c3899lhWRITE_REG16(struct LayerPointers *pLayerPointers, long x, int y)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_put16(pLayerPointers->pOdl->MemBasehandle, (uint16_t *)(x), y);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhvoid
75ab5f91d942eea4138efe4799ca0589870c3899lhWRITE_REG32(struct LayerPointers *pLayerPointers, long x, int y)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh ddi_put32(pLayerPointers->pOdl->MemBasehandle, (uint32_t *)(x), y);
75ab5f91d942eea4138efe4799ca0589870c3899lh}
75ab5f91d942eea4138efe4799ca0589870c3899lh
75ab5f91d942eea4138efe4799ca0589870c3899lhvoid
75ab5f91d942eea4138efe4799ca0589870c3899lhWRITE_REG64(struct LayerPointers *pLayerPointers, long x, char *y)
75ab5f91d942eea4138efe4799ca0589870c3899lh{
75ab5f91d942eea4138efe4799ca0589870c3899lh int i;
75ab5f91d942eea4138efe4799ca0589870c3899lh for (i = 0; i < 8; i++) {
75ab5f91d942eea4138efe4799ca0589870c3899lh WRITE_REG8(pLayerPointers, (x + i), y[i]);
75ab5f91d942eea4138efe4799ca0589870c3899lh }
75ab5f91d942eea4138efe4799ca0589870c3899lh}