d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * CDDL HEADER START
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * The contents of this file are subject to the terms of the
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Common Development and Distribution License (the "License").
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * You may not use this file except in compliance with the License.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * or http://www.opensolaris.org/os/licensing.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * See the License for the specific language governing permissions
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * and limitations under the License.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * When distributing Covered Code, include this CDDL HEADER in each
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * If applicable, add the following below this CDDL HEADER, with the
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * fields enclosed by brackets "[]" replaced with your own identifying
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * information: Portions Copyright [yyyy] [name of copyright owner]
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * CDDL HEADER END
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Copyright (C) 2003-2005 Chelsio Communications. All rights reserved.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#pragma ident "%Z%%M% %I% %E% SMI" /* pm3393.c */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "common.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "regs.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "gmac.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "elmer0.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "suni1x10gexp_regs.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* 802.3ae 10Gb/s MDIO Manageable Device(MMD)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MMD_RESERVED 0
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MMD_PMAPMD 1
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MMD_WIS 2
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MMD_PCS 3
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MMD_PHY_XGXS 4 /* XGMII Extender Sublayer */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MMD_DTE_XGXS 5
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define PHY_XGXS_CTRL_1 0
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define PHY_XGXS_STATUS_1 1
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define OFFSET(REG_ADDR) (REG_ADDR << 2)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Max frame size PM3393 can handle. Includes Ethernet header and CRC. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MAX_FRAME_SIZE 9600
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define IPG 12
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define TXXG_CONF1_VAL ((IPG << SUNI1x10GEXP_BITOFF_TXXG_IPGT) | \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SUNI1x10GEXP_BITMSK_TXXG_32BIT_ALIGN | SUNI1x10GEXP_BITMSK_TXXG_CRCEN | \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SUNI1x10GEXP_BITMSK_TXXG_PADEN)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define RXXG_CONF1_VAL (SUNI1x10GEXP_BITMSK_RXXG_PUREP | 0x14 | \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SUNI1x10GEXP_BITMSK_RXXG_FLCHK | SUNI1x10GEXP_BITMSK_RXXG_CRC_STRIP)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Update statistics every 15 minutes */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define STATS_TICK_SECS (15 * 60)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwenum { /* RMON registers */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxOctetsReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_1_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxUnicastFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_4_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxMulticastFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_5_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxBroadcastFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_6_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxPAUSEMACCtrlFramesReceived = SUNI1x10GEXP_REG_MSTAT_COUNTER_8_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxFrameCheckSequenceErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_10_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxFramesLostDueToInternalMACErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_11_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxSymbolErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_12_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxInRangeLengthErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_13_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxFramesTooLongErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_15_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxJabbers = SUNI1x10GEXP_REG_MSTAT_COUNTER_16_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxFragments = SUNI1x10GEXP_REG_MSTAT_COUNTER_17_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxUndersizedFrames = SUNI1x10GEXP_REG_MSTAT_COUNTER_18_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxJumboFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_25_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RxJumboOctetsReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_26_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw TxOctetsTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_33_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw TxFramesLostDueToInternalMACTransmissionError = SUNI1x10GEXP_REG_MSTAT_COUNTER_35_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw TxTransmitSystemError = SUNI1x10GEXP_REG_MSTAT_COUNTER_36_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw TxUnicastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_38_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw TxMulticastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_40_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw TxBroadcastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_42_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw TxPAUSEMACCtrlFramesTransmitted = SUNI1x10GEXP_REG_MSTAT_COUNTER_43_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw TxJumboFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_51_LOW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw TxJumboOctetsReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_52_LOW
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw};
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstruct _cmac_instance {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u8 enabled;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u8 fc;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u8 mac_addr[6];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw};
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pmread(struct cmac *cmac, u32 reg, u32 * data32)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read(cmac->adapter, OFFSET(reg), data32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pmwrite(struct cmac *cmac, u32 reg, u32 data32)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(cmac->adapter, OFFSET(reg), data32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Port reset. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_reset(struct cmac *cmac)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Enable interrupts for the PM3393
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 1. Enable PM3393 BLOCK interrupts.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 2. Enable PM3393 Master Interrupt bit(INTE)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 3. Enable ELMER's PM3393 bit.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 4. Enable Terminator external interrupt.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw*/
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_interrupt_enable(struct cmac *cmac)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#if 0
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 elmer;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 pl_intr;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* PM3393 - Enabling all hardware block interrupts.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_ENABLE, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_ENABLE, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_ENABLE, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_ENABLE, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Don't interrupt on statistics overflow, we are polling */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_0, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_1, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_2, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_3, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_ENABLE, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT_MASK, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_ENABLE, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_ENABLE, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_3, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_MASK, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_3, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT_MASK, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_ENABLE, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* PM3393 - Global interrupt enable
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* TBD XXX Disable for now until we figure out why error interrupts keep asserting. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_GLOBAL_INTERRUPT_ENABLE,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 0 /*SUNI1x10GEXP_BITMSK_TOP_INTE */ );
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#if 0
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* ELMER - External chip interrupts.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read(cmac->adapter, A_ELMER0_INT_ENABLE, &elmer);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw elmer |= ELMER0_GP_BIT1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(cmac->adapter, A_ELMER0_INT_ENABLE, elmer);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* TERMINATOR - PL_INTERUPTS_EXT */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pl_intr = t1_read_reg_4(cmac->adapter, A_PL_ENABLE);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pl_intr |= F_PL_INTR_EXT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(cmac->adapter, A_PL_ENABLE, pl_intr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_interrupt_disable(struct cmac *cmac)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 elmer;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* PM3393 - Enabling HW interrupt blocks. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_ENABLE, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_ENABLE, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_ENABLE, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_ENABLE, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_0, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_1, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_2, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_3, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_ENABLE, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT_MASK, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_ENABLE, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_ENABLE, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_3, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_MASK, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_3, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT_MASK, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_ENABLE, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* PM3393 - Global interrupt enable */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_GLOBAL_INTERRUPT_ENABLE, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* ELMER - External chip interrupts. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read(cmac->adapter, A_ELMER0_INT_ENABLE, &elmer);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw elmer &= ~ELMER0_GP_BIT1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(cmac->adapter, A_ELMER0_INT_ENABLE, elmer);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* TERMINATOR - PL_INTERUPTS_EXT */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* DO NOT DISABLE TERMINATOR's EXTERNAL INTERRUPTS. ANOTHER CHIP
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * COULD WANT THEM ENABLED. We disable PM3393 at the ELMER level.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_interrupt_clear(struct cmac *cmac)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 elmer;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 pl_intr;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 val32;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* PM3393 - Clearing HW interrupt blocks. Note, this assumes
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * bit WCIMODE=0 for a clear-on-read.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_STATUS, &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_STATUS, &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_STATUS, &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_STATUS, &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT, &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_STATUS, &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_INTERRUPT, &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_STATUS, &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_RXXG_INTERRUPT, &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_TXXG_INTERRUPT, &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT, &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_INDICATION,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_STATUS, &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_CHANGE, &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* PM3393 - Global interrupt status
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS, &val32);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* ELMER - External chip interrupts.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read(cmac->adapter, A_ELMER0_INT_CAUSE, &elmer);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw elmer |= ELMER0_GP_BIT1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(cmac->adapter, A_ELMER0_INT_CAUSE, elmer);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* TERMINATOR - PL_INTERUPTS_EXT
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pl_intr = t1_read_reg_4(cmac->adapter, A_PL_CAUSE);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pl_intr |= F_PL_INTR_EXT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(cmac->adapter, A_PL_CAUSE, pl_intr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Interrupt handler */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_interrupt_handler(struct cmac *cmac)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 master_intr_status;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 1. Read master interrupt register.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 2. Read BLOCK's interrupt status registers.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 3. Handle BLOCK interrupts.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw*/
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Read the master interrupt status register. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw &master_intr_status);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw CH_DBG(cmac->adapter, INTR, "PM3393 intr cause 0x%x\n",
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw master_intr_status);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Handle BLOCK's interrupts. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_PL4IO_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_IRAM_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_ERAM_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* SERDES */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_XAUI_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* MSTAT */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_MSTAT_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* RXXG */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_RXXG_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* TXXG */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_TXXG_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* XRF */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_XRF_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* XTEF */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_XTEF_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* MDIO */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_MDIO_BUSY_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Not used. 8000 uses MDIO through Elmer. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* RXOAM */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_RXOAM_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* TXOAM */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_TXOAM_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* IFLX */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_IFLX_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EFLX */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_EFLX_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* PL4ODP */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_PL4ODP_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* PL4IDU */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (SUNI1x10GEXP_BITMSK_TOP_PL4IDU_INT & master_intr_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* EMPTY */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* TBD XXX Lets just clear everything for now */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pm3393_interrupt_clear(cmac);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_enable(struct cmac *cmac, int which)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (which & MAC_DIRECTION_RX)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_1,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (RXXG_CONF1_VAL | SUNI1x10GEXP_BITMSK_RXXG_RXEN));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (which & MAC_DIRECTION_TX) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 val = TXXG_CONF1_VAL | SUNI1x10GEXP_BITMSK_TXXG_TXEN0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cmac->instance->fc & PAUSE_RX)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw val |= SUNI1x10GEXP_BITMSK_TXXG_FCRX;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cmac->instance->fc & PAUSE_TX)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw val |= SUNI1x10GEXP_BITMSK_TXXG_FCTX;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_1, val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmac->instance->enabled |= which;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_enable_port(struct cmac *cmac, int which)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Clear port statistics */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_CONTROL,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SUNI1x10GEXP_BITMSK_MSTAT_CLEAR);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DELAY_US(2);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) memset(&cmac->stats, 0, sizeof(struct cmac_statistics));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pm3393_enable(cmac, which);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * XXX This should be done by the PHY and preferrably not at all.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * The PHY doesn't give us link status indication on its own so have
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * the link management code query it instead.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw extern void link_changed(adapter_t *adapter, int port_id);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw link_changed(cmac->adapter, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_disable(struct cmac *cmac, int which)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (which & MAC_DIRECTION_RX)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_1, RXXG_CONF1_VAL);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (which & MAC_DIRECTION_TX)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_1, TXXG_CONF1_VAL);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * The disable is graceful. Give the PM3393 time. Can't wait very
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * long here, we may be holding locks.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DELAY_US(20);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmac->instance->enabled &= ~which;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_loopback_enable(struct cmac *cmac)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_loopback_disable(struct cmac *cmac)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_set_mtu(struct cmac *cmac, int mtu)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int enabled = cmac->instance->enabled;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* MAX_FRAME_SIZE includes header + FCS, mtu doesn't */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mtu += 14 + 4;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mtu > MAX_FRAME_SIZE)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -EINVAL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Disable Rx/Tx MAC before configuring it. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (enabled)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pm3393_disable(cmac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MAX_FRAME_LENGTH, mtu);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_MAX_FRAME_SIZE, mtu);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (enabled)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pm3393_enable(cmac, enabled);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic u32 calc_crc(u8 *b, int len)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int i;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 crc = (u32)~0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* calculate crc one bit at a time */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw while (len--) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw crc ^= *b++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (i = 0; i < 8; i++) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (crc & 0x1)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw crc = (crc >> 1) ^ 0xedb88320;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw crc = (crc >> 1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* reverse bits */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw crc = ((crc >> 4) & 0x0f0f0f0f) | ((crc << 4) & 0xf0f0f0f0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw crc = ((crc >> 2) & 0x33333333) | ((crc << 2) & 0xcccccccc);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw crc = ((crc >> 1) & 0x55555555) | ((crc << 1) & 0xaaaaaaaa);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* swap bytes */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw crc = (crc >> 16) | (crc << 16);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return crc;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_set_rx_mode(struct cmac *cmac, struct t1_rx_mode *rm)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int enabled = cmac->instance->enabled & MAC_DIRECTION_RX;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 rx_mode;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Disable MAC RX before reconfiguring it */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (enabled)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pm3393_disable(cmac, MAC_DIRECTION_RX);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2, &rx_mode);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rx_mode &= ~(SUNI1x10GEXP_BITMSK_RXXG_PMODE | SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2, (u16)rx_mode);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (t1_rx_mode_promisc(rm)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Promiscuous mode. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_PMODE;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (t1_rx_mode_allmulti(rm)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Accept all multicast. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_LOW, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDLOW, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDHIGH, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_HIGH, 0xffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } else if (t1_rx_mode_mc_cnt(rm)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Accept one or more multicast(s). */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u8 *addr;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int bit;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u16 mc_filter[4] = { 0, };
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw while ((addr = t1_get_next_mcaddr(rm))) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bit = (calc_crc(addr, ETH_ALEN) >> 23) & 0x3f; /* bit[23:28] */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc_filter[bit >> 4] |= 1 << (bit & 0xf);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_LOW, mc_filter[0]);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDLOW, mc_filter[1]);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDHIGH, mc_filter[2]);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_HIGH, mc_filter[3]);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2, (u16)rx_mode);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (enabled)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pm3393_enable(cmac, MAC_DIRECTION_RX);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_get_speed_duplex_fc(struct cmac *cmac, int *speed,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int *duplex, int *fc)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (speed)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *speed = SPEED_10000;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (duplex)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *duplex = DUPLEX_FULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (fc)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *fc = cmac->instance->fc;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_set_speed_duplex_fc(struct cmac *cmac, int speed, int duplex,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int fc)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (speed >= 0 && speed != SPEED_10000)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (duplex >= 0 && duplex != DUPLEX_FULL)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (fc & ~(PAUSE_TX | PAUSE_RX))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (fc != cmac->instance->fc) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmac->instance->fc = (u8) fc;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cmac->instance->enabled & MAC_DIRECTION_TX)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pm3393_enable(cmac, MAC_DIRECTION_TX);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define RMON_UPDATE(mac, name, stat_name) \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw { \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read((mac)->adapter, OFFSET(name), &val0); \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read((mac)->adapter, OFFSET(((name)+1)), &val1); \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read((mac)->adapter, OFFSET(((name)+2)), &val2); \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (mac)->stats.stat_name = (u16)val0 | (((u16)val1) << 16) \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw | ((u64)((u8)val2) << 32) \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw | ((mac)->stats.stat_name & (~(u64)0 << 40)); \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (ro & ((name - SUNI1x10GEXP_REG_MSTAT_COUNTER_0_LOW) >> 2)) \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (mac)->stats.stat_name += ((u64)1 << 40); \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic const struct cmac_statistics *pm3393_update_statistics(struct cmac *mac,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int flag)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u64 ro;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 val0, val1, val2, val3;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Snap the counters */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(mac, SUNI1x10GEXP_REG_MSTAT_CONTROL,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SUNI1x10GEXP_BITMSK_MSTAT_SNAP);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Counter rollover, clear on read */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_0, &val0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_1, &val1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_2, &val2);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_3, &val3);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ro = (u16)val0 | (((u16)val1) << 16) | ((u64)((u16)val2) << 32)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw | ((u64)((u16)val3) << 48);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Rx stats */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, RxOctetsReceivedOK, RxOctetsOK);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, RxUnicastFramesReceivedOK, RxUnicastFramesOK);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, RxMulticastFramesReceivedOK, RxMulticastFramesOK);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, RxBroadcastFramesReceivedOK, RxBroadcastFramesOK);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, RxPAUSEMACCtrlFramesReceived, RxPauseFrames);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, RxFrameCheckSequenceErrors, RxFCSErrors);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, RxFramesLostDueToInternalMACErrors, RxInternalMACRcvError);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, RxSymbolErrors, RxSymbolErrors);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, RxInRangeLengthErrors, RxInRangeLengthErrors);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, RxFramesTooLongErrors , RxFrameTooLongErrors);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, RxJabbers, RxJabberErrors);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, RxFragments, RxRuntErrors);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, RxUndersizedFrames, RxRuntErrors);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Tx stats */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, TxOctetsTransmittedOK, TxOctetsOK);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, TxFramesLostDueToInternalMACTransmissionError, TxInternalMACXmitError);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, TxTransmitSystemError, TxFCSErrors);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, TxUnicastFramesTransmittedOK, TxUnicastFramesOK);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, TxMulticastFramesTransmittedOK, TxMulticastFramesOK);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, TxBroadcastFramesTransmittedOK, TxBroadcastFramesOK);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw RMON_UPDATE(mac, TxPAUSEMACCtrlFramesTransmitted, TxPauseFrames);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return &mac->stats;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_macaddress_get(struct cmac *cmac, u8 mac_addr[6])
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw memcpy(mac_addr, cmac->instance->mac_addr, 6);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_macaddress_set(struct cmac *cmac, u8 ma[6])
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 val, lo, mid, hi, enabled = cmac->instance->enabled;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * MAC addr: 00:07:43:00:13:09
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * ma[5] = 0x09
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * ma[4] = 0x13
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * ma[3] = 0x00
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * ma[2] = 0x43
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * ma[1] = 0x07
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * ma[0] = 0x00
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * The PM3393 requires byte swapping and reverse order entry
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * when programming MAC addresses:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * low_bits[15:0] = ma[1]:ma[0]
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * mid_bits[31:16] = ma[3]:ma[2]
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * high_bits[47:32] = ma[5]:ma[4]
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Store local copy */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw memcpy(cmac->instance->mac_addr, ma, 6);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw lo = ((u32) ma[1] << 8) | (u32) ma[0];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mid = ((u32) ma[3] << 8) | (u32) ma[2];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw hi = ((u32) ma[5] << 8) | (u32) ma[4];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Disable Rx/Tx MAC before configuring it. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (enabled)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pm3393_disable(cmac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Set RXXG Station Address */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_SA_15_0, lo);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_SA_31_16, mid);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_SA_47_32, hi);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Set TXXG Station Address */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_SA_15_0, lo);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_SA_31_16, mid);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_SA_47_32, hi);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Setup Exact Match Filter 1 with our MAC address
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Must disable exact match filter before configuring it.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmread(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_0, &val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw val &= 0xff0f;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_0, val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_LOW, lo);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_MID, mid);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_HIGH, hi);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw val |= 0x0090;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_0, val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (enabled)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pm3393_enable(cmac, enabled);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void pm3393_destroy(struct cmac *cmac)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_os_free((void *)cmac, sizeof(*cmac) + sizeof(cmac_instance));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef C99_NOT_SUPPORTED
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic struct cmac_ops pm3393_ops = {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_destroy,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_reset,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_interrupt_enable,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_interrupt_disable,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_interrupt_clear,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_interrupt_handler,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_enable,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_disable,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_loopback_enable,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_loopback_disable,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_set_mtu,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_set_rx_mode,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_set_speed_duplex_fc,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_get_speed_duplex_fc,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_update_statistics,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_macaddress_get,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_macaddress_set
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw};
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic struct cmac_ops pm3393_ops = {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .destroy = pm3393_destroy,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .reset = pm3393_reset,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .interrupt_enable = pm3393_interrupt_enable,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .interrupt_disable = pm3393_interrupt_disable,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .interrupt_clear = pm3393_interrupt_clear,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .interrupt_handler = pm3393_interrupt_handler,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .enable = pm3393_enable_port,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .disable = pm3393_disable,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .loopback_enable = pm3393_loopback_enable,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .loopback_disable = pm3393_loopback_disable,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .set_mtu = pm3393_set_mtu,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .set_rx_mode = pm3393_set_rx_mode,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .get_speed_duplex_fc = pm3393_get_speed_duplex_fc,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .set_speed_duplex_fc = pm3393_set_speed_duplex_fc,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .statistics_update = pm3393_update_statistics,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .macaddress_get = pm3393_macaddress_get,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw .macaddress_set = pm3393_macaddress_set
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw};
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic struct cmac *pm3393_mac_create(adapter_t *adapter, int index)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct cmac *cmac;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmac = t1_os_malloc_wait_zero(sizeof(*cmac) + sizeof(cmac_instance));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (!cmac)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmac->ops = &pm3393_ops;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmac->instance = (cmac_instance *) (cmac + 1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmac->adapter = adapter;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmac->instance->fc = PAUSE_TX | PAUSE_RX;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x0001), 0x00008000);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x0001), 0x00000000);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2308), 0x00009800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2305), 0x00001001); /* PL4IO Enable */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2320), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2321), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2322), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2323), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2324), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2325), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2326), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2327), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2328), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2329), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x232a), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x232b), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x232c), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x232d), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x232e), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x232f), 0x00008800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x230d), 0x00009c00);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2304), 0x00000202); /* PL4IO Calendar Repetitions */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x3200), 0x00008080); /* EFLX Enable */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x3210), 0x00000000); /* EFLX Channel Deprovision */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x3203), 0x00000000); /* EFLX Low Limit */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x3204), 0x00000040); /* EFLX High Limit */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x3205), 0x000002cc); /* EFLX Almost Full */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x3206), 0x00000199); /* EFLX Almost Empty */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x3207), 0x00000240); /* EFLX Cut Through Threshold */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x3202), 0x00000000); /* EFLX Indirect Register Update */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x3210), 0x00000001); /* EFLX Channel Provision */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x3208), 0x0000ffff); /* EFLX Undocumented */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x320a), 0x0000ffff); /* EFLX Undocumented */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x320c), 0x0000ffff); /* EFLX enable overflow interrupt The other bit are undocumented */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x320e), 0x0000ffff); /* EFLX Undocumented */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2200), 0x0000c000); /* IFLX Configuration - enable */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2201), 0x00000000); /* IFLX Channel Deprovision */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x220e), 0x00000000); /* IFLX Low Limit */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x220f), 0x00000100); /* IFLX High Limit */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2210), 0x00000c00); /* IFLX Almost Full Limit */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2211), 0x00000599); /* IFLX Almost Empty Limit */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x220d), 0x00000000); /* IFLX Indirect Register Update */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2201), 0x00000001); /* IFLX Channel Provision */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2203), 0x0000ffff); /* IFLX Undocumented */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2205), 0x0000ffff); /* IFLX Undocumented */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2209), 0x0000ffff); /* IFLX Enable overflow interrupt. The other bit are undocumented */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2241), 0xfffffffe); /* PL4MOS Undocumented */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2242), 0x0000ffff); /* PL4MOS Undocumented */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2243), 0x00000008); /* PL4MOS Starving Burst Size */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2244), 0x00000008); /* PL4MOS Hungry Burst Size */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2245), 0x00000008); /* PL4MOS Transfer Size */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2240), 0x00000005); /* PL4MOS Disable */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2280), 0x00002103); /* PL4ODP Training Repeat and SOP rule */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2284), 0x00000000); /* PL4ODP MAX_T setting */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x3280), 0x00000087); /* PL4IDU Enable data forward, port state machine. Set ALLOW_NON_ZERO_OLB */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x3282), 0x0000001f); /* PL4IDU Enable Dip4 check error interrupts */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x3040), 0x0c32); /* # TXXG Config */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* For T1 use timer based Mac flow control. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x304d), 0x8000);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2040), 0x059c); /* # RXXG Config */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2049), 0x0001); /* # RXXG Cut Through */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x2070), 0x0000); /* # Disable promiscuous mode */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Setup Exact Match Filter 0 to allow broadcast packets.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x206e), 0x0000); /* # Disable Match Enable bit */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x204a), 0xffff); /* # low addr */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x204b), 0xffff); /* # mid addr */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x204c), 0xffff); /* # high addr */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x206e), 0x0009); /* # Enable Match Enable bit */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x0003), 0x0000); /* # NO SOP/ PAD_EN setup */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x0100), 0x0ff0); /* # RXEQB disabled */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, OFFSET(0x0101), 0x0f0f); /* # No Preemphasis */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return cmac;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pm3393_mac_reset(adapter_t * adapter)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 val;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 x;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 is_pl4_reset_finished;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 is_pl4_outof_lock;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 is_xaui_mabc_pll_locked;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 successful_reset;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int i;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* The following steps are required to properly reset
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * the PM3393. This information is provided in the
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * PM3393 datasheet (Issue 2: November 2002)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * section 13.1 -- Device Reset.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * The PM3393 has three types of components that are
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * individually reset:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * DRESETB - Digital circuitry
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * PL4_ARESETB - PL4 analog circuitry
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * XAUI_ARESETB - XAUI bus analog circuitry
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Steps to reset PM3393 using RSTB pin:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * 1. Assert RSTB pin low ( write 0 )
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * 2. Wait at least 1ms to initiate a complete initialization of device.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * 3. Wait until all external clocks and REFSEL are stable.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * 4. Wait minimum of 1ms. (after external clocks and REFEL are stable)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * 5. De-assert RSTB ( write 1 )
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * 6. Wait until internal timers to expires after ~14ms.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * - Allows analog clock synthesizer(PL4CSU) to stabilize to
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * selected reference frequency before allowing the digital
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * portion of the device to operate.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * 7. Wait at least 200us for XAUI interface to stabilize.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * 8. Verify the PM3393 came out of reset successfully.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Set successful reset flag if everything worked else try again
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * a few more times.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw successful_reset = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (i = 0; i < 3 && !successful_reset; i++) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* 1 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read(adapter, A_ELMER0_GPO, &val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw val &= ~1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, A_ELMER0_GPO, val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* 2 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DELAY_MS(1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* 3 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DELAY_MS(1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* 4 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DELAY_MS(2 /*1 extra ms for safety */ );
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* 5 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw val |= 1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, A_ELMER0_GPO, val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* 6 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DELAY_MS(15 /*1 extra ms for safety */ );
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* 7 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DELAY_MS(1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* 8 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Has PL4 analog block come out of reset correctly? */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read(adapter, OFFSET(SUNI1x10GEXP_REG_DEVICE_STATUS), &val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw is_pl4_reset_finished = (val & SUNI1x10GEXP_BITMSK_TOP_EXPIRED);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* TBD XXX SUNI1x10GEXP_BITMSK_TOP_PL4_IS_DOOL gets locked later in the init sequence
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * figure out why? */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Have all PL4 block clocks locked? */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw x = (SUNI1x10GEXP_BITMSK_TOP_PL4_ID_DOOL
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*| SUNI1x10GEXP_BITMSK_TOP_PL4_IS_DOOL */ |
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SUNI1x10GEXP_BITMSK_TOP_PL4_ID_ROOL |
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SUNI1x10GEXP_BITMSK_TOP_PL4_IS_ROOL |
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SUNI1x10GEXP_BITMSK_TOP_PL4_OUT_ROOL);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw is_pl4_outof_lock = (val & x);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* ??? If this fails, might be able to software reset the XAUI part
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * and try to recover... thus saving us from doing another HW reset */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Has the XAUI MABC PLL circuitry stablized? */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw is_xaui_mabc_pll_locked =
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (val & SUNI1x10GEXP_BITMSK_TOP_SXRA_EXPIRED);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw successful_reset = (is_pl4_reset_finished && !is_pl4_outof_lock
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw && is_xaui_mabc_pll_locked);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw CH_DBG(adapter, HW,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw "PM3393 HW reset %d: pl4_reset 0x%x, val 0x%x, "
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw "is_pl4_outof_lock 0x%x, xaui_locked 0x%x\n",
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw i, is_pl4_reset_finished, val, is_pl4_outof_lock,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw is_xaui_mabc_pll_locked);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return successful_reset ? 0 : 1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstruct gmac t1_pm3393_ops = {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw STATS_TICK_SECS,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_mac_create,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pm3393_mac_reset
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw};