1*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /************************************************************************** 2*2439e4bfSJean-Christophe PLAGNIOL-VILLARD Inter Pro 1000 for ppcboot/das-u-boot 3*2439e4bfSJean-Christophe PLAGNIOL-VILLARD Drivers are port from Intel's Linux driver e1000-4.3.15 4*2439e4bfSJean-Christophe PLAGNIOL-VILLARD and from Etherboot pro 1000 driver by mrakes at vivato dot net 5*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tested on both gig copper and gig fiber boards 6*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ***************************************************************************/ 7*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /******************************************************************************* 8*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 9*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 10*2439e4bfSJean-Christophe PLAGNIOL-VILLARD Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. 11*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 12*2439e4bfSJean-Christophe PLAGNIOL-VILLARD This program is free software; you can redistribute it and/or modify it 13*2439e4bfSJean-Christophe PLAGNIOL-VILLARD under the terms of the GNU General Public License as published by the Free 14*2439e4bfSJean-Christophe PLAGNIOL-VILLARD Software Foundation; either version 2 of the License, or (at your option) 15*2439e4bfSJean-Christophe PLAGNIOL-VILLARD any later version. 16*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 17*2439e4bfSJean-Christophe PLAGNIOL-VILLARD This program is distributed in the hope that it will be useful, but WITHOUT 18*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19*2439e4bfSJean-Christophe PLAGNIOL-VILLARD FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 20*2439e4bfSJean-Christophe PLAGNIOL-VILLARD more details. 21*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 22*2439e4bfSJean-Christophe PLAGNIOL-VILLARD You should have received a copy of the GNU General Public License along with 23*2439e4bfSJean-Christophe PLAGNIOL-VILLARD this program; if not, write to the Free Software Foundation, Inc., 59 24*2439e4bfSJean-Christophe PLAGNIOL-VILLARD Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 26*2439e4bfSJean-Christophe PLAGNIOL-VILLARD The full GNU General Public License is included in this distribution in the 27*2439e4bfSJean-Christophe PLAGNIOL-VILLARD file called LICENSE. 28*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 29*2439e4bfSJean-Christophe PLAGNIOL-VILLARD Contact Information: 30*2439e4bfSJean-Christophe PLAGNIOL-VILLARD Linux NICS <linux.nics@intel.com> 31*2439e4bfSJean-Christophe PLAGNIOL-VILLARD Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 32*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 33*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *******************************************************************************/ 34*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* 35*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Copyright (C) Archway Digital Solutions. 36*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 37*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * written by Chrsitopher Li <cli at arcyway dot com> or <chrisl at gnuchina dot org> 38*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2/9/2002 39*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 40*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Copyright (C) Linux Networx. 41*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Massive upgrade to work with the new intel gigabit NICs. 42*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * <ebiederman at lnxi dot com> 43*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 44*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 45*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #include "e1000.h" 46*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 47*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_CMD_NET) \ 48*2439e4bfSJean-Christophe PLAGNIOL-VILLARD && defined(CONFIG_NET_MULTI) && defined(CONFIG_E1000) 49*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 50*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #define TOUT_LOOP 100000 51*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 52*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #undef virt_to_bus 53*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #define virt_to_bus(x) ((unsigned long)x) 54*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #define bus_to_phys(devno, a) pci_mem_to_phys(devno, a) 55*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #define mdelay(n) udelay((n)*1000) 56*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 57*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #define E1000_DEFAULT_PBA 0x00000030 58*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 59*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* NIC specific static variables go here */ 60*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 61*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static char tx_pool[128 + 16]; 62*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static char rx_pool[128 + 16]; 63*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static char packet[2096]; 64*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 65*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static struct e1000_tx_desc *tx_base; 66*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static struct e1000_rx_desc *rx_base; 67*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 68*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int tx_tail; 69*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int rx_tail, rx_last; 70*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 71*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static struct pci_device_id supported[] = { 72*2439e4bfSJean-Christophe PLAGNIOL-VILLARD {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82542}, 73*2439e4bfSJean-Christophe PLAGNIOL-VILLARD {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_FIBER}, 74*2439e4bfSJean-Christophe PLAGNIOL-VILLARD {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_COPPER}, 75*2439e4bfSJean-Christophe PLAGNIOL-VILLARD {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_COPPER}, 76*2439e4bfSJean-Christophe PLAGNIOL-VILLARD {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_FIBER}, 77*2439e4bfSJean-Christophe PLAGNIOL-VILLARD {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_COPPER}, 78*2439e4bfSJean-Christophe PLAGNIOL-VILLARD {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_LOM}, 79*2439e4bfSJean-Christophe PLAGNIOL-VILLARD {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM}, 80*2439e4bfSJean-Christophe PLAGNIOL-VILLARD {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_COPPER}, 81*2439e4bfSJean-Christophe PLAGNIOL-VILLARD {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_COPPER}, 82*2439e4bfSJean-Christophe PLAGNIOL-VILLARD {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER}, 83*2439e4bfSJean-Christophe PLAGNIOL-VILLARD {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER}, 84*2439e4bfSJean-Christophe PLAGNIOL-VILLARD {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM}, 85*2439e4bfSJean-Christophe PLAGNIOL-VILLARD }; 86*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 87*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Function forward declarations */ 88*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int e1000_setup_link(struct eth_device *nic); 89*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int e1000_setup_fiber_link(struct eth_device *nic); 90*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int e1000_setup_copper_link(struct eth_device *nic); 91*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int e1000_phy_setup_autoneg(struct e1000_hw *hw); 92*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void e1000_config_collision_dist(struct e1000_hw *hw); 93*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int e1000_config_mac_to_phy(struct e1000_hw *hw); 94*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int e1000_config_fc_after_link_up(struct e1000_hw *hw); 95*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int e1000_check_for_link(struct eth_device *nic); 96*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int e1000_wait_autoneg(struct e1000_hw *hw); 97*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, 98*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t * duplex); 99*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, 100*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t * phy_data); 101*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, 102*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t phy_data); 103*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void e1000_phy_hw_reset(struct e1000_hw *hw); 104*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int e1000_phy_reset(struct e1000_hw *hw); 105*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int e1000_detect_gig_phy(struct e1000_hw *hw); 106*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 107*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #define E1000_WRITE_REG(a, reg, value) (writel((value), ((a)->hw_addr + E1000_##reg))) 108*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #define E1000_READ_REG(a, reg) (readl((a)->hw_addr + E1000_##reg)) 109*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #define E1000_WRITE_REG_ARRAY(a, reg, offset, value) (\ 110*2439e4bfSJean-Christophe PLAGNIOL-VILLARD writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2)))) 111*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #define E1000_READ_REG_ARRAY(a, reg, offset) ( \ 112*2439e4bfSJean-Christophe PLAGNIOL-VILLARD readl((a)->hw_addr + E1000_##reg + ((offset) << 2))) 113*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #define E1000_WRITE_FLUSH(a) {uint32_t x; x = E1000_READ_REG(a, STATUS);} 114*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 115*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_AP1000 /* remove for warnings */ 116*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 117*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Raises the EEPROM's clock input. 118*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 119*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 120*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * eecd - EECD's current value 121*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 122*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 123*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t * eecd) 124*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 125*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Raise the clock input to the EEPROM (by setting the SK bit), and then 126*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * wait 50 microseconds. 127*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 128*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *eecd = *eecd | E1000_EECD_SK; 129*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, *eecd); 130*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 131*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(50); 132*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 133*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 134*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 135*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Lowers the EEPROM's clock input. 136*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 137*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 138*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * eecd - EECD's current value 139*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 140*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 141*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t * eecd) 142*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 143*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Lower the clock input to the EEPROM (by clearing the SK bit), and then 144*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * wait 50 microseconds. 145*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 146*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *eecd = *eecd & ~E1000_EECD_SK; 147*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, *eecd); 148*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 149*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(50); 150*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 151*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 152*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 153*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Shift data bits out to the EEPROM. 154*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 155*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 156*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * data - data to send to the EEPROM 157*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * count - number of bits to shift out 158*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 159*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 160*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count) 161*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 162*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t eecd; 163*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t mask; 164*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 165*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* We need to shift "count" bits out to the EEPROM. So, value in the 166*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * "data" parameter will be shifted out to the EEPROM one bit at a time. 167*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * In order to do this, "data" must be broken down into bits. 168*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 169*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mask = 0x01 << (count - 1); 170*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 171*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); 172*2439e4bfSJean-Christophe PLAGNIOL-VILLARD do { 173*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1", 174*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * and then raising and then lowering the clock (the SK bit controls 175*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the clock input to the EEPROM). A "0" is shifted out to the EEPROM 176*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * by setting "DI" to "0" and then raising and then lowering the clock. 177*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 178*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd &= ~E1000_EECD_DI; 179*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 180*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (data & mask) 181*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd |= E1000_EECD_DI; 182*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 183*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 184*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 185*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 186*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(50); 187*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 188*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_raise_ee_clk(hw, &eecd); 189*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_lower_ee_clk(hw, &eecd); 190*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 191*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mask = mask >> 1; 192*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 193*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } while (mask); 194*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 195*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* We leave the "DI" bit set to "0" when we leave this routine. */ 196*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd &= ~E1000_EECD_DI; 197*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 198*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 199*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 200*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 201*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Shift data bits in from the EEPROM 202*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 203*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 204*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 205*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static uint16_t 206*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_in_ee_bits(struct e1000_hw *hw) 207*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 208*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t eecd; 209*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t i; 210*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t data; 211*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 212*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* In order to read a register from the EEPROM, we need to shift 16 bits 213*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * in from the EEPROM. Bits are "shifted in" by raising the clock input to 214*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the EEPROM (setting the SK bit), and then reading the value of the "DO" 215*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * bit. During this "shifting in" process the "DI" bit should always be 216*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * clear.. 217*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 218*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 219*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 220*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 221*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); 222*2439e4bfSJean-Christophe PLAGNIOL-VILLARD data = 0; 223*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 224*2439e4bfSJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < 16; i++) { 225*2439e4bfSJean-Christophe PLAGNIOL-VILLARD data = data << 1; 226*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_raise_ee_clk(hw, &eecd); 227*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 228*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 229*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 230*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd &= ~(E1000_EECD_DI); 231*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (eecd & E1000_EECD_DO) 232*2439e4bfSJean-Christophe PLAGNIOL-VILLARD data |= 1; 233*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 234*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_lower_ee_clk(hw, &eecd); 235*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 236*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 237*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return data; 238*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 239*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 240*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 241*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Prepares EEPROM for access 242*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 243*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 244*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 245*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This 246*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * function should be called before issuing a command to the EEPROM. 247*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 248*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 249*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_setup_eeprom(struct e1000_hw *hw) 250*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 251*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t eecd; 252*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 253*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 254*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 255*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Clear SK and DI */ 256*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd &= ~(E1000_EECD_SK | E1000_EECD_DI); 257*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 258*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 259*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Set CS */ 260*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd |= E1000_EECD_CS; 261*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 262*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 263*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 264*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 265*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Returns EEPROM to a "standby" state 266*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 267*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 268*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 269*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 270*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_standby_eeprom(struct e1000_hw *hw) 271*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 272*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t eecd; 273*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 274*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 275*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 276*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Deselct EEPROM */ 277*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); 278*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 279*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 280*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(50); 281*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 282*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Clock high */ 283*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd |= E1000_EECD_SK; 284*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 285*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 286*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(50); 287*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 288*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Select EEPROM */ 289*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd |= E1000_EECD_CS; 290*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 291*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 292*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(50); 293*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 294*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Clock low */ 295*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd &= ~E1000_EECD_SK; 296*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 297*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 298*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(50); 299*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 300*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 301*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 302*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Reads a 16 bit word from the EEPROM. 303*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 304*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 305*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * offset - offset of word in the EEPROM to read 306*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * data - word read from the EEPROM 307*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 308*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 309*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, uint16_t * data) 310*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 311*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t eecd; 312*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t i = 0; 313*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int large_eeprom = FALSE; 314*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 315*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Request EEPROM Access */ 316*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type > e1000_82544) { 317*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 318*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (eecd & E1000_EECD_SIZE) 319*2439e4bfSJean-Christophe PLAGNIOL-VILLARD large_eeprom = TRUE; 320*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd |= E1000_EECD_REQ; 321*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 322*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 323*2439e4bfSJean-Christophe PLAGNIOL-VILLARD while ((!(eecd & E1000_EECD_GNT)) && (i < 100)) { 324*2439e4bfSJean-Christophe PLAGNIOL-VILLARD i++; 325*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(10); 326*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 327*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 328*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (!(eecd & E1000_EECD_GNT)) { 329*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd &= ~E1000_EECD_REQ; 330*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 331*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Could not acquire EEPROM grant\n"); 332*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_EEPROM; 333*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 334*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 335*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 336*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Prepare the EEPROM for reading */ 337*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_setup_eeprom(hw); 338*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 339*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Send the READ command (opcode + addr) */ 340*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE, 3); 341*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_ee_bits(hw, offset, (large_eeprom) ? 8 : 6); 342*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 343*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Read the data */ 344*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *data = e1000_shift_in_ee_bits(hw); 345*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 346*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* End this read operation */ 347*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_standby_eeprom(hw); 348*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 349*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Stop requesting EEPROM access */ 350*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type > e1000_82544) { 351*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 352*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd &= ~E1000_EECD_REQ; 353*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 354*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 355*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 356*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 357*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 358*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 359*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 360*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 361*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_eeprom_cleanup(struct e1000_hw *hw) 362*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 363*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t eecd; 364*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 365*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 366*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd &= ~(E1000_EECD_CS | E1000_EECD_DI); 367*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 368*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_raise_ee_clk(hw, &eecd); 369*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_lower_ee_clk(hw, &eecd); 370*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 371*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 372*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static uint16_t 373*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_wait_eeprom_done(struct e1000_hw *hw) 374*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 375*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t eecd; 376*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t i; 377*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 378*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_standby_eeprom(hw); 379*2439e4bfSJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < 200; i++) { 380*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 381*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (eecd & E1000_EECD_DO) 382*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return (TRUE); 383*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(5); 384*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 385*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return (FALSE); 386*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 387*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 388*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 389*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_write_eeprom(struct e1000_hw *hw, uint16_t Reg, uint16_t Data) 390*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 391*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t eecd; 392*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int large_eeprom = FALSE; 393*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int i = 0; 394*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 395*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Request EEPROM Access */ 396*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type > e1000_82544) { 397*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 398*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (eecd & E1000_EECD_SIZE) 399*2439e4bfSJean-Christophe PLAGNIOL-VILLARD large_eeprom = TRUE; 400*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd |= E1000_EECD_REQ; 401*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 402*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 403*2439e4bfSJean-Christophe PLAGNIOL-VILLARD while ((!(eecd & E1000_EECD_GNT)) && (i < 100)) { 404*2439e4bfSJean-Christophe PLAGNIOL-VILLARD i++; 405*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(5); 406*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 407*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 408*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (!(eecd & E1000_EECD_GNT)) { 409*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd &= ~E1000_EECD_REQ; 410*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 411*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Could not acquire EEPROM grant\n"); 412*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return FALSE; 413*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 414*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 415*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_setup_eeprom(hw); 416*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE, 5); 417*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_ee_bits(hw, Reg, (large_eeprom) ? 6 : 4); 418*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_standby_eeprom(hw); 419*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE, 3); 420*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_ee_bits(hw, Reg, (large_eeprom) ? 8 : 6); 421*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_ee_bits(hw, Data, 16); 422*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (!e1000_wait_eeprom_done(hw)) { 423*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return FALSE; 424*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 425*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE, 5); 426*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_ee_bits(hw, Reg, (large_eeprom) ? 6 : 4); 427*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_eeprom_cleanup(hw); 428*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 429*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Stop requesting EEPROM access */ 430*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type > e1000_82544) { 431*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 432*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd &= ~E1000_EECD_REQ; 433*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, EECD, eecd); 434*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 435*2439e4bfSJean-Christophe PLAGNIOL-VILLARD i = 0; 436*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 437*2439e4bfSJean-Christophe PLAGNIOL-VILLARD while (((eecd & E1000_EECD_GNT)) && (i < 500)) { 438*2439e4bfSJean-Christophe PLAGNIOL-VILLARD i++; 439*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(10); 440*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eecd = E1000_READ_REG(hw, EECD); 441*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 442*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((eecd & E1000_EECD_GNT)) { 443*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Could not release EEPROM grant\n"); 444*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 445*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return TRUE; 446*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 447*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 448*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 449*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 450*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Verifies that the EEPROM has a valid checksum 451*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 452*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 453*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 454*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Reads the first 64 16 bit words of the EEPROM and sums the values read. 455*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is 456*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * valid. 457*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 458*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 459*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_validate_eeprom_checksum(struct eth_device *nic) 460*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 461*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = nic->priv; 462*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t checksum = 0; 463*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t i, eeprom_data; 464*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 465*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 466*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 467*2439e4bfSJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) { 468*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_eeprom(hw, i, &eeprom_data) < 0) { 469*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("EEPROM Read Error\n"); 470*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_EEPROM; 471*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 472*2439e4bfSJean-Christophe PLAGNIOL-VILLARD checksum += eeprom_data; 473*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 474*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 475*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (checksum == (uint16_t) EEPROM_SUM) { 476*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 477*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 478*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("EEPROM Checksum Invalid\n"); 479*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_EEPROM; 480*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 481*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 482*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif /* #ifndef CONFIG_AP1000 */ 483*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 484*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 485*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the 486*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * second function of dual function devices 487*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 488*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * nic - Struct containing variables accessed by shared code 489*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 490*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 491*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_read_mac_addr(struct eth_device *nic) 492*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 493*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_AP1000 494*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = nic->priv; 495*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t offset; 496*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t eeprom_data; 497*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int i; 498*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 499*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 500*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 501*2439e4bfSJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) { 502*2439e4bfSJean-Christophe PLAGNIOL-VILLARD offset = i >> 1; 503*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_eeprom(hw, offset, &eeprom_data) < 0) { 504*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("EEPROM Read Error\n"); 505*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_EEPROM; 506*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 507*2439e4bfSJean-Christophe PLAGNIOL-VILLARD nic->enetaddr[i] = eeprom_data & 0xff; 508*2439e4bfSJean-Christophe PLAGNIOL-VILLARD nic->enetaddr[i + 1] = (eeprom_data >> 8) & 0xff; 509*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 510*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((hw->mac_type == e1000_82546) && 511*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { 512*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Invert the last bit if this is the second device */ 513*2439e4bfSJean-Christophe PLAGNIOL-VILLARD nic->enetaddr[5] += 1; 514*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 515*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #else 516*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* 517*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * The AP1000's e1000 has no eeprom; the MAC address is stored in the 518*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * environment variables. Currently this does not support the addition 519*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * of a PMC e1000 card, which is certainly a possibility, so this should 520*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * be updated to properly use the env variable only for the onboard e1000 521*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 522*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 523*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int ii; 524*2439e4bfSJean-Christophe PLAGNIOL-VILLARD char *s, *e; 525*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 526*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 527*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 528*2439e4bfSJean-Christophe PLAGNIOL-VILLARD s = getenv ("ethaddr"); 529*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (s == NULL){ 530*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_EEPROM; 531*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 532*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else{ 533*2439e4bfSJean-Christophe PLAGNIOL-VILLARD for(ii = 0; ii < 6; ii++) { 534*2439e4bfSJean-Christophe PLAGNIOL-VILLARD nic->enetaddr[ii] = s ? simple_strtoul (s, &e, 16) : 0; 535*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (s){ 536*2439e4bfSJean-Christophe PLAGNIOL-VILLARD s = (*e) ? e + 1 : e; 537*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 538*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 539*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 540*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 541*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 542*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 543*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 544*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 545*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Initializes receive address filters. 546*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 547*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 548*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 549*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Places the MAC address in receive address register 0 and clears the rest 550*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * of the receive addresss registers. Clears the multicast table. Assumes 551*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the receiver is in reset when the routine is called. 552*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 553*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 554*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_init_rx_addrs(struct eth_device *nic) 555*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 556*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = nic->priv; 557*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t i; 558*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t addr_low; 559*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t addr_high; 560*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 561*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 562*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 563*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Setup the receive address. */ 564*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Programming MAC Address into RAR[0]\n"); 565*2439e4bfSJean-Christophe PLAGNIOL-VILLARD addr_low = (nic->enetaddr[0] | 566*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (nic->enetaddr[1] << 8) | 567*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (nic->enetaddr[2] << 16) | (nic->enetaddr[3] << 24)); 568*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 569*2439e4bfSJean-Christophe PLAGNIOL-VILLARD addr_high = (nic->enetaddr[4] | (nic->enetaddr[5] << 8) | E1000_RAH_AV); 570*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 571*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low); 572*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high); 573*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 574*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Zero out the other 15 receive addresses. */ 575*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Clearing RAR[1-15]\n"); 576*2439e4bfSJean-Christophe PLAGNIOL-VILLARD for (i = 1; i < E1000_RAR_ENTRIES; i++) { 577*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); 578*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); 579*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 580*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 581*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 582*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 583*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Clears the VLAN filer table 584*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 585*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 586*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 587*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 588*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_clear_vfta(struct e1000_hw *hw) 589*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 590*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t offset; 591*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 592*2439e4bfSJean-Christophe PLAGNIOL-VILLARD for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) 593*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0); 594*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 595*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 596*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 597*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Set the mac type member in the hw struct. 598*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 599*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 600*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 601*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 602*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_set_mac_type(struct e1000_hw *hw) 603*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 604*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 605*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 606*2439e4bfSJean-Christophe PLAGNIOL-VILLARD switch (hw->device_id) { 607*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_DEV_ID_82542: 608*2439e4bfSJean-Christophe PLAGNIOL-VILLARD switch (hw->revision_id) { 609*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_82542_2_0_REV_ID: 610*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->mac_type = e1000_82542_rev2_0; 611*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 612*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_82542_2_1_REV_ID: 613*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->mac_type = e1000_82542_rev2_1; 614*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 615*2439e4bfSJean-Christophe PLAGNIOL-VILLARD default: 616*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Invalid 82542 revision ID */ 617*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_MAC_TYPE; 618*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 619*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 620*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_DEV_ID_82543GC_FIBER: 621*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_DEV_ID_82543GC_COPPER: 622*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->mac_type = e1000_82543; 623*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 624*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_DEV_ID_82544EI_COPPER: 625*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_DEV_ID_82544EI_FIBER: 626*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_DEV_ID_82544GC_COPPER: 627*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_DEV_ID_82544GC_LOM: 628*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->mac_type = e1000_82544; 629*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 630*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_DEV_ID_82540EM: 631*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_DEV_ID_82540EM_LOM: 632*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->mac_type = e1000_82540; 633*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 634*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_DEV_ID_82545EM_COPPER: 635*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_DEV_ID_82545EM_FIBER: 636*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->mac_type = e1000_82545; 637*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 638*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_DEV_ID_82546EB_COPPER: 639*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_DEV_ID_82546EB_FIBER: 640*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->mac_type = e1000_82546; 641*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 642*2439e4bfSJean-Christophe PLAGNIOL-VILLARD default: 643*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Should never have loaded on this device */ 644*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_MAC_TYPE; 645*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 646*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return E1000_SUCCESS; 647*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 648*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 649*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 650*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Reset the transmit and receive units; mask and clear all interrupts. 651*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 652*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 653*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 654*2439e4bfSJean-Christophe PLAGNIOL-VILLARD void 655*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_reset_hw(struct e1000_hw *hw) 656*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 657*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t ctrl; 658*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t ctrl_ext; 659*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t icr; 660*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t manc; 661*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 662*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 663*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 664*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* For 82542 (rev 2.0), disable MWI before issuing a device reset */ 665*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type == e1000_82542_rev2_0) { 666*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Disabling MWI on 82542 rev 2.0\n"); 667*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_write_config_word(hw->pdev, PCI_COMMAND, 668*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw-> 669*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_cmd_word & ~PCI_COMMAND_INVALIDATE); 670*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 671*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 672*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Clear interrupt mask to stop board from generating interrupts */ 673*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Masking off all interrupts\n"); 674*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, IMC, 0xffffffff); 675*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 676*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Disable the Transmit and Receive units. Then delay to allow 677*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * any pending transactions to complete before we hit the MAC with 678*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the global reset. 679*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 680*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RCTL, 0); 681*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP); 682*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 683*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 684*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */ 685*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->tbi_compatibility_on = FALSE; 686*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 687*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Delay to allow any outstanding PCI transactions to complete before 688*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * resetting the device 689*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 690*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdelay(10); 691*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 692*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Issue a global reset to the MAC. This will reset the chip's 693*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * transmit, receive, DMA, and link units. It will not effect 694*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the current PCI configuration. The global reset bit is self- 695*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * clearing, and should clear within a microsecond. 696*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 697*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Issuing a global reset to MAC\n"); 698*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl = E1000_READ_REG(hw, CTRL); 699*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 700*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 701*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type > e1000_82543) 702*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST)); 703*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else 704*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 705*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST)); 706*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 707*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Force a reload from the EEPROM if necessary */ 708*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type < e1000_82540) { 709*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Wait for reset to complete */ 710*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(10); 711*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); 712*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl_ext |= E1000_CTRL_EXT_EE_RST; 713*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); 714*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 715*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Wait for EEPROM reload */ 716*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdelay(2); 717*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 718*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Wait for EEPROM reload (it happens automatically) */ 719*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdelay(4); 720*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Dissable HW ARPs on ASF enabled adapters */ 721*2439e4bfSJean-Christophe PLAGNIOL-VILLARD manc = E1000_READ_REG(hw, MANC); 722*2439e4bfSJean-Christophe PLAGNIOL-VILLARD manc &= ~(E1000_MANC_ARP_EN); 723*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, MANC, manc); 724*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 725*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 726*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Clear interrupt mask to stop board from generating interrupts */ 727*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Masking off all interrupts\n"); 728*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, IMC, 0xffffffff); 729*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 730*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Clear any pending interrupt events. */ 731*2439e4bfSJean-Christophe PLAGNIOL-VILLARD icr = E1000_READ_REG(hw, ICR); 732*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 733*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* If MWI was previously enabled, reenable it. */ 734*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type == e1000_82542_rev2_0) { 735*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word); 736*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 737*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 738*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 739*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 740*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Performs basic configuration of the adapter. 741*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 742*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 743*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 744*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Assumes that the controller has previously been reset and is in a 745*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * post-reset uninitialized state. Initializes the receive address registers, 746*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * multicast table, and VLAN filter table. Calls routines to setup link 747*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * configuration and flow control settings. Clears all on-chip counters. Leaves 748*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the transmit and receive units disabled and uninitialized. 749*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 750*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 751*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_init_hw(struct eth_device *nic) 752*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 753*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = nic->priv; 754*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t ctrl, status; 755*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t i; 756*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int32_t ret_val; 757*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t pcix_cmd_word; 758*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t pcix_stat_hi_word; 759*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t cmd_mmrbc; 760*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t stat_mmrbc; 761*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_bus_type bus_type = e1000_bus_type_unknown; 762*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 763*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 764*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 765*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Initialize Identification LED */ 766*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_id_led_init(hw); 767*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 768*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Error Initializing Identification LED\n"); 769*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 770*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 771*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 772*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Set the Media Type and exit with error if it is not valid. */ 773*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type != e1000_82543) { 774*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* tbi_compatibility is only valid on 82543 */ 775*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->tbi_compatibility_en = FALSE; 776*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 777*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 778*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type >= e1000_82543) { 779*2439e4bfSJean-Christophe PLAGNIOL-VILLARD status = E1000_READ_REG(hw, STATUS); 780*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (status & E1000_STATUS_TBIMODE) { 781*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->media_type = e1000_media_type_fiber; 782*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* tbi_compatibility not valid on fiber */ 783*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->tbi_compatibility_en = FALSE; 784*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 785*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->media_type = e1000_media_type_copper; 786*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 787*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 788*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* This is an 82542 (fiber only) */ 789*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->media_type = e1000_media_type_fiber; 790*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 791*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 792*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Disabling VLAN filtering. */ 793*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Initializing the IEEE VLAN\n"); 794*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, VET, 0); 795*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 796*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_clear_vfta(hw); 797*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 798*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */ 799*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type == e1000_82542_rev2_0) { 800*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Disabling MWI on 82542 rev 2.0\n"); 801*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_write_config_word(hw->pdev, PCI_COMMAND, 802*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw-> 803*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_cmd_word & ~PCI_COMMAND_INVALIDATE); 804*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST); 805*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 806*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdelay(5); 807*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 808*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 809*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Setup the receive address. This involves initializing all of the Receive 810*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Address Registers (RARs 0 - 15). 811*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 812*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_init_rx_addrs(nic); 813*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 814*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */ 815*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type == e1000_82542_rev2_0) { 816*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RCTL, 0); 817*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 818*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdelay(1); 819*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word); 820*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 821*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 822*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Zero out the Multicast HASH table */ 823*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Zeroing the MTA\n"); 824*2439e4bfSJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < E1000_MC_TBL_SIZE; i++) 825*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); 826*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 827*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 828*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Set the PCI priority bit correctly in the CTRL register. This 829*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * determines if the adapter gives priority to receives, or if it 830*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * gives equal priority to transmits and receives. 831*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 832*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->dma_fairness) { 833*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl = E1000_READ_REG(hw, CTRL); 834*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR); 835*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 836*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 837*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type >= e1000_82543) { 838*2439e4bfSJean-Christophe PLAGNIOL-VILLARD status = E1000_READ_REG(hw, STATUS); 839*2439e4bfSJean-Christophe PLAGNIOL-VILLARD bus_type = (status & E1000_STATUS_PCIX_MODE) ? 840*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_bus_type_pcix : e1000_bus_type_pci; 841*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 842*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */ 843*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (bus_type == e1000_bus_type_pcix) { 844*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_read_config_word(hw->pdev, PCIX_COMMAND_REGISTER, 845*2439e4bfSJean-Christophe PLAGNIOL-VILLARD &pcix_cmd_word); 846*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_read_config_word(hw->pdev, PCIX_STATUS_REGISTER_HI, 847*2439e4bfSJean-Christophe PLAGNIOL-VILLARD &pcix_stat_hi_word); 848*2439e4bfSJean-Christophe PLAGNIOL-VILLARD cmd_mmrbc = 849*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >> 850*2439e4bfSJean-Christophe PLAGNIOL-VILLARD PCIX_COMMAND_MMRBC_SHIFT; 851*2439e4bfSJean-Christophe PLAGNIOL-VILLARD stat_mmrbc = 852*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >> 853*2439e4bfSJean-Christophe PLAGNIOL-VILLARD PCIX_STATUS_HI_MMRBC_SHIFT; 854*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K) 855*2439e4bfSJean-Christophe PLAGNIOL-VILLARD stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K; 856*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (cmd_mmrbc > stat_mmrbc) { 857*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK; 858*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT; 859*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_write_config_word(hw->pdev, PCIX_COMMAND_REGISTER, 860*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pcix_cmd_word); 861*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 862*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 863*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 864*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Call a subroutine to configure the link and setup flow control. */ 865*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_setup_link(nic); 866*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 867*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Set the transmit descriptor write-back policy */ 868*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type > e1000_82544) { 869*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl = E1000_READ_REG(hw, TXDCTL); 870*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl = 871*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (ctrl & ~E1000_TXDCTL_WTHRESH) | 872*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_TXDCTL_FULL_TX_DESC_WB; 873*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TXDCTL, ctrl); 874*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 875*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 876*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Clear all of the statistics registers (clear on read). It is 877*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * important that we do this after we have tried to establish link 878*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * because the symbol error count will increment wildly if there 879*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * is no link. 880*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 881*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_clear_hw_cntrs(hw); 882*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 883*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 884*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 885*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 886*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 887*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 888*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Configures flow control and link settings. 889*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 890*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 891*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 892*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Determines which flow control settings to use. Calls the apropriate media- 893*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * specific link configuration function. Configures the flow control settings. 894*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Assuming the adapter has a valid link partner, a valid link should be 895*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * established. Assumes the hardware has previously been reset and the 896*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * transmitter and receiver are not enabled. 897*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 898*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 899*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_setup_link(struct eth_device *nic) 900*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 901*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = nic->priv; 902*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t ctrl_ext; 903*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int32_t ret_val; 904*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t eeprom_data; 905*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 906*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 907*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 908*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_AP1000 909*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Read and store word 0x0F of the EEPROM. This word contains bits 910*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * that determine the hardware's default PAUSE (flow control) mode, 911*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * a bit that determines whether the HW defaults to enabling or 912*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * disabling auto-negotiation, and the direction of the 913*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * SW defined pins. If there is no SW over-ride of the flow 914*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * control setting, then the variable hw->fc will 915*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * be initialized based on a value in the EEPROM. 916*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 917*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, &eeprom_data) < 0) { 918*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("EEPROM Read Error\n"); 919*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_EEPROM; 920*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 921*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #else 922*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* we have to hardcode the proper value for our hardware. */ 923*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* this value is for the 82540EM pci card used for prototyping, and it works. */ 924*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eeprom_data = 0xb220; 925*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 926*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 927*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->fc == e1000_fc_default) { 928*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0) 929*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc = e1000_fc_none; 930*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 931*2439e4bfSJean-Christophe PLAGNIOL-VILLARD EEPROM_WORD0F_ASM_DIR) 932*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc = e1000_fc_tx_pause; 933*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else 934*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc = e1000_fc_full; 935*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 936*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 937*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* We want to save off the original Flow Control configuration just 938*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * in case we get disconnected and then reconnected into a different 939*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hub or switch with different Flow Control capabilities. 940*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 941*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type == e1000_82542_rev2_0) 942*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc &= (~e1000_fc_tx_pause); 943*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 944*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1)) 945*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc &= (~e1000_fc_rx_pause); 946*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 947*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->original_fc = hw->fc; 948*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 949*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("After fix-ups FlowControl is now = %x\n", hw->fc); 950*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 951*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Take the 4 bits from EEPROM word 0x0F that determine the initial 952*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * polarity value for the SW controlled pins, and setup the 953*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Extended Device Control reg with that info. 954*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * This is needed because one of the SW controlled pins is used for 955*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * signal detection. So this should be done before e1000_setup_pcs_link() 956*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * or e1000_phy_setup() is called. 957*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 958*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type == e1000_82543) { 959*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) << 960*2439e4bfSJean-Christophe PLAGNIOL-VILLARD SWDPIO__EXT_SHIFT); 961*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); 962*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 963*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 964*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Call the necessary subroutine to configure the link. */ 965*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = (hw->media_type == e1000_media_type_fiber) ? 966*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_setup_fiber_link(nic) : e1000_setup_copper_link(nic); 967*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 968*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 969*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 970*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 971*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Initialize the flow control address, type, and PAUSE timer 972*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * registers to their default values. This is done even if flow 973*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * control is disabled, because it does not hurt anything to 974*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * initialize these registers. 975*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 976*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT 977*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ("Initializing the Flow Control address, type and timer regs\n"); 978*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 979*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW); 980*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH); 981*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE); 982*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time); 983*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 984*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Set the flow control receive threshold registers. Normally, 985*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * these registers will be set to a default threshold that may be 986*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * adjusted later by the driver's runtime code. However, if the 987*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * ability to transmit pause frames in not enabled, then these 988*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * registers will be set to 0. 989*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 990*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (!(hw->fc & e1000_fc_tx_pause)) { 991*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, FCRTL, 0); 992*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, FCRTH, 0); 993*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 994*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* We need to set up the Receive Threshold high and low water marks 995*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * as well as (optionally) enabling the transmission of XON frames. 996*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 997*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->fc_send_xon) { 998*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, FCRTL, 999*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (hw->fc_low_water | E1000_FCRTL_XONE)); 1000*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water); 1001*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 1002*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, FCRTL, hw->fc_low_water); 1003*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water); 1004*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1005*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1006*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 1007*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1008*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1009*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 1010*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Sets up link for a fiber based adapter 1011*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1012*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 1013*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1014*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Manipulates Physical Coding Sublayer functions in order to configure 1015*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * link. Assumes the hardware has been previously reset and the transmitter 1016*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * and receiver are not enabled. 1017*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 1018*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 1019*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_setup_fiber_link(struct eth_device *nic) 1020*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1021*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = nic->priv; 1022*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t ctrl; 1023*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t status; 1024*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t txcw = 0; 1025*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t i; 1026*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t signal; 1027*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int32_t ret_val; 1028*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1029*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 1030*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be 1031*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * set when the optics detect a signal. On older adapters, it will be 1032*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * cleared when there is a signal 1033*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1034*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl = E1000_READ_REG(hw, CTRL); 1035*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((hw->mac_type > e1000_82544) && !(ctrl & E1000_CTRL_ILOS)) 1036*2439e4bfSJean-Christophe PLAGNIOL-VILLARD signal = E1000_CTRL_SWDPIN1; 1037*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else 1038*2439e4bfSJean-Christophe PLAGNIOL-VILLARD signal = 0; 1039*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1040*2439e4bfSJean-Christophe PLAGNIOL-VILLARD printf("signal for %s is %x (ctrl %08x)!!!!\n", nic->name, signal, 1041*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl); 1042*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Take the link out of reset */ 1043*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl &= ~(E1000_CTRL_LRST); 1044*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1045*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_config_collision_dist(hw); 1046*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1047*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Check for a software override of the flow control settings, and setup 1048*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the device accordingly. If auto-negotiation is enabled, then software 1049*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * will have to set the "PAUSE" bits to the correct value in the Tranmsit 1050*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Config Word Register (TXCW) and re-start auto-negotiation. However, if 1051*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * auto-negotiation is disabled, then software will have to manually 1052*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * configure the two flow control enable bits in the CTRL register. 1053*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1054*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * The possible values of the "fc" parameter are: 1055*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 0: Flow control is completely disabled 1056*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1: Rx flow control is enabled (we can receive pause frames, but 1057*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * not send pause frames). 1058*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2: Tx flow control is enabled (we can send pause frames but we do 1059*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * not support receiving pause frames). 1060*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 3: Both Rx and TX flow control (symmetric) are enabled. 1061*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1062*2439e4bfSJean-Christophe PLAGNIOL-VILLARD switch (hw->fc) { 1063*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_fc_none: 1064*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Flow control is completely disabled by a software over-ride. */ 1065*2439e4bfSJean-Christophe PLAGNIOL-VILLARD txcw = (E1000_TXCW_ANE | E1000_TXCW_FD); 1066*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1067*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_fc_rx_pause: 1068*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* RX Flow control is enabled and TX Flow control is disabled by a 1069*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * software over-ride. Since there really isn't a way to advertise 1070*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * that we are capable of RX Pause ONLY, we will advertise that we 1071*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * support both symmetric and asymmetric RX PAUSE. Later, we will 1072*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * disable the adapter's ability to send PAUSE frames. 1073*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1074*2439e4bfSJean-Christophe PLAGNIOL-VILLARD txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); 1075*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1076*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_fc_tx_pause: 1077*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* TX Flow control is enabled, and RX Flow control is disabled, by a 1078*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * software over-ride. 1079*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1080*2439e4bfSJean-Christophe PLAGNIOL-VILLARD txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR); 1081*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1082*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_fc_full: 1083*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Flow control (both RX and TX) is enabled by a software over-ride. */ 1084*2439e4bfSJean-Christophe PLAGNIOL-VILLARD txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); 1085*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1086*2439e4bfSJean-Christophe PLAGNIOL-VILLARD default: 1087*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Flow control param set incorrectly\n"); 1088*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_CONFIG; 1089*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1090*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1091*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1092*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Since auto-negotiation is enabled, take the link out of reset (the link 1093*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * will be in reset, because we previously reset the chip). This will 1094*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * restart auto-negotiation. If auto-neogtiation is successful then the 1095*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * link-up status bit will be set and the flow control enable bits (RFCE 1096*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * and TFCE) will be set according to their negotiated value. 1097*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1098*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Auto-negotiation enabled (%#x)\n", txcw); 1099*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1100*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TXCW, txcw); 1101*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, ctrl); 1102*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 1103*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1104*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->txcw = txcw; 1105*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdelay(1); 1106*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1107*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* If we have a signal (the cable is plugged in) then poll for a "Link-Up" 1108*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * indication in the Device Status Register. Time-out if a link isn't 1109*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * seen in 500 milliseconds seconds (Auto-negotiation should complete in 1110*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * less than 500 milliseconds even if the other end is doing it in SW). 1111*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1112*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) { 1113*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Looking for Link\n"); 1114*2439e4bfSJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) { 1115*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdelay(10); 1116*2439e4bfSJean-Christophe PLAGNIOL-VILLARD status = E1000_READ_REG(hw, STATUS); 1117*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (status & E1000_STATUS_LU) 1118*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1119*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1120*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (i == (LINK_UP_TIMEOUT / 10)) { 1121*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* AutoNeg failed to achieve a link, so we'll call 1122*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * e1000_check_for_link. This routine will force the link up if we 1123*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * detect a signal. This will allow us to communicate with 1124*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * non-autonegotiating link partners. 1125*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1126*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Never got a valid link from auto-neg!!!\n"); 1127*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->autoneg_failed = 1; 1128*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_check_for_link(nic); 1129*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 1130*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Error while checking for link\n"); 1131*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 1132*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1133*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->autoneg_failed = 0; 1134*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 1135*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->autoneg_failed = 0; 1136*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Valid Link Found\n"); 1137*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1138*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 1139*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("No Signal Detected\n"); 1140*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_NOLINK; 1141*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1142*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 1143*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1144*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1145*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 1146*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Detects which PHY is present and the speed and duplex 1147*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1148*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 1149*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ******************************************************************************/ 1150*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 1151*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_setup_copper_link(struct eth_device *nic) 1152*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1153*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = nic->priv; 1154*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t ctrl; 1155*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int32_t ret_val; 1156*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t i; 1157*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t phy_data; 1158*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1159*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 1160*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1161*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl = E1000_READ_REG(hw, CTRL); 1162*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* With 82543, we need to force speed and duplex on the MAC equal to what 1163*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the PHY speed and duplex configuration is. In addition, we need to 1164*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * perform a hardware reset on the PHY to take it out of reset. 1165*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1166*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type > e1000_82543) { 1167*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl |= E1000_CTRL_SLU; 1168*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); 1169*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, ctrl); 1170*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 1171*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl |= 1172*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU); 1173*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, ctrl); 1174*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_phy_hw_reset(hw); 1175*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1176*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1177*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Make sure we have a valid PHY */ 1178*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_detect_gig_phy(hw); 1179*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 1180*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Error, did not detect valid phy.\n"); 1181*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 1182*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1183*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Phy ID = %x \n", hw->phy_id); 1184*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1185*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Enable CRS on TX. This must be set for half-duplex operation. */ 1186*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) { 1187*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 1188*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1189*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1190*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; 1191*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1192*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 1193*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Options: 1194*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * MDI/MDI-X = 0 (default) 1195*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 0 - Auto for all speeds 1196*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1 - MDI mode 1197*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2 - MDI-X mode 1198*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) 1199*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1200*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; 1201*2439e4bfSJean-Christophe PLAGNIOL-VILLARD switch (hw->mdix) { 1202*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case 1: 1203*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE; 1204*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1205*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case 2: 1206*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE; 1207*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1208*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case 3: 1209*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data |= M88E1000_PSCR_AUTO_X_1000T; 1210*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1211*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case 0: 1212*2439e4bfSJean-Christophe PLAGNIOL-VILLARD default: 1213*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data |= M88E1000_PSCR_AUTO_X_MODE; 1214*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1215*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1216*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #else 1217*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data |= M88E1000_PSCR_AUTO_X_MODE; 1218*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 1219*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1220*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 1221*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Options: 1222*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * disable_polarity_correction = 0 (default) 1223*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Automatic Correction for Reversed Cable Polarity 1224*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 0 - Disabled 1225*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1 - Enabled 1226*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1227*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; 1228*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->disable_polarity_correction == 1) 1229*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; 1230*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #else 1231*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; 1232*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 1233*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) { 1234*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Write Error\n"); 1235*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1236*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1237*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1238*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Force TX_CLK in the Extended PHY Specific Control Register 1239*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * to 25MHz clock. 1240*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1241*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) { 1242*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 1243*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1244*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1245*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data |= M88E1000_EPSCR_TX_CLK_25; 1246*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Configure Master and Slave downshift values */ 1247*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK | 1248*2439e4bfSJean-Christophe PLAGNIOL-VILLARD M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK); 1249*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X | 1250*2439e4bfSJean-Christophe PLAGNIOL-VILLARD M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X); 1251*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data) < 0) { 1252*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Write Error\n"); 1253*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1254*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1255*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1256*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* SW Reset the PHY so all changes take effect */ 1257*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_phy_reset(hw); 1258*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 1259*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Error Resetting the PHY\n"); 1260*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 1261*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1262*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1263*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Options: 1264*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * autoneg = 1 (default) 1265*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * PHY will advertise value(s) parsed from 1266*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * autoneg_advertised and fc 1267*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * autoneg = 0 1268*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * PHY will be set to 10H, 10F, 100H, or 100F 1269*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * depending on value parsed from forced_speed_duplex. 1270*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1271*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1272*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Is autoneg enabled? This is enabled by default or by software override. 1273*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * If so, call e1000_phy_setup_autoneg routine to parse the 1274*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * autoneg_advertised and fc options. If autoneg is NOT enabled, then the 1275*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * user should have provided a speed/duplex override. If so, then call 1276*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * e1000_phy_force_speed_duplex to parse and set this up. 1277*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1278*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Perform some bounds checking on the hw->autoneg_advertised 1279*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * parameter. If this variable is zero, then set it to the default. 1280*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1281*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT; 1282*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1283*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* If autoneg_advertised is zero, we assume it was not defaulted 1284*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * by the calling code so we set to advertise full capability. 1285*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1286*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->autoneg_advertised == 0) 1287*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT; 1288*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1289*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Reconfiguring auto-neg advertisement params\n"); 1290*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_phy_setup_autoneg(hw); 1291*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 1292*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Error Setting up Auto-Negotiation\n"); 1293*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 1294*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1295*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Restarting Auto-Neg\n"); 1296*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1297*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Restart auto-negotiation by setting the Auto Neg Enable bit and 1298*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the Auto Neg Restart bit in the PHY control register. 1299*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1300*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) { 1301*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 1302*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1303*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1304*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); 1305*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) { 1306*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Write Error\n"); 1307*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1308*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1309*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 1310*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Does the user want to wait for Auto-Neg to complete here, or 1311*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * check at a later time (for example, callback routine). 1312*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1313*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->wait_autoneg_complete) { 1314*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_wait_autoneg(hw); 1315*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 1316*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT 1317*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ("Error while waiting for autoneg to complete\n"); 1318*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 1319*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1320*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1321*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #else 1322*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* If we do not wait for autonegtation to complete I 1323*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * do not see a valid link status. 1324*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1325*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_wait_autoneg(hw); 1326*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 1327*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Error while waiting for autoneg to complete\n"); 1328*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 1329*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1330*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 1331*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1332*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Check link status. Wait up to 100 microseconds for link to become 1333*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * valid. 1334*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1335*2439e4bfSJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < 10; i++) { 1336*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { 1337*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 1338*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1339*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1340*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { 1341*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 1342*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1343*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1344*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (phy_data & MII_SR_LINK_STATUS) { 1345*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* We have link, so we need to finish the config process: 1346*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1) Set up the MAC to the current PHY speed/duplex 1347*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * if we are on 82543. If we 1348*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * are on newer silicon, we only need to configure 1349*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * collision distance in the Transmit Control Register. 1350*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2) Set up flow control on the MAC to that established with 1351*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the link partner. 1352*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1353*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type >= e1000_82544) { 1354*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_config_collision_dist(hw); 1355*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 1356*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_config_mac_to_phy(hw); 1357*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 1358*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT 1359*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ("Error configuring MAC to PHY settings\n"); 1360*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 1361*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1362*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1363*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_config_fc_after_link_up(hw); 1364*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 1365*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Error Configuring Flow Control\n"); 1366*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 1367*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1368*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Valid link established!!!\n"); 1369*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 1370*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1371*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(10); 1372*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1373*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1374*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Unable to establish link!!!\n"); 1375*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_NOLINK; 1376*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1377*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1378*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 1379*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Configures PHY autoneg and flow control advertisement settings 1380*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1381*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 1382*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ******************************************************************************/ 1383*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 1384*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_phy_setup_autoneg(struct e1000_hw *hw) 1385*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1386*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t mii_autoneg_adv_reg; 1387*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t mii_1000t_ctrl_reg; 1388*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1389*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 1390*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1391*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Read the MII Auto-Neg Advertisement Register (Address 4). */ 1392*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg) < 0) { 1393*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 1394*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1395*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1396*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1397*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Read the MII 1000Base-T Control Register (Address 9). */ 1398*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg) < 0) { 1399*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 1400*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1401*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1402*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1403*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Need to parse both autoneg_advertised and fc and set up 1404*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the appropriate PHY registers. First we will parse for 1405*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * autoneg_advertised software override. Since we can advertise 1406*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * a plethora of combinations, we need to check each bit 1407*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * individually. 1408*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1409*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1410*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* First we clear all the 10/100 mb speed bits in the Auto-Neg 1411*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Advertisement Register (Address 4) and the 1000 mb speed bits in 1412*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the 1000Base-T Control Register (Address 9). 1413*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1414*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mii_autoneg_adv_reg &= ~REG4_SPEED_MASK; 1415*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK; 1416*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1417*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("autoneg_advertised %x\n", hw->autoneg_advertised); 1418*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1419*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Do we want to advertise 10 Mb Half Duplex? */ 1420*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->autoneg_advertised & ADVERTISE_10_HALF) { 1421*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Advertise 10mb Half duplex\n"); 1422*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS; 1423*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1424*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1425*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Do we want to advertise 10 Mb Full Duplex? */ 1426*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->autoneg_advertised & ADVERTISE_10_FULL) { 1427*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Advertise 10mb Full duplex\n"); 1428*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS; 1429*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1430*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1431*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Do we want to advertise 100 Mb Half Duplex? */ 1432*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->autoneg_advertised & ADVERTISE_100_HALF) { 1433*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Advertise 100mb Half duplex\n"); 1434*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS; 1435*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1436*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1437*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Do we want to advertise 100 Mb Full Duplex? */ 1438*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->autoneg_advertised & ADVERTISE_100_FULL) { 1439*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Advertise 100mb Full duplex\n"); 1440*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS; 1441*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1442*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1443*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* We do not allow the Phy to advertise 1000 Mb Half Duplex */ 1444*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->autoneg_advertised & ADVERTISE_1000_HALF) { 1445*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT 1446*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ("Advertise 1000mb Half duplex requested, request denied!\n"); 1447*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1448*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1449*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Do we want to advertise 1000 Mb Full Duplex? */ 1450*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->autoneg_advertised & ADVERTISE_1000_FULL) { 1451*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Advertise 1000mb Full duplex\n"); 1452*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS; 1453*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1454*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1455*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Check for a software override of the flow control settings, and 1456*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * setup the PHY advertisement registers accordingly. If 1457*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * auto-negotiation is enabled, then software will have to set the 1458*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * "PAUSE" bits to the correct value in the Auto-Negotiation 1459*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation. 1460*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1461*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * The possible values of the "fc" parameter are: 1462*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 0: Flow control is completely disabled 1463*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1: Rx flow control is enabled (we can receive pause frames 1464*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * but not send pause frames). 1465*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2: Tx flow control is enabled (we can send pause frames 1466*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * but we do not support receiving pause frames). 1467*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 3: Both Rx and TX flow control (symmetric) are enabled. 1468*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * other: No software override. The flow control configuration 1469*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * in the EEPROM is used. 1470*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1471*2439e4bfSJean-Christophe PLAGNIOL-VILLARD switch (hw->fc) { 1472*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_fc_none: /* 0 */ 1473*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Flow control (RX & TX) is completely disabled by a 1474*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * software over-ride. 1475*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1476*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); 1477*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1478*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_fc_rx_pause: /* 1 */ 1479*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* RX Flow control is enabled, and TX Flow control is 1480*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * disabled, by a software over-ride. 1481*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1482*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Since there really isn't a way to advertise that we are 1483*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * capable of RX Pause ONLY, we will advertise that we 1484*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * support both symmetric and asymmetric RX PAUSE. Later 1485*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * (in e1000_config_fc_after_link_up) we will disable the 1486*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *hw's ability to send PAUSE frames. 1487*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1488*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); 1489*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1490*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_fc_tx_pause: /* 2 */ 1491*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* TX Flow control is enabled, and RX Flow control is 1492*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * disabled, by a software over-ride. 1493*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1494*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR; 1495*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE; 1496*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1497*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_fc_full: /* 3 */ 1498*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Flow control (both RX and TX) is enabled by a software 1499*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * over-ride. 1500*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1501*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); 1502*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1503*2439e4bfSJean-Christophe PLAGNIOL-VILLARD default: 1504*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Flow control param set incorrectly\n"); 1505*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_CONFIG; 1506*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1507*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1508*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg) < 0) { 1509*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Write Error\n"); 1510*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1511*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1512*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1513*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); 1514*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1515*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg) < 0) { 1516*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Write Error\n"); 1517*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1518*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1519*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 1520*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1521*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1522*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 1523*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Sets the collision distance in the Transmit Control register 1524*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1525*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 1526*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1527*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Link should have been established previously. Reads the speed and duplex 1528*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * information from the Device Status register. 1529*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ******************************************************************************/ 1530*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 1531*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_config_collision_dist(struct e1000_hw *hw) 1532*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1533*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t tctl; 1534*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1535*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tctl = E1000_READ_REG(hw, TCTL); 1536*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1537*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tctl &= ~E1000_TCTL_COLD; 1538*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT; 1539*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1540*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TCTL, tctl); 1541*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 1542*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1543*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1544*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 1545*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Sets MAC speed and duplex settings to reflect the those in the PHY 1546*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1547*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 1548*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * mii_reg - data to write to the MII control register 1549*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1550*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * The contents of the PHY register containing the needed information need to 1551*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * be passed in. 1552*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ******************************************************************************/ 1553*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 1554*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_config_mac_to_phy(struct e1000_hw *hw) 1555*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1556*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t ctrl; 1557*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t phy_data; 1558*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1559*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 1560*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1561*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Read the Device Control Register and set the bits to Force Speed 1562*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * and Duplex. 1563*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1564*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl = E1000_READ_REG(hw, CTRL); 1565*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); 1566*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS); 1567*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1568*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Set up duplex in the Device Control and Transmit Control 1569*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * registers depending on negotiated values. 1570*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1571*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) { 1572*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 1573*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1574*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1575*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (phy_data & M88E1000_PSSR_DPLX) 1576*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl |= E1000_CTRL_FD; 1577*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else 1578*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl &= ~E1000_CTRL_FD; 1579*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1580*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_config_collision_dist(hw); 1581*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1582*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Set up speed in the Device Control register depending on 1583*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * negotiated values. 1584*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1585*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) 1586*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl |= E1000_CTRL_SPD_1000; 1587*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS) 1588*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl |= E1000_CTRL_SPD_100; 1589*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Write the configured values back to the Device Control Reg. */ 1590*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, ctrl); 1591*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 1592*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1593*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1594*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 1595*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Forces the MAC's flow control settings. 1596*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1597*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 1598*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1599*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Sets the TFCE and RFCE bits in the device control register to reflect 1600*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the adapter settings. TFCE and RFCE need to be explicitly set by 1601*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * software when a Copper PHY is used because autonegotiation is managed 1602*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * by the PHY rather than the MAC. Software must also configure these 1603*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * bits when link is forced on a fiber connection. 1604*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 1605*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 1606*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_force_mac_fc(struct e1000_hw *hw) 1607*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1608*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t ctrl; 1609*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1610*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 1611*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1612*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Get the current configuration of the Device Control Register */ 1613*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl = E1000_READ_REG(hw, CTRL); 1614*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1615*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Because we didn't get link via the internal auto-negotiation 1616*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * mechanism (we either forced link or we got link via PHY 1617*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * auto-neg), we have to manually enable/disable transmit an 1618*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * receive flow control. 1619*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1620*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * The "Case" statement below enables/disable flow control 1621*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * according to the "hw->fc" parameter. 1622*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1623*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * The possible values of the "fc" parameter are: 1624*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 0: Flow control is completely disabled 1625*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1: Rx flow control is enabled (we can receive pause 1626*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * frames but not send pause frames). 1627*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2: Tx flow control is enabled (we can send pause frames 1628*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * frames but we do not receive pause frames). 1629*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 3: Both Rx and TX flow control (symmetric) is enabled. 1630*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * other: No other values should be possible at this point. 1631*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1632*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1633*2439e4bfSJean-Christophe PLAGNIOL-VILLARD switch (hw->fc) { 1634*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_fc_none: 1635*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE)); 1636*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1637*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_fc_rx_pause: 1638*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl &= (~E1000_CTRL_TFCE); 1639*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl |= E1000_CTRL_RFCE; 1640*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1641*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_fc_tx_pause: 1642*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl &= (~E1000_CTRL_RFCE); 1643*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl |= E1000_CTRL_TFCE; 1644*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1645*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_fc_full: 1646*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE); 1647*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 1648*2439e4bfSJean-Christophe PLAGNIOL-VILLARD default: 1649*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Flow control param set incorrectly\n"); 1650*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_CONFIG; 1651*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1652*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1653*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Disable TX Flow Control for 82542 (rev 2.0) */ 1654*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type == e1000_82542_rev2_0) 1655*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl &= (~E1000_CTRL_TFCE); 1656*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1657*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, ctrl); 1658*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 1659*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1660*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1661*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 1662*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Configures flow control settings after link is established 1663*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1664*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 1665*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1666*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Should be called immediately after a valid link has been established. 1667*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Forces MAC flow control settings if link was forced. When in MII/GMII mode 1668*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * and autonegotiation is enabled, the MAC flow control settings will be set 1669*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * based on the flow control negotiated by the PHY. In TBI mode, the TFCE 1670*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * and RFCE bits will be automaticaly set to the negotiated flow control mode. 1671*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 1672*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 1673*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_config_fc_after_link_up(struct e1000_hw *hw) 1674*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1675*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int32_t ret_val; 1676*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t mii_status_reg; 1677*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t mii_nway_adv_reg; 1678*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t mii_nway_lp_ability_reg; 1679*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t speed; 1680*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t duplex; 1681*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1682*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 1683*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1684*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Check for the case where we have fiber media and auto-neg failed 1685*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * so we had to force link. In this case, we need to force the 1686*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * configuration of the MAC to match the "fc" parameter. 1687*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1688*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) { 1689*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_force_mac_fc(hw); 1690*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 1691*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Error forcing flow control settings\n"); 1692*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 1693*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1694*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1695*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1696*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Check for the case where we have copper media and auto-neg is 1697*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * enabled. In this case, we need to check and see if Auto-Neg 1698*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * has completed, and if so, how the PHY and link partner has 1699*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * flow control configured. 1700*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1701*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->media_type == e1000_media_type_copper) { 1702*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Read the MII Status Register and check to see if AutoNeg 1703*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * has completed. We read this twice because this reg has 1704*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * some "sticky" (latched) bits. 1705*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1706*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) { 1707*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error \n"); 1708*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1709*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1710*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) { 1711*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error \n"); 1712*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1713*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1714*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1715*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) { 1716*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* The AutoNeg process has completed, so we now need to 1717*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * read both the Auto Negotiation Advertisement Register 1718*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * (Address 4) and the Auto_Negotiation Base Page Ability 1719*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Register (Address 5) to determine how flow control was 1720*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * negotiated. 1721*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1722*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg 1723*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg) < 0) { 1724*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 1725*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1726*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1727*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg 1728*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (hw, PHY_LP_ABILITY, 1729*2439e4bfSJean-Christophe PLAGNIOL-VILLARD &mii_nway_lp_ability_reg) < 0) { 1730*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 1731*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1732*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1733*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1734*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Two bits in the Auto Negotiation Advertisement Register 1735*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * (Address 4) and two bits in the Auto Negotiation Base 1736*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Page Ability Register (Address 5) determine flow control 1737*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * for both the PHY and the link partner. The following 1738*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * table, taken out of the IEEE 802.3ab/D6.0 dated March 25, 1739*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1999, describes these PAUSE resolution bits and how flow 1740*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * control is determined based upon these settings. 1741*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * NOTE: DC = Don't Care 1742*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1743*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * LOCAL DEVICE | LINK PARTNER 1744*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution 1745*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *-------|---------|-------|---------|-------------------- 1746*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 0 | 0 | DC | DC | e1000_fc_none 1747*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 0 | 1 | 0 | DC | e1000_fc_none 1748*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 0 | 1 | 1 | 0 | e1000_fc_none 1749*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 0 | 1 | 1 | 1 | e1000_fc_tx_pause 1750*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1 | 0 | 0 | DC | e1000_fc_none 1751*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1 | DC | 1 | DC | e1000_fc_full 1752*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1 | 1 | 0 | 0 | e1000_fc_none 1753*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1 | 1 | 0 | 1 | e1000_fc_rx_pause 1754*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1755*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1756*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Are both PAUSE bits set to 1? If so, this implies 1757*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Symmetric Flow Control is enabled at both ends. The 1758*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * ASM_DIR bits are irrelevant per the spec. 1759*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1760*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * For Symmetric Flow Control: 1761*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1762*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * LOCAL DEVICE | LINK PARTNER 1763*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result 1764*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *-------|---------|-------|---------|-------------------- 1765*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1 | DC | 1 | DC | e1000_fc_full 1766*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1767*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1768*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && 1769*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) { 1770*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Now we need to check if the user selected RX ONLY 1771*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * of pause frames. In this case, we had to advertise 1772*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * FULL flow control because we could not advertise RX 1773*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * ONLY. Hence, we must now check to see if we need to 1774*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * turn OFF the TRANSMISSION of PAUSE frames. 1775*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1776*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->original_fc == e1000_fc_full) { 1777*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc = e1000_fc_full; 1778*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Flow Control = FULL.\r\n"); 1779*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 1780*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc = e1000_fc_rx_pause; 1781*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT 1782*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ("Flow Control = RX PAUSE frames only.\r\n"); 1783*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1784*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1785*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* For receiving PAUSE frames ONLY. 1786*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1787*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * LOCAL DEVICE | LINK PARTNER 1788*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result 1789*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *-------|---------|-------|---------|-------------------- 1790*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 0 | 1 | 1 | 1 | e1000_fc_tx_pause 1791*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1792*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1793*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) && 1794*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && 1795*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && 1796*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) 1797*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1798*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc = e1000_fc_tx_pause; 1799*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT 1800*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ("Flow Control = TX PAUSE frames only.\r\n"); 1801*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1802*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* For transmitting PAUSE frames ONLY. 1803*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1804*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * LOCAL DEVICE | LINK PARTNER 1805*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result 1806*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *-------|---------|-------|---------|-------------------- 1807*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1 | 1 | 0 | 1 | e1000_fc_rx_pause 1808*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1809*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1810*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && 1811*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && 1812*2439e4bfSJean-Christophe PLAGNIOL-VILLARD !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && 1813*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) 1814*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1815*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc = e1000_fc_rx_pause; 1816*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT 1817*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ("Flow Control = RX PAUSE frames only.\r\n"); 1818*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1819*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Per the IEEE spec, at this point flow control should be 1820*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * disabled. However, we want to consider that we could 1821*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * be connected to a legacy switch that doesn't advertise 1822*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * desired flow control, but can be forced on the link 1823*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * partner. So if we advertised no flow control, that is 1824*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * what we will resolve to. If we advertised some kind of 1825*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * receive capability (Rx Pause Only or Full Flow Control) 1826*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * and the link partner advertised none, we will configure 1827*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * ourselves to enable Rx Flow Control only. We can do 1828*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * this safely for two reasons: If the link partner really 1829*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * didn't want flow control enabled, and we enable Rx, no 1830*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * harm done since we won't be receiving any PAUSE frames 1831*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * anyway. If the intent on the link partner was to have 1832*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * flow control enabled, then by us enabling RX only, we 1833*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * can at least receive pause frames and process them. 1834*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * This is a good idea because in most cases, since we are 1835*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * predominantly a server NIC, more times than not we will 1836*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * be asked to delay transmission of packets than asking 1837*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * our link partner to pause transmission of frames. 1838*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1839*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else if (hw->original_fc == e1000_fc_none || 1840*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->original_fc == e1000_fc_tx_pause) { 1841*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc = e1000_fc_none; 1842*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Flow Control = NONE.\r\n"); 1843*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 1844*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc = e1000_fc_rx_pause; 1845*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT 1846*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ("Flow Control = RX PAUSE frames only.\r\n"); 1847*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1848*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1849*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Now we need to do one last check... If we auto- 1850*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * negotiated to HALF DUPLEX, flow control should not be 1851*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * enabled per IEEE 802.3 spec. 1852*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1853*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_get_speed_and_duplex(hw, &speed, &duplex); 1854*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1855*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (duplex == HALF_DUPLEX) 1856*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc = e1000_fc_none; 1857*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1858*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Now we call a subroutine to actually force the MAC 1859*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * controller to use the correct flow control settings. 1860*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1861*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_force_mac_fc(hw); 1862*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 1863*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT 1864*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ("Error forcing flow control settings\n"); 1865*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 1866*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1867*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 1868*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT 1869*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ("Copper PHY and Auto Neg has not completed.\r\n"); 1870*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1871*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1872*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 1873*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1874*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1875*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 1876*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Checks to see if the link status of the hardware has changed. 1877*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1878*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 1879*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 1880*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Called by any function that needs to check the link status of the adapter. 1881*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 1882*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 1883*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_check_for_link(struct eth_device *nic) 1884*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1885*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = nic->priv; 1886*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t rxcw; 1887*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t ctrl; 1888*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t status; 1889*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t rctl; 1890*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t signal; 1891*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int32_t ret_val; 1892*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t phy_data; 1893*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t lp_capability; 1894*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1895*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 1896*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1897*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be 1898*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * set when the optics detect a signal. On older adapters, it will be 1899*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * cleared when there is a signal 1900*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1901*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl = E1000_READ_REG(hw, CTRL); 1902*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((hw->mac_type > e1000_82544) && !(ctrl & E1000_CTRL_ILOS)) 1903*2439e4bfSJean-Christophe PLAGNIOL-VILLARD signal = E1000_CTRL_SWDPIN1; 1904*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else 1905*2439e4bfSJean-Christophe PLAGNIOL-VILLARD signal = 0; 1906*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1907*2439e4bfSJean-Christophe PLAGNIOL-VILLARD status = E1000_READ_REG(hw, STATUS); 1908*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rxcw = E1000_READ_REG(hw, RXCW); 1909*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("ctrl: %#08x status %#08x rxcw %#08x\n", ctrl, status, rxcw); 1910*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1911*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* If we have a copper PHY then we only want to go out to the PHY 1912*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * registers to see if Auto-Neg has completed and/or if our link 1913*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * status has changed. The get_link_status flag will be set if we 1914*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * receive a Link Status Change interrupt or we have Rx Sequence 1915*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Errors. 1916*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1917*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) { 1918*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* First we want to see if the MII Status Register reports 1919*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * link. If so, then we want to get the current speed/duplex 1920*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * of the PHY. 1921*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Read the register twice since the link bit is sticky. 1922*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1923*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { 1924*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 1925*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1926*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1927*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { 1928*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 1929*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1930*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1931*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1932*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (phy_data & MII_SR_LINK_STATUS) { 1933*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->get_link_status = FALSE; 1934*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 1935*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* No link detected */ 1936*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_NOLINK; 1937*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1938*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1939*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* We have a M88E1000 PHY and Auto-Neg is enabled. If we 1940*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * have Si on board that is 82544 or newer, Auto 1941*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Speed Detection takes care of MAC speed/duplex 1942*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * configuration. So we only need to configure Collision 1943*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Distance in the MAC. Otherwise, we need to force 1944*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * speed/duplex on the MAC to the current PHY speed/duplex 1945*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * settings. 1946*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1947*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type >= e1000_82544) 1948*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_config_collision_dist(hw); 1949*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else { 1950*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_config_mac_to_phy(hw); 1951*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 1952*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT 1953*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ("Error configuring MAC to PHY settings\n"); 1954*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 1955*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1956*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1957*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1958*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Configure Flow Control now that Auto-Neg has completed. First, we 1959*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * need to restore the desired flow control settings because we may 1960*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * have had to re-autoneg with a different link partner. 1961*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1962*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_config_fc_after_link_up(hw); 1963*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 1964*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Error configuring flow control\n"); 1965*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 1966*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1967*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 1968*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* At this point we know that we are on copper and we have 1969*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * auto-negotiated link. These are conditions for checking the link 1970*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * parter capability register. We use the link partner capability to 1971*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * determine if TBI Compatibility needs to be turned on or off. If 1972*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the link partner advertises any speed in addition to Gigabit, then 1973*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * we assume that they are GMII-based, and TBI compatibility is not 1974*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * needed. If no other speeds are advertised, we assume the link 1975*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * partner is TBI-based, and we turn on TBI Compatibility. 1976*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1977*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->tbi_compatibility_en) { 1978*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg 1979*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (hw, PHY_LP_ABILITY, &lp_capability) < 0) { 1980*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 1981*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 1982*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1983*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (lp_capability & (NWAY_LPAR_10T_HD_CAPS | 1984*2439e4bfSJean-Christophe PLAGNIOL-VILLARD NWAY_LPAR_10T_FD_CAPS | 1985*2439e4bfSJean-Christophe PLAGNIOL-VILLARD NWAY_LPAR_100TX_HD_CAPS | 1986*2439e4bfSJean-Christophe PLAGNIOL-VILLARD NWAY_LPAR_100TX_FD_CAPS | 1987*2439e4bfSJean-Christophe PLAGNIOL-VILLARD NWAY_LPAR_100T4_CAPS)) { 1988*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* If our link partner advertises anything in addition to 1989*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * gigabit, we do not need to enable TBI compatibility. 1990*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 1991*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->tbi_compatibility_on) { 1992*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* If we previously were in the mode, turn it off. */ 1993*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl = E1000_READ_REG(hw, RCTL); 1994*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl &= ~E1000_RCTL_SBP; 1995*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RCTL, rctl); 1996*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->tbi_compatibility_on = FALSE; 1997*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1998*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 1999*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* If TBI compatibility is was previously off, turn it on. For 2000*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * compatibility with a TBI link partner, we will store bad 2001*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * packets. Some frames have an additional byte on the end and 2002*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * will look like CRC errors to to the hardware. 2003*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2004*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (!hw->tbi_compatibility_on) { 2005*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->tbi_compatibility_on = TRUE; 2006*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl = E1000_READ_REG(hw, RCTL); 2007*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl |= E1000_RCTL_SBP; 2008*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RCTL, rctl); 2009*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2010*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2011*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2012*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2013*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* If we don't have link (auto-negotiation failed or link partner cannot 2014*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * auto-negotiate), the cable is plugged in (we have signal), and our 2015*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * link partner is not trying to auto-negotiate with us (we are receiving 2016*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * idles or data), we need to force link up. We also need to give 2017*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * auto-negotiation time to complete, in case the cable was just plugged 2018*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * in. The autoneg_failed flag does this. 2019*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2020*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else if ((hw->media_type == e1000_media_type_fiber) && 2021*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (!(status & E1000_STATUS_LU)) && 2022*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ((ctrl & E1000_CTRL_SWDPIN1) == signal) && 2023*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (!(rxcw & E1000_RXCW_C))) { 2024*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->autoneg_failed == 0) { 2025*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->autoneg_failed = 1; 2026*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2027*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2028*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\r\n"); 2029*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2030*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Disable auto-negotiation in the TXCW register */ 2031*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TXCW, (hw->txcw & ~E1000_TXCW_ANE)); 2032*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2033*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Force link-up and also force full-duplex. */ 2034*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl = E1000_READ_REG(hw, CTRL); 2035*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); 2036*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, ctrl); 2037*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2038*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Configure Flow Control after forcing link up. */ 2039*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_config_fc_after_link_up(hw); 2040*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 2041*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Error configuring flow control\n"); 2042*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return ret_val; 2043*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2044*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2045*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* If we are forcing link and we are receiving /C/ ordered sets, re-enable 2046*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * auto-negotiation in the TXCW register and disable forced link in the 2047*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Device Control register in an attempt to auto-negotiate with our link 2048*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * partner. 2049*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2050*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else if ((hw->media_type == e1000_media_type_fiber) && 2051*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { 2052*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT 2053*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ("RXing /C/, enable AutoNeg and stop forcing link.\r\n"); 2054*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TXCW, hw->txcw); 2055*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU)); 2056*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2057*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2058*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2059*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2060*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 2061*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Detects the current speed and duplex settings of the hardware. 2062*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2063*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 2064*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * speed - Speed of the connection 2065*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * duplex - Duplex setting of the connection 2066*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *****************************************************************************/ 2067*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 2068*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_get_speed_and_duplex(struct e1000_hw *hw, 2069*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t * speed, uint16_t * duplex) 2070*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2071*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t status; 2072*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2073*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 2074*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2075*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type >= e1000_82543) { 2076*2439e4bfSJean-Christophe PLAGNIOL-VILLARD status = E1000_READ_REG(hw, STATUS); 2077*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (status & E1000_STATUS_SPEED_1000) { 2078*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *speed = SPEED_1000; 2079*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("1000 Mbs, "); 2080*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else if (status & E1000_STATUS_SPEED_100) { 2081*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *speed = SPEED_100; 2082*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("100 Mbs, "); 2083*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 2084*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *speed = SPEED_10; 2085*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("10 Mbs, "); 2086*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2087*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2088*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (status & E1000_STATUS_FD) { 2089*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *duplex = FULL_DUPLEX; 2090*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Full Duplex\r\n"); 2091*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 2092*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *duplex = HALF_DUPLEX; 2093*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT(" Half Duplex\r\n"); 2094*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2095*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 2096*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("1000 Mbs, Full Duplex\r\n"); 2097*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *speed = SPEED_1000; 2098*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *duplex = FULL_DUPLEX; 2099*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2100*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2101*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2102*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 2103*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Blocks until autoneg completes or times out (~4.5 seconds) 2104*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2105*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 2106*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ******************************************************************************/ 2107*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 2108*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_wait_autoneg(struct e1000_hw *hw) 2109*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2110*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t i; 2111*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t phy_data; 2112*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2113*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 2114*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Waiting for Auto-Neg to complete.\n"); 2115*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2116*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* We will wait for autoneg to complete or 4.5 seconds to expire. */ 2117*2439e4bfSJean-Christophe PLAGNIOL-VILLARD for (i = PHY_AUTO_NEG_TIME; i > 0; i--) { 2118*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Read the MII Status Register and wait for Auto-Neg 2119*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Complete bit to be set. 2120*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2121*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { 2122*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 2123*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 2124*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2125*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { 2126*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 2127*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 2128*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2129*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (phy_data & MII_SR_AUTONEG_COMPLETE) { 2130*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Auto-Neg complete.\n"); 2131*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2132*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2133*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdelay(100); 2134*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2135*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Auto-Neg timedout.\n"); 2136*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_TIMEOUT; 2137*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2138*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2139*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 2140*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Raises the Management Data Clock 2141*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2142*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 2143*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * ctrl - Device control register's current value 2144*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ******************************************************************************/ 2145*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 2146*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_raise_mdi_clk(struct e1000_hw *hw, uint32_t * ctrl) 2147*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2148*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Raise the clock input to the Management Data Clock (by setting the MDC 2149*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * bit), and then delay 2 microseconds. 2150*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2151*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC)); 2152*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 2153*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(2); 2154*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2155*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2156*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 2157*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Lowers the Management Data Clock 2158*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2159*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 2160*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * ctrl - Device control register's current value 2161*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ******************************************************************************/ 2162*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 2163*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_lower_mdi_clk(struct e1000_hw *hw, uint32_t * ctrl) 2164*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2165*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Lower the clock input to the Management Data Clock (by clearing the MDC 2166*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * bit), and then delay 2 microseconds. 2167*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2168*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC)); 2169*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 2170*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(2); 2171*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2172*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2173*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 2174*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Shifts data bits out to the PHY 2175*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2176*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 2177*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * data - Data to send out to the PHY 2178*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * count - Number of bits to shift out 2179*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2180*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Bits are shifted out in MSB to LSB order. 2181*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ******************************************************************************/ 2182*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 2183*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, uint16_t count) 2184*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2185*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t ctrl; 2186*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t mask; 2187*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2188*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* We need to shift "count" number of bits out to the PHY. So, the value 2189*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * in the "data" parameter will be shifted out to the PHY one bit at a 2190*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * time. In order to do this, "data" must be broken down into bits. 2191*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2192*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mask = 0x01; 2193*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mask <<= (count - 1); 2194*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2195*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl = E1000_READ_REG(hw, CTRL); 2196*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2197*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */ 2198*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR); 2199*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2200*2439e4bfSJean-Christophe PLAGNIOL-VILLARD while (mask) { 2201*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and 2202*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * then raising and lowering the Management Data Clock. A "0" is 2203*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * shifted out to the PHY by setting the MDIO bit to "0" and then 2204*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * raising and lowering the clock. 2205*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2206*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (data & mask) 2207*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl |= E1000_CTRL_MDIO; 2208*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else 2209*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl &= ~E1000_CTRL_MDIO; 2210*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2211*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, ctrl); 2212*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 2213*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2214*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(2); 2215*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2216*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_raise_mdi_clk(hw, &ctrl); 2217*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_lower_mdi_clk(hw, &ctrl); 2218*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2219*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mask = mask >> 1; 2220*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2221*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2222*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2223*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 2224*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Shifts data bits in from the PHY 2225*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2226*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 2227*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2228*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Bits are shifted in in MSB to LSB order. 2229*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ******************************************************************************/ 2230*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static uint16_t 2231*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_in_mdi_bits(struct e1000_hw *hw) 2232*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2233*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t ctrl; 2234*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t data = 0; 2235*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint8_t i; 2236*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2237*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* In order to read a register from the PHY, we need to shift in a total 2238*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * of 18 bits from the PHY. The first two bit (turnaround) times are used 2239*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * to avoid contention on the MDIO pin when a read operation is performed. 2240*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * These two bits are ignored by us and thrown away. Bits are "shifted in" 2241*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * by raising the input to the Management Data Clock (setting the MDC bit), 2242*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * and then reading the value of the MDIO bit. 2243*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2244*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl = E1000_READ_REG(hw, CTRL); 2245*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2246*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */ 2247*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl &= ~E1000_CTRL_MDIO_DIR; 2248*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl &= ~E1000_CTRL_MDIO; 2249*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2250*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, ctrl); 2251*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 2252*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2253*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Raise and Lower the clock before reading in the data. This accounts for 2254*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * the turnaround bits. The first clock occurred when we clocked out the 2255*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * last bit of the Register Address. 2256*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2257*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_raise_mdi_clk(hw, &ctrl); 2258*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_lower_mdi_clk(hw, &ctrl); 2259*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2260*2439e4bfSJean-Christophe PLAGNIOL-VILLARD for (data = 0, i = 0; i < 16; i++) { 2261*2439e4bfSJean-Christophe PLAGNIOL-VILLARD data = data << 1; 2262*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_raise_mdi_clk(hw, &ctrl); 2263*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl = E1000_READ_REG(hw, CTRL); 2264*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Check to see if we shifted in a "1". */ 2265*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ctrl & E1000_CTRL_MDIO) 2266*2439e4bfSJean-Christophe PLAGNIOL-VILLARD data |= 1; 2267*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_lower_mdi_clk(hw, &ctrl); 2268*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2269*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2270*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_raise_mdi_clk(hw, &ctrl); 2271*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_lower_mdi_clk(hw, &ctrl); 2272*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2273*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return data; 2274*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2275*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2276*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /***************************************************************************** 2277*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Reads the value from a PHY register 2278*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2279*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 2280*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * reg_addr - address of the PHY register to read 2281*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ******************************************************************************/ 2282*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 2283*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t * phy_data) 2284*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2285*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t i; 2286*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t mdic = 0; 2287*2439e4bfSJean-Christophe PLAGNIOL-VILLARD const uint32_t phy_addr = 1; 2288*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2289*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (reg_addr > MAX_PHY_REG_ADDRESS) { 2290*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Address %d is out of range\n", reg_addr); 2291*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PARAM; 2292*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2293*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2294*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type > e1000_82543) { 2295*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Set up Op-code, Phy Address, and register address in the MDI 2296*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Control register. The MAC will take care of interfacing with the 2297*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * PHY to retrieve the desired data. 2298*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2299*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) | 2300*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (phy_addr << E1000_MDIC_PHY_SHIFT) | 2301*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (E1000_MDIC_OP_READ)); 2302*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2303*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, MDIC, mdic); 2304*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2305*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Poll the ready bit to see if the MDI read completed */ 2306*2439e4bfSJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < 64; i++) { 2307*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(10); 2308*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdic = E1000_READ_REG(hw, MDIC); 2309*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (mdic & E1000_MDIC_READY) 2310*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 2311*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2312*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (!(mdic & E1000_MDIC_READY)) { 2313*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("MDI Read did not complete\n"); 2314*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 2315*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2316*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (mdic & E1000_MDIC_ERROR) { 2317*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("MDI Error\n"); 2318*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 2319*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2320*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *phy_data = (uint16_t) mdic; 2321*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 2322*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* We must first send a preamble through the MDIO pin to signal the 2323*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * beginning of an MII instruction. This is done by sending 32 2324*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * consecutive "1" bits. 2325*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2326*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE); 2327*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2328*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Now combine the next few fields that are required for a read 2329*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * operation. We use this method instead of calling the 2330*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * e1000_shift_out_mdi_bits routine five different times. The format of 2331*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * a MII read instruction consists of a shift out of 14 bits and is 2332*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * defined as follows: 2333*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * <Preamble><SOF><Op Code><Phy Addr><Reg Addr> 2334*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * followed by a shift in of 18 bits. This first two bits shifted in 2335*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * are TurnAround bits used to avoid contention on the MDIO pin when a 2336*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * READ operation is performed. These two bits are thrown away 2337*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * followed by a shift in of 16 bits which contains the desired data. 2338*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2339*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdic = ((reg_addr) | (phy_addr << 5) | 2340*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (PHY_OP_READ << 10) | (PHY_SOF << 12)); 2341*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2342*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_mdi_bits(hw, mdic, 14); 2343*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2344*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Now that we've shifted out the read command to the MII, we need to 2345*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * "shift in" the 16-bit value (18 total bits) of the requested PHY 2346*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * register address. 2347*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2348*2439e4bfSJean-Christophe PLAGNIOL-VILLARD *phy_data = e1000_shift_in_mdi_bits(hw); 2349*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2350*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2351*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2352*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2353*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 2354*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Writes a value to a PHY register 2355*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2356*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 2357*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * reg_addr - address of the PHY register to write 2358*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * data - data to write to the PHY 2359*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ******************************************************************************/ 2360*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 2361*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t phy_data) 2362*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2363*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t i; 2364*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t mdic = 0; 2365*2439e4bfSJean-Christophe PLAGNIOL-VILLARD const uint32_t phy_addr = 1; 2366*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2367*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (reg_addr > MAX_PHY_REG_ADDRESS) { 2368*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Address %d is out of range\n", reg_addr); 2369*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PARAM; 2370*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2371*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2372*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type > e1000_82543) { 2373*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Set up Op-code, Phy Address, register address, and data intended 2374*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * for the PHY register in the MDI Control register. The MAC will take 2375*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * care of interfacing with the PHY to send the desired data. 2376*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2377*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdic = (((uint32_t) phy_data) | 2378*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (reg_addr << E1000_MDIC_REG_SHIFT) | 2379*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (phy_addr << E1000_MDIC_PHY_SHIFT) | 2380*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (E1000_MDIC_OP_WRITE)); 2381*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2382*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, MDIC, mdic); 2383*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2384*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Poll the ready bit to see if the MDI read completed */ 2385*2439e4bfSJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < 64; i++) { 2386*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(10); 2387*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdic = E1000_READ_REG(hw, MDIC); 2388*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (mdic & E1000_MDIC_READY) 2389*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 2390*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2391*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (!(mdic & E1000_MDIC_READY)) { 2392*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("MDI Write did not complete\n"); 2393*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 2394*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2395*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 2396*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* We'll need to use the SW defined pins to shift the write command 2397*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * out to the PHY. We first send a preamble to the PHY to signal the 2398*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * beginning of the MII instruction. This is done by sending 32 2399*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * consecutive "1" bits. 2400*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2401*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE); 2402*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2403*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Now combine the remaining required fields that will indicate a 2404*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * write operation. We use this method instead of calling the 2405*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * e1000_shift_out_mdi_bits routine for each field in the command. The 2406*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * format of a MII write instruction is as follows: 2407*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>. 2408*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2409*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) | 2410*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (PHY_OP_WRITE << 12) | (PHY_SOF << 14)); 2411*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdic <<= 16; 2412*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdic |= (uint32_t) phy_data; 2413*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2414*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_shift_out_mdi_bits(hw, mdic, 32); 2415*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2416*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2417*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2418*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2419*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 2420*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Returns the PHY to the power-on reset state 2421*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2422*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 2423*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ******************************************************************************/ 2424*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 2425*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_phy_hw_reset(struct e1000_hw *hw) 2426*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2427*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t ctrl; 2428*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t ctrl_ext; 2429*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2430*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 2431*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2432*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Resetting Phy...\n"); 2433*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2434*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type > e1000_82543) { 2435*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Read the device control register and assert the E1000_CTRL_PHY_RST 2436*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * bit. Then, take it out of reset. 2437*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2438*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl = E1000_READ_REG(hw, CTRL); 2439*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST); 2440*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 2441*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdelay(10); 2442*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, ctrl); 2443*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 2444*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 2445*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Read the Extended Device Control Register, assert the PHY_RESET_DIR 2446*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * bit to put the PHY into reset. Then, take it out of reset. 2447*2439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 2448*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); 2449*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR; 2450*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA; 2451*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); 2452*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 2453*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdelay(10); 2454*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA; 2455*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); 2456*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_FLUSH(hw); 2457*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2458*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(150); 2459*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2460*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2461*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 2462*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Resets the PHY 2463*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2464*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 2465*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2466*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Sets bit 15 of the MII Control regiser 2467*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ******************************************************************************/ 2468*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 2469*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_phy_reset(struct e1000_hw *hw) 2470*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2471*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t phy_data; 2472*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2473*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 2474*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2475*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) { 2476*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 2477*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 2478*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2479*2439e4bfSJean-Christophe PLAGNIOL-VILLARD phy_data |= MII_CR_RESET; 2480*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) { 2481*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Write Error\n"); 2482*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 2483*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2484*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(1); 2485*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2486*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2487*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2488*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /****************************************************************************** 2489*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Probes the expected PHY address for known PHY IDs 2490*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2491*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * hw - Struct containing variables accessed by shared code 2492*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ******************************************************************************/ 2493*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 2494*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_detect_gig_phy(struct e1000_hw *hw) 2495*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2496*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint16_t phy_id_high, phy_id_low; 2497*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int match = FALSE; 2498*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2499*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGFUNC(); 2500*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2501*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Read the PHY ID Registers to identify which PHY is onboard. */ 2502*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high) < 0) { 2503*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 2504*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 2505*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2506*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->phy_id = (uint32_t) (phy_id_high << 16); 2507*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(2); 2508*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low) < 0) { 2509*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY Read Error\n"); 2510*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 2511*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2512*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK); 2513*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2514*2439e4bfSJean-Christophe PLAGNIOL-VILLARD switch (hw->mac_type) { 2515*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_82543: 2516*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->phy_id == M88E1000_E_PHY_ID) 2517*2439e4bfSJean-Christophe PLAGNIOL-VILLARD match = TRUE; 2518*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 2519*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_82544: 2520*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->phy_id == M88E1000_I_PHY_ID) 2521*2439e4bfSJean-Christophe PLAGNIOL-VILLARD match = TRUE; 2522*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 2523*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_82540: 2524*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_82545: 2525*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_82546: 2526*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->phy_id == M88E1011_I_PHY_ID) 2527*2439e4bfSJean-Christophe PLAGNIOL-VILLARD match = TRUE; 2528*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 2529*2439e4bfSJean-Christophe PLAGNIOL-VILLARD default: 2530*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Invalid MAC type %d\n", hw->mac_type); 2531*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_CONFIG; 2532*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2533*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (match) { 2534*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("PHY ID 0x%X detected\n", hw->phy_id); 2535*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2536*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2537*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("Invalid PHY ID 0x%X\n", hw->phy_id); 2538*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return -E1000_ERR_PHY; 2539*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2540*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2541*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /** 2542*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * e1000_sw_init - Initialize general software structures (struct e1000_adapter) 2543*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2544*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * e1000_sw_init initializes the Adapter private data structure. 2545*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Fields are initialized based on PCI device information and 2546*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * OS network device settings (MTU size). 2547*2439e4bfSJean-Christophe PLAGNIOL-VILLARD **/ 2548*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2549*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 2550*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_sw_init(struct eth_device *nic, int cardnum) 2551*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2552*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = (typeof(hw)) nic->priv; 2553*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int result; 2554*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2555*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* PCI config space info */ 2556*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_read_config_word(hw->pdev, PCI_VENDOR_ID, &hw->vendor_id); 2557*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_read_config_word(hw->pdev, PCI_DEVICE_ID, &hw->device_id); 2558*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_read_config_word(hw->pdev, PCI_SUBSYSTEM_VENDOR_ID, 2559*2439e4bfSJean-Christophe PLAGNIOL-VILLARD &hw->subsystem_vendor_id); 2560*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_read_config_word(hw->pdev, PCI_SUBSYSTEM_ID, &hw->subsystem_id); 2561*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2562*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_read_config_byte(hw->pdev, PCI_REVISION_ID, &hw->revision_id); 2563*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_read_config_word(hw->pdev, PCI_COMMAND, &hw->pci_cmd_word); 2564*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2565*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* identify the MAC */ 2566*2439e4bfSJean-Christophe PLAGNIOL-VILLARD result = e1000_set_mac_type(hw); 2567*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (result) { 2568*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_ERR("Unknown MAC Type\n"); 2569*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return result; 2570*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2571*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2572*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* lan a vs. lan b settings */ 2573*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type == e1000_82546) 2574*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /*this also works w/ multiple 82546 cards */ 2575*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /*but not if they're intermingled /w other e1000s */ 2576*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->lan_loc = (cardnum % 2) ? e1000_lan_b : e1000_lan_a; 2577*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else 2578*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->lan_loc = e1000_lan_a; 2579*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2580*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* flow control settings */ 2581*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc_high_water = E1000_FC_HIGH_THRESH; 2582*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc_low_water = E1000_FC_LOW_THRESH; 2583*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc_pause_time = E1000_FC_PAUSE_TIME; 2584*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc_send_xon = 1; 2585*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2586*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Media type - copper or fiber */ 2587*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2588*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type >= e1000_82543) { 2589*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t status = E1000_READ_REG(hw, STATUS); 2590*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2591*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (status & E1000_STATUS_TBIMODE) { 2592*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("fiber interface\n"); 2593*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->media_type = e1000_media_type_fiber; 2594*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 2595*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("copper interface\n"); 2596*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->media_type = e1000_media_type_copper; 2597*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2598*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 2599*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->media_type = e1000_media_type_fiber; 2600*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2601*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2602*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type < e1000_82543) 2603*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->report_tx_early = 0; 2604*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else 2605*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->report_tx_early = 1; 2606*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2607*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->tbi_compatibility_en = TRUE; 2608*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 2609*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->wait_autoneg_complete = FALSE; 2610*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->adaptive_ifs = TRUE; 2611*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2612*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Copper options */ 2613*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->media_type == e1000_media_type_copper) { 2614*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->mdix = AUTO_ALL_MODES; 2615*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->disable_polarity_correction = FALSE; 2616*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2617*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 2618*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return E1000_SUCCESS; 2619*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2620*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2621*2439e4bfSJean-Christophe PLAGNIOL-VILLARD void 2622*2439e4bfSJean-Christophe PLAGNIOL-VILLARD fill_rx(struct e1000_hw *hw) 2623*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2624*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_rx_desc *rd; 2625*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2626*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rx_last = rx_tail; 2627*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rd = rx_base + rx_tail; 2628*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rx_tail = (rx_tail + 1) % 8; 2629*2439e4bfSJean-Christophe PLAGNIOL-VILLARD memset(rd, 0, 16); 2630*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rd->buffer_addr = cpu_to_le64((u32) & packet); 2631*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RDT, rx_tail); 2632*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2633*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2634*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /** 2635*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * e1000_configure_tx - Configure 8254x Transmit Unit after Reset 2636*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * @adapter: board private structure 2637*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2638*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Configure the Tx unit of the MAC after a reset. 2639*2439e4bfSJean-Christophe PLAGNIOL-VILLARD **/ 2640*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2641*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 2642*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_configure_tx(struct e1000_hw *hw) 2643*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2644*2439e4bfSJean-Christophe PLAGNIOL-VILLARD unsigned long ptr; 2645*2439e4bfSJean-Christophe PLAGNIOL-VILLARD unsigned long tctl; 2646*2439e4bfSJean-Christophe PLAGNIOL-VILLARD unsigned long tipg; 2647*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2648*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ptr = (u32) tx_pool; 2649*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ptr & 0xf) 2650*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ptr = (ptr + 0x10) & (~0xf); 2651*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2652*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tx_base = (typeof(tx_base)) ptr; 2653*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2654*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TDBAL, (u32) tx_base); 2655*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TDBAH, 0); 2656*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2657*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TDLEN, 128); 2658*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2659*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Setup the HW Tx Head and Tail descriptor pointers */ 2660*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TDH, 0); 2661*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TDT, 0); 2662*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tx_tail = 0; 2663*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2664*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Set the default values for the Tx Inter Packet Gap timer */ 2665*2439e4bfSJean-Christophe PLAGNIOL-VILLARD switch (hw->mac_type) { 2666*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_82542_rev2_0: 2667*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case e1000_82542_rev2_1: 2668*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tipg = DEFAULT_82542_TIPG_IPGT; 2669*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT; 2670*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT; 2671*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 2672*2439e4bfSJean-Christophe PLAGNIOL-VILLARD default: 2673*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->media_type == e1000_media_type_fiber) 2674*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tipg = DEFAULT_82543_TIPG_IPGT_FIBER; 2675*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else 2676*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tipg = DEFAULT_82543_TIPG_IPGT_COPPER; 2677*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT; 2678*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT; 2679*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2680*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TIPG, tipg); 2681*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 2682*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Set the Tx Interrupt Delay register */ 2683*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TIDV, adapter->tx_int_delay); 2684*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type >= e1000_82540) 2685*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay); 2686*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 2687*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Program the Transmit Control Register */ 2688*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tctl = E1000_READ_REG(hw, TCTL); 2689*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tctl &= ~E1000_TCTL_CT; 2690*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tctl |= E1000_TCTL_EN | E1000_TCTL_PSP | 2691*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); 2692*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TCTL, tctl); 2693*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2694*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_config_collision_dist(hw); 2695*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 2696*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Setup Transmit Descriptor Settings for this adapter */ 2697*2439e4bfSJean-Christophe PLAGNIOL-VILLARD adapter->txd_cmd = E1000_TXD_CMD_IFCS | E1000_TXD_CMD_IDE; 2698*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2699*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (adapter->hw.report_tx_early == 1) 2700*2439e4bfSJean-Christophe PLAGNIOL-VILLARD adapter->txd_cmd |= E1000_TXD_CMD_RS; 2701*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else 2702*2439e4bfSJean-Christophe PLAGNIOL-VILLARD adapter->txd_cmd |= E1000_TXD_CMD_RPS; 2703*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 2704*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2705*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2706*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /** 2707*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * e1000_setup_rctl - configure the receive control register 2708*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * @adapter: Board private structure 2709*2439e4bfSJean-Christophe PLAGNIOL-VILLARD **/ 2710*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 2711*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_setup_rctl(struct e1000_hw *hw) 2712*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2713*2439e4bfSJean-Christophe PLAGNIOL-VILLARD uint32_t rctl; 2714*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2715*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl = E1000_READ_REG(hw, RCTL); 2716*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2717*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl &= ~(3 << E1000_RCTL_MO_SHIFT); 2718*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2719*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF; /* | 2720*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (hw.mc_filter_type << E1000_RCTL_MO_SHIFT); */ 2721*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2722*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->tbi_compatibility_on == 1) 2723*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl |= E1000_RCTL_SBP; 2724*2439e4bfSJean-Christophe PLAGNIOL-VILLARD else 2725*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl &= ~E1000_RCTL_SBP; 2726*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2727*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl &= ~(E1000_RCTL_SZ_4096); 2728*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 2729*2439e4bfSJean-Christophe PLAGNIOL-VILLARD switch (adapter->rx_buffer_len) { 2730*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_RXBUFFER_2048: 2731*2439e4bfSJean-Christophe PLAGNIOL-VILLARD default: 2732*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 2733*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl |= E1000_RCTL_SZ_2048; 2734*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl &= ~(E1000_RCTL_BSEX | E1000_RCTL_LPE); 2735*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 2736*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 2737*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_RXBUFFER_4096: 2738*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX | E1000_RCTL_LPE; 2739*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 2740*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_RXBUFFER_8192: 2741*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX | E1000_RCTL_LPE; 2742*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 2743*2439e4bfSJean-Christophe PLAGNIOL-VILLARD case E1000_RXBUFFER_16384: 2744*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl |= E1000_RCTL_SZ_16384 | E1000_RCTL_BSEX | E1000_RCTL_LPE; 2745*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 2746*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2747*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 2748*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RCTL, rctl); 2749*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2750*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2751*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /** 2752*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * e1000_configure_rx - Configure 8254x Receive Unit after Reset 2753*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * @adapter: board private structure 2754*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * 2755*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * Configure the Rx unit of the MAC after a reset. 2756*2439e4bfSJean-Christophe PLAGNIOL-VILLARD **/ 2757*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 2758*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_configure_rx(struct e1000_hw *hw) 2759*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2760*2439e4bfSJean-Christophe PLAGNIOL-VILLARD unsigned long ptr; 2761*2439e4bfSJean-Christophe PLAGNIOL-VILLARD unsigned long rctl; 2762*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 2763*2439e4bfSJean-Christophe PLAGNIOL-VILLARD unsigned long rxcsum; 2764*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 2765*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rx_tail = 0; 2766*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* make sure receives are disabled while setting up the descriptors */ 2767*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rctl = E1000_READ_REG(hw, RCTL); 2768*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); 2769*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 2770*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* set the Receive Delay Timer Register */ 2771*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2772*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RDTR, adapter->rx_int_delay); 2773*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 2774*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type >= e1000_82540) { 2775*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 2776*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay); 2777*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 2778*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Set the interrupt throttling rate. Value is calculated 2779*2439e4bfSJean-Christophe PLAGNIOL-VILLARD * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) */ 2780*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #define MAX_INTS_PER_SEC 8000 2781*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #define DEFAULT_ITR 1000000000/(MAX_INTS_PER_SEC * 256) 2782*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, ITR, DEFAULT_ITR); 2783*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2784*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2785*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Setup the Base and Length of the Rx Descriptor Ring */ 2786*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ptr = (u32) rx_pool; 2787*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ptr & 0xf) 2788*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ptr = (ptr + 0x10) & (~0xf); 2789*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rx_base = (typeof(rx_base)) ptr; 2790*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RDBAL, (u32) rx_base); 2791*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RDBAH, 0); 2792*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2793*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RDLEN, 128); 2794*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2795*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Setup the HW Rx Head and Tail Descriptor Pointers */ 2796*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RDH, 0); 2797*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RDT, 0); 2798*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 2799*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Enable 82543 Receive Checksum Offload for TCP and UDP */ 2800*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((adapter->hw.mac_type >= e1000_82543) && (adapter->rx_csum == TRUE)) { 2801*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rxcsum = E1000_READ_REG(hw, RXCSUM); 2802*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rxcsum |= E1000_RXCSUM_TUOFL; 2803*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RXCSUM, rxcsum); 2804*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2805*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 2806*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Enable Receives */ 2807*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2808*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RCTL, rctl); 2809*2439e4bfSJean-Christophe PLAGNIOL-VILLARD fill_rx(hw); 2810*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2811*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2812*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /************************************************************************** 2813*2439e4bfSJean-Christophe PLAGNIOL-VILLARD POLL - Wait for a frame 2814*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ***************************************************************************/ 2815*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 2816*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_poll(struct eth_device *nic) 2817*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2818*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = nic->priv; 2819*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_rx_desc *rd; 2820*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* return true if there's an ethernet packet ready to read */ 2821*2439e4bfSJean-Christophe PLAGNIOL-VILLARD rd = rx_base + rx_last; 2822*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (!(le32_to_cpu(rd->status)) & E1000_RXD_STAT_DD) 2823*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2824*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /*DEBUGOUT("recv: packet len=%d \n", rd->length); */ 2825*2439e4bfSJean-Christophe PLAGNIOL-VILLARD NetReceive((uchar *)packet, le32_to_cpu(rd->length)); 2826*2439e4bfSJean-Christophe PLAGNIOL-VILLARD fill_rx(hw); 2827*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 1; 2828*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2829*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2830*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /************************************************************************** 2831*2439e4bfSJean-Christophe PLAGNIOL-VILLARD TRANSMIT - Transmit a frame 2832*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ***************************************************************************/ 2833*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 2834*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_transmit(struct eth_device *nic, volatile void *packet, int length) 2835*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2836*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = nic->priv; 2837*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_tx_desc *txp; 2838*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int i = 0; 2839*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2840*2439e4bfSJean-Christophe PLAGNIOL-VILLARD txp = tx_base + tx_tail; 2841*2439e4bfSJean-Christophe PLAGNIOL-VILLARD tx_tail = (tx_tail + 1) % 8; 2842*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2843*2439e4bfSJean-Christophe PLAGNIOL-VILLARD txp->buffer_addr = cpu_to_le64(virt_to_bus(packet)); 2844*2439e4bfSJean-Christophe PLAGNIOL-VILLARD txp->lower.data = cpu_to_le32(E1000_TXD_CMD_RPS | E1000_TXD_CMD_EOP | 2845*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_TXD_CMD_IFCS | length); 2846*2439e4bfSJean-Christophe PLAGNIOL-VILLARD txp->upper.data = 0; 2847*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TDT, tx_tail); 2848*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2849*2439e4bfSJean-Christophe PLAGNIOL-VILLARD while (!(le32_to_cpu(txp->upper.data) & E1000_TXD_STAT_DD)) { 2850*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (i++ > TOUT_LOOP) { 2851*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("e1000: tx timeout\n"); 2852*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2853*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2854*2439e4bfSJean-Christophe PLAGNIOL-VILLARD udelay(10); /* give the nic a chance to write to the register */ 2855*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2856*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 1; 2857*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2858*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2859*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /*reset function*/ 2860*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static inline int 2861*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_reset(struct eth_device *nic) 2862*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2863*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = nic->priv; 2864*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2865*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_reset_hw(hw); 2866*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (hw->mac_type >= e1000_82544) { 2867*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, WUC, 0); 2868*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2869*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return e1000_init_hw(nic); 2870*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2871*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2872*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /************************************************************************** 2873*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DISABLE - Turn off ethernet interface 2874*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ***************************************************************************/ 2875*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static void 2876*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_disable(struct eth_device *nic) 2877*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2878*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = nic->priv; 2879*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2880*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Turn off the ethernet interface */ 2881*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RCTL, 0); 2882*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TCTL, 0); 2883*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2884*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Clear the transmit ring */ 2885*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TDH, 0); 2886*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, TDT, 0); 2887*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2888*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Clear the receive ring */ 2889*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RDH, 0); 2890*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, RDT, 0); 2891*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2892*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* put the card in its initial state */ 2893*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 2894*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, CTRL, E1000_CTRL_RST); 2895*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 2896*2439e4bfSJean-Christophe PLAGNIOL-VILLARD mdelay(10); 2897*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2898*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2899*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2900*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /************************************************************************** 2901*2439e4bfSJean-Christophe PLAGNIOL-VILLARD INIT - set up ethernet interface(s) 2902*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ***************************************************************************/ 2903*2439e4bfSJean-Christophe PLAGNIOL-VILLARD static int 2904*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_init(struct eth_device *nic, bd_t * bis) 2905*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2906*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = nic->priv; 2907*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int ret_val = 0; 2908*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2909*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ret_val = e1000_reset(nic); 2910*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (ret_val < 0) { 2911*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((ret_val == -E1000_ERR_NOLINK) || 2912*2439e4bfSJean-Christophe PLAGNIOL-VILLARD (ret_val == -E1000_ERR_TIMEOUT)) { 2913*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_ERR("Valid Link not detected\n"); 2914*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 2915*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_ERR("Hardware Initialization Failed\n"); 2916*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2917*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2918*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2919*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_configure_tx(hw); 2920*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_setup_rctl(hw); 2921*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_configure_rx(hw); 2922*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 1; 2923*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2924*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2925*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /************************************************************************** 2926*2439e4bfSJean-Christophe PLAGNIOL-VILLARD PROBE - Look for an adapter, this routine's visible to the outside 2927*2439e4bfSJean-Christophe PLAGNIOL-VILLARD You should omit the last argument struct pci_device * for a non-PCI NIC 2928*2439e4bfSJean-Christophe PLAGNIOL-VILLARD ***************************************************************************/ 2929*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int 2930*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_initialize(bd_t * bis) 2931*2439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2932*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_dev_t devno; 2933*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int card_number = 0; 2934*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct eth_device *nic = NULL; 2935*2439e4bfSJean-Christophe PLAGNIOL-VILLARD struct e1000_hw *hw = NULL; 2936*2439e4bfSJean-Christophe PLAGNIOL-VILLARD u32 iobase; 2937*2439e4bfSJean-Christophe PLAGNIOL-VILLARD int idx = 0; 2938*2439e4bfSJean-Christophe PLAGNIOL-VILLARD u32 PciCommandWord; 2939*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2940*2439e4bfSJean-Christophe PLAGNIOL-VILLARD while (1) { /* Find PCI device(s) */ 2941*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((devno = pci_find_devices(supported, idx++)) < 0) { 2942*2439e4bfSJean-Christophe PLAGNIOL-VILLARD break; 2943*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2944*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2945*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase); 2946*2439e4bfSJean-Christophe PLAGNIOL-VILLARD iobase &= ~0xf; /* Mask the bits that say "this is an io addr" */ 2947*2439e4bfSJean-Christophe PLAGNIOL-VILLARD DEBUGOUT("e1000#%d: iobase 0x%08x\n", card_number, iobase); 2948*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2949*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_write_config_dword(devno, PCI_COMMAND, 2950*2439e4bfSJean-Christophe PLAGNIOL-VILLARD PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); 2951*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Check if I/O accesses and Bus Mastering are enabled. */ 2952*2439e4bfSJean-Christophe PLAGNIOL-VILLARD pci_read_config_dword(devno, PCI_COMMAND, &PciCommandWord); 2953*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (!(PciCommandWord & PCI_COMMAND_MEMORY)) { 2954*2439e4bfSJean-Christophe PLAGNIOL-VILLARD printf("Error: Can not enable MEM access.\n"); 2955*2439e4bfSJean-Christophe PLAGNIOL-VILLARD continue; 2956*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } else if (!(PciCommandWord & PCI_COMMAND_MASTER)) { 2957*2439e4bfSJean-Christophe PLAGNIOL-VILLARD printf("Error: Can not enable Bus Mastering.\n"); 2958*2439e4bfSJean-Christophe PLAGNIOL-VILLARD continue; 2959*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2960*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2961*2439e4bfSJean-Christophe PLAGNIOL-VILLARD nic = (struct eth_device *) malloc(sizeof (*nic)); 2962*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw = (struct e1000_hw *) malloc(sizeof (*hw)); 2963*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->pdev = devno; 2964*2439e4bfSJean-Christophe PLAGNIOL-VILLARD nic->priv = hw; 2965*2439e4bfSJean-Christophe PLAGNIOL-VILLARD nic->iobase = bus_to_phys(devno, iobase); 2966*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2967*2439e4bfSJean-Christophe PLAGNIOL-VILLARD sprintf(nic->name, "e1000#%d", card_number); 2968*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2969*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Are these variables needed? */ 2970*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #if 0 2971*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc = e1000_fc_none; 2972*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->original_fc = e1000_fc_none; 2973*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #else 2974*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->fc = e1000_fc_default; 2975*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->original_fc = e1000_fc_default; 2976*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 2977*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->autoneg_failed = 0; 2978*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->get_link_status = TRUE; 2979*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->hw_addr = (typeof(hw->hw_addr)) iobase; 2980*2439e4bfSJean-Christophe PLAGNIOL-VILLARD hw->mac_type = e1000_undefined; 2981*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2982*2439e4bfSJean-Christophe PLAGNIOL-VILLARD /* MAC and Phy settings */ 2983*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_sw_init(nic, card_number) < 0) { 2984*2439e4bfSJean-Christophe PLAGNIOL-VILLARD free(hw); 2985*2439e4bfSJean-Christophe PLAGNIOL-VILLARD free(nic); 2986*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2987*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2988*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_AP1000 2989*2439e4bfSJean-Christophe PLAGNIOL-VILLARD if (e1000_validate_eeprom_checksum(nic) < 0) { 2990*2439e4bfSJean-Christophe PLAGNIOL-VILLARD printf("The EEPROM Checksum Is Not Valid\n"); 2991*2439e4bfSJean-Christophe PLAGNIOL-VILLARD free(hw); 2992*2439e4bfSJean-Christophe PLAGNIOL-VILLARD free(nic); 2993*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2994*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2995*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 2996*2439e4bfSJean-Christophe PLAGNIOL-VILLARD e1000_read_mac_addr(nic); 2997*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 2998*2439e4bfSJean-Christophe PLAGNIOL-VILLARD E1000_WRITE_REG(hw, PBA, E1000_DEFAULT_PBA); 2999*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 3000*2439e4bfSJean-Christophe PLAGNIOL-VILLARD printf("e1000: %02x:%02x:%02x:%02x:%02x:%02x\n", 3001*2439e4bfSJean-Christophe PLAGNIOL-VILLARD nic->enetaddr[0], nic->enetaddr[1], nic->enetaddr[2], 3002*2439e4bfSJean-Christophe PLAGNIOL-VILLARD nic->enetaddr[3], nic->enetaddr[4], nic->enetaddr[5]); 3003*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 3004*2439e4bfSJean-Christophe PLAGNIOL-VILLARD nic->init = e1000_init; 3005*2439e4bfSJean-Christophe PLAGNIOL-VILLARD nic->recv = e1000_poll; 3006*2439e4bfSJean-Christophe PLAGNIOL-VILLARD nic->send = e1000_transmit; 3007*2439e4bfSJean-Christophe PLAGNIOL-VILLARD nic->halt = e1000_disable; 3008*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 3009*2439e4bfSJean-Christophe PLAGNIOL-VILLARD eth_register(nic); 3010*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 3011*2439e4bfSJean-Christophe PLAGNIOL-VILLARD card_number++; 3012*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 3013*2439e4bfSJean-Christophe PLAGNIOL-VILLARD return 1; 3014*2439e4bfSJean-Christophe PLAGNIOL-VILLARD } 3015*2439e4bfSJean-Christophe PLAGNIOL-VILLARD 3016*2439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif 3017