/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (C) 2003-2005 Chelsio Communications. All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/* Driver for Vitesse VSC7326 (Schaumburg) MAC */
#include "gmac.h"
#include "elmer0.h"
#include "vsc7326_reg.h"
FILE_IDENT("@(#) $Id: vsc7326.c,v 1.17 2005/10/29 05:42:36 sbardone Exp $");
/* Update fast changing statistics every 15 seconds */
/* 30 minutes for full statistics update */
struct init_table {
};
struct _cmac_instance {
};
{
int i;
i = 0;
do {
i++;
if (i == 50)
CH_ERR("Invalid tpi read from MAC, breaking loop.\n");
/* CH_ERR("rd: block: 0x%x sublock: 0x%x reg: 0x%x data: 0x%x\n",
((addr&0xe000)>>13), ((addr&0x1e00)>>9),
((addr&0x01fe)>>1), *val); */
}
{
/* CH_ERR("wr: block: 0x%x sublock: 0x%x reg: 0x%x data: 0x%x\n",
((addr&0xe000)>>13), ((addr&0x1e00)>>9),
((addr&0x01fe)>>1), data); */
}
/* Hard reset the MAC. This wipes out *all* configuration. */
{
val &= ~1;
DELAY_US(2);
DELAY_MS(1);
do {
DELAY_MS(1);
} while (result != 0x0);
}
{ REG_IFACE_MODE, 0x00000000 },
{ REG_CRC_CFG, 0x00000020 },
{ REG_PLL_CLK_SPEED, 0x00050c00 },
{ REG_PLL_CLK_SPEED, 0x00050c00 },
{ REG_MSCH, 0x00002f14 },
{ REG_SPI4_MISC, 0x00040409 },
{ REG_SPI4_DESKEW, 0x00080000 },
{ REG_SPI4_ING_SETUP2, 0x08080004 },
{ REG_SPI4_ING_SETUP0, 0x04111004 },
{ REG_SPI4_EGR_SETUP0, 0x80001a04 },
{ REG_SPI4_ING_SETUP1, 0x02010000 },
{ REG_AGE_INC(0), 0x00000000 },
{ REG_ING_CONTROL, 0x0a200011 },
{ REG_EGR_CONTROL, 0xa0010091 },
};
{ /* Port 0 */
/* FIFO setup */
{ REG_DBG(0), 0x000004f0 },
{ REG_HDX(0), 0x00073101 },
{ REG_TEST(0,0), 0x00000022 },
{ REG_TOP_BOTTOM(0,0), 0x003f0000 },
{ REG_HIGH_LOW_WM(0,0), 0x07460757 },
{ REG_CT_THRHLD(0,0), 0x00000000 },
{ REG_BUCKE(0), 0x0002ffff },
{ REG_BUCKI(0), 0x0002ffff },
{ REG_TEST(0,0), 0x00000020 },
/* Port config */
{ REG_MAX_LEN(0), 0x00002710 },
{ REG_PORT_FAIL(0), 0x00000002 },
{ REG_NORMALIZER(0), 0x00000a64 },
{ REG_DENORM(0), 0x00000010 },
{ REG_STICK_BIT(0), 0x03baa370 },
{ REG_DEV_SETUP(0), 0x00000083 },
{ REG_DEV_SETUP(0), 0x00000082 },
{ REG_MODE_CFG(0), 0x0200259f },
},
{ /* Port 1 */
/* FIFO setup */
/* Port config */
},
{ /* Port 2 */
/* FIFO setup */
/* Port config */
},
{ /* Port 3 */
/* FIFO setup */
/* Port config */
},
};
{
int i;
for (i = 0; i < len; i++) {
} else {
}
}
}
{
int data=0;
if( (address != 0x0) &&
(address != 0x1) &&
(address != 0x2) &&
(address != 0xd) &&
(address != 0xe))
((moduleid & 0xff) << 0));
DELAY_US(10);
return(result & 0xff);
}
{
int data=0;
if( (address != 0x0) &&
(address != 0x1) &&
(address != 0x2) &&
(address != 0xd) &&
(address != 0xe))
if( value>255 )
((moduleid & 0xff) << 0));
DELAY_US(5);
return(0);
}
{
/*run bist*/
return(0);
}
{
int result=0;
int column=0;
/*check bist*/
CH_ERR("Result: 0x%x BIST error in ram %d, column: 0x%04x\n",
return(0);
}
{
/*enable mem*/
return(0);
}
{
int port=0;
}
DELAY_US(300);
DELAY_US(300);
DELAY_MS(200);
DELAY_US(100);
DELAY_US(300);
DELAY_US(300);
}
DELAY_US(300);
DELAY_MS(10);
return(0);
}
/* ARGSUSED */
{
return 0;
}
/* ARGSUSED */
{
return 0;
}
/* ARGSUSED */
{
return 0;
}
/* ARGSUSED */
{
return 0;
}
/* Expect MAC address to be in network byte order. */
{
val &= ~0xf0000000;
return 0;
}
{
return 0;
}
/* This is intended to reset a port, not the whole MAC */
{
return 0;
}
{
u32 v;
v |= 1 << 12;
if (t1_rx_mode_promisc(rm))
else
return 0;
}
{
return -EINVAL;
/* max_len includes header and FCS */
return 0;
}
int fc)
{
u32 v;
speed != SPEED_1000)
return -1;
return -1;
if (speed >= 0) {
v &= ~0xf;
v |= 4; /* full duplex */
if (speed == SPEED_1000)
v |= 8; /* GigE */
enable |= v;
if (speed == SPEED_1000)
v = 0x82;
v = 0x84;
else /* SPEED_10 */
v = 0x86;
v &= ~0xff00;
if (speed == SPEED_1000)
v |= 0x400;
v |= 0x2000;
else /* SPEED_10 */
v |= 0xff00;
if (duplex == DUPLEX_HALF)
else if (speed == SPEED_1000)
enable = 0xc;
else /* SPEED_100 or 10 */
enable = 0x4;
}
v &= 0xfff0ffff;
v |= 0x40000;
v |= 0x80000;
v |= 0x10000;
return 0;
}
{
if (which & MAC_DIRECTION_RX)
val |= 0x2;
if (which & MAC_DIRECTION_TX)
val |= 1;
return 0;
}
{
/* Reset the port */
if (which & MAC_DIRECTION_RX)
val &= ~0x2;
if (which & MAC_DIRECTION_TX)
val &= ~0x1;
/* Clear stats */
for (i = 0; i <= 0x3a; ++i)
/* Clear sofware counters */
return 0;
}
{
if (v == 0)
return;
if (v < lo)
}
{
/* Rx stats */
/* Tx stats (skip collision stats as we are full-duplex only) */
}
/*
* This function is called periodically to accumulate the current values of the
* RMON counters into the port statistics. Since the counters are only 32 bits
* some of them can overflow in less than a minute at GigE speeds, so this
* function should be called every 30 seconds or so.
*
* To cut down on reading costs we update only the octet counters at each tick
* and do a full update at major ticks, which can be every 30 minutes or more.
*/
int flag)
{
if (flag == MAC_STATS_UPDATE_FULL ||
} else {
}
}
{
}
#ifdef C99_NOT_SUPPORTED
NULL,
NULL,
NULL,
};
#else
.destroy = mac_destroy,
.enable = mac_enable,
.disable = mac_disable,
.set_mtu = mac_set_mtu,
};
#endif
{
int i;
i = 0;
do {
DELAY_US(1);
DELAY_US(5);
return mac;
}
{
(void) run_bist_all(adapter);
return 0;
}
};