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 * 82543GC Gigabit Ethernet Controller (Fiber)
37daf9197cSJack F Vogel * 82543GC Gigabit Ethernet Controller (Copper)
38daf9197cSJack F Vogel * 82544EI Gigabit Ethernet Controller (Copper)
39daf9197cSJack F Vogel * 82544EI Gigabit Ethernet Controller (Fiber)
40daf9197cSJack F Vogel * 82544GC Gigabit Ethernet Controller (Copper)
41daf9197cSJack F Vogel * 82544GC Gigabit Ethernet Controller (LOM)
428cfa0ad2SJack F Vogel */
438cfa0ad2SJack F Vogel
448cfa0ad2SJack F Vogel #include "e1000_api.h"
458cfa0ad2SJack F Vogel
468cfa0ad2SJack F Vogel static s32 e1000_init_phy_params_82543(struct e1000_hw *hw);
478cfa0ad2SJack F Vogel static s32 e1000_init_nvm_params_82543(struct e1000_hw *hw);
488cfa0ad2SJack F Vogel static s32 e1000_init_mac_params_82543(struct e1000_hw *hw);
498cfa0ad2SJack F Vogel static s32 e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset,
508cfa0ad2SJack F Vogel u16 *data);
518cfa0ad2SJack F Vogel static s32 e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset,
528cfa0ad2SJack F Vogel u16 data);
538cfa0ad2SJack F Vogel static s32 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw);
548cfa0ad2SJack F Vogel static s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw);
558cfa0ad2SJack F Vogel static s32 e1000_reset_hw_82543(struct e1000_hw *hw);
568cfa0ad2SJack F Vogel static s32 e1000_init_hw_82543(struct e1000_hw *hw);
578cfa0ad2SJack F Vogel static s32 e1000_setup_link_82543(struct e1000_hw *hw);
588cfa0ad2SJack F Vogel static s32 e1000_setup_copper_link_82543(struct e1000_hw *hw);
598cfa0ad2SJack F Vogel static s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw);
608cfa0ad2SJack F Vogel static s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw);
618cfa0ad2SJack F Vogel static s32 e1000_check_for_fiber_link_82543(struct e1000_hw *hw);
628cfa0ad2SJack F Vogel static s32 e1000_led_on_82543(struct e1000_hw *hw);
638cfa0ad2SJack F Vogel static s32 e1000_led_off_82543(struct e1000_hw *hw);
648cfa0ad2SJack F Vogel static void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset,
658cfa0ad2SJack F Vogel u32 value);
668cfa0ad2SJack F Vogel static void e1000_clear_hw_cntrs_82543(struct e1000_hw *hw);
678cfa0ad2SJack F Vogel static s32 e1000_config_mac_to_phy_82543(struct e1000_hw *hw);
688cfa0ad2SJack F Vogel static bool e1000_init_phy_disabled_82543(struct e1000_hw *hw);
698cfa0ad2SJack F Vogel static void e1000_lower_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl);
708cfa0ad2SJack F Vogel static s32 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw);
718cfa0ad2SJack F Vogel static void e1000_raise_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl);
728cfa0ad2SJack F Vogel static u16 e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw);
738cfa0ad2SJack F Vogel static void e1000_shift_out_mdi_bits_82543(struct e1000_hw *hw, u32 data,
748cfa0ad2SJack F Vogel u16 count);
758cfa0ad2SJack F Vogel static bool e1000_tbi_compatibility_enabled_82543(struct e1000_hw *hw);
768cfa0ad2SJack F Vogel static void e1000_set_tbi_sbp_82543(struct e1000_hw *hw, bool state);
7774dbc418SJack F Vogel static s32 e1000_read_mac_addr_82543(struct e1000_hw *hw);
7874dbc418SJack F Vogel
798cfa0ad2SJack F Vogel
808cfa0ad2SJack F Vogel /**
818cfa0ad2SJack F Vogel * e1000_init_phy_params_82543 - Init PHY func ptrs.
828cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
838cfa0ad2SJack F Vogel **/
e1000_init_phy_params_82543(struct e1000_hw * hw)848cfa0ad2SJack F Vogel static s32 e1000_init_phy_params_82543(struct e1000_hw *hw)
858cfa0ad2SJack F Vogel {
868cfa0ad2SJack F Vogel struct e1000_phy_info *phy = &hw->phy;
878cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS;
888cfa0ad2SJack F Vogel
898cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_phy_params_82543");
908cfa0ad2SJack F Vogel
918cfa0ad2SJack F Vogel if (hw->phy.media_type != e1000_media_type_copper) {
928cfa0ad2SJack F Vogel phy->type = e1000_phy_none;
938cfa0ad2SJack F Vogel goto out;
948cfa0ad2SJack F Vogel } else {
958cfa0ad2SJack F Vogel phy->ops.power_up = e1000_power_up_phy_copper;
968cfa0ad2SJack F Vogel phy->ops.power_down = e1000_power_down_phy_copper;
978cfa0ad2SJack F Vogel }
988cfa0ad2SJack F Vogel
998cfa0ad2SJack F Vogel phy->addr = 1;
1008cfa0ad2SJack F Vogel phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
1018cfa0ad2SJack F Vogel phy->reset_delay_us = 10000;
1028cfa0ad2SJack F Vogel phy->type = e1000_phy_m88;
1038cfa0ad2SJack F Vogel
1048cfa0ad2SJack F Vogel /* Function Pointers */
1058cfa0ad2SJack F Vogel phy->ops.check_polarity = e1000_check_polarity_m88;
1068cfa0ad2SJack F Vogel phy->ops.commit = e1000_phy_sw_reset_generic;
1078cfa0ad2SJack F Vogel phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_82543;
1088cfa0ad2SJack F Vogel phy->ops.get_cable_length = e1000_get_cable_length_m88;
1098cfa0ad2SJack F Vogel phy->ops.get_cfg_done = e1000_get_cfg_done_generic;
1108cfa0ad2SJack F Vogel phy->ops.read_reg = (hw->mac.type == e1000_82543)
1118cfa0ad2SJack F Vogel ? e1000_read_phy_reg_82543
1128cfa0ad2SJack F Vogel : e1000_read_phy_reg_m88;
1138cfa0ad2SJack F Vogel phy->ops.reset = (hw->mac.type == e1000_82543)
1148cfa0ad2SJack F Vogel ? e1000_phy_hw_reset_82543
1158cfa0ad2SJack F Vogel : e1000_phy_hw_reset_generic;
1168cfa0ad2SJack F Vogel phy->ops.write_reg = (hw->mac.type == e1000_82543)
1178cfa0ad2SJack F Vogel ? e1000_write_phy_reg_82543
1188cfa0ad2SJack F Vogel : e1000_write_phy_reg_m88;
1198cfa0ad2SJack F Vogel phy->ops.get_info = e1000_get_phy_info_m88;
1208cfa0ad2SJack F Vogel
1218cfa0ad2SJack F Vogel /*
1228cfa0ad2SJack F Vogel * The external PHY of the 82543 can be in a funky state.
1238cfa0ad2SJack F Vogel * Resetting helps us read the PHY registers for acquiring
1248cfa0ad2SJack F Vogel * the PHY ID.
1258cfa0ad2SJack F Vogel */
1268cfa0ad2SJack F Vogel if (!e1000_init_phy_disabled_82543(hw)) {
1278cfa0ad2SJack F Vogel ret_val = phy->ops.reset(hw);
1288cfa0ad2SJack F Vogel if (ret_val) {
1298cfa0ad2SJack F Vogel DEBUGOUT("Resetting PHY during init failed.\n");
1308cfa0ad2SJack F Vogel goto out;
1318cfa0ad2SJack F Vogel }
1328cfa0ad2SJack F Vogel msec_delay(20);
1338cfa0ad2SJack F Vogel }
1348cfa0ad2SJack F Vogel
1358cfa0ad2SJack F Vogel ret_val = e1000_get_phy_id(hw);
1368cfa0ad2SJack F Vogel if (ret_val)
1378cfa0ad2SJack F Vogel goto out;
1388cfa0ad2SJack F Vogel
1398cfa0ad2SJack F Vogel /* Verify phy id */
1408cfa0ad2SJack F Vogel switch (hw->mac.type) {
1418cfa0ad2SJack F Vogel case e1000_82543:
1428cfa0ad2SJack F Vogel if (phy->id != M88E1000_E_PHY_ID) {
1438cfa0ad2SJack F Vogel ret_val = -E1000_ERR_PHY;
1448cfa0ad2SJack F Vogel goto out;
1458cfa0ad2SJack F Vogel }
1468cfa0ad2SJack F Vogel break;
1478cfa0ad2SJack F Vogel case e1000_82544:
1488cfa0ad2SJack F Vogel if (phy->id != M88E1000_I_PHY_ID) {
1498cfa0ad2SJack F Vogel ret_val = -E1000_ERR_PHY;
1508cfa0ad2SJack F Vogel goto out;
1518cfa0ad2SJack F Vogel }
1528cfa0ad2SJack F Vogel break;
1538cfa0ad2SJack F Vogel default:
1548cfa0ad2SJack F Vogel ret_val = -E1000_ERR_PHY;
1558cfa0ad2SJack F Vogel goto out;
1568cfa0ad2SJack F Vogel break;
1578cfa0ad2SJack F Vogel }
1588cfa0ad2SJack F Vogel
1598cfa0ad2SJack F Vogel out:
1608cfa0ad2SJack F Vogel return ret_val;
1618cfa0ad2SJack F Vogel }
1628cfa0ad2SJack F Vogel
1638cfa0ad2SJack F Vogel /**
1648cfa0ad2SJack F Vogel * e1000_init_nvm_params_82543 - Init NVM func ptrs.
1658cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
1668cfa0ad2SJack F Vogel **/
e1000_init_nvm_params_82543(struct e1000_hw * hw)1678cfa0ad2SJack F Vogel static s32 e1000_init_nvm_params_82543(struct e1000_hw *hw)
1688cfa0ad2SJack F Vogel {
1698cfa0ad2SJack F Vogel struct e1000_nvm_info *nvm = &hw->nvm;
1708cfa0ad2SJack F Vogel
1718cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_nvm_params_82543");
1728cfa0ad2SJack F Vogel
1738cfa0ad2SJack F Vogel nvm->type = e1000_nvm_eeprom_microwire;
1748cfa0ad2SJack F Vogel nvm->word_size = 64;
1758cfa0ad2SJack F Vogel nvm->delay_usec = 50;
1768cfa0ad2SJack F Vogel nvm->address_bits = 6;
1778cfa0ad2SJack F Vogel nvm->opcode_bits = 3;
1788cfa0ad2SJack F Vogel
1798cfa0ad2SJack F Vogel /* Function Pointers */
1808cfa0ad2SJack F Vogel nvm->ops.read = e1000_read_nvm_microwire;
1818cfa0ad2SJack F Vogel nvm->ops.update = e1000_update_nvm_checksum_generic;
1828cfa0ad2SJack F Vogel nvm->ops.valid_led_default = e1000_valid_led_default_generic;
1838cfa0ad2SJack F Vogel nvm->ops.validate = e1000_validate_nvm_checksum_generic;
1848cfa0ad2SJack F Vogel nvm->ops.write = e1000_write_nvm_microwire;
1858cfa0ad2SJack F Vogel
1868cfa0ad2SJack F Vogel return E1000_SUCCESS;
1878cfa0ad2SJack F Vogel }
1888cfa0ad2SJack F Vogel
1898cfa0ad2SJack F Vogel /**
1908cfa0ad2SJack F Vogel * e1000_init_mac_params_82543 - Init MAC func ptrs.
1918cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
1928cfa0ad2SJack F Vogel **/
e1000_init_mac_params_82543(struct e1000_hw * hw)1938cfa0ad2SJack F Vogel static s32 e1000_init_mac_params_82543(struct e1000_hw *hw)
1948cfa0ad2SJack F Vogel {
1958cfa0ad2SJack F Vogel struct e1000_mac_info *mac = &hw->mac;
1968cfa0ad2SJack F Vogel
1978cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_mac_params_82543");
1988cfa0ad2SJack F Vogel
1998cfa0ad2SJack F Vogel /* Set media type */
2008cfa0ad2SJack F Vogel switch (hw->device_id) {
2018cfa0ad2SJack F Vogel case E1000_DEV_ID_82543GC_FIBER:
2028cfa0ad2SJack F Vogel case E1000_DEV_ID_82544EI_FIBER:
2038cfa0ad2SJack F Vogel hw->phy.media_type = e1000_media_type_fiber;
2048cfa0ad2SJack F Vogel break;
2058cfa0ad2SJack F Vogel default:
2068cfa0ad2SJack F Vogel hw->phy.media_type = e1000_media_type_copper;
2078cfa0ad2SJack F Vogel break;
2088cfa0ad2SJack F Vogel }
2098cfa0ad2SJack F Vogel
2108cfa0ad2SJack F Vogel /* Set mta register count */
2118cfa0ad2SJack F Vogel mac->mta_reg_count = 128;
2128cfa0ad2SJack F Vogel /* Set rar entry count */
2138cfa0ad2SJack F Vogel mac->rar_entry_count = E1000_RAR_ENTRIES;
2148cfa0ad2SJack F Vogel
2158cfa0ad2SJack F Vogel /* Function pointers */
2168cfa0ad2SJack F Vogel
2178cfa0ad2SJack F Vogel /* bus type/speed/width */
2188cfa0ad2SJack F Vogel mac->ops.get_bus_info = e1000_get_bus_info_pci_generic;
219daf9197cSJack F Vogel /* function id */
220daf9197cSJack F Vogel mac->ops.set_lan_id = e1000_set_lan_id_multi_port_pci;
2218cfa0ad2SJack F Vogel /* reset */
2228cfa0ad2SJack F Vogel mac->ops.reset_hw = e1000_reset_hw_82543;
2238cfa0ad2SJack F Vogel /* hw initialization */
2248cfa0ad2SJack F Vogel mac->ops.init_hw = e1000_init_hw_82543;
2258cfa0ad2SJack F Vogel /* link setup */
2268cfa0ad2SJack F Vogel mac->ops.setup_link = e1000_setup_link_82543;
2278cfa0ad2SJack F Vogel /* physical interface setup */
2288cfa0ad2SJack F Vogel mac->ops.setup_physical_interface =
2298cfa0ad2SJack F Vogel (hw->phy.media_type == e1000_media_type_copper)
23048600901SSean Bruno ? e1000_setup_copper_link_82543 : e1000_setup_fiber_link_82543;
2318cfa0ad2SJack F Vogel /* check for link */
2328cfa0ad2SJack F Vogel mac->ops.check_for_link =
2338cfa0ad2SJack F Vogel (hw->phy.media_type == e1000_media_type_copper)
2348cfa0ad2SJack F Vogel ? e1000_check_for_copper_link_82543
2358cfa0ad2SJack F Vogel : e1000_check_for_fiber_link_82543;
2368cfa0ad2SJack F Vogel /* link info */
2378cfa0ad2SJack F Vogel mac->ops.get_link_up_info =
2388cfa0ad2SJack F Vogel (hw->phy.media_type == e1000_media_type_copper)
2398cfa0ad2SJack F Vogel ? e1000_get_speed_and_duplex_copper_generic
2408cfa0ad2SJack F Vogel : e1000_get_speed_and_duplex_fiber_serdes_generic;
2418cfa0ad2SJack F Vogel /* multicast address update */
2428cfa0ad2SJack F Vogel mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
2438cfa0ad2SJack F Vogel /* writing VFTA */
2448cfa0ad2SJack F Vogel mac->ops.write_vfta = e1000_write_vfta_82543;
2458cfa0ad2SJack F Vogel /* clearing VFTA */
2468cfa0ad2SJack F Vogel mac->ops.clear_vfta = e1000_clear_vfta_generic;
24774dbc418SJack F Vogel /* read mac address */
24874dbc418SJack F Vogel mac->ops.read_mac_addr = e1000_read_mac_addr_82543;
2498cfa0ad2SJack F Vogel /* turn on/off LED */
2508cfa0ad2SJack F Vogel mac->ops.led_on = e1000_led_on_82543;
2518cfa0ad2SJack F Vogel mac->ops.led_off = e1000_led_off_82543;
2528cfa0ad2SJack F Vogel /* clear hardware counters */
2538cfa0ad2SJack F Vogel mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82543;
2548cfa0ad2SJack F Vogel
2558cfa0ad2SJack F Vogel /* Set tbi compatibility */
2568cfa0ad2SJack F Vogel if ((hw->mac.type != e1000_82543) ||
2578cfa0ad2SJack F Vogel (hw->phy.media_type == e1000_media_type_fiber))
258*1bbdc25fSKevin Bowling e1000_set_tbi_compatibility_82543(hw, false);
2598cfa0ad2SJack F Vogel
260daf9197cSJack F Vogel return E1000_SUCCESS;
2618cfa0ad2SJack F Vogel }
2628cfa0ad2SJack F Vogel
2638cfa0ad2SJack F Vogel /**
2648cfa0ad2SJack F Vogel * e1000_init_function_pointers_82543 - Init func ptrs.
2658cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
2668cfa0ad2SJack F Vogel *
267daf9197cSJack F Vogel * Called to initialize all function pointers and parameters.
2688cfa0ad2SJack F Vogel **/
e1000_init_function_pointers_82543(struct e1000_hw * hw)2698cfa0ad2SJack F Vogel void e1000_init_function_pointers_82543(struct e1000_hw *hw)
2708cfa0ad2SJack F Vogel {
2718cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_function_pointers_82543");
2728cfa0ad2SJack F Vogel
2738cfa0ad2SJack F Vogel hw->mac.ops.init_params = e1000_init_mac_params_82543;
2748cfa0ad2SJack F Vogel hw->nvm.ops.init_params = e1000_init_nvm_params_82543;
2758cfa0ad2SJack F Vogel hw->phy.ops.init_params = e1000_init_phy_params_82543;
2768cfa0ad2SJack F Vogel }
2778cfa0ad2SJack F Vogel
2788cfa0ad2SJack F Vogel /**
2798cfa0ad2SJack F Vogel * e1000_tbi_compatibility_enabled_82543 - Returns TBI compat status
2808cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
2818cfa0ad2SJack F Vogel *
2828cfa0ad2SJack F Vogel * Returns the current status of 10-bit Interface (TBI) compatibility
2838cfa0ad2SJack F Vogel * (enabled/disabled).
2848cfa0ad2SJack F Vogel **/
e1000_tbi_compatibility_enabled_82543(struct e1000_hw * hw)2858cfa0ad2SJack F Vogel static bool e1000_tbi_compatibility_enabled_82543(struct e1000_hw *hw)
2868cfa0ad2SJack F Vogel {
287daf9197cSJack F Vogel struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
288*1bbdc25fSKevin Bowling bool state = false;
2898cfa0ad2SJack F Vogel
2908cfa0ad2SJack F Vogel DEBUGFUNC("e1000_tbi_compatibility_enabled_82543");
2918cfa0ad2SJack F Vogel
2928cfa0ad2SJack F Vogel if (hw->mac.type != e1000_82543) {
2938cfa0ad2SJack F Vogel DEBUGOUT("TBI compatibility workaround for 82543 only.\n");
2948cfa0ad2SJack F Vogel goto out;
2958cfa0ad2SJack F Vogel }
2968cfa0ad2SJack F Vogel
29748600901SSean Bruno state = !!(dev_spec->tbi_compatibility & TBI_COMPAT_ENABLED);
2988cfa0ad2SJack F Vogel
2998cfa0ad2SJack F Vogel out:
3008cfa0ad2SJack F Vogel return state;
3018cfa0ad2SJack F Vogel }
3028cfa0ad2SJack F Vogel
3038cfa0ad2SJack F Vogel /**
3048cfa0ad2SJack F Vogel * e1000_set_tbi_compatibility_82543 - Set TBI compatibility
3058cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
3068cfa0ad2SJack F Vogel * @state: enable/disable TBI compatibility
3078cfa0ad2SJack F Vogel *
3088cfa0ad2SJack F Vogel * Enables or disabled 10-bit Interface (TBI) compatibility.
3098cfa0ad2SJack F Vogel **/
e1000_set_tbi_compatibility_82543(struct e1000_hw * hw,bool state)3108cfa0ad2SJack F Vogel void e1000_set_tbi_compatibility_82543(struct e1000_hw *hw, bool state)
3118cfa0ad2SJack F Vogel {
312daf9197cSJack F Vogel struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
3138cfa0ad2SJack F Vogel
3148cfa0ad2SJack F Vogel DEBUGFUNC("e1000_set_tbi_compatibility_82543");
3158cfa0ad2SJack F Vogel
3168cfa0ad2SJack F Vogel if (hw->mac.type != e1000_82543) {
3178cfa0ad2SJack F Vogel DEBUGOUT("TBI compatibility workaround for 82543 only.\n");
3188cfa0ad2SJack F Vogel goto out;
3198cfa0ad2SJack F Vogel }
3208cfa0ad2SJack F Vogel
3218cfa0ad2SJack F Vogel if (state)
3228cfa0ad2SJack F Vogel dev_spec->tbi_compatibility |= TBI_COMPAT_ENABLED;
3238cfa0ad2SJack F Vogel else
3248cfa0ad2SJack F Vogel dev_spec->tbi_compatibility &= ~TBI_COMPAT_ENABLED;
3258cfa0ad2SJack F Vogel
3268cfa0ad2SJack F Vogel out:
3278cfa0ad2SJack F Vogel return;
3288cfa0ad2SJack F Vogel }
3298cfa0ad2SJack F Vogel
3308cfa0ad2SJack F Vogel /**
3318cfa0ad2SJack F Vogel * e1000_tbi_sbp_enabled_82543 - Returns TBI SBP status
3328cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
3338cfa0ad2SJack F Vogel *
3348cfa0ad2SJack F Vogel * Returns the current status of 10-bit Interface (TBI) store bad packet (SBP)
3358cfa0ad2SJack F Vogel * (enabled/disabled).
3368cfa0ad2SJack F Vogel **/
e1000_tbi_sbp_enabled_82543(struct e1000_hw * hw)3378cfa0ad2SJack F Vogel bool e1000_tbi_sbp_enabled_82543(struct e1000_hw *hw)
3388cfa0ad2SJack F Vogel {
339daf9197cSJack F Vogel struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
340*1bbdc25fSKevin Bowling bool state = false;
3418cfa0ad2SJack F Vogel
3428cfa0ad2SJack F Vogel DEBUGFUNC("e1000_tbi_sbp_enabled_82543");
3438cfa0ad2SJack F Vogel
3448cfa0ad2SJack F Vogel if (hw->mac.type != e1000_82543) {
3458cfa0ad2SJack F Vogel DEBUGOUT("TBI compatibility workaround for 82543 only.\n");
3468cfa0ad2SJack F Vogel goto out;
3478cfa0ad2SJack F Vogel }
3488cfa0ad2SJack F Vogel
34948600901SSean Bruno state = !!(dev_spec->tbi_compatibility & TBI_SBP_ENABLED);
3508cfa0ad2SJack F Vogel
3518cfa0ad2SJack F Vogel out:
3528cfa0ad2SJack F Vogel return state;
3538cfa0ad2SJack F Vogel }
3548cfa0ad2SJack F Vogel
3558cfa0ad2SJack F Vogel /**
3568cfa0ad2SJack F Vogel * e1000_set_tbi_sbp_82543 - Set TBI SBP
3578cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
3588cfa0ad2SJack F Vogel * @state: enable/disable TBI store bad packet
3598cfa0ad2SJack F Vogel *
3608cfa0ad2SJack F Vogel * Enables or disabled 10-bit Interface (TBI) store bad packet (SBP).
3618cfa0ad2SJack F Vogel **/
e1000_set_tbi_sbp_82543(struct e1000_hw * hw,bool state)3628cfa0ad2SJack F Vogel static void e1000_set_tbi_sbp_82543(struct e1000_hw *hw, bool state)
3638cfa0ad2SJack F Vogel {
364daf9197cSJack F Vogel struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
3658cfa0ad2SJack F Vogel
3668cfa0ad2SJack F Vogel DEBUGFUNC("e1000_set_tbi_sbp_82543");
3678cfa0ad2SJack F Vogel
3688cfa0ad2SJack F Vogel if (state && e1000_tbi_compatibility_enabled_82543(hw))
3698cfa0ad2SJack F Vogel dev_spec->tbi_compatibility |= TBI_SBP_ENABLED;
3708cfa0ad2SJack F Vogel else
3718cfa0ad2SJack F Vogel dev_spec->tbi_compatibility &= ~TBI_SBP_ENABLED;
3728cfa0ad2SJack F Vogel
3738cfa0ad2SJack F Vogel return;
3748cfa0ad2SJack F Vogel }
3758cfa0ad2SJack F Vogel
3768cfa0ad2SJack F Vogel /**
3778cfa0ad2SJack F Vogel * e1000_init_phy_disabled_82543 - Returns init PHY status
3788cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
3798cfa0ad2SJack F Vogel *
3808cfa0ad2SJack F Vogel * Returns the current status of whether PHY initialization is disabled.
381*1bbdc25fSKevin Bowling * True if PHY initialization is disabled else false.
3828cfa0ad2SJack F Vogel **/
e1000_init_phy_disabled_82543(struct e1000_hw * hw)3838cfa0ad2SJack F Vogel static bool e1000_init_phy_disabled_82543(struct e1000_hw *hw)
3848cfa0ad2SJack F Vogel {
385daf9197cSJack F Vogel struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
3868cfa0ad2SJack F Vogel bool ret_val;
3878cfa0ad2SJack F Vogel
3888cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_phy_disabled_82543");
3898cfa0ad2SJack F Vogel
3908cfa0ad2SJack F Vogel if (hw->mac.type != e1000_82543) {
391*1bbdc25fSKevin Bowling ret_val = false;
3928cfa0ad2SJack F Vogel goto out;
3938cfa0ad2SJack F Vogel }
3948cfa0ad2SJack F Vogel
3958cfa0ad2SJack F Vogel ret_val = dev_spec->init_phy_disabled;
3968cfa0ad2SJack F Vogel
3978cfa0ad2SJack F Vogel out:
3988cfa0ad2SJack F Vogel return ret_val;
3998cfa0ad2SJack F Vogel }
4008cfa0ad2SJack F Vogel
4018cfa0ad2SJack F Vogel /**
4028cfa0ad2SJack F Vogel * e1000_tbi_adjust_stats_82543 - Adjust stats when TBI enabled
4038cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
4048cfa0ad2SJack F Vogel * @stats: Struct containing statistic register values
4058cfa0ad2SJack F Vogel * @frame_len: The length of the frame in question
4068cfa0ad2SJack F Vogel * @mac_addr: The Ethernet destination address of the frame in question
4078cfa0ad2SJack F Vogel * @max_frame_size: The maximum frame size
4088cfa0ad2SJack F Vogel *
4098cfa0ad2SJack F Vogel * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
4108cfa0ad2SJack F Vogel **/
e1000_tbi_adjust_stats_82543(struct e1000_hw * hw,struct e1000_hw_stats * stats,u32 frame_len,u8 * mac_addr,u32 max_frame_size)4118cfa0ad2SJack F Vogel void e1000_tbi_adjust_stats_82543(struct e1000_hw *hw,
4128cfa0ad2SJack F Vogel struct e1000_hw_stats *stats, u32 frame_len,
4138cfa0ad2SJack F Vogel u8 *mac_addr, u32 max_frame_size)
4148cfa0ad2SJack F Vogel {
4158cfa0ad2SJack F Vogel if (!(e1000_tbi_sbp_enabled_82543(hw)))
4168cfa0ad2SJack F Vogel goto out;
4178cfa0ad2SJack F Vogel
4188cfa0ad2SJack F Vogel /* First adjust the frame length. */
4198cfa0ad2SJack F Vogel frame_len--;
4208cfa0ad2SJack F Vogel /*
4218cfa0ad2SJack F Vogel * We need to adjust the statistics counters, since the hardware
4228cfa0ad2SJack F Vogel * counters overcount this packet as a CRC error and undercount
4238cfa0ad2SJack F Vogel * the packet as a good packet
4248cfa0ad2SJack F Vogel */
4258cfa0ad2SJack F Vogel /* This packet should not be counted as a CRC error. */
4268cfa0ad2SJack F Vogel stats->crcerrs--;
4278cfa0ad2SJack F Vogel /* This packet does count as a Good Packet Received. */
4288cfa0ad2SJack F Vogel stats->gprc++;
4298cfa0ad2SJack F Vogel
4308cfa0ad2SJack F Vogel /* Adjust the Good Octets received counters */
4318cfa0ad2SJack F Vogel stats->gorc += frame_len;
4328cfa0ad2SJack F Vogel
4338cfa0ad2SJack F Vogel /*
4348cfa0ad2SJack F Vogel * Is this a broadcast or multicast? Check broadcast first,
4358cfa0ad2SJack F Vogel * since the test for a multicast frame will test positive on
4368cfa0ad2SJack F Vogel * a broadcast frame.
4378cfa0ad2SJack F Vogel */
4388cfa0ad2SJack F Vogel if ((mac_addr[0] == 0xff) && (mac_addr[1] == 0xff))
4398cfa0ad2SJack F Vogel /* Broadcast packet */
4408cfa0ad2SJack F Vogel stats->bprc++;
4418cfa0ad2SJack F Vogel else if (*mac_addr & 0x01)
4428cfa0ad2SJack F Vogel /* Multicast packet */
4438cfa0ad2SJack F Vogel stats->mprc++;
4448cfa0ad2SJack F Vogel
4458cfa0ad2SJack F Vogel /*
4468cfa0ad2SJack F Vogel * In this case, the hardware has over counted the number of
4478cfa0ad2SJack F Vogel * oversize frames.
4488cfa0ad2SJack F Vogel */
4498cfa0ad2SJack F Vogel if ((frame_len == max_frame_size) && (stats->roc > 0))
4508cfa0ad2SJack F Vogel stats->roc--;
4518cfa0ad2SJack F Vogel
4528cfa0ad2SJack F Vogel /*
4538cfa0ad2SJack F Vogel * Adjust the bin counters when the extra byte put the frame in the
4548cfa0ad2SJack F Vogel * wrong bin. Remember that the frame_len was adjusted above.
4558cfa0ad2SJack F Vogel */
4568cfa0ad2SJack F Vogel if (frame_len == 64) {
4578cfa0ad2SJack F Vogel stats->prc64++;
4588cfa0ad2SJack F Vogel stats->prc127--;
4598cfa0ad2SJack F Vogel } else if (frame_len == 127) {
4608cfa0ad2SJack F Vogel stats->prc127++;
4618cfa0ad2SJack F Vogel stats->prc255--;
4628cfa0ad2SJack F Vogel } else if (frame_len == 255) {
4638cfa0ad2SJack F Vogel stats->prc255++;
4648cfa0ad2SJack F Vogel stats->prc511--;
4658cfa0ad2SJack F Vogel } else if (frame_len == 511) {
4668cfa0ad2SJack F Vogel stats->prc511++;
4678cfa0ad2SJack F Vogel stats->prc1023--;
4688cfa0ad2SJack F Vogel } else if (frame_len == 1023) {
4698cfa0ad2SJack F Vogel stats->prc1023++;
4708cfa0ad2SJack F Vogel stats->prc1522--;
4718cfa0ad2SJack F Vogel } else if (frame_len == 1522) {
4728cfa0ad2SJack F Vogel stats->prc1522++;
4738cfa0ad2SJack F Vogel }
4748cfa0ad2SJack F Vogel
4758cfa0ad2SJack F Vogel out:
4768cfa0ad2SJack F Vogel return;
4778cfa0ad2SJack F Vogel }
4788cfa0ad2SJack F Vogel
4798cfa0ad2SJack F Vogel /**
4808cfa0ad2SJack F Vogel * e1000_read_phy_reg_82543 - Read PHY register
4818cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
4828cfa0ad2SJack F Vogel * @offset: register offset to be read
4838cfa0ad2SJack F Vogel * @data: pointer to the read data
4848cfa0ad2SJack F Vogel *
4858cfa0ad2SJack F Vogel * Reads the PHY at offset and stores the information read to data.
4868cfa0ad2SJack F Vogel **/
e1000_read_phy_reg_82543(struct e1000_hw * hw,u32 offset,u16 * data)4878cfa0ad2SJack F Vogel static s32 e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 *data)
4888cfa0ad2SJack F Vogel {
4898cfa0ad2SJack F Vogel u32 mdic;
4908cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS;
4918cfa0ad2SJack F Vogel
4928cfa0ad2SJack F Vogel DEBUGFUNC("e1000_read_phy_reg_82543");
4938cfa0ad2SJack F Vogel
4948cfa0ad2SJack F Vogel if (offset > MAX_PHY_REG_ADDRESS) {
4958cfa0ad2SJack F Vogel DEBUGOUT1("PHY Address %d is out of range\n", offset);
4968cfa0ad2SJack F Vogel ret_val = -E1000_ERR_PARAM;
4978cfa0ad2SJack F Vogel goto out;
4988cfa0ad2SJack F Vogel }
4998cfa0ad2SJack F Vogel
5008cfa0ad2SJack F Vogel /*
5018cfa0ad2SJack F Vogel * We must first send a preamble through the MDIO pin to signal the
5028cfa0ad2SJack F Vogel * beginning of an MII instruction. This is done by sending 32
5038cfa0ad2SJack F Vogel * consecutive "1" bits.
5048cfa0ad2SJack F Vogel */
5058cfa0ad2SJack F Vogel e1000_shift_out_mdi_bits_82543(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
5068cfa0ad2SJack F Vogel
5078cfa0ad2SJack F Vogel /*
5088cfa0ad2SJack F Vogel * Now combine the next few fields that are required for a read
5098cfa0ad2SJack F Vogel * operation. We use this method instead of calling the
5108cfa0ad2SJack F Vogel * e1000_shift_out_mdi_bits routine five different times. The format
5118cfa0ad2SJack F Vogel * of an MII read instruction consists of a shift out of 14 bits and
5128cfa0ad2SJack F Vogel * is defined as follows:
5138cfa0ad2SJack F Vogel * <Preamble><SOF><Op Code><Phy Addr><Offset>
5148cfa0ad2SJack F Vogel * followed by a shift in of 18 bits. This first two bits shifted in
5158cfa0ad2SJack F Vogel * are TurnAround bits used to avoid contention on the MDIO pin when a
5168cfa0ad2SJack F Vogel * READ operation is performed. These two bits are thrown away
5178cfa0ad2SJack F Vogel * followed by a shift in of 16 bits which contains the desired data.
5188cfa0ad2SJack F Vogel */
5198cfa0ad2SJack F Vogel mdic = (offset | (hw->phy.addr << 5) |
5208cfa0ad2SJack F Vogel (PHY_OP_READ << 10) | (PHY_SOF << 12));
5218cfa0ad2SJack F Vogel
5228cfa0ad2SJack F Vogel e1000_shift_out_mdi_bits_82543(hw, mdic, 14);
5238cfa0ad2SJack F Vogel
5248cfa0ad2SJack F Vogel /*
5258cfa0ad2SJack F Vogel * Now that we've shifted out the read command to the MII, we need to
5268cfa0ad2SJack F Vogel * "shift in" the 16-bit value (18 total bits) of the requested PHY
5278cfa0ad2SJack F Vogel * register address.
5288cfa0ad2SJack F Vogel */
5298cfa0ad2SJack F Vogel *data = e1000_shift_in_mdi_bits_82543(hw);
5308cfa0ad2SJack F Vogel
5318cfa0ad2SJack F Vogel out:
5328cfa0ad2SJack F Vogel return ret_val;
5338cfa0ad2SJack F Vogel }
5348cfa0ad2SJack F Vogel
5358cfa0ad2SJack F Vogel /**
5368cfa0ad2SJack F Vogel * e1000_write_phy_reg_82543 - Write PHY register
5378cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
5388cfa0ad2SJack F Vogel * @offset: register offset to be written
5398cfa0ad2SJack F Vogel * @data: pointer to the data to be written at offset
5408cfa0ad2SJack F Vogel *
5418cfa0ad2SJack F Vogel * Writes data to the PHY at offset.
5428cfa0ad2SJack F Vogel **/
e1000_write_phy_reg_82543(struct e1000_hw * hw,u32 offset,u16 data)5438cfa0ad2SJack F Vogel static s32 e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 data)
5448cfa0ad2SJack F Vogel {
5458cfa0ad2SJack F Vogel u32 mdic;
5468cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS;
5478cfa0ad2SJack F Vogel
5488cfa0ad2SJack F Vogel DEBUGFUNC("e1000_write_phy_reg_82543");
5498cfa0ad2SJack F Vogel
5508cfa0ad2SJack F Vogel if (offset > MAX_PHY_REG_ADDRESS) {
5518cfa0ad2SJack F Vogel DEBUGOUT1("PHY Address %d is out of range\n", offset);
5528cfa0ad2SJack F Vogel ret_val = -E1000_ERR_PARAM;
5538cfa0ad2SJack F Vogel goto out;
5548cfa0ad2SJack F Vogel }
5558cfa0ad2SJack F Vogel
5568cfa0ad2SJack F Vogel /*
5578cfa0ad2SJack F Vogel * We'll need to use the SW defined pins to shift the write command
5588cfa0ad2SJack F Vogel * out to the PHY. We first send a preamble to the PHY to signal the
5598cfa0ad2SJack F Vogel * beginning of the MII instruction. This is done by sending 32
5608cfa0ad2SJack F Vogel * consecutive "1" bits.
5618cfa0ad2SJack F Vogel */
5628cfa0ad2SJack F Vogel e1000_shift_out_mdi_bits_82543(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
5638cfa0ad2SJack F Vogel
5648cfa0ad2SJack F Vogel /*
5658cfa0ad2SJack F Vogel * Now combine the remaining required fields that will indicate a
5668cfa0ad2SJack F Vogel * write operation. We use this method instead of calling the
5678cfa0ad2SJack F Vogel * e1000_shift_out_mdi_bits routine for each field in the command. The
5688cfa0ad2SJack F Vogel * format of a MII write instruction is as follows:
5698cfa0ad2SJack F Vogel * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
5708cfa0ad2SJack F Vogel */
5718cfa0ad2SJack F Vogel mdic = ((PHY_TURNAROUND) | (offset << 2) | (hw->phy.addr << 7) |
5728cfa0ad2SJack F Vogel (PHY_OP_WRITE << 12) | (PHY_SOF << 14));
5738cfa0ad2SJack F Vogel mdic <<= 16;
5748cfa0ad2SJack F Vogel mdic |= (u32)data;
5758cfa0ad2SJack F Vogel
5768cfa0ad2SJack F Vogel e1000_shift_out_mdi_bits_82543(hw, mdic, 32);
5778cfa0ad2SJack F Vogel
5788cfa0ad2SJack F Vogel out:
5798cfa0ad2SJack F Vogel return ret_val;
5808cfa0ad2SJack F Vogel }
5818cfa0ad2SJack F Vogel
5828cfa0ad2SJack F Vogel /**
5838cfa0ad2SJack F Vogel * e1000_raise_mdi_clk_82543 - Raise Management Data Input clock
5848cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
5858cfa0ad2SJack F Vogel * @ctrl: pointer to the control register
5868cfa0ad2SJack F Vogel *
5878cfa0ad2SJack F Vogel * Raise the management data input clock by setting the MDC bit in the control
5888cfa0ad2SJack F Vogel * register.
5898cfa0ad2SJack F Vogel **/
e1000_raise_mdi_clk_82543(struct e1000_hw * hw,u32 * ctrl)5908cfa0ad2SJack F Vogel static void e1000_raise_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl)
5918cfa0ad2SJack F Vogel {
5928cfa0ad2SJack F Vogel /*
5938cfa0ad2SJack F Vogel * Raise the clock input to the Management Data Clock (by setting the
5948cfa0ad2SJack F Vogel * MDC bit), and then delay a sufficient amount of time.
5958cfa0ad2SJack F Vogel */
5968cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, (*ctrl | E1000_CTRL_MDC));
5978cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw);
5988cfa0ad2SJack F Vogel usec_delay(10);
5998cfa0ad2SJack F Vogel }
6008cfa0ad2SJack F Vogel
6018cfa0ad2SJack F Vogel /**
6028cfa0ad2SJack F Vogel * e1000_lower_mdi_clk_82543 - Lower Management Data Input clock
6038cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
6048cfa0ad2SJack F Vogel * @ctrl: pointer to the control register
6058cfa0ad2SJack F Vogel *
6068cfa0ad2SJack F Vogel * Lower the management data input clock by clearing the MDC bit in the
6078cfa0ad2SJack F Vogel * control register.
6088cfa0ad2SJack F Vogel **/
e1000_lower_mdi_clk_82543(struct e1000_hw * hw,u32 * ctrl)6098cfa0ad2SJack F Vogel static void e1000_lower_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl)
6108cfa0ad2SJack F Vogel {
6118cfa0ad2SJack F Vogel /*
6128cfa0ad2SJack F Vogel * Lower the clock input to the Management Data Clock (by clearing the
6138cfa0ad2SJack F Vogel * MDC bit), and then delay a sufficient amount of time.
6148cfa0ad2SJack F Vogel */
6158cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, (*ctrl & ~E1000_CTRL_MDC));
6168cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw);
6178cfa0ad2SJack F Vogel usec_delay(10);
6188cfa0ad2SJack F Vogel }
6198cfa0ad2SJack F Vogel
6208cfa0ad2SJack F Vogel /**
6218cfa0ad2SJack F Vogel * e1000_shift_out_mdi_bits_82543 - Shift data bits our to the PHY
6228cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
6238cfa0ad2SJack F Vogel * @data: data to send to the PHY
6248cfa0ad2SJack F Vogel * @count: number of bits to shift out
6258cfa0ad2SJack F Vogel *
6268cfa0ad2SJack F Vogel * We need to shift 'count' bits out to the PHY. So, the value in the
6278cfa0ad2SJack F Vogel * "data" parameter will be shifted out to the PHY one bit at a time.
6288cfa0ad2SJack F Vogel * In order to do this, "data" must be broken down into bits.
6298cfa0ad2SJack F Vogel **/
e1000_shift_out_mdi_bits_82543(struct e1000_hw * hw,u32 data,u16 count)6308cfa0ad2SJack F Vogel static void e1000_shift_out_mdi_bits_82543(struct e1000_hw *hw, u32 data,
6318cfa0ad2SJack F Vogel u16 count)
6328cfa0ad2SJack F Vogel {
6338cfa0ad2SJack F Vogel u32 ctrl, mask;
6348cfa0ad2SJack F Vogel
6358cfa0ad2SJack F Vogel /*
6368cfa0ad2SJack F Vogel * We need to shift "count" number of bits out to the PHY. So, the
6378cfa0ad2SJack F Vogel * value in the "data" parameter will be shifted out to the PHY one
6388cfa0ad2SJack F Vogel * bit at a time. In order to do this, "data" must be broken down
6398cfa0ad2SJack F Vogel * into bits.
6408cfa0ad2SJack F Vogel */
6418cfa0ad2SJack F Vogel mask = 0x01;
6428cfa0ad2SJack F Vogel mask <<= (count - 1);
6438cfa0ad2SJack F Vogel
6448cfa0ad2SJack F Vogel ctrl = E1000_READ_REG(hw, E1000_CTRL);
6458cfa0ad2SJack F Vogel
6468cfa0ad2SJack F Vogel /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
6478cfa0ad2SJack F Vogel ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
6488cfa0ad2SJack F Vogel
6498cfa0ad2SJack F Vogel while (mask) {
6508cfa0ad2SJack F Vogel /*
6518cfa0ad2SJack F Vogel * A "1" is shifted out to the PHY by setting the MDIO bit to
6528cfa0ad2SJack F Vogel * "1" and then raising and lowering the Management Data Clock.
6538cfa0ad2SJack F Vogel * A "0" is shifted out to the PHY by setting the MDIO bit to
6548cfa0ad2SJack F Vogel * "0" and then raising and lowering the clock.
6558cfa0ad2SJack F Vogel */
65648600901SSean Bruno if (data & mask)
65748600901SSean Bruno ctrl |= E1000_CTRL_MDIO;
65848600901SSean Bruno else
65948600901SSean Bruno ctrl &= ~E1000_CTRL_MDIO;
6608cfa0ad2SJack F Vogel
6618cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
6628cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw);
6638cfa0ad2SJack F Vogel
6648cfa0ad2SJack F Vogel usec_delay(10);
6658cfa0ad2SJack F Vogel
6668cfa0ad2SJack F Vogel e1000_raise_mdi_clk_82543(hw, &ctrl);
6678cfa0ad2SJack F Vogel e1000_lower_mdi_clk_82543(hw, &ctrl);
6688cfa0ad2SJack F Vogel
6698cfa0ad2SJack F Vogel mask >>= 1;
6708cfa0ad2SJack F Vogel }
6718cfa0ad2SJack F Vogel }
6728cfa0ad2SJack F Vogel
6738cfa0ad2SJack F Vogel /**
6748cfa0ad2SJack F Vogel * e1000_shift_in_mdi_bits_82543 - Shift data bits in from the PHY
6758cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
6768cfa0ad2SJack F Vogel *
6778cfa0ad2SJack F Vogel * In order to read a register from the PHY, we need to shift 18 bits
6788cfa0ad2SJack F Vogel * in from the PHY. Bits are "shifted in" by raising the clock input to
6798cfa0ad2SJack F Vogel * the PHY (setting the MDC bit), and then reading the value of the data out
6808cfa0ad2SJack F Vogel * MDIO bit.
6818cfa0ad2SJack F Vogel **/
e1000_shift_in_mdi_bits_82543(struct e1000_hw * hw)6828cfa0ad2SJack F Vogel static u16 e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw)
6838cfa0ad2SJack F Vogel {
6848cfa0ad2SJack F Vogel u32 ctrl;
6858cfa0ad2SJack F Vogel u16 data = 0;
6868cfa0ad2SJack F Vogel u8 i;
6878cfa0ad2SJack F Vogel
6888cfa0ad2SJack F Vogel /*
6898cfa0ad2SJack F Vogel * In order to read a register from the PHY, we need to shift in a
6908cfa0ad2SJack F Vogel * total of 18 bits from the PHY. The first two bit (turnaround)
6918cfa0ad2SJack F Vogel * times are used to avoid contention on the MDIO pin when a read
6928cfa0ad2SJack F Vogel * operation is performed. These two bits are ignored by us and
6938cfa0ad2SJack F Vogel * thrown away. Bits are "shifted in" by raising the input to the
6948cfa0ad2SJack F Vogel * Management Data Clock (setting the MDC bit) and then reading the
6958cfa0ad2SJack F Vogel * value of the MDIO bit.
6968cfa0ad2SJack F Vogel */
6978cfa0ad2SJack F Vogel ctrl = E1000_READ_REG(hw, E1000_CTRL);
6988cfa0ad2SJack F Vogel
6998cfa0ad2SJack F Vogel /*
7008cfa0ad2SJack F Vogel * Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as
7018cfa0ad2SJack F Vogel * input.
7028cfa0ad2SJack F Vogel */
7038cfa0ad2SJack F Vogel ctrl &= ~E1000_CTRL_MDIO_DIR;
7048cfa0ad2SJack F Vogel ctrl &= ~E1000_CTRL_MDIO;
7058cfa0ad2SJack F Vogel
7068cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
7078cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw);
7088cfa0ad2SJack F Vogel
7098cfa0ad2SJack F Vogel /*
7108cfa0ad2SJack F Vogel * Raise and lower the clock before reading in the data. This accounts
7118cfa0ad2SJack F Vogel * for the turnaround bits. The first clock occurred when we clocked
7128cfa0ad2SJack F Vogel * out the last bit of the Register Address.
7138cfa0ad2SJack F Vogel */
7148cfa0ad2SJack F Vogel e1000_raise_mdi_clk_82543(hw, &ctrl);
7158cfa0ad2SJack F Vogel e1000_lower_mdi_clk_82543(hw, &ctrl);
7168cfa0ad2SJack F Vogel
7178cfa0ad2SJack F Vogel for (data = 0, i = 0; i < 16; i++) {
7188cfa0ad2SJack F Vogel data <<= 1;
7198cfa0ad2SJack F Vogel e1000_raise_mdi_clk_82543(hw, &ctrl);
7208cfa0ad2SJack F Vogel ctrl = E1000_READ_REG(hw, E1000_CTRL);
7218cfa0ad2SJack F Vogel /* Check to see if we shifted in a "1". */
7228cfa0ad2SJack F Vogel if (ctrl & E1000_CTRL_MDIO)
7238cfa0ad2SJack F Vogel data |= 1;
7248cfa0ad2SJack F Vogel e1000_lower_mdi_clk_82543(hw, &ctrl);
7258cfa0ad2SJack F Vogel }
7268cfa0ad2SJack F Vogel
7278cfa0ad2SJack F Vogel e1000_raise_mdi_clk_82543(hw, &ctrl);
7288cfa0ad2SJack F Vogel e1000_lower_mdi_clk_82543(hw, &ctrl);
7298cfa0ad2SJack F Vogel
7308cfa0ad2SJack F Vogel return data;
7318cfa0ad2SJack F Vogel }
7328cfa0ad2SJack F Vogel
7338cfa0ad2SJack F Vogel /**
7348cfa0ad2SJack F Vogel * e1000_phy_force_speed_duplex_82543 - Force speed/duplex for PHY
7358cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
7368cfa0ad2SJack F Vogel *
7378cfa0ad2SJack F Vogel * Calls the function to force speed and duplex for the m88 PHY, and
7388cfa0ad2SJack F Vogel * if the PHY is not auto-negotiating and the speed is forced to 10Mbit,
7398cfa0ad2SJack F Vogel * then call the function for polarity reversal workaround.
7408cfa0ad2SJack F Vogel **/
e1000_phy_force_speed_duplex_82543(struct e1000_hw * hw)7418cfa0ad2SJack F Vogel static s32 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw)
7428cfa0ad2SJack F Vogel {
7438cfa0ad2SJack F Vogel s32 ret_val;
7448cfa0ad2SJack F Vogel
7458cfa0ad2SJack F Vogel DEBUGFUNC("e1000_phy_force_speed_duplex_82543");
7468cfa0ad2SJack F Vogel
7478cfa0ad2SJack F Vogel ret_val = e1000_phy_force_speed_duplex_m88(hw);
7488cfa0ad2SJack F Vogel if (ret_val)
7498cfa0ad2SJack F Vogel goto out;
7508cfa0ad2SJack F Vogel
75148600901SSean Bruno if (!hw->mac.autoneg && (hw->mac.forced_speed_duplex &
75248600901SSean Bruno E1000_ALL_10_SPEED))
7538cfa0ad2SJack F Vogel ret_val = e1000_polarity_reversal_workaround_82543(hw);
7548cfa0ad2SJack F Vogel
7558cfa0ad2SJack F Vogel out:
7568cfa0ad2SJack F Vogel return ret_val;
7578cfa0ad2SJack F Vogel }
7588cfa0ad2SJack F Vogel
7598cfa0ad2SJack F Vogel /**
7608cfa0ad2SJack F Vogel * e1000_polarity_reversal_workaround_82543 - Workaround polarity reversal
7618cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
7628cfa0ad2SJack F Vogel *
7638cfa0ad2SJack F Vogel * When forcing link to 10 Full or 10 Half, the PHY can reverse the polarity
7648cfa0ad2SJack F Vogel * inadvertently. To workaround the issue, we disable the transmitter on
7658cfa0ad2SJack F Vogel * the PHY until we have established the link partner's link parameters.
7668cfa0ad2SJack F Vogel **/
e1000_polarity_reversal_workaround_82543(struct e1000_hw * hw)7678cfa0ad2SJack F Vogel static s32 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw)
7688cfa0ad2SJack F Vogel {
7698cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS;
7708cfa0ad2SJack F Vogel u16 mii_status_reg;
7718cfa0ad2SJack F Vogel u16 i;
7728cfa0ad2SJack F Vogel bool link;
7738cfa0ad2SJack F Vogel
7748cfa0ad2SJack F Vogel if (!(hw->phy.ops.write_reg))
7758cfa0ad2SJack F Vogel goto out;
7768cfa0ad2SJack F Vogel
7778cfa0ad2SJack F Vogel /* Polarity reversal workaround for forced 10F/10H links. */
7788cfa0ad2SJack F Vogel
7798cfa0ad2SJack F Vogel /* Disable the transmitter on the PHY */
7808cfa0ad2SJack F Vogel
7818cfa0ad2SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
7828cfa0ad2SJack F Vogel if (ret_val)
7838cfa0ad2SJack F Vogel goto out;
7848cfa0ad2SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
7858cfa0ad2SJack F Vogel if (ret_val)
7868cfa0ad2SJack F Vogel goto out;
7878cfa0ad2SJack F Vogel
7888cfa0ad2SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
7898cfa0ad2SJack F Vogel if (ret_val)
7908cfa0ad2SJack F Vogel goto out;
7918cfa0ad2SJack F Vogel
7928cfa0ad2SJack F Vogel /*
7938cfa0ad2SJack F Vogel * This loop will early-out if the NO link condition has been met.
7948cfa0ad2SJack F Vogel * In other words, DO NOT use e1000_phy_has_link_generic() here.
7958cfa0ad2SJack F Vogel */
7968cfa0ad2SJack F Vogel for (i = PHY_FORCE_TIME; i > 0; i--) {
7978cfa0ad2SJack F Vogel /*
7988cfa0ad2SJack F Vogel * Read the MII Status Register and wait for Link Status bit
7998cfa0ad2SJack F Vogel * to be clear.
8008cfa0ad2SJack F Vogel */
8018cfa0ad2SJack F Vogel
8028cfa0ad2SJack F Vogel ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg);
8038cfa0ad2SJack F Vogel if (ret_val)
8048cfa0ad2SJack F Vogel goto out;
8058cfa0ad2SJack F Vogel
8068cfa0ad2SJack F Vogel ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg);
8078cfa0ad2SJack F Vogel if (ret_val)
8088cfa0ad2SJack F Vogel goto out;
8098cfa0ad2SJack F Vogel
81048600901SSean Bruno if (!(mii_status_reg & ~MII_SR_LINK_STATUS))
8118cfa0ad2SJack F Vogel break;
8128cfa0ad2SJack F Vogel msec_delay_irq(100);
8138cfa0ad2SJack F Vogel }
8148cfa0ad2SJack F Vogel
8158cfa0ad2SJack F Vogel /* Recommended delay time after link has been lost */
8168cfa0ad2SJack F Vogel msec_delay_irq(1000);
8178cfa0ad2SJack F Vogel
8188cfa0ad2SJack F Vogel /* Now we will re-enable the transmitter on the PHY */
8198cfa0ad2SJack F Vogel
8208cfa0ad2SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
8218cfa0ad2SJack F Vogel if (ret_val)
8228cfa0ad2SJack F Vogel goto out;
8238cfa0ad2SJack F Vogel msec_delay_irq(50);
8248cfa0ad2SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);
8258cfa0ad2SJack F Vogel if (ret_val)
8268cfa0ad2SJack F Vogel goto out;
8278cfa0ad2SJack F Vogel msec_delay_irq(50);
8288cfa0ad2SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);
8298cfa0ad2SJack F Vogel if (ret_val)
8308cfa0ad2SJack F Vogel goto out;
8318cfa0ad2SJack F Vogel msec_delay_irq(50);
8328cfa0ad2SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);
8338cfa0ad2SJack F Vogel if (ret_val)
8348cfa0ad2SJack F Vogel goto out;
8358cfa0ad2SJack F Vogel
8368cfa0ad2SJack F Vogel ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
8378cfa0ad2SJack F Vogel if (ret_val)
8388cfa0ad2SJack F Vogel goto out;
8398cfa0ad2SJack F Vogel
8408cfa0ad2SJack F Vogel /*
8418cfa0ad2SJack F Vogel * Read the MII Status Register and wait for Link Status bit
8428cfa0ad2SJack F Vogel * to be set.
8438cfa0ad2SJack F Vogel */
8448cfa0ad2SJack F Vogel ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_TIME, 100000, &link);
8458cfa0ad2SJack F Vogel if (ret_val)
8468cfa0ad2SJack F Vogel goto out;
8478cfa0ad2SJack F Vogel
8488cfa0ad2SJack F Vogel out:
8498cfa0ad2SJack F Vogel return ret_val;
8508cfa0ad2SJack F Vogel }
8518cfa0ad2SJack F Vogel
8528cfa0ad2SJack F Vogel /**
8538cfa0ad2SJack F Vogel * e1000_phy_hw_reset_82543 - PHY hardware reset
8548cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
8558cfa0ad2SJack F Vogel *
8568cfa0ad2SJack F Vogel * Sets the PHY_RESET_DIR bit in the extended device control register
8578cfa0ad2SJack F Vogel * to put the PHY into a reset and waits for completion. Once the reset
8588cfa0ad2SJack F Vogel * has been accomplished, clear the PHY_RESET_DIR bit to take the PHY out
859daf9197cSJack F Vogel * of reset.
8608cfa0ad2SJack F Vogel **/
e1000_phy_hw_reset_82543(struct e1000_hw * hw)8618cfa0ad2SJack F Vogel static s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw)
8628cfa0ad2SJack F Vogel {
8638cfa0ad2SJack F Vogel u32 ctrl_ext;
8648cfa0ad2SJack F Vogel s32 ret_val;
8658cfa0ad2SJack F Vogel
8668cfa0ad2SJack F Vogel DEBUGFUNC("e1000_phy_hw_reset_82543");
8678cfa0ad2SJack F Vogel
8688cfa0ad2SJack F Vogel /*
8698cfa0ad2SJack F Vogel * Read the Extended Device Control Register, assert the PHY_RESET_DIR
8708cfa0ad2SJack F Vogel * bit to put the PHY into reset...
8718cfa0ad2SJack F Vogel */
8728cfa0ad2SJack F Vogel ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
8738cfa0ad2SJack F Vogel ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
8748cfa0ad2SJack F Vogel ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
8758cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
8768cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw);
8778cfa0ad2SJack F Vogel
8788cfa0ad2SJack F Vogel msec_delay(10);
8798cfa0ad2SJack F Vogel
8808cfa0ad2SJack F Vogel /* ...then take it out of reset. */
8818cfa0ad2SJack F Vogel ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
8828cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
8838cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw);
8848cfa0ad2SJack F Vogel
8858cfa0ad2SJack F Vogel usec_delay(150);
8868cfa0ad2SJack F Vogel
8878cfa0ad2SJack F Vogel if (!(hw->phy.ops.get_cfg_done))
8888cfa0ad2SJack F Vogel return E1000_SUCCESS;
8898cfa0ad2SJack F Vogel
8908cfa0ad2SJack F Vogel ret_val = hw->phy.ops.get_cfg_done(hw);
8918cfa0ad2SJack F Vogel
8928cfa0ad2SJack F Vogel return ret_val;
8938cfa0ad2SJack F Vogel }
8948cfa0ad2SJack F Vogel
8958cfa0ad2SJack F Vogel /**
8968cfa0ad2SJack F Vogel * e1000_reset_hw_82543 - Reset hardware
8978cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
8988cfa0ad2SJack F Vogel *
899daf9197cSJack F Vogel * This resets the hardware into a known state.
9008cfa0ad2SJack F Vogel **/
e1000_reset_hw_82543(struct e1000_hw * hw)9018cfa0ad2SJack F Vogel static s32 e1000_reset_hw_82543(struct e1000_hw *hw)
9028cfa0ad2SJack F Vogel {
903c80429ceSEric Joyner u32 ctrl;
9048cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS;
9058cfa0ad2SJack F Vogel
9068cfa0ad2SJack F Vogel DEBUGFUNC("e1000_reset_hw_82543");
9078cfa0ad2SJack F Vogel
9088cfa0ad2SJack F Vogel DEBUGOUT("Masking off all interrupts\n");
9098cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
9108cfa0ad2SJack F Vogel
9118cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_RCTL, 0);
9128cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
9138cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw);
9148cfa0ad2SJack F Vogel
915*1bbdc25fSKevin Bowling e1000_set_tbi_sbp_82543(hw, false);
9168cfa0ad2SJack F Vogel
9178cfa0ad2SJack F Vogel /*
9188cfa0ad2SJack F Vogel * Delay to allow any outstanding PCI transactions to complete before
9198cfa0ad2SJack F Vogel * resetting the device
9208cfa0ad2SJack F Vogel */
9218cfa0ad2SJack F Vogel msec_delay(10);
9228cfa0ad2SJack F Vogel
9238cfa0ad2SJack F Vogel ctrl = E1000_READ_REG(hw, E1000_CTRL);
9248cfa0ad2SJack F Vogel
9258cfa0ad2SJack F Vogel DEBUGOUT("Issuing a global reset to 82543/82544 MAC\n");
9268cfa0ad2SJack F Vogel if (hw->mac.type == e1000_82543) {
9278cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
9288cfa0ad2SJack F Vogel } else {
9298cfa0ad2SJack F Vogel /*
9308cfa0ad2SJack F Vogel * The 82544 can't ACK the 64-bit write when issuing the
9318cfa0ad2SJack F Vogel * reset, so use IO-mapping as a workaround.
9328cfa0ad2SJack F Vogel */
9338cfa0ad2SJack F Vogel E1000_WRITE_REG_IO(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
9348cfa0ad2SJack F Vogel }
9358cfa0ad2SJack F Vogel
9368cfa0ad2SJack F Vogel /*
9378cfa0ad2SJack F Vogel * After MAC reset, force reload of NVM to restore power-on
9388cfa0ad2SJack F Vogel * settings to device.
9398cfa0ad2SJack F Vogel */
9408cfa0ad2SJack F Vogel hw->nvm.ops.reload(hw);
9418cfa0ad2SJack F Vogel msec_delay(2);
9428cfa0ad2SJack F Vogel
9438cfa0ad2SJack F Vogel /* Masking off and clearing any pending interrupts */
9448cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
945c80429ceSEric Joyner E1000_READ_REG(hw, E1000_ICR);
9468cfa0ad2SJack F Vogel
9478cfa0ad2SJack F Vogel return ret_val;
9488cfa0ad2SJack F Vogel }
9498cfa0ad2SJack F Vogel
9508cfa0ad2SJack F Vogel /**
9518cfa0ad2SJack F Vogel * e1000_init_hw_82543 - Initialize hardware
9528cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
9538cfa0ad2SJack F Vogel *
9548cfa0ad2SJack F Vogel * This inits the hardware readying it for operation.
9558cfa0ad2SJack F Vogel **/
e1000_init_hw_82543(struct e1000_hw * hw)9568cfa0ad2SJack F Vogel static s32 e1000_init_hw_82543(struct e1000_hw *hw)
9578cfa0ad2SJack F Vogel {
9588cfa0ad2SJack F Vogel struct e1000_mac_info *mac = &hw->mac;
959daf9197cSJack F Vogel struct e1000_dev_spec_82543 *dev_spec = &hw->dev_spec._82543;
9608cfa0ad2SJack F Vogel u32 ctrl;
9618cfa0ad2SJack F Vogel s32 ret_val;
9628cfa0ad2SJack F Vogel u16 i;
9638cfa0ad2SJack F Vogel
9648cfa0ad2SJack F Vogel DEBUGFUNC("e1000_init_hw_82543");
9658cfa0ad2SJack F Vogel
9668cfa0ad2SJack F Vogel /* Disabling VLAN filtering */
9678cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_VET, 0);
9688cfa0ad2SJack F Vogel mac->ops.clear_vfta(hw);
9698cfa0ad2SJack F Vogel
9708cfa0ad2SJack F Vogel /* Setup the receive address. */
9718cfa0ad2SJack F Vogel e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);
9728cfa0ad2SJack F Vogel
9738cfa0ad2SJack F Vogel /* Zero out the Multicast HASH table */
9748cfa0ad2SJack F Vogel DEBUGOUT("Zeroing the MTA\n");
9758cfa0ad2SJack F Vogel for (i = 0; i < mac->mta_reg_count; i++) {
9768cfa0ad2SJack F Vogel E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
9778cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw);
9788cfa0ad2SJack F Vogel }
9798cfa0ad2SJack F Vogel
9808cfa0ad2SJack F Vogel /*
9818cfa0ad2SJack F Vogel * Set the PCI priority bit correctly in the CTRL register. This
9828cfa0ad2SJack F Vogel * determines if the adapter gives priority to receives, or if it
9838cfa0ad2SJack F Vogel * gives equal priority to transmits and receives.
9848cfa0ad2SJack F Vogel */
9858cfa0ad2SJack F Vogel if (hw->mac.type == e1000_82543 && dev_spec->dma_fairness) {
9868cfa0ad2SJack F Vogel ctrl = E1000_READ_REG(hw, E1000_CTRL);
9878cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PRIOR);
9888cfa0ad2SJack F Vogel }
9898cfa0ad2SJack F Vogel
9908cfa0ad2SJack F Vogel e1000_pcix_mmrbc_workaround_generic(hw);
9918cfa0ad2SJack F Vogel
9928cfa0ad2SJack F Vogel /* Setup link and flow control */
9938cfa0ad2SJack F Vogel ret_val = mac->ops.setup_link(hw);
9948cfa0ad2SJack F Vogel
9958cfa0ad2SJack F Vogel /*
9968cfa0ad2SJack F Vogel * Clear all of the statistics registers (clear on read). It is
9978cfa0ad2SJack F Vogel * important that we do this after we have tried to establish link
9988cfa0ad2SJack F Vogel * because the symbol error count will increment wildly if there
9998cfa0ad2SJack F Vogel * is no link.
10008cfa0ad2SJack F Vogel */
10018cfa0ad2SJack F Vogel e1000_clear_hw_cntrs_82543(hw);
10028cfa0ad2SJack F Vogel
10038cfa0ad2SJack F Vogel return ret_val;
10048cfa0ad2SJack F Vogel }
10058cfa0ad2SJack F Vogel
10068cfa0ad2SJack F Vogel /**
10078cfa0ad2SJack F Vogel * e1000_setup_link_82543 - Setup flow control and link settings
10088cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
10098cfa0ad2SJack F Vogel *
10108cfa0ad2SJack F Vogel * Read the EEPROM to determine the initial polarity value and write the
10118cfa0ad2SJack F Vogel * extended device control register with the information before calling
10128cfa0ad2SJack F Vogel * the generic setup link function, which does the following:
10138cfa0ad2SJack F Vogel * Determines which flow control settings to use, then configures flow
10148cfa0ad2SJack F Vogel * control. Calls the appropriate media-specific link configuration
10158cfa0ad2SJack F Vogel * function. Assuming the adapter has a valid link partner, a valid link
10168cfa0ad2SJack F Vogel * should be established. Assumes the hardware has previously been reset
10178cfa0ad2SJack F Vogel * and the transmitter and receiver are not enabled.
10188cfa0ad2SJack F Vogel **/
e1000_setup_link_82543(struct e1000_hw * hw)10198cfa0ad2SJack F Vogel static s32 e1000_setup_link_82543(struct e1000_hw *hw)
10208cfa0ad2SJack F Vogel {
10218cfa0ad2SJack F Vogel u32 ctrl_ext;
10228cfa0ad2SJack F Vogel s32 ret_val;
10238cfa0ad2SJack F Vogel u16 data;
10248cfa0ad2SJack F Vogel
10258cfa0ad2SJack F Vogel DEBUGFUNC("e1000_setup_link_82543");
10268cfa0ad2SJack F Vogel
10278cfa0ad2SJack F Vogel /*
10288cfa0ad2SJack F Vogel * Take the 4 bits from NVM word 0xF that determine the initial
10298cfa0ad2SJack F Vogel * polarity value for the SW controlled pins, and setup the
10308cfa0ad2SJack F Vogel * Extended Device Control reg with that info.
10318cfa0ad2SJack F Vogel * This is needed because one of the SW controlled pins is used for
10328cfa0ad2SJack F Vogel * signal detection. So this should be done before phy setup.
10338cfa0ad2SJack F Vogel */
10348cfa0ad2SJack F Vogel if (hw->mac.type == e1000_82543) {
10358cfa0ad2SJack F Vogel ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &data);
10368cfa0ad2SJack F Vogel if (ret_val) {
10378cfa0ad2SJack F Vogel DEBUGOUT("NVM Read Error\n");
10388cfa0ad2SJack F Vogel ret_val = -E1000_ERR_NVM;
10398cfa0ad2SJack F Vogel goto out;
10408cfa0ad2SJack F Vogel }
10418cfa0ad2SJack F Vogel ctrl_ext = ((data & NVM_WORD0F_SWPDIO_EXT_MASK) <<
10428cfa0ad2SJack F Vogel NVM_SWDPIO_EXT_SHIFT);
10438cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
10448cfa0ad2SJack F Vogel }
10458cfa0ad2SJack F Vogel
10468cfa0ad2SJack F Vogel ret_val = e1000_setup_link_generic(hw);
10478cfa0ad2SJack F Vogel
10488cfa0ad2SJack F Vogel out:
10498cfa0ad2SJack F Vogel return ret_val;
10508cfa0ad2SJack F Vogel }
10518cfa0ad2SJack F Vogel
10528cfa0ad2SJack F Vogel /**
10538cfa0ad2SJack F Vogel * e1000_setup_copper_link_82543 - Configure copper link settings
10548cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
10558cfa0ad2SJack F Vogel *
10568cfa0ad2SJack F Vogel * Configures the link for auto-neg or forced speed and duplex. Then we check
10578cfa0ad2SJack F Vogel * for link, once link is established calls to configure collision distance
10588cfa0ad2SJack F Vogel * and flow control are called.
10598cfa0ad2SJack F Vogel **/
e1000_setup_copper_link_82543(struct e1000_hw * hw)10608cfa0ad2SJack F Vogel static s32 e1000_setup_copper_link_82543(struct e1000_hw *hw)
10618cfa0ad2SJack F Vogel {
10628cfa0ad2SJack F Vogel u32 ctrl;
10638cfa0ad2SJack F Vogel s32 ret_val;
1064089cdb39SAndrzej Ostruszka bool link = true;
10658cfa0ad2SJack F Vogel
10668cfa0ad2SJack F Vogel DEBUGFUNC("e1000_setup_copper_link_82543");
10678cfa0ad2SJack F Vogel
10688cfa0ad2SJack F Vogel ctrl = E1000_READ_REG(hw, E1000_CTRL) | E1000_CTRL_SLU;
10698cfa0ad2SJack F Vogel /*
10708cfa0ad2SJack F Vogel * With 82543, we need to force speed and duplex on the MAC
10718cfa0ad2SJack F Vogel * equal to what the PHY speed and duplex configuration is.
10728cfa0ad2SJack F Vogel * In addition, we need to perform a hardware reset on the
10738cfa0ad2SJack F Vogel * PHY to take it out of reset.
10748cfa0ad2SJack F Vogel */
10758cfa0ad2SJack F Vogel if (hw->mac.type == e1000_82543) {
10768cfa0ad2SJack F Vogel ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
10778cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
10788cfa0ad2SJack F Vogel ret_val = hw->phy.ops.reset(hw);
10798cfa0ad2SJack F Vogel if (ret_val)
10808cfa0ad2SJack F Vogel goto out;
10818cfa0ad2SJack F Vogel } else {
10828cfa0ad2SJack F Vogel ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
10838cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
10848cfa0ad2SJack F Vogel }
10858cfa0ad2SJack F Vogel
10868cfa0ad2SJack F Vogel /* Set MDI/MDI-X, Polarity Reversal, and downshift settings */
10878cfa0ad2SJack F Vogel ret_val = e1000_copper_link_setup_m88(hw);
10888cfa0ad2SJack F Vogel if (ret_val)
10898cfa0ad2SJack F Vogel goto out;
10908cfa0ad2SJack F Vogel
10918cfa0ad2SJack F Vogel if (hw->mac.autoneg) {
10928cfa0ad2SJack F Vogel /*
10938cfa0ad2SJack F Vogel * Setup autoneg and flow control advertisement and perform
10948cfa0ad2SJack F Vogel * autonegotiation.
10958cfa0ad2SJack F Vogel */
10968cfa0ad2SJack F Vogel ret_val = e1000_copper_link_autoneg(hw);
10978cfa0ad2SJack F Vogel if (ret_val)
10988cfa0ad2SJack F Vogel goto out;
10998cfa0ad2SJack F Vogel } else {
11008cfa0ad2SJack F Vogel /*
11018cfa0ad2SJack F Vogel * PHY will be set to 10H, 10F, 100H or 100F
11028cfa0ad2SJack F Vogel * depending on user settings.
11038cfa0ad2SJack F Vogel */
11048cfa0ad2SJack F Vogel DEBUGOUT("Forcing Speed and Duplex\n");
11058cfa0ad2SJack F Vogel ret_val = e1000_phy_force_speed_duplex_82543(hw);
11068cfa0ad2SJack F Vogel if (ret_val) {
11078cfa0ad2SJack F Vogel DEBUGOUT("Error Forcing Speed and Duplex\n");
11088cfa0ad2SJack F Vogel goto out;
11098cfa0ad2SJack F Vogel }
11108cfa0ad2SJack F Vogel }
11118cfa0ad2SJack F Vogel
11128cfa0ad2SJack F Vogel /*
11138cfa0ad2SJack F Vogel * Check link status. Wait up to 100 microseconds for link to become
11148cfa0ad2SJack F Vogel * valid.
11158cfa0ad2SJack F Vogel */
111648600901SSean Bruno ret_val = e1000_phy_has_link_generic(hw, COPPER_LINK_UP_LIMIT, 10,
11178cfa0ad2SJack F Vogel &link);
11188cfa0ad2SJack F Vogel if (ret_val)
11198cfa0ad2SJack F Vogel goto out;
11208cfa0ad2SJack F Vogel
11218cfa0ad2SJack F Vogel
11228cfa0ad2SJack F Vogel if (link) {
11238cfa0ad2SJack F Vogel DEBUGOUT("Valid link established!!!\n");
11248cfa0ad2SJack F Vogel /* Config the MAC and PHY after link is up */
11258cfa0ad2SJack F Vogel if (hw->mac.type == e1000_82544) {
1126ab5d0362SJack F Vogel hw->mac.ops.config_collision_dist(hw);
11278cfa0ad2SJack F Vogel } else {
11288cfa0ad2SJack F Vogel ret_val = e1000_config_mac_to_phy_82543(hw);
11298cfa0ad2SJack F Vogel if (ret_val)
11308cfa0ad2SJack F Vogel goto out;
11318cfa0ad2SJack F Vogel }
11328cfa0ad2SJack F Vogel ret_val = e1000_config_fc_after_link_up_generic(hw);
11338cfa0ad2SJack F Vogel } else {
11348cfa0ad2SJack F Vogel DEBUGOUT("Unable to establish link!!!\n");
11358cfa0ad2SJack F Vogel }
11368cfa0ad2SJack F Vogel
11378cfa0ad2SJack F Vogel out:
11388cfa0ad2SJack F Vogel return ret_val;
11398cfa0ad2SJack F Vogel }
11408cfa0ad2SJack F Vogel
11418cfa0ad2SJack F Vogel /**
11428cfa0ad2SJack F Vogel * e1000_setup_fiber_link_82543 - Setup link for fiber
11438cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
11448cfa0ad2SJack F Vogel *
11458cfa0ad2SJack F Vogel * Configures collision distance and flow control for fiber links. Upon
11468cfa0ad2SJack F Vogel * successful setup, poll for link.
11478cfa0ad2SJack F Vogel **/
e1000_setup_fiber_link_82543(struct e1000_hw * hw)11488cfa0ad2SJack F Vogel static s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw)
11498cfa0ad2SJack F Vogel {
11508cfa0ad2SJack F Vogel u32 ctrl;
11518cfa0ad2SJack F Vogel s32 ret_val;
11528cfa0ad2SJack F Vogel
11538cfa0ad2SJack F Vogel DEBUGFUNC("e1000_setup_fiber_link_82543");
11548cfa0ad2SJack F Vogel
11558cfa0ad2SJack F Vogel ctrl = E1000_READ_REG(hw, E1000_CTRL);
11568cfa0ad2SJack F Vogel
11578cfa0ad2SJack F Vogel /* Take the link out of reset */
11588cfa0ad2SJack F Vogel ctrl &= ~E1000_CTRL_LRST;
11598cfa0ad2SJack F Vogel
1160ab5d0362SJack F Vogel hw->mac.ops.config_collision_dist(hw);
11618cfa0ad2SJack F Vogel
11628cfa0ad2SJack F Vogel ret_val = e1000_commit_fc_settings_generic(hw);
11638cfa0ad2SJack F Vogel if (ret_val)
11648cfa0ad2SJack F Vogel goto out;
11658cfa0ad2SJack F Vogel
11668cfa0ad2SJack F Vogel DEBUGOUT("Auto-negotiation enabled\n");
11678cfa0ad2SJack F Vogel
11688cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
11698cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw);
11708cfa0ad2SJack F Vogel msec_delay(1);
11718cfa0ad2SJack F Vogel
11728cfa0ad2SJack F Vogel /*
11738cfa0ad2SJack F Vogel * For these adapters, the SW definable pin 1 is cleared when the
11748cfa0ad2SJack F Vogel * optics detect a signal. If we have a signal, then poll for a
11758cfa0ad2SJack F Vogel * "Link-Up" indication.
11768cfa0ad2SJack F Vogel */
117748600901SSean Bruno if (!(E1000_READ_REG(hw, E1000_CTRL) & E1000_CTRL_SWDPIN1))
11788cfa0ad2SJack F Vogel ret_val = e1000_poll_fiber_serdes_link_generic(hw);
117948600901SSean Bruno else
11808cfa0ad2SJack F Vogel DEBUGOUT("No signal detected\n");
11818cfa0ad2SJack F Vogel
11828cfa0ad2SJack F Vogel out:
11838cfa0ad2SJack F Vogel return ret_val;
11848cfa0ad2SJack F Vogel }
11858cfa0ad2SJack F Vogel
11868cfa0ad2SJack F Vogel /**
11878cfa0ad2SJack F Vogel * e1000_check_for_copper_link_82543 - Check for link (Copper)
11888cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
11898cfa0ad2SJack F Vogel *
11908cfa0ad2SJack F Vogel * Checks the phy for link, if link exists, do the following:
11918cfa0ad2SJack F Vogel * - check for downshift
11928cfa0ad2SJack F Vogel * - do polarity workaround (if necessary)
11938cfa0ad2SJack F Vogel * - configure collision distance
11948cfa0ad2SJack F Vogel * - configure flow control after link up
11958cfa0ad2SJack F Vogel * - configure tbi compatibility
11968cfa0ad2SJack F Vogel **/
e1000_check_for_copper_link_82543(struct e1000_hw * hw)11978cfa0ad2SJack F Vogel static s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw)
11988cfa0ad2SJack F Vogel {
11998cfa0ad2SJack F Vogel struct e1000_mac_info *mac = &hw->mac;
12008cfa0ad2SJack F Vogel u32 icr, rctl;
12018cfa0ad2SJack F Vogel s32 ret_val;
12028cfa0ad2SJack F Vogel u16 speed, duplex;
12038cfa0ad2SJack F Vogel bool link;
12048cfa0ad2SJack F Vogel
12058cfa0ad2SJack F Vogel DEBUGFUNC("e1000_check_for_copper_link_82543");
12068cfa0ad2SJack F Vogel
12078cfa0ad2SJack F Vogel if (!mac->get_link_status) {
12088cfa0ad2SJack F Vogel ret_val = E1000_SUCCESS;
12098cfa0ad2SJack F Vogel goto out;
12108cfa0ad2SJack F Vogel }
12118cfa0ad2SJack F Vogel
12128cfa0ad2SJack F Vogel ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
12138cfa0ad2SJack F Vogel if (ret_val)
12148cfa0ad2SJack F Vogel goto out;
12158cfa0ad2SJack F Vogel
12168cfa0ad2SJack F Vogel if (!link)
12178cfa0ad2SJack F Vogel goto out; /* No link detected */
12188cfa0ad2SJack F Vogel
1219*1bbdc25fSKevin Bowling mac->get_link_status = false;
12208cfa0ad2SJack F Vogel
12218cfa0ad2SJack F Vogel e1000_check_downshift_generic(hw);
12228cfa0ad2SJack F Vogel
12238cfa0ad2SJack F Vogel /*
12248cfa0ad2SJack F Vogel * If we are forcing speed/duplex, then we can return since
12258cfa0ad2SJack F Vogel * we have already determined whether we have link or not.
12268cfa0ad2SJack F Vogel */
12278cfa0ad2SJack F Vogel if (!mac->autoneg) {
12288cfa0ad2SJack F Vogel /*
12298cfa0ad2SJack F Vogel * If speed and duplex are forced to 10H or 10F, then we will
12308cfa0ad2SJack F Vogel * implement the polarity reversal workaround. We disable
12318cfa0ad2SJack F Vogel * interrupts first, and upon returning, place the devices
12328cfa0ad2SJack F Vogel * interrupt state to its previous value except for the link
12338cfa0ad2SJack F Vogel * status change interrupt which will happened due to the
12348cfa0ad2SJack F Vogel * execution of this workaround.
12358cfa0ad2SJack F Vogel */
12368cfa0ad2SJack F Vogel if (mac->forced_speed_duplex & E1000_ALL_10_SPEED) {
12378cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_IMC, 0xFFFFFFFF);
12388cfa0ad2SJack F Vogel ret_val = e1000_polarity_reversal_workaround_82543(hw);
12398cfa0ad2SJack F Vogel icr = E1000_READ_REG(hw, E1000_ICR);
12408cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_ICS, (icr & ~E1000_ICS_LSC));
12418cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_IMS, IMS_ENABLE_MASK);
12428cfa0ad2SJack F Vogel }
12438cfa0ad2SJack F Vogel
12448cfa0ad2SJack F Vogel ret_val = -E1000_ERR_CONFIG;
12458cfa0ad2SJack F Vogel goto out;
12468cfa0ad2SJack F Vogel }
12478cfa0ad2SJack F Vogel
12488cfa0ad2SJack F Vogel /*
12498cfa0ad2SJack F Vogel * We have a M88E1000 PHY and Auto-Neg is enabled. If we
12508cfa0ad2SJack F Vogel * have Si on board that is 82544 or newer, Auto
12518cfa0ad2SJack F Vogel * Speed Detection takes care of MAC speed/duplex
12528cfa0ad2SJack F Vogel * configuration. So we only need to configure Collision
12538cfa0ad2SJack F Vogel * Distance in the MAC. Otherwise, we need to force
12548cfa0ad2SJack F Vogel * speed/duplex on the MAC to the current PHY speed/duplex
12558cfa0ad2SJack F Vogel * settings.
12568cfa0ad2SJack F Vogel */
12578cfa0ad2SJack F Vogel if (mac->type == e1000_82544)
1258ab5d0362SJack F Vogel hw->mac.ops.config_collision_dist(hw);
12598cfa0ad2SJack F Vogel else {
12608cfa0ad2SJack F Vogel ret_val = e1000_config_mac_to_phy_82543(hw);
12618cfa0ad2SJack F Vogel if (ret_val) {
12628cfa0ad2SJack F Vogel DEBUGOUT("Error configuring MAC to PHY settings\n");
12638cfa0ad2SJack F Vogel goto out;
12648cfa0ad2SJack F Vogel }
12658cfa0ad2SJack F Vogel }
12668cfa0ad2SJack F Vogel
12678cfa0ad2SJack F Vogel /*
12688cfa0ad2SJack F Vogel * Configure Flow Control now that Auto-Neg has completed.
12698cfa0ad2SJack F Vogel * First, we need to restore the desired flow control
12708cfa0ad2SJack F Vogel * settings because we may have had to re-autoneg with a
12718cfa0ad2SJack F Vogel * different link partner.
12728cfa0ad2SJack F Vogel */
12738cfa0ad2SJack F Vogel ret_val = e1000_config_fc_after_link_up_generic(hw);
127448600901SSean Bruno if (ret_val)
12758cfa0ad2SJack F Vogel DEBUGOUT("Error configuring flow control\n");
12768cfa0ad2SJack F Vogel
12778cfa0ad2SJack F Vogel /*
12788cfa0ad2SJack F Vogel * At this point we know that we are on copper and we have
12798cfa0ad2SJack F Vogel * auto-negotiated link. These are conditions for checking the link
12808cfa0ad2SJack F Vogel * partner capability register. We use the link speed to determine if
12818cfa0ad2SJack F Vogel * TBI compatibility needs to be turned on or off. If the link is not
12828cfa0ad2SJack F Vogel * at gigabit speed, then TBI compatibility is not needed. If we are
12838cfa0ad2SJack F Vogel * at gigabit speed, we turn on TBI compatibility.
12848cfa0ad2SJack F Vogel */
12858cfa0ad2SJack F Vogel if (e1000_tbi_compatibility_enabled_82543(hw)) {
12868cfa0ad2SJack F Vogel ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex);
12878cfa0ad2SJack F Vogel if (ret_val) {
12888cfa0ad2SJack F Vogel DEBUGOUT("Error getting link speed and duplex\n");
12898cfa0ad2SJack F Vogel return ret_val;
12908cfa0ad2SJack F Vogel }
12918cfa0ad2SJack F Vogel if (speed != SPEED_1000) {
12928cfa0ad2SJack F Vogel /*
12938cfa0ad2SJack F Vogel * If link speed is not set to gigabit speed,
12948cfa0ad2SJack F Vogel * we do not need to enable TBI compatibility.
12958cfa0ad2SJack F Vogel */
12968cfa0ad2SJack F Vogel if (e1000_tbi_sbp_enabled_82543(hw)) {
12978cfa0ad2SJack F Vogel /*
12988cfa0ad2SJack F Vogel * If we previously were in the mode,
12998cfa0ad2SJack F Vogel * turn it off.
13008cfa0ad2SJack F Vogel */
1301*1bbdc25fSKevin Bowling e1000_set_tbi_sbp_82543(hw, false);
13028cfa0ad2SJack F Vogel rctl = E1000_READ_REG(hw, E1000_RCTL);
13038cfa0ad2SJack F Vogel rctl &= ~E1000_RCTL_SBP;
13048cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_RCTL, rctl);
13058cfa0ad2SJack F Vogel }
13068cfa0ad2SJack F Vogel } else {
13078cfa0ad2SJack F Vogel /*
13088cfa0ad2SJack F Vogel * If TBI compatibility is was previously off,
13098cfa0ad2SJack F Vogel * turn it on. For compatibility with a TBI link
13108cfa0ad2SJack F Vogel * partner, we will store bad packets. Some
13118cfa0ad2SJack F Vogel * frames have an additional byte on the end and
1312caa7e52fSEitan Adler * will look like CRC errors to the hardware.
13138cfa0ad2SJack F Vogel */
13148cfa0ad2SJack F Vogel if (!e1000_tbi_sbp_enabled_82543(hw)) {
1315*1bbdc25fSKevin Bowling e1000_set_tbi_sbp_82543(hw, true);
13168cfa0ad2SJack F Vogel rctl = E1000_READ_REG(hw, E1000_RCTL);
13178cfa0ad2SJack F Vogel rctl |= E1000_RCTL_SBP;
13188cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_RCTL, rctl);
13198cfa0ad2SJack F Vogel }
13208cfa0ad2SJack F Vogel }
13218cfa0ad2SJack F Vogel }
13228cfa0ad2SJack F Vogel out:
13238cfa0ad2SJack F Vogel return ret_val;
13248cfa0ad2SJack F Vogel }
13258cfa0ad2SJack F Vogel
13268cfa0ad2SJack F Vogel /**
13278cfa0ad2SJack F Vogel * e1000_check_for_fiber_link_82543 - Check for link (Fiber)
13288cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
13298cfa0ad2SJack F Vogel *
13308cfa0ad2SJack F Vogel * Checks for link up on the hardware. If link is not up and we have
13318cfa0ad2SJack F Vogel * a signal, then we need to force link up.
13328cfa0ad2SJack F Vogel **/
e1000_check_for_fiber_link_82543(struct e1000_hw * hw)13338cfa0ad2SJack F Vogel static s32 e1000_check_for_fiber_link_82543(struct e1000_hw *hw)
13348cfa0ad2SJack F Vogel {
13358cfa0ad2SJack F Vogel struct e1000_mac_info *mac = &hw->mac;
13368cfa0ad2SJack F Vogel u32 rxcw, ctrl, status;
13378cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS;
13388cfa0ad2SJack F Vogel
13398cfa0ad2SJack F Vogel DEBUGFUNC("e1000_check_for_fiber_link_82543");
13408cfa0ad2SJack F Vogel
13418cfa0ad2SJack F Vogel ctrl = E1000_READ_REG(hw, E1000_CTRL);
13428cfa0ad2SJack F Vogel status = E1000_READ_REG(hw, E1000_STATUS);
13438cfa0ad2SJack F Vogel rxcw = E1000_READ_REG(hw, E1000_RXCW);
13448cfa0ad2SJack F Vogel
13458cfa0ad2SJack F Vogel /*
13468cfa0ad2SJack F Vogel * If we don't have link (auto-negotiation failed or link partner
13478cfa0ad2SJack F Vogel * cannot auto-negotiate), the cable is plugged in (we have signal),
13488cfa0ad2SJack F Vogel * and our link partner is not trying to auto-negotiate with us (we
13498cfa0ad2SJack F Vogel * are receiving idles or data), we need to force link up. We also
13508cfa0ad2SJack F Vogel * need to give auto-negotiation time to complete, in case the cable
13518cfa0ad2SJack F Vogel * was just plugged in. The autoneg_failed flag does this.
13528cfa0ad2SJack F Vogel */
13538cfa0ad2SJack F Vogel /* (ctrl & E1000_CTRL_SWDPIN1) == 0 == have signal */
13548cfa0ad2SJack F Vogel if ((!(ctrl & E1000_CTRL_SWDPIN1)) &&
13558cfa0ad2SJack F Vogel (!(status & E1000_STATUS_LU)) &&
13568cfa0ad2SJack F Vogel (!(rxcw & E1000_RXCW_C))) {
135748600901SSean Bruno if (!mac->autoneg_failed) {
1358*1bbdc25fSKevin Bowling mac->autoneg_failed = true;
13598cfa0ad2SJack F Vogel ret_val = 0;
13608cfa0ad2SJack F Vogel goto out;
13618cfa0ad2SJack F Vogel }
13628cfa0ad2SJack F Vogel DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n");
13638cfa0ad2SJack F Vogel
13648cfa0ad2SJack F Vogel /* Disable auto-negotiation in the TXCW register */
13658cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_TXCW, (mac->txcw & ~E1000_TXCW_ANE));
13668cfa0ad2SJack F Vogel
13678cfa0ad2SJack F Vogel /* Force link-up and also force full-duplex. */
13688cfa0ad2SJack F Vogel ctrl = E1000_READ_REG(hw, E1000_CTRL);
13698cfa0ad2SJack F Vogel ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
13708cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
13718cfa0ad2SJack F Vogel
13728cfa0ad2SJack F Vogel /* Configure Flow Control after forcing link up. */
13738cfa0ad2SJack F Vogel ret_val = e1000_config_fc_after_link_up_generic(hw);
13748cfa0ad2SJack F Vogel if (ret_val) {
13758cfa0ad2SJack F Vogel DEBUGOUT("Error configuring flow control\n");
13768cfa0ad2SJack F Vogel goto out;
13778cfa0ad2SJack F Vogel }
13788cfa0ad2SJack F Vogel } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
13798cfa0ad2SJack F Vogel /*
13808cfa0ad2SJack F Vogel * If we are forcing link and we are receiving /C/ ordered
13818cfa0ad2SJack F Vogel * sets, re-enable auto-negotiation in the TXCW register
13828cfa0ad2SJack F Vogel * and disable forced link in the Device Control register
13838cfa0ad2SJack F Vogel * in an attempt to auto-negotiate with our link partner.
13848cfa0ad2SJack F Vogel */
13858cfa0ad2SJack F Vogel DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n");
13868cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw);
13878cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, (ctrl & ~E1000_CTRL_SLU));
13888cfa0ad2SJack F Vogel
1389*1bbdc25fSKevin Bowling mac->serdes_has_link = true;
13908cfa0ad2SJack F Vogel }
13918cfa0ad2SJack F Vogel
13928cfa0ad2SJack F Vogel out:
13938cfa0ad2SJack F Vogel return ret_val;
13948cfa0ad2SJack F Vogel }
13958cfa0ad2SJack F Vogel
13968cfa0ad2SJack F Vogel /**
13978cfa0ad2SJack F Vogel * e1000_config_mac_to_phy_82543 - Configure MAC to PHY settings
13988cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
13998cfa0ad2SJack F Vogel *
14008cfa0ad2SJack F Vogel * For the 82543 silicon, we need to set the MAC to match the settings
14018cfa0ad2SJack F Vogel * of the PHY, even if the PHY is auto-negotiating.
14028cfa0ad2SJack F Vogel **/
e1000_config_mac_to_phy_82543(struct e1000_hw * hw)14038cfa0ad2SJack F Vogel static s32 e1000_config_mac_to_phy_82543(struct e1000_hw *hw)
14048cfa0ad2SJack F Vogel {
14058cfa0ad2SJack F Vogel u32 ctrl;
14068cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS;
14078cfa0ad2SJack F Vogel u16 phy_data;
14088cfa0ad2SJack F Vogel
14098cfa0ad2SJack F Vogel DEBUGFUNC("e1000_config_mac_to_phy_82543");
14108cfa0ad2SJack F Vogel
14118cfa0ad2SJack F Vogel if (!(hw->phy.ops.read_reg))
14128cfa0ad2SJack F Vogel goto out;
14138cfa0ad2SJack F Vogel
14148cfa0ad2SJack F Vogel /* Set the bits to force speed and duplex */
14158cfa0ad2SJack F Vogel ctrl = E1000_READ_REG(hw, E1000_CTRL);
14168cfa0ad2SJack F Vogel ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
14178cfa0ad2SJack F Vogel ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
14188cfa0ad2SJack F Vogel
14198cfa0ad2SJack F Vogel /*
14208cfa0ad2SJack F Vogel * Set up duplex in the Device Control and Transmit Control
14218cfa0ad2SJack F Vogel * registers depending on negotiated values.
14228cfa0ad2SJack F Vogel */
14238cfa0ad2SJack F Vogel ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
14248cfa0ad2SJack F Vogel if (ret_val)
14258cfa0ad2SJack F Vogel goto out;
14268cfa0ad2SJack F Vogel
14278cfa0ad2SJack F Vogel ctrl &= ~E1000_CTRL_FD;
14288cfa0ad2SJack F Vogel if (phy_data & M88E1000_PSSR_DPLX)
14298cfa0ad2SJack F Vogel ctrl |= E1000_CTRL_FD;
14308cfa0ad2SJack F Vogel
1431ab5d0362SJack F Vogel hw->mac.ops.config_collision_dist(hw);
14328cfa0ad2SJack F Vogel
14338cfa0ad2SJack F Vogel /*
14348cfa0ad2SJack F Vogel * Set up speed in the Device Control register depending on
14358cfa0ad2SJack F Vogel * negotiated values.
14368cfa0ad2SJack F Vogel */
14378cfa0ad2SJack F Vogel if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
14388cfa0ad2SJack F Vogel ctrl |= E1000_CTRL_SPD_1000;
14398cfa0ad2SJack F Vogel else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
14408cfa0ad2SJack F Vogel ctrl |= E1000_CTRL_SPD_100;
14418cfa0ad2SJack F Vogel
14428cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
14438cfa0ad2SJack F Vogel
14448cfa0ad2SJack F Vogel out:
14458cfa0ad2SJack F Vogel return ret_val;
14468cfa0ad2SJack F Vogel }
14478cfa0ad2SJack F Vogel
14488cfa0ad2SJack F Vogel /**
14498cfa0ad2SJack F Vogel * e1000_write_vfta_82543 - Write value to VLAN filter table
14508cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
14518cfa0ad2SJack F Vogel * @offset: the 32-bit offset in which to write the value to.
14528cfa0ad2SJack F Vogel * @value: the 32-bit value to write at location offset.
14538cfa0ad2SJack F Vogel *
14548cfa0ad2SJack F Vogel * This writes a 32-bit value to a 32-bit offset in the VLAN filter
14558cfa0ad2SJack F Vogel * table.
14568cfa0ad2SJack F Vogel **/
e1000_write_vfta_82543(struct e1000_hw * hw,u32 offset,u32 value)14578cfa0ad2SJack F Vogel static void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, u32 value)
14588cfa0ad2SJack F Vogel {
14598cfa0ad2SJack F Vogel u32 temp;
14608cfa0ad2SJack F Vogel
14618cfa0ad2SJack F Vogel DEBUGFUNC("e1000_write_vfta_82543");
14628cfa0ad2SJack F Vogel
14638cfa0ad2SJack F Vogel if ((hw->mac.type == e1000_82544) && (offset & 1)) {
14648cfa0ad2SJack F Vogel temp = E1000_READ_REG_ARRAY(hw, E1000_VFTA, offset - 1);
14658cfa0ad2SJack F Vogel E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
14668cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw);
14678cfa0ad2SJack F Vogel E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset - 1, temp);
14688cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw);
14698cfa0ad2SJack F Vogel } else {
14708cfa0ad2SJack F Vogel e1000_write_vfta_generic(hw, offset, value);
14718cfa0ad2SJack F Vogel }
14728cfa0ad2SJack F Vogel }
14738cfa0ad2SJack F Vogel
14748cfa0ad2SJack F Vogel /**
14758cfa0ad2SJack F Vogel * e1000_led_on_82543 - Turn on SW controllable LED
14768cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
14778cfa0ad2SJack F Vogel *
1478daf9197cSJack F Vogel * Turns the SW defined LED on.
14798cfa0ad2SJack F Vogel **/
e1000_led_on_82543(struct e1000_hw * hw)14808cfa0ad2SJack F Vogel static s32 e1000_led_on_82543(struct e1000_hw *hw)
14818cfa0ad2SJack F Vogel {
14828cfa0ad2SJack F Vogel u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
14838cfa0ad2SJack F Vogel
14848cfa0ad2SJack F Vogel DEBUGFUNC("e1000_led_on_82543");
14858cfa0ad2SJack F Vogel
14868cfa0ad2SJack F Vogel if (hw->mac.type == e1000_82544 &&
14878cfa0ad2SJack F Vogel hw->phy.media_type == e1000_media_type_copper) {
14888cfa0ad2SJack F Vogel /* Clear SW-definable Pin 0 to turn on the LED */
14898cfa0ad2SJack F Vogel ctrl &= ~E1000_CTRL_SWDPIN0;
14908cfa0ad2SJack F Vogel ctrl |= E1000_CTRL_SWDPIO0;
14918cfa0ad2SJack F Vogel } else {
14928cfa0ad2SJack F Vogel /* Fiber 82544 and all 82543 use this method */
14938cfa0ad2SJack F Vogel ctrl |= E1000_CTRL_SWDPIN0;
14948cfa0ad2SJack F Vogel ctrl |= E1000_CTRL_SWDPIO0;
14958cfa0ad2SJack F Vogel }
14968cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
14978cfa0ad2SJack F Vogel
14988cfa0ad2SJack F Vogel return E1000_SUCCESS;
14998cfa0ad2SJack F Vogel }
15008cfa0ad2SJack F Vogel
15018cfa0ad2SJack F Vogel /**
15028cfa0ad2SJack F Vogel * e1000_led_off_82543 - Turn off SW controllable LED
15038cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
15048cfa0ad2SJack F Vogel *
1505daf9197cSJack F Vogel * Turns the SW defined LED off.
15068cfa0ad2SJack F Vogel **/
e1000_led_off_82543(struct e1000_hw * hw)15078cfa0ad2SJack F Vogel static s32 e1000_led_off_82543(struct e1000_hw *hw)
15088cfa0ad2SJack F Vogel {
15098cfa0ad2SJack F Vogel u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
15108cfa0ad2SJack F Vogel
15118cfa0ad2SJack F Vogel DEBUGFUNC("e1000_led_off_82543");
15128cfa0ad2SJack F Vogel
15138cfa0ad2SJack F Vogel if (hw->mac.type == e1000_82544 &&
15148cfa0ad2SJack F Vogel hw->phy.media_type == e1000_media_type_copper) {
15158cfa0ad2SJack F Vogel /* Set SW-definable Pin 0 to turn off the LED */
15168cfa0ad2SJack F Vogel ctrl |= E1000_CTRL_SWDPIN0;
15178cfa0ad2SJack F Vogel ctrl |= E1000_CTRL_SWDPIO0;
15188cfa0ad2SJack F Vogel } else {
15198cfa0ad2SJack F Vogel ctrl &= ~E1000_CTRL_SWDPIN0;
15208cfa0ad2SJack F Vogel ctrl |= E1000_CTRL_SWDPIO0;
15218cfa0ad2SJack F Vogel }
15228cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
15238cfa0ad2SJack F Vogel
15248cfa0ad2SJack F Vogel return E1000_SUCCESS;
15258cfa0ad2SJack F Vogel }
15268cfa0ad2SJack F Vogel
15278cfa0ad2SJack F Vogel /**
15288cfa0ad2SJack F Vogel * e1000_clear_hw_cntrs_82543 - Clear device specific hardware counters
15298cfa0ad2SJack F Vogel * @hw: pointer to the HW structure
15308cfa0ad2SJack F Vogel *
15318cfa0ad2SJack F Vogel * Clears the hardware counters by reading the counter registers.
15328cfa0ad2SJack F Vogel **/
e1000_clear_hw_cntrs_82543(struct e1000_hw * hw)15338cfa0ad2SJack F Vogel static void e1000_clear_hw_cntrs_82543(struct e1000_hw *hw)
15348cfa0ad2SJack F Vogel {
15358cfa0ad2SJack F Vogel DEBUGFUNC("e1000_clear_hw_cntrs_82543");
15368cfa0ad2SJack F Vogel
15378cfa0ad2SJack F Vogel e1000_clear_hw_cntrs_base_generic(hw);
15388cfa0ad2SJack F Vogel
1539daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC64);
1540daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC127);
1541daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC255);
1542daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC511);
1543daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC1023);
1544daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PRC1522);
1545daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC64);
1546daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC127);
1547daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC255);
1548daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC511);
1549daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC1023);
1550daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_PTC1522);
15518cfa0ad2SJack F Vogel
1552daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_ALGNERRC);
1553daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_RXERRC);
1554daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_TNCRS);
1555daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_CEXTERR);
1556daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_TSCTC);
1557daf9197cSJack F Vogel E1000_READ_REG(hw, E1000_TSCTFC);
15588cfa0ad2SJack F Vogel }
155974dbc418SJack F Vogel
156074dbc418SJack F Vogel /**
156174dbc418SJack F Vogel * e1000_read_mac_addr_82543 - Read device MAC address
156274dbc418SJack F Vogel * @hw: pointer to the HW structure
156374dbc418SJack F Vogel *
156474dbc418SJack F Vogel * Reads the device MAC address from the EEPROM and stores the value.
156574dbc418SJack F Vogel * Since devices with two ports use the same EEPROM, we increment the
156674dbc418SJack F Vogel * last bit in the MAC address for the second port.
156774dbc418SJack F Vogel *
156874dbc418SJack F Vogel **/
e1000_read_mac_addr_82543(struct e1000_hw * hw)156974dbc418SJack F Vogel s32 e1000_read_mac_addr_82543(struct e1000_hw *hw)
157074dbc418SJack F Vogel {
157174dbc418SJack F Vogel s32 ret_val = E1000_SUCCESS;
157274dbc418SJack F Vogel u16 offset, nvm_data, i;
157374dbc418SJack F Vogel
157474dbc418SJack F Vogel DEBUGFUNC("e1000_read_mac_addr");
157574dbc418SJack F Vogel
1576e81998f4SEric Joyner for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
157774dbc418SJack F Vogel offset = i >> 1;
157874dbc418SJack F Vogel ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
157974dbc418SJack F Vogel if (ret_val) {
158074dbc418SJack F Vogel DEBUGOUT("NVM Read Error\n");
158174dbc418SJack F Vogel goto out;
158274dbc418SJack F Vogel }
158374dbc418SJack F Vogel hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
158474dbc418SJack F Vogel hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
158574dbc418SJack F Vogel }
158674dbc418SJack F Vogel
158774dbc418SJack F Vogel /* Flip last bit of mac address if we're on second port */
158874dbc418SJack F Vogel if (hw->bus.func == E1000_FUNC_1)
158974dbc418SJack F Vogel hw->mac.perm_addr[5] ^= 1;
159074dbc418SJack F Vogel
1591e81998f4SEric Joyner for (i = 0; i < ETHER_ADDR_LEN; i++)
159274dbc418SJack F Vogel hw->mac.addr[i] = hw->mac.perm_addr[i];
159374dbc418SJack F Vogel
159474dbc418SJack F Vogel out:
159574dbc418SJack F Vogel return ret_val;
159674dbc418SJack F Vogel }
1597