176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**************************************************************************
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Etherboot driver for Level 5 Etherfabric network cards
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Written by Michael Brown <mbrown@fensystems.co.uk>
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright Fen Systems Ltd. 2005
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright Level 5 Networks Inc. 2005
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This software may be used and distributed according to the terms of
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * the GNU General Public License (GPL), incorporated herein by
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * reference.  Drivers based on or derived from this code fall under
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * the GPL and must retain the authorship, copyright and license
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * notice.
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman **************************************************************************
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1976d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( GPL_ANY );
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdint.h>
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdlib.h>
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <unistd.h>
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <errno.h>
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <assert.h>
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <byteswap.h>
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <console.h>
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/io.h>
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/pci.h>
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/malloc.h>
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/ethernet.h>
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/iobuf.h>
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/netdevice.h>
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/timer.h>
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <mii.h>
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "etherfabric.h"
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "etherfabric_nic.h"
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**************************************************************************
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Constants and macros
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman **************************************************************************
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EFAB_REGDUMP(...)
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EFAB_TRACE(...) DBGP(__VA_ARGS__)
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman// printf() is not allowed within drivers.  Use DBG() instead.
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EFAB_LOG(...) DBG(__VA_ARGS__)
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EFAB_ERR(...) DBG(__VA_ARGS__)
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FALCON_USE_IO_BAR 0
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define HZ 100
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EFAB_BYTE 1
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**************************************************************************
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Hardware data structures and sizing
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman **************************************************************************
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int __invalid_queue_size;
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FQS(_prefix, _x)					\
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	( ( (_x) == 512 ) ? _prefix ## _SIZE_512 :		\
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	  ( ( (_x) == 1024 ) ? _prefix ## _SIZE_1K :		\
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ( ( (_x) == 2048 ) ? _prefix ## _SIZE_2K :		\
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	      ( ( (_x) == 4096) ? _prefix ## _SIZE_4K :		\
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		__invalid_queue_size ) ) ) )
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EFAB_MAX_FRAME_LEN(mtu)				\
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	( ( ( ( mtu ) + 4/* FCS */ ) + 7 ) & ~7 )
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**************************************************************************
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * GMII routines
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman **************************************************************************
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void falcon_mdio_write (struct efab_nic *efab, int device,
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			       int location, int value );
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int falcon_mdio_read ( struct efab_nic *efab, int device, int location );
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMII registers */
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMII_PSSR		0x11	/* PHY-specific status register */
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Pseudo extensions to the link partner ability register */
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LPA_EF_1000FULL		0x00020000
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LPA_EF_1000HALF		0x00010000
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LPA_EF_10000FULL		0x00040000
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LPA_EF_10000HALF		0x00080000
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LPA_100			(LPA_100FULL | LPA_100HALF | LPA_100BASE4)
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LPA_EF_1000		( LPA_EF_1000FULL | LPA_EF_1000HALF )
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LPA_EF_10000               ( LPA_EF_10000FULL | LPA_EF_10000HALF )
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LPA_EF_DUPLEX		( LPA_10FULL | LPA_100FULL | LPA_EF_1000FULL | \
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				  LPA_EF_10000FULL )
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Mask of bits not associated with speed or duplexity. */
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LPA_OTHER		~( LPA_10FULL | LPA_10HALF | LPA_100FULL | \
10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				   LPA_100HALF | LPA_EF_1000FULL | LPA_EF_1000HALF )
10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* PHY-specific status register */
10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PSSR_LSTATUS		0x0400	/* Bit 10 - link status */
10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Retrieve GMII autonegotiation advertised abilities
11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic unsigned int
11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmangmii_autoneg_advertised ( struct efab_nic *efab )
11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int mii_advertise;
11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int gmii_advertise;
11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Extended bits are in bits 8 and 9 of MII_CTRL1000 */
12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	mii_advertise = falcon_mdio_read ( efab, 0, MII_ADVERTISE );
12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	gmii_advertise = ( ( falcon_mdio_read ( efab, 0, MII_CTRL1000 ) >> 8 )
12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			   & 0x03 );
12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return ( ( gmii_advertise << 16 ) | mii_advertise );
12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Retrieve GMII autonegotiation link partner abilities
12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic unsigned int
13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmangmii_autoneg_lpa ( struct efab_nic *efab )
13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int mii_lpa;
13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int gmii_lpa;
13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Extended bits are in bits 10 and 11 of MII_STAT1000 */
13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	mii_lpa = falcon_mdio_read ( efab, 0, MII_LPA );
13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	gmii_lpa = ( falcon_mdio_read ( efab, 0, MII_STAT1000 ) >> 10 ) & 0x03;
13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return ( ( gmii_lpa << 16 ) | mii_lpa );
14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Calculate GMII autonegotiated link technology
14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic unsigned int
14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmangmii_nway_result ( unsigned int negotiated )
14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int other_bits;
15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Mask out the speed and duplexity bits */
15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	other_bits = negotiated & LPA_OTHER;
15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( negotiated & LPA_EF_1000FULL )
15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return ( other_bits | LPA_EF_1000FULL );
15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else if ( negotiated & LPA_EF_1000HALF )
15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return ( other_bits | LPA_EF_1000HALF );
15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else if ( negotiated & LPA_100FULL )
15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return ( other_bits | LPA_100FULL );
16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else if ( negotiated & LPA_100BASE4 )
16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return ( other_bits | LPA_100BASE4 );
16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else if ( negotiated & LPA_100HALF )
16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return ( other_bits | LPA_100HALF );
16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else if ( negotiated & LPA_10FULL )
16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return ( other_bits | LPA_10FULL );
16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else return ( other_bits | LPA_10HALF );
16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Check GMII PHY link status
17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmangmii_link_ok ( struct efab_nic *efab )
17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int status;
17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int phy_status;
17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* BMSR is latching - it returns "link down" if the link has
18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * been down at any point since the last read.  To get a
18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * real-time status, we therefore read the register twice and
18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * use the result of the second read.
18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	(void) falcon_mdio_read ( efab, 0, MII_BMSR );
18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	status = falcon_mdio_read ( efab, 0, MII_BMSR );
18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Read the PHY-specific Status Register.  This is
18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * non-latching, so we need do only a single read.
18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	phy_status = falcon_mdio_read ( efab, 0, GMII_PSSR );
19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return ( ( status & BMSR_LSTATUS ) && ( phy_status & PSSR_LSTATUS ) );
19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**************************************************************************
19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * MDIO routines
19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman **************************************************************************
20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Numbering of the MDIO Manageable Devices (MMDs) */
20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Physical Medium Attachment/ Physical Medium Dependent sublayer */
20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMD_PMAPMD	(1)
20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* WAN Interface Sublayer */
20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMD_WIS	(2)
20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Physical Coding Sublayer */
20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMD_PCS	(3)
20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* PHY Extender Sublayer */
21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMD_PHYXS	(4)
21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Extender Sublayer */
21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMD_DTEXS	(5)
21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Transmission convergence */
21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMD_TC	(6)
21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Auto negotiation */
21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMD_AN	(7)
21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Generic register locations */
21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_CTRL1	(0)
22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_STAT1	(1)
22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_DEVS0	(5)
22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_STAT2	(8)
22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Bits in MMDREG_CTRL1 */
22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Reset */
22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_CTRL1_RESET_LBN	(15)
22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_CTRL1_RESET_WIDTH	(1)
22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Bits in MMDREG_STAT1 */
23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_STAT1_FAULT_LBN	(7)
23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_STAT1_FAULT_WIDTH	(1)
23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Link state */
23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_STAT1_LINK_LBN	(2)
23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_STAT1_LINK_WIDTH	(1)
23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Bits in MMDREG_DEVS0. */
23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define DEV_PRESENT_BIT(_b) (1 << _b)
23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_DEVS0_DTEXS	 DEV_PRESENT_BIT(MDIO_MMD_DTEXS)
24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_DEVS0_PHYXS	 DEV_PRESENT_BIT(MDIO_MMD_PHYXS)
24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_DEVS0_PCS	 DEV_PRESENT_BIT(MDIO_MMD_PCS)
24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_DEVS0_WIS	 DEV_PRESENT_BIT(MDIO_MMD_WIS)
24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_DEVS0_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD)
24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_DEVS0_AN     DEV_PRESENT_BIT(MDIO_MMD_AN)
24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Bits in MMDREG_STAT2 */
24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_STAT2_PRESENT_VAL	(2)
25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_STAT2_PRESENT_LBN	(14)
25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_MMDREG_STAT2_PRESENT_WIDTH (2)
25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* PHY XGXS lane state */
25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_PHYXS_LANE_STATE		(0x18)
25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_PHYXS_LANE_ALIGNED_LBN	(12)
25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_PHYXS_LANE_SYNC0_LBN	(0)
25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_PHYXS_LANE_SYNC1_LBN	(1)
25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_PHYXS_LANE_SYNC2_LBN	(2)
25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO_PHYXS_LANE_SYNC3_LBN	(3)
26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* This ought to be ridiculous overkill. We expect it to fail rarely */
26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO45_RESET_TRIES      100
26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDIO45_RESET_SPINTIME   10
26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanmdio_clause45_wait_reset_mmds ( struct efab_nic* efab )
26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int tries = MDIO45_RESET_TRIES;
26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int in_reset;
27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	while(tries) {
27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		int mask = efab->phy_op->mmds;
27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		int mmd = 0;
27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		in_reset = 0;
27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		while(mask) {
27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			if (mask & 1) {
27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				int stat = falcon_mdio_read ( efab,  mmd,
27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman							      MDIO_MMDREG_CTRL1 );
27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				if (stat < 0) {
28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					EFAB_ERR("Failed to read status of MMD %d\n",
28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman						 mmd );
28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					in_reset = 1;
28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					break;
28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				}
28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				if (stat & (1 << MDIO_MMDREG_CTRL1_RESET_LBN))
28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					in_reset |= (1 << mmd);
28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			}
28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			mask = mask >> 1;
28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			mmd++;
29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (!in_reset)
29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			break;
29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		tries--;
29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mdelay ( MDIO45_RESET_SPINTIME );
29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (in_reset != 0) {
29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_ERR("Not all MMDs came out of reset in time. MMDs "
29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			 "still in reset: %x\n", in_reset);
29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return -ETIMEDOUT;
30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
30376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
30576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanmdio_clause45_reset_mmd ( struct efab_nic *efab, int mmd )
30676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
30776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int tries = MDIO45_RESET_TRIES;
30876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int ctrl;
30976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
31076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_mdio_write ( efab, mmd, MDIO_MMDREG_CTRL1,
31176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    ( 1 << MDIO_MMDREG_CTRL1_RESET_LBN ) );
31276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
31376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Wait for the reset bit to clear. */
31476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	do {
31576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mdelay ( MDIO45_RESET_SPINTIME );
31676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
31776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ctrl = falcon_mdio_read ( efab, mmd, MDIO_MMDREG_CTRL1 );
31876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( ~ctrl & ( 1 << MDIO_MMDREG_CTRL1_RESET_LBN ) )
31976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			return 0;
32076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} while ( --tries );
32176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
32276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_ERR ( "Failed to reset mmd %d\n", mmd );
32376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
32476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return -ETIMEDOUT;
32576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
32676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
32776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
32876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanmdio_clause45_links_ok(struct efab_nic *efab )
32976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
33076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int status, good;
33176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int ok = 1;
33276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int mmd = 0;
33376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int mmd_mask = efab->phy_op->mmds;
33476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
33576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	while (mmd_mask) {
33676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (mmd_mask & 1) {
33776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			/* Double reads because link state is latched, and a
33876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			 * read	moves the current state into the register */
33976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			status = falcon_mdio_read ( efab, mmd,
34076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman						    MDIO_MMDREG_STAT1 );
34176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			status = falcon_mdio_read ( efab, mmd,
34276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman						    MDIO_MMDREG_STAT1 );
34376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
34476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			good = status & (1 << MDIO_MMDREG_STAT1_LINK_LBN);
34576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			ok = ok && good;
34676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
34776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mmd_mask = (mmd_mask >> 1);
34876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mmd++;
34976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
35076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return ok;
35176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
35276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
35376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
35476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanmdio_clause45_check_mmds ( struct efab_nic *efab )
35576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
35676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int mmd = 0;
35776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int devices = falcon_mdio_read ( efab, MDIO_MMD_PHYXS,
35876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					 MDIO_MMDREG_DEVS0 );
35976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int mmd_mask = efab->phy_op->mmds;
36076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
36176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Check all the expected MMDs are present */
36276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( devices < 0 ) {
36376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_ERR ( "Failed to read devices present\n" );
36476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return -EIO;
36576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
36676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ( devices & mmd_mask ) != mmd_mask ) {
36776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_ERR ( "required MMDs not present: got %x, wanted %x\n",
36876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			   devices, mmd_mask );
36976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return -EIO;
37076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
37176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
37276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Check all required MMDs are responding and happy. */
37376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	while ( mmd_mask ) {
37476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( mmd_mask & 1 ) {
37576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			efab_dword_t reg;
37676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			int status;
37776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			reg.opaque = falcon_mdio_read ( efab, mmd,
37876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman							MDIO_MMDREG_STAT2 );
37976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			status = EFAB_DWORD_FIELD ( reg,
38076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman						    MDIO_MMDREG_STAT2_PRESENT );
38176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			if ( status != MDIO_MMDREG_STAT2_PRESENT_VAL ) {
38276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
38376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
38476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				return -EIO;
38576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			}
38676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
38776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mmd_mask >>= 1;
38876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mmd++;
38976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
39076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
39176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
39276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
39376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
39476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* I/O BAR address register */
39576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_IOM_IND_ADR_REG 0x0
39676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
39776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* I/O BAR data register */
39876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_IOM_IND_DAT_REG 0x4
39976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
40076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Address region register */
40176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_ADR_REGION_REG_KER	0x00
40276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_ADR_REGION0_LBN	0
40376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_ADR_REGION0_WIDTH	18
40476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_ADR_REGION1_LBN	32
40576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_ADR_REGION1_WIDTH	18
40676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_ADR_REGION2_LBN	64
40776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_ADR_REGION2_WIDTH	18
40876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_ADR_REGION3_LBN	96
40976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_ADR_REGION3_WIDTH	18
41076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
41176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Interrupt enable register */
41276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_INT_EN_REG_KER 0x0010
41376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MEM_PERR_INT_EN_KER_LBN 5
41476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MEM_PERR_INT_EN_KER_WIDTH 1
41576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_KER_INT_CHAR_LBN 4
41676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_KER_INT_CHAR_WIDTH 1
41776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_KER_INT_KER_LBN 3
41876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_KER_INT_KER_WIDTH 1
41976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_ILL_ADR_ERR_INT_EN_KER_LBN 2
42076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_ILL_ADR_ERR_INT_EN_KER_WIDTH 1
42176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_PERR_INT_EN_KER_LBN 1
42276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_PERR_INT_EN_KER_WIDTH 1
42376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_DRV_INT_EN_KER_LBN 0
42476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_DRV_INT_EN_KER_WIDTH 1
42576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
42676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Interrupt status register */
42776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_INT_ADR_REG_KER	0x0030
42876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_INT_ADR_KER_LBN 0
42976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_INT_ADR_KER_WIDTH EFAB_DMA_TYPE_WIDTH ( 64 )
43076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
43176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Interrupt status register (B0 only) */
43276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define INT_ISR0_B0 0x90
43376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define INT_ISR1_B0 0xA0
43476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
43576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Interrupt acknowledge register (A0/A1 only) */
43676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_INT_ACK_KER_REG_A1 0x0050
43776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define INT_ACK_DUMMY_DATA_LBN 0
43876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define INT_ACK_DUMMY_DATA_WIDTH 32
43976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
44076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Interrupt acknowledge work-around register (A0/A1 only )*/
44176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define WORK_AROUND_BROKEN_PCI_READS_REG_KER_A1 0x0070
44276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
44376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Hardware initialisation register */
44476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_HW_INIT_REG_KER 0x00c0
44576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_BCSR_TARGET_MASK_LBN 101
44676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_BCSR_TARGET_MASK_WIDTH 4
44776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
44876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* SPI host command register */
44976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_REG 0x0100
45076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_CMD_EN_LBN 31
45176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_CMD_EN_WIDTH 1
45276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_WR_TIMER_ACTIVE_LBN 28
45376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_WR_TIMER_ACTIVE_WIDTH 1
45476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_SF_SEL_LBN 24
45576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_SF_SEL_WIDTH 1
45676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_EEPROM 0
45776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_FLASH 1
45876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_DABCNT_LBN 16
45976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_DABCNT_WIDTH 5
46076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_READ_LBN 15
46176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_READ_WIDTH 1
46276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_READ 1
46376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_WRITE 0
46476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_DUBCNT_LBN 12
46576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_DUBCNT_WIDTH 2
46676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_ADBCNT_LBN 8
46776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_ADBCNT_WIDTH 2
46876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_ENC_LBN 0
46976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HCMD_ENC_WIDTH 8
47076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
47176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* SPI host address register */
47276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HADR_REG 0x0110
47376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HADR_DUBYTE_LBN 24
47476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HADR_DUBYTE_WIDTH 8
47576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HADR_ADR_LBN 0
47676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HADR_ADR_WIDTH 24
47776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
47876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* SPI host data register */
47976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HDATA_REG 0x0120
48076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HDATA3_LBN 96
48176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HDATA3_WIDTH 32
48276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HDATA2_LBN 64
48376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HDATA2_WIDTH 32
48476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HDATA1_LBN 32
48576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HDATA1_WIDTH 32
48676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HDATA0_LBN 0
48776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SPI_HDATA0_WIDTH 32
48876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
48976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* VPD Config 0 Register register */
49076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_VPD_CFG_REG 0x0140
49176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_VPD_EN_LBN 0
49276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_VPD_EN_WIDTH 1
49376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_VPD_EN_AD9_MODE_LBN 1
49476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_VPD_EN_AD9_MODE_WIDTH 1
49576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_EE_CLOCK_DIV_LBN 112
49676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_EE_CLOCK_DIV_WIDTH 7
49776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SF_CLOCK_DIV_LBN 120
49876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_SF_CLOCK_DIV_WIDTH 7
49976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
50076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
50176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* NIC status register */
50276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_NIC_STAT_REG 0x0200
50376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_ONCHIP_SRAM_LBN 16
50476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_ONCHIP_SRAM_WIDTH 1
50576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SF_PRST_LBN 9
50676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SF_PRST_WIDTH 1
50776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_PRST_LBN 8
50876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_PRST_WIDTH 1
50976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_STRAP_LBN 7
51076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_STRAP_WIDTH 1
51176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCI_PCIX_MODE_LBN 4
51276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCI_PCIX_MODE_WIDTH 3
51376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCI_PCIX_MODE_PCI33_DECODE 0
51476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCI_PCIX_MODE_PCI66_DECODE 1
51576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCI_PCIX_MODE_PCIX66_DECODE 5
51676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCI_PCIX_MODE_PCIX100_DECODE 6
51776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCI_PCIX_MODE_PCIX133_DECODE 7
51876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_STRAP_ISCSI_EN_LBN 3
51976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_STRAP_ISCSI_EN_WIDTH 1
52076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_STRAP_PINS_LBN 0
52176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_STRAP_PINS_WIDTH 3
52276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_STRAP_10G_LBN 2
52376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_STRAP_10G_WIDTH 1
52476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_STRAP_DUAL_PORT_LBN 1
52576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_STRAP_DUAL_PORT_WIDTH 1
52676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_STRAP_PCIE_LBN 0
52776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_STRAP_PCIE_WIDTH 1
52876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
52976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Falcon revisions */
53076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FALCON_REV_A0 0
53176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FALCON_REV_A1 1
53276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FALCON_REV_B0 2
53376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
53476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GPIO control register */
53576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO_CTL_REG_KER 0x0210
53676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO_CTL_REG_KER 0x0210
53776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
53876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO3_OEN_LBN 27
53976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO3_OEN_WIDTH 1
54076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO2_OEN_LBN 26
54176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO2_OEN_WIDTH 1
54276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO1_OEN_LBN 25
54376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO1_OEN_WIDTH 1
54476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO0_OEN_LBN 24
54576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO0_OEN_WIDTH 1
54676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
54776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO3_OUT_LBN 19
54876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO3_OUT_WIDTH 1
54976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO2_OUT_LBN 18
55076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO2_OUT_WIDTH 1
55176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO1_OUT_LBN 17
55276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO1_OUT_WIDTH 1
55376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO0_OUT_LBN 16
55476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO0_OUT_WIDTH 1
55576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
55676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO3_IN_LBN 11
55776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO3_IN_WIDTH 1
55876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO2_IN_LBN 10
55976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO2_IN_WIDTH 1
56076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO1_IN_LBN 9
56176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO1_IN_WIDTH 1
56276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO0_IN_LBN 8
56376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GPIO0_IN_WIDTH 1
56476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
56576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_FLASH_PRESENT_LBN 7
56676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_FLASH_PRESENT_WIDTH 1
56776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EEPROM_PRESENT_LBN 6
56876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EEPROM_PRESENT_WIDTH 1
56976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_BOOTED_USING_NVDEVICE_LBN 3
57076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_BOOTED_USING_NVDEVICE_WIDTH 1
57176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
57276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Defines for extra non-volatile storage */
57376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_NV_MAGIC_NUMBER 0xFA1C
57476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
57576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Global control register */
57676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_GLB_CTL_REG_KER	0x0220
57776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EXT_PHY_RST_CTL_LBN 63
57876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EXT_PHY_RST_CTL_WIDTH 1
57976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCIE_SD_RST_CTL_LBN 61
58076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCIE_SD_RST_CTL_WIDTH 1
58176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCIE_STCK_RST_CTL_LBN 59
58276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCIE_STCK_RST_CTL_WIDTH 1
58376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCIE_NSTCK_RST_CTL_LBN 58
58476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCIE_NSTCK_RST_CTL_WIDTH 1
58576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCIE_CORE_RST_CTL_LBN 57
58676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_PCIE_CORE_RST_CTL_WIDTH 1
58776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_RST_CTL_LBN 49
58876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EE_RST_CTL_WIDTH 1
58976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RST_EXT_PHY_LBN 31
59076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RST_EXT_PHY_WIDTH 1
59176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EXT_PHY_RST_DUR_LBN 1
59276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EXT_PHY_RST_DUR_WIDTH 3
59376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SWRST_LBN 0
59476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SWRST_WIDTH 1
59576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define INCLUDE_IN_RESET 0
59676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EXCLUDE_FROM_RESET 1
59776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
59876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* FPGA build version */
59976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_ALTERA_BUILD_REG_KER 0x0300
60076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_VER_MAJOR_LBN 24
60176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_VER_MAJOR_WIDTH 8
60276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_VER_MINOR_LBN 16
60376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_VER_MINOR_WIDTH 8
60476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_VER_BUILD_LBN 0
60576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_VER_BUILD_WIDTH 16
60676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_VER_ALL_LBN 0
60776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_VER_ALL_WIDTH 32
60876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
60976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Spare EEPROM bits register (flash 0x390) */
61076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SPARE_REG_KER 0x310
61176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MEM_PERR_EN_TX_DATA_LBN 72
61276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MEM_PERR_EN_TX_DATA_WIDTH 2
61376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
61476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Timer table for kernel access */
61576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TIMER_CMD_REG_KER 0x420
61676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TIMER_MODE_LBN 12
61776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TIMER_MODE_WIDTH 2
61876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TIMER_MODE_DIS 0
61976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TIMER_MODE_INT_HLDOFF 1
62076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TIMER_VAL_LBN 0
62176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TIMER_VAL_WIDTH 12
62276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
62376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Receive configuration register */
62476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_CFG_REG_KER 0x800
62576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XOFF_EN_LBN 0
62676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XOFF_EN_WIDTH 1
62776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
62876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* SRAM receive descriptor cache configuration register */
62976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_RX_DC_CFG_REG_KER 0x610
63076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_RX_DC_BASE_ADR_LBN 0
63176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_RX_DC_BASE_ADR_WIDTH 21
63276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
63376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* SRAM transmit descriptor cache configuration register */
63476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_TX_DC_CFG_REG_KER 0x620
63576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_TX_DC_BASE_ADR_LBN 0
63676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_TX_DC_BASE_ADR_WIDTH 21
63776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
63876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* SRAM configuration register */
63976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_CFG_REG_KER 0x630
64076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRAM_OOB_ADR_INTEN_LBN 5
64176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRAM_OOB_ADR_INTEN_WIDTH 1
64276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRAM_OOB_BUF_INTEN_LBN 4
64376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRAM_OOB_BUF_INTEN_WIDTH 1
64476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRAM_OOB_BT_INIT_EN_LBN 3
64576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRAM_OOB_BT_INIT_EN_WIDTH 1
64676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_NUM_BANK_LBN 2
64776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_NUM_BANK_WIDTH 1
64876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_BANK_SIZE_LBN 0
64976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_BANK_SIZE_WIDTH 2
65076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_NUM_BANKS_AND_BANK_SIZE_LBN 0
65176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_SRM_NUM_BANKS_AND_BANK_SIZE_WIDTH 3
65276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
65376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_CFG_REG_KER 0x800
65476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_INGR_EN_B0_LBN 47
65576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_INGR_EN_B0_WIDTH 1
65676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_USR_BUF_SIZE_B0_LBN 19
65776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_USR_BUF_SIZE_B0_WIDTH 9
65876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XON_MAC_TH_B0_LBN 10
65976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XON_MAC_TH_B0_WIDTH 9
66076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XOFF_MAC_TH_B0_LBN 1
66176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XOFF_MAC_TH_B0_WIDTH 9
66276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XOFF_MAC_EN_B0_LBN 0
66376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XOFF_MAC_EN_B0_WIDTH 1
66476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_USR_BUF_SIZE_A1_LBN 11
66576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_USR_BUF_SIZE_A1_WIDTH 9
66676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XON_MAC_TH_A1_LBN 6
66776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XON_MAC_TH_A1_WIDTH 5
66876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XOFF_MAC_TH_A1_LBN 1
66976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XOFF_MAC_TH_A1_WIDTH 5
67076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XOFF_MAC_EN_A1_LBN 0
67176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XOFF_MAC_EN_A1_WIDTH 1
67276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
67376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_USR_BUF_SIZE_A1_LBN 11
67476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_USR_BUF_SIZE_A1_WIDTH 9
67576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XOFF_MAC_EN_A1_LBN 0
67676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_XOFF_MAC_EN_A1_WIDTH 1
67776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
67876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Receive filter control register */
67976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_FILTER_CTL_REG_KER 0x810
68076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_UDP_FULL_SRCH_LIMIT_LBN 32
68176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_UDP_FULL_SRCH_LIMIT_WIDTH 8
68276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_NUM_KER_LBN 24
68376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_NUM_KER_WIDTH 2
68476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_UDP_WILD_SRCH_LIMIT_LBN 16
68576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_UDP_WILD_SRCH_LIMIT_WIDTH 8
68676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TCP_WILD_SRCH_LIMIT_LBN 8
68776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TCP_WILD_SRCH_LIMIT_WIDTH 8
68876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TCP_FULL_SRCH_LIMIT_LBN 0
68976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TCP_FULL_SRCH_LIMIT_WIDTH 8
69076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
69176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* RX queue flush register */
69276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_FLUSH_DESCQ_REG_KER 0x0820
69376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_FLUSH_DESCQ_CMD_LBN 24
69476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_FLUSH_DESCQ_CMD_WIDTH 1
69576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_FLUSH_DESCQ_LBN 0
69676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_FLUSH_DESCQ_WIDTH 12
69776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
69876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Receive descriptor update register */
69976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESC_UPD_REG_KER 0x0830
70076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESC_WPTR_LBN 96
70176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESC_WPTR_WIDTH 12
70276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESC_UPD_REG_KER_DWORD ( FCN_RX_DESC_UPD_REG_KER + 12 )
70376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESC_WPTR_DWORD_LBN 0
70476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESC_WPTR_DWORD_WIDTH 12
70576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
70676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Receive descriptor cache configuration register */
70776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DC_CFG_REG_KER 0x840
70876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DC_SIZE_LBN 0
70976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DC_SIZE_WIDTH 2
71076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
71176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_SELF_RST_REG_KER 0x890
71276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_ISCSI_DIS_LBN 17
71376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_ISCSI_DIS_WIDTH 1
71476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_NODESC_WAIT_DIS_LBN 9
71576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_NODESC_WAIT_DIS_WIDTH 1
71676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_RECOVERY_EN_LBN 8
71776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_RECOVERY_EN_WIDTH 1
71876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
71976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* TX queue flush register */
72076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_FLUSH_DESCQ_REG_KER 0x0a00
72176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_FLUSH_DESCQ_CMD_LBN 12
72276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_FLUSH_DESCQ_CMD_WIDTH 1
72376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_FLUSH_DESCQ_LBN 0
72476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_FLUSH_DESCQ_WIDTH 12
72576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
72676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Transmit configuration register 2 */
72776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_CFG2_REG_KER 0xa80
72876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DIS_NON_IP_EV_LBN 17
72976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DIS_NON_IP_EV_WIDTH 1
73076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
73176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Transmit descriptor update register */
73276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESC_UPD_REG_KER 0x0a10
73376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESC_WPTR_LBN 96
73476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESC_WPTR_WIDTH 12
73576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESC_UPD_REG_KER_DWORD ( FCN_TX_DESC_UPD_REG_KER + 12 )
73676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESC_WPTR_DWORD_LBN 0
73776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESC_WPTR_DWORD_WIDTH 12
73876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
73976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Transmit descriptor cache configuration register */
74076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DC_CFG_REG_KER 0xa20
74176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DC_SIZE_LBN 0
74276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DC_SIZE_WIDTH 2
74376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
74476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* PHY management transmit data register */
74576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_TXD_REG_KER 0xc00
74676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_TXD_LBN 0
74776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_TXD_WIDTH 16
74876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
74976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* PHY management receive data register */
75076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_RXD_REG_KER 0xc10
75176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_RXD_LBN 0
75276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_RXD_WIDTH 16
75376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
75476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* PHY management configuration & status register */
75576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_CS_REG_KER 0xc20
75676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_GC_LBN 4
75776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_GC_WIDTH 1
75876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_RIC_LBN 2
75976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_RIC_WIDTH 1
76076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_RDC_LBN 1
76176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_RDC_WIDTH 1
76276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_WRC_LBN 0
76376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_WRC_WIDTH 1
76476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
76576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* PHY management PHY address register */
76676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_PHY_ADR_REG_KER 0xc30
76776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_PHY_ADR_LBN 0
76876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_PHY_ADR_WIDTH 16
76976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
77076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* PHY management ID register */
77176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_ID_REG_KER 0xc40
77276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_PRT_ADR_LBN 11
77376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_PRT_ADR_WIDTH 5
77476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_DEV_ADR_LBN 6
77576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_DEV_ADR_WIDTH 5
77676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
77776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* PHY management status & mask register */
77876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_STAT_REG_KER 0xc50
77976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_PINT_LBN 4
78076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_PINT_WIDTH 1
78176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_DONE_LBN 3
78276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_DONE_WIDTH 1
78376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_BSERR_LBN 2
78476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_BSERR_WIDTH 1
78576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_LNFL_LBN 1
78676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_LNFL_WIDTH 1
78776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_BSY_LBN 0
78876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MD_BSY_WIDTH 1
78976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
79076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Port 0 and 1 MAC control registers */
79176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MAC0_CTRL_REG_KER 0xc80
79276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MAC1_CTRL_REG_KER 0xc90
79376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MAC_XOFF_VAL_LBN 16
79476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MAC_XOFF_VAL_WIDTH 16
79576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MAC_BCAD_ACPT_LBN 4
79676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MAC_BCAD_ACPT_WIDTH 1
79776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MAC_UC_PROM_LBN 3
79876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MAC_UC_PROM_WIDTH 1
79976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MAC_LINK_STATUS_LBN 2
80076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MAC_LINK_STATUS_WIDTH 1
80176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MAC_SPEED_LBN 0
80276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MAC_SPEED_WIDTH 2
80376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
80476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 10Gig Xaui XGXS Default Values  */
80576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define XX_TXDRV_DEQ_DEFAULT 0xe /* deq=.6 */
80676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define XX_TXDRV_DTX_DEFAULT 0x5 /* 1.25 */
80776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define XX_SD_CTL_DRV_DEFAULT 0  /* 20mA */
80876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
80976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC registers */
81076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FALCON_GMAC_REGBANK 0xe00
81176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FALCON_GMAC_REGBANK_SIZE 0x200
81276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FALCON_GMAC_REG_SIZE 0x10
81376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
81476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* XGMAC registers */
81576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FALCON_XMAC_REGBANK 0x1200
81676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FALCON_XMAC_REGBANK_SIZE 0x200
81776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FALCON_XMAC_REG_SIZE 0x10
81876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
81976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* XGMAC address register low */
82076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ADR_LO_REG_MAC 0x00
82176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ADR_3_LBN 24
82276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ADR_3_WIDTH 8
82376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ADR_2_LBN 16
82476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ADR_2_WIDTH 8
82576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ADR_1_LBN 8
82676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ADR_1_WIDTH 8
82776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ADR_0_LBN 0
82876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ADR_0_WIDTH 8
82976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
83076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* XGMAC address register high */
83176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ADR_HI_REG_MAC 0x01
83276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ADR_5_LBN 8
83376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ADR_5_WIDTH 8
83476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ADR_4_LBN 0
83576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ADR_4_WIDTH 8
83676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
83776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* XGMAC global configuration - port 0*/
83876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_GLB_CFG_REG_MAC 0x02
83976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_RX_STAT_EN_LBN 11
84076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_RX_STAT_EN_WIDTH 1
84176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_TX_STAT_EN_LBN 10
84276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_TX_STAT_EN_WIDTH 1
84376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_RX_JUMBO_MODE_LBN 6
84476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_RX_JUMBO_MODE_WIDTH 1
84576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_CORE_RST_LBN 0
84676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_CORE_RST_WIDTH 1
84776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
84876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* XGMAC transmit configuration - port 0 */
84976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_TX_CFG_REG_MAC 0x03
85076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_IPG_LBN 16
85176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_IPG_WIDTH 4
85276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_FCNTL_LBN 10
85376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_FCNTL_WIDTH 1
85476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_TXCRC_LBN 8
85576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_TXCRC_WIDTH 1
85676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_AUTO_PAD_LBN 5
85776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_AUTO_PAD_WIDTH 1
85876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_TX_PRMBL_LBN 2
85976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_TX_PRMBL_WIDTH 1
86076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_TXEN_LBN 1
86176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_TXEN_WIDTH 1
86276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
86376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* XGMAC receive configuration - port 0 */
86476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_RX_CFG_REG_MAC 0x04
86576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_PASS_CRC_ERR_LBN 25
86676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_PASS_CRC_ERR_WIDTH 1
86776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_AUTO_DEPAD_LBN 8
86876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_AUTO_DEPAD_WIDTH 1
86976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_RXEN_LBN 1
87076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_RXEN_WIDTH 1
87176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
87276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* XGMAC management interrupt mask register */
87376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_MGT_INT_MSK_REG_MAC_B0 0x5
87476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_MSK_PRMBLE_ERR_LBN 2
87576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_MSK_PRMBLE_ERR_WIDTH 1
87676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_MSK_RMTFLT_LBN 1
87776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_MSK_RMTFLT_WIDTH 1
87876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_MSK_LCLFLT_LBN 0
87976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_MSK_LCLFLT_WIDTH 1
88076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
88176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* XGMAC flow control register */
88276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_FC_REG_MAC 0x7
88376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_PAUSE_TIME_LBN 16
88476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_PAUSE_TIME_WIDTH 16
88576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_DIS_FCNTL_LBN 0
88676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_DIS_FCNTL_WIDTH 1
88776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
88876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* XGMAC transmit parameter register */
88976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_TX_PARAM_REG_MAC 0x0d
89076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_TX_JUMBO_MODE_LBN 31
89176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_TX_JUMBO_MODE_WIDTH 1
89276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_MAX_TX_FRM_SIZE_LBN 16
89376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_MAX_TX_FRM_SIZE_WIDTH 14
89476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ACPT_ALL_MCAST_LBN 11
89576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_ACPT_ALL_MCAST_WIDTH 1
89676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
89776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* XGMAC receive parameter register */
89876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_RX_PARAM_REG_MAC 0x0e
89976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_MAX_RX_FRM_SIZE_LBN 0
90076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_MAX_RX_FRM_SIZE_WIDTH 14
90176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
90276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* XGMAC management interrupt status register */
90376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_MGT_INT_REG_MAC_B0 0x0f
90476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_PRMBLE_ERR 2
90576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_PRMBLE_WIDTH 1
90676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_RMTFLT_LBN 1
90776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_RMTFLT_WIDTH 1
90876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_LCLFLT_LBN 0
90976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XM_LCLFLT_WIDTH 1
91076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
91176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* XAUI XGXS core status register */
91276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_ALIGN_DONE_LBN 20
91376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_ALIGN_DONE_WIDTH 1
91476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_CORE_STAT_REG_MAC 0x16
91576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_SYNC_STAT_LBN 16
91676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_SYNC_STAT_WIDTH 4
91776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_SYNC_STAT_DECODE_SYNCED 0xf
91876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_COMMA_DET_LBN 12
91976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_COMMA_DET_WIDTH 4
92076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_COMMA_DET_RESET 0xf
92176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_CHARERR_LBN 4
92276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_CHARERR_WIDTH 4
92376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_CHARERR_RESET 0xf
92476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DISPERR_LBN 0
92576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DISPERR_WIDTH 4
92676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DISPERR_RESET 0xf
92776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
92876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* XGXS/XAUI powerdown/reset register */
92976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_PWR_RST_REG_MAC 0x10
93076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_PWRDND_EN_LBN 15
93176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_PWRDND_EN_WIDTH 1
93276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_PWRDNC_EN_LBN 14
93376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_PWRDNC_EN_WIDTH 1
93476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_PWRDNB_EN_LBN 13
93576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_PWRDNB_EN_WIDTH 1
93676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_PWRDNA_EN_LBN 12
93776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_PWRDNA_EN_WIDTH 1
93876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RSTPLLCD_EN_LBN 9
93976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RSTPLLCD_EN_WIDTH 1
94076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RSTPLLAB_EN_LBN 8
94176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RSTPLLAB_EN_WIDTH 1
94276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RESETD_EN_LBN 7
94376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RESETD_EN_WIDTH 1
94476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RESETC_EN_LBN 6
94576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RESETC_EN_WIDTH 1
94676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RESETB_EN_LBN 5
94776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RESETB_EN_WIDTH 1
94876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RESETA_EN_LBN 4
94976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RESETA_EN_WIDTH 1
95076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RSTXGXSRX_EN_LBN 2
95176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RSTXGXSRX_EN_WIDTH 1
95276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RSTXGXSTX_EN_LBN 1
95376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RSTXGXSTX_EN_WIDTH 1
95476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RST_XX_EN_LBN 0
95576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_RST_XX_EN_WIDTH 1
95676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
95776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
95876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* XGXS/XAUI powerdown/reset control register */
95976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_SD_CTL_REG_MAC 0x11
96076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_TERMADJ1_LBN 17
96176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_TERMADJ1_WIDTH 1
96276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_TERMADJ0_LBN 16
96376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_TERMADJ0_WIDTH 1
96476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_HIDRVD_LBN 15
96576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_HIDRVD_WIDTH 1
96676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LODRVD_LBN 14
96776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LODRVD_WIDTH 1
96876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_HIDRVC_LBN 13
96976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_HIDRVC_WIDTH 1
97076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LODRVC_LBN 12
97176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LODRVC_WIDTH 1
97276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_HIDRVB_LBN 11
97376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_HIDRVB_WIDTH 1
97476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LODRVB_LBN 10
97576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LODRVB_WIDTH 1
97676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_HIDRVA_LBN 9
97776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_HIDRVA_WIDTH 1
97876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LODRVA_LBN 8
97976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LODRVA_WIDTH 1
98076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LPBKD_LBN 3
98176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LPBKD_WIDTH 1
98276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LPBKC_LBN 2
98376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LPBKC_WIDTH 1
98476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LPBKB_LBN 1
98576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LPBKB_WIDTH 1
98676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LPBKA_LBN 0
98776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_LPBKA_WIDTH 1
98876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
98976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_TXDRV_CTL_REG_MAC 0x12
99076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DEQD_LBN 28
99176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DEQD_WIDTH 4
99276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DEQC_LBN 24
99376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DEQC_WIDTH 4
99476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DEQB_LBN 20
99576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DEQB_WIDTH 4
99676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DEQA_LBN 16
99776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DEQA_WIDTH 4
99876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DTXD_LBN 12
99976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DTXD_WIDTH 4
100076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DTXC_LBN 8
100176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DTXC_WIDTH 4
100276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DTXB_LBN 4
100376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DTXB_WIDTH 4
100476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DTXA_LBN 0
100576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_XX_DTXA_WIDTH 4
100676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
100776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Receive filter table */
100876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_FILTER_TBL0 0xF00000
100976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
101076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Receive descriptor pointer table */
101176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESC_PTR_TBL_KER_A1 0x11800
101276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESC_PTR_TBL_KER_B0 0xF40000
101376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_ISCSI_DDIG_EN_LBN 88
101476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_ISCSI_DDIG_EN_WIDTH 1
101576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_ISCSI_HDIG_EN_LBN 87
101676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_ISCSI_HDIG_EN_WIDTH 1
101776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_BUF_BASE_ID_LBN 36
101876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_BUF_BASE_ID_WIDTH 20
101976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_EVQ_ID_LBN 24
102076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_EVQ_ID_WIDTH 12
102176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_OWNER_ID_LBN 10
102276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_OWNER_ID_WIDTH 14
102376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_SIZE_LBN 3
102476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_SIZE_WIDTH 2
102576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_SIZE_4K 3
102676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_SIZE_2K 2
102776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_SIZE_1K 1
102876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_SIZE_512 0
102976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_TYPE_LBN 2
103076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_TYPE_WIDTH 1
103176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_JUMBO_LBN 1
103276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_JUMBO_WIDTH 1
103376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_EN_LBN 0
103476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_DESCQ_EN_WIDTH 1
103576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
103676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Transmit descriptor pointer table */
103776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESC_PTR_TBL_KER_A1 0x11900
103876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESC_PTR_TBL_KER_B0 0xF50000
103976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_NON_IP_DROP_DIS_B0_LBN 91
104076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_NON_IP_DROP_DIS_B0_WIDTH 1
104176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_EN_LBN 88
104276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_EN_WIDTH 1
104376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_ISCSI_DDIG_EN_LBN 87
104476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_ISCSI_DDIG_EN_WIDTH 1
104576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_ISCSI_HDIG_EN_LBN 86
104676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_ISCSI_HDIG_EN_WIDTH 1
104776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_BUF_BASE_ID_LBN 36
104876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_BUF_BASE_ID_WIDTH 20
104976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_EVQ_ID_LBN 24
105076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_EVQ_ID_WIDTH 12
105176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_OWNER_ID_LBN 10
105276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_OWNER_ID_WIDTH 14
105376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_SIZE_LBN 3
105476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_SIZE_WIDTH 2
105576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_SIZE_4K 3
105676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_SIZE_2K 2
105776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_SIZE_1K 1
105876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_SIZE_512 0
105976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_TYPE_LBN 1
106076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_TYPE_WIDTH 2
106176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_FLUSH_LBN 0
106276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_DESCQ_FLUSH_WIDTH 1
106376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
106476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Event queue pointer */
106576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_PTR_TBL_KER_A1 0x11a00
106676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_PTR_TBL_KER_B0 0xf60000
106776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_EN_LBN 23
106876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_EN_WIDTH 1
106976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_SIZE_LBN 20
107076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_SIZE_WIDTH 3
107176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_SIZE_32K 6
107276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_SIZE_16K 5
107376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_SIZE_8K 4
107476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_SIZE_4K 3
107576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_SIZE_2K 2
107676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_SIZE_1K 1
107776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_SIZE_512 0
107876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_BUF_BASE_ID_LBN 0
107976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_BUF_BASE_ID_WIDTH 20
108076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
108176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* RSS indirection table */
108276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_RSS_INDIR_TBL_B0 0xFB0000
108376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
108476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Event queue read pointer */
108576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_RPTR_REG_KER_A1 0x11b00
108676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_RPTR_REG_KER_B0 0xfa0000
108776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_RPTR_LBN 0
108876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_RPTR_WIDTH 14
108976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_RPTR_REG_KER_DWORD_A1 ( FCN_EVQ_RPTR_REG_KER_A1 + 0 )
109076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_RPTR_REG_KER_DWORD_B0 ( FCN_EVQ_RPTR_REG_KER_B0 + 0 )
109176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_RPTR_DWORD_LBN 0
109276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EVQ_RPTR_DWORD_WIDTH 14
109376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
109476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Special buffer descriptors */
109576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_BUF_FULL_TBL_KER_A1 0x18000
109676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_BUF_FULL_TBL_KER_B0 0x800000
109776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_IP_DAT_BUF_SIZE_LBN 50
109876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_IP_DAT_BUF_SIZE_WIDTH 1
109976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_IP_DAT_BUF_SIZE_8K 1
110076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_IP_DAT_BUF_SIZE_4K 0
110176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_BUF_ADR_FBUF_LBN 14
110276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_BUF_ADR_FBUF_WIDTH 34
110376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_BUF_OWNER_ID_FBUF_LBN 0
110476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_BUF_OWNER_ID_FBUF_WIDTH 14
110576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
110676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Offset of a GMAC register within Falcon */
110776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FALCON_GMAC_REG( efab, mac_reg )				\
110876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	( FALCON_GMAC_REGBANK +					\
110976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	  ( (mac_reg) * FALCON_GMAC_REG_SIZE ) )
111076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
111176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Offset of an XMAC register within Falcon */
111276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FALCON_XMAC_REG( efab_port, mac_reg )			\
111376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	( FALCON_XMAC_REGBANK +					\
111476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	  ( (mac_reg) * FALCON_XMAC_REG_SIZE ) )
111576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
111676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MAC_DATA_LBN 0
111776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_MAC_DATA_WIDTH 32
111876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
111976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Transmit descriptor */
112076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_KER_PORT_LBN 63
112176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_KER_PORT_WIDTH 1
112276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_KER_BYTE_CNT_LBN 48
112376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_KER_BYTE_CNT_WIDTH 14
112476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_KER_BUF_ADR_LBN 0
112576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_KER_BUF_ADR_WIDTH EFAB_DMA_TYPE_WIDTH ( 46 )
112676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
112776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
112876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Receive descriptor */
112976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_KER_BUF_SIZE_LBN 48
113076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_KER_BUF_SIZE_WIDTH 14
113176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_KER_BUF_ADR_LBN 0
113276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_KER_BUF_ADR_WIDTH EFAB_DMA_TYPE_WIDTH ( 46 )
113376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
113476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Event queue entries */
113576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EV_CODE_LBN 60
113676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_EV_CODE_WIDTH 4
113776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_IP_EV_DECODE 0
113876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_IP_EV_DECODE 2
113976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_DRIVER_EV_DECODE 5
114076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
114176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Receive events */
114276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_EV_PKT_OK_LBN 56
114376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_EV_PKT_OK_WIDTH 1
114476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_PORT_LBN 30
114576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_PORT_WIDTH 1
114676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_EV_BYTE_CNT_LBN 16
114776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_EV_BYTE_CNT_WIDTH 14
114876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_EV_DESC_PTR_LBN 0
114976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_RX_EV_DESC_PTR_WIDTH 12
115076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
115176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Transmit events */
115276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_EV_DESC_PTR_LBN 0
115376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_TX_EV_DESC_PTR_WIDTH 12
115476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
115576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
115676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
115776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
115876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Low-level hardware access
115976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
116076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
116176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
116276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
116376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_REVISION_REG(efab, reg) \
116476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	( ( efab->pci_revision == FALCON_REV_B0 ) ? reg ## _B0 : reg ## _A1 )
116576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
116676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EFAB_SET_OWORD_FIELD_VER(efab, reg, field, val)			\
116776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->pci_revision == FALCON_REV_B0 )			\
116876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_SET_OWORD_FIELD ( reg, field ## _B0, val );	\
116976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else								\
117076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_SET_OWORD_FIELD ( reg, field ## _A1, val );
117176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
117276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if FALCON_USE_IO_BAR
117376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
117476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Write dword via the I/O BAR */
117576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void _falcon_writel ( struct efab_nic *efab, uint32_t value,
117676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				    unsigned int reg ) {
117776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	outl ( reg, efab->iobase + FCN_IOM_IND_ADR_REG );
117876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	outl ( value, efab->iobase + FCN_IOM_IND_DAT_REG );
117976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
118076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
118176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Read dword via the I/O BAR */
118276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline uint32_t _falcon_readl ( struct efab_nic *efab,
118376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				       unsigned int reg ) {
118476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	outl ( reg, efab->iobase + FCN_IOM_IND_ADR_REG );
118576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return inl ( efab->iobase + FCN_IOM_IND_DAT_REG );
118676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
118776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
118876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#else /* FALCON_USE_IO_BAR */
118976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
119076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define _falcon_writel( efab, value, reg ) \
119176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	writel ( (value), (efab)->membase + (reg) )
119276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define _falcon_readl( efab, reg ) readl ( (efab)->membase + (reg) )
119376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
119476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* FALCON_USE_IO_BAR */
119576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
119676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
119776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Write to a Falcon register
119876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
119976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
120076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void
120176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_write ( struct efab_nic *efab, efab_oword_t *value, unsigned int reg )
120276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
120376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
120476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_REGDUMP ( "Writing register %x with " EFAB_OWORD_FMT "\n",
120576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       reg, EFAB_OWORD_VAL ( *value ) );
120676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
120776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	_falcon_writel ( efab, value->u32[0], reg + 0  );
120876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	_falcon_writel ( efab, value->u32[1], reg + 4  );
120976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	_falcon_writel ( efab, value->u32[2], reg + 8  );
121076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	wmb();
121176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	_falcon_writel ( efab, value->u32[3], reg + 12 );
121276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	wmb();
121376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
121476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
121576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
121676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Write to Falcon SRAM
121776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
121876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
121976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void
122076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_write_sram ( struct efab_nic *efab, efab_qword_t *value,
122176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    unsigned int index )
122276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
122376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int reg = ( FCN_REVISION_REG ( efab, FCN_BUF_FULL_TBL_KER ) +
122476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			     ( index * sizeof ( *value ) ) );
122576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
122676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_REGDUMP ( "Writing SRAM register %x with " EFAB_QWORD_FMT "\n",
122776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       reg, EFAB_QWORD_VAL ( *value ) );
122876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
122976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	_falcon_writel ( efab, value->u32[0], reg + 0  );
123076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	_falcon_writel ( efab, value->u32[1], reg + 4  );
123176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	wmb();
123276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
123376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
123476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
123576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Write dword to Falcon register that allows partial writes
123676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
123776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
123876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void
123976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_writel ( struct efab_nic *efab, efab_dword_t *value, unsigned int reg )
124076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
124176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_REGDUMP ( "Writing partial register %x with " EFAB_DWORD_FMT "\n",
124276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       reg, EFAB_DWORD_VAL ( *value ) );
124376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	_falcon_writel ( efab, value->u32[0], reg );
124476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
124576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
124676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
124776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Read from a Falcon register
124876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
124976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
125076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void
125176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_read ( struct efab_nic *efab, efab_oword_t *value, unsigned int reg )
125276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
125376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	value->u32[0] = _falcon_readl ( efab, reg + 0  );
125476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	wmb();
125576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	value->u32[1] = _falcon_readl ( efab, reg + 4  );
125676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	value->u32[2] = _falcon_readl ( efab, reg + 8  );
125776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	value->u32[3] = _falcon_readl ( efab, reg + 12 );
125876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
125976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_REGDUMP ( "Read from register %x, got " EFAB_OWORD_FMT "\n",
126076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       reg, EFAB_OWORD_VAL ( *value ) );
126176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
126276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
126376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
126476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Read from Falcon SRAM
126576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
126676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
126776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void
126876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_read_sram ( struct efab_nic *efab, efab_qword_t *value,
126976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		   unsigned int index )
127076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
127176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int reg = ( FCN_REVISION_REG ( efab, FCN_BUF_FULL_TBL_KER ) +
127276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			     ( index * sizeof ( *value ) ) );
127376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
127476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	value->u32[0] = _falcon_readl ( efab, reg + 0 );
127576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	value->u32[1] = _falcon_readl ( efab, reg + 4 );
127676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_REGDUMP ( "Read from SRAM register %x, got " EFAB_QWORD_FMT "\n",
127776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       reg, EFAB_QWORD_VAL ( *value ) );
127876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
127976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
128076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
128176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Read dword from a portion of a Falcon register
128276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
128376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
128476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void
128576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_readl ( struct efab_nic *efab, efab_dword_t *value, unsigned int reg )
128676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
128776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	value->u32[0] = _falcon_readl ( efab, reg );
128876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_REGDUMP ( "Read from register %x, got " EFAB_DWORD_FMT "\n",
128976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       reg, EFAB_DWORD_VAL ( *value ) );
129076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
129176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
129276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_DUMP_REG( efab, _reg ) do {				\
129376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab_oword_t reg;				\
129476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_read ( efab, &reg, _reg );		\
129576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_LOG ( #_reg " = " EFAB_OWORD_FMT "\n",	\
129676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			   EFAB_OWORD_VAL ( reg ) );		\
129776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} while ( 0 );
129876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
129976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FCN_DUMP_MAC_REG( efab, _mac_reg ) do {				\
130076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab_dword_t reg;					\
130176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->mac_op->mac_readl ( efab, &reg, _mac_reg );	\
130276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_LOG ( #_mac_reg " = " EFAB_DWORD_FMT "\n",		\
130376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			   EFAB_DWORD_VAL ( reg ) );			\
130476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} while ( 0 );
130576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
130676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
130776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * See if an event is present
130876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
130976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v event		Falcon event structure
131076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret True		An event is pending
131176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret False		No event is pending
131276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
131376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * We check both the high and low dword of the event for all ones.  We
131476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * wrote all ones when we cleared the event, and no valid event can
131576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * have all ones in either its high or low dwords.  This approach is
131676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * robust against reordering.
131776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
131876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Note that using a single 64-bit comparison is incorrect; even
131976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * though the CPU read will be atomic, the DMA write may not be.
132076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
132176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline int
132276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_event_present ( falcon_event_t* event )
132376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
132476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return ( ! ( EFAB_DWORD_IS_ALL_ONES ( event->dword[0] ) |
132576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     EFAB_DWORD_IS_ALL_ONES ( event->dword[1] ) ) );
132676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
132776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
132876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
132976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_eventq_read_ack ( struct efab_nic *efab, struct efab_ev_queue *ev_queue )
133076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
133176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t reg;
133276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
133376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_1 ( reg, FCN_EVQ_RPTR_DWORD, ev_queue->read_ptr );
133476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_writel ( efab, &reg,
133576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			FCN_REVISION_REG ( efab, FCN_EVQ_RPTR_REG_KER_DWORD ) );
133676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
133776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
133876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if 0
133976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
134076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Dump register contents (for debugging)
134176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
134276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Marked as static inline so that it will not be compiled in if not
134376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * used.
134476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
134576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void
134676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_dump_regs ( struct efab_nic *efab )
134776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
134876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_REG ( efab, FCN_INT_EN_REG_KER );
134976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_REG ( efab, FCN_INT_ADR_REG_KER );
135076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_REG ( efab, FCN_GLB_CTL_REG_KER );
135176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_REG ( efab, FCN_TIMER_CMD_REG_KER );
135276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_REG ( efab, FCN_SRM_RX_DC_CFG_REG_KER );
135376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_REG ( efab, FCN_SRM_TX_DC_CFG_REG_KER );
135476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_REG ( efab, FCN_RX_FILTER_CTL_REG_KER );
135576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_REG ( efab, FCN_RX_DC_CFG_REG_KER );
135676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_REG ( efab, FCN_TX_DC_CFG_REG_KER );
135776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_REG ( efab, FCN_MAC0_CTRL_REG_KER );
135876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_REG ( efab, FCN_MAC1_CTRL_REG_KER );
135976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_REG ( efab, FCN_REVISION_REG ( efab, FCN_RX_DESC_PTR_TBL_KER ) );
136076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_REG ( efab, FCN_REVISION_REG ( efab, FCN_TX_DESC_PTR_TBL_KER ) );
136176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_REG ( efab, FCN_REVISION_REG ( efab, FCN_EVQ_PTR_TBL_KER ) );
136276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_MAC_REG ( efab, GM_CFG1_REG_MAC );
136376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_MAC_REG ( efab, GM_CFG2_REG_MAC );
136476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_MAC_REG ( efab, GM_MAX_FLEN_REG_MAC );
136576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_MAC_REG ( efab, GM_MII_MGMT_CFG_REG_MAC );
136676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_MAC_REG ( efab, GM_ADR1_REG_MAC );
136776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_MAC_REG ( efab, GM_ADR2_REG_MAC );
136876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_MAC_REG ( efab, GMF_CFG0_REG_MAC );
136976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_MAC_REG ( efab, GMF_CFG1_REG_MAC );
137076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_MAC_REG ( efab, GMF_CFG2_REG_MAC );
137176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_MAC_REG ( efab, GMF_CFG3_REG_MAC );
137276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_MAC_REG ( efab, GMF_CFG4_REG_MAC );
137376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FCN_DUMP_MAC_REG ( efab, GMF_CFG5_REG_MAC );
137476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
137576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
137676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
137776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
137876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_interrupts ( struct efab_nic *efab, int enabled, int force )
137976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
138076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t int_en_reg_ker;
138176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
138276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_2 ( int_en_reg_ker,
138376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_KER_INT_KER, force,
138476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_DRV_INT_EN_KER, enabled );
138576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &int_en_reg_ker, FCN_INT_EN_REG_KER );
138676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
138776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
138876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
138976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
139076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
139176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * SPI access
139276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
139376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
139476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
139576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
139676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
139776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Maximum length for a single SPI transaction */
139876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FALCON_SPI_MAX_LEN 16
139976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
140076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
140176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_spi_wait ( struct efab_nic *efab )
140276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
140376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t reg;
140476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int count;
140576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
140676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	count = 0;
140776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	do {
140876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		udelay ( 100 );
140976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_read ( efab, &reg, FCN_EE_SPI_HCMD_REG );
141076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( EFAB_OWORD_FIELD ( reg, FCN_EE_SPI_HCMD_CMD_EN ) == 0 )
141176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			return 0;
141276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} while ( ++count < 1000 );
141376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
141476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_ERR ( "Timed out waiting for SPI\n" );
141576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return -ETIMEDOUT;
141676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
141776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
141876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
141976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_spi_rw ( struct spi_bus* bus, struct spi_device *device,
142076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		unsigned int command, int address,
142176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		const void* data_out, void *data_in, size_t len )
142276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
142376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_nic *efab = container_of ( bus, struct efab_nic, spi_bus );
142476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int address_len, rc, device_id, read_cmd;
142576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t reg;
142676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
142776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* falcon_init_spi_device() should have reduced the block size
142876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * down so this constraint holds */
142976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	assert ( len <= FALCON_SPI_MAX_LEN );
143076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
143176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Is this the FLASH or EEPROM device? */
143276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( device == &efab->spi_flash )
143376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		device_id = FCN_EE_SPI_FLASH;
143476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else if ( device == &efab->spi_eeprom )
143576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		device_id = FCN_EE_SPI_EEPROM;
143676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else {
143776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_ERR ( "Unknown device %p\n", device );
143876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return -EINVAL;
143976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
144076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
144176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_TRACE ( "Executing spi command %d on device %d at %d for %zd bytes\n",
144276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     command, device_id, address, len );
144376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
144476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* The bus must be idle */
144576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = falcon_spi_wait ( efab );
144676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
144776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail1;
144876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
144976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Copy data out */
145076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( data_out ) {
145176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		memcpy ( &reg, data_out, len );
145276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_write ( efab, &reg, FCN_EE_SPI_HDATA_REG );
145376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
145476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
145576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Program address register */
145676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( address >= 0 ) {
145776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_POPULATE_OWORD_1 ( reg, FCN_EE_SPI_HADR_ADR, address );
145876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_write ( efab, &reg, FCN_EE_SPI_HADR_REG );
145976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
146076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
146176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Issue command */
146276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	address_len = ( address >= 0 ) ? device->address_len / 8 : 0;
146376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	read_cmd = ( data_in ? FCN_EE_SPI_READ : FCN_EE_SPI_WRITE );
146476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_7 ( reg,
146576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_EE_SPI_HCMD_CMD_EN, 1,
146676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_EE_SPI_HCMD_SF_SEL, device_id,
146776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_EE_SPI_HCMD_DABCNT, len,
146876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_EE_SPI_HCMD_READ, read_cmd,
146976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_EE_SPI_HCMD_DUBCNT, 0,
147076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_EE_SPI_HCMD_ADBCNT, address_len,
147176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_EE_SPI_HCMD_ENC, command );
147276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_EE_SPI_HCMD_REG );
147376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
147476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Wait for the command to complete */
147576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = falcon_spi_wait ( efab );
147676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
147776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail2;
147876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
147976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Copy data in */
148076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( data_in ) {
148176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_read ( efab, &reg, FCN_EE_SPI_HDATA_REG );
148276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		memcpy ( data_in, &reg, len );
148376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
148476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
148576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
148676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
148776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail2:
148876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail1:
148976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_ERR ( "Failed SPI command %d to device %d address 0x%x len 0x%zx\n",
149076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		   command, device_id, address, len );
149176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
149276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return rc;
149376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
149476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
149576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Portion of EEPROM available for non-volatile options */
149676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct nvo_fragment falcon_nvo_fragments[] = {
149776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	{ 0x100, 0xf0 },
149876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	{ 0, 0 }
149976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
150076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
150176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
150276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
150376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
150476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Falcon bit-bashed I2C interface
150576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
150676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
150776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
150876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
150976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
151076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_i2c_bit_write ( struct bit_basher *basher, unsigned int bit_id,
151176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       unsigned long data )
151276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
151376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_nic *efab = container_of ( basher, struct efab_nic,
151476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					       i2c_bb.basher );
151576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t reg;
151676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
151776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &reg, FCN_GPIO_CTL_REG_KER );
151876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	switch ( bit_id ) {
151976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case I2C_BIT_SCL:
152076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_SET_OWORD_FIELD ( reg, FCN_GPIO0_OEN, ( data ? 0 : 1 ) );
152176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
152276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case I2C_BIT_SDA:
152376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_SET_OWORD_FIELD ( reg, FCN_GPIO3_OEN, ( data ? 0 : 1 ) );
152476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
152576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	default:
152676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_ERR ( "%s bit=%d\n", __func__, bit_id );
152776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
152876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
152976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
153076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg,  FCN_GPIO_CTL_REG_KER );
153176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
153276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
153376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
153476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_i2c_bit_read ( struct bit_basher *basher, unsigned int bit_id )
153576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
153676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_nic *efab = container_of ( basher, struct efab_nic,
153776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					       i2c_bb.basher );
153876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t reg;
153976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
154076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &reg, FCN_GPIO_CTL_REG_KER );
154176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	switch ( bit_id ) {
154276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case I2C_BIT_SCL:
154376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return EFAB_OWORD_FIELD ( reg, FCN_GPIO0_IN );
154476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
154576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case I2C_BIT_SDA:
154676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return EFAB_OWORD_FIELD ( reg, FCN_GPIO3_IN );
154776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
154876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	default:
154976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_ERR ( "%s bit=%d\n", __func__, bit_id );
155076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
155176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
155276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
155376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return -1;
155476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
155576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
155676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct bit_basher_operations falcon_i2c_bit_ops = {
155776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.read           = falcon_i2c_bit_read,
155876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.write          = falcon_i2c_bit_write,
155976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
156076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
156176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
156276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
156376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
156476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
156576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * MDIO access
156676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
156776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
156876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
156976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
157076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
157176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_gmii_wait ( struct efab_nic *efab )
157276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
157376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t md_stat;
157476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int count;
157576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
157676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* wait upto 10ms */
157776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for (count = 0; count < 1000; count++) {
157876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_readl ( efab, &md_stat, FCN_MD_STAT_REG_KER );
157976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( EFAB_DWORD_FIELD ( md_stat, FCN_MD_BSY ) == 0 ) {
158076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			if ( EFAB_DWORD_FIELD ( md_stat, FCN_MD_LNFL ) != 0 ||
158176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			     EFAB_DWORD_FIELD ( md_stat, FCN_MD_BSERR ) != 0 ) {
158276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				EFAB_ERR ( "Error from GMII access "
158376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					   EFAB_DWORD_FMT"\n",
158476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					   EFAB_DWORD_VAL ( md_stat ));
158576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				return -EIO;
158676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			}
158776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			return 0;
158876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
158976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		udelay(10);
159076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
159176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
159276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_ERR ( "Timed out waiting for GMII\n" );
159376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return -ETIMEDOUT;
159476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
159576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
159676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
159776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_mdio_write ( struct efab_nic *efab, int device,
159876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    int location, int value )
159976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
160076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t reg;
160176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
160276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_TRACE ( "Writing GMII %d register %02x with %04x\n",
160376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     device, location, value );
160476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
160576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Check MII not currently being accessed */
160676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( falcon_gmii_wait ( efab ) )
160776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return;
160876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
160976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Write the address/ID register */
161076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_1 ( reg, FCN_MD_PHY_ADR, location );
161176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_MD_PHY_ADR_REG_KER );
161276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
161376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->phy_10g ) {
161476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* clause45 */
161576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_POPULATE_OWORD_2 ( reg,
161676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_PRT_ADR, efab->phy_addr,
161776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_DEV_ADR, device );
161876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
161976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else {
162076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* clause22 */
162176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		assert ( device == 0 );
162276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
162376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_POPULATE_OWORD_2 ( reg,
162476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_PRT_ADR, efab->phy_addr,
162576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_DEV_ADR, location );
162676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
162776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_MD_ID_REG_KER );
162876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
162976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
163076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Write data */
163176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_1 ( reg, FCN_MD_TXD, value );
163276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_MD_TXD_REG_KER );
163376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
163476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_2 ( reg,
163576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_MD_WRC, 1,
163676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_MD_GC, ( efab->phy_10g ? 0 : 1 ) );
163776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_MD_CS_REG_KER );
163876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
163976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Wait for data to be written */
164076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( falcon_gmii_wait ( efab ) ) {
164176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Abort the write operation */
164276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_POPULATE_OWORD_2 ( reg,
164376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_WRC, 0,
164476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_GC, 1);
164576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_write ( efab, &reg, FCN_MD_CS_REG_KER );
164676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		udelay(10);
164776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
164876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
164976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
165076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
165176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_mdio_read ( struct efab_nic *efab, int device, int location )
165276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
165376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t reg;
165476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int value;
165576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
165676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Check MII not currently being accessed */
165776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( falcon_gmii_wait ( efab ) )
165876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return -1;
165976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
166076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->phy_10g ) {
166176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* clause45 */
166276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_POPULATE_OWORD_1 ( reg, FCN_MD_PHY_ADR, location );
166376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_write ( efab, &reg, FCN_MD_PHY_ADR_REG_KER );
166476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
166576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_POPULATE_OWORD_2 ( reg,
166676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_PRT_ADR, efab->phy_addr,
166776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_DEV_ADR, device );
166876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_write ( efab, &reg, FCN_MD_ID_REG_KER);
166976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
167076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* request data to be read */
167176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_POPULATE_OWORD_2 ( reg,
167276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_RDC, 1,
167376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_GC, 0 );
167476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
167576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else {
167676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* clause22 */
167776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		assert ( device == 0 );
167876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
167976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_POPULATE_OWORD_2 ( reg,
168076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_PRT_ADR, efab->phy_addr,
168176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_DEV_ADR, location );
168276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_write ( efab, &reg, FCN_MD_ID_REG_KER );
168376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
168476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Request data to be read */
168576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_POPULATE_OWORD_2 ( reg,
168676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_RIC, 1,
168776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_GC, 1 );
168876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
168976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
169076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_MD_CS_REG_KER );
169176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
169276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Wait for data to become available */
169376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( falcon_gmii_wait ( efab ) ) {
169476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Abort the read operation */
169576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_POPULATE_OWORD_2 ( reg,
169676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_RIC, 0,
169776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_MD_GC, 1 );
169876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_write ( efab, &reg, FCN_MD_CS_REG_KER );
169976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		udelay ( 10 );
170076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		value = -1;
170176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
170276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else {
170376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Read the data */
170476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_read ( efab, &reg, FCN_MD_RXD_REG_KER );
170576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		value = EFAB_OWORD_FIELD ( reg, FCN_MD_RXD );
170676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
170776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
170876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_TRACE ( "Read from GMII %d register %02x, got %04x\n",
170976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     device, location, value );
171076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
171176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return value;
171276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
171376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
171476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
171576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
171676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
171776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * MAC wrapper
171876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
171976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
172076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
172176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
172276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
172376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_reconfigure_mac_wrapper ( struct efab_nic *efab )
172476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
172576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t reg;
172676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int link_speed;
172776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
172876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->link_options & LPA_EF_10000 ) {
172976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		link_speed = 0x3;
173076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if ( efab->link_options & LPA_EF_1000 ) {
173176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		link_speed = 0x2;
173276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if ( efab->link_options & LPA_100 ) {
173376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		link_speed = 0x1;
173476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else {
173576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		link_speed = 0x0;
173676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
173776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_5 ( reg,
173876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_MAC_XOFF_VAL, 0xffff /* datasheet */,
173976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_MAC_BCAD_ACPT, 1,
174076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_MAC_UC_PROM, 0,
174176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_MAC_LINK_STATUS, 1,
174276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_MAC_SPEED, link_speed );
174376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
174476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_MAC0_CTRL_REG_KER );
174576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
174676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
174776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
174876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
174976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
175076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * GMAC handling
175176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
175276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
175376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
175476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
175576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC configuration register 1 */
175676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_CFG1_REG_MAC 0x00
175776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_SW_RST_LBN 31
175876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_SW_RST_WIDTH 1
175976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_RX_FC_EN_LBN 5
176076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_RX_FC_EN_WIDTH 1
176176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_TX_FC_EN_LBN 4
176276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_TX_FC_EN_WIDTH 1
176376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_RX_EN_LBN 2
176476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_RX_EN_WIDTH 1
176576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_TX_EN_LBN 0
176676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_TX_EN_WIDTH 1
176776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
176876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC configuration register 2 */
176976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_CFG2_REG_MAC 0x01
177076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_PAMBL_LEN_LBN 12
177176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_PAMBL_LEN_WIDTH 4
177276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_IF_MODE_LBN 8
177376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_IF_MODE_WIDTH 2
177476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_PAD_CRC_EN_LBN 2
177576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_PAD_CRC_EN_WIDTH 1
177676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_FD_LBN 0
177776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_FD_WIDTH 1
177876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
177976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC maximum frame length register */
178076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MAX_FLEN_REG_MAC 0x04
178176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MAX_FLEN_LBN 0
178276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MAX_FLEN_WIDTH 16
178376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
178476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC MII management configuration register */
178576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MII_MGMT_CFG_REG_MAC 0x08
178676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_CLK_SEL_LBN 0
178776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_CLK_SEL_WIDTH 3
178876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
178976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC MII management command register */
179076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MII_MGMT_CMD_REG_MAC 0x09
179176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_SCAN_CYC_LBN 1
179276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_SCAN_CYC_WIDTH 1
179376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_RD_CYC_LBN 0
179476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_RD_CYC_WIDTH 1
179576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
179676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC MII management address register */
179776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MII_MGMT_ADR_REG_MAC 0x0a
179876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_PHY_ADDR_LBN 8
179976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_PHY_ADDR_WIDTH 5
180076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_REG_ADDR_LBN 0
180176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_REG_ADDR_WIDTH 5
180276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
180376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC MII management control register */
180476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MII_MGMT_CTL_REG_MAC 0x0b
180576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_CTL_LBN 0
180676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_CTL_WIDTH 16
180776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
180876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC MII management status register */
180976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MII_MGMT_STAT_REG_MAC 0x0c
181076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_STAT_LBN 0
181176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_STAT_WIDTH 16
181276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
181376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC MII management indicators register */
181476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MII_MGMT_IND_REG_MAC 0x0d
181576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_BUSY_LBN 0
181676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_MGMT_BUSY_WIDTH 1
181776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
181876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC station address register 1 */
181976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_ADR1_REG_MAC 0x10
182076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_HWADDR_5_LBN 24
182176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_HWADDR_5_WIDTH 8
182276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_HWADDR_4_LBN 16
182376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_HWADDR_4_WIDTH 8
182476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_HWADDR_3_LBN 8
182576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_HWADDR_3_WIDTH 8
182676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_HWADDR_2_LBN 0
182776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_HWADDR_2_WIDTH 8
182876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
182976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC station address register 2 */
183076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_ADR2_REG_MAC 0x11
183176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_HWADDR_1_LBN 24
183276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_HWADDR_1_WIDTH 8
183376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_HWADDR_0_LBN 16
183476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GM_HWADDR_0_WIDTH 8
183576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
183676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC FIFO configuration register 0 */
183776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFG0_REG_MAC 0x12
183876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_FTFENREQ_LBN 12
183976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_FTFENREQ_WIDTH 1
184076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_STFENREQ_LBN 11
184176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_STFENREQ_WIDTH 1
184276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_FRFENREQ_LBN 10
184376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_FRFENREQ_WIDTH 1
184476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_SRFENREQ_LBN 9
184576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_SRFENREQ_WIDTH 1
184676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_WTMENREQ_LBN 8
184776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_WTMENREQ_WIDTH 1
184876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
184976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC FIFO configuration register 1 */
185076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFG1_REG_MAC 0x13
185176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGFRTH_LBN 16
185276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGFRTH_WIDTH 5
185376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGXOFFRTX_LBN 0
185476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGXOFFRTX_WIDTH 16
185576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
185676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC FIFO configuration register 2 */
185776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFG2_REG_MAC 0x14
185876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGHWM_LBN 16
185976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGHWM_WIDTH 6
186076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGLWM_LBN 0
186176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGLWM_WIDTH 6
186276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
186376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC FIFO configuration register 3 */
186476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFG3_REG_MAC 0x15
186576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGHWMFT_LBN 16
186676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGHWMFT_WIDTH 6
186776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGFTTH_LBN 0
186876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGFTTH_WIDTH 6
186976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
187076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC FIFO configuration register 4 */
187176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFG4_REG_MAC 0x16
187276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_HSTFLTRFRM_PAUSE_LBN 12
187376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_HSTFLTRFRM_PAUSE_WIDTH 12
187476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
187576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* GMAC FIFO configuration register 5 */
187676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFG5_REG_MAC 0x17
187776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGHDPLX_LBN 22
187876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGHDPLX_WIDTH 1
187976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGBYTMODE_LBN 19
188076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_CFGBYTMODE_WIDTH 1
188176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_HSTDRPLT64_LBN 18
188276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_HSTDRPLT64_WIDTH 1
188376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_HSTFLTRFRMDC_PAUSE_LBN 12
188476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define GMF_HSTFLTRFRMDC_PAUSE_WIDTH 1
188576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
188676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
188776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_gmac_writel ( struct efab_nic *efab, efab_dword_t *value,
188876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     unsigned int mac_reg )
188976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
189076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t temp;
189176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
189276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_1 ( temp, FCN_MAC_DATA,
189376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				EFAB_DWORD_FIELD ( *value, FCN_MAC_DATA ) );
189476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &temp, FALCON_GMAC_REG ( efab, mac_reg ) );
189576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
189676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
189776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
189876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_gmac_readl ( struct efab_nic *efab, efab_dword_t *value,
189976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    unsigned int mac_reg )
190076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
190176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t temp;
190276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
190376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &temp, FALCON_GMAC_REG ( efab, mac_reg ) );
190476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_1 ( *value, FCN_MAC_DATA,
190576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				EFAB_OWORD_FIELD ( temp, FCN_MAC_DATA ) );
190676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
190776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
190876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
190976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanmentormac_reset ( struct efab_nic *efab )
191076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
191176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t reg;
191276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
191376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Take into reset */
191476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_1 ( reg, GM_SW_RST, 1 );
191576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_writel ( efab, &reg, GM_CFG1_REG_MAC );
191676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 1000 );
191776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
191876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Take out of reset */
191976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_1 ( reg, GM_SW_RST, 0 );
192076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_writel ( efab, &reg, GM_CFG1_REG_MAC );
192176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 1000 );
192276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
192376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Configure GMII interface so PHY is accessible.  Note that
192476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * GMII interface is connected only to port 0, and that on
192576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Falcon this is a no-op.
192676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
192776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_1 ( reg, GM_MGMT_CLK_SEL, 0x4 );
192876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_writel ( efab, &reg, GM_MII_MGMT_CFG_REG_MAC );
192976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 10 );
193076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
193176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
193276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
193376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanmentormac_init ( struct efab_nic *efab )
193476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
193576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int pause, if_mode, full_duplex, bytemode, half_duplex;
193676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t reg;
193776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
193876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Configuration register 1 */
193976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pause = ( efab->link_options & LPA_PAUSE_CAP ) ? 1 : 0;
194076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ! ( efab->link_options & LPA_EF_DUPLEX ) ) {
194176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Half-duplex operation requires TX flow control */
194276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pause = 1;
194376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
194476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_4 ( reg,
194576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GM_TX_EN, 1,
194676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GM_TX_FC_EN, pause,
194776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GM_RX_EN, 1,
194876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GM_RX_FC_EN, 1 );
194976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_writel ( efab, &reg, GM_CFG1_REG_MAC );
195076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 10 );
195176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
195276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Configuration register 2 */
195376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if_mode = ( efab->link_options & LPA_EF_1000 ) ? 2 : 1;
195476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	full_duplex = ( efab->link_options & LPA_EF_DUPLEX ) ? 1 : 0;
195576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_4 ( reg,
195676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GM_IF_MODE, if_mode,
195776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GM_PAD_CRC_EN, 1,
195876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GM_FD, full_duplex,
195976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GM_PAMBL_LEN, 0x7 /* ? */ );
196076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_writel ( efab, &reg, GM_CFG2_REG_MAC );
196176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 10 );
196276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
196376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Max frame len register */
196476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_1 ( reg, GM_MAX_FLEN,
196576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				EFAB_MAX_FRAME_LEN ( ETH_FRAME_LEN ) );
196676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_writel ( efab, &reg, GM_MAX_FLEN_REG_MAC );
196776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 10 );
196876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
196976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* FIFO configuration register 0 */
197076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_5 ( reg,
197176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GMF_FTFENREQ, 1,
197276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GMF_STFENREQ, 1,
197376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GMF_FRFENREQ, 1,
197476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GMF_SRFENREQ, 1,
197576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GMF_WTMENREQ, 1 );
197676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_writel ( efab, &reg, GMF_CFG0_REG_MAC );
197776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 10 );
197876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
197976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* FIFO configuration register 1 */
198076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_2 ( reg,
198176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GMF_CFGFRTH, 0x12,
198276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GMF_CFGXOFFRTX, 0xffff );
198376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_writel ( efab, &reg, GMF_CFG1_REG_MAC );
198476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 10 );
198576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
198676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* FIFO configuration register 2 */
198776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_2 ( reg,
198876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GMF_CFGHWM, 0x3f,
198976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GMF_CFGLWM, 0xa );
199076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_writel ( efab, &reg, GMF_CFG2_REG_MAC );
199176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 10 );
199276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
199376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* FIFO configuration register 3 */
199476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_2 ( reg,
199576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GMF_CFGHWMFT, 0x1c,
199676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GMF_CFGFTTH, 0x08 );
199776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_writel ( efab, &reg, GMF_CFG3_REG_MAC );
199876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 10 );
199976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
200076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* FIFO configuration register 4 */
200176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_1 ( reg, GMF_HSTFLTRFRM_PAUSE, 1 );
200276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_writel ( efab, &reg, GMF_CFG4_REG_MAC );
200376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 10 );
200476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
200576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* FIFO configuration register 5 */
200676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	bytemode = ( efab->link_options & LPA_EF_1000 ) ? 1 : 0;
200776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	half_duplex = ( efab->link_options & LPA_EF_DUPLEX ) ? 0 : 1;
200876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_readl ( efab, &reg, GMF_CFG5_REG_MAC );
200976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( reg, GMF_CFGBYTMODE, bytemode );
201076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( reg, GMF_CFGHDPLX, half_duplex );
201176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( reg, GMF_HSTDRPLT64, half_duplex );
201276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( reg, GMF_HSTFLTRFRMDC_PAUSE, 0 );
201376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_writel ( efab, &reg, GMF_CFG5_REG_MAC );
201476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 10 );
201576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
201676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* MAC address */
201776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_4 ( reg,
201876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GM_HWADDR_5, efab->mac_addr[5],
201976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GM_HWADDR_4, efab->mac_addr[4],
202076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GM_HWADDR_3, efab->mac_addr[3],
202176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GM_HWADDR_2, efab->mac_addr[2] );
202276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_writel ( efab, &reg, GM_ADR1_REG_MAC );
202376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 10 );
202476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_2 ( reg,
202576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GM_HWADDR_1, efab->mac_addr[1],
202676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				GM_HWADDR_0, efab->mac_addr[0] );
202776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_gmac_writel ( efab, &reg, GM_ADR2_REG_MAC );
202876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 10 );
202976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
203076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
203176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
203276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_init_gmac ( struct efab_nic *efab )
203376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
203476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Reset the MAC */
203576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	mentormac_reset ( efab );
203676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
203776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Initialise PHY */
203876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->phy_op->init ( efab );
203976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
204076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* check the link is up */
204176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( !efab->link_up )
204276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return -EAGAIN;
204376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
204476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Initialise MAC */
204576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	mentormac_init ( efab );
204676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
204776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* reconfigure the MAC wrapper */
204876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_reconfigure_mac_wrapper ( efab );
204976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
205076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
205176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
205276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
205376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct efab_mac_operations falcon_gmac_operations = {
205476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.init                   = falcon_init_gmac,
205576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
205676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
205776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
205876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
205976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
206076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
206176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * XMAC handling
206276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
206376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
206476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
206576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
206676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
206776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Write dword to a Falcon XMAC register
206876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
206976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
207076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
207176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_xmac_writel ( struct efab_nic *efab, efab_dword_t *value,
207276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     unsigned int mac_reg )
207376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
207476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t temp;
207576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
207676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_1 ( temp, FCN_MAC_DATA,
207776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				EFAB_DWORD_FIELD ( *value, FCN_MAC_DATA ) );
207876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &temp,
207976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       FALCON_XMAC_REG ( efab, mac_reg ) );
208076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
208176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
208276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
208376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Read dword from a Falcon XMAC register
208476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
208576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
208676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
208776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_xmac_readl ( struct efab_nic *efab, efab_dword_t *value,
208876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    unsigned int mac_reg )
208976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
209076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t temp;
209176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
209276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &temp,
209376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		      FALCON_XMAC_REG ( efab, mac_reg ) );
209476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_1 ( *value, FCN_MAC_DATA,
209576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				EFAB_OWORD_FIELD ( temp, FCN_MAC_DATA ) );
209676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
209776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
209876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
209976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Configure Falcon XAUI output
210076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
210176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
210276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_setup_xaui ( struct efab_nic *efab )
210376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
210476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t sdctl, txdrv;
210576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
210676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_readl ( efab, &sdctl, FCN_XX_SD_CTL_REG_MAC );
210776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_HIDRVD, XX_SD_CTL_DRV_DEFAULT );
210876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_LODRVD, XX_SD_CTL_DRV_DEFAULT );
210976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_HIDRVC, XX_SD_CTL_DRV_DEFAULT );
211076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_LODRVC, XX_SD_CTL_DRV_DEFAULT );
211176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_HIDRVB, XX_SD_CTL_DRV_DEFAULT );
211276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_LODRVB, XX_SD_CTL_DRV_DEFAULT );
211376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_HIDRVA, XX_SD_CTL_DRV_DEFAULT );
211476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( sdctl, FCN_XX_LODRVA, XX_SD_CTL_DRV_DEFAULT );
211576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_writel ( efab, &sdctl, FCN_XX_SD_CTL_REG_MAC );
211676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
211776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_8 ( txdrv,
211876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_DEQD, XX_TXDRV_DEQ_DEFAULT,
211976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_DEQC, XX_TXDRV_DEQ_DEFAULT,
212076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_DEQB, XX_TXDRV_DEQ_DEFAULT,
212176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_DEQA, XX_TXDRV_DEQ_DEFAULT,
212276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_DTXD, XX_TXDRV_DTX_DEFAULT,
212376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_DTXC, XX_TXDRV_DTX_DEFAULT,
212476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_DTXB, XX_TXDRV_DTX_DEFAULT,
212576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_DTXA, XX_TXDRV_DTX_DEFAULT);
212676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_writel ( efab, &txdrv, FCN_XX_TXDRV_CTL_REG_MAC);
212776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
212876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
212976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
213076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_xgmii_status ( struct efab_nic *efab )
213176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
213276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t reg;
213376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
213476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->pci_revision  < FALCON_REV_B0 )
213576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return 1;
213676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* The ISR latches, so clear it and re-read */
213776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_readl ( efab, &reg, FCN_XM_MGT_INT_REG_MAC_B0 );
213876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_readl ( efab, &reg, FCN_XM_MGT_INT_REG_MAC_B0 );
213976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
214076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( EFAB_DWORD_FIELD ( reg, FCN_XM_LCLFLT ) ||
214176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     EFAB_DWORD_FIELD ( reg, FCN_XM_RMTFLT ) ) {
214276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_TRACE ( "MGT_INT: "EFAB_DWORD_FMT"\n",
214376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			     EFAB_DWORD_VAL ( reg ) );
214476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return 0;
214576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
214676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
214776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 1;
214876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
214976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
215076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
215176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_mask_status_intr ( struct efab_nic *efab, int enable )
215276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
215376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t reg;
215476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
215576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->pci_revision  < FALCON_REV_B0 )
215676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return;
215776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
215876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Flush the ISR */
215976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( enable )
216076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_xmac_readl ( efab, &reg, FCN_XM_MGT_INT_REG_MAC_B0 );
216176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
216276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_2 ( reg,
216376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_MSK_RMTFLT, !enable,
216476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_MSK_LCLFLT, !enable);
216576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_readl ( efab, &reg, FCN_XM_MGT_INT_MSK_REG_MAC_B0 );
216676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
216776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
216876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
216976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Reset 10G MAC connected to port
217076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
217176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
217276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
217376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_reset_xmac ( struct efab_nic *efab )
217476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
217576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t reg;
217676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int count;
217776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
217876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_1 ( reg, FCN_XM_CORE_RST, 1 );
217976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_writel ( efab, &reg, FCN_XM_GLB_CFG_REG_MAC );
218076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
218176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for ( count = 0 ; count < 1000 ; count++ ) {
218276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		udelay ( 10 );
218376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_xmac_readl ( efab, &reg,
218476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				    FCN_XM_GLB_CFG_REG_MAC );
218576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( EFAB_DWORD_FIELD ( reg, FCN_XM_CORE_RST ) == 0 )
218676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			return 0;
218776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
218876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return -ETIMEDOUT;
218976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
219076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
219176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
219276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
219376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_reset_xaui ( struct efab_nic *efab )
219476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
219576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t reg;
219676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int count;
219776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
219876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (!efab->is_asic)
219976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return 0;
220076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
220176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_1 ( reg, FCN_XX_RST_XX_EN, 1 );
220276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_writel ( efab, &reg, FCN_XX_PWR_RST_REG_MAC );
220376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
220476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Give some time for the link to establish */
220576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for (count = 0; count < 1000; count++) { /* wait upto 10ms */
220676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_xmac_readl ( efab, &reg, FCN_XX_PWR_RST_REG_MAC );
220776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( EFAB_DWORD_FIELD ( reg, FCN_XX_RST_XX_EN ) == 0 ) {
220876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			falcon_setup_xaui ( efab );
220976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			return 0;
221076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
221176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		udelay(10);
221276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
221376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_ERR ( "timed out waiting for XAUI/XGXS reset\n" );
221476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return -ETIMEDOUT;
221576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
221676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
221776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
221876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_xaui_link_ok ( struct efab_nic *efab )
221976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
222076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t reg;
222176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int align_done, lane_status, sync;
222276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int has_phyxs;
222376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int link_ok = 1;
222476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
222576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Read Falcon XAUI side */
222676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->is_asic ) {
222776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Read link status */
222876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_xmac_readl ( efab, &reg, FCN_XX_CORE_STAT_REG_MAC );
222976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		align_done = EFAB_DWORD_FIELD ( reg, FCN_XX_ALIGN_DONE );
223076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
223176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		sync = EFAB_DWORD_FIELD ( reg, FCN_XX_SYNC_STAT );
223276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		sync = ( sync == FCN_XX_SYNC_STAT_DECODE_SYNCED );
223376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
223476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		link_ok = align_done && sync;
223576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
223676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
223776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Clear link status ready for next read */
223876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( reg, FCN_XX_COMMA_DET, FCN_XX_COMMA_DET_RESET );
223976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( reg, FCN_XX_CHARERR, FCN_XX_CHARERR_RESET);
224076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_DWORD_FIELD ( reg, FCN_XX_DISPERR, FCN_XX_DISPERR_RESET);
224176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_writel ( efab, &reg, FCN_XX_CORE_STAT_REG_MAC );
224276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
224376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	has_phyxs = ( efab->phy_op->mmds & ( 1 << MDIO_MMD_PHYXS ) );
224476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( link_ok && has_phyxs ) {
224576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		lane_status = falcon_mdio_read ( efab, MDIO_MMD_PHYXS,
224676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman						 MDIO_PHYXS_LANE_STATE );
224776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		link_ok = ( lane_status & ( 1 << MDIO_PHYXS_LANE_ALIGNED_LBN ) );
224876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
224976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (!link_ok )
225076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			EFAB_LOG ( "XGXS lane status: %x\n", lane_status );
225176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
225276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
225376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return link_ok;
225476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
225576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
225676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
225776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Initialise XMAC
225876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
225976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
226076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
226176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_reconfigure_xmac ( struct efab_nic *efab )
226276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
226376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t reg;
226476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int max_frame_len;
226576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
226676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Configure MAC - cut-thru mode is hard wired on */
226776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_3 ( reg,
226876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_RX_JUMBO_MODE, 1,
226976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_TX_STAT_EN, 1,
227076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_RX_STAT_EN, 1);
227176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_writel ( efab, &reg, FCN_XM_GLB_CFG_REG_MAC );
227276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
227376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Configure TX */
227476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_6 ( reg,
227576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_TXEN, 1,
227676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_TX_PRMBL, 1,
227776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_AUTO_PAD, 1,
227876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_TXCRC, 1,
227976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_FCNTL, 1,
228076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_IPG, 0x3 );
228176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_writel ( efab, &reg, FCN_XM_TX_CFG_REG_MAC );
228276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
228376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Configure RX */
228476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_4 ( reg,
228576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_RXEN, 1,
228676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_AUTO_DEPAD, 0,
228776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_ACPT_ALL_MCAST, 1,
228876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_PASS_CRC_ERR, 1 );
228976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_writel ( efab, &reg, FCN_XM_RX_CFG_REG_MAC );
229076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
229176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Set frame length */
229276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	max_frame_len = EFAB_MAX_FRAME_LEN ( ETH_FRAME_LEN );
229376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_1 ( reg,
229476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_MAX_RX_FRM_SIZE, max_frame_len );
229576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_writel ( efab, &reg, FCN_XM_RX_PARAM_REG_MAC );
229676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_2 ( reg,
229776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_MAX_TX_FRM_SIZE, max_frame_len,
229876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_TX_JUMBO_MODE, 1 );
229976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_writel ( efab, &reg, FCN_XM_TX_PARAM_REG_MAC );
230076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
230176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Enable flow control receipt */
230276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_2 ( reg,
230376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_PAUSE_TIME, 0xfffe,
230476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_DIS_FCNTL, 0 );
230576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_writel ( efab, &reg, FCN_XM_FC_REG_MAC );
230676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
230776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Set MAC address */
230876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_4 ( reg,
230976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_ADR_0, efab->mac_addr[0],
231076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_ADR_1, efab->mac_addr[1],
231176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_ADR_2, efab->mac_addr[2],
231276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_ADR_3, efab->mac_addr[3] );
231376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_writel ( efab, &reg, FCN_XM_ADR_LO_REG_MAC );
231476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_2 ( reg,
231576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_ADR_4, efab->mac_addr[4],
231676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XM_ADR_5, efab->mac_addr[5] );
231776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_writel ( efab, &reg, FCN_XM_ADR_HI_REG_MAC );
231876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
231976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
232076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
232176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_init_xmac ( struct efab_nic *efab )
232276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
232376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int count, rc;
232476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
232576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Mask the PHY management interrupt */
232676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_mask_status_intr ( efab, 0 );
232776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
232876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Initialise the PHY to instantiate the clock. */
232976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = efab->phy_op->init ( efab );
233076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc ) {
233176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_ERR ( "unable to initialise PHY\n" );
233276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail1;
233376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
233476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
233576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_reset_xaui ( efab );
233676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
233776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Give the PHY and MAC time to faff */
233876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	mdelay ( 100 );
233976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
234076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Reset and reconfigure the XMAC */
234176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = falcon_reset_xmac ( efab );
234276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
234376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail2;
234476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_reconfigure_xmac ( efab );
234576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_reconfigure_mac_wrapper ( efab );
234676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/**
234776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Now wait for the link to come up. This may take a while
234876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * for some slower PHY's.
234976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
235076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for (count=0; count<50; count++) {
235176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		int link_ok = 1;
235276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
235376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Wait a while for the link to come up. */
235476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mdelay ( 100 );
235576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ((count % 5) == 0)
235676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			putchar ( '.' );
235776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
235876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Does the PHY think the wire-side link is up? */
235976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		link_ok = mdio_clause45_links_ok ( efab );
236076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Ensure the XAUI link to the PHY is good */
236176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( link_ok ) {
236276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			link_ok = falcon_xaui_link_ok ( efab );
236376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			if ( !link_ok )
236476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				falcon_reset_xaui ( efab );
236576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
236676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
236776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Check fault indication */
236876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( link_ok )
236976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			link_ok = falcon_xgmii_status ( efab );
237076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
237176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->link_up = link_ok;
237276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( link_ok ) {
237376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			/* unmask the status interrupt */
237476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			falcon_mask_status_intr ( efab, 1 );
237576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			return 0;
237676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
237776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
237876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
237976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Link failed to come up, but initialisation was fine. */
238076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = -ETIMEDOUT;
238176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
238276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail2:
238376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail1:
238476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return rc;
238576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
238676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
238776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct efab_mac_operations falcon_xmac_operations = {
238876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.init                   = falcon_init_xmac,
238976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
239076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
239176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
239276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
239376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
239476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Null PHY handling
239576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
239676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
239776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
239876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
239976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
240076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_xaui_phy_init ( struct efab_nic *efab )
240176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
240276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* CX4 is always 10000FD only */
240376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->link_options = LPA_EF_10000FULL;
240476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
240576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* There is no PHY! */
240676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
240776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
240876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
240976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct efab_phy_operations falcon_xaui_phy_ops = {
241076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.init                   = falcon_xaui_phy_init,
241176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.mmds                   = 0,
241276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
241376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
241476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
241576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
241676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
241776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
241876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Alaska PHY
241976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
242076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
242176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
242276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
242376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
242476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Initialise Alaska PHY
242576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
242676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
242776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
242876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanalaska_init ( struct efab_nic *efab )
242976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
243076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int advertised, lpa;
243176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
243276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Read link up status */
243376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->link_up = gmii_link_ok ( efab );
243476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
243576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ! efab->link_up )
243676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return -EIO;
243776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
243876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Determine link options from PHY. */
243976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	advertised = gmii_autoneg_advertised ( efab );
244076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	lpa = gmii_autoneg_lpa ( efab );
244176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->link_options = gmii_nway_result ( advertised & lpa );
244276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
244376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
244476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
244576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
244676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct efab_phy_operations falcon_alaska_phy_ops = {
244776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.init  	    	= alaska_init,
244876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
244976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
245076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
245176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
245276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
245376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * xfp
245476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
245576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
245676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
245776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
245876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define XFP_REQUIRED_DEVS ( MDIO_MMDREG_DEVS0_PCS    |		\
245976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    MDIO_MMDREG_DEVS0_PMAPMD |		\
246076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    MDIO_MMDREG_DEVS0_PHYXS )
246176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
246276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
246376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_xfp_phy_init ( struct efab_nic *efab )
246476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
246576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int rc;
246676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
246776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Optical link is always 10000FD only */
246876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->link_options = LPA_EF_10000FULL;
246976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
247076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Reset the PHY */
247176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = mdio_clause45_reset_mmd ( efab, MDIO_MMD_PHYXS );
247276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
247376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return rc;
247476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
247576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
247676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
247776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
247876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct efab_phy_operations falcon_xfp_phy_ops = {
247976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.init                   = falcon_xfp_phy_init,
248076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.mmds                   = XFP_REQUIRED_DEVS,
248176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
248276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
248376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
248476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
248576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
248676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * txc43128
248776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
248876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
248976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
249076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
249176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Command register */
249276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_GLRGS_GLCMD		(0xc004)
249376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_GLCMD_LMTSWRST_LBN	(14)
249476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
249576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Amplitude on lanes 0+1, 2+3 */
249676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define  TXC_ALRGS_ATXAMP0	(0xc041)
249776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define  TXC_ALRGS_ATXAMP1	(0xc042)
249876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Bit position of value for lane 0+2, 1+3 */
249976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_ATXAMP_LANE02_LBN	(3)
250076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_ATXAMP_LANE13_LBN	(11)
250176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
250276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_ATXAMP_1280_mV	(0)
250376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_ATXAMP_1200_mV	(8)
250476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_ATXAMP_1120_mV	(12)
250576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_ATXAMP_1060_mV	(14)
250676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_ATXAMP_0820_mV	(25)
250776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_ATXAMP_0720_mV	(26)
250876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_ATXAMP_0580_mV	(27)
250976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_ATXAMP_0440_mV	(28)
251076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
251176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_ATXAMP_0820_BOTH	( (TXC_ATXAMP_0820_mV << TXC_ATXAMP_LANE02_LBN) | \
251276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				  (TXC_ATXAMP_0820_mV << TXC_ATXAMP_LANE13_LBN) )
251376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
251476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_ATXAMP_DEFAULT	(0x6060) /* From databook */
251576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
251676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Preemphasis on lanes 0+1, 2+3 */
251776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define  TXC_ALRGS_ATXPRE0	(0xc043)
251876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define  TXC_ALRGS_ATXPRE1	(0xc044)
251976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
252076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_ATXPRE_NONE (0)
252176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_ATXPRE_DEFAULT	(0x1010) /* From databook */
252276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
252376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TXC_REQUIRED_DEVS ( MDIO_MMDREG_DEVS0_PCS    |	       \
252476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    MDIO_MMDREG_DEVS0_PMAPMD |	       \
252576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    MDIO_MMDREG_DEVS0_PHYXS )
252676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
252776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
252876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_txc_logic_reset ( struct efab_nic *efab )
252976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
253076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int val;
253176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int tries = 50;
253276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
253376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	val = falcon_mdio_read ( efab, MDIO_MMD_PCS, TXC_GLRGS_GLCMD );
253476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	val |= (1 << TXC_GLCMD_LMTSWRST_LBN);
253576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_mdio_write ( efab, MDIO_MMD_PCS, TXC_GLRGS_GLCMD, val );
253676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
253776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	while ( tries--) {
253876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		val = falcon_mdio_read ( efab, MDIO_MMD_PCS, TXC_GLRGS_GLCMD );
253976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( ~val & ( 1 << TXC_GLCMD_LMTSWRST_LBN ) )
254076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			return 0;
254176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		udelay(1);
254276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
254376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
254476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_ERR ( "logic reset failed\n" );
254576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
254676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return -ETIMEDOUT;
254776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
254876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
254976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
255076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_txc_phy_init ( struct efab_nic *efab )
255176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
255276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int rc;
255376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
255476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* CX4 is always 10000FD only */
255576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->link_options = LPA_EF_10000FULL;
255676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
255776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* reset the phy */
255876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = mdio_clause45_reset_mmd ( efab, MDIO_MMD_PMAPMD );
255976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
256076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail1;
256176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
256276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = mdio_clause45_check_mmds ( efab );
256376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
256476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail2;
256576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
256676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Turn amplitude down and preemphasis off on the host side
256776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * (PHY<->MAC) as this is believed less likely to upset falcon
256876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * and no adverse effects have been noted. It probably also
256976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * saves a picowatt or two */
257076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
257176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Turn off preemphasis */
257276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_mdio_write ( efab, MDIO_MMD_PHYXS, TXC_ALRGS_ATXPRE0,
257376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    TXC_ATXPRE_NONE );
257476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_mdio_write ( efab, MDIO_MMD_PHYXS, TXC_ALRGS_ATXPRE1,
257576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    TXC_ATXPRE_NONE );
257676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
257776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Turn down the amplitude */
257876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_mdio_write ( efab, MDIO_MMD_PHYXS, TXC_ALRGS_ATXAMP0,
257976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    TXC_ATXAMP_0820_BOTH );
258076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_mdio_write ( efab, MDIO_MMD_PHYXS, TXC_ALRGS_ATXAMP1,
258176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    TXC_ATXAMP_0820_BOTH );
258276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
258376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Set the line side amplitude and preemphasis to the databook
258476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * defaults as an erratum causes them to be 0 on at least some
258576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * PHY rev.s */
258676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_mdio_write ( efab, MDIO_MMD_PMAPMD, TXC_ALRGS_ATXPRE0,
258776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    TXC_ATXPRE_DEFAULT );
258876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_mdio_write ( efab, MDIO_MMD_PMAPMD, TXC_ALRGS_ATXPRE1,
258976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    TXC_ATXPRE_DEFAULT );
259076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_mdio_write ( efab, MDIO_MMD_PMAPMD, TXC_ALRGS_ATXAMP0,
259176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    TXC_ATXAMP_DEFAULT );
259276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_mdio_write ( efab, MDIO_MMD_PMAPMD, TXC_ALRGS_ATXAMP1,
259376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    TXC_ATXAMP_DEFAULT );
259476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
259576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = falcon_txc_logic_reset ( efab );
259676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
259776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail3;
259876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
259976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
260076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
260176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail3:
260276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail2:
260376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail1:
260476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return rc;
260576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
260676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
260776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct efab_phy_operations falcon_txc_phy_ops = {
260876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.init                   = falcon_txc_phy_init,
260976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.mmds                   = TXC_REQUIRED_DEVS,
261076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
261176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
261276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
261376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
261476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
261576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * tenxpress
261676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
261776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
261876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
261976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
262076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
262176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TENXPRESS_REQUIRED_DEVS ( MDIO_MMDREG_DEVS0_PMAPMD |	\
262276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				  MDIO_MMDREG_DEVS0_PCS    |	\
262376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				  MDIO_MMDREG_DEVS0_PHYXS )
262476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
262576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define	PCS_TEST_SELECT_REG 0xd807	/* PRM 10.5.8 */
262676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define	CLK312_EN_LBN 3
262776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define	CLK312_EN_WIDTH 1
262876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
262976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PCS_CLOCK_CTRL_REG 0xd801
263076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PLL312_RST_N_LBN 2
263176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
263276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Special Software reset register */
263376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMA_PMD_EXT_CTRL_REG 49152
263476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMA_PMD_EXT_SSR_LBN 15
263576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
263676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Boot status register */
263776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PCS_BOOT_STATUS_REG	0xd000
263876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PCS_BOOT_FATAL_ERR_LBN	0
263976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PCS_BOOT_PROGRESS_LBN	1
264076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PCS_BOOT_PROGRESS_WIDTH	2
264176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PCS_BOOT_COMPLETE_LBN	3
264276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
264376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PCS_SOFT_RST2_REG 0xd806
264476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define SERDES_RST_N_LBN 13
264576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define XGXS_RST_N_LBN 12
264676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
264776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
264876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_tenxpress_check_c11 ( struct efab_nic *efab )
264976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
265076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int count;
265176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t boot_stat;
265276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
265376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Check that the C11 CPU has booted */
265476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for (count=0; count<10; count++) {
265576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		boot_stat = falcon_mdio_read ( efab, MDIO_MMD_PCS,
265676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					       PCS_BOOT_STATUS_REG );
265776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( boot_stat & ( 1 << PCS_BOOT_COMPLETE_LBN ) )
265876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			return 0;
265976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
266076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		udelay(10);
266176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
266276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
266376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_ERR ( "C11 failed to boot\n" );
266476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return -ETIMEDOUT;
266576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
266676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
266776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
266876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_tenxpress_phy_init ( struct efab_nic *efab )
266976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
267076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int rc, reg;
267176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
267276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* 10XPRESS is always 10000FD (at the moment) */
267376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->link_options = LPA_EF_10000FULL;
267476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
267576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Wait for the blocks to come out of reset */
267676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = mdio_clause45_wait_reset_mmds ( efab );
267776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
267876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail1;
267976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
268076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = mdio_clause45_check_mmds ( efab );
268176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
268276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail2;
268376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
268476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Turn on the clock  */
268576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	reg = (1 << CLK312_EN_LBN);
268676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_mdio_write ( efab, MDIO_MMD_PCS, PCS_TEST_SELECT_REG, reg);
268776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
268876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Wait 200ms for the PHY to boot */
268976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	mdelay(200);
269076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
269176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = falcon_tenxpress_check_c11 ( efab );
269276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
269376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail3;
269476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
269576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
269676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
269776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail3:
269876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail2:
269976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail1:
270076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return rc;
270176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
270276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
270376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct efab_phy_operations falcon_tenxpress_phy_ops = {
270476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.init                   = falcon_tenxpress_phy_init,
270576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.mmds                   = TENXPRESS_REQUIRED_DEVS,
270676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
270776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
270876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
270976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
271076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
271176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * PM8358
271276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
271376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
271476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
271576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
271676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* The PM8358 just presents a DTE XS */
271776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PM8358_REQUIRED_DEVS (MDIO_MMDREG_DEVS0_DTEXS)
271876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
271976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* PHY-specific definitions */
272076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Master ID and Global Performance Monitor Update */
272176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMC_MASTER_REG (0xd000)
272276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Analog Tx Rx settings under software control */
272376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMC_MASTER_ANLG_CTRL (1<< 11)
272476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
272576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Master Configuration register 2 */
272676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMC_MCONF2_REG	(0xd002)
272776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Drive Tx off centre of data eye (1) vs. clock edge (0) */
272876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define	PMC_MCONF2_TEDGE (1 << 2)
272976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Drive Rx off centre of data eye (1) vs. clock edge (0) */
273076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMC_MCONF2_REDGE (1 << 3)
273176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
273276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Analog Rx settings */
273376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMC_ANALOG_RX_CFG0   (0xd025)
273476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMC_ANALOG_RX_CFG1   (0xd02d)
273576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMC_ANALOG_RX_CFG2   (0xd035)
273676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMC_ANALOG_RX_CFG3   (0xd03d)
273776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
273876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
273976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMC_ANALOG_RX_TERM     (1 << 15) /* Bit 15 of RX CFG: 0 for 100 ohms float,
274076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					    1 for 50 to 1.2V */
274176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMC_ANALOG_RX_EQ_MASK (3 << 8)
274276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMC_ANALOG_RX_EQ_NONE (0 << 8)
274376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMC_ANALOG_RX_EQ_HALF (1 << 8)
274476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMC_ANALOG_RX_EQ_FULL (2 << 8)
274576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PMC_ANALOG_RX_EQ_RSVD (3 << 8)
274676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
274776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
274876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_pm8358_phy_init ( struct efab_nic *efab )
274976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
275076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int rc, reg, i;
275176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
275276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* This is a XAUI retimer part */
275376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->link_options = LPA_EF_10000FULL;
275476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
275576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = mdio_clause45_reset_mmd ( efab, MDIO_MMDREG_DEVS0_DTEXS );
275676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
275776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return rc;
275876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
275976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Enable software control of analogue settings */
276076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	reg = falcon_mdio_read ( efab, MDIO_MMD_DTEXS,  PMC_MASTER_REG );
276176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	reg |= PMC_MASTER_ANLG_CTRL;
276276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_mdio_write ( efab, MDIO_MMD_DTEXS, PMC_MASTER_REG, reg );
276376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
276476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Turn rx eq on for all channels */
276576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for (i=0; i< 3; i++) {
276676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* The analog CFG registers are evenly spaced 8 apart */
276776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		uint16_t addr = PMC_ANALOG_RX_CFG0 + 8*i;
276876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		reg = falcon_mdio_read ( efab, MDIO_MMD_DTEXS, addr );
276976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		reg = ( reg & ~PMC_ANALOG_RX_EQ_MASK ) | PMC_ANALOG_RX_EQ_FULL;
277076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_mdio_write ( efab, MDIO_MMD_DTEXS, addr, reg );
277176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
277276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
277376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Set TEDGE, clear REDGE */
277476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	reg = falcon_mdio_read ( efab, MDIO_MMD_DTEXS, PMC_MCONF2_REG );
277576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	reg = ( reg & ~PMC_MCONF2_REDGE) | PMC_MCONF2_TEDGE;
277676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_mdio_write ( efab, MDIO_MMD_DTEXS, PMC_MCONF2_REG, reg );
277776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
277876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
277976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
278076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
278176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct efab_phy_operations falcon_pm8358_phy_ops = {
278276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.init                   = falcon_pm8358_phy_init,
278376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.mmds                   = PM8358_REQUIRED_DEVS,
278476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
278576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
278676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
278776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
278876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
278976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * SFE4001 support
279076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
279176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
279276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
279376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
279476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MAX_TEMP_THRESH 90
279576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
279676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* I2C Expander */
279776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PCA9539 0x74
279876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
279976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_IN 0x00
280076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_OUT 0x02
280176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_CONFIG 0x06
280276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
280376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_EN_1V0X_LBN 0
280476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_EN_1V0X_WIDTH 1
280576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_EN_1V2_LBN 1
280676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_EN_1V2_WIDTH 1
280776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_EN_2V5_LBN 2
280876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_EN_2V5_WIDTH 1
280976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_EN_3V3X_LBN 3
281076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_EN_3V3X_WIDTH 1
281176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_EN_5V_LBN 4
281276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_EN_5V_WIDTH 1
281376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_X_TRST_LBN 6
281476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P0_X_TRST_WIDTH 1
281576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
281676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P1_IN 0x01
281776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P1_CONFIG 0x07
281876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
281976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P1_AFE_PWD_LBN 0
282076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P1_AFE_PWD_WIDTH 1
282176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P1_DSP_PWD25_LBN 1
282276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P1_DSP_PWD25_WIDTH 1
282376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P1_SPARE_LBN 4
282476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define P1_SPARE_WIDTH 4
282576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
282676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Temperature Sensor */
282776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MAX6647	0x4e
282876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
282976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define RSL	0x02
283076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define RLHN	0x05
283176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define WLHO	0x0b
283276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
283376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct i2c_device i2c_pca9539 = {
283476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.dev_addr = PCA9539,
283576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.dev_addr_len = 1,
283676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.word_addr_len = 1,
283776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
283876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
283976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
284076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct i2c_device i2c_max6647 = {
284176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.dev_addr = MAX6647,
284276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.dev_addr_len = 1,
284376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.word_addr_len = 1,
284476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
284576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
284676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
284776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmansfe4001_init ( struct efab_nic *efab )
284876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
284976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct i2c_interface *i2c = &efab->i2c_bb.i2c;
285076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t reg;
285176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t in, cfg, out;
285276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int count, rc;
285376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
285476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_LOG ( "Initialise SFE4001 board\n" );
285576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
285676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Ensure XGXS and XAUI SerDes are held in reset */
285776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_7 ( reg,
285876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_PWRDNA_EN, 1,
285976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_PWRDNB_EN, 1,
286076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_RSTPLLAB_EN, 1,
286176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_RESETA_EN, 1,
286276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_RESETB_EN, 1,
286376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_RSTXGXSRX_EN, 1,
286476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_XX_RSTXGXSTX_EN, 1 );
286576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_xmac_writel ( efab, &reg, FCN_XX_PWR_RST_REG_MAC);
286676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay(10);
286776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
286876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Set DSP over-temperature alert threshold */
286976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cfg = MAX_TEMP_THRESH;
287076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = i2c->write ( i2c, &i2c_max6647, WLHO, &cfg, EFAB_BYTE );
287176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
287276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail1;
287376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
287476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Read it back and verify */
287576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = i2c->read ( i2c, &i2c_max6647, RLHN, &in, EFAB_BYTE );
287676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
287776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail2;
287876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
287976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( in != MAX_TEMP_THRESH ) {
288076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_ERR ( "Unable to verify MAX6647 limit (requested=%d "
288176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			   "confirmed=%d)\n", cfg, in );
288276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rc = -EIO;
288376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail3;
288476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
288576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
288676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Clear any previous over-temperature alert */
288776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = i2c->read ( i2c, &i2c_max6647, RSL, &in, EFAB_BYTE );
288876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
288976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail4;
289076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
289176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Enable port 0 and 1 outputs on IO expander */
289276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cfg = 0x00;
289376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = i2c->write ( i2c, &i2c_pca9539, P0_CONFIG, &cfg, EFAB_BYTE );
289476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
289576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail5;
289676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cfg = 0xff & ~(1 << P1_SPARE_LBN);
289776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = i2c->write ( i2c, &i2c_pca9539, P1_CONFIG, &cfg, EFAB_BYTE );
289876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
289976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail6;
290076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
290176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Turn all power off then wait 1 sec. This ensures PHY is reset */
290276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) |
290376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) |
290476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       (0 << P0_EN_1V0X_LBN));
290576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
290676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = i2c->write ( i2c, &i2c_pca9539, P0_OUT, &out, EFAB_BYTE );
290776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
290876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail7;
290976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
291076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	mdelay(1000);
291176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
291276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for (count=0; count<20; count++) {
291376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Turn on 1.2V, 2.5V, 3.3V and 5V power rails */
291476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		out = 0xff & ~( (1 << P0_EN_1V2_LBN)  | (1 << P0_EN_2V5_LBN) |
291576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				(1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN)  |
291676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				(1 << P0_X_TRST_LBN) );
291776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
291876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rc = i2c->write ( i2c, &i2c_pca9539, P0_OUT, &out, EFAB_BYTE );
291976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( rc )
292076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			goto fail8;
292176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
292276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mdelay ( 10 );
292376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
292476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Turn on the 1V power rail */
292576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		out  &= ~( 1 << P0_EN_1V0X_LBN );
292676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rc = i2c->write ( i2c, &i2c_pca9539, P0_OUT, &out, EFAB_BYTE );
292776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( rc )
292876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			goto fail9;
292976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
293076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_LOG ( "Waiting for power...(attempt %d)\n", count);
293176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mdelay ( 1000 );
293276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
293376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Check DSP is powered */
293476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rc = i2c->read ( i2c, &i2c_pca9539, P1_IN, &in, EFAB_BYTE );
293576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( rc )
293676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			goto fail10;
293776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
293876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( in & ( 1 << P1_AFE_PWD_LBN ) )
293976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			return 0;
294076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
294176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
294276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = -ETIMEDOUT;
294376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
294476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail10:
294576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail9:
294676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail8:
294776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail7:
294876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Turn off power rails */
294976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	out = 0xff;
295076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	(void) i2c->write ( i2c, &i2c_pca9539, P0_OUT, &out, EFAB_BYTE );
295176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Disable port 1 outputs on IO expander */
295276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	out = 0xff;
295376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	(void) i2c->write ( i2c, &i2c_pca9539, P1_CONFIG, &out, EFAB_BYTE );
295476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail6:
295576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Disable port 0 outputs */
295676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	out = 0xff;
295776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	(void) i2c->write ( i2c, &i2c_pca9539, P1_CONFIG, &out, EFAB_BYTE );
295876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail5:
295976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail4:
296076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail3:
296176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail2:
296276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail1:
296376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_ERR ( "Failed initialising SFE4001 board\n" );
296476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return rc;
296576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
296676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
296776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
296876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmansfe4001_fini ( struct efab_nic *efab )
296976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
297076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct i2c_interface *i2c = &efab->i2c_bb.i2c;
297176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t in, cfg, out;
297276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
297376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_ERR ( "Turning off SFE4001\n" );
297476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
297576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Turn off all power rails */
297676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	out = 0xff;
297776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	(void) i2c->write ( i2c, &i2c_pca9539, P0_OUT, &out, EFAB_BYTE );
297876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
297976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Disable port 1 outputs on IO expander */
298076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cfg = 0xff;
298176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	(void) i2c->write ( i2c, &i2c_pca9539, P1_CONFIG, &cfg, EFAB_BYTE );
298276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
298376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Disable port 0 outputs on IO expander */
298476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cfg = 0xff;
298576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	(void) i2c->write ( i2c, &i2c_pca9539, P0_CONFIG, &cfg, EFAB_BYTE );
298676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
298776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Clear any over-temperature alert */
298876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	(void) i2c->read ( i2c, &i2c_max6647, RSL, &in, EFAB_BYTE );
298976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
299076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
299176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct efab_board_operations sfe4001_ops = {
299276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.init		= sfe4001_init,
299376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.fini		= sfe4001_fini,
299476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
299576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
299676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int sfe4002_init ( struct efab_nic *efab __attribute__((unused)) )
299776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
299876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
299976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
300076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void sfe4002_fini ( struct efab_nic *efab __attribute__((unused)) )
300176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
300276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
300376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
300476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct efab_board_operations sfe4002_ops = {
300576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.init		= sfe4002_init,
300676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.fini		= sfe4002_fini,
300776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
300876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
300976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int sfe4003_init ( struct efab_nic *efab __attribute__((unused)) )
301076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
301176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
301276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
301376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void sfe4003_fini ( struct efab_nic *efab __attribute__((unused)) )
301476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
301576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
301676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
301776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct efab_board_operations sfe4003_ops = {
301876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.init		= sfe4003_init,
301976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.fini		= sfe4003_fini,
302076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
302176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
302276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
302376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
302476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
302576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Hardware initialisation
302676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
302776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
302876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
302976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
303076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
303176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_free_special_buffer ( void *p )
303276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
303376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* We don't bother cleaning up the buffer table entries -
303476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * we're hardly limited */
303576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	free_dma ( p, EFAB_BUF_ALIGN );
303676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
303776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
303876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void*
303976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_alloc_special_buffer ( struct efab_nic *efab, int bytes,
304076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			      struct efab_special_buffer *entry )
304176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
304276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	void* buffer;
304376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int remaining;
304476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_qword_t buf_desc;
304576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned long dma_addr;
304676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
304776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Allocate the buffer, aligned on a buffer address boundary */
304876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	buffer = malloc_dma ( bytes, EFAB_BUF_ALIGN );
304976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ! buffer )
305076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return NULL;
305176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
305276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Push buffer table entries to back the buffer */
305376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	entry->id = efab->buffer_head;
305476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	entry->dma_addr = dma_addr = virt_to_bus ( buffer );
305576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	assert ( ( dma_addr & ( EFAB_BUF_ALIGN - 1 ) ) == 0 );
305676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
305776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	remaining = bytes;
305876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	while ( remaining > 0 ) {
305976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_POPULATE_QWORD_3 ( buf_desc,
306076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_IP_DAT_BUF_SIZE, FCN_IP_DAT_BUF_SIZE_4K,
306176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_BUF_ADR_FBUF, ( dma_addr >> 12 ),
306276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					FCN_BUF_OWNER_ID_FBUF, 0 );
306376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
306476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_write_sram ( efab, &buf_desc, efab->buffer_head );
306576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
306676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		++efab->buffer_head;
306776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		dma_addr += EFAB_BUF_ALIGN;
306876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		remaining -= EFAB_BUF_ALIGN;
306976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
307076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
307176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_TRACE ( "Allocated 0x%x bytes at %p backed by buffer table "
307276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     "entries 0x%x..0x%x\n", bytes, buffer, entry->id,
307376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     efab->buffer_head - 1 );
307476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
307576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return buffer;
307676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
307776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
307876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
307976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanclear_b0_fpga_memories ( struct efab_nic *efab)
308076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
308176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t blanko, temp;
308276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t blankd;
308376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int offset;
308476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
308576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_ZERO_OWORD ( blanko );
308676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_ZERO_DWORD ( blankd );
308776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
308876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Clear the address region register */
308976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_4 ( temp,
309076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_ADR_REGION0, 0,
309176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_ADR_REGION1, ( 1 << 16 ),
309276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_ADR_REGION2, ( 2 << 16 ),
309376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_ADR_REGION3, ( 3 << 16 ) );
309476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &temp, FCN_ADR_REGION_REG_KER );
309576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
309676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_TRACE ( "Clearing filter and RSS tables\n" );
309776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
309876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for ( offset = FCN_RX_FILTER_TBL0 ;
309976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	      offset < FCN_RX_RSS_INDIR_TBL_B0+0x800 ;
310076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	      offset += 0x10 ) {
310176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_write ( efab, &blanko, offset );
310276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
310376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
310476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_TRACE ( "Wiping buffer tables\n" );
310576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
310676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Notice the 8 byte access mode */
310776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for ( offset = 0x2800000 ;
310876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	      offset < 0x3000000 ;
310976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	      offset += 0x8) {
311076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		_falcon_writel ( efab, 0, offset );
311176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		_falcon_writel ( efab, 0, offset + 4 );
311276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		wmb();
311376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
311476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
311576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
311676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
311776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_reset ( struct efab_nic *efab )
311876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
311976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t glb_ctl_reg_ker;
312076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
312176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Initiate software reset */
312276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_6 ( glb_ctl_reg_ker,
312376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_PCIE_CORE_RST_CTL, EXCLUDE_FROM_RESET,
312476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_PCIE_NSTCK_RST_CTL, EXCLUDE_FROM_RESET,
312576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_PCIE_SD_RST_CTL, EXCLUDE_FROM_RESET,
312676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_EE_RST_CTL, EXCLUDE_FROM_RESET,
312776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_EXT_PHY_RST_DUR, 0x7, /* 10ms */
312876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_SWRST, 1 );
312976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
313076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &glb_ctl_reg_ker, FCN_GLB_CTL_REG_KER );
313176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
313276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Allow 50ms for reset */
313376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	mdelay ( 50 );
313476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
313576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Check for device reset complete */
313676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &glb_ctl_reg_ker, FCN_GLB_CTL_REG_KER );
313776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( EFAB_OWORD_FIELD ( glb_ctl_reg_ker, FCN_SWRST ) != 0 ) {
313876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_ERR ( "Reset failed\n" );
313976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return -ETIMEDOUT;
314076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
314176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
314276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ( efab->pci_revision == FALCON_REV_B0 ) && !efab->is_asic ) {
314376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		clear_b0_fpga_memories ( efab );
314476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
314576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
314676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
314776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
314876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
314976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Offset of MAC address within EEPROM or Flash */
315076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FALCON_MAC_ADDRESS_OFFSET 0x310
315176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
315276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
315376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Falcon EEPROM structure
315476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
315576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define SF_NV_CONFIG_BASE 0x300
315676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define SF_NV_CONFIG_EXTRA 0xA0
315776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
315876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct falcon_nv_config_ver2 {
315976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t nports;
316076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t  port0_phy_addr;
316176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t  port0_phy_type;
316276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t  port1_phy_addr;
316376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t  port1_phy_type;
316476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t asic_sub_revision;
316576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t board_revision;
316676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t mac_location;
316776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
316876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
316976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct falcon_nv_extra {
317076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t magicnumber;
317176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t structure_version;
317276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t checksum;
317376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	union {
317476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		struct falcon_nv_config_ver2 ver2;
317576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} ver_specific;
317676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
317776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
317876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define BOARD_TYPE(_rev) (_rev >> 8)
317976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
318076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
318176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_probe_nic_variant ( struct efab_nic *efab, struct pci_device *pci )
318276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
318376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t altera_build, nic_stat;
318476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int is_pcie, fpga_version;
318576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t revision;
318676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
318776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* PCI revision */
318876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pci_read_config_byte ( pci, PCI_CLASS_REVISION, &revision );
318976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->pci_revision = revision;
319076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
319176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Asic vs FPGA */
319276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &altera_build, FCN_ALTERA_BUILD_REG_KER );
319376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	fpga_version = EFAB_OWORD_FIELD ( altera_build, FCN_VER_ALL );
319476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->is_asic = (fpga_version == 0);
319576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
319676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* MAC and PCI type */
319776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &nic_stat, FCN_NIC_STAT_REG );
319876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->pci_revision == FALCON_REV_B0 ) {
319976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		is_pcie = 1;
320076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->phy_10g = EFAB_OWORD_FIELD ( nic_stat, FCN_STRAP_10G );
320176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
320276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else if ( efab->is_asic ) {
320376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		is_pcie = EFAB_OWORD_FIELD ( nic_stat, FCN_STRAP_PCIE );
320476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->phy_10g = EFAB_OWORD_FIELD ( nic_stat, FCN_STRAP_10G );
320576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
320676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else {
320776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		int minor = EFAB_OWORD_FIELD ( altera_build,  FCN_VER_MINOR );
320876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		is_pcie = 0;
320976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->phy_10g = ( minor == 0x14 );
321076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
321176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
321276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
321376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
321476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_init_spi_device ( struct efab_nic *efab, struct spi_device *spi )
321576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
321676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Falcon's SPI interface only supports reads/writes of up to 16 bytes.
321776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Reduce the nvs block size down to satisfy this - which means callers
321876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * should use the nvs_* functions rather than spi_*. */
321976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( spi->nvs.block_size > FALCON_SPI_MAX_LEN )
322076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		spi->nvs.block_size = FALCON_SPI_MAX_LEN;
322176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
322276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	spi->bus = &efab->spi_bus;
322376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->spi = spi;
322476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
322576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
322676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
322776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_probe_spi ( struct efab_nic *efab )
322876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
322976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t nic_stat, gpio_ctl, ee_vpd_cfg;
323076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int has_flash, has_eeprom, ad9bit;
323176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
323276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &nic_stat, FCN_NIC_STAT_REG );
323376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &gpio_ctl, FCN_GPIO_CTL_REG_KER );
323476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &ee_vpd_cfg, FCN_EE_VPD_CFG_REG );
323576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
323676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* determine if FLASH / EEPROM is present */
323776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ( efab->pci_revision >= FALCON_REV_B0 ) || efab->is_asic ) {
323876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		has_flash = EFAB_OWORD_FIELD ( nic_stat, FCN_SF_PRST );
323976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		has_eeprom = EFAB_OWORD_FIELD ( nic_stat, FCN_EE_PRST );
324076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else {
324176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		has_flash = EFAB_OWORD_FIELD ( gpio_ctl, FCN_FLASH_PRESENT );
324276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		has_eeprom = EFAB_OWORD_FIELD ( gpio_ctl, FCN_EEPROM_PRESENT );
324376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
324476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ad9bit = EFAB_OWORD_FIELD ( ee_vpd_cfg, FCN_EE_VPD_EN_AD9_MODE );
324576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
324676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Configure the SPI and I2C bus */
324776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->spi_bus.rw = falcon_spi_rw;
324876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	init_i2c_bit_basher ( &efab->i2c_bb, &falcon_i2c_bit_ops );
324976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
325076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Configure the EEPROM SPI device. Generally, an Atmel 25040
325176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * (or similar) is used, but this is only possible if there is also
325276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * a flash device present to store the boot-time chip configuration.
325376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
325476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( has_eeprom ) {
325576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( has_flash && ad9bit )
325676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			init_at25040 ( &efab->spi_eeprom );
325776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		else
325876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			init_mc25xx640 ( &efab->spi_eeprom );
325976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_init_spi_device ( efab, &efab->spi_eeprom );
326076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
326176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
326276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Configure the FLASH SPI device */
326376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( has_flash ) {
326476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		init_at25f1024 ( &efab->spi_flash );
326576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_init_spi_device ( efab, &efab->spi_flash );
326676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
326776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
326876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_LOG ( "flash is %s, EEPROM is %s%s\n",
326976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		   ( has_flash ? "present" : "absent" ),
327076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		   ( has_eeprom ? "present " : "absent" ),
327176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		   ( has_eeprom ? (ad9bit ? "(9bit)" : "(16bit)") : "") );
327276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
327376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* The device MUST have flash or eeprom */
327476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ! efab->spi ) {
327576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_ERR ( "Device appears to have no flash or eeprom\n" );
327676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return -EIO;
327776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
327876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
327976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* If the device has EEPROM attached, then advertise NVO space */
328076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( has_eeprom )
328176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		nvo_init ( &efab->nvo, &efab->spi_eeprom.nvs, falcon_nvo_fragments,
328276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			   &efab->netdev->refcnt );
328376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
328476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
328576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
328676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
328776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
328876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_probe_nvram ( struct efab_nic *efab )
328976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
329076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct nvs_device *nvs = &efab->spi->nvs;
329176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct falcon_nv_extra nv;
329276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int rc, board_revision;
329376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
329476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Read the MAC address */
329576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = nvs_read ( nvs, FALCON_MAC_ADDRESS_OFFSET,
329676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			efab->mac_addr, ETH_ALEN );
329776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
329876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return rc;
329976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
330076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Poke through the NVRAM structure for the PHY type. */
330176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = nvs_read ( nvs, SF_NV_CONFIG_BASE + SF_NV_CONFIG_EXTRA,
330276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			&nv, sizeof ( nv ) );
330376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
330476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return rc;
330576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
330676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Handle each supported NVRAM version */
330776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ( le16_to_cpu ( nv.magicnumber ) == FCN_NV_MAGIC_NUMBER ) &&
330876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     ( le16_to_cpu ( nv.structure_version ) >= 2 ) ) {
330976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		struct falcon_nv_config_ver2* ver2 = &nv.ver_specific.ver2;
331076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
331176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Get the PHY type */
331276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->phy_addr = le16_to_cpu ( ver2->port0_phy_addr );
331376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->phy_type = le16_to_cpu ( ver2->port0_phy_type );
331476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		board_revision = le16_to_cpu ( ver2->board_revision );
331576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
331676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else {
331776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_ERR ( "NVram is not recognised\n" );
331876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return -EINVAL;
331976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
332076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
332176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->board_type = BOARD_TYPE ( board_revision );
332276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
332376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_TRACE ( "Falcon board %d phy %d @ addr %d\n",
332476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     efab->board_type, efab->phy_type, efab->phy_addr );
332576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
332676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Patch in the board operations */
332776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	switch ( efab->board_type ) {
332876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case EFAB_BOARD_SFE4001:
332976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->board_op = &sfe4001_ops;
333076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
333176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case EFAB_BOARD_SFE4002:
333276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->board_op = &sfe4002_ops;
333376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
333476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case EFAB_BOARD_SFE4003:
333576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->board_op = &sfe4003_ops;
333676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
333776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	default:
333876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_ERR ( "Unrecognised board type\n" );
333976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return -EINVAL;
334076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
334176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
334276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Patch in MAC operations */
334376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->phy_10g )
334476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->mac_op = &falcon_xmac_operations;
334576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else
334676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->mac_op = &falcon_gmac_operations;
334776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
334876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Hook in the PHY ops */
334976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	switch ( efab->phy_type ) {
335076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case PHY_TYPE_10XPRESS:
335176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->phy_op = &falcon_tenxpress_phy_ops;
335276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
335376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case PHY_TYPE_CX4:
335476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->phy_op = &falcon_xaui_phy_ops;
335576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
335676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case PHY_TYPE_XFP:
335776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->phy_op = &falcon_xfp_phy_ops;
335876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
335976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case PHY_TYPE_CX4_RTMR:
336076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->phy_op = &falcon_txc_phy_ops;
336176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
336276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case PHY_TYPE_PM8358:
336376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->phy_op = &falcon_pm8358_phy_ops;
336476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
336576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case PHY_TYPE_1GIG_ALASKA:
336676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->phy_op = &falcon_alaska_phy_ops;
336776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
336876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	default:
336976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_ERR ( "Unknown PHY type: %d\n", efab->phy_type );
337076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return -EINVAL;
337176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
337276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
337376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
337476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
337576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
337676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
337776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_init_sram ( struct efab_nic *efab )
337876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
337976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t reg;
338076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int count;
338176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
338276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* use card in internal SRAM mode */
338376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &reg, FCN_NIC_STAT_REG );
338476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_OWORD_FIELD ( reg, FCN_ONCHIP_SRAM, 1 );
338576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_NIC_STAT_REG );
338676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
338776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Deactivate any external SRAM that might be present */
338876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_2 ( reg,
338976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_GPIO1_OEN, 1,
339076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_GPIO1_OUT, 1 );
339176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_GPIO_CTL_REG_KER );
339276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
339376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Initiate SRAM reset */
339476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_2 ( reg,
339576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_SRAM_OOB_BT_INIT_EN, 1,
339676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_SRM_NUM_BANKS_AND_BANK_SIZE, 0 );
339776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_SRM_CFG_REG_KER );
339876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
339976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Wait for SRAM reset to complete */
340076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	count = 0;
340176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	do {
340276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* SRAM reset is slow; expect around 16ms */
340376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mdelay ( 20 );
340476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
340576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Check for reset complete */
340676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_read ( efab, &reg, FCN_SRM_CFG_REG_KER );
340776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( !EFAB_OWORD_FIELD ( reg, FCN_SRAM_OOB_BT_INIT_EN ) )
340876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			return 0;
340976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} while (++count < 20);	/* wait upto 0.4 sec */
341076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
341176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_ERR ( "timed out waiting for SRAM reset\n");
341276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return -ETIMEDOUT;
341376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
341476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
341576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
341676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_setup_nic ( struct efab_nic *efab )
341776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
341876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t timer_cmd;
341976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t reg;
342076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int tx_fc, xoff_thresh, xon_thresh;
342176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
342276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* bug5129: Clear the parity enables on the TX data fifos as
342376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * they produce false parity errors because of timing issues
342476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
342576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &reg, FCN_SPARE_REG_KER );
342676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_OWORD_FIELD ( reg, FCN_MEM_PERR_EN_TX_DATA, 0 );
342776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_SPARE_REG_KER );
342876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
342976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Set up TX and RX descriptor caches in SRAM */
343076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_1 ( reg, FCN_SRM_TX_DC_BASE_ADR, 0x130000 );
343176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_SRM_TX_DC_CFG_REG_KER );
343276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_1 ( reg, FCN_TX_DC_SIZE, 1 /* 16 descriptors */ );
343376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_TX_DC_CFG_REG_KER );
343476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_1 ( reg, FCN_SRM_RX_DC_BASE_ADR, 0x100000 );
343576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_SRM_RX_DC_CFG_REG_KER );
343676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_1 ( reg, FCN_RX_DC_SIZE, 2 /* 32 descriptors */ );
343776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_RX_DC_CFG_REG_KER );
343876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
343976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Set number of RSS CPUs
344076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * bug7244: Increase filter depth to reduce RX_RESET likelyhood
344176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
344276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_5 ( reg,
344376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_NUM_KER, 0,
344476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_UDP_FULL_SRCH_LIMIT, 8,
344576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                                FCN_UDP_WILD_SRCH_LIMIT, 8,
344676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                                FCN_TCP_WILD_SRCH_LIMIT, 8,
344776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                                FCN_TCP_FULL_SRCH_LIMIT, 8);
344876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_RX_FILTER_CTL_REG_KER );
344976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	udelay ( 1000 );
345076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
345176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Setup RX.  Wait for descriptor is broken and must
345276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * be disabled.  RXDP recovery shouldn't be needed, but is.
345376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * disable ISCSI parsing because we don't need it
345476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
345576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &reg, FCN_RX_SELF_RST_REG_KER );
345676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_OWORD_FIELD ( reg, FCN_RX_NODESC_WAIT_DIS, 1 );
345776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_OWORD_FIELD ( reg, FCN_RX_RECOVERY_EN, 1 );
345876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_OWORD_FIELD ( reg, FCN_RX_ISCSI_DIS, 1 );
345976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_RX_SELF_RST_REG_KER );
346076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
346176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Determine recommended flow control settings. *
346276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Flow control is qualified on B0 and A1/1G, not on A1/10G */
346376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->pci_revision == FALCON_REV_B0 ) {
346476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		tx_fc = 1;
346576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		xoff_thresh = 54272;  /* ~80Kb - 3*max MTU */
346676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		xon_thresh = 27648; /* ~3*max MTU */
346776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
346876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else if ( !efab->phy_10g ) {
346976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		tx_fc = 1;
347076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		xoff_thresh = 2048;
347176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		xon_thresh = 512;
347276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
347376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else {
347476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		tx_fc = xoff_thresh = xon_thresh = 0;
347576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
347676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
347776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Setup TX and RX */
347876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &reg, FCN_TX_CFG2_REG_KER );
347976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_OWORD_FIELD ( reg, FCN_TX_DIS_NON_IP_EV, 1 );
348076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_TX_CFG2_REG_KER );
348176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
348276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_read ( efab, &reg, FCN_RX_CFG_REG_KER );
348376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_OWORD_FIELD_VER ( efab, reg, FCN_RX_USR_BUF_SIZE,
348476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				   (3*4096) / 32 );
348576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->pci_revision == FALCON_REV_B0)
348676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_SET_OWORD_FIELD ( reg, FCN_RX_INGR_EN_B0, 1 );
348776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_OWORD_FIELD_VER ( efab, reg, FCN_RX_XON_MAC_TH,
348876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				   xon_thresh / 256);
348976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_OWORD_FIELD_VER ( efab, reg, FCN_RX_XOFF_MAC_TH,
349076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				   xoff_thresh / 256);
349176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_SET_OWORD_FIELD_VER ( efab, reg, FCN_RX_XOFF_MAC_EN, tx_fc);
349276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_RX_CFG_REG_KER );
349376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
349476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Set timer register */
349576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_2 ( timer_cmd,
349676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_TIMER_MODE, FCN_TIMER_MODE_DIS,
349776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_TIMER_VAL, 0 );
349876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_writel ( efab, &timer_cmd, FCN_TIMER_CMD_REG_KER );
349976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
350076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
350176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
350276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_init_resources ( struct efab_nic *efab )
350376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
350476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_ev_queue *ev_queue = &efab->ev_queue;
350576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_rx_queue *rx_queue = &efab->rx_queue;
350676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_tx_queue *tx_queue = &efab->tx_queue;
350776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
350876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t reg;
350976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int jumbo;
351076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
351176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Initialise the ptrs */
351276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	tx_queue->read_ptr = tx_queue->write_ptr = 0;
351376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rx_queue->read_ptr = rx_queue->write_ptr = 0;
351476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ev_queue->read_ptr = 0;
351576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
351676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Push the event queue to the hardware */
351776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_3 ( reg,
351876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_EVQ_EN, 1,
351976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_EVQ_SIZE, FQS(FCN_EVQ, EFAB_EVQ_SIZE),
352076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_EVQ_BUF_BASE_ID, ev_queue->entry.id );
352176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg,
352276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       FCN_REVISION_REG ( efab, FCN_EVQ_PTR_TBL_KER ) );
352376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
352476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Push the tx queue to the hardware */
352576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_8 ( reg,
352676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_TX_DESCQ_EN, 1,
352776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_TX_ISCSI_DDIG_EN, 0,
352876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_TX_ISCSI_DDIG_EN, 0,
352976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_TX_DESCQ_BUF_BASE_ID, tx_queue->entry.id,
353076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_TX_DESCQ_EVQ_ID, 0,
353176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_TX_DESCQ_SIZE, FQS(FCN_TX_DESCQ, EFAB_TXD_SIZE),
353276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_TX_DESCQ_TYPE, 0 /* kernel queue */,
353376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_TX_NON_IP_DROP_DIS_B0, 1 );
353476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg,
353576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       FCN_REVISION_REG ( efab, FCN_TX_DESC_PTR_TBL_KER ) );
353676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
353776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Push the rx queue to the hardware */
353876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jumbo = ( efab->pci_revision == FALCON_REV_B0 ) ? 0 : 1;
353976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_8 ( reg,
354076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_RX_ISCSI_DDIG_EN, 0,
354176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_RX_ISCSI_HDIG_EN, 0,
354276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_RX_DESCQ_BUF_BASE_ID, rx_queue->entry.id,
354376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_RX_DESCQ_EVQ_ID, 0,
354476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_RX_DESCQ_SIZE, FQS(FCN_RX_DESCQ, EFAB_RXD_SIZE),
354576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_RX_DESCQ_TYPE, 0 /* kernel queue */,
354676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_RX_DESCQ_JUMBO, jumbo,
354776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_RX_DESCQ_EN, 1 );
354876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg,
354976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       FCN_REVISION_REG ( efab, FCN_RX_DESC_PTR_TBL_KER ) );
355076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
355176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Program INT_ADR_REG_KER */
355276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_1 ( reg,
355376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_INT_ADR_KER, virt_to_bus ( &efab->int_ker ) );
355476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &reg, FCN_INT_ADR_REG_KER );
355576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
355676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Ack the event queue */
355776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_eventq_read_ack ( efab, ev_queue );
355876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
355976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
356076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
356176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_fini_resources ( struct efab_nic *efab )
356276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
356376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_oword_t cmd;
356476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
356576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Disable interrupts */
356676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_interrupts ( efab, 0, 0 );
356776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
356876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Flush the dma queues */
356976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_2 ( cmd,
357076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_TX_FLUSH_DESCQ_CMD, 1,
357176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_TX_FLUSH_DESCQ, 0 );
357276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &cmd,
357376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       FCN_REVISION_REG ( efab, FCN_TX_DESC_PTR_TBL_KER ) );
357476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
357576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_OWORD_2 ( cmd,
357676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_RX_FLUSH_DESCQ_CMD, 1,
357776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_RX_FLUSH_DESCQ, 0 );
357876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &cmd,
357976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       FCN_REVISION_REG ( efab, FCN_RX_DESC_PTR_TBL_KER ) );
358076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
358176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	mdelay ( 100 );
358276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
358376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Remove descriptor rings from card */
358476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_ZERO_OWORD ( cmd );
358576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &cmd,
358676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       FCN_REVISION_REG ( efab, FCN_TX_DESC_PTR_TBL_KER ) );
358776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &cmd,
358876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       FCN_REVISION_REG ( efab, FCN_RX_DESC_PTR_TBL_KER ) );
358976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_write ( efab, &cmd,
359076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       FCN_REVISION_REG ( efab, FCN_EVQ_PTR_TBL_KER ) );
359176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
359276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
359376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
359476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
359576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
359676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Hardware rx path
359776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
359876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
359976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
360076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
360176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
360276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_build_rx_desc ( falcon_rx_desc_t *rxd, struct io_buffer *iob )
360376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
360476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_QWORD_2 ( *rxd,
360576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_RX_KER_BUF_SIZE, EFAB_RX_BUF_SIZE,
360676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_RX_KER_BUF_ADR, virt_to_bus ( iob->data ) );
360776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
360876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
360976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
361076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_notify_rx_desc ( struct efab_nic *efab, struct efab_rx_queue *rx_queue )
361176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
361276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t reg;
361376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int ptr = rx_queue->write_ptr % EFAB_RXD_SIZE;
361476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
361576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_1 ( reg, FCN_RX_DESC_WPTR_DWORD, ptr );
361676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_writel ( efab, &reg, FCN_RX_DESC_UPD_REG_KER_DWORD );
361776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
361876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
361976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
362076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
362176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
362276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
362376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Hardware tx path
362476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
362576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
362676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
362776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
362876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
362976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_build_tx_desc ( falcon_tx_desc_t *txd, struct io_buffer *iob )
363076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
363176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_QWORD_2 ( *txd,
363276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_TX_KER_BYTE_CNT, iob_len ( iob ),
363376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				FCN_TX_KER_BUF_ADR, virt_to_bus ( iob->data ) );
363476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
363576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
363676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
363776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_notify_tx_desc ( struct efab_nic *efab,
363876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			struct efab_tx_queue *tx_queue )
363976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
364076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t reg;
364176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int ptr = tx_queue->write_ptr % EFAB_TXD_SIZE;
364276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
364376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_POPULATE_DWORD_1 ( reg, FCN_TX_DESC_WPTR_DWORD, ptr );
364476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_writel ( efab, &reg, FCN_TX_DESC_UPD_REG_KER_DWORD );
364576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
364676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
364776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
364876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
364976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
365076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
365176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Software receive interface
365276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
365376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
365476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
365576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
365676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
365776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanefab_fill_rx_queue ( struct efab_nic *efab,
365876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     struct efab_rx_queue *rx_queue )
365976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
366076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int fill_level = rx_queue->write_ptr - rx_queue->read_ptr;
366176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int space = EFAB_NUM_RX_DESC - fill_level - 1;
366276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int pushed = 0;
366376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
366476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	while ( space ) {
366576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		int buf_id = rx_queue->write_ptr % EFAB_NUM_RX_DESC;
366676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		int desc_id = rx_queue->write_ptr % EFAB_RXD_SIZE;
366776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		struct io_buffer *iob;
366876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_rx_desc_t *rxd;
366976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
367076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		assert ( rx_queue->buf[buf_id] == NULL );
367176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		iob = alloc_iob ( EFAB_RX_BUF_SIZE );
367276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( !iob )
367376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			break;
367476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
367576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_TRACE ( "pushing rx_buf[%d] iob %p data %p\n",
367676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			     buf_id, iob, iob->data );
367776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
367876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rx_queue->buf[buf_id] = iob;
367976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rxd = rx_queue->ring + desc_id;
368076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_build_rx_desc ( rxd, iob );
368176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		++rx_queue->write_ptr;
368276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		++pushed;
368376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		--space;
368476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
368576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
368676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( pushed ) {
368776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Push the ptr to hardware */
368876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_notify_rx_desc ( efab, rx_queue );
368976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
369076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fill_level = rx_queue->write_ptr - rx_queue->read_ptr;
369176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_TRACE ( "pushed %d rx buffers to fill level %d\n",
369276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			     pushed, fill_level );
369376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
369476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
369576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( fill_level == 0 )
369676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return -ENOMEM;
369776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
369876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
369976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
370076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
370176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanefab_receive ( struct efab_nic *efab, unsigned int id, int len, int drop )
370276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
370376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_rx_queue *rx_queue = &efab->rx_queue;
370476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct io_buffer *iob;
370576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int read_ptr = rx_queue->read_ptr % EFAB_RXD_SIZE;
370676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int buf_ptr = rx_queue->read_ptr % EFAB_NUM_RX_DESC;
370776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
370876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	assert ( id == read_ptr );
370976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
371076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Pop this rx buffer out of the software ring */
371176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	iob = rx_queue->buf[buf_ptr];
371276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rx_queue->buf[buf_ptr] = NULL;
371376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
371476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_TRACE ( "popping rx_buf[%d] iob %p data %p with %d bytes %s\n",
371576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     id, iob, iob->data, len, drop ? "bad" : "ok" );
371676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
371776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Pass the packet up if required */
371876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( drop )
371976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		free_iob ( iob );
372076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else {
372176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		iob_put ( iob, len );
372276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		netdev_rx ( efab->netdev, iob );
372376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
372476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
372576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	++rx_queue->read_ptr;
372676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
372776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
372876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
372976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
373076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
373176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Software transmit interface
373276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
373376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
373476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
373576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
373676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
373776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanefab_transmit ( struct net_device *netdev, struct io_buffer *iob )
373876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
373976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_nic *efab = netdev_priv ( netdev );
374076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_tx_queue *tx_queue = &efab->tx_queue;
374176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int fill_level, space;
374276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_tx_desc_t *txd;
374376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int buf_id;
374476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
374576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	fill_level = tx_queue->write_ptr - tx_queue->read_ptr;
374676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	space = EFAB_TXD_SIZE - fill_level - 1;
374776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( space < 1 )
374876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return -ENOBUFS;
374976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
375076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Save the iobuffer for later completion */
375176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	buf_id = tx_queue->write_ptr % EFAB_TXD_SIZE;
375276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	assert ( tx_queue->buf[buf_id] == NULL );
375376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	tx_queue->buf[buf_id] = iob;
375476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
375576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_TRACE ( "tx_buf[%d] for iob %p data %p len %zd\n",
375676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     buf_id, iob, iob->data, iob_len ( iob ) );
375776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
375876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Form the descriptor, and push it to hardware */
375976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	txd = tx_queue->ring + buf_id;
376076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_build_tx_desc ( txd, iob );
376176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	++tx_queue->write_ptr;
376276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_notify_tx_desc ( efab, tx_queue );
376376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
376476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
376576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
376676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
376776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
376876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanefab_transmit_done ( struct efab_nic *efab, int id )
376976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
377076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_tx_queue *tx_queue = &efab->tx_queue;
377176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int read_ptr, stop;
377276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
377376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Complete all buffers from read_ptr up to and including id */
377476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	read_ptr = tx_queue->read_ptr % EFAB_TXD_SIZE;
377576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	stop = ( id + 1 ) % EFAB_TXD_SIZE;
377676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
377776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	while ( read_ptr != stop ) {
377876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		struct io_buffer *iob = tx_queue->buf[read_ptr];
377976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		assert ( iob );
378076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
378176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Complete the tx buffer */
378276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( iob )
378376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			netdev_tx_complete ( efab->netdev, iob );
378476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		tx_queue->buf[read_ptr] = NULL;
378576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
378676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		++tx_queue->read_ptr;
378776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		read_ptr = tx_queue->read_ptr % EFAB_TXD_SIZE;
378876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
378976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
379076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
379176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
379276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
379376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
379476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
379576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
379676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Hardware event path
379776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
379876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
379976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
380076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
380176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
380276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_clear_interrupts ( struct efab_nic *efab )
380376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
380476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_dword_t reg;
380576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
380676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->pci_revision == FALCON_REV_B0 ) {
380776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* read the ISR */
380876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_readl( efab, &reg, INT_ISR0_B0 );
380976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
381076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else {
381176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* write to the INT_ACK register */
381276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_writel ( efab, 0, FCN_INT_ACK_KER_REG_A1 );
381376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mb();
381476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_readl ( efab, &reg,
381576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			       WORK_AROUND_BROKEN_PCI_READS_REG_KER_A1 );
381676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
381776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
381876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
381976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
382076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfalcon_handle_event ( struct efab_nic *efab, falcon_event_t *evt )
382176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
382276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int ev_code, desc_ptr, len, drop;
382376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
382476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Decode event */
382576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ev_code = EFAB_QWORD_FIELD ( *evt, FCN_EV_CODE );
382676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	switch ( ev_code ) {
382776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case FCN_TX_IP_EV_DECODE:
382876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		desc_ptr = EFAB_QWORD_FIELD ( *evt, FCN_TX_EV_DESC_PTR );
382976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab_transmit_done ( efab, desc_ptr );
383076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
383176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
383276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case FCN_RX_IP_EV_DECODE:
383376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		desc_ptr = EFAB_QWORD_FIELD ( *evt, FCN_RX_EV_DESC_PTR );
383476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		len = EFAB_QWORD_FIELD ( *evt, FCN_RX_EV_BYTE_CNT );
383576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		drop = !EFAB_QWORD_FIELD ( *evt, FCN_RX_EV_PKT_OK );
383676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
383776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab_receive ( efab, desc_ptr, len, drop );
383876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
383976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
384076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	default:
384176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_TRACE ( "Unknown event type %d\n", ev_code );
384276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
384376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
384476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
384576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
384676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
384776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
384876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
384976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Software (polling) interrupt handler
385076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
385176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
385276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
385376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
385476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
385576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanefab_poll ( struct net_device *netdev )
385676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
385776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_nic *efab = netdev_priv ( netdev );
385876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_ev_queue *ev_queue = &efab->ev_queue;
385976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_rx_queue *rx_queue = &efab->rx_queue;
386076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_event_t *evt;
386176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
386276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Read the event queue by directly looking for events
386376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * (we don't even bother to read the eventq write ptr) */
386476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	evt = ev_queue->ring + ev_queue->read_ptr;
386576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	while ( falcon_event_present ( evt ) ) {
386676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
386776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_TRACE ( "Event at index 0x%x address %p is "
386876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			     EFAB_QWORD_FMT "\n", ev_queue->read_ptr,
386976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			     evt, EFAB_QWORD_VAL ( *evt ) );
387076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
387176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_handle_event ( efab, evt );
387276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
387376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Clear the event */
387476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_SET_QWORD ( *evt );
387576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
387676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Move to the next event. We don't ack the event
387776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		 * queue until the end */
387876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ev_queue->read_ptr = ( ( ev_queue->read_ptr + 1 ) %
387976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				       EFAB_EVQ_SIZE );
388076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		evt = ev_queue->ring + ev_queue->read_ptr;
388176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
388276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
388376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Push more buffers if needed */
388476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	(void) efab_fill_rx_queue ( efab, rx_queue );
388576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
388676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Clear any pending interrupts */
388776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_clear_interrupts ( efab );
388876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
388976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Ack the event queue */
389076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_eventq_read_ack ( efab, ev_queue );
389176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
389276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
389376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
389476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanefab_irq ( struct net_device *netdev, int enable )
389576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
389676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_nic *efab = netdev_priv ( netdev );
389776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_ev_queue *ev_queue = &efab->ev_queue;
389876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
389976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	switch ( enable ) {
390076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case 0:
390176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_interrupts ( efab, 0, 0 );
390276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
390376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case 1:
390476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_interrupts ( efab, 1, 0 );
390576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_eventq_read_ack ( efab, ev_queue );
390676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
390776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case 2:
390876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_interrupts ( efab, 1, 1 );
390976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
391076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
391176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
391276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
391376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*******************************************************************************
391476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
391576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
391676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Software open/close
391776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
391876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
391976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *******************************************************************************/
392076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
392176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
392276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanefab_free_resources ( struct efab_nic *efab )
392376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
392476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_ev_queue *ev_queue = &efab->ev_queue;
392576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_rx_queue *rx_queue = &efab->rx_queue;
392676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_tx_queue *tx_queue = &efab->tx_queue;
392776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int i;
392876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
392976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for ( i = 0; i < EFAB_NUM_RX_DESC; i++ ) {
393076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( rx_queue->buf[i] )
393176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			free_iob ( rx_queue->buf[i] );
393276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
393376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
393476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for ( i = 0; i < EFAB_TXD_SIZE; i++ ) {
393576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( tx_queue->buf[i] )
393676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			netdev_tx_complete ( efab->netdev,  tx_queue->buf[i] );
393776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
393876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
393976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rx_queue->ring )
394076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_free_special_buffer ( rx_queue->ring );
394176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
394276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( tx_queue->ring )
394376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_free_special_buffer ( tx_queue->ring );
394476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
394576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ev_queue->ring )
394676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_free_special_buffer ( ev_queue->ring );
394776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
394876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	memset ( rx_queue, 0, sizeof ( *rx_queue ) );
394976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	memset ( tx_queue, 0, sizeof ( *tx_queue ) );
395076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	memset ( ev_queue, 0, sizeof ( *ev_queue ) );
395176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
395276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Ensure subsequent buffer allocations start at id 0 */
395376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->buffer_head = 0;
395476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
395576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
395676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
395776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanefab_alloc_resources ( struct efab_nic *efab )
395876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
395976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_ev_queue *ev_queue = &efab->ev_queue;
396076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_rx_queue *rx_queue = &efab->rx_queue;
396176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_tx_queue *tx_queue = &efab->tx_queue;
396276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	size_t bytes;
396376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
396476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Allocate the hardware event queue */
396576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	bytes = sizeof ( falcon_event_t ) * EFAB_TXD_SIZE;
396676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ev_queue->ring = falcon_alloc_special_buffer ( efab, bytes,
396776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman						       &ev_queue->entry );
396876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( !ev_queue->ring )
396976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail1;
397076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
397176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Initialise the hardware event queue */
397276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	memset ( ev_queue->ring, 0xff, bytes );
397376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
397476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Allocate the hardware tx queue */
397576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	bytes = sizeof ( falcon_tx_desc_t ) * EFAB_TXD_SIZE;
397676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	tx_queue->ring = falcon_alloc_special_buffer ( efab, bytes,
397776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman						       &tx_queue->entry );
397876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ! tx_queue->ring )
397976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail2;
398076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
398176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Allocate the hardware rx queue */
398276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	bytes = sizeof ( falcon_rx_desc_t ) * EFAB_RXD_SIZE;
398376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rx_queue->ring = falcon_alloc_special_buffer ( efab, bytes,
398476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman						       &rx_queue->entry );
398576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ! rx_queue->ring )
398676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail3;
398776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
398876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
398976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
399076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail3:
399176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_free_special_buffer ( tx_queue->ring );
399276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	tx_queue->ring = NULL;
399376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail2:
399476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_free_special_buffer ( ev_queue->ring );
399576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ev_queue->ring = NULL;
399676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail1:
399776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return -ENOMEM;
399876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
399976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
400076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
400176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanefab_init_mac ( struct efab_nic *efab )
400276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
400376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int count, rc;
400476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
400576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* This can take several seconds */
400676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_LOG ( "Waiting for link..\n" );
400776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for ( count=0; count<5; count++ ) {
400876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rc = efab->mac_op->init ( efab );
400976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( rc ) {
401076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			EFAB_ERR ( "Failed reinitialising MAC, error %s\n",
401176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				strerror ( rc ));
401276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			return rc;
401376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
401476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
401576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Sleep for 2s to wait for the link to settle, either
401676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		 * because we want to use it, or because we're about
401776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		 * to reset the mac anyway
401876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		 */
401976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		sleep ( 2 );
402076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
402176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( ! efab->link_up ) {
402276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			EFAB_ERR ( "!\n" );
402376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			continue;
402476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
402576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
402676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		EFAB_LOG ( "\n%dMbps %s-duplex\n",
402776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			   ( efab->link_options & LPA_EF_10000 ? 10000 :
402876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			     ( efab->link_options & LPA_EF_1000 ? 1000 :
402976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			       ( efab->link_options & LPA_100 ? 100 : 10 ) ) ),
403076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			   ( efab->link_options & LPA_EF_DUPLEX ?
403176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			     "full" : "half" ) );
403276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
403376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* TODO: Move link state handling to the poll() routine */
403476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		netdev_link_up ( efab->netdev );
403576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return 0;
403676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
403776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
403876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_ERR ( "timed initialising MAC\n" );
403976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return -ETIMEDOUT;
404076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
404176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
404276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
404376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanefab_close ( struct net_device *netdev )
404476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
404576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_nic *efab = netdev_priv ( netdev );
404676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
404776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_fini_resources ( efab );
404876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_free_resources ( efab );
404976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->board_op->fini ( efab );
405076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_reset ( efab );
405176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
405276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
405376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
405476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanefab_open ( struct net_device *netdev )
405576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
405676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_nic *efab = netdev_priv ( netdev );
405776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_rx_queue *rx_queue = &efab->rx_queue;
405876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int rc;
405976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
406076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = falcon_reset ( efab );
406176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
406276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail1;
406376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
406476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = efab->board_op->init ( efab );
406576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
406676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail2;
406776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
406876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = falcon_init_sram ( efab );
406976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
407076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail3;
407176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
407276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Configure descriptor caches before pushing hardware queues */
407376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_setup_nic ( efab );
407476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
407576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = efab_alloc_resources ( efab );
407676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
407776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail4;
407876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
407976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_init_resources ( efab );
408076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
408176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Push rx buffers */
408276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = efab_fill_rx_queue ( efab, rx_queue );
408376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
408476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail5;
408576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
408676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Try and bring the interface up */
408776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = efab_init_mac ( efab );
408876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
408976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail6;
409076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
409176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
409276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
409376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail6:
409476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail5:
409576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab_free_resources ( efab );
409676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail4:
409776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail3:
409876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->board_op->fini ( efab );
409976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail2:
410076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_reset ( efab );
410176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail1:
410276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return rc;
410376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
410476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
410576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct net_device_operations efab_operations = {
410676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        .open           = efab_open,
410776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        .close          = efab_close,
410876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        .transmit       = efab_transmit,
410976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        .poll           = efab_poll,
411076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        .irq            = efab_irq,
411176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
411276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
411376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void
411476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanefab_remove ( struct pci_device *pci )
411576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
411676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct net_device *netdev = pci_get_drvdata ( pci );
411776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_nic *efab = netdev_priv ( netdev );
411876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
411976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->membase ) {
412076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		falcon_reset ( efab );
412176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
412276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		iounmap ( efab->membase );
412376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->membase = NULL;
412476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
412576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
412676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->nvo.nvs ) {
412776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		unregister_nvo ( &efab->nvo );
412876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		efab->nvo.nvs = NULL;
412976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
413076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
413176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unregister_netdev ( netdev );
413276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	netdev_nullify ( netdev );
413376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	netdev_put ( netdev );
413476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
413576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
413676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int
413776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanefab_probe ( struct pci_device *pci,
413876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     const struct pci_device_id *id )
413976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
414076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct net_device *netdev;
414176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct efab_nic *efab;
414276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned long mmio_start, mmio_len;
414376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int rc;
414476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
414576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Create the network adapter */
414676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	netdev = alloc_etherdev ( sizeof ( struct efab_nic ) );
414776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ! netdev ) {
414876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rc = -ENOMEM;
414976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail1;
415076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
415176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
415276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Initialise the network adapter, and initialise private storage */
415376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	netdev_init ( netdev, &efab_operations );
415476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pci_set_drvdata ( pci, netdev );
415576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	netdev->dev = &pci->dev;
415676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
415776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab = netdev_priv ( netdev );
415876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	memset ( efab, 0, sizeof ( *efab ) );
415976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->netdev = netdev;
416076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
416176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Get iobase/membase */
416276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	mmio_start = pci_bar_start ( pci, PCI_BASE_ADDRESS_2 );
416376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	mmio_len = pci_bar_size ( pci, PCI_BASE_ADDRESS_2 );
416476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->membase = ioremap ( mmio_start, mmio_len );
416576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_TRACE ( "BAR of %lx bytes at phys %lx mapped at %p\n",
416676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     mmio_len, mmio_start, efab->membase );
416776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
416876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Enable the PCI device */
416976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	adjust_pci_device ( pci );
417076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->iobase = pci->ioaddr & ~3;
417176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
417276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Determine the NIC variant */
417376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	falcon_probe_nic_variant ( efab, pci );
417476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
417576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Read the SPI interface and determine the MAC address,
417676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * and the board and phy variant. Hook in the op tables */
417776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = falcon_probe_spi ( efab );
417876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
417976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail2;
418076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = falcon_probe_nvram ( efab );
418176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
418276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail3;
418376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
418476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	memcpy ( netdev->hw_addr, efab->mac_addr, ETH_ALEN );
418576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
418676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	netdev_link_up ( netdev );
418776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rc = register_netdev ( netdev );
418876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( rc )
418976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		goto fail4;
419076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
419176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Advertise non-volatile storage */
419276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( efab->nvo.nvs ) {
419376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rc = register_nvo ( &efab->nvo, netdev_settings ( netdev ) );
419476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( rc )
419576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			goto fail5;
419676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
419776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
419876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFAB_LOG ( "Found %s EtherFabric %s %s revision %d\n", id->name,
419976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		   efab->is_asic ? "ASIC" : "FPGA",
420076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		   efab->phy_10g ? "10G" : "1G",
420176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		   efab->pci_revision );
420276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
420376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
420476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
420576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail5:
420676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unregister_netdev ( netdev );
420776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail4:
420876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail3:
420976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail2:
421076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	iounmap ( efab->membase );
421176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efab->membase = NULL;
421276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	netdev_put ( netdev );
421376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfail1:
421476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return rc;
421576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
421676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
421776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
421876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct pci_device_id efab_nics[] = {
421976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	PCI_ROM(0x1924, 0x0703, "falcon", "EtherFabric Falcon", 0),
422076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	PCI_ROM(0x1924, 0x0710, "falconb0", "EtherFabric FalconB0", 0),
422176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
422276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
422376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct pci_driver etherfabric_driver __pci_driver = {
422476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.ids = efab_nics,
422576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.id_count = sizeof ( efab_nics ) / sizeof ( efab_nics[0] ),
422676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.probe = efab_probe,
422776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.remove = efab_remove,
422876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
422976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
423076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
423176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Local variables:
423276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *  c-basic-offset: 8
423376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *  c-indent-level: 8
423476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *  tab-width: 8
423576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * End:
423676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
4237