18cfa0ad2SJack F Vogel /******************************************************************************
27282444bSPedro F. Giffuni SPDX-License-Identifier: BSD-3-Clause
38cfa0ad2SJack F Vogel
4702cac6cSKevin Bowling Copyright (c) 2001-2020, Intel Corporation
58cfa0ad2SJack F Vogel All rights reserved.
68cfa0ad2SJack F Vogel
78cfa0ad2SJack F Vogel Redistribution and use in source and binary forms, with or without
88cfa0ad2SJack F Vogel modification, are permitted provided that the following conditions are met:
98cfa0ad2SJack F Vogel
108cfa0ad2SJack F Vogel 1. Redistributions of source code must retain the above copyright notice,
118cfa0ad2SJack F Vogel this list of conditions and the following disclaimer.
128cfa0ad2SJack F Vogel
138cfa0ad2SJack F Vogel 2. Redistributions in binary form must reproduce the above copyright
148cfa0ad2SJack F Vogel notice, this list of conditions and the following disclaimer in the
158cfa0ad2SJack F Vogel documentation and/or other materials provided with the distribution.
168cfa0ad2SJack F Vogel
178cfa0ad2SJack F Vogel 3. Neither the name of the Intel Corporation nor the names of its
188cfa0ad2SJack F Vogel contributors may be used to endorse or promote products derived from
198cfa0ad2SJack F Vogel this software without specific prior written permission.
208cfa0ad2SJack F Vogel
218cfa0ad2SJack F Vogel THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
228cfa0ad2SJack F Vogel AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
238cfa0ad2SJack F Vogel IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
248cfa0ad2SJack F Vogel ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
258cfa0ad2SJack F Vogel LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
268cfa0ad2SJack F Vogel CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
278cfa0ad2SJack F Vogel SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
288cfa0ad2SJack F Vogel INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
298cfa0ad2SJack F Vogel CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
308cfa0ad2SJack F Vogel ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
318cfa0ad2SJack F Vogel POSSIBILITY OF SUCH DAMAGE.
328cfa0ad2SJack F Vogel
338cfa0ad2SJack F Vogel ******************************************************************************/
348cfa0ad2SJack F Vogel
35daf9197cSJack F Vogel /*
36daf9197cSJack F Vogel * 82540EM Gigabit Ethernet Controller
37daf9197cSJack F Vogel * 82540EP Gigabit Ethernet Controller
38daf9197cSJack F Vogel * 82545EM Gigabit Ethernet Controller (Copper)
39daf9197cSJack F Vogel * 82545EM Gigabit Ethernet Controller (Fiber)
40daf9197cSJack F Vogel * 82545GM Gigabit Ethernet Controller
41daf9197cSJack F Vogel * 82546EB Gigabit Ethernet Controller (Copper)
42daf9197cSJack F Vogel * 82546EB Gigabit Ethernet Controller (Fiber)
43daf9197cSJack F Vogel * 82546GB Gigabit Ethernet Controller
448cfa0ad2SJack F Vogel */
458cfa0ad2SJack F Vogel
468cfa0ad2SJack F Vogel #include "e1000_api.h"
478cfa0ad2SJack F Vogel
488cfa0ad2SJack F Vogel static s32 e1000_init_phy_params_82540(struct e1000_hw *hw);
498cfa0ad2SJack F Vogel static s32 e1000_init_nvm_params_82540(struct e1000_hw *hw);
508cfa0ad2SJack F Vogel static s32 e1000_init_mac_params_82540(struct e1000_hw *hw);
518cfa0ad2SJack F Vogel static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw);
528cfa0ad2SJack F Vogel static void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw);
538cfa0ad2SJack F Vogel static s32 e1000_init_hw_82540(struct e1000_hw *hw);
548cfa0ad2SJack F Vogel static s32 e1000_reset_hw_82540(struct e1000_hw *hw);
558cfa0ad2SJack F Vogel static s32 e1000_set_phy_mode_82540(struct e1000_hw *hw);
568cfa0ad2SJack F Vogel static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw);
578cfa0ad2SJack F Vogel static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw);
588cfa0ad2SJack F Vogel static s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw);
598cfa0ad2SJack F Vogel static void e1000_power_down_phy_copper_82540(struct e1000_hw *hw);
609d81738fSJack F Vogel static s32 e1000_read_mac_addr_82540(struct e1000_hw *hw);
618cfa0ad2SJack F Vogel
628cfa0ad2SJack F Vogel /**
638cfa0ad2SJack F Vogel * e1000_init_phy_params_82540 - Init PHY func ptrs.
648cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
658cfa0ad2SJack F Vogel **/
e1000_init_phy_params_82540(struct e1000_hw * hw)668cfa0ad2SJack F Vogel static s32 e1000_init_phy_params_82540(struct e1000_hw *hw)
678cfa0ad2SJack F Vogel {
688cfa0ad2SJack F Vogel struct e1000_phy_info *phy = &hw->phy;
69c80429ceSEric Joyner s32 ret_val;
708cfa0ad2SJack F Vogel
718cfa0ad2SJack F Vogel phy->addr = 1;
728cfa0ad2SJack F Vogel phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
738cfa0ad2SJack F Vogel phy->reset_delay_us = 10000;
748cfa0ad2SJack F Vogel phy->type = e1000_phy_m88;
758cfa0ad2SJack F Vogel
768cfa0ad2SJack F Vogel /* Function Pointers */
778cfa0ad2SJack F Vogel phy->ops.check_polarity = e1000_check_polarity_m88;
788cfa0ad2SJack F Vogel phy->ops.commit = e1000_phy_sw_reset_generic;
798cfa0ad2SJack F Vogel phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
808cfa0ad2SJack F Vogel phy->ops.get_cable_length = e1000_get_cable_length_m88;
818cfa0ad2SJack F Vogel phy->ops.get_cfg_done = e1000_get_cfg_done_generic;
828cfa0ad2SJack F Vogel phy->ops.read_reg = e1000_read_phy_reg_m88;
838cfa0ad2SJack F Vogel phy->ops.reset = e1000_phy_hw_reset_generic;
848cfa0ad2SJack F Vogel phy->ops.write_reg = e1000_write_phy_reg_m88;
858cfa0ad2SJack F Vogel phy->ops.get_info = e1000_get_phy_info_m88;
868cfa0ad2SJack F Vogel phy->ops.power_up = e1000_power_up_phy_copper;
878cfa0ad2SJack F Vogel phy->ops.power_down = e1000_power_down_phy_copper_82540;
888cfa0ad2SJack F Vogel
898cfa0ad2SJack F Vogel ret_val = e1000_get_phy_id(hw);
908cfa0ad2SJack F Vogel if (ret_val)
918cfa0ad2SJack F Vogel goto out;
928cfa0ad2SJack F Vogel
938cfa0ad2SJack F Vogel /* Verify phy id */
948cfa0ad2SJack F Vogel switch (hw->mac.type) {
958cfa0ad2SJack F Vogel case e1000_82540:
968cfa0ad2SJack F Vogel case e1000_82545:
978cfa0ad2SJack F Vogel case e1000_82545_rev_3:
988cfa0ad2SJack F Vogel case e1000_82546:
998cfa0ad2SJack F Vogel case e1000_82546_rev_3:
1008cfa0ad2SJack F Vogel if (phy->id == M88E1011_I_PHY_ID)
1018cfa0ad2SJack F Vogel break;
102*e05d9788SKevin Bowling /* FALLTHROUGH */
1038cfa0ad2SJack F Vogel default:
1048cfa0ad2SJack F Vogel ret_val = -E1000_ERR_PHY;
1058cfa0ad2SJack F Vogel goto out;
1068cfa0ad2SJack F Vogel break;
1078cfa0ad2SJack F Vogel }
1088cfa0ad2SJack F Vogel
1098cfa0ad2SJack F Vogel out:
1108cfa0ad2SJack F Vogel return ret_val;
1118cfa0ad2SJack F Vogel }
1128cfa0ad2SJack F Vogel
1138cfa0ad2SJack F Vogel /**
1148cfa0ad2SJack F Vogel * e1000_init_nvm_params_82540 - Init NVM func ptrs.
1158cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
1168cfa0ad2SJack F Vogel **/
e1000_init_nvm_params_82540(struct e1000_hw * hw)1178cfa0ad2SJack F Vogel static s32 e1000_init_nvm_params_82540(struct e1000_hw *hw)
1188cfa0ad2SJack F Vogel {
1198cfa0ad2SJack F Vogel struct e1000_nvm_info *nvm = &hw->nvm;
1208cfa0ad2SJack F Vogel u32 eecd = E1000_READ_REG(hw, E1000_EECD);
1218cfa0ad2SJack F Vogel
1228cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_nvm_params_82540");
1238cfa0ad2SJack F Vogel
1248cfa0ad2SJack F Vogel nvm->type = e1000_nvm_eeprom_microwire;
1258cfa0ad2SJack F Vogel nvm->delay_usec = 50;
1268cfa0ad2SJack F Vogel nvm->opcode_bits = 3;
1278cfa0ad2SJack F Vogel switch (nvm->override) {
1288cfa0ad2SJack F Vogel case e1000_nvm_override_microwire_large:
1298cfa0ad2SJack F Vogel nvm->address_bits = 8;
1308cfa0ad2SJack F Vogel nvm->word_size = 256;
1318cfa0ad2SJack F Vogel break;
1328cfa0ad2SJack F Vogel case e1000_nvm_override_microwire_small:
1338cfa0ad2SJack F Vogel nvm->address_bits = 6;
1348cfa0ad2SJack F Vogel nvm->word_size = 64;
1358cfa0ad2SJack F Vogel break;
1368cfa0ad2SJack F Vogel default:
1378cfa0ad2SJack F Vogel nvm->address_bits = eecd & E1000_EECD_SIZE ? 8 : 6;
1388cfa0ad2SJack F Vogel nvm->word_size = eecd & E1000_EECD_SIZE ? 256 : 64;
1398cfa0ad2SJack F Vogel break;
1408cfa0ad2SJack F Vogel }
1418cfa0ad2SJack F Vogel
1428cfa0ad2SJack F Vogel /* Function Pointers */
1438cfa0ad2SJack F Vogel nvm->ops.acquire = e1000_acquire_nvm_generic;
1448cfa0ad2SJack F Vogel nvm->ops.read = e1000_read_nvm_microwire;
1458cfa0ad2SJack F Vogel nvm->ops.release = e1000_release_nvm_generic;
1468cfa0ad2SJack F Vogel nvm->ops.update = e1000_update_nvm_checksum_generic;
1478cfa0ad2SJack F Vogel nvm->ops.valid_led_default = e1000_valid_led_default_generic;
1488cfa0ad2SJack F Vogel nvm->ops.validate = e1000_validate_nvm_checksum_generic;
1498cfa0ad2SJack F Vogel nvm->ops.write = e1000_write_nvm_microwire;
1508cfa0ad2SJack F Vogel
1518cfa0ad2SJack F Vogel return E1000_SUCCESS;
1528cfa0ad2SJack F Vogel }
1538cfa0ad2SJack F Vogel
1548cfa0ad2SJack F Vogel /**
1558cfa0ad2SJack F Vogel * e1000_init_mac_params_82540 - Init MAC func ptrs.
1568cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
1578cfa0ad2SJack F Vogel **/
e1000_init_mac_params_82540(struct e1000_hw * hw)1588cfa0ad2SJack F Vogel static s32 e1000_init_mac_params_82540(struct e1000_hw *hw)
1598cfa0ad2SJack F Vogel {
1608cfa0ad2SJack F Vogel struct e1000_mac_info *mac = &hw->mac;
1618cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS;
1628cfa0ad2SJack F Vogel
1638cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_mac_params_82540");
1648cfa0ad2SJack F Vogel
1658cfa0ad2SJack F Vogel /* Set media type */
1668cfa0ad2SJack F Vogel switch (hw->device_id) {
1678cfa0ad2SJack F Vogel case E1000_DEV_ID_82545EM_FIBER:
1688cfa0ad2SJack F Vogel case E1000_DEV_ID_82545GM_FIBER:
1698cfa0ad2SJack F Vogel case E1000_DEV_ID_82546EB_FIBER:
1708cfa0ad2SJack F Vogel case E1000_DEV_ID_82546GB_FIBER:
1718cfa0ad2SJack F Vogel hw->phy.media_type = e1000_media_type_fiber;
1728cfa0ad2SJack F Vogel break;
1738cfa0ad2SJack F Vogel case E1000_DEV_ID_82545GM_SERDES:
1748cfa0ad2SJack F Vogel case E1000_DEV_ID_82546GB_SERDES:
1758cfa0ad2SJack F Vogel hw->phy.media_type = e1000_media_type_internal_serdes;
1768cfa0ad2SJack F Vogel break;
1778cfa0ad2SJack F Vogel default:
1788cfa0ad2SJack F Vogel hw->phy.media_type = e1000_media_type_copper;
1798cfa0ad2SJack F Vogel break;
1808cfa0ad2SJack F Vogel }
1818cfa0ad2SJack F Vogel
1828cfa0ad2SJack F Vogel /* Set mta register count */
1838cfa0ad2SJack F Vogel mac->mta_reg_count = 128;
1848cfa0ad2SJack F Vogel /* Set rar entry count */
1858cfa0ad2SJack F Vogel mac->rar_entry_count = E1000_RAR_ENTRIES;
1868cfa0ad2SJack F Vogel
1878cfa0ad2SJack F Vogel /* Function pointers */
1888cfa0ad2SJack F Vogel
1898cfa0ad2SJack F Vogel /* bus type/speed/width */
1908cfa0ad2SJack F Vogel mac->ops.get_bus_info = e1000_get_bus_info_pci_generic;
191daf9197cSJack F Vogel /* function id */
192daf9197cSJack F Vogel mac->ops.set_lan_id = e1000_set_lan_id_multi_port_pci;
1938cfa0ad2SJack F Vogel /* reset */
1948cfa0ad2SJack F Vogel mac->ops.reset_hw = e1000_reset_hw_82540;
1958cfa0ad2SJack F Vogel /* hw initialization */
1968cfa0ad2SJack F Vogel mac->ops.init_hw = e1000_init_hw_82540;
1978cfa0ad2SJack F Vogel /* link setup */
1988cfa0ad2SJack F Vogel mac->ops.setup_link = e1000_setup_link_generic;
1998cfa0ad2SJack F Vogel /* physical interface setup */
2008cfa0ad2SJack F Vogel mac->ops.setup_physical_interface =
2018cfa0ad2SJack F Vogel (hw->phy.media_type == e1000_media_type_copper)
2028cfa0ad2SJack F Vogel ? e1000_setup_copper_link_82540
2038cfa0ad2SJack F Vogel : e1000_setup_fiber_serdes_link_82540;
2048cfa0ad2SJack F Vogel /* check for link */
2058cfa0ad2SJack F Vogel switch (hw->phy.media_type) {
2068cfa0ad2SJack F Vogel case e1000_media_type_copper:
2078cfa0ad2SJack F Vogel mac->ops.check_for_link = e1000_check_for_copper_link_generic;
2088cfa0ad2SJack F Vogel break;
2098cfa0ad2SJack F Vogel case e1000_media_type_fiber:
2108cfa0ad2SJack F Vogel mac->ops.check_for_link = e1000_check_for_fiber_link_generic;
2118cfa0ad2SJack F Vogel break;
2128cfa0ad2SJack F Vogel case e1000_media_type_internal_serdes:
2138cfa0ad2SJack F Vogel mac->ops.check_for_link = e1000_check_for_serdes_link_generic;
2148cfa0ad2SJack F Vogel break;
2158cfa0ad2SJack F Vogel default:
2168cfa0ad2SJack F Vogel ret_val = -E1000_ERR_CONFIG;
2178cfa0ad2SJack F Vogel goto out;
2188cfa0ad2SJack F Vogel break;
2198cfa0ad2SJack F Vogel }
2208cfa0ad2SJack F Vogel /* link info */
2218cfa0ad2SJack F Vogel mac->ops.get_link_up_info =
2228cfa0ad2SJack F Vogel (hw->phy.media_type == e1000_media_type_copper)
2238cfa0ad2SJack F Vogel ? e1000_get_speed_and_duplex_copper_generic
2248cfa0ad2SJack F Vogel : e1000_get_speed_and_duplex_fiber_serdes_generic;
2258cfa0ad2SJack F Vogel /* multicast address update */
2268cfa0ad2SJack F Vogel mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
2278cfa0ad2SJack F Vogel /* writing VFTA */
2288cfa0ad2SJack F Vogel mac->ops.write_vfta = e1000_write_vfta_generic;
2298cfa0ad2SJack F Vogel /* clearing VFTA */
2308cfa0ad2SJack F Vogel mac->ops.clear_vfta = e1000_clear_vfta_generic;
2319d81738fSJack F Vogel /* read mac address */
2329d81738fSJack F Vogel mac->ops.read_mac_addr = e1000_read_mac_addr_82540;
233d035aa2dSJack F Vogel /* ID LED init */
234d035aa2dSJack F Vogel mac->ops.id_led_init = e1000_id_led_init_generic;
2358cfa0ad2SJack F Vogel /* setup LED */
2368cfa0ad2SJack F Vogel mac->ops.setup_led = e1000_setup_led_generic;
2378cfa0ad2SJack F Vogel /* cleanup LED */
2388cfa0ad2SJack F Vogel mac->ops.cleanup_led = e1000_cleanup_led_generic;
2398cfa0ad2SJack F Vogel /* turn on/off LED */
2408cfa0ad2SJack F Vogel mac->ops.led_on = e1000_led_on_generic;
2418cfa0ad2SJack F Vogel mac->ops.led_off = e1000_led_off_generic;
2428cfa0ad2SJack F Vogel /* clear hardware counters */
2438cfa0ad2SJack F Vogel mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82540;
2448cfa0ad2SJack F Vogel
2458cfa0ad2SJack F Vogel out:
2468cfa0ad2SJack F Vogel return ret_val;
2478cfa0ad2SJack F Vogel }
2488cfa0ad2SJack F Vogel
2498cfa0ad2SJack F Vogel /**
2508cfa0ad2SJack F Vogel * e1000_init_function_pointers_82540 - Init func ptrs.
2518cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
2528cfa0ad2SJack F Vogel *
253daf9197cSJack F Vogel * Called to initialize all function pointers and parameters.
2548cfa0ad2SJack F Vogel **/
e1000_init_function_pointers_82540(struct e1000_hw * hw)2558cfa0ad2SJack F Vogel void e1000_init_function_pointers_82540(struct e1000_hw *hw)
2568cfa0ad2SJack F Vogel {
2578cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_function_pointers_82540");
2588cfa0ad2SJack F Vogel
2598cfa0ad2SJack F Vogel hw->mac.ops.init_params = e1000_init_mac_params_82540;
2608cfa0ad2SJack F Vogel hw->nvm.ops.init_params = e1000_init_nvm_params_82540;
2618cfa0ad2SJack F Vogel hw->phy.ops.init_params = e1000_init_phy_params_82540;
2628cfa0ad2SJack F Vogel }
2638cfa0ad2SJack F Vogel
2648cfa0ad2SJack F Vogel /**
2658cfa0ad2SJack F Vogel * e1000_reset_hw_82540 - Reset hardware
2668cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
2678cfa0ad2SJack F Vogel *
268daf9197cSJack F Vogel * This resets the hardware into a known state.
2698cfa0ad2SJack F Vogel **/
e1000_reset_hw_82540(struct e1000_hw * hw)2708cfa0ad2SJack F Vogel static s32 e1000_reset_hw_82540(struct e1000_hw *hw)
2718cfa0ad2SJack F Vogel {
272730d3130SJack F Vogel u32 ctrl, manc;
2738cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS;
2748cfa0ad2SJack F Vogel
2758cfa0ad2SJack F Vogel DEBUGFUNC("e1000_reset_hw_82540");
2768cfa0ad2SJack F Vogel
2778cfa0ad2SJack F Vogel DEBUGOUT("Masking off all interrupts\n");
2788cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_IMC, 0xFFFFFFFF);
2798cfa0ad2SJack F Vogel
2808cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_RCTL, 0);
2818cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
2828cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw);
2838cfa0ad2SJack F Vogel
2848cfa0ad2SJack F Vogel /*
2858cfa0ad2SJack F Vogel * Delay to allow any outstanding PCI transactions to complete
2868cfa0ad2SJack F Vogel * before resetting the device.
2878cfa0ad2SJack F Vogel */
2888cfa0ad2SJack F Vogel msec_delay(10);
2898cfa0ad2SJack F Vogel
2908cfa0ad2SJack F Vogel ctrl = E1000_READ_REG(hw, E1000_CTRL);
2918cfa0ad2SJack F Vogel
2928cfa0ad2SJack F Vogel DEBUGOUT("Issuing a global reset to 82540/82545/82546 MAC\n");
2938cfa0ad2SJack F Vogel switch (hw->mac.type) {
2948cfa0ad2SJack F Vogel case e1000_82545_rev_3:
2958cfa0ad2SJack F Vogel case e1000_82546_rev_3:
2968cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL_DUP, ctrl | E1000_CTRL_RST);
2978cfa0ad2SJack F Vogel break;
2988cfa0ad2SJack F Vogel default:
2998cfa0ad2SJack F Vogel /*
3008cfa0ad2SJack F Vogel * These controllers can't ack the 64-bit write when
3018cfa0ad2SJack F Vogel * issuing the reset, so we use IO-mapping as a
3028cfa0ad2SJack F Vogel * workaround to issue the reset.
3038cfa0ad2SJack F Vogel */
3048cfa0ad2SJack F Vogel E1000_WRITE_REG_IO(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
3058cfa0ad2SJack F Vogel break;
3068cfa0ad2SJack F Vogel }
3078cfa0ad2SJack F Vogel
3088cfa0ad2SJack F Vogel /* Wait for EEPROM reload */
3098cfa0ad2SJack F Vogel msec_delay(5);
3108cfa0ad2SJack F Vogel
3118cfa0ad2SJack F Vogel /* Disable HW ARPs on ASF enabled adapters */
3128cfa0ad2SJack F Vogel manc = E1000_READ_REG(hw, E1000_MANC);
3138cfa0ad2SJack F Vogel manc &= ~E1000_MANC_ARP_EN;
3148cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_MANC, manc);
3158cfa0ad2SJack F Vogel
3168cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
317730d3130SJack F Vogel E1000_READ_REG(hw, E1000_ICR);
3188cfa0ad2SJack F Vogel
3198cfa0ad2SJack F Vogel return ret_val;
3208cfa0ad2SJack F Vogel }
3218cfa0ad2SJack F Vogel
3228cfa0ad2SJack F Vogel /**
3238cfa0ad2SJack F Vogel * e1000_init_hw_82540 - Initialize hardware
3248cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
3258cfa0ad2SJack F Vogel *
326daf9197cSJack F Vogel * This inits the hardware readying it for operation.
3278cfa0ad2SJack F Vogel **/
e1000_init_hw_82540(struct e1000_hw * hw)3288cfa0ad2SJack F Vogel static s32 e1000_init_hw_82540(struct e1000_hw *hw)
3298cfa0ad2SJack F Vogel {
3308cfa0ad2SJack F Vogel struct e1000_mac_info *mac = &hw->mac;
3318cfa0ad2SJack F Vogel u32 txdctl, ctrl_ext;
332c80429ceSEric Joyner s32 ret_val;
3338cfa0ad2SJack F Vogel u16 i;
3348cfa0ad2SJack F Vogel
3358cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_hw_82540");
3368cfa0ad2SJack F Vogel
3378cfa0ad2SJack F Vogel /* Initialize identification LED */
338d035aa2dSJack F Vogel ret_val = mac->ops.id_led_init(hw);
3398cfa0ad2SJack F Vogel if (ret_val) {
3408cfa0ad2SJack F Vogel DEBUGOUT("Error initializing identification LED\n");
3418cfa0ad2SJack F Vogel /* This is not fatal and we should not stop init due to this */
3428cfa0ad2SJack F Vogel }
3438cfa0ad2SJack F Vogel
3448cfa0ad2SJack F Vogel /* Disabling VLAN filtering */
3458cfa0ad2SJack F Vogel DEBUGOUT("Initializing the IEEE VLAN\n");
3468cfa0ad2SJack F Vogel if (mac->type < e1000_82545_rev_3)
3478cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_VET, 0);
3488cfa0ad2SJack F Vogel
3498cfa0ad2SJack F Vogel mac->ops.clear_vfta(hw);
3508cfa0ad2SJack F Vogel
3518cfa0ad2SJack F Vogel /* Setup the receive address. */
3528cfa0ad2SJack F Vogel e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);
3538cfa0ad2SJack F Vogel
3548cfa0ad2SJack F Vogel /* Zero out the Multicast HASH table */
3558cfa0ad2SJack F Vogel DEBUGOUT("Zeroing the MTA\n");
3568cfa0ad2SJack F Vogel for (i = 0; i < mac->mta_reg_count; i++) {
3578cfa0ad2SJack F Vogel E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
3588cfa0ad2SJack F Vogel /*
3598cfa0ad2SJack F Vogel * Avoid back to back register writes by adding the register
3608cfa0ad2SJack F Vogel * read (flush). This is to protect against some strange
3618cfa0ad2SJack F Vogel * bridge configurations that may issue Memory Write Block
3628cfa0ad2SJack F Vogel * (MWB) to our register space. The *_rev_3 hardware at
3638cfa0ad2SJack F Vogel * least doesn't respond correctly to every other dword in an
3648cfa0ad2SJack F Vogel * MWB to our register space.
3658cfa0ad2SJack F Vogel */
3668cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw);
3678cfa0ad2SJack F Vogel }
3688cfa0ad2SJack F Vogel
3698cfa0ad2SJack F Vogel if (mac->type < e1000_82545_rev_3)
3708cfa0ad2SJack F Vogel e1000_pcix_mmrbc_workaround_generic(hw);
3718cfa0ad2SJack F Vogel
3728cfa0ad2SJack F Vogel /* Setup link and flow control */
3738cfa0ad2SJack F Vogel ret_val = mac->ops.setup_link(hw);
3748cfa0ad2SJack F Vogel
3758cfa0ad2SJack F Vogel txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0));
3768cfa0ad2SJack F Vogel txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) |
3778cfa0ad2SJack F Vogel E1000_TXDCTL_FULL_TX_DESC_WB;
3788cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_TXDCTL(0), txdctl);
3798cfa0ad2SJack F Vogel
3808cfa0ad2SJack F Vogel /*
3818cfa0ad2SJack F Vogel * Clear all of the statistics registers (clear on read). It is
3828cfa0ad2SJack F Vogel * important that we do this after we have tried to establish link
3838cfa0ad2SJack F Vogel * because the symbol error count will increment wildly if there
3848cfa0ad2SJack F Vogel * is no link.
3858cfa0ad2SJack F Vogel */
3868cfa0ad2SJack F Vogel e1000_clear_hw_cntrs_82540(hw);
3878cfa0ad2SJack F Vogel
3888cfa0ad2SJack F Vogel if ((hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER) ||
3898cfa0ad2SJack F Vogel (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3)) {
3908cfa0ad2SJack F Vogel ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
3918cfa0ad2SJack F Vogel /*
3928cfa0ad2SJack F Vogel * Relaxed ordering must be disabled to avoid a parity
3938cfa0ad2SJack F Vogel * error crash in a PCI slot.
3948cfa0ad2SJack F Vogel */
3958cfa0ad2SJack F Vogel ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
3968cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
3978cfa0ad2SJack F Vogel }
3988cfa0ad2SJack F Vogel
3998cfa0ad2SJack F Vogel return ret_val;
4008cfa0ad2SJack F Vogel }
4018cfa0ad2SJack F Vogel
4028cfa0ad2SJack F Vogel /**
4038cfa0ad2SJack F Vogel * e1000_setup_copper_link_82540 - Configure copper link settings
4048cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
4058cfa0ad2SJack F Vogel *
4068cfa0ad2SJack F Vogel * Calls the appropriate function to configure the link for auto-neg or forced
4078cfa0ad2SJack F Vogel * speed and duplex. Then we check for link, once link is established calls
4088cfa0ad2SJack F Vogel * to configure collision distance and flow control are called. If link is
409daf9197cSJack F Vogel * not established, we return -E1000_ERR_PHY (-2).
4108cfa0ad2SJack F Vogel **/
e1000_setup_copper_link_82540(struct e1000_hw * hw)4118cfa0ad2SJack F Vogel static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw)
4128cfa0ad2SJack F Vogel {
4138cfa0ad2SJack F Vogel u32 ctrl;
414c80429ceSEric Joyner s32 ret_val;
4158cfa0ad2SJack F Vogel u16 data;
4168cfa0ad2SJack F Vogel
4178cfa0ad2SJack F Vogel DEBUGFUNC("e1000_setup_copper_link_82540");
4188cfa0ad2SJack F Vogel
4198cfa0ad2SJack F Vogel ctrl = E1000_READ_REG(hw, E1000_CTRL);
4208cfa0ad2SJack F Vogel ctrl |= E1000_CTRL_SLU;
4218cfa0ad2SJack F Vogel ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
4228cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
4238cfa0ad2SJack F Vogel
4248cfa0ad2SJack F Vogel ret_val = e1000_set_phy_mode_82540(hw);
4258cfa0ad2SJack F Vogel if (ret_val)
4268cfa0ad2SJack F Vogel goto out;
4278cfa0ad2SJack F Vogel
4288cfa0ad2SJack F Vogel if (hw->mac.type == e1000_82545_rev_3 ||
4298cfa0ad2SJack F Vogel hw->mac.type == e1000_82546_rev_3) {
4304dab5c37SJack F Vogel ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL,
4314dab5c37SJack F Vogel &data);
4328cfa0ad2SJack F Vogel if (ret_val)
4338cfa0ad2SJack F Vogel goto out;
4348cfa0ad2SJack F Vogel data |= 0x00000008;
4354dab5c37SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL,
4364dab5c37SJack F Vogel data);
4378cfa0ad2SJack F Vogel if (ret_val)
4388cfa0ad2SJack F Vogel goto out;
4398cfa0ad2SJack F Vogel }
4408cfa0ad2SJack F Vogel
4418cfa0ad2SJack F Vogel ret_val = e1000_copper_link_setup_m88(hw);
4428cfa0ad2SJack F Vogel if (ret_val)
4438cfa0ad2SJack F Vogel goto out;
4448cfa0ad2SJack F Vogel
4458cfa0ad2SJack F Vogel ret_val = e1000_setup_copper_link_generic(hw);
4468cfa0ad2SJack F Vogel
4478cfa0ad2SJack F Vogel out:
4488cfa0ad2SJack F Vogel return ret_val;
4498cfa0ad2SJack F Vogel }
4508cfa0ad2SJack F Vogel
4518cfa0ad2SJack F Vogel /**
4528cfa0ad2SJack F Vogel * e1000_setup_fiber_serdes_link_82540 - Setup link for fiber/serdes
4538cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
4548cfa0ad2SJack F Vogel *
4558cfa0ad2SJack F Vogel * Set the output amplitude to the value in the EEPROM and adjust the VCO
4568cfa0ad2SJack F Vogel * speed to improve Bit Error Rate (BER) performance. Configures collision
4578cfa0ad2SJack F Vogel * distance and flow control for fiber and serdes links. Upon successful
458daf9197cSJack F Vogel * setup, poll for link.
4598cfa0ad2SJack F Vogel **/
e1000_setup_fiber_serdes_link_82540(struct e1000_hw * hw)4608cfa0ad2SJack F Vogel static s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw)
4618cfa0ad2SJack F Vogel {
4628cfa0ad2SJack F Vogel struct e1000_mac_info *mac = &hw->mac;
4638cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS;
4648cfa0ad2SJack F Vogel
4658cfa0ad2SJack F Vogel DEBUGFUNC("e1000_setup_fiber_serdes_link_82540");
4668cfa0ad2SJack F Vogel
4678cfa0ad2SJack F Vogel switch (mac->type) {
4688cfa0ad2SJack F Vogel case e1000_82545_rev_3:
4698cfa0ad2SJack F Vogel case e1000_82546_rev_3:
4708cfa0ad2SJack F Vogel if (hw->phy.media_type == e1000_media_type_internal_serdes) {
4718cfa0ad2SJack F Vogel /*
4728cfa0ad2SJack F Vogel * If we're on serdes media, adjust the output
4738cfa0ad2SJack F Vogel * amplitude to value set in the EEPROM.
4748cfa0ad2SJack F Vogel */
4758cfa0ad2SJack F Vogel ret_val = e1000_adjust_serdes_amplitude_82540(hw);
4768cfa0ad2SJack F Vogel if (ret_val)
4778cfa0ad2SJack F Vogel goto out;
4788cfa0ad2SJack F Vogel }
4798cfa0ad2SJack F Vogel /* Adjust VCO speed to improve BER performance */
4808cfa0ad2SJack F Vogel ret_val = e1000_set_vco_speed_82540(hw);
4818cfa0ad2SJack F Vogel if (ret_val)
4828cfa0ad2SJack F Vogel goto out;
4838cfa0ad2SJack F Vogel default:
4848cfa0ad2SJack F Vogel break;
4858cfa0ad2SJack F Vogel }
4868cfa0ad2SJack F Vogel
4878cfa0ad2SJack F Vogel ret_val = e1000_setup_fiber_serdes_link_generic(hw);
4888cfa0ad2SJack F Vogel
4898cfa0ad2SJack F Vogel out:
4908cfa0ad2SJack F Vogel return ret_val;
4918cfa0ad2SJack F Vogel }
4928cfa0ad2SJack F Vogel
4938cfa0ad2SJack F Vogel /**
4948cfa0ad2SJack F Vogel * e1000_adjust_serdes_amplitude_82540 - Adjust amplitude based on EEPROM
4958cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
4968cfa0ad2SJack F Vogel *
4978cfa0ad2SJack F Vogel * Adjust the SERDES output amplitude based on the EEPROM settings.
4988cfa0ad2SJack F Vogel **/
e1000_adjust_serdes_amplitude_82540(struct e1000_hw * hw)4998cfa0ad2SJack F Vogel static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw)
5008cfa0ad2SJack F Vogel {
501c80429ceSEric Joyner s32 ret_val;
5028cfa0ad2SJack F Vogel u16 nvm_data;
5038cfa0ad2SJack F Vogel
5048cfa0ad2SJack F Vogel DEBUGFUNC("e1000_adjust_serdes_amplitude_82540");
5058cfa0ad2SJack F Vogel
5068cfa0ad2SJack F Vogel ret_val = hw->nvm.ops.read(hw, NVM_SERDES_AMPLITUDE, 1, &nvm_data);
5078cfa0ad2SJack F Vogel if (ret_val)
5088cfa0ad2SJack F Vogel goto out;
5098cfa0ad2SJack F Vogel
5108cfa0ad2SJack F Vogel if (nvm_data != NVM_RESERVED_WORD) {
5118cfa0ad2SJack F Vogel /* Adjust serdes output amplitude only. */
5128cfa0ad2SJack F Vogel nvm_data &= NVM_SERDES_AMPLITUDE_MASK;
5134dab5c37SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_EXT_CTRL,
5148cfa0ad2SJack F Vogel nvm_data);
5158cfa0ad2SJack F Vogel if (ret_val)
5168cfa0ad2SJack F Vogel goto out;
5178cfa0ad2SJack F Vogel }
5188cfa0ad2SJack F Vogel
5198cfa0ad2SJack F Vogel out:
5208cfa0ad2SJack F Vogel return ret_val;
5218cfa0ad2SJack F Vogel }
5228cfa0ad2SJack F Vogel
5238cfa0ad2SJack F Vogel /**
5248cfa0ad2SJack F Vogel * e1000_set_vco_speed_82540 - Set VCO speed for better performance
5258cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
5268cfa0ad2SJack F Vogel *
5278cfa0ad2SJack F Vogel * Set the VCO speed to improve Bit Error Rate (BER) performance.
5288cfa0ad2SJack F Vogel **/
e1000_set_vco_speed_82540(struct e1000_hw * hw)5298cfa0ad2SJack F Vogel static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw)
5308cfa0ad2SJack F Vogel {
531c80429ceSEric Joyner s32 ret_val;
5328cfa0ad2SJack F Vogel u16 default_page = 0;
5338cfa0ad2SJack F Vogel u16 phy_data;
5348cfa0ad2SJack F Vogel
5358cfa0ad2SJack F Vogel DEBUGFUNC("e1000_set_vco_speed_82540");
5368cfa0ad2SJack F Vogel
5378cfa0ad2SJack F Vogel /* Set PHY register 30, page 5, bit 8 to 0 */
5388cfa0ad2SJack F Vogel
5394dab5c37SJack F Vogel ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_PAGE_SELECT,
5408cfa0ad2SJack F Vogel &default_page);
5418cfa0ad2SJack F Vogel if (ret_val)
5428cfa0ad2SJack F Vogel goto out;
5438cfa0ad2SJack F Vogel
5448cfa0ad2SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);
5458cfa0ad2SJack F Vogel if (ret_val)
5468cfa0ad2SJack F Vogel goto out;
5478cfa0ad2SJack F Vogel
5488cfa0ad2SJack F Vogel ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
5498cfa0ad2SJack F Vogel if (ret_val)
5508cfa0ad2SJack F Vogel goto out;
5518cfa0ad2SJack F Vogel
5528cfa0ad2SJack F Vogel phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
5538cfa0ad2SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
5548cfa0ad2SJack F Vogel if (ret_val)
5558cfa0ad2SJack F Vogel goto out;
5568cfa0ad2SJack F Vogel
5578cfa0ad2SJack F Vogel /* Set PHY register 30, page 4, bit 11 to 1 */
5588cfa0ad2SJack F Vogel
5598cfa0ad2SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);
5608cfa0ad2SJack F Vogel if (ret_val)
5618cfa0ad2SJack F Vogel goto out;
5628cfa0ad2SJack F Vogel
5638cfa0ad2SJack F Vogel ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
5648cfa0ad2SJack F Vogel if (ret_val)
5658cfa0ad2SJack F Vogel goto out;
5668cfa0ad2SJack F Vogel
5678cfa0ad2SJack F Vogel phy_data |= M88E1000_PHY_VCO_REG_BIT11;
5688cfa0ad2SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
5698cfa0ad2SJack F Vogel if (ret_val)
5708cfa0ad2SJack F Vogel goto out;
5718cfa0ad2SJack F Vogel
5728cfa0ad2SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT,
5738cfa0ad2SJack F Vogel default_page);
5748cfa0ad2SJack F Vogel
5758cfa0ad2SJack F Vogel out:
5768cfa0ad2SJack F Vogel return ret_val;
5778cfa0ad2SJack F Vogel }
5788cfa0ad2SJack F Vogel
5798cfa0ad2SJack F Vogel /**
5808cfa0ad2SJack F Vogel * e1000_set_phy_mode_82540 - Set PHY to class A mode
5818cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
5828cfa0ad2SJack F Vogel *
5838cfa0ad2SJack F Vogel * Sets the PHY to class A mode and assumes the following operations will
5848cfa0ad2SJack F Vogel * follow to enable the new class mode:
5858cfa0ad2SJack F Vogel * 1. Do a PHY soft reset.
5868cfa0ad2SJack F Vogel * 2. Restart auto-negotiation or force link.
5878cfa0ad2SJack F Vogel **/
e1000_set_phy_mode_82540(struct e1000_hw * hw)5888cfa0ad2SJack F Vogel static s32 e1000_set_phy_mode_82540(struct e1000_hw *hw)
5898cfa0ad2SJack F Vogel {
5908cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS;
5918cfa0ad2SJack F Vogel u16 nvm_data;
5928cfa0ad2SJack F Vogel
5938cfa0ad2SJack F Vogel DEBUGFUNC("e1000_set_phy_mode_82540");
5948cfa0ad2SJack F Vogel
5958cfa0ad2SJack F Vogel if (hw->mac.type != e1000_82545_rev_3)
5968cfa0ad2SJack F Vogel goto out;
5978cfa0ad2SJack F Vogel
5988cfa0ad2SJack F Vogel ret_val = hw->nvm.ops.read(hw, NVM_PHY_CLASS_WORD, 1, &nvm_data);
5998cfa0ad2SJack F Vogel if (ret_val) {
6008cfa0ad2SJack F Vogel ret_val = -E1000_ERR_PHY;
6018cfa0ad2SJack F Vogel goto out;
6028cfa0ad2SJack F Vogel }
6038cfa0ad2SJack F Vogel
6048cfa0ad2SJack F Vogel if ((nvm_data != NVM_RESERVED_WORD) && (nvm_data & NVM_PHY_CLASS_A)) {
6058cfa0ad2SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT,
6068cfa0ad2SJack F Vogel 0x000B);
6078cfa0ad2SJack F Vogel if (ret_val) {
6088cfa0ad2SJack F Vogel ret_val = -E1000_ERR_PHY;
6098cfa0ad2SJack F Vogel goto out;
6108cfa0ad2SJack F Vogel }
6114dab5c37SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL,
6128cfa0ad2SJack F Vogel 0x8104);
6138cfa0ad2SJack F Vogel if (ret_val) {
6148cfa0ad2SJack F Vogel ret_val = -E1000_ERR_PHY;
6158cfa0ad2SJack F Vogel goto out;
6168cfa0ad2SJack F Vogel }
6178cfa0ad2SJack F Vogel
6188cfa0ad2SJack F Vogel }
6198cfa0ad2SJack F Vogel
6208cfa0ad2SJack F Vogel out:
6218cfa0ad2SJack F Vogel return ret_val;
6228cfa0ad2SJack F Vogel }
6238cfa0ad2SJack F Vogel
6248cfa0ad2SJack F Vogel /**
6258cfa0ad2SJack F Vogel * e1000_power_down_phy_copper_82540 - Remove link in case of PHY power down
6268cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
6278cfa0ad2SJack F Vogel *
6288cfa0ad2SJack F Vogel * In the case of a PHY power down to save power, or to turn off link during a
6298cfa0ad2SJack F Vogel * driver unload, or wake on lan is not enabled, remove the link.
6308cfa0ad2SJack F Vogel **/
e1000_power_down_phy_copper_82540(struct e1000_hw * hw)6318cfa0ad2SJack F Vogel static void e1000_power_down_phy_copper_82540(struct e1000_hw *hw)
6328cfa0ad2SJack F Vogel {
6338cfa0ad2SJack F Vogel /* If the management interface is not enabled, then power down */
6348cfa0ad2SJack F Vogel if (!(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_SMBUS_EN))
6358cfa0ad2SJack F Vogel e1000_power_down_phy_copper(hw);
6368cfa0ad2SJack F Vogel
6378cfa0ad2SJack F Vogel return;
6388cfa0ad2SJack F Vogel }
6398cfa0ad2SJack F Vogel
6408cfa0ad2SJack F Vogel /**
6418cfa0ad2SJack F Vogel * e1000_clear_hw_cntrs_82540 - Clear device specific hardware counters
6428cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
6438cfa0ad2SJack F Vogel *
6448cfa0ad2SJack F Vogel * Clears the hardware counters by reading the counter registers.
6458cfa0ad2SJack F Vogel **/
e1000_clear_hw_cntrs_82540(struct e1000_hw * hw)6468cfa0ad2SJack F Vogel static void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw)
6478cfa0ad2SJack F Vogel {
6488cfa0ad2SJack F Vogel DEBUGFUNC("e1000_clear_hw_cntrs_82540");
6498cfa0ad2SJack F Vogel
6508cfa0ad2SJack F Vogel e1000_clear_hw_cntrs_base_generic(hw);
6518cfa0ad2SJack F Vogel
652daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC64);
653daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC127);
654daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC255);
655daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC511);
656daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC1023);
657daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC1522);
658daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC64);
659daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC127);
660daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC255);
661daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC511);
662daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC1023);
663daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC1522);
6648cfa0ad2SJack F Vogel
665daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_ALGNERRC);
666daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_RXERRC);
667daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_TNCRS);
668daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_CEXTERR);
669daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_TSCTC);
670daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_TSCTFC);
6718cfa0ad2SJack F Vogel
672daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_MGTPRC);
673daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_MGTPDC);
674daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_MGTPTC);
6758cfa0ad2SJack F Vogel }
6768cfa0ad2SJack F Vogel
6779d81738fSJack F Vogel /**
6789d81738fSJack F Vogel * e1000_read_mac_addr_82540 - Read device MAC address
6799d81738fSJack F Vogel * @hw: pointer to the HW structure
6809d81738fSJack F Vogel *
6819d81738fSJack F Vogel * Reads the device MAC address from the EEPROM and stores the value.
6829d81738fSJack F Vogel * Since devices with two ports use the same EEPROM, we increment the
6839d81738fSJack F Vogel * last bit in the MAC address for the second port.
6849d81738fSJack F Vogel *
6859d81738fSJack F Vogel * This version is being used over generic because of customer issues
6869d81738fSJack F Vogel * with VmWare and Virtual Box when using generic. It seems in
6879d81738fSJack F Vogel * the emulated 82545, RAR[0] does NOT have a valid address after a
6889d81738fSJack F Vogel * reset, this older method works and using this breaks nothing for
6899d81738fSJack F Vogel * these legacy adapters.
6909d81738fSJack F Vogel **/
e1000_read_mac_addr_82540(struct e1000_hw * hw)6919d81738fSJack F Vogel s32 e1000_read_mac_addr_82540(struct e1000_hw *hw)
6929d81738fSJack F Vogel {
6939d81738fSJack F Vogel s32 ret_val = E1000_SUCCESS;
6949d81738fSJack F Vogel u16 offset, nvm_data, i;
6959d81738fSJack F Vogel
6969d81738fSJack F Vogel DEBUGFUNC("e1000_read_mac_addr");
6979d81738fSJack F Vogel
698e81998f4SEric Joyner for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
6999d81738fSJack F Vogel offset = i >> 1;
7009d81738fSJack F Vogel ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
7019d81738fSJack F Vogel if (ret_val) {
7029d81738fSJack F Vogel DEBUGOUT("NVM Read Error\n");
7039d81738fSJack F Vogel goto out;
7049d81738fSJack F Vogel }
7059d81738fSJack F Vogel hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
7069d81738fSJack F Vogel hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
7079d81738fSJack F Vogel }
7089d81738fSJack F Vogel
7099d81738fSJack F Vogel /* Flip last bit of mac address if we're on second port */
7109d81738fSJack F Vogel if (hw->bus.func == E1000_FUNC_1)
7119d81738fSJack F Vogel hw->mac.perm_addr[5] ^= 1;
7129d81738fSJack F Vogel
713e81998f4SEric Joyner for (i = 0; i < ETHER_ADDR_LEN; i++)
7149d81738fSJack F Vogel hw->mac.addr[i] = hw->mac.perm_addr[i];
7159d81738fSJack F Vogel
7169d81738fSJack F Vogel out:
7179d81738fSJack F Vogel return ret_val;
7189d81738fSJack F Vogel }
719