18cfa0ad2SJack F Vogel /****************************************************************************** 28cfa0ad2SJack F Vogel 3*8cc64f1eSJack F Vogel Copyright (c) 2001-2014, Intel Corporation 48cfa0ad2SJack F Vogel All rights reserved. 58cfa0ad2SJack F Vogel 68cfa0ad2SJack F Vogel Redistribution and use in source and binary forms, with or without 78cfa0ad2SJack F Vogel modification, are permitted provided that the following conditions are met: 88cfa0ad2SJack F Vogel 98cfa0ad2SJack F Vogel 1. Redistributions of source code must retain the above copyright notice, 108cfa0ad2SJack F Vogel this list of conditions and the following disclaimer. 118cfa0ad2SJack F Vogel 128cfa0ad2SJack F Vogel 2. Redistributions in binary form must reproduce the above copyright 138cfa0ad2SJack F Vogel notice, this list of conditions and the following disclaimer in the 148cfa0ad2SJack F Vogel documentation and/or other materials provided with the distribution. 158cfa0ad2SJack F Vogel 168cfa0ad2SJack F Vogel 3. Neither the name of the Intel Corporation nor the names of its 178cfa0ad2SJack F Vogel contributors may be used to endorse or promote products derived from 188cfa0ad2SJack F Vogel this software without specific prior written permission. 198cfa0ad2SJack F Vogel 208cfa0ad2SJack F Vogel THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 218cfa0ad2SJack F Vogel AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 228cfa0ad2SJack F Vogel IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 238cfa0ad2SJack F Vogel ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 248cfa0ad2SJack F Vogel LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 258cfa0ad2SJack F Vogel CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 268cfa0ad2SJack F Vogel SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 278cfa0ad2SJack F Vogel INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 288cfa0ad2SJack F Vogel CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 298cfa0ad2SJack F Vogel ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 308cfa0ad2SJack F Vogel POSSIBILITY OF SUCH DAMAGE. 318cfa0ad2SJack F Vogel 328cfa0ad2SJack F Vogel ******************************************************************************/ 338cfa0ad2SJack F Vogel /*$FreeBSD$*/ 348cfa0ad2SJack F Vogel 35daf9197cSJack F Vogel /* 36daf9197cSJack F Vogel * 82542 Gigabit Ethernet Controller 378cfa0ad2SJack F Vogel */ 388cfa0ad2SJack F Vogel 398cfa0ad2SJack F Vogel #include "e1000_api.h" 408cfa0ad2SJack F Vogel 418cfa0ad2SJack F Vogel static s32 e1000_init_phy_params_82542(struct e1000_hw *hw); 428cfa0ad2SJack F Vogel static s32 e1000_init_nvm_params_82542(struct e1000_hw *hw); 438cfa0ad2SJack F Vogel static s32 e1000_init_mac_params_82542(struct e1000_hw *hw); 448cfa0ad2SJack F Vogel static s32 e1000_get_bus_info_82542(struct e1000_hw *hw); 458cfa0ad2SJack F Vogel static s32 e1000_reset_hw_82542(struct e1000_hw *hw); 468cfa0ad2SJack F Vogel static s32 e1000_init_hw_82542(struct e1000_hw *hw); 478cfa0ad2SJack F Vogel static s32 e1000_setup_link_82542(struct e1000_hw *hw); 488cfa0ad2SJack F Vogel static s32 e1000_led_on_82542(struct e1000_hw *hw); 498cfa0ad2SJack F Vogel static s32 e1000_led_off_82542(struct e1000_hw *hw); 50*8cc64f1eSJack F Vogel static int e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index); 518cfa0ad2SJack F Vogel static void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw); 5238537cb9SJack F Vogel static s32 e1000_read_mac_addr_82542(struct e1000_hw *hw); 5338537cb9SJack F Vogel 548cfa0ad2SJack F Vogel /** 558cfa0ad2SJack F Vogel * e1000_init_phy_params_82542 - Init PHY func ptrs. 568cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 578cfa0ad2SJack F Vogel **/ 588cfa0ad2SJack F Vogel static s32 e1000_init_phy_params_82542(struct e1000_hw *hw) 598cfa0ad2SJack F Vogel { 608cfa0ad2SJack F Vogel struct e1000_phy_info *phy = &hw->phy; 618cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS; 628cfa0ad2SJack F Vogel 638cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_phy_params_82542"); 648cfa0ad2SJack F Vogel 658cfa0ad2SJack F Vogel phy->type = e1000_phy_none; 668cfa0ad2SJack F Vogel 678cfa0ad2SJack F Vogel return ret_val; 688cfa0ad2SJack F Vogel } 698cfa0ad2SJack F Vogel 708cfa0ad2SJack F Vogel /** 718cfa0ad2SJack F Vogel * e1000_init_nvm_params_82542 - Init NVM func ptrs. 728cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 738cfa0ad2SJack F Vogel **/ 748cfa0ad2SJack F Vogel static s32 e1000_init_nvm_params_82542(struct e1000_hw *hw) 758cfa0ad2SJack F Vogel { 768cfa0ad2SJack F Vogel struct e1000_nvm_info *nvm = &hw->nvm; 778cfa0ad2SJack F Vogel 788cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_nvm_params_82542"); 798cfa0ad2SJack F Vogel 808cfa0ad2SJack F Vogel nvm->address_bits = 6; 818cfa0ad2SJack F Vogel nvm->delay_usec = 50; 828cfa0ad2SJack F Vogel nvm->opcode_bits = 3; 838cfa0ad2SJack F Vogel nvm->type = e1000_nvm_eeprom_microwire; 848cfa0ad2SJack F Vogel nvm->word_size = 64; 858cfa0ad2SJack F Vogel 868cfa0ad2SJack F Vogel /* Function Pointers */ 878cfa0ad2SJack F Vogel nvm->ops.read = e1000_read_nvm_microwire; 888cfa0ad2SJack F Vogel nvm->ops.release = e1000_stop_nvm; 898cfa0ad2SJack F Vogel nvm->ops.write = e1000_write_nvm_microwire; 908cfa0ad2SJack F Vogel nvm->ops.update = e1000_update_nvm_checksum_generic; 918cfa0ad2SJack F Vogel nvm->ops.validate = e1000_validate_nvm_checksum_generic; 928cfa0ad2SJack F Vogel 938cfa0ad2SJack F Vogel return E1000_SUCCESS; 948cfa0ad2SJack F Vogel } 958cfa0ad2SJack F Vogel 968cfa0ad2SJack F Vogel /** 978cfa0ad2SJack F Vogel * e1000_init_mac_params_82542 - Init MAC func ptrs. 988cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 998cfa0ad2SJack F Vogel **/ 1008cfa0ad2SJack F Vogel static s32 e1000_init_mac_params_82542(struct e1000_hw *hw) 1018cfa0ad2SJack F Vogel { 1028cfa0ad2SJack F Vogel struct e1000_mac_info *mac = &hw->mac; 1038cfa0ad2SJack F Vogel 1048cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_mac_params_82542"); 1058cfa0ad2SJack F Vogel 1068cfa0ad2SJack F Vogel /* Set media type */ 1078cfa0ad2SJack F Vogel hw->phy.media_type = e1000_media_type_fiber; 1088cfa0ad2SJack F Vogel 1098cfa0ad2SJack F Vogel /* Set mta register count */ 1108cfa0ad2SJack F Vogel mac->mta_reg_count = 128; 1118cfa0ad2SJack F Vogel /* Set rar entry count */ 1128cfa0ad2SJack F Vogel mac->rar_entry_count = E1000_RAR_ENTRIES; 1138cfa0ad2SJack F Vogel 1148cfa0ad2SJack F Vogel /* Function pointers */ 1158cfa0ad2SJack F Vogel 1168cfa0ad2SJack F Vogel /* bus type/speed/width */ 1178cfa0ad2SJack F Vogel mac->ops.get_bus_info = e1000_get_bus_info_82542; 118daf9197cSJack F Vogel /* function id */ 119daf9197cSJack F Vogel mac->ops.set_lan_id = e1000_set_lan_id_multi_port_pci; 1208cfa0ad2SJack F Vogel /* reset */ 1218cfa0ad2SJack F Vogel mac->ops.reset_hw = e1000_reset_hw_82542; 1228cfa0ad2SJack F Vogel /* hw initialization */ 1238cfa0ad2SJack F Vogel mac->ops.init_hw = e1000_init_hw_82542; 1248cfa0ad2SJack F Vogel /* link setup */ 1258cfa0ad2SJack F Vogel mac->ops.setup_link = e1000_setup_link_82542; 1268cfa0ad2SJack F Vogel /* phy/fiber/serdes setup */ 1278cfa0ad2SJack F Vogel mac->ops.setup_physical_interface = e1000_setup_fiber_serdes_link_generic; 1288cfa0ad2SJack F Vogel /* check for link */ 1298cfa0ad2SJack F Vogel mac->ops.check_for_link = e1000_check_for_fiber_link_generic; 1308cfa0ad2SJack F Vogel /* multicast address update */ 1318cfa0ad2SJack F Vogel mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; 1328cfa0ad2SJack F Vogel /* writing VFTA */ 1338cfa0ad2SJack F Vogel mac->ops.write_vfta = e1000_write_vfta_generic; 1348cfa0ad2SJack F Vogel /* clearing VFTA */ 1358cfa0ad2SJack F Vogel mac->ops.clear_vfta = e1000_clear_vfta_generic; 13638537cb9SJack F Vogel /* read mac address */ 13738537cb9SJack F Vogel mac->ops.read_mac_addr = e1000_read_mac_addr_82542; 1388cfa0ad2SJack F Vogel /* set RAR */ 1398cfa0ad2SJack F Vogel mac->ops.rar_set = e1000_rar_set_82542; 1408cfa0ad2SJack F Vogel /* turn on/off LED */ 1418cfa0ad2SJack F Vogel mac->ops.led_on = e1000_led_on_82542; 1428cfa0ad2SJack F Vogel mac->ops.led_off = e1000_led_off_82542; 1438cfa0ad2SJack F Vogel /* clear hardware counters */ 1448cfa0ad2SJack F Vogel mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82542; 1458cfa0ad2SJack F Vogel /* link info */ 1468cfa0ad2SJack F Vogel mac->ops.get_link_up_info = e1000_get_speed_and_duplex_fiber_serdes_generic; 1478cfa0ad2SJack F Vogel 148daf9197cSJack F Vogel return E1000_SUCCESS; 1498cfa0ad2SJack F Vogel } 1508cfa0ad2SJack F Vogel 1518cfa0ad2SJack F Vogel /** 1528cfa0ad2SJack F Vogel * e1000_init_function_pointers_82542 - Init func ptrs. 1538cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 1548cfa0ad2SJack F Vogel * 155daf9197cSJack F Vogel * Called to initialize all function pointers and parameters. 1568cfa0ad2SJack F Vogel **/ 1578cfa0ad2SJack F Vogel void e1000_init_function_pointers_82542(struct e1000_hw *hw) 1588cfa0ad2SJack F Vogel { 1598cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_function_pointers_82542"); 1608cfa0ad2SJack F Vogel 1618cfa0ad2SJack F Vogel hw->mac.ops.init_params = e1000_init_mac_params_82542; 1628cfa0ad2SJack F Vogel hw->nvm.ops.init_params = e1000_init_nvm_params_82542; 1638cfa0ad2SJack F Vogel hw->phy.ops.init_params = e1000_init_phy_params_82542; 1648cfa0ad2SJack F Vogel } 1658cfa0ad2SJack F Vogel 1668cfa0ad2SJack F Vogel /** 1678cfa0ad2SJack F Vogel * e1000_get_bus_info_82542 - Obtain bus information for adapter 1688cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 1698cfa0ad2SJack F Vogel * 1708cfa0ad2SJack F Vogel * This will obtain information about the HW bus for which the 171daf9197cSJack F Vogel * adapter is attached and stores it in the hw structure. 1728cfa0ad2SJack F Vogel **/ 1738cfa0ad2SJack F Vogel static s32 e1000_get_bus_info_82542(struct e1000_hw *hw) 1748cfa0ad2SJack F Vogel { 1758cfa0ad2SJack F Vogel DEBUGFUNC("e1000_get_bus_info_82542"); 1768cfa0ad2SJack F Vogel 1778cfa0ad2SJack F Vogel hw->bus.type = e1000_bus_type_pci; 1788cfa0ad2SJack F Vogel hw->bus.speed = e1000_bus_speed_unknown; 1798cfa0ad2SJack F Vogel hw->bus.width = e1000_bus_width_unknown; 1808cfa0ad2SJack F Vogel 1818cfa0ad2SJack F Vogel return E1000_SUCCESS; 1828cfa0ad2SJack F Vogel } 1838cfa0ad2SJack F Vogel 1848cfa0ad2SJack F Vogel /** 1858cfa0ad2SJack F Vogel * e1000_reset_hw_82542 - Reset hardware 1868cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 1878cfa0ad2SJack F Vogel * 188daf9197cSJack F Vogel * This resets the hardware into a known state. 1898cfa0ad2SJack F Vogel **/ 1908cfa0ad2SJack F Vogel static s32 e1000_reset_hw_82542(struct e1000_hw *hw) 1918cfa0ad2SJack F Vogel { 1928cfa0ad2SJack F Vogel struct e1000_bus_info *bus = &hw->bus; 1938cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS; 194fe954359SJack F Vogel u32 ctrl; 1958cfa0ad2SJack F Vogel 1968cfa0ad2SJack F Vogel DEBUGFUNC("e1000_reset_hw_82542"); 1978cfa0ad2SJack F Vogel 1988cfa0ad2SJack F Vogel if (hw->revision_id == E1000_REVISION_2) { 1998cfa0ad2SJack F Vogel DEBUGOUT("Disabling MWI on 82542 rev 2\n"); 2008cfa0ad2SJack F Vogel e1000_pci_clear_mwi(hw); 2018cfa0ad2SJack F Vogel } 2028cfa0ad2SJack F Vogel 2038cfa0ad2SJack F Vogel DEBUGOUT("Masking off all interrupts\n"); 2048cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); 2058cfa0ad2SJack F Vogel 2068cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_RCTL, 0); 2078cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP); 2088cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw); 2098cfa0ad2SJack F Vogel 2108cfa0ad2SJack F Vogel /* 2118cfa0ad2SJack F Vogel * Delay to allow any outstanding PCI transactions to complete before 2128cfa0ad2SJack F Vogel * resetting the device 2138cfa0ad2SJack F Vogel */ 2148cfa0ad2SJack F Vogel msec_delay(10); 2158cfa0ad2SJack F Vogel 2168cfa0ad2SJack F Vogel ctrl = E1000_READ_REG(hw, E1000_CTRL); 2178cfa0ad2SJack F Vogel 2188cfa0ad2SJack F Vogel DEBUGOUT("Issuing a global reset to 82542/82543 MAC\n"); 2198cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); 2208cfa0ad2SJack F Vogel 2218cfa0ad2SJack F Vogel hw->nvm.ops.reload(hw); 2228cfa0ad2SJack F Vogel msec_delay(2); 2238cfa0ad2SJack F Vogel 2248cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); 225fe954359SJack F Vogel E1000_READ_REG(hw, E1000_ICR); 2268cfa0ad2SJack F Vogel 2278cfa0ad2SJack F Vogel if (hw->revision_id == E1000_REVISION_2) { 2288cfa0ad2SJack F Vogel if (bus->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) 2298cfa0ad2SJack F Vogel e1000_pci_set_mwi(hw); 2308cfa0ad2SJack F Vogel } 2318cfa0ad2SJack F Vogel 2328cfa0ad2SJack F Vogel return ret_val; 2338cfa0ad2SJack F Vogel } 2348cfa0ad2SJack F Vogel 2358cfa0ad2SJack F Vogel /** 2368cfa0ad2SJack F Vogel * e1000_init_hw_82542 - Initialize hardware 2378cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 2388cfa0ad2SJack F Vogel * 239daf9197cSJack F Vogel * This inits the hardware readying it for operation. 2408cfa0ad2SJack F Vogel **/ 2418cfa0ad2SJack F Vogel static s32 e1000_init_hw_82542(struct e1000_hw *hw) 2428cfa0ad2SJack F Vogel { 2438cfa0ad2SJack F Vogel struct e1000_mac_info *mac = &hw->mac; 244daf9197cSJack F Vogel struct e1000_dev_spec_82542 *dev_spec = &hw->dev_spec._82542; 2458cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS; 2468cfa0ad2SJack F Vogel u32 ctrl; 2478cfa0ad2SJack F Vogel u16 i; 2488cfa0ad2SJack F Vogel 2498cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_hw_82542"); 2508cfa0ad2SJack F Vogel 2518cfa0ad2SJack F Vogel /* Disabling VLAN filtering */ 2528cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_VET, 0); 2538cfa0ad2SJack F Vogel mac->ops.clear_vfta(hw); 2548cfa0ad2SJack F Vogel 2558cfa0ad2SJack F Vogel /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */ 2568cfa0ad2SJack F Vogel if (hw->revision_id == E1000_REVISION_2) { 2578cfa0ad2SJack F Vogel DEBUGOUT("Disabling MWI on 82542 rev 2.0\n"); 2588cfa0ad2SJack F Vogel e1000_pci_clear_mwi(hw); 2598cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_RCTL, E1000_RCTL_RST); 2608cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw); 2618cfa0ad2SJack F Vogel msec_delay(5); 2628cfa0ad2SJack F Vogel } 2638cfa0ad2SJack F Vogel 2648cfa0ad2SJack F Vogel /* Setup the receive address. */ 2658cfa0ad2SJack F Vogel e1000_init_rx_addrs_generic(hw, mac->rar_entry_count); 2668cfa0ad2SJack F Vogel 2678cfa0ad2SJack F Vogel /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */ 2688cfa0ad2SJack F Vogel if (hw->revision_id == E1000_REVISION_2) { 2698cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_RCTL, 0); 2708cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw); 2718cfa0ad2SJack F Vogel msec_delay(1); 2728cfa0ad2SJack F Vogel if (hw->bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE) 2738cfa0ad2SJack F Vogel e1000_pci_set_mwi(hw); 2748cfa0ad2SJack F Vogel } 2758cfa0ad2SJack F Vogel 2768cfa0ad2SJack F Vogel /* Zero out the Multicast HASH table */ 2778cfa0ad2SJack F Vogel DEBUGOUT("Zeroing the MTA\n"); 2788cfa0ad2SJack F Vogel for (i = 0; i < mac->mta_reg_count; i++) 2798cfa0ad2SJack F Vogel E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); 2808cfa0ad2SJack F Vogel 2818cfa0ad2SJack F Vogel /* 2828cfa0ad2SJack F Vogel * Set the PCI priority bit correctly in the CTRL register. This 2838cfa0ad2SJack F Vogel * determines if the adapter gives priority to receives, or if it 2848cfa0ad2SJack F Vogel * gives equal priority to transmits and receives. 2858cfa0ad2SJack F Vogel */ 2868cfa0ad2SJack F Vogel if (dev_spec->dma_fairness) { 2878cfa0ad2SJack F Vogel ctrl = E1000_READ_REG(hw, E1000_CTRL); 2888cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PRIOR); 2898cfa0ad2SJack F Vogel } 2908cfa0ad2SJack F Vogel 2918cfa0ad2SJack F Vogel /* Setup link and flow control */ 2928cfa0ad2SJack F Vogel ret_val = e1000_setup_link_82542(hw); 2938cfa0ad2SJack F Vogel 2948cfa0ad2SJack F Vogel /* 2958cfa0ad2SJack F Vogel * Clear all of the statistics registers (clear on read). It is 2968cfa0ad2SJack F Vogel * important that we do this after we have tried to establish link 2978cfa0ad2SJack F Vogel * because the symbol error count will increment wildly if there 2988cfa0ad2SJack F Vogel * is no link. 2998cfa0ad2SJack F Vogel */ 3008cfa0ad2SJack F Vogel e1000_clear_hw_cntrs_82542(hw); 3018cfa0ad2SJack F Vogel 3028cfa0ad2SJack F Vogel return ret_val; 3038cfa0ad2SJack F Vogel } 3048cfa0ad2SJack F Vogel 3058cfa0ad2SJack F Vogel /** 3068cfa0ad2SJack F Vogel * e1000_setup_link_82542 - Setup flow control and link settings 3078cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 3088cfa0ad2SJack F Vogel * 3098cfa0ad2SJack F Vogel * Determines which flow control settings to use, then configures flow 3108cfa0ad2SJack F Vogel * control. Calls the appropriate media-specific link configuration 3118cfa0ad2SJack F Vogel * function. Assuming the adapter has a valid link partner, a valid link 3128cfa0ad2SJack F Vogel * should be established. Assumes the hardware has previously been reset 313daf9197cSJack F Vogel * and the transmitter and receiver are not enabled. 3148cfa0ad2SJack F Vogel **/ 3158cfa0ad2SJack F Vogel static s32 e1000_setup_link_82542(struct e1000_hw *hw) 3168cfa0ad2SJack F Vogel { 3178cfa0ad2SJack F Vogel struct e1000_mac_info *mac = &hw->mac; 3188cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS; 3198cfa0ad2SJack F Vogel 3208cfa0ad2SJack F Vogel DEBUGFUNC("e1000_setup_link_82542"); 3218cfa0ad2SJack F Vogel 3228cfa0ad2SJack F Vogel ret_val = e1000_set_default_fc_generic(hw); 3238cfa0ad2SJack F Vogel if (ret_val) 3248cfa0ad2SJack F Vogel goto out; 3258cfa0ad2SJack F Vogel 326daf9197cSJack F Vogel hw->fc.requested_mode &= ~e1000_fc_tx_pause; 3278cfa0ad2SJack F Vogel 3288cfa0ad2SJack F Vogel if (mac->report_tx_early == 1) 329daf9197cSJack F Vogel hw->fc.requested_mode &= ~e1000_fc_rx_pause; 3308cfa0ad2SJack F Vogel 3318cfa0ad2SJack F Vogel /* 332daf9197cSJack F Vogel * Save off the requested flow control mode for use later. Depending 333daf9197cSJack F Vogel * on the link partner's capabilities, we may or may not use this mode. 3348cfa0ad2SJack F Vogel */ 335daf9197cSJack F Vogel hw->fc.current_mode = hw->fc.requested_mode; 3368cfa0ad2SJack F Vogel 337daf9197cSJack F Vogel DEBUGOUT1("After fix-ups FlowControl is now = %x\n", 338daf9197cSJack F Vogel hw->fc.current_mode); 3398cfa0ad2SJack F Vogel 3408cfa0ad2SJack F Vogel /* Call the necessary subroutine to configure the link. */ 3418cfa0ad2SJack F Vogel ret_val = mac->ops.setup_physical_interface(hw); 3428cfa0ad2SJack F Vogel if (ret_val) 3438cfa0ad2SJack F Vogel goto out; 3448cfa0ad2SJack F Vogel 3458cfa0ad2SJack F Vogel /* 3468cfa0ad2SJack F Vogel * Initialize the flow control address, type, and PAUSE timer 3478cfa0ad2SJack F Vogel * registers to their default values. This is done even if flow 3488cfa0ad2SJack F Vogel * control is disabled, because it does not hurt anything to 3498cfa0ad2SJack F Vogel * initialize these registers. 3508cfa0ad2SJack F Vogel */ 3518cfa0ad2SJack F Vogel DEBUGOUT("Initializing Flow Control address, type and timer regs\n"); 3528cfa0ad2SJack F Vogel 3538cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_FCAL, FLOW_CONTROL_ADDRESS_LOW); 3548cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_FCAH, FLOW_CONTROL_ADDRESS_HIGH); 3558cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_FCT, FLOW_CONTROL_TYPE); 3568cfa0ad2SJack F Vogel 3578cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_FCTTV, hw->fc.pause_time); 3588cfa0ad2SJack F Vogel 3598cfa0ad2SJack F Vogel ret_val = e1000_set_fc_watermarks_generic(hw); 3608cfa0ad2SJack F Vogel 3618cfa0ad2SJack F Vogel out: 3628cfa0ad2SJack F Vogel return ret_val; 3638cfa0ad2SJack F Vogel } 3648cfa0ad2SJack F Vogel 3658cfa0ad2SJack F Vogel /** 3668cfa0ad2SJack F Vogel * e1000_led_on_82542 - Turn on SW controllable LED 3678cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 3688cfa0ad2SJack F Vogel * 369daf9197cSJack F Vogel * Turns the SW defined LED on. 3708cfa0ad2SJack F Vogel **/ 3718cfa0ad2SJack F Vogel static s32 e1000_led_on_82542(struct e1000_hw *hw) 3728cfa0ad2SJack F Vogel { 3738cfa0ad2SJack F Vogel u32 ctrl = E1000_READ_REG(hw, E1000_CTRL); 3748cfa0ad2SJack F Vogel 3758cfa0ad2SJack F Vogel DEBUGFUNC("e1000_led_on_82542"); 3768cfa0ad2SJack F Vogel 3778cfa0ad2SJack F Vogel ctrl |= E1000_CTRL_SWDPIN0; 3788cfa0ad2SJack F Vogel ctrl |= E1000_CTRL_SWDPIO0; 3798cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl); 3808cfa0ad2SJack F Vogel 3818cfa0ad2SJack F Vogel return E1000_SUCCESS; 3828cfa0ad2SJack F Vogel } 3838cfa0ad2SJack F Vogel 3848cfa0ad2SJack F Vogel /** 3858cfa0ad2SJack F Vogel * e1000_led_off_82542 - Turn off SW controllable LED 3868cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 3878cfa0ad2SJack F Vogel * 388daf9197cSJack F Vogel * Turns the SW defined LED off. 3898cfa0ad2SJack F Vogel **/ 3908cfa0ad2SJack F Vogel static s32 e1000_led_off_82542(struct e1000_hw *hw) 3918cfa0ad2SJack F Vogel { 3928cfa0ad2SJack F Vogel u32 ctrl = E1000_READ_REG(hw, E1000_CTRL); 3938cfa0ad2SJack F Vogel 3948cfa0ad2SJack F Vogel DEBUGFUNC("e1000_led_off_82542"); 3958cfa0ad2SJack F Vogel 3968cfa0ad2SJack F Vogel ctrl &= ~E1000_CTRL_SWDPIN0; 3978cfa0ad2SJack F Vogel ctrl |= E1000_CTRL_SWDPIO0; 3988cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl); 3998cfa0ad2SJack F Vogel 4008cfa0ad2SJack F Vogel return E1000_SUCCESS; 4018cfa0ad2SJack F Vogel } 4028cfa0ad2SJack F Vogel 4038cfa0ad2SJack F Vogel /** 4048cfa0ad2SJack F Vogel * e1000_rar_set_82542 - Set receive address register 4058cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 4068cfa0ad2SJack F Vogel * @addr: pointer to the receive address 4078cfa0ad2SJack F Vogel * @index: receive address array register 4088cfa0ad2SJack F Vogel * 4098cfa0ad2SJack F Vogel * Sets the receive address array register at index to the address passed 4108cfa0ad2SJack F Vogel * in by addr. 4118cfa0ad2SJack F Vogel **/ 412*8cc64f1eSJack F Vogel static int e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index) 4138cfa0ad2SJack F Vogel { 4148cfa0ad2SJack F Vogel u32 rar_low, rar_high; 4158cfa0ad2SJack F Vogel 4168cfa0ad2SJack F Vogel DEBUGFUNC("e1000_rar_set_82542"); 4178cfa0ad2SJack F Vogel 4188cfa0ad2SJack F Vogel /* 4198cfa0ad2SJack F Vogel * HW expects these in little endian so we reverse the byte order 4208cfa0ad2SJack F Vogel * from network order (big endian) to little endian 4218cfa0ad2SJack F Vogel */ 4228cfa0ad2SJack F Vogel rar_low = ((u32) addr[0] | 4238cfa0ad2SJack F Vogel ((u32) addr[1] << 8) | 4248cfa0ad2SJack F Vogel ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); 4258cfa0ad2SJack F Vogel 4268cfa0ad2SJack F Vogel rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); 4278cfa0ad2SJack F Vogel 4288cfa0ad2SJack F Vogel /* If MAC address zero, no need to set the AV bit */ 429daf9197cSJack F Vogel if (rar_low || rar_high) 4308cfa0ad2SJack F Vogel rar_high |= E1000_RAH_AV; 4318cfa0ad2SJack F Vogel 4328cfa0ad2SJack F Vogel E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low); 4338cfa0ad2SJack F Vogel E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); 434*8cc64f1eSJack F Vogel return E1000_SUCCESS; 4358cfa0ad2SJack F Vogel } 4368cfa0ad2SJack F Vogel 4378cfa0ad2SJack F Vogel /** 4388cfa0ad2SJack F Vogel * e1000_translate_register_82542 - Translate the proper register offset 4398cfa0ad2SJack F Vogel * @reg: e1000 register to be read 4408cfa0ad2SJack F Vogel * 4418cfa0ad2SJack F Vogel * Registers in 82542 are located in different offsets than other adapters 4428cfa0ad2SJack F Vogel * even though they function in the same manner. This function takes in 4438cfa0ad2SJack F Vogel * the name of the register to read and returns the correct offset for 4448cfa0ad2SJack F Vogel * 82542 silicon. 4458cfa0ad2SJack F Vogel **/ 4468cfa0ad2SJack F Vogel u32 e1000_translate_register_82542(u32 reg) 4478cfa0ad2SJack F Vogel { 4488cfa0ad2SJack F Vogel /* 4498cfa0ad2SJack F Vogel * Some of the 82542 registers are located at different 4508cfa0ad2SJack F Vogel * offsets than they are in newer adapters. 4518cfa0ad2SJack F Vogel * Despite the difference in location, the registers 4528cfa0ad2SJack F Vogel * function in the same manner. 4538cfa0ad2SJack F Vogel */ 4548cfa0ad2SJack F Vogel switch (reg) { 4558cfa0ad2SJack F Vogel case E1000_RA: 4568cfa0ad2SJack F Vogel reg = 0x00040; 4578cfa0ad2SJack F Vogel break; 4588cfa0ad2SJack F Vogel case E1000_RDTR: 4598cfa0ad2SJack F Vogel reg = 0x00108; 4608cfa0ad2SJack F Vogel break; 4618cfa0ad2SJack F Vogel case E1000_RDBAL(0): 4628cfa0ad2SJack F Vogel reg = 0x00110; 4638cfa0ad2SJack F Vogel break; 4648cfa0ad2SJack F Vogel case E1000_RDBAH(0): 4658cfa0ad2SJack F Vogel reg = 0x00114; 4668cfa0ad2SJack F Vogel break; 4678cfa0ad2SJack F Vogel case E1000_RDLEN(0): 4688cfa0ad2SJack F Vogel reg = 0x00118; 4698cfa0ad2SJack F Vogel break; 4708cfa0ad2SJack F Vogel case E1000_RDH(0): 4718cfa0ad2SJack F Vogel reg = 0x00120; 4728cfa0ad2SJack F Vogel break; 4738cfa0ad2SJack F Vogel case E1000_RDT(0): 4748cfa0ad2SJack F Vogel reg = 0x00128; 4758cfa0ad2SJack F Vogel break; 4768cfa0ad2SJack F Vogel case E1000_RDBAL(1): 4778cfa0ad2SJack F Vogel reg = 0x00138; 4788cfa0ad2SJack F Vogel break; 4798cfa0ad2SJack F Vogel case E1000_RDBAH(1): 4808cfa0ad2SJack F Vogel reg = 0x0013C; 4818cfa0ad2SJack F Vogel break; 4828cfa0ad2SJack F Vogel case E1000_RDLEN(1): 4838cfa0ad2SJack F Vogel reg = 0x00140; 4848cfa0ad2SJack F Vogel break; 4858cfa0ad2SJack F Vogel case E1000_RDH(1): 4868cfa0ad2SJack F Vogel reg = 0x00148; 4878cfa0ad2SJack F Vogel break; 4888cfa0ad2SJack F Vogel case E1000_RDT(1): 4898cfa0ad2SJack F Vogel reg = 0x00150; 4908cfa0ad2SJack F Vogel break; 4918cfa0ad2SJack F Vogel case E1000_FCRTH: 4928cfa0ad2SJack F Vogel reg = 0x00160; 4938cfa0ad2SJack F Vogel break; 4948cfa0ad2SJack F Vogel case E1000_FCRTL: 4958cfa0ad2SJack F Vogel reg = 0x00168; 4968cfa0ad2SJack F Vogel break; 4978cfa0ad2SJack F Vogel case E1000_MTA: 4988cfa0ad2SJack F Vogel reg = 0x00200; 4998cfa0ad2SJack F Vogel break; 5008cfa0ad2SJack F Vogel case E1000_TDBAL(0): 5018cfa0ad2SJack F Vogel reg = 0x00420; 5028cfa0ad2SJack F Vogel break; 5038cfa0ad2SJack F Vogel case E1000_TDBAH(0): 5048cfa0ad2SJack F Vogel reg = 0x00424; 5058cfa0ad2SJack F Vogel break; 5068cfa0ad2SJack F Vogel case E1000_TDLEN(0): 5078cfa0ad2SJack F Vogel reg = 0x00428; 5088cfa0ad2SJack F Vogel break; 5098cfa0ad2SJack F Vogel case E1000_TDH(0): 5108cfa0ad2SJack F Vogel reg = 0x00430; 5118cfa0ad2SJack F Vogel break; 5128cfa0ad2SJack F Vogel case E1000_TDT(0): 5138cfa0ad2SJack F Vogel reg = 0x00438; 5148cfa0ad2SJack F Vogel break; 5158cfa0ad2SJack F Vogel case E1000_TIDV: 5168cfa0ad2SJack F Vogel reg = 0x00440; 5178cfa0ad2SJack F Vogel break; 5188cfa0ad2SJack F Vogel case E1000_VFTA: 5198cfa0ad2SJack F Vogel reg = 0x00600; 5208cfa0ad2SJack F Vogel break; 5218cfa0ad2SJack F Vogel case E1000_TDFH: 5228cfa0ad2SJack F Vogel reg = 0x08010; 5238cfa0ad2SJack F Vogel break; 5248cfa0ad2SJack F Vogel case E1000_TDFT: 5258cfa0ad2SJack F Vogel reg = 0x08018; 5268cfa0ad2SJack F Vogel break; 5278cfa0ad2SJack F Vogel default: 5288cfa0ad2SJack F Vogel break; 5298cfa0ad2SJack F Vogel } 5308cfa0ad2SJack F Vogel 5318cfa0ad2SJack F Vogel return reg; 5328cfa0ad2SJack F Vogel } 5338cfa0ad2SJack F Vogel 5348cfa0ad2SJack F Vogel /** 5358cfa0ad2SJack F Vogel * e1000_clear_hw_cntrs_82542 - Clear device specific hardware counters 5368cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 5378cfa0ad2SJack F Vogel * 5388cfa0ad2SJack F Vogel * Clears the hardware counters by reading the counter registers. 5398cfa0ad2SJack F Vogel **/ 5408cfa0ad2SJack F Vogel static void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw) 5418cfa0ad2SJack F Vogel { 5428cfa0ad2SJack F Vogel DEBUGFUNC("e1000_clear_hw_cntrs_82542"); 5438cfa0ad2SJack F Vogel 5448cfa0ad2SJack F Vogel e1000_clear_hw_cntrs_base_generic(hw); 5458cfa0ad2SJack F Vogel 546daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC64); 547daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC127); 548daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC255); 549daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC511); 550daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC1023); 551daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC1522); 552daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC64); 553daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC127); 554daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC255); 555daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC511); 556daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC1023); 557daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC1522); 5588cfa0ad2SJack F Vogel } 55938537cb9SJack F Vogel 56038537cb9SJack F Vogel /** 56138537cb9SJack F Vogel * e1000_read_mac_addr_82542 - Read device MAC address 56238537cb9SJack F Vogel * @hw: pointer to the HW structure 56338537cb9SJack F Vogel * 56438537cb9SJack F Vogel * Reads the device MAC address from the EEPROM and stores the value. 56538537cb9SJack F Vogel **/ 56638537cb9SJack F Vogel static s32 e1000_read_mac_addr_82542(struct e1000_hw *hw) 56738537cb9SJack F Vogel { 56838537cb9SJack F Vogel s32 ret_val = E1000_SUCCESS; 56938537cb9SJack F Vogel u16 offset, nvm_data, i; 57038537cb9SJack F Vogel 57138537cb9SJack F Vogel DEBUGFUNC("e1000_read_mac_addr"); 57238537cb9SJack F Vogel 57338537cb9SJack F Vogel for (i = 0; i < ETH_ADDR_LEN; i += 2) { 57438537cb9SJack F Vogel offset = i >> 1; 57538537cb9SJack F Vogel ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); 57638537cb9SJack F Vogel if (ret_val) { 57738537cb9SJack F Vogel DEBUGOUT("NVM Read Error\n"); 57838537cb9SJack F Vogel goto out; 57938537cb9SJack F Vogel } 58038537cb9SJack F Vogel hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF); 58138537cb9SJack F Vogel hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8); 58238537cb9SJack F Vogel } 58338537cb9SJack F Vogel 58438537cb9SJack F Vogel for (i = 0; i < ETH_ADDR_LEN; i++) 58538537cb9SJack F Vogel hw->mac.addr[i] = hw->mac.perm_addr[i]; 58638537cb9SJack F Vogel 58738537cb9SJack F Vogel out: 58838537cb9SJack F Vogel return ret_val; 58938537cb9SJack F Vogel } 590