/*
* Copyright (C) 2001,2002,2003,2004 Broadcom Corporation
* Copyright (c) 2006, 2007 Maciej W. Rozycki
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
* This driver is designed for the Broadcom SiByte SOC built-in
* Ethernet controllers. Written by Mitch Lichtenberg at Broadcom Corp.
*
* Updated to the driver model and the PHY abstraction layer
* by Maciej W. Rozycki.
*/
#include <linux/bug.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <asm/cache.h>
#include <asm/io.h>
#include <asm/processor.h> /* Processor type for cache alignment. */
/* This is only here until the firmware is ready. In that case,
the firmware leaves the ethernet address in the register for us. */
#ifdef CONFIG_SIBYTE_STANDALONE
#define SBMAC_ETH0_HWADDR "40:00:00:00:01:00"
#define SBMAC_ETH1_HWADDR "40:00:00:00:01:01"
#define SBMAC_ETH2_HWADDR "40:00:00:00:01:02"
#define SBMAC_ETH3_HWADDR "40:00:00:00:01:03"
#endif
/* These identify the driver base version and may not be removed. */
#if 0
static char version1[] __initdata =
"sb1250-mac.c:1.00 1/11/2001 Written by Mitch Lichtenberg\n";
#endif
/* Operational parameters that usually are not changed. */
#define CONFIG_SBMAC_COALESCE
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT (2*HZ)
MODULE_AUTHOR("Mitch Lichtenberg (Broadcom Corp.)");
MODULE_DESCRIPTION("Broadcom SiByte SOC GB Ethernet driver");
/* A few user-configurable values which may be modified when a driver
module is loaded. */
/* 1 normal messages, 0 quiet .. 7 verbose. */
static int debug = 1;
module_param(debug, int, S_IRUGO);
MODULE_PARM_DESC(debug, "Debug messages");
#ifdef CONFIG_SBMAC_COALESCE
static int int_pktcnt_tx = 255;
module_param(int_pktcnt_tx, int, S_IRUGO);
MODULE_PARM_DESC(int_pktcnt_tx, "TX packet count");
static int int_timeout_tx = 255;
module_param(int_timeout_tx, int, S_IRUGO);
MODULE_PARM_DESC(int_timeout_tx, "TX timeout value");
static int int_pktcnt_rx = 64;
module_param(int_pktcnt_rx, int, S_IRUGO);
MODULE_PARM_DESC(int_pktcnt_rx, "RX packet count");
static int int_timeout_rx = 64;
module_param(int_timeout_rx, int, S_IRUGO);
MODULE_PARM_DESC(int_timeout_rx, "RX timeout value");
#endif
#include <asm/sibyte/board.h>
#include <asm/sibyte/sb1250.h>
#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
#include <asm/sibyte/bcm1480_regs.h>
#include <asm/sibyte/bcm1480_int.h>
#define R_MAC_DMA_OODPKTLOST_RX R_MAC_DMA_OODPKTLOST
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
#include <asm/sibyte/sb1250_regs.h>
#include <asm/sibyte/sb1250_int.h>
#else
#error invalid SiByte MAC configuation
#endif
#include <asm/sibyte/sb1250_scd.h>
#include <asm/sibyte/sb1250_mac.h>
#include <asm/sibyte/sb1250_dma.h>
#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
#define UNIT_INT(n) (K_BCM1480_INT_MAC_0 + ((n) * 2))
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
#define UNIT_INT(n) (K_INT_MAC_0 + (n))
#else
#error invalid SiByte MAC configuation
#endif
#ifdef K_INT_PHY
#define SBMAC_PHY_INT K_INT_PHY
#else
#define SBMAC_PHY_INT PHY_POLL
#endif
/**********************************************************************
* Simple types
********************************************************************* */
enum sbmac_speed {
sbmac_speed_none = 0,
sbmac_speed_10 = SPEED_10,
sbmac_speed_100 = SPEED_100,
sbmac_speed_1000 = SPEED_1000,
};
enum sbmac_duplex {
sbmac_duplex_none = -1,
sbmac_duplex_half = DUPLEX_HALF,
sbmac_duplex_full = DUPLEX_FULL,
};
enum sbmac_fc {
sbmac_fc_none,
sbmac_fc_disabled,
sbmac_fc_frame,
sbmac_fc_collision,
sbmac_fc_carrier,
};
enum sbmac_state {
sbmac_state_uninit,
sbmac_state_off,
sbmac_state_on,
sbmac_state_broken,
};
/**********************************************************************
* Macros