6f3e57ac9d0b054c3169579f3422080b8ba10105mx/*
47693af92e50a1ad81825eb01b7157a211269613mx * CDDL HEADER START
47693af92e50a1ad81825eb01b7157a211269613mx *
47693af92e50a1ad81825eb01b7157a211269613mx * The contents of this file are subject to the terms of the
47693af92e50a1ad81825eb01b7157a211269613mx * Common Development and Distribution License (the "License").
47693af92e50a1ad81825eb01b7157a211269613mx * You may not use this file except in compliance with the License.
47693af92e50a1ad81825eb01b7157a211269613mx *
47693af92e50a1ad81825eb01b7157a211269613mx * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
47693af92e50a1ad81825eb01b7157a211269613mx * or http://www.opensolaris.org/os/licensing.
47693af92e50a1ad81825eb01b7157a211269613mx * See the License for the specific language governing permissions
47693af92e50a1ad81825eb01b7157a211269613mx * and limitations under the License.
47693af92e50a1ad81825eb01b7157a211269613mx *
47693af92e50a1ad81825eb01b7157a211269613mx * When distributing Covered Code, include this CDDL HEADER in each
47693af92e50a1ad81825eb01b7157a211269613mx * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
47693af92e50a1ad81825eb01b7157a211269613mx * If applicable, add the following below this CDDL HEADER, with the
47693af92e50a1ad81825eb01b7157a211269613mx * fields enclosed by brackets "[]" replaced with your own identifying
47693af92e50a1ad81825eb01b7157a211269613mx * information: Portions Copyright [yyyy] [name of copyright owner]
47693af92e50a1ad81825eb01b7157a211269613mx *
47693af92e50a1ad81825eb01b7157a211269613mx * CDDL HEADER END
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx/*
d635b452b5b58e50f0c67983f4a57a04deefce77Winson Wang - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
47693af92e50a1ad81825eb01b7157a211269613mx * Use is subject to license terms.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#include "nge.h"
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing Chinastatic uint32_t nge_watchdog_count = 1 << 5;
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing Chinastatic uint32_t nge_watchdog_check = 1 << 3;
6f3e57ac9d0b054c3169579f3422080b8ba10105mxextern boolean_t nge_enable_msi;
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic void nge_sync_mac_modes(nge_t *);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#undef NGE_DBG
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#define NGE_DBG NGE_DBG_CHIP
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx/*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Operating register get/set access routines
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mxuint8_t nge_reg_get8(nge_t *ngep, nge_regno_t regno);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#pragma inline(nge_reg_get8)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxuint8_t
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_reg_get8(nge_t *ngep, nge_regno_t regno)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_reg_get8($%p, 0x%lx)", (void *)ngep, regno));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (ddi_get8(ngep->io_handle, PIO_ADDR(ngep, regno)));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxvoid nge_reg_put8(nge_t *ngep, nge_regno_t regno, uint8_t data);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#pragma inline(nge_reg_put8)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxvoid
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_reg_put8(nge_t *ngep, nge_regno_t regno, uint8_t data)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_reg_put8($%p, 0x%lx, 0x%x)",
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (void *)ngep, regno, data));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ddi_put8(ngep->io_handle, PIO_ADDR(ngep, regno), data);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxuint16_t nge_reg_get16(nge_t *ngep, nge_regno_t regno);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#pragma inline(nge_reg_get16)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxuint16_t
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_reg_get16(nge_t *ngep, nge_regno_t regno)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_reg_get16($%p, 0x%lx)", (void *)ngep, regno));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (ddi_get16(ngep->io_handle, PIO_ADDR(ngep, regno)));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxvoid nge_reg_put16(nge_t *ngep, nge_regno_t regno, uint16_t data);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#pragma inline(nge_reg_put16)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxvoid
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_reg_put16(nge_t *ngep, nge_regno_t regno, uint16_t data)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_reg_put16($%p, 0x%lx, 0x%x)",
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (void *)ngep, regno, data));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ddi_put16(ngep->io_handle, PIO_ADDR(ngep, regno), data);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxuint32_t nge_reg_get32(nge_t *ngep, nge_regno_t regno);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#pragma inline(nge_reg_get32)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxuint32_t
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_reg_get32(nge_t *ngep, nge_regno_t regno)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_reg_get32($%p, 0x%lx)", (void *)ngep, regno));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (ddi_get32(ngep->io_handle, PIO_ADDR(ngep, regno)));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxvoid nge_reg_put32(nge_t *ngep, nge_regno_t regno, uint32_t data);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#pragma inline(nge_reg_put32)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxvoid
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_reg_put32(nge_t *ngep, nge_regno_t regno, uint32_t data)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_reg_put32($%p, 0x%lx, 0x%x)",
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (void *)ngep, regno, data));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ddi_put32(ngep->io_handle, PIO_ADDR(ngep, regno), data);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int nge_chip_peek_cfg(nge_t *ngep, nge_peekpoke_t *ppd);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#pragma no_inline(nge_chip_peek_cfg)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_peek_cfg(nge_t *ngep, nge_peekpoke_t *ppd)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx int err;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint64_t regval;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint64_t regno;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_chip_peek_cfg($%p, $%p)",
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (void *)ngep, (void *)ppd));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx err = DDI_SUCCESS;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regno = ppd->pp_acc_offset;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx switch (ppd->pp_acc_size) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 1:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regval = pci_config_get8(ngep->cfg_handle, regno);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 2:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regval = pci_config_get16(ngep->cfg_handle, regno);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 4:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regval = pci_config_get32(ngep->cfg_handle, regno);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 8:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regval = pci_config_get64(ngep->cfg_handle, regno);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ppd->pp_acc_data = regval;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (err);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int nge_chip_poke_cfg(nge_t *ngep, nge_peekpoke_t *ppd);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_poke_cfg(nge_t *ngep, nge_peekpoke_t *ppd)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx int err;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint64_t regval;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint64_t regno;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_chip_poke_cfg($%p, $%p)",
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (void *)ngep, (void *)ppd));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx err = DDI_SUCCESS;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regno = ppd->pp_acc_offset;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regval = ppd->pp_acc_data;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx switch (ppd->pp_acc_size) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 1:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pci_config_put8(ngep->cfg_handle, regno, regval);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 2:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pci_config_put16(ngep->cfg_handle, regno, regval);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 4:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pci_config_put32(ngep->cfg_handle, regno, regval);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 8:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pci_config_put64(ngep->cfg_handle, regno, regval);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (err);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int nge_chip_peek_reg(nge_t *ngep, nge_peekpoke_t *ppd);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_peek_reg(nge_t *ngep, nge_peekpoke_t *ppd)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx int err;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint64_t regval;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx void *regaddr;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_chip_peek_reg($%p, $%p)",
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (void *)ngep, (void *)ppd));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx err = DDI_SUCCESS;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regaddr = PIO_ADDR(ngep, ppd->pp_acc_offset);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx switch (ppd->pp_acc_size) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 1:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regval = ddi_get8(ngep->io_handle, regaddr);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 2:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regval = ddi_get16(ngep->io_handle, regaddr);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 4:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regval = ddi_get32(ngep->io_handle, regaddr);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 8:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regval = ddi_get64(ngep->io_handle, regaddr);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx default:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regval = 0x0ull;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ppd->pp_acc_data = regval;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (err);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int nge_chip_poke_reg(nge_t *ngep, nge_peekpoke_t *ppd);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_poke_reg(nge_t *ngep, nge_peekpoke_t *ppd)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx int err;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint64_t regval;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx void *regaddr;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_chip_poke_reg($%p, $%p)",
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (void *)ngep, (void *)ppd));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx err = DDI_SUCCESS;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regaddr = PIO_ADDR(ngep, ppd->pp_acc_offset);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regval = ppd->pp_acc_data;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx switch (ppd->pp_acc_size) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 1:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ddi_put8(ngep->io_handle, regaddr, regval);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 2:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ddi_put16(ngep->io_handle, regaddr, regval);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 4:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ddi_put32(ngep->io_handle, regaddr, regval);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 8:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ddi_put64(ngep->io_handle, regaddr, regval);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (err);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int nge_chip_peek_mii(nge_t *ngep, nge_peekpoke_t *ppd);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#pragma no_inline(nge_chip_peek_mii)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_peek_mii(nge_t *ngep, nge_peekpoke_t *ppd)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx int err;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx err = DDI_SUCCESS;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ppd->pp_acc_data = nge_mii_get16(ngep, ppd->pp_acc_offset/2);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (err);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int nge_chip_poke_mii(nge_t *ngep, nge_peekpoke_t *ppd);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#pragma no_inline(nge_chip_poke_mii)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_poke_mii(nge_t *ngep, nge_peekpoke_t *ppd)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx int err;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx err = DDI_SUCCESS;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_mii_put16(ngep, ppd->pp_acc_offset/2, ppd->pp_acc_data);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (err);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx/*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Basic SEEPROM get/set access routine
6f3e57ac9d0b054c3169579f3422080b8ba10105mx *
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * This uses the chip's SEEPROM auto-access method, controlled by the
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Serial EEPROM Address/Data Registers at 0x504h, so the CPU
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * doesn't have to fiddle with the individual bits.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx *
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * The caller should hold <genlock> and *also* have already acquired
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * the right to access the SEEPROM.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx *
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Return value:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 0 on success,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * ENODATA on access timeout (maybe retryable: device may just be busy)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * EPROTO on other h/w or s/w errors.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx *
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * <*dp> is an input to a SEEPROM_ACCESS_WRITE operation, or an output
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * from a (successful) SEEPROM_ACCESS_READ.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_seeprom_access(nge_t *ngep, uint32_t cmd, nge_regno_t addr, uint16_t *dp)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint32_t tries;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_ep_cmd cmd_reg;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_ep_data data_reg;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_seeprom_access($%p, %d, %x, $%p)",
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (void *)ngep, cmd, addr, (void *)dp));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ASSERT(mutex_owned(ngep->genlock));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Check there's no command in progress.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx *
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Note: this *shouldn't* ever find that there is a command
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * in progress, because we already hold the <genlock> mutex.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Also, to ensure we don't have a conflict with the chip's
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * internal firmware or a process accessing the same (shared)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * So this is just a final consistency check: we shouldn't
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * see EITHER the START bit (command started but not complete)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * OR the COMPLETE bit (command completed but not cleared).
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx cmd_reg.cmd_val = nge_reg_get32(ngep, NGE_EP_CMD);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx for (tries = 0; tries < 30; tries++) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (cmd_reg.cmd_bits.sts == SEEPROM_READY)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx drv_usecwait(10);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx cmd_reg.cmd_val = nge_reg_get32(ngep, NGE_EP_CMD);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * This should not happen. If so, we have to restart eeprom
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * state machine
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (tries == 30) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx cmd_reg.cmd_bits.sts = SEEPROM_READY;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_EP_CMD, cmd_reg.cmd_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx drv_usecwait(10);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Polling the status bit to make assure the eeprom is ready
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx cmd_reg.cmd_val = nge_reg_get32(ngep, NGE_EP_CMD);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx for (tries = 0; tries < 30; tries++) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (cmd_reg.cmd_bits.sts == SEEPROM_READY)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx drv_usecwait(10);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx cmd_reg.cmd_val = nge_reg_get32(ngep, NGE_EP_CMD);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Assemble the command ...
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
a55f711916b9f7718fabc2d1822bf5719aa6140fMiles Xu, Sun Microsystems cmd_reg.cmd_bits.addr = (uint32_t)addr;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx cmd_reg.cmd_bits.cmd = cmd;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx cmd_reg.cmd_bits.sts = 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_EP_CMD, cmd_reg.cmd_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Polling whether the access is successful.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx *
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx cmd_reg.cmd_val = nge_reg_get32(ngep, NGE_EP_CMD);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx for (tries = 0; tries < 30; tries++) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (cmd_reg.cmd_bits.sts == SEEPROM_READY)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx drv_usecwait(10);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx cmd_reg.cmd_val = nge_reg_get32(ngep, NGE_EP_CMD);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (tries == 30) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_report(ngep, NGE_HW_ROM);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (DDI_FAILURE);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx switch (cmd) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx default:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case SEEPROM_CMD_WRITE_ENABLE:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case SEEPROM_CMD_ERASE:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case SEEPROM_CMD_ERALSE_ALL:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case SEEPROM_CMD_WRITE_DIS:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case SEEPROM_CMD_READ:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx data_reg.data_val = nge_reg_get32(ngep, NGE_EP_DATA);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx *dp = data_reg.data_bits.data;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case SEEPROM_CMD_WRITE:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx data_reg.data_val = nge_reg_get32(ngep, NGE_EP_DATA);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx data_reg.data_bits.data = *dp;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_EP_DATA, data_reg.data_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (DDI_SUCCESS);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_peek_seeprom(nge_t *ngep, nge_peekpoke_t *ppd)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint16_t data;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx int err;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx err = nge_seeprom_access(ngep, SEEPROM_CMD_READ,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ppd->pp_acc_offset, &data);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ppd->pp_acc_data = data;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (err);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_poke_seeprom(nge_t *ngep, nge_peekpoke_t *ppd)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint16_t data;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx int err;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx data = ppd->pp_acc_data;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx err = nge_seeprom_access(ngep, SEEPROM_CMD_WRITE,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ppd->pp_acc_offset, &data);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (err);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxvoid
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_init_dev_spec_param(nge_t *ngep)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_dev_spec_param_t *dev_param_p;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx chip_info_t *infop;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p = &ngep->dev_spec_param;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx infop = (chip_info_t *)&ngep->chipinfo;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx switch (infop->device) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case DEVICE_ID_NF3_E6:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case DEVICE_ID_NF3_DF:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case DEVICE_ID_MCP04_37:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case DEVICE_ID_MCP04_38:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->msi = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->msi_x = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->vlan = B_FALSE;
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj dev_param_p->advanced_pm = B_FALSE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->mac_addr_order = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_pause_frame = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_pause_frame = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->jumbo = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_rx_64byte = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_hw_checksum = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_hw_checksum = 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->desc_type = DESC_OFFLOAD;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_desc_num = NGE_RECV_SLOTS_DESC_1024;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_desc_num = NGE_SEND_SLOTS_DESC_1024;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->nge_split = NGE_SPLIT_32;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case DEVICE_ID_CK804_56:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case DEVICE_ID_CK804_57:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->msi = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->msi_x = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->vlan = B_FALSE;
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj dev_param_p->advanced_pm = B_FALSE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->mac_addr_order = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_pause_frame = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_pause_frame = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->jumbo = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_rx_64byte = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_hw_checksum = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_hw_checksum = HCKSUM_IPHDRCKSUM;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->desc_type = DESC_HOT;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_desc_num = NGE_RECV_SLOTS_DESC_3072;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_desc_num = NGE_SEND_SLOTS_DESC_3072;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->nge_split = NGE_SPLIT_96;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case DEVICE_ID_MCP51_268:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case DEVICE_ID_MCP51_269:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->msi = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->msi_x = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->vlan = B_FALSE;
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj dev_param_p->advanced_pm = B_TRUE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->mac_addr_order = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_pause_frame = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_pause_frame = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->jumbo = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_rx_64byte = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_hw_checksum = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_hw_checksum = 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->desc_type = DESC_OFFLOAD;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_desc_num = NGE_RECV_SLOTS_DESC_1024;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_desc_num = NGE_SEND_SLOTS_DESC_1024;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->nge_split = NGE_SPLIT_32;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case DEVICE_ID_MCP55_372:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case DEVICE_ID_MCP55_373:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->msi = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->msi_x = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->vlan = B_TRUE;
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj dev_param_p->advanced_pm = B_TRUE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->mac_addr_order = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_pause_frame = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_pause_frame = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->jumbo = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_rx_64byte = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_hw_checksum = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_hw_checksum = HCKSUM_IPHDRCKSUM;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->desc_type = DESC_HOT;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_desc_num = NGE_RECV_SLOTS_DESC_3072;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_desc_num = NGE_SEND_SLOTS_DESC_3072;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->nge_split = NGE_SPLIT_96;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems case DEVICE_ID_MCP61_3EE:
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems case DEVICE_ID_MCP61_3EF:
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->msi = B_FALSE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->msi_x = B_FALSE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->vlan = B_FALSE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->advanced_pm = B_TRUE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->mac_addr_order = B_TRUE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->tx_pause_frame = B_FALSE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->rx_pause_frame = B_FALSE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->jumbo = B_FALSE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->tx_rx_64byte = B_TRUE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->rx_hw_checksum = B_FALSE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->tx_hw_checksum = 0;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->desc_type = DESC_OFFLOAD;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->rx_desc_num = NGE_RECV_SLOTS_DESC_1024;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->tx_desc_num = NGE_SEND_SLOTS_DESC_1024;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->nge_split = NGE_SPLIT_32;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems break;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China case DEVICE_ID_MCP77_760:
9fa05d92f6b225eb418fb782225c991b887ea8b7Winson Wang - Sun Microsystems - Beijing China case DEVICE_ID_MCP79_AB0:
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->msi = B_FALSE;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->msi_x = B_FALSE;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->vlan = B_FALSE;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->advanced_pm = B_TRUE;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->mac_addr_order = B_TRUE;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->tx_pause_frame = B_FALSE;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->rx_pause_frame = B_FALSE;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->jumbo = B_FALSE;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->tx_rx_64byte = B_TRUE;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->rx_hw_checksum = B_FALSE;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->tx_hw_checksum = 0;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->desc_type = DESC_HOT;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->rx_desc_num = NGE_RECV_SLOTS_DESC_1024;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->tx_desc_num = NGE_SEND_SLOTS_DESC_1024;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China dev_param_p->nge_split = NGE_SPLIT_32;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China break;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China
6f3e57ac9d0b054c3169579f3422080b8ba10105mx default:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->msi = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->msi_x = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->vlan = B_FALSE;
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj dev_param_p->advanced_pm = B_FALSE;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems dev_param_p->mac_addr_order = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_pause_frame = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_pause_frame = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->jumbo = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_rx_64byte = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_hw_checksum = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_hw_checksum = 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->desc_type = DESC_OFFLOAD;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->rx_desc_num = NGE_RECV_SLOTS_DESC_1024;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->tx_desc_num = NGE_SEND_SLOTS_DESC_1024;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p->nge_split = NGE_SPLIT_32;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx/*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Perform first-stage chip (re-)initialisation, using only config-space
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * accesses:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx *
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * + Read the vendor/device/revision/subsystem/cache-line-size registers,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * returning the data in the structure pointed to by <infop>.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mxvoid nge_chip_cfg_init(nge_t *ngep, chip_info_t *infop, boolean_t reset);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#pragma no_inline(nge_chip_cfg_init)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxvoid
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_cfg_init(nge_t *ngep, chip_info_t *infop, boolean_t reset)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint16_t command;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ddi_acc_handle_t handle;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_interbus_conf interbus_conf;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_msi_mask_conf msi_mask_conf;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_msi_map_cap_conf cap_conf;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_chip_cfg_init($%p, $%p, %d)",
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (void *)ngep, (void *)infop, reset));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * save PCI cache line size and subsystem vendor ID
6f3e57ac9d0b054c3169579f3422080b8ba10105mx *
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Read all the config-space registers that characterise the
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * chip, specifically vendor/device/revision/subsystem vendor
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * and subsystem device id. We expect (but don't check) that
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx handle = ngep->cfg_handle;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* reading the vendor information once */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (reset == B_FALSE) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx infop->command = pci_config_get16(handle,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx PCI_CONF_COMM);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx infop->vendor = pci_config_get16(handle,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx PCI_CONF_VENID);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx infop->device = pci_config_get16(handle,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx PCI_CONF_DEVID);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx infop->subven = pci_config_get16(handle,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx PCI_CONF_SUBVENID);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx infop->subdev = pci_config_get16(handle,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx PCI_CONF_SUBSYSID);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx infop->class_code = pci_config_get8(handle,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx PCI_CONF_BASCLASS);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx infop->revision = pci_config_get8(handle,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx PCI_CONF_REVID);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx infop->clsize = pci_config_get8(handle,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx PCI_CONF_CACHE_LINESZ);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx infop->latency = pci_config_get8(handle,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx PCI_CONF_LATENCY_TIMER);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (nge_enable_msi) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Disable the hidden for MSI support */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx interbus_conf.conf_val = pci_config_get32(handle,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx PCI_CONF_HT_INTERNAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if ((infop->device == DEVICE_ID_MCP55_373) ||
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (infop->device == DEVICE_ID_MCP55_372))
6f3e57ac9d0b054c3169579f3422080b8ba10105mx interbus_conf.conf_bits.msix_off = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx interbus_conf.conf_bits.msi_off = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pci_config_put32(handle, PCI_CONF_HT_INTERNAL,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx interbus_conf.conf_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if ((infop->device == DEVICE_ID_MCP55_373) ||
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (infop->device == DEVICE_ID_MCP55_372)) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Disable the vector off for mcp55 */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx msi_mask_conf.msi_mask_conf_val =
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pci_config_get32(handle, PCI_CONF_HT_MSI_MASK);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx msi_mask_conf.msi_mask_bits.vec0_off = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx msi_mask_conf.msi_mask_bits.vec1_off = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx msi_mask_conf.msi_mask_bits.vec2_off = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx msi_mask_conf.msi_mask_bits.vec3_off = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx msi_mask_conf.msi_mask_bits.vec4_off = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx msi_mask_conf.msi_mask_bits.vec5_off = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx msi_mask_conf.msi_mask_bits.vec6_off = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx msi_mask_conf.msi_mask_bits.vec7_off = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pci_config_put32(handle, PCI_CONF_HT_MSI_MASK,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx msi_mask_conf.msi_mask_conf_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Enable the MSI mapping */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx cap_conf.msi_map_cap_conf_val =
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pci_config_get32(handle, PCI_CONF_HT_MSI_MAP_CAP);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx cap_conf.map_cap_conf_bits.map_en = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pci_config_put32(handle, PCI_CONF_HT_MSI_MAP_CAP,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx cap_conf.msi_map_cap_conf_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx } else {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx interbus_conf.conf_val = pci_config_get32(handle,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx PCI_CONF_HT_INTERNAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx interbus_conf.conf_bits.msi_off = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pci_config_put32(handle, PCI_CONF_HT_INTERNAL,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx interbus_conf.conf_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx command = infop->command | PCI_COMM_MAE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx command &= ~PCI_COMM_MEMWR_INVAL;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx command |= PCI_COMM_ME;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pci_config_put16(handle, PCI_CONF_COMM, command);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pci_config_put16(handle, PCI_CONF_STAT, ~0);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxint
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_stop(nge_t *ngep, boolean_t fault)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx int err;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint32_t reg_val;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint32_t tries;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_mintr_src mintr_src;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_mii_cs mii_cs;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_rx_poll rx_poll;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_tx_poll tx_poll;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_rx_en rx_en;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_tx_en tx_en;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_tx_sta tx_sta;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_rx_sta rx_sta;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_mode_cntl mode;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_pmu_cntl2 pmu_cntl2;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_chip_stop($%p, %d)", (void *)ngep, fault));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx err = DDI_SUCCESS;
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj /* Clear any pending PHY interrupt */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mintr_src.src_val = nge_reg_get8(ngep, NGE_MINTR_SRC);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put8(ngep, NGE_MINTR_SRC, mintr_src.src_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Mask all interrupts */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx reg_val = nge_reg_get32(ngep, NGE_INTR_MASK);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx reg_val &= ~NGE_INTR_ALL_EN;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_INTR_MASK, reg_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Disable auto-polling of phy */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mii_cs.cs_val = nge_reg_get32(ngep, NGE_MII_CS);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mii_cs.cs_bits.ap_en = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_MII_CS, mii_cs.cs_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Reset buffer management & DMA */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode.mode_val = nge_reg_get32(ngep, NGE_MODE_CNTL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode.mode_bits.dma_dis = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode.mode_bits.desc_type = ngep->desc_mode;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_MODE_CNTL, mode.mode_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6de4f663f1451acc7a8968bb7891bc18eaba0db5mx for (tries = 0; tries < 10000; tries++) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx drv_usecwait(10);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode.mode_val = nge_reg_get32(ngep, NGE_MODE_CNTL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (mode.mode_bits.dma_status == NGE_SET)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6de4f663f1451acc7a8968bb7891bc18eaba0db5mx if (tries == 10000) {
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China ngep->nge_chip_state = NGE_CHIP_ERROR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (DDI_FAILURE);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
d635b452b5b58e50f0c67983f4a57a04deefce77Winson Wang - Sun Microsystems - Beijing China /* Disable rx's machine */
d635b452b5b58e50f0c67983f4a57a04deefce77Winson Wang - Sun Microsystems - Beijing China rx_en.val = nge_reg_get8(ngep, NGE_RX_EN);
d635b452b5b58e50f0c67983f4a57a04deefce77Winson Wang - Sun Microsystems - Beijing China rx_en.bits.rx_en = NGE_CLEAR;
d635b452b5b58e50f0c67983f4a57a04deefce77Winson Wang - Sun Microsystems - Beijing China nge_reg_put8(ngep, NGE_RX_EN, rx_en.val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
d635b452b5b58e50f0c67983f4a57a04deefce77Winson Wang - Sun Microsystems - Beijing China /* Disable tx's machine */
d635b452b5b58e50f0c67983f4a57a04deefce77Winson Wang - Sun Microsystems - Beijing China tx_en.val = nge_reg_get8(ngep, NGE_TX_EN);
d635b452b5b58e50f0c67983f4a57a04deefce77Winson Wang - Sun Microsystems - Beijing China tx_en.bits.tx_en = NGE_CLEAR;
d635b452b5b58e50f0c67983f4a57a04deefce77Winson Wang - Sun Microsystems - Beijing China nge_reg_put8(ngep, NGE_TX_EN, tx_en.val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Clean the status of tx's state machine
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * and Make assure the tx's channel is idle
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_sta.sta_val = nge_reg_get32(ngep, NGE_TX_STA);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx for (tries = 0; tries < 1000; tries++) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (tx_sta.sta_bits.tx_chan_sta == NGE_CLEAR)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx drv_usecwait(10);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_sta.sta_val = nge_reg_get32(ngep, NGE_TX_STA);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (tries == 1000) {
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China ngep->nge_chip_state = NGE_CHIP_ERROR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (DDI_FAILURE);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_TX_STA, tx_sta.sta_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Clean the status of rx's state machine
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * and Make assure the tx's channel is idle
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_sta.sta_val = nge_reg_get32(ngep, NGE_RX_STA);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx for (tries = 0; tries < 1000; tries++) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (rx_sta.sta_bits.rx_chan_sta == NGE_CLEAR)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx drv_usecwait(10);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_sta.sta_val = nge_reg_get32(ngep, NGE_RX_STA);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (tries == 1000) {
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China ngep->nge_chip_state = NGE_CHIP_ERROR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (DDI_FAILURE);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_RX_STA, rx_sta.sta_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj /* Disable auto-poll of rx's state machine */
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj rx_poll.poll_val = nge_reg_get32(ngep, NGE_RX_POLL);
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj rx_poll.poll_bits.rpen = NGE_CLEAR;
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj rx_poll.poll_bits.rpi = NGE_CLEAR;
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj nge_reg_put32(ngep, NGE_RX_POLL, rx_poll.poll_val);
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj /* Disable auto-polling of tx's state machine */
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj tx_poll.poll_val = nge_reg_get32(ngep, NGE_TX_POLL);
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj tx_poll.poll_bits.tpen = NGE_CLEAR;
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj tx_poll.poll_bits.tpi = NGE_CLEAR;
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj nge_reg_put32(ngep, NGE_TX_POLL, tx_poll.poll_val);
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj /* Restore buffer management */
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj mode.mode_val = nge_reg_get32(ngep, NGE_MODE_CNTL);
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj mode.mode_bits.bm_reset = NGE_SET;
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj mode.mode_bits.tx_rcom_en = NGE_SET;
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj nge_reg_put32(ngep, NGE_MODE_CNTL, mode.mode_val);
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj if (ngep->dev_spec_param.advanced_pm) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_PMU_CIDLE_LIMIT, 0);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_PMU_DIDLE_LIMIT, 0);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl2.cntl2_val = nge_reg_get32(ngep, NGE_PMU_CNTL2);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl2.cntl2_bits.cidle_timer = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl2.cntl2_bits.didle_timer = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_PMU_CNTL2, pmu_cntl2.cntl2_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (fault)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->nge_chip_state = NGE_CHIP_FAULT;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx else
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->nge_chip_state = NGE_CHIP_STOPPED;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (err);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic void
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_rx_setup(nge_t *ngep)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint64_t desc_addr;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_rxtx_dlen dlen;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_rx_poll rx_poll;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Filling the address and length of rx's descriptors
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx desc_addr = ngep->recv->desc.cookie.dmac_laddress;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_RX_DADR, desc_addr);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_RX_DADR_HI, desc_addr >> 32);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dlen.dlen_val = nge_reg_get32(ngep, NGE_RXTX_DLEN);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dlen.dlen_bits.rdlen = ngep->recv->desc.nslots - 1;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_RXTX_DLEN, dlen.dlen_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_poll.poll_val = nge_reg_get32(ngep, NGE_RX_POLL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_poll.poll_bits.rpi = RX_POLL_INTV_1G;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_poll.poll_bits.rpen = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_RX_POLL, rx_poll.poll_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic void
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_tx_setup(nge_t *ngep)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint64_t desc_addr;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_rxtx_dlen dlen;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Filling the address and length of tx's descriptors
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx desc_addr = ngep->send->desc.cookie.dmac_laddress;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_TX_DADR, desc_addr);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_TX_DADR_HI, desc_addr >> 32);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dlen.dlen_val = nge_reg_get32(ngep, NGE_RXTX_DLEN);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dlen.dlen_bits.tdlen = ngep->send->desc.nslots - 1;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_RXTX_DLEN, dlen.dlen_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic int
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_buff_setup(nge_t *ngep)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_mode_cntl mode_cntl;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_dev_spec_param_t *dev_param_p;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p = &ngep->dev_spec_param;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Configure Rx&Tx's buffer
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_rx_setup(ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_tx_setup(ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Configure buffer attribute
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_val = nge_reg_get32(ngep, NGE_MODE_CNTL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Enable Dma access request
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.dma_dis = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Enbale Buffer management
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.bm_reset = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Support Standoffload Descriptor
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.desc_type = ngep->desc_mode;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Support receive hardware checksum
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (dev_param_p->rx_hw_checksum) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.rx_sum_en = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx } else
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.rx_sum_en = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Disable Tx PRD coarse update
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.tx_prd_cu_en = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Disable 64-byte access
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.w64_dis = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Skip Rx Error Frame is not supported and if
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * enable it, jumbo frame does not work any more.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.rx_filter_en = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Can not support hot mode now
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.resv15 = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (dev_param_p->vlan) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Disable the vlan strip for devices which support vlan */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.vlan_strip = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Disable the vlan insert for devices which supprot vlan */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.vlan_ins = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (dev_param_p->tx_rx_64byte) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Set the maximum TX PRD fetch size to 64 bytes */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.tx_fetch_prd = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Set the maximum RX PRD fetch size to 64 bytes */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.rx_fetch_prd = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Upload Rx data as it arrives, rather than waiting for full frame
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.resv16 = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Normal HOT table accesses
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.resv17 = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Normal HOT buffer requesting
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.resv18 = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_MODE_CNTL, mode_cntl.mode_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Signal controller to check for new Rx descriptors
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_val = nge_reg_get32(ngep, NGE_MODE_CNTL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.rxdm = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mode_cntl.mode_bits.tx_rcom_en = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_MODE_CNTL, mode_cntl.mode_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (DDI_SUCCESS);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx/*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * When chipset resets, the chipset can not restore the orignial
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * mac address to the mac address registers.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx *
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * When the driver is dettached, the function will write the orignial
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * mac address to the mac address registers.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxvoid
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_restore_mac_addr(nge_t *ngep)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint32_t mac_addr;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mac_addr = (uint32_t)ngep->chipinfo.hw_mac_addr;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_UNI_ADDR0, mac_addr);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mac_addr = (uint32_t)(ngep->chipinfo.hw_mac_addr >> 32);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_UNI_ADDR1, mac_addr);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxint
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_reset(nge_t *ngep)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx int err;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint8_t i;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint32_t regno;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems uint64_t mac = 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_uni_addr1 uaddr1;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_cp_cntl ee_cntl;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_soft_misc soft_misc;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_pmu_cntl0 pmu_cntl0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_pmu_cntl2 pmu_cntl2;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_pm_cntl2 pm_cntl2;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx const nge_ksindex_t *ksip;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_chip_reset($%p)", (void *)ngep));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Clear the statistics by reading the statistics register
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx for (ksip = nge_statistics; ksip->name != NULL; ++ksip) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx regno = KS_BASE + ksip->index * sizeof (uint32_t);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (void) nge_reg_get32(ngep, regno);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Setup seeprom control
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ee_cntl.cntl_val = nge_reg_get32(ngep, NGE_EP_CNTL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ee_cntl.cntl_bits.clkdiv = EEPROM_CLKDIV;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ee_cntl.cntl_bits.rom_size = EEPROM_32K;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ee_cntl.cntl_bits.word_wid = ACCESS_16BIT;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ee_cntl.cntl_bits.wait_slots = EEPROM_WAITCLK;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_EP_CNTL, ee_cntl.cntl_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Reading the unicast mac address table
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ngep->nge_chip_state == NGE_CHIP_INITIAL) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uaddr1.addr_val = nge_reg_get32(ngep, NGE_UNI_ADDR1);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mac = uaddr1.addr_bits.addr;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mac <<= 32;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mac |= nge_reg_get32(ngep, NGE_UNI_ADDR0);
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China ngep->chipinfo.hw_mac_addr = mac;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China if (ngep->dev_spec_param.mac_addr_order) {
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China for (i = 0; i < ETHERADDRL; i++) {
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China ngep->chipinfo.vendor_addr.addr[i] =
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China (uchar_t)mac;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China ngep->cur_uni_addr.addr[i] =
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China (uchar_t)mac;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China mac >>= 8;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China }
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China } else {
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China for (i = ETHERADDRL; i-- != 0; ) {
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China ngep->chipinfo.vendor_addr.addr[i] =
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China (uchar_t)mac;
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China ngep->cur_uni_addr.addr[i] =
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China (uchar_t)mac;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems mac >>= 8;
d27d4a13eaba374ddedac2be3de8c5318360ca01Miles Xu, Sun Microsystems }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->chipinfo.vendor_addr.set = 1;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pci_config_put8(ngep->cfg_handle, PCI_CONF_CACHE_LINESZ,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->chipinfo.clsize);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pci_config_put8(ngep->cfg_handle, PCI_CONF_LATENCY_TIMER,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->chipinfo.latency);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj if (ngep->dev_spec_param.advanced_pm) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Program software misc register */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_val = nge_reg_get32(ngep, NGE_SOFT_MISC);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.rx_clk_vx_rst = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.tx_clk_vx_rst = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.clk12m_vx_rst = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.fpci_clk_vx_rst = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.rx_clk_vc_rst = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.tx_clk_vc_rst = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.fs_clk_vc_rst = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.rst_ex_m2pintf = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_SOFT_MISC, soft_misc.misc_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj /* wait for 32 us */
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj drv_usecwait(32);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_val = nge_reg_get32(ngep, NGE_SOFT_MISC);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.rx_clk_vx_rst = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.tx_clk_vx_rst = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.clk12m_vx_rst = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.fpci_clk_vx_rst = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.rx_clk_vc_rst = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.tx_clk_vc_rst = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.fs_clk_vc_rst = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx soft_misc.misc_bits.rst_ex_m2pintf = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_SOFT_MISC, soft_misc.misc_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Program PMU registers */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl0.cntl0_val = nge_reg_get32(ngep, NGE_PMU_CNTL0);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl0.cntl0_bits.core_spd10_fp =
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_PMU_CORE_SPD10_BUSY;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl0.cntl0_bits.core_spd10_idle =
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_PMU_CORE_SPD10_IDLE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl0.cntl0_bits.core_spd100_fp =
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_PMU_CORE_SPD100_BUSY;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl0.cntl0_bits.core_spd100_idle =
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_PMU_CORE_SPD100_IDLE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl0.cntl0_bits.core_spd1000_fp =
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_PMU_CORE_SPD1000_BUSY;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl0.cntl0_bits.core_spd1000_idle =
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_PMU_CORE_SPD100_IDLE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl0.cntl0_bits.core_spd10_idle =
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_PMU_CORE_SPD10_IDLE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_PMU_CNTL0, pmu_cntl0.cntl0_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Set the core idle limit value */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_PMU_CIDLE_LIMIT,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_PMU_CIDLE_LIMIT_DEF);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Set the device idle limit value */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_PMU_DIDLE_LIMIT,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_PMU_DIDLE_LIMIT_DEF);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* Enable the core/device idle timer in PMU control 2 */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl2.cntl2_val = nge_reg_get32(ngep, NGE_PMU_CNTL2);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl2.cntl2_bits.cidle_timer = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl2.cntl2_bits.didle_timer = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl2.cntl2_bits.core_enable = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pmu_cntl2.cntl2_bits.dev_enable = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_PMU_CNTL2, pmu_cntl2.cntl2_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj /*
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj * Stop the chipset and clear buffer management
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj */
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj err = nge_chip_stop(ngep, B_FALSE);
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj if (err == DDI_FAILURE)
9ae6bcf17ff4e3ecd536b6572764993c9778d76djj return (err);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Clear the power state bits for phy since interface no longer
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * works after rebooting from Windows on a multi-boot machine
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ngep->chipinfo.device == DEVICE_ID_MCP51_268 ||
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->chipinfo.device == DEVICE_ID_MCP51_269 ||
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->chipinfo.device == DEVICE_ID_MCP55_372 ||
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->chipinfo.device == DEVICE_ID_MCP55_373 ||
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->chipinfo.device == DEVICE_ID_MCP61_3EE ||
a01a4735489b25416b449c3231ab8b710caaeb1cWinson Wang - Sun Microsystems - Beijing China ngep->chipinfo.device == DEVICE_ID_MCP61_3EF ||
9fa05d92f6b225eb418fb782225c991b887ea8b7Winson Wang - Sun Microsystems - Beijing China ngep->chipinfo.device == DEVICE_ID_MCP77_760 ||
9fa05d92f6b225eb418fb782225c991b887ea8b7Winson Wang - Sun Microsystems - Beijing China ngep->chipinfo.device == DEVICE_ID_MCP79_AB0) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pm_cntl2.cntl_val = nge_reg_get32(ngep, NGE_PM_CNTL2);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* bring phy out of coma mode */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pm_cntl2.cntl_bits.phy_coma_set = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* disable auto reset coma bits */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pm_cntl2.cntl_bits.resv4 = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* restore power to gated clocks */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx pm_cntl2.cntl_bits.resv8_11 = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_PM_CNTL2, pm_cntl2.cntl_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->nge_chip_state = NGE_CHIP_RESET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (DDI_SUCCESS);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxint
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_start(nge_t *ngep)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx int err;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_itc itc;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_tx_cntl tx_cntl;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_rx_cntrl0 rx_cntl0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_rx_cntl1 rx_cntl1;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_tx_en tx_en;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_rx_en rx_en;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_mii_cs mii_cs;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_swtr_cntl swtr_cntl;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_rx_fifo_wm rx_fifo;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_intr_mask intr_mask;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_mintr_mask mintr_mask;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_dev_spec_param_t *dev_param_p;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_chip_start($%p)", (void *)ngep));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Setup buffer management
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx err = nge_buff_setup(ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (err == DDI_FAILURE)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (err);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p = &ngep->dev_spec_param;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Enable polling attribute
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mii_cs.cs_val = nge_reg_get32(ngep, NGE_MII_CS);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mii_cs.cs_bits.ap_paddr = ngep->phy_xmii_addr;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mii_cs.cs_bits.ap_en = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mii_cs.cs_bits.ap_intv = MII_POLL_INTV;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_MII_CS, mii_cs.cs_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Setup link
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (*ngep->physops->phys_update)(ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Configure the tx's parameters
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_val = nge_reg_get32(ngep, NGE_TX_CNTL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (dev_param_p->tx_pause_frame)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.paen = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx else
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.paen = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.retry_en = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.pad_en = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.fappend_en = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.two_def_en = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.max_retry = 15;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.burst_en = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.uflo_err_mask = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.tlcol_mask = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.lcar_mask = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.def_mask = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.exdef_mask = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.lcar_mask = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.tlcol_mask = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.uflo_err_mask = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_cntl.cntl_bits.jam_seq_en = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_TX_CNTL, tx_cntl.cntl_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Configure the parameters of Rx's state machine
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Enabe the parameters:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 1). Pad Strip
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 2). FCS Relay
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 3). Pause
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 4). Address filter
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 5). Runt Packet receive
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 6). Broadcast
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 7). Receive Deferral
6f3e57ac9d0b054c3169579f3422080b8ba10105mx *
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Disable the following parameters for decreasing
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * the number of interrupts:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 1). Runt Inerrupt.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 2). Rx's Late Collision interrupt.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 3). Rx's Max length Error Interrupt.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 4). Rx's Length Field error Interrupt.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 5). Rx's FCS error interrupt.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 6). Rx's overflow error interrupt.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * 7). Rx's Frame alignment error interrupt.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_val = nge_reg_get32(ngep, NGE_RX_CNTL0);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.padsen = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.fcsren = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (dev_param_p->rx_pause_frame)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.paen = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx else
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.paen = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.lben = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.afen = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.runten = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.brdis = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.rdfen = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.runtm = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.slfb = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.rlcolm = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.maxerm = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.lferm = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.crcm = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.ofolm = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_bits.framerm = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_RX_CNTL0, rx_cntl0.cntl_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Configure the watermark for the rx's statemachine
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_fifo.wm_val = nge_reg_get32(ngep, NGE_RX_FIFO_WM);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_fifo.wm_bits.data_hwm = ngep->rx_datahwm;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_fifo.wm_bits.prd_lwm = ngep->rx_prdlwm;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_fifo.wm_bits.prd_hwm = ngep->rx_prdhwm;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_RX_FIFO_WM, rx_fifo.wm_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Configure the deffer time slot for rx's state machine
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put8(ngep, NGE_RX_DEf, ngep->rx_def);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Configure the length of rx's packet
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl1.cntl_val = nge_reg_get32(ngep, NGE_RX_CNTL1);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl1.cntl_bits.length = ngep->max_sdu;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_RX_CNTL1, rx_cntl1.cntl_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Enable Tx's state machine
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_en.val = nge_reg_get8(ngep, NGE_TX_EN);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_en.bits.tx_en = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put8(ngep, NGE_TX_EN, tx_en.val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Enable Rx's state machine
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_en.val = nge_reg_get8(ngep, NGE_RX_EN);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_en.bits.rx_en = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put8(ngep, NGE_RX_EN, rx_en.val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx itc.itc_val = nge_reg_get32(ngep, NGE_SWTR_ITC);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx itc.itc_bits.sw_intv = ngep->sw_intr_intv;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_SWTR_ITC, itc.itc_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx swtr_cntl.ctrl_val = nge_reg_get8(ngep, NGE_SWTR_CNTL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx swtr_cntl.cntl_bits.sten = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx swtr_cntl.cntl_bits.stren = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_SWTR_CNTL, swtr_cntl.ctrl_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Disable all mii read/write operation Interrupt
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mintr_mask.mask_val = nge_reg_get8(ngep, NGE_MINTR_MASK);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mintr_mask.mask_bits.mrei = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mintr_mask.mask_bits.mcc2 = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mintr_mask.mask_bits.mcc1 = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mintr_mask.mask_bits.mapi = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mintr_mask.mask_bits.mpdi = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put8(ngep, NGE_MINTR_MASK, mintr_mask.mask_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Enable all interrupt event
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_val = nge_reg_get32(ngep, NGE_INTR_MASK);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_bits.reint = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_bits.rcint = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_bits.miss = NGE_SET;
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing China intr_mask.mask_bits.teint = NGE_SET;
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing China intr_mask.mask_bits.tcint = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_bits.stint = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_bits.mint = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_bits.rfint = NGE_CLEAR;
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing China intr_mask.mask_bits.tfint = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_bits.feint = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_bits.resv10 = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_bits.resv11 = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_bits.resv12 = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_bits.resv13 = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_bits.phyint = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->intr_masks = intr_mask.mask_val;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_INTR_MASK, intr_mask.mask_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->nge_chip_state = NGE_CHIP_RUNNING;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (DDI_SUCCESS);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx/*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * nge_chip_sync() -- program the chip with the unicast MAC address,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * the multicast hash table, the required level of promiscuity.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mxvoid
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_sync(nge_t *ngep)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint8_t i;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint64_t macaddr;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint64_t mul_addr;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint64_t mul_mask;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_rx_cntrl0 rx_cntl;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_uni_addr1 uni_adr1;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_chip_sync($%p)", (void *)ngep));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx macaddr = 0x0ull;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mul_addr = 0x0ull;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mul_mask = 0x0ull;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl.cntl_val = nge_reg_get32(ngep, NGE_RX_CNTL0);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ngep->promisc) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl.cntl_bits.afen = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl.cntl_bits.brdis = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx } else {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl.cntl_bits.afen = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl.cntl_bits.brdis = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Transform the MAC address from host to chip format, the unicast
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * MAC address(es) ...
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx for (i = ETHERADDRL, macaddr = 0ull; i != 0; --i) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx macaddr |= ngep->cur_uni_addr.addr[i-1];
6f3e57ac9d0b054c3169579f3422080b8ba10105mx macaddr <<= (i > 1) ? 8 : 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_UNI_ADDR0, (uint32_t)macaddr);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx macaddr = macaddr >>32;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uni_adr1.addr_val = nge_reg_get32(ngep, NGE_UNI_ADDR1);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uni_adr1.addr_bits.addr = (uint16_t)macaddr;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uni_adr1.addr_bits.resv16_31 = (uint16_t)0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_UNI_ADDR1, uni_adr1.addr_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Reprogram the multicast address table ...
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx for (i = ETHERADDRL, mul_addr = 0ull; i != 0; --i) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mul_addr |= ngep->cur_mul_addr.addr[i-1];
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mul_addr <<= (i > 1) ? 8 : 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mul_mask |= ngep->cur_mul_mask.addr[i-1];
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mul_mask <<= (i > 1) ? 8 : 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_MUL_ADDR0, (uint32_t)mul_addr);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mul_addr >>= 32;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_MUL_ADDR1, mul_addr);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_MUL_MASK, (uint32_t)mul_mask);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mul_mask >>= 32;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_MUL_MASK1, mul_mask);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Set or clear the PROMISCUOUS mode bit
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_RX_CNTL0, rx_cntl.cntl_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * For internal PHY loopback, the link will
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * not be up, so it need to sync mac modes directly.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ngep->param_loop_mode == NGE_LOOP_INTERNAL_PHY)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_sync_mac_modes(ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic void
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_err(nge_t *ngep)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg010 reg010_ins;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_sw_statistics_t *psw_stat;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_intr_mask intr_mask;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_chip_err($%p)", (void *)ngep));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx psw_stat = (nge_sw_statistics_t *)&ngep->statistics.sw_statistics;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx reg010_ins.reg010_val = nge_reg_get32(ngep, NGE_REG010);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (reg010_ins.reg010_bits.resv0)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx psw_stat->fe_err.tso_err_mss ++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (reg010_ins.reg010_bits.resv1)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx psw_stat->fe_err.tso_dis ++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (reg010_ins.reg010_bits.resv2)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx psw_stat->fe_err.tso_err_nosum ++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (reg010_ins.reg010_bits.resv3)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx psw_stat->fe_err.tso_err_hov ++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (reg010_ins.reg010_bits.resv4)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx psw_stat->fe_err.tso_err_huf ++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (reg010_ins.reg010_bits.resv5)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx psw_stat->fe_err.tso_err_l2 ++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (reg010_ins.reg010_bits.resv6)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx psw_stat->fe_err.tso_err_ip ++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (reg010_ins.reg010_bits.resv7)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx psw_stat->fe_err.tso_err_l4 ++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (reg010_ins.reg010_bits.resv8)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx psw_stat->fe_err.tso_err_tcp ++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (reg010_ins.reg010_bits.resv9)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx psw_stat->fe_err.hsum_err_ip ++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (reg010_ins.reg010_bits.resv10)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx psw_stat->fe_err.hsum_err_l4 ++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (reg010_ins.reg010_val != 0) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Fatal error is triggered by malformed driver commands.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Disable unless debugging.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_val = nge_reg_get32(ngep, NGE_INTR_MASK);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_bits.feint = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_INTR_MASK, intr_mask.mask_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->intr_masks = intr_mask.mask_val;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic void
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_sync_mac_modes(nge_t *ngep)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_tx_def tx_def;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_tx_fifo_wm tx_fifo;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_bkoff_cntl bk_cntl;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_mac2phy m2p;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_rx_cntrl0 rx_cntl0;
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You nge_tx_cntl tx_cntl;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_dev_spec_param_t *dev_param_p;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dev_param_p = &ngep->dev_spec_param;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_val = nge_reg_get32(ngep, NGE_TX_DEF);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx m2p.m2p_val = nge_reg_get32(ngep, NGE_MAC2PHY);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_fifo.wm_val = nge_reg_get32(ngep, NGE_TX_FIFO_WM);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx bk_cntl.cntl_val = nge_reg_get32(ngep, NGE_BKOFF_CNTL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx bk_cntl.bkoff_bits.rseed = BKOFF_RSEED;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx switch (ngep->param_link_speed) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 10:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx m2p.m2p_bits.speed = low_speed;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.ifg1_def = TX_IFG1_DEFAULT;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ngep->phy_mode == RGMII_IN) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.ifg2_def = TX_IFG2_RGMII_10_100;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.if_def = TX_IFG_RGMII_OTHER;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx } else {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.if_def = TX_TIFG_MII;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.ifg2_def = TX_IFG2_MII;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_fifo.wm_bits.nbfb_wm = TX_FIFO_NOB_WM_MII;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx bk_cntl.bkoff_bits.sltm = BKOFF_SLIM_MII;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 100:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx m2p.m2p_bits.speed = fast_speed;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.ifg1_def = TX_IFG1_DEFAULT;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ngep->phy_mode == RGMII_IN) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.ifg2_def = TX_IFG2_RGMII_10_100;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.if_def = TX_IFG_RGMII_OTHER;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx } else {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.if_def = TX_TIFG_MII;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.ifg2_def = TX_IFG2_MII;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_fifo.wm_bits.nbfb_wm = TX_FIFO_NOB_WM_MII;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx bk_cntl.bkoff_bits.sltm = BKOFF_SLIM_MII;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 1000:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx m2p.m2p_bits.speed = giga_speed;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.ifg1_def = TX_IFG1_DEFAULT;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ngep->param_link_duplex == LINK_DUPLEX_FULL) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.ifg2_def = TX_IFG2_RGMII_1000;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.if_def = TX_IFG_RGMII_1000_FD;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx } else {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.ifg2_def = TX_IFG2_RGMII_1000;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_def.def_bits.if_def = TX_IFG_RGMII_OTHER;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_fifo.wm_bits.nbfb_wm = TX_FIFO_NOB_WM_GMII;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx bk_cntl.bkoff_bits.sltm = BKOFF_SLIM_GMII;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ngep->chipinfo.device == DEVICE_ID_MCP55_373 ||
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->chipinfo.device == DEVICE_ID_MCP55_372) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx m2p.m2p_bits.phyintr = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx m2p.m2p_bits.phyintrlvl = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ngep->param_link_duplex == LINK_DUPLEX_HALF) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx m2p.m2p_bits.hdup_en = NGE_SET;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx else
6f3e57ac9d0b054c3169579f3422080b8ba10105mx m2p.m2p_bits.hdup_en = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_MAC2PHY, m2p.m2p_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_TX_DEF, tx_def.def_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_fifo.wm_bits.data_lwm = TX_FIFO_DATA_LWM;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_fifo.wm_bits.prd_lwm = TX_FIFO_PRD_LWM;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_fifo.wm_bits.uprd_hwm = TX_FIFO_PRD_HWM;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx tx_fifo.wm_bits.fb_wm = TX_FIFO_TBFW;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_TX_FIFO_WM, tx_fifo.wm_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_BKOFF_CNTL, bk_cntl.cntl_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx rx_cntl0.cntl_val = nge_reg_get32(ngep, NGE_RX_CNTL0);
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You if (ngep->param_link_rx_pause && dev_param_p->rx_pause_frame) {
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You if (rx_cntl0.cntl_bits.paen == NGE_CLEAR) {
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You rx_cntl0.cntl_bits.paen = NGE_SET;
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You nge_reg_put32(ngep, NGE_RX_CNTL0, rx_cntl0.cntl_val);
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You }
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You } else {
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You if (rx_cntl0.cntl_bits.paen == NGE_SET) {
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You rx_cntl0.cntl_bits.paen = NGE_CLEAR;
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You nge_reg_put32(ngep, NGE_RX_CNTL0, rx_cntl0.cntl_val);
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You }
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You }
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You tx_cntl.cntl_val = nge_reg_get32(ngep, NGE_TX_CNTL);
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You if (ngep->param_link_tx_pause && dev_param_p->tx_pause_frame) {
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You if (tx_cntl.cntl_bits.paen == NGE_CLEAR) {
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You tx_cntl.cntl_bits.paen = NGE_SET;
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You nge_reg_put32(ngep, NGE_TX_CNTL, tx_cntl.cntl_val);
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You }
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You } else {
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You if (tx_cntl.cntl_bits.paen == NGE_SET) {
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You tx_cntl.cntl_bits.paen = NGE_CLEAR;
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You nge_reg_put32(ngep, NGE_TX_CNTL, tx_cntl.cntl_val);
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You }
86d6718f496c4610ccde9646950290901cd512beLi-Zhen You }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx/*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Handler for hardware link state change.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx *
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * When this routine is called, the hardware link state has changed
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * and the new state is reflected in the param_* variables. Here
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * we must update the softstate, reprogram the MAC to match, and
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * record the change in the log and/or on the console.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic void
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_factotum_link_handler(nge_t *ngep)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Update the s/w link_state
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ngep->param_link_up)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->link_state = LINK_STATE_UP;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx else
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->link_state = LINK_STATE_DOWN;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Reprogram the MAC modes to match
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_sync_mac_modes(ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic boolean_t
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_factotum_link_check(nge_t *ngep)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx boolean_t lchg;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx boolean_t check;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ASSERT(mutex_owned(ngep->genlock));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (*ngep->physops->phys_check)(ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx switch (ngep->link_state) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case LINK_STATE_UP:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx lchg = (ngep->param_link_up == B_FALSE);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx check = (ngep->param_link_up == B_FALSE);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case LINK_STATE_DOWN:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx lchg = (ngep->param_link_up == B_TRUE);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx check = (ngep->param_link_up == B_TRUE);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx default:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx check = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * If <check> is false, we're sure the link hasn't changed.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * If true, however, it's not yet definitive; we have to call
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * nge_phys_check() to determine whether the link has settled
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * into a new state yet ... and if it has, then call the link
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * state change handler.But when the chip is 5700 in Dell 6650
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * ,even if check is false, the link may have changed.So we
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * have to call nge_phys_check() to determine the link state.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (check)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_factotum_link_handler(ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (lchg);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx/*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Factotum routine to check for Tx stall, using the 'watchdog' counter
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic boolean_t nge_factotum_stall_check(nge_t *ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic boolean_t
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_factotum_stall_check(nge_t *ngep)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint32_t dogval;
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing China send_ring_t *srp;
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing China srp = ngep->send;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Specific check for Tx stall ...
6f3e57ac9d0b054c3169579f3422080b8ba10105mx *
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * The 'watchdog' counter is incremented whenever a packet
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * is queued, reset to 1 when some (but not all) buffers
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * are reclaimed, reset to 0 (disabled) when all buffers
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * are reclaimed, and shifted left here. If it exceeds the
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * threshold value, the chip is assumed to have stalled and
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * is put into the ERROR state. The factotum will then reset
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * it on the next pass.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx *
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * All of which should ensure that we don't get into a state
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * where packets are left pending indefinitely!
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing China if (ngep->watchdog == 0 &&
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing China srp->tx_free < srp->desc.nslots)
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing China ngep->watchdog = 1;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx dogval = nge_atomic_shl32(&ngep->watchdog, 1);
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing China if (dogval >= nge_watchdog_check)
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing China nge_tx_recycle(ngep, B_FALSE);
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing China if (dogval < nge_watchdog_count)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (B_FALSE);
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing China else {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->statistics.sw_statistics.tx_stall++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (B_TRUE);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx/*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * The factotum is woken up when there's something to do that we'd rather
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * not do from inside a hardware interrupt handler or high-level cyclic.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Its two main tasks are:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * reset & restart the chip after an error
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * check the link status whenever necessary
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx/* ARGSUSED */
6f3e57ac9d0b054c3169579f3422080b8ba10105mxuint_t
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_factotum(caddr_t args1, caddr_t args2)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint_t result;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_t *ngep;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx boolean_t err;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx boolean_t linkchg;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep = (nge_t *)args1;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_TRACE(("nge_chip_factotum($%p)", (void *)ngep));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mutex_enter(ngep->softlock);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ngep->factotum_flag == 0) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mutex_exit(ngep->softlock);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (DDI_INTR_UNCLAIMED);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->factotum_flag = 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mutex_exit(ngep->softlock);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx err = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx linkchg = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx result = DDI_INTR_CLAIMED;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mutex_enter(ngep->genlock);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx switch (ngep->nge_chip_state) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx default:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_CHIP_RUNNING:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx linkchg = nge_factotum_link_check(ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx err = nge_factotum_stall_check(ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_CHIP_FAULT:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (void) nge_restart(ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx NGE_REPORT((ngep, "automatic recovery activated"));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (err)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx (void) nge_chip_stop(ngep, B_TRUE);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mutex_exit(ngep->genlock);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * If the link state changed, tell the world about it (if
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * this version of MAC supports link state notification).
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Note: can't do this while still holding the mutex.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (linkchg)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mac_link_update(ngep->mh, ngep->link_state);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (result);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic void
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_intr_handle(nge_t *ngep, nge_intr_src *pintr_src)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx boolean_t brx;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx boolean_t btx;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_mintr_src mintr_src;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx brx = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx btx = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->statistics.sw_statistics.intr_count++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->statistics.sw_statistics.intr_lval = pintr_src->intr_val;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx brx = (pintr_src->int_bits.reint | pintr_src->int_bits.miss
6f3e57ac9d0b054c3169579f3422080b8ba10105mx | pintr_src->int_bits.rcint | pintr_src->int_bits.stint)
b2fa2f2baf176872ba0001d487bf94e14bef5485jj != 0 ? B_TRUE : B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (pintr_src->int_bits.reint)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->statistics.sw_statistics.rx_err++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (pintr_src->int_bits.miss)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->statistics.sw_statistics.rx_nobuffer++;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
51fc88a818087605a0e5f11eddb8b66576f72c23Winson Wang - Sun Microsystems - Beijing China btx = (pintr_src->int_bits.teint | pintr_src->int_bits.tfint)
b2fa2f2baf176872ba0001d487bf94e14bef5485jj != 0 ? B_TRUE : B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (btx)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_tx_recycle(ngep, B_TRUE);
b2fa2f2baf176872ba0001d487bf94e14bef5485jj if (brx)
b2fa2f2baf176872ba0001d487bf94e14bef5485jj nge_receive(ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (pintr_src->int_bits.teint)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->statistics.sw_statistics.tx_stop_err++;
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj if (ngep->intr_moderation && brx) {
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj if (ngep->poll) {
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj if (ngep->recv_count < ngep->param_rx_intr_hwater) {
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj ngep->quiet_time++;
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj if (ngep->quiet_time ==
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj ngep->param_poll_quiet_time) {
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj ngep->poll = B_FALSE;
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj ngep->quiet_time = 0;
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj }
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj } else
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj ngep->quiet_time = 0;
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj } else {
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj if (ngep->recv_count > ngep->param_rx_intr_lwater) {
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj ngep->busy_time++;
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj if (ngep->busy_time ==
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj ngep->param_poll_busy_time) {
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj ngep->poll = B_TRUE;
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj ngep->busy_time = 0;
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj }
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj } else
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj ngep->busy_time = 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj ngep->recv_count = 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (pintr_src->int_bits.feint)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_chip_err(ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* link interrupt, check the link state */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (pintr_src->int_bits.mint) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mintr_src.src_val = nge_reg_get32(ngep, NGE_MINTR_SRC);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_MINTR_SRC, mintr_src.src_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_wake_factotum(ngep);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx/*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * nge_chip_intr() -- handle chip interrupts
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx/* ARGSUSED */
6f3e57ac9d0b054c3169579f3422080b8ba10105mxuint_t
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_intr(caddr_t arg1, caddr_t arg2)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_t *ngep = (nge_t *)arg1;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_intr_src intr_src;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_intr_mask intr_mask;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mutex_enter(ngep->genlock);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
2d58516de420814c8fd871526b0aaa3cd9fb9443mx if (ngep->suspended) {
2d58516de420814c8fd871526b0aaa3cd9fb9443mx mutex_exit(ngep->genlock);
2d58516de420814c8fd871526b0aaa3cd9fb9443mx return (DDI_INTR_UNCLAIMED);
2d58516de420814c8fd871526b0aaa3cd9fb9443mx }
2d58516de420814c8fd871526b0aaa3cd9fb9443mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Check whether chip's says it's asserting #INTA;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * if not, don't process or claim the interrupt.
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_src.intr_val = nge_reg_get32(ngep, NGE_INTR_SRC);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (intr_src.intr_val == 0) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mutex_exit(ngep->genlock);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (DDI_INTR_UNCLAIMED);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Ack the interrupt
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_INTR_SRC, intr_src.intr_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ngep->nge_chip_state != NGE_CHIP_RUNNING) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mutex_exit(ngep->genlock);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (DDI_INTR_CLAIMED);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_intr_handle(ngep, &intr_src);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ngep->poll && !ngep->ch_intr_mode) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_val = nge_reg_get32(ngep, NGE_INTR_MASK);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx intr_mask.mask_bits.stint = NGE_SET;
02d51d0d625c185ad277d9ad1ddf34b06f78b9b4jj intr_mask.mask_bits.rcint = NGE_CLEAR;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_INTR_MASK, intr_mask.mask_val);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->ch_intr_mode = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx } else if ((ngep->ch_intr_mode) && (!ngep->poll)) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_reg_put32(ngep, NGE_INTR_MASK, ngep->intr_masks);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ngep->ch_intr_mode = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mutex_exit(ngep->genlock);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (DDI_INTR_CLAIMED);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic enum ioc_reply
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_pp_ioctl(nge_t *ngep, int cmd, mblk_t *mp, struct iocblk *iocp)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx int err;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint64_t sizemask;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint64_t mem_va;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx uint64_t maxoff;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx boolean_t peek;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_peekpoke_t *ppd;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx int (*ppfn)(nge_t *ngep, nge_peekpoke_t *ppd);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx switch (cmd) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx default:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_PEEK:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx peek = B_TRUE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_POKE:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx peek = B_FALSE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Validate format of ioctl
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (iocp->ioc_count != sizeof (nge_peekpoke_t))
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (mp->b_cont == NULL)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ppd = (nge_peekpoke_t *)mp->b_cont->b_rptr;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Validate request parameters
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx switch (ppd->pp_acc_space) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx default:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_PP_SPACE_CFG:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Config space
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx sizemask = 8|4|2|1;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mem_va = 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx maxoff = PCI_CONF_HDR_SIZE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ppfn = peek ? nge_chip_peek_cfg : nge_chip_poke_cfg;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_PP_SPACE_REG:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * Memory-mapped I/O space
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx sizemask = 8|4|2|1;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mem_va = 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx maxoff = NGE_REG_SIZE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ppfn = peek ? nge_chip_peek_reg : nge_chip_poke_reg;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_PP_SPACE_MII:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx sizemask = 4|2|1;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mem_va = 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx maxoff = NGE_MII_SIZE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ppfn = peek ? nge_chip_peek_mii : nge_chip_poke_mii;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_PP_SPACE_SEEPROM:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx sizemask = 4|2|1;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx mem_va = 0;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx maxoff = NGE_SEEROM_SIZE;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ppfn = peek ? nge_chip_peek_seeprom : nge_chip_poke_seeprom;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx switch (ppd->pp_acc_size) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx default:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 8:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 4:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 2:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case 1:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if ((ppd->pp_acc_size & sizemask) == 0)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx break;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if ((ppd->pp_acc_offset % ppd->pp_acc_size) != 0)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ppd->pp_acc_offset >= maxoff)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ppd->pp_acc_offset+ppd->pp_acc_size > maxoff)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /*
6f3e57ac9d0b054c3169579f3422080b8ba10105mx * All OK - go do it!
6f3e57ac9d0b054c3169579f3422080b8ba10105mx */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ppd->pp_acc_offset += mem_va;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (ppfn)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx err = (*ppfn)(ngep, ppd);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx if (err != DDI_SUCCESS)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (peek ? IOC_REPLY : IOC_ACK);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic enum ioc_reply nge_diag_ioctl(nge_t *ngep, int cmd, mblk_t *mp,
6f3e57ac9d0b054c3169579f3422080b8ba10105mx struct iocblk *iocp);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#pragma no_inline(nge_diag_ioctl)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxstatic enum ioc_reply
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_diag_ioctl(nge_t *ngep, int cmd, mblk_t *mp, struct iocblk *iocp)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ASSERT(mutex_owned(ngep->genlock));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx switch (cmd) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx default:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx nge_error(ngep, "nge_diag_ioctl: invalid cmd 0x%x", cmd);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_DIAG:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_ACK);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_PEEK:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_POKE:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (nge_pp_ioctl(ngep, cmd, mp, iocp));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_PHY_RESET:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_RESTART_ACK);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_SOFT_RESET:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_HARD_RESET:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_ACK);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx /* NOTREACHED */
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mxenum ioc_reply
6f3e57ac9d0b054c3169579f3422080b8ba10105mxnge_chip_ioctl(nge_t *ngep, mblk_t *mp, struct iocblk *iocp)
6f3e57ac9d0b054c3169579f3422080b8ba10105mx{
6f3e57ac9d0b054c3169579f3422080b8ba10105mx int cmd;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx ASSERT(mutex_owned(ngep->genlock));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx cmd = iocp->ioc_cmd;
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx switch (cmd) {
6f3e57ac9d0b054c3169579f3422080b8ba10105mx default:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_DIAG:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_PEEK:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_POKE:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_PHY_RESET:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_SOFT_RESET:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_HARD_RESET:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#if NGE_DEBUGGING
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (nge_diag_ioctl(ngep, cmd, mp, iocp));
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#else
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#endif
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_MII_READ:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_MII_WRITE:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#if NGE_SEE_IO32
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_SEE_READ:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_SEE_WRITE:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#endif
6f3e57ac9d0b054c3169579f3422080b8ba10105mx
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#if NGE_FLASH_IO32
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_FLASH_READ:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx case NGE_FLASH_WRITE:
6f3e57ac9d0b054c3169579f3422080b8ba10105mx return (IOC_INVAL);
6f3e57ac9d0b054c3169579f3422080b8ba10105mx#endif
6f3e57ac9d0b054c3169579f3422080b8ba10105mx }
6f3e57ac9d0b054c3169579f3422080b8ba10105mx}