/**************************************************************************
Intel Pro 1000 for ppcboot/das-u-boot
Drivers are port from Intel's Linux driver e1000-4.3.15
and from Etherboot pro 1000 driver by mrakes at vivato dot net
tested on both gig copper and gig fiber boards
***************************************************************************/
/*******************************************************************************
Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
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.
The full GNU General Public License is included in this distribution in the
file called LICENSE.
Contact Information:
Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
/*
* Copyright (C) Archway Digital Solutions.
*
* written by Chrsitopher Li <cli at arcyway dot com> or <chrisl at gnuchina dot org>
* 2/9/2002
*
* Copyright (C) Linux Networx.
* Massive upgrade to work with the new intel gigabit NICs.
* <ebiederman at lnxi dot com>
*
* Copyright 2011 Freescale Semiconductor, Inc.
*/
#include "e1000.h"
#define TOUT_LOOP 100000
#define virt_to_bus(devno, v) pci_virt_to_mem(devno, (void *) (v))
#define bus_to_phys(devno, a) pci_mem_to_phys(devno, a)
#define E1000_DEFAULT_PCI_PBA 0x00000030
#define E1000_DEFAULT_PCIE_PBA 0x000a0026
/* NIC specific static variables go here */
static char tx_pool[128 + 16];
static char rx_pool[128 + 16];
static char packet[2096];
static struct e1000_tx_desc *tx_base;
static struct e1000_rx_desc *rx_base;
static int tx_tail;
static int rx_tail, rx_last;
static struct pci_device_id e1000_supported[] = {
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82542},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_FIBER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_COPPER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_COPPER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_FIBER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_COPPER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_LOM},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_COPPER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545GM_COPPER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_COPPER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_COPPER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541ER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541GI_LF},
/* E1000 PCIe card */
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_COPPER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_FIBER },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571PT_QUAD_COPPER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_FIBER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER_LOWPROFILE},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_DUAL},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_QUAD},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_COPPER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_FIBER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_SERDES},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E_IAMT},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573L},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82574L},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_QUAD_COPPER_KSP3},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_DPT},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_DPT},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_SPT},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_SPT},
{}
};
/* Function forward declarations */
static int e1000_setup_link(struct eth_device *nic);
static int e1000_setup_fiber_link(struct eth_device *nic);
static int e1000_setup_copper_link(struct eth_device *nic);
static int e1000_phy_setup_autoneg(struct e1000_hw *hw);
static void e1000_config_collision_dist(struct e1000_hw *hw);
static int e1000_config_mac_to_phy(struct e1000_hw *hw);
static int e1000_config_fc_after_link_up(struct e1000_hw *hw);
static int e1000_check_for_link(struct eth_device *nic);
static int e1000_wait_autoneg(struct e1000_hw *hw);
static int e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed,
uint16_t * duplex);
static int e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,
uint16_t * phy_data);
static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,
uint16_t phy_data);
static int32_t e1000_phy_hw_reset(struct e1000_hw *hw);
static int e1000_phy_reset(struct e1000_hw *hw);
static int e1000_detect_gig_phy(struct e1000_hw *hw);
static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
static void e1000_set_media_type(struct e1000_hw *hw);
static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
static int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
#ifndef CONFIG_AP1000 /* remove for warnings */
static int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset,
uint16_t words,
uint16_t *data);
/******************************************************************************
* Raises the EEPROM's clock input.
*
* hw - Struct containing variables accessed by shared code
* eecd - EECD's current value
*****************************************************************************/
void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t * eecd)
{
/* Raise the clock input to the EEPROM (by setting the SK bit), and then
* wait 50 microseconds.
*/
*eecd = *eecd | E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, *eecd);
E1000_WRITE_FLUSH(hw);
udelay(50);
}
/******************************************************************************
* Lowers the EEPROM's clock input.
*
* hw - Struct containing variables accessed by shared code
* eecd - EECD's current value
*****************************************************************************/
void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t * eecd)
{
/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
* wait 50 microseconds.
*/
*eecd = *eecd & ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, *eecd);
E1000_WRITE_FLUSH(hw);
udelay(50);
}
/******************************************************************************
* Shift data bits out to the EEPROM.
*
* hw - Struct containing variables accessed by shared code
* data - data to send to the EEPROM
* count - number of bits to shift out
*****************************************************************************/
static void
e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count)
{
uint32_t eecd;
uint32_t mask;
/* We need to shift "count" bits out to the EEPROM. So, value in the
* "data" parameter will be shifted out to the EEPROM one bit at a time.
* In order to do this, "data" must be broken down into bits.
*/
mask = 0x01 << (count - 1);
eecd = E1000_READ_REG(hw, EECD);
eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
do {
/* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
* and then raising and then lowering the clock (the SK bit controls
* the clock input to the EEPROM). A "0" is shifted out to the EEPROM
* by setting "DI" to "0" and then raising and then lowering the clock.
*/
eecd &= ~E1000_EECD_DI;
if (data & mask)
eecd |= E1000_EECD_DI;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
udelay(50);
e1000_raise_ee_clk(hw, &eecd);
e1000_lower_ee_clk(hw, &eecd);
mask = mask >> 1;
} while (mask);
/* We leave the "DI" bit set to "0" when we leave this routine. */
eecd &= ~E1000_EECD_DI;
E1000_WRITE_REG(hw, EECD, eecd);
}
/******************************************************************************
* Shift data bits in from the EEPROM
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static uint16_t
e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count)
{
uint32_t eecd;
uint32_t i;
uint16_t data;
/* In order to read a register from the EEPROM, we need to shift 'count'
|