d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * CDDL HEADER START
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 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * See the License for the specific language governing permissions
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * and limitations under the License.
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 * CDDL HEADER END
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Copyright (C) 2003-2005 Chelsio Communications. All rights reserved.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#pragma ident "%Z%%M% %I% %E% SMI"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Driver for Vitesse VSC7326 (Schaumburg) MAC */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwFILE_IDENT("@(#) $Id: vsc7326.c,v 1.17 2005/10/29 05:42:36 sbardone Exp $");
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Update fast changing statistics every 15 seconds */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* 30 minutes for full statistics update */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void vsc_read(adapter_t *adapter, u32 addr, u32 *val)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read(adapter, (REG_LOCAL_STATUS << 2) + 4, &vlo);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read(adapter, REG_LOCAL_STATUS << 2, &vhi);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (i == 50)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read(adapter, (REG_LOCAL_DATA << 2) + 4, &vlo);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* CH_ERR("rd: block: 0x%x sublock: 0x%x reg: 0x%x data: 0x%x\n",
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ((addr&0xe000)>>13), ((addr&0x1e00)>>9),
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ((addr&0x01fe)>>1), *val); */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void vsc_write(adapter_t *adapter, u32 addr, u32 data)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, (addr << 2) + 4, data & 0xFFFF);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_write(adapter, addr << 2, (data >> 16) & 0xFFFF);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* CH_ERR("wr: block: 0x%x sublock: 0x%x reg: 0x%x data: 0x%x\n",
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ((addr&0xe000)>>13), ((addr&0x1e00)>>9),
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ((addr&0x01fe)>>1), data); */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Hard reset the MAC. This wipes out *all* configuration. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw { /* Port 0 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* FIFO setup */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Port config */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw { /* Port 1 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* FIFO setup */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Port config */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw { /* Port 2 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* FIFO setup */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Port config */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw { /* Port 3 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* FIFO setup */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Port config */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void run_table(adapter_t *adapter, struct init_table *ib, int len)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (i = 0; i < len; i++) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int bist_rd(adapter_t *adapter, int moduleid, int address)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw data = ((0x00 << 24) | ((address & 0xff) << 16) | (0x00 << 8) |
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int bist_wr(adapter_t *adapter, int moduleid, int address, int value)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw CH_ERR("Suspicious write out of range value: 0x%x\n", value);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw data = ((0x01 << 24) | ((address & 0xff) << 16) | (value << 8) |
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return(0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*run bist*/
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return(0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*check bist*/
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw CH_ERR("Result: 0x%x BIST error in ram %d, column: 0x%04x\n",
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return(0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*enable mem*/
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return(0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return(0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Expect MAC address to be in network byte order. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw vsc_write(mac->adapter, REG_ING_FFILT_UM_EN, val | (port << 28));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw vsc_read(mac->adapter, REG_MAC_LOW_ADDR(port), &addr_lo);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw vsc_read(mac->adapter, REG_MAC_HIGH_ADDR(port), &addr_hi);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* This is intended to reset a port, not the whole MAC */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int mac_set_rx_mode(struct cmac *mac, struct t1_rx_mode *rm)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* max_len includes header and FCS */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw vsc_write(mac->adapter, REG_MAX_LEN(port), mtu + 14 + 4);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (speed >= 0 && speed != SPEED_10 && speed != SPEED_100 &&
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (speed >= 0) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw v &= ~0xf;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else /* SPEED_10 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw vsc_write(mac->adapter, REG_DEV_SETUP(port), v | 1); /* reset */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw v &= ~0xff00;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw v |= 0x400;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw v |= 0x2000;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else /* SPEED_10 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw v |= 0xff00;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else /* SPEED_100 or 10 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw v &= 0xfff0ffff;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw v |= 0x40000;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw v |= 0x80000;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw v |= 0x10000;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Reset the port */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Clear stats */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (i = 0; i <= 0x3a; ++i)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Clear sofware counters */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void rmon_update(struct cmac *mac, unsigned int addr, u64 *stat)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (v == 0)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Rx stats */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rmon_update(mac, REG_RX_OK_BYTES(port), &mac->stats.RxOctetsOK);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rmon_update(mac, REG_RX_BAD_BYTES(port), &mac->stats.RxOctetsBad);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rmon_update(mac, REG_RX_UNICAST(port), &mac->stats.RxUnicastFramesOK);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rmon_update(mac, REG_CRC(port), &mac->stats.RxFCSErrors);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rmon_update(mac, REG_RX_ALIGNMENT(port), &mac->stats.RxAlignErrors);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rmon_update(mac, REG_RX_PAUSE(port), &mac->stats.RxPauseFrames);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rmon_update(mac, REG_RX_JABBERS(port), &mac->stats.RxJabberErrors);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rmon_update(mac, REG_RX_FRAGMENTS(port), &mac->stats.RxRuntErrors);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rmon_update(mac, REG_RX_UNDERSIZE(port), &mac->stats.RxRuntErrors);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Tx stats (skip collision stats as we are full-duplex only) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rmon_update(mac, REG_TX_OK_BYTES(port), &mac->stats.TxOctetsOK);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rmon_update(mac, REG_TX_UNICAST(port), &mac->stats.TxUnicastFramesOK);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rmon_update(mac, REG_TX_PAUSE(port), &mac->stats.TxPauseFrames);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rmon_update(mac, REG_TX_UNDERRUN(port), &mac->stats.TxUnderrun);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * This function is called periodically to accumulate the current values of the
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * RMON counters into the port statistics. Since the counters are only 32 bits
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * some of them can overflow in less than a minute at GigE speeds, so this
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * function should be called every 30 seconds or so.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * To cut down on reading costs we update only the octet counters at each tick
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * and do a full update at major ticks, which can be every 30 minutes or more.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic const struct cmac_statistics *mac_update_statistics(struct cmac *mac,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_os_free((void *)mac, sizeof(*mac) + sizeof(cmac_instance));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic struct cmac *vsc7326_mac_create(adapter_t *adapter, int index)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mac = t1_os_malloc_wait_zero(sizeof(*mac) + sizeof(cmac_instance));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read(adapter, (REG_LOCAL_STATUS << 2) + 4, &vlo);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read(adapter, REG_LOCAL_STATUS << 2, &vhi);