18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright(c) 1999 - 2018 Intel Corporation. */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci/* 82571EB Gigabit Ethernet Controller 58c2ecf20Sopenharmony_ci * 82571EB Gigabit Ethernet Controller (Copper) 68c2ecf20Sopenharmony_ci * 82571EB Gigabit Ethernet Controller (Fiber) 78c2ecf20Sopenharmony_ci * 82571EB Dual Port Gigabit Mezzanine Adapter 88c2ecf20Sopenharmony_ci * 82571EB Quad Port Gigabit Mezzanine Adapter 98c2ecf20Sopenharmony_ci * 82571PT Gigabit PT Quad Port Server ExpressModule 108c2ecf20Sopenharmony_ci * 82572EI Gigabit Ethernet Controller (Copper) 118c2ecf20Sopenharmony_ci * 82572EI Gigabit Ethernet Controller (Fiber) 128c2ecf20Sopenharmony_ci * 82572EI Gigabit Ethernet Controller 138c2ecf20Sopenharmony_ci * 82573V Gigabit Ethernet Controller (Copper) 148c2ecf20Sopenharmony_ci * 82573E Gigabit Ethernet Controller (Copper) 158c2ecf20Sopenharmony_ci * 82573L Gigabit Ethernet Controller 168c2ecf20Sopenharmony_ci * 82574L Gigabit Network Connection 178c2ecf20Sopenharmony_ci * 82583V Gigabit Network Connection 188c2ecf20Sopenharmony_ci */ 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#include "e1000.h" 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic s32 e1000_get_phy_id_82571(struct e1000_hw *hw); 238c2ecf20Sopenharmony_cistatic s32 e1000_setup_copper_link_82571(struct e1000_hw *hw); 248c2ecf20Sopenharmony_cistatic s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw); 258c2ecf20Sopenharmony_cistatic s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw); 268c2ecf20Sopenharmony_cistatic s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, 278c2ecf20Sopenharmony_ci u16 words, u16 *data); 288c2ecf20Sopenharmony_cistatic s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw); 298c2ecf20Sopenharmony_cistatic void e1000_initialize_hw_bits_82571(struct e1000_hw *hw); 308c2ecf20Sopenharmony_cistatic void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw); 318c2ecf20Sopenharmony_cistatic bool e1000_check_mng_mode_82574(struct e1000_hw *hw); 328c2ecf20Sopenharmony_cistatic s32 e1000_led_on_82574(struct e1000_hw *hw); 338c2ecf20Sopenharmony_cistatic void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); 348c2ecf20Sopenharmony_cistatic void e1000_power_down_phy_copper_82571(struct e1000_hw *hw); 358c2ecf20Sopenharmony_cistatic void e1000_put_hw_semaphore_82573(struct e1000_hw *hw); 368c2ecf20Sopenharmony_cistatic s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw); 378c2ecf20Sopenharmony_cistatic void e1000_put_hw_semaphore_82574(struct e1000_hw *hw); 388c2ecf20Sopenharmony_cistatic s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw, bool active); 398c2ecf20Sopenharmony_cistatic s32 e1000_set_d3_lplu_state_82574(struct e1000_hw *hw, bool active); 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci/** 428c2ecf20Sopenharmony_ci * e1000_init_phy_params_82571 - Init PHY func ptrs. 438c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 448c2ecf20Sopenharmony_ci **/ 458c2ecf20Sopenharmony_cistatic s32 e1000_init_phy_params_82571(struct e1000_hw *hw) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci struct e1000_phy_info *phy = &hw->phy; 488c2ecf20Sopenharmony_ci s32 ret_val; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci if (hw->phy.media_type != e1000_media_type_copper) { 518c2ecf20Sopenharmony_ci phy->type = e1000_phy_none; 528c2ecf20Sopenharmony_ci return 0; 538c2ecf20Sopenharmony_ci } 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci phy->addr = 1; 568c2ecf20Sopenharmony_ci phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; 578c2ecf20Sopenharmony_ci phy->reset_delay_us = 100; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci phy->ops.power_up = e1000_power_up_phy_copper; 608c2ecf20Sopenharmony_ci phy->ops.power_down = e1000_power_down_phy_copper_82571; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci switch (hw->mac.type) { 638c2ecf20Sopenharmony_ci case e1000_82571: 648c2ecf20Sopenharmony_ci case e1000_82572: 658c2ecf20Sopenharmony_ci phy->type = e1000_phy_igp_2; 668c2ecf20Sopenharmony_ci break; 678c2ecf20Sopenharmony_ci case e1000_82573: 688c2ecf20Sopenharmony_ci phy->type = e1000_phy_m88; 698c2ecf20Sopenharmony_ci break; 708c2ecf20Sopenharmony_ci case e1000_82574: 718c2ecf20Sopenharmony_ci case e1000_82583: 728c2ecf20Sopenharmony_ci phy->type = e1000_phy_bm; 738c2ecf20Sopenharmony_ci phy->ops.acquire = e1000_get_hw_semaphore_82574; 748c2ecf20Sopenharmony_ci phy->ops.release = e1000_put_hw_semaphore_82574; 758c2ecf20Sopenharmony_ci phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82574; 768c2ecf20Sopenharmony_ci phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82574; 778c2ecf20Sopenharmony_ci break; 788c2ecf20Sopenharmony_ci default: 798c2ecf20Sopenharmony_ci return -E1000_ERR_PHY; 808c2ecf20Sopenharmony_ci } 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci /* This can only be done after all function pointers are setup. */ 838c2ecf20Sopenharmony_ci ret_val = e1000_get_phy_id_82571(hw); 848c2ecf20Sopenharmony_ci if (ret_val) { 858c2ecf20Sopenharmony_ci e_dbg("Error getting PHY ID\n"); 868c2ecf20Sopenharmony_ci return ret_val; 878c2ecf20Sopenharmony_ci } 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci /* Verify phy id */ 908c2ecf20Sopenharmony_ci switch (hw->mac.type) { 918c2ecf20Sopenharmony_ci case e1000_82571: 928c2ecf20Sopenharmony_ci case e1000_82572: 938c2ecf20Sopenharmony_ci if (phy->id != IGP01E1000_I_PHY_ID) 948c2ecf20Sopenharmony_ci ret_val = -E1000_ERR_PHY; 958c2ecf20Sopenharmony_ci break; 968c2ecf20Sopenharmony_ci case e1000_82573: 978c2ecf20Sopenharmony_ci if (phy->id != M88E1111_I_PHY_ID) 988c2ecf20Sopenharmony_ci ret_val = -E1000_ERR_PHY; 998c2ecf20Sopenharmony_ci break; 1008c2ecf20Sopenharmony_ci case e1000_82574: 1018c2ecf20Sopenharmony_ci case e1000_82583: 1028c2ecf20Sopenharmony_ci if (phy->id != BME1000_E_PHY_ID_R2) 1038c2ecf20Sopenharmony_ci ret_val = -E1000_ERR_PHY; 1048c2ecf20Sopenharmony_ci break; 1058c2ecf20Sopenharmony_ci default: 1068c2ecf20Sopenharmony_ci ret_val = -E1000_ERR_PHY; 1078c2ecf20Sopenharmony_ci break; 1088c2ecf20Sopenharmony_ci } 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci if (ret_val) 1118c2ecf20Sopenharmony_ci e_dbg("PHY ID unknown: type = 0x%08x\n", phy->id); 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci return ret_val; 1148c2ecf20Sopenharmony_ci} 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci/** 1178c2ecf20Sopenharmony_ci * e1000_init_nvm_params_82571 - Init NVM func ptrs. 1188c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 1198c2ecf20Sopenharmony_ci **/ 1208c2ecf20Sopenharmony_cistatic s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) 1218c2ecf20Sopenharmony_ci{ 1228c2ecf20Sopenharmony_ci struct e1000_nvm_info *nvm = &hw->nvm; 1238c2ecf20Sopenharmony_ci u32 eecd = er32(EECD); 1248c2ecf20Sopenharmony_ci u16 size; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci nvm->opcode_bits = 8; 1278c2ecf20Sopenharmony_ci nvm->delay_usec = 1; 1288c2ecf20Sopenharmony_ci switch (nvm->override) { 1298c2ecf20Sopenharmony_ci case e1000_nvm_override_spi_large: 1308c2ecf20Sopenharmony_ci nvm->page_size = 32; 1318c2ecf20Sopenharmony_ci nvm->address_bits = 16; 1328c2ecf20Sopenharmony_ci break; 1338c2ecf20Sopenharmony_ci case e1000_nvm_override_spi_small: 1348c2ecf20Sopenharmony_ci nvm->page_size = 8; 1358c2ecf20Sopenharmony_ci nvm->address_bits = 8; 1368c2ecf20Sopenharmony_ci break; 1378c2ecf20Sopenharmony_ci default: 1388c2ecf20Sopenharmony_ci nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; 1398c2ecf20Sopenharmony_ci nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8; 1408c2ecf20Sopenharmony_ci break; 1418c2ecf20Sopenharmony_ci } 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci switch (hw->mac.type) { 1448c2ecf20Sopenharmony_ci case e1000_82573: 1458c2ecf20Sopenharmony_ci case e1000_82574: 1468c2ecf20Sopenharmony_ci case e1000_82583: 1478c2ecf20Sopenharmony_ci if (((eecd >> 15) & 0x3) == 0x3) { 1488c2ecf20Sopenharmony_ci nvm->type = e1000_nvm_flash_hw; 1498c2ecf20Sopenharmony_ci nvm->word_size = 2048; 1508c2ecf20Sopenharmony_ci /* Autonomous Flash update bit must be cleared due 1518c2ecf20Sopenharmony_ci * to Flash update issue. 1528c2ecf20Sopenharmony_ci */ 1538c2ecf20Sopenharmony_ci eecd &= ~E1000_EECD_AUPDEN; 1548c2ecf20Sopenharmony_ci ew32(EECD, eecd); 1558c2ecf20Sopenharmony_ci break; 1568c2ecf20Sopenharmony_ci } 1578c2ecf20Sopenharmony_ci fallthrough; 1588c2ecf20Sopenharmony_ci default: 1598c2ecf20Sopenharmony_ci nvm->type = e1000_nvm_eeprom_spi; 1608c2ecf20Sopenharmony_ci size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> 1618c2ecf20Sopenharmony_ci E1000_EECD_SIZE_EX_SHIFT); 1628c2ecf20Sopenharmony_ci /* Added to a constant, "size" becomes the left-shift value 1638c2ecf20Sopenharmony_ci * for setting word_size. 1648c2ecf20Sopenharmony_ci */ 1658c2ecf20Sopenharmony_ci size += NVM_WORD_SIZE_BASE_SHIFT; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci /* EEPROM access above 16k is unsupported */ 1688c2ecf20Sopenharmony_ci if (size > 14) 1698c2ecf20Sopenharmony_ci size = 14; 1708c2ecf20Sopenharmony_ci nvm->word_size = BIT(size); 1718c2ecf20Sopenharmony_ci break; 1728c2ecf20Sopenharmony_ci } 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci /* Function Pointers */ 1758c2ecf20Sopenharmony_ci switch (hw->mac.type) { 1768c2ecf20Sopenharmony_ci case e1000_82574: 1778c2ecf20Sopenharmony_ci case e1000_82583: 1788c2ecf20Sopenharmony_ci nvm->ops.acquire = e1000_get_hw_semaphore_82574; 1798c2ecf20Sopenharmony_ci nvm->ops.release = e1000_put_hw_semaphore_82574; 1808c2ecf20Sopenharmony_ci break; 1818c2ecf20Sopenharmony_ci default: 1828c2ecf20Sopenharmony_ci break; 1838c2ecf20Sopenharmony_ci } 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci return 0; 1868c2ecf20Sopenharmony_ci} 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci/** 1898c2ecf20Sopenharmony_ci * e1000_init_mac_params_82571 - Init MAC func ptrs. 1908c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 1918c2ecf20Sopenharmony_ci **/ 1928c2ecf20Sopenharmony_cistatic s32 e1000_init_mac_params_82571(struct e1000_hw *hw) 1938c2ecf20Sopenharmony_ci{ 1948c2ecf20Sopenharmony_ci struct e1000_mac_info *mac = &hw->mac; 1958c2ecf20Sopenharmony_ci u32 swsm = 0; 1968c2ecf20Sopenharmony_ci u32 swsm2 = 0; 1978c2ecf20Sopenharmony_ci bool force_clear_smbi = false; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci /* Set media type and media-dependent function pointers */ 2008c2ecf20Sopenharmony_ci switch (hw->adapter->pdev->device) { 2018c2ecf20Sopenharmony_ci case E1000_DEV_ID_82571EB_FIBER: 2028c2ecf20Sopenharmony_ci case E1000_DEV_ID_82572EI_FIBER: 2038c2ecf20Sopenharmony_ci case E1000_DEV_ID_82571EB_QUAD_FIBER: 2048c2ecf20Sopenharmony_ci hw->phy.media_type = e1000_media_type_fiber; 2058c2ecf20Sopenharmony_ci mac->ops.setup_physical_interface = 2068c2ecf20Sopenharmony_ci e1000_setup_fiber_serdes_link_82571; 2078c2ecf20Sopenharmony_ci mac->ops.check_for_link = e1000e_check_for_fiber_link; 2088c2ecf20Sopenharmony_ci mac->ops.get_link_up_info = 2098c2ecf20Sopenharmony_ci e1000e_get_speed_and_duplex_fiber_serdes; 2108c2ecf20Sopenharmony_ci break; 2118c2ecf20Sopenharmony_ci case E1000_DEV_ID_82571EB_SERDES: 2128c2ecf20Sopenharmony_ci case E1000_DEV_ID_82571EB_SERDES_DUAL: 2138c2ecf20Sopenharmony_ci case E1000_DEV_ID_82571EB_SERDES_QUAD: 2148c2ecf20Sopenharmony_ci case E1000_DEV_ID_82572EI_SERDES: 2158c2ecf20Sopenharmony_ci hw->phy.media_type = e1000_media_type_internal_serdes; 2168c2ecf20Sopenharmony_ci mac->ops.setup_physical_interface = 2178c2ecf20Sopenharmony_ci e1000_setup_fiber_serdes_link_82571; 2188c2ecf20Sopenharmony_ci mac->ops.check_for_link = e1000_check_for_serdes_link_82571; 2198c2ecf20Sopenharmony_ci mac->ops.get_link_up_info = 2208c2ecf20Sopenharmony_ci e1000e_get_speed_and_duplex_fiber_serdes; 2218c2ecf20Sopenharmony_ci break; 2228c2ecf20Sopenharmony_ci default: 2238c2ecf20Sopenharmony_ci hw->phy.media_type = e1000_media_type_copper; 2248c2ecf20Sopenharmony_ci mac->ops.setup_physical_interface = 2258c2ecf20Sopenharmony_ci e1000_setup_copper_link_82571; 2268c2ecf20Sopenharmony_ci mac->ops.check_for_link = e1000e_check_for_copper_link; 2278c2ecf20Sopenharmony_ci mac->ops.get_link_up_info = e1000e_get_speed_and_duplex_copper; 2288c2ecf20Sopenharmony_ci break; 2298c2ecf20Sopenharmony_ci } 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci /* Set mta register count */ 2328c2ecf20Sopenharmony_ci mac->mta_reg_count = 128; 2338c2ecf20Sopenharmony_ci /* Set rar entry count */ 2348c2ecf20Sopenharmony_ci mac->rar_entry_count = E1000_RAR_ENTRIES; 2358c2ecf20Sopenharmony_ci /* Adaptive IFS supported */ 2368c2ecf20Sopenharmony_ci mac->adaptive_ifs = true; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci /* MAC-specific function pointers */ 2398c2ecf20Sopenharmony_ci switch (hw->mac.type) { 2408c2ecf20Sopenharmony_ci case e1000_82573: 2418c2ecf20Sopenharmony_ci mac->ops.set_lan_id = e1000_set_lan_id_single_port; 2428c2ecf20Sopenharmony_ci mac->ops.check_mng_mode = e1000e_check_mng_mode_generic; 2438c2ecf20Sopenharmony_ci mac->ops.led_on = e1000e_led_on_generic; 2448c2ecf20Sopenharmony_ci mac->ops.blink_led = e1000e_blink_led_generic; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci /* FWSM register */ 2478c2ecf20Sopenharmony_ci mac->has_fwsm = true; 2488c2ecf20Sopenharmony_ci /* ARC supported; valid only if manageability features are 2498c2ecf20Sopenharmony_ci * enabled. 2508c2ecf20Sopenharmony_ci */ 2518c2ecf20Sopenharmony_ci mac->arc_subsystem_valid = !!(er32(FWSM) & 2528c2ecf20Sopenharmony_ci E1000_FWSM_MODE_MASK); 2538c2ecf20Sopenharmony_ci break; 2548c2ecf20Sopenharmony_ci case e1000_82574: 2558c2ecf20Sopenharmony_ci case e1000_82583: 2568c2ecf20Sopenharmony_ci mac->ops.set_lan_id = e1000_set_lan_id_single_port; 2578c2ecf20Sopenharmony_ci mac->ops.check_mng_mode = e1000_check_mng_mode_82574; 2588c2ecf20Sopenharmony_ci mac->ops.led_on = e1000_led_on_82574; 2598c2ecf20Sopenharmony_ci break; 2608c2ecf20Sopenharmony_ci default: 2618c2ecf20Sopenharmony_ci mac->ops.check_mng_mode = e1000e_check_mng_mode_generic; 2628c2ecf20Sopenharmony_ci mac->ops.led_on = e1000e_led_on_generic; 2638c2ecf20Sopenharmony_ci mac->ops.blink_led = e1000e_blink_led_generic; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci /* FWSM register */ 2668c2ecf20Sopenharmony_ci mac->has_fwsm = true; 2678c2ecf20Sopenharmony_ci break; 2688c2ecf20Sopenharmony_ci } 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci /* Ensure that the inter-port SWSM.SMBI lock bit is clear before 2718c2ecf20Sopenharmony_ci * first NVM or PHY access. This should be done for single-port 2728c2ecf20Sopenharmony_ci * devices, and for one port only on dual-port devices so that 2738c2ecf20Sopenharmony_ci * for those devices we can still use the SMBI lock to synchronize 2748c2ecf20Sopenharmony_ci * inter-port accesses to the PHY & NVM. 2758c2ecf20Sopenharmony_ci */ 2768c2ecf20Sopenharmony_ci switch (hw->mac.type) { 2778c2ecf20Sopenharmony_ci case e1000_82571: 2788c2ecf20Sopenharmony_ci case e1000_82572: 2798c2ecf20Sopenharmony_ci swsm2 = er32(SWSM2); 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci if (!(swsm2 & E1000_SWSM2_LOCK)) { 2828c2ecf20Sopenharmony_ci /* Only do this for the first interface on this card */ 2838c2ecf20Sopenharmony_ci ew32(SWSM2, swsm2 | E1000_SWSM2_LOCK); 2848c2ecf20Sopenharmony_ci force_clear_smbi = true; 2858c2ecf20Sopenharmony_ci } else { 2868c2ecf20Sopenharmony_ci force_clear_smbi = false; 2878c2ecf20Sopenharmony_ci } 2888c2ecf20Sopenharmony_ci break; 2898c2ecf20Sopenharmony_ci default: 2908c2ecf20Sopenharmony_ci force_clear_smbi = true; 2918c2ecf20Sopenharmony_ci break; 2928c2ecf20Sopenharmony_ci } 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci if (force_clear_smbi) { 2958c2ecf20Sopenharmony_ci /* Make sure SWSM.SMBI is clear */ 2968c2ecf20Sopenharmony_ci swsm = er32(SWSM); 2978c2ecf20Sopenharmony_ci if (swsm & E1000_SWSM_SMBI) { 2988c2ecf20Sopenharmony_ci /* This bit should not be set on a first interface, and 2998c2ecf20Sopenharmony_ci * indicates that the bootagent or EFI code has 3008c2ecf20Sopenharmony_ci * improperly left this bit enabled 3018c2ecf20Sopenharmony_ci */ 3028c2ecf20Sopenharmony_ci e_dbg("Please update your 82571 Bootagent\n"); 3038c2ecf20Sopenharmony_ci } 3048c2ecf20Sopenharmony_ci ew32(SWSM, swsm & ~E1000_SWSM_SMBI); 3058c2ecf20Sopenharmony_ci } 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci /* Initialize device specific counter of SMBI acquisition timeouts. */ 3088c2ecf20Sopenharmony_ci hw->dev_spec.e82571.smb_counter = 0; 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci return 0; 3118c2ecf20Sopenharmony_ci} 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_cistatic s32 e1000_get_variants_82571(struct e1000_adapter *adapter) 3148c2ecf20Sopenharmony_ci{ 3158c2ecf20Sopenharmony_ci struct e1000_hw *hw = &adapter->hw; 3168c2ecf20Sopenharmony_ci static int global_quad_port_a; /* global port a indication */ 3178c2ecf20Sopenharmony_ci struct pci_dev *pdev = adapter->pdev; 3188c2ecf20Sopenharmony_ci int is_port_b = er32(STATUS) & E1000_STATUS_FUNC_1; 3198c2ecf20Sopenharmony_ci s32 rc; 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci rc = e1000_init_mac_params_82571(hw); 3228c2ecf20Sopenharmony_ci if (rc) 3238c2ecf20Sopenharmony_ci return rc; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci rc = e1000_init_nvm_params_82571(hw); 3268c2ecf20Sopenharmony_ci if (rc) 3278c2ecf20Sopenharmony_ci return rc; 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci rc = e1000_init_phy_params_82571(hw); 3308c2ecf20Sopenharmony_ci if (rc) 3318c2ecf20Sopenharmony_ci return rc; 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci /* tag quad port adapters first, it's used below */ 3348c2ecf20Sopenharmony_ci switch (pdev->device) { 3358c2ecf20Sopenharmony_ci case E1000_DEV_ID_82571EB_QUAD_COPPER: 3368c2ecf20Sopenharmony_ci case E1000_DEV_ID_82571EB_QUAD_FIBER: 3378c2ecf20Sopenharmony_ci case E1000_DEV_ID_82571EB_QUAD_COPPER_LP: 3388c2ecf20Sopenharmony_ci case E1000_DEV_ID_82571PT_QUAD_COPPER: 3398c2ecf20Sopenharmony_ci adapter->flags |= FLAG_IS_QUAD_PORT; 3408c2ecf20Sopenharmony_ci /* mark the first port */ 3418c2ecf20Sopenharmony_ci if (global_quad_port_a == 0) 3428c2ecf20Sopenharmony_ci adapter->flags |= FLAG_IS_QUAD_PORT_A; 3438c2ecf20Sopenharmony_ci /* Reset for multiple quad port adapters */ 3448c2ecf20Sopenharmony_ci global_quad_port_a++; 3458c2ecf20Sopenharmony_ci if (global_quad_port_a == 4) 3468c2ecf20Sopenharmony_ci global_quad_port_a = 0; 3478c2ecf20Sopenharmony_ci break; 3488c2ecf20Sopenharmony_ci default: 3498c2ecf20Sopenharmony_ci break; 3508c2ecf20Sopenharmony_ci } 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci switch (adapter->hw.mac.type) { 3538c2ecf20Sopenharmony_ci case e1000_82571: 3548c2ecf20Sopenharmony_ci /* these dual ports don't have WoL on port B at all */ 3558c2ecf20Sopenharmony_ci if (((pdev->device == E1000_DEV_ID_82571EB_FIBER) || 3568c2ecf20Sopenharmony_ci (pdev->device == E1000_DEV_ID_82571EB_SERDES) || 3578c2ecf20Sopenharmony_ci (pdev->device == E1000_DEV_ID_82571EB_COPPER)) && 3588c2ecf20Sopenharmony_ci (is_port_b)) 3598c2ecf20Sopenharmony_ci adapter->flags &= ~FLAG_HAS_WOL; 3608c2ecf20Sopenharmony_ci /* quad ports only support WoL on port A */ 3618c2ecf20Sopenharmony_ci if (adapter->flags & FLAG_IS_QUAD_PORT && 3628c2ecf20Sopenharmony_ci (!(adapter->flags & FLAG_IS_QUAD_PORT_A))) 3638c2ecf20Sopenharmony_ci adapter->flags &= ~FLAG_HAS_WOL; 3648c2ecf20Sopenharmony_ci /* Does not support WoL on any port */ 3658c2ecf20Sopenharmony_ci if (pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD) 3668c2ecf20Sopenharmony_ci adapter->flags &= ~FLAG_HAS_WOL; 3678c2ecf20Sopenharmony_ci break; 3688c2ecf20Sopenharmony_ci case e1000_82573: 3698c2ecf20Sopenharmony_ci if (pdev->device == E1000_DEV_ID_82573L) { 3708c2ecf20Sopenharmony_ci adapter->flags |= FLAG_HAS_JUMBO_FRAMES; 3718c2ecf20Sopenharmony_ci adapter->max_hw_frame_size = DEFAULT_JUMBO; 3728c2ecf20Sopenharmony_ci } 3738c2ecf20Sopenharmony_ci break; 3748c2ecf20Sopenharmony_ci default: 3758c2ecf20Sopenharmony_ci break; 3768c2ecf20Sopenharmony_ci } 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci return 0; 3798c2ecf20Sopenharmony_ci} 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci/** 3828c2ecf20Sopenharmony_ci * e1000_get_phy_id_82571 - Retrieve the PHY ID and revision 3838c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 3848c2ecf20Sopenharmony_ci * 3858c2ecf20Sopenharmony_ci * Reads the PHY registers and stores the PHY ID and possibly the PHY 3868c2ecf20Sopenharmony_ci * revision in the hardware structure. 3878c2ecf20Sopenharmony_ci **/ 3888c2ecf20Sopenharmony_cistatic s32 e1000_get_phy_id_82571(struct e1000_hw *hw) 3898c2ecf20Sopenharmony_ci{ 3908c2ecf20Sopenharmony_ci struct e1000_phy_info *phy = &hw->phy; 3918c2ecf20Sopenharmony_ci s32 ret_val; 3928c2ecf20Sopenharmony_ci u16 phy_id = 0; 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ci switch (hw->mac.type) { 3958c2ecf20Sopenharmony_ci case e1000_82571: 3968c2ecf20Sopenharmony_ci case e1000_82572: 3978c2ecf20Sopenharmony_ci /* The 82571 firmware may still be configuring the PHY. 3988c2ecf20Sopenharmony_ci * In this case, we cannot access the PHY until the 3998c2ecf20Sopenharmony_ci * configuration is done. So we explicitly set the 4008c2ecf20Sopenharmony_ci * PHY ID. 4018c2ecf20Sopenharmony_ci */ 4028c2ecf20Sopenharmony_ci phy->id = IGP01E1000_I_PHY_ID; 4038c2ecf20Sopenharmony_ci break; 4048c2ecf20Sopenharmony_ci case e1000_82573: 4058c2ecf20Sopenharmony_ci return e1000e_get_phy_id(hw); 4068c2ecf20Sopenharmony_ci case e1000_82574: 4078c2ecf20Sopenharmony_ci case e1000_82583: 4088c2ecf20Sopenharmony_ci ret_val = e1e_rphy(hw, MII_PHYSID1, &phy_id); 4098c2ecf20Sopenharmony_ci if (ret_val) 4108c2ecf20Sopenharmony_ci return ret_val; 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci phy->id = (u32)(phy_id << 16); 4138c2ecf20Sopenharmony_ci usleep_range(20, 40); 4148c2ecf20Sopenharmony_ci ret_val = e1e_rphy(hw, MII_PHYSID2, &phy_id); 4158c2ecf20Sopenharmony_ci if (ret_val) 4168c2ecf20Sopenharmony_ci return ret_val; 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci phy->id |= (u32)(phy_id); 4198c2ecf20Sopenharmony_ci phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK); 4208c2ecf20Sopenharmony_ci break; 4218c2ecf20Sopenharmony_ci default: 4228c2ecf20Sopenharmony_ci return -E1000_ERR_PHY; 4238c2ecf20Sopenharmony_ci } 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci return 0; 4268c2ecf20Sopenharmony_ci} 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci/** 4298c2ecf20Sopenharmony_ci * e1000_get_hw_semaphore_82571 - Acquire hardware semaphore 4308c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 4318c2ecf20Sopenharmony_ci * 4328c2ecf20Sopenharmony_ci * Acquire the HW semaphore to access the PHY or NVM 4338c2ecf20Sopenharmony_ci **/ 4348c2ecf20Sopenharmony_cistatic s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) 4358c2ecf20Sopenharmony_ci{ 4368c2ecf20Sopenharmony_ci u32 swsm; 4378c2ecf20Sopenharmony_ci s32 sw_timeout = hw->nvm.word_size + 1; 4388c2ecf20Sopenharmony_ci s32 fw_timeout = hw->nvm.word_size + 1; 4398c2ecf20Sopenharmony_ci s32 i = 0; 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci /* If we have timedout 3 times on trying to acquire 4428c2ecf20Sopenharmony_ci * the inter-port SMBI semaphore, there is old code 4438c2ecf20Sopenharmony_ci * operating on the other port, and it is not 4448c2ecf20Sopenharmony_ci * releasing SMBI. Modify the number of times that 4458c2ecf20Sopenharmony_ci * we try for the semaphore to interwork with this 4468c2ecf20Sopenharmony_ci * older code. 4478c2ecf20Sopenharmony_ci */ 4488c2ecf20Sopenharmony_ci if (hw->dev_spec.e82571.smb_counter > 2) 4498c2ecf20Sopenharmony_ci sw_timeout = 1; 4508c2ecf20Sopenharmony_ci 4518c2ecf20Sopenharmony_ci /* Get the SW semaphore */ 4528c2ecf20Sopenharmony_ci while (i < sw_timeout) { 4538c2ecf20Sopenharmony_ci swsm = er32(SWSM); 4548c2ecf20Sopenharmony_ci if (!(swsm & E1000_SWSM_SMBI)) 4558c2ecf20Sopenharmony_ci break; 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_ci usleep_range(50, 100); 4588c2ecf20Sopenharmony_ci i++; 4598c2ecf20Sopenharmony_ci } 4608c2ecf20Sopenharmony_ci 4618c2ecf20Sopenharmony_ci if (i == sw_timeout) { 4628c2ecf20Sopenharmony_ci e_dbg("Driver can't access device - SMBI bit is set.\n"); 4638c2ecf20Sopenharmony_ci hw->dev_spec.e82571.smb_counter++; 4648c2ecf20Sopenharmony_ci } 4658c2ecf20Sopenharmony_ci /* Get the FW semaphore. */ 4668c2ecf20Sopenharmony_ci for (i = 0; i < fw_timeout; i++) { 4678c2ecf20Sopenharmony_ci swsm = er32(SWSM); 4688c2ecf20Sopenharmony_ci ew32(SWSM, swsm | E1000_SWSM_SWESMBI); 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci /* Semaphore acquired if bit latched */ 4718c2ecf20Sopenharmony_ci if (er32(SWSM) & E1000_SWSM_SWESMBI) 4728c2ecf20Sopenharmony_ci break; 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci usleep_range(50, 100); 4758c2ecf20Sopenharmony_ci } 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_ci if (i == fw_timeout) { 4788c2ecf20Sopenharmony_ci /* Release semaphores */ 4798c2ecf20Sopenharmony_ci e1000_put_hw_semaphore_82571(hw); 4808c2ecf20Sopenharmony_ci e_dbg("Driver can't access the NVM\n"); 4818c2ecf20Sopenharmony_ci return -E1000_ERR_NVM; 4828c2ecf20Sopenharmony_ci } 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci return 0; 4858c2ecf20Sopenharmony_ci} 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci/** 4888c2ecf20Sopenharmony_ci * e1000_put_hw_semaphore_82571 - Release hardware semaphore 4898c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 4908c2ecf20Sopenharmony_ci * 4918c2ecf20Sopenharmony_ci * Release hardware semaphore used to access the PHY or NVM 4928c2ecf20Sopenharmony_ci **/ 4938c2ecf20Sopenharmony_cistatic void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) 4948c2ecf20Sopenharmony_ci{ 4958c2ecf20Sopenharmony_ci u32 swsm; 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci swsm = er32(SWSM); 4988c2ecf20Sopenharmony_ci swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); 4998c2ecf20Sopenharmony_ci ew32(SWSM, swsm); 5008c2ecf20Sopenharmony_ci} 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_ci/** 5038c2ecf20Sopenharmony_ci * e1000_get_hw_semaphore_82573 - Acquire hardware semaphore 5048c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 5058c2ecf20Sopenharmony_ci * 5068c2ecf20Sopenharmony_ci * Acquire the HW semaphore during reset. 5078c2ecf20Sopenharmony_ci * 5088c2ecf20Sopenharmony_ci **/ 5098c2ecf20Sopenharmony_cistatic s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw) 5108c2ecf20Sopenharmony_ci{ 5118c2ecf20Sopenharmony_ci u32 extcnf_ctrl; 5128c2ecf20Sopenharmony_ci s32 i = 0; 5138c2ecf20Sopenharmony_ci 5148c2ecf20Sopenharmony_ci extcnf_ctrl = er32(EXTCNF_CTRL); 5158c2ecf20Sopenharmony_ci do { 5168c2ecf20Sopenharmony_ci extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; 5178c2ecf20Sopenharmony_ci ew32(EXTCNF_CTRL, extcnf_ctrl); 5188c2ecf20Sopenharmony_ci extcnf_ctrl = er32(EXTCNF_CTRL); 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_ci if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) 5218c2ecf20Sopenharmony_ci break; 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_ci usleep_range(2000, 4000); 5248c2ecf20Sopenharmony_ci i++; 5258c2ecf20Sopenharmony_ci } while (i < MDIO_OWNERSHIP_TIMEOUT); 5268c2ecf20Sopenharmony_ci 5278c2ecf20Sopenharmony_ci if (i == MDIO_OWNERSHIP_TIMEOUT) { 5288c2ecf20Sopenharmony_ci /* Release semaphores */ 5298c2ecf20Sopenharmony_ci e1000_put_hw_semaphore_82573(hw); 5308c2ecf20Sopenharmony_ci e_dbg("Driver can't access the PHY\n"); 5318c2ecf20Sopenharmony_ci return -E1000_ERR_PHY; 5328c2ecf20Sopenharmony_ci } 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ci return 0; 5358c2ecf20Sopenharmony_ci} 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci/** 5388c2ecf20Sopenharmony_ci * e1000_put_hw_semaphore_82573 - Release hardware semaphore 5398c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 5408c2ecf20Sopenharmony_ci * 5418c2ecf20Sopenharmony_ci * Release hardware semaphore used during reset. 5428c2ecf20Sopenharmony_ci * 5438c2ecf20Sopenharmony_ci **/ 5448c2ecf20Sopenharmony_cistatic void e1000_put_hw_semaphore_82573(struct e1000_hw *hw) 5458c2ecf20Sopenharmony_ci{ 5468c2ecf20Sopenharmony_ci u32 extcnf_ctrl; 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_ci extcnf_ctrl = er32(EXTCNF_CTRL); 5498c2ecf20Sopenharmony_ci extcnf_ctrl &= ~E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; 5508c2ecf20Sopenharmony_ci ew32(EXTCNF_CTRL, extcnf_ctrl); 5518c2ecf20Sopenharmony_ci} 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(swflag_mutex); 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_ci/** 5568c2ecf20Sopenharmony_ci * e1000_get_hw_semaphore_82574 - Acquire hardware semaphore 5578c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 5588c2ecf20Sopenharmony_ci * 5598c2ecf20Sopenharmony_ci * Acquire the HW semaphore to access the PHY or NVM. 5608c2ecf20Sopenharmony_ci * 5618c2ecf20Sopenharmony_ci **/ 5628c2ecf20Sopenharmony_cistatic s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw) 5638c2ecf20Sopenharmony_ci{ 5648c2ecf20Sopenharmony_ci s32 ret_val; 5658c2ecf20Sopenharmony_ci 5668c2ecf20Sopenharmony_ci mutex_lock(&swflag_mutex); 5678c2ecf20Sopenharmony_ci ret_val = e1000_get_hw_semaphore_82573(hw); 5688c2ecf20Sopenharmony_ci if (ret_val) 5698c2ecf20Sopenharmony_ci mutex_unlock(&swflag_mutex); 5708c2ecf20Sopenharmony_ci return ret_val; 5718c2ecf20Sopenharmony_ci} 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_ci/** 5748c2ecf20Sopenharmony_ci * e1000_put_hw_semaphore_82574 - Release hardware semaphore 5758c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 5768c2ecf20Sopenharmony_ci * 5778c2ecf20Sopenharmony_ci * Release hardware semaphore used to access the PHY or NVM 5788c2ecf20Sopenharmony_ci * 5798c2ecf20Sopenharmony_ci **/ 5808c2ecf20Sopenharmony_cistatic void e1000_put_hw_semaphore_82574(struct e1000_hw *hw) 5818c2ecf20Sopenharmony_ci{ 5828c2ecf20Sopenharmony_ci e1000_put_hw_semaphore_82573(hw); 5838c2ecf20Sopenharmony_ci mutex_unlock(&swflag_mutex); 5848c2ecf20Sopenharmony_ci} 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_ci/** 5878c2ecf20Sopenharmony_ci * e1000_set_d0_lplu_state_82574 - Set Low Power Linkup D0 state 5888c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 5898c2ecf20Sopenharmony_ci * @active: true to enable LPLU, false to disable 5908c2ecf20Sopenharmony_ci * 5918c2ecf20Sopenharmony_ci * Sets the LPLU D0 state according to the active flag. 5928c2ecf20Sopenharmony_ci * LPLU will not be activated unless the 5938c2ecf20Sopenharmony_ci * device autonegotiation advertisement meets standards of 5948c2ecf20Sopenharmony_ci * either 10 or 10/100 or 10/100/1000 at all duplexes. 5958c2ecf20Sopenharmony_ci * This is a function pointer entry point only called by 5968c2ecf20Sopenharmony_ci * PHY setup routines. 5978c2ecf20Sopenharmony_ci **/ 5988c2ecf20Sopenharmony_cistatic s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw, bool active) 5998c2ecf20Sopenharmony_ci{ 6008c2ecf20Sopenharmony_ci u32 data = er32(POEMB); 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_ci if (active) 6038c2ecf20Sopenharmony_ci data |= E1000_PHY_CTRL_D0A_LPLU; 6048c2ecf20Sopenharmony_ci else 6058c2ecf20Sopenharmony_ci data &= ~E1000_PHY_CTRL_D0A_LPLU; 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_ci ew32(POEMB, data); 6088c2ecf20Sopenharmony_ci return 0; 6098c2ecf20Sopenharmony_ci} 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_ci/** 6128c2ecf20Sopenharmony_ci * e1000_set_d3_lplu_state_82574 - Sets low power link up state for D3 6138c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 6148c2ecf20Sopenharmony_ci * @active: boolean used to enable/disable lplu 6158c2ecf20Sopenharmony_ci * 6168c2ecf20Sopenharmony_ci * The low power link up (lplu) state is set to the power management level D3 6178c2ecf20Sopenharmony_ci * when active is true, else clear lplu for D3. LPLU 6188c2ecf20Sopenharmony_ci * is used during Dx states where the power conservation is most important. 6198c2ecf20Sopenharmony_ci * During driver activity, SmartSpeed should be enabled so performance is 6208c2ecf20Sopenharmony_ci * maintained. 6218c2ecf20Sopenharmony_ci **/ 6228c2ecf20Sopenharmony_cistatic s32 e1000_set_d3_lplu_state_82574(struct e1000_hw *hw, bool active) 6238c2ecf20Sopenharmony_ci{ 6248c2ecf20Sopenharmony_ci u32 data = er32(POEMB); 6258c2ecf20Sopenharmony_ci 6268c2ecf20Sopenharmony_ci if (!active) { 6278c2ecf20Sopenharmony_ci data &= ~E1000_PHY_CTRL_NOND0A_LPLU; 6288c2ecf20Sopenharmony_ci } else if ((hw->phy.autoneg_advertised == E1000_ALL_SPEED_DUPLEX) || 6298c2ecf20Sopenharmony_ci (hw->phy.autoneg_advertised == E1000_ALL_NOT_GIG) || 6308c2ecf20Sopenharmony_ci (hw->phy.autoneg_advertised == E1000_ALL_10_SPEED)) { 6318c2ecf20Sopenharmony_ci data |= E1000_PHY_CTRL_NOND0A_LPLU; 6328c2ecf20Sopenharmony_ci } 6338c2ecf20Sopenharmony_ci 6348c2ecf20Sopenharmony_ci ew32(POEMB, data); 6358c2ecf20Sopenharmony_ci return 0; 6368c2ecf20Sopenharmony_ci} 6378c2ecf20Sopenharmony_ci 6388c2ecf20Sopenharmony_ci/** 6398c2ecf20Sopenharmony_ci * e1000_acquire_nvm_82571 - Request for access to the EEPROM 6408c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 6418c2ecf20Sopenharmony_ci * 6428c2ecf20Sopenharmony_ci * To gain access to the EEPROM, first we must obtain a hardware semaphore. 6438c2ecf20Sopenharmony_ci * Then for non-82573 hardware, set the EEPROM access request bit and wait 6448c2ecf20Sopenharmony_ci * for EEPROM access grant bit. If the access grant bit is not set, release 6458c2ecf20Sopenharmony_ci * hardware semaphore. 6468c2ecf20Sopenharmony_ci **/ 6478c2ecf20Sopenharmony_cistatic s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) 6488c2ecf20Sopenharmony_ci{ 6498c2ecf20Sopenharmony_ci s32 ret_val; 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_ci ret_val = e1000_get_hw_semaphore_82571(hw); 6528c2ecf20Sopenharmony_ci if (ret_val) 6538c2ecf20Sopenharmony_ci return ret_val; 6548c2ecf20Sopenharmony_ci 6558c2ecf20Sopenharmony_ci switch (hw->mac.type) { 6568c2ecf20Sopenharmony_ci case e1000_82573: 6578c2ecf20Sopenharmony_ci break; 6588c2ecf20Sopenharmony_ci default: 6598c2ecf20Sopenharmony_ci ret_val = e1000e_acquire_nvm(hw); 6608c2ecf20Sopenharmony_ci break; 6618c2ecf20Sopenharmony_ci } 6628c2ecf20Sopenharmony_ci 6638c2ecf20Sopenharmony_ci if (ret_val) 6648c2ecf20Sopenharmony_ci e1000_put_hw_semaphore_82571(hw); 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci return ret_val; 6678c2ecf20Sopenharmony_ci} 6688c2ecf20Sopenharmony_ci 6698c2ecf20Sopenharmony_ci/** 6708c2ecf20Sopenharmony_ci * e1000_release_nvm_82571 - Release exclusive access to EEPROM 6718c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 6728c2ecf20Sopenharmony_ci * 6738c2ecf20Sopenharmony_ci * Stop any current commands to the EEPROM and clear the EEPROM request bit. 6748c2ecf20Sopenharmony_ci **/ 6758c2ecf20Sopenharmony_cistatic void e1000_release_nvm_82571(struct e1000_hw *hw) 6768c2ecf20Sopenharmony_ci{ 6778c2ecf20Sopenharmony_ci e1000e_release_nvm(hw); 6788c2ecf20Sopenharmony_ci e1000_put_hw_semaphore_82571(hw); 6798c2ecf20Sopenharmony_ci} 6808c2ecf20Sopenharmony_ci 6818c2ecf20Sopenharmony_ci/** 6828c2ecf20Sopenharmony_ci * e1000_write_nvm_82571 - Write to EEPROM using appropriate interface 6838c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 6848c2ecf20Sopenharmony_ci * @offset: offset within the EEPROM to be written to 6858c2ecf20Sopenharmony_ci * @words: number of words to write 6868c2ecf20Sopenharmony_ci * @data: 16 bit word(s) to be written to the EEPROM 6878c2ecf20Sopenharmony_ci * 6888c2ecf20Sopenharmony_ci * For non-82573 silicon, write data to EEPROM at offset using SPI interface. 6898c2ecf20Sopenharmony_ci * 6908c2ecf20Sopenharmony_ci * If e1000e_update_nvm_checksum is not called after this function, the 6918c2ecf20Sopenharmony_ci * EEPROM will most likely contain an invalid checksum. 6928c2ecf20Sopenharmony_ci **/ 6938c2ecf20Sopenharmony_cistatic s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, 6948c2ecf20Sopenharmony_ci u16 *data) 6958c2ecf20Sopenharmony_ci{ 6968c2ecf20Sopenharmony_ci s32 ret_val; 6978c2ecf20Sopenharmony_ci 6988c2ecf20Sopenharmony_ci switch (hw->mac.type) { 6998c2ecf20Sopenharmony_ci case e1000_82573: 7008c2ecf20Sopenharmony_ci case e1000_82574: 7018c2ecf20Sopenharmony_ci case e1000_82583: 7028c2ecf20Sopenharmony_ci ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data); 7038c2ecf20Sopenharmony_ci break; 7048c2ecf20Sopenharmony_ci case e1000_82571: 7058c2ecf20Sopenharmony_ci case e1000_82572: 7068c2ecf20Sopenharmony_ci ret_val = e1000e_write_nvm_spi(hw, offset, words, data); 7078c2ecf20Sopenharmony_ci break; 7088c2ecf20Sopenharmony_ci default: 7098c2ecf20Sopenharmony_ci ret_val = -E1000_ERR_NVM; 7108c2ecf20Sopenharmony_ci break; 7118c2ecf20Sopenharmony_ci } 7128c2ecf20Sopenharmony_ci 7138c2ecf20Sopenharmony_ci return ret_val; 7148c2ecf20Sopenharmony_ci} 7158c2ecf20Sopenharmony_ci 7168c2ecf20Sopenharmony_ci/** 7178c2ecf20Sopenharmony_ci * e1000_update_nvm_checksum_82571 - Update EEPROM checksum 7188c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 7198c2ecf20Sopenharmony_ci * 7208c2ecf20Sopenharmony_ci * Updates the EEPROM checksum by reading/adding each word of the EEPROM 7218c2ecf20Sopenharmony_ci * up to the checksum. Then calculates the EEPROM checksum and writes the 7228c2ecf20Sopenharmony_ci * value to the EEPROM. 7238c2ecf20Sopenharmony_ci **/ 7248c2ecf20Sopenharmony_cistatic s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw) 7258c2ecf20Sopenharmony_ci{ 7268c2ecf20Sopenharmony_ci u32 eecd; 7278c2ecf20Sopenharmony_ci s32 ret_val; 7288c2ecf20Sopenharmony_ci u16 i; 7298c2ecf20Sopenharmony_ci 7308c2ecf20Sopenharmony_ci ret_val = e1000e_update_nvm_checksum_generic(hw); 7318c2ecf20Sopenharmony_ci if (ret_val) 7328c2ecf20Sopenharmony_ci return ret_val; 7338c2ecf20Sopenharmony_ci 7348c2ecf20Sopenharmony_ci /* If our nvm is an EEPROM, then we're done 7358c2ecf20Sopenharmony_ci * otherwise, commit the checksum to the flash NVM. 7368c2ecf20Sopenharmony_ci */ 7378c2ecf20Sopenharmony_ci if (hw->nvm.type != e1000_nvm_flash_hw) 7388c2ecf20Sopenharmony_ci return 0; 7398c2ecf20Sopenharmony_ci 7408c2ecf20Sopenharmony_ci /* Check for pending operations. */ 7418c2ecf20Sopenharmony_ci for (i = 0; i < E1000_FLASH_UPDATES; i++) { 7428c2ecf20Sopenharmony_ci usleep_range(1000, 2000); 7438c2ecf20Sopenharmony_ci if (!(er32(EECD) & E1000_EECD_FLUPD)) 7448c2ecf20Sopenharmony_ci break; 7458c2ecf20Sopenharmony_ci } 7468c2ecf20Sopenharmony_ci 7478c2ecf20Sopenharmony_ci if (i == E1000_FLASH_UPDATES) 7488c2ecf20Sopenharmony_ci return -E1000_ERR_NVM; 7498c2ecf20Sopenharmony_ci 7508c2ecf20Sopenharmony_ci /* Reset the firmware if using STM opcode. */ 7518c2ecf20Sopenharmony_ci if ((er32(FLOP) & 0xFF00) == E1000_STM_OPCODE) { 7528c2ecf20Sopenharmony_ci /* The enabling of and the actual reset must be done 7538c2ecf20Sopenharmony_ci * in two write cycles. 7548c2ecf20Sopenharmony_ci */ 7558c2ecf20Sopenharmony_ci ew32(HICR, E1000_HICR_FW_RESET_ENABLE); 7568c2ecf20Sopenharmony_ci e1e_flush(); 7578c2ecf20Sopenharmony_ci ew32(HICR, E1000_HICR_FW_RESET); 7588c2ecf20Sopenharmony_ci } 7598c2ecf20Sopenharmony_ci 7608c2ecf20Sopenharmony_ci /* Commit the write to flash */ 7618c2ecf20Sopenharmony_ci eecd = er32(EECD) | E1000_EECD_FLUPD; 7628c2ecf20Sopenharmony_ci ew32(EECD, eecd); 7638c2ecf20Sopenharmony_ci 7648c2ecf20Sopenharmony_ci for (i = 0; i < E1000_FLASH_UPDATES; i++) { 7658c2ecf20Sopenharmony_ci usleep_range(1000, 2000); 7668c2ecf20Sopenharmony_ci if (!(er32(EECD) & E1000_EECD_FLUPD)) 7678c2ecf20Sopenharmony_ci break; 7688c2ecf20Sopenharmony_ci } 7698c2ecf20Sopenharmony_ci 7708c2ecf20Sopenharmony_ci if (i == E1000_FLASH_UPDATES) 7718c2ecf20Sopenharmony_ci return -E1000_ERR_NVM; 7728c2ecf20Sopenharmony_ci 7738c2ecf20Sopenharmony_ci return 0; 7748c2ecf20Sopenharmony_ci} 7758c2ecf20Sopenharmony_ci 7768c2ecf20Sopenharmony_ci/** 7778c2ecf20Sopenharmony_ci * e1000_validate_nvm_checksum_82571 - Validate EEPROM checksum 7788c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 7798c2ecf20Sopenharmony_ci * 7808c2ecf20Sopenharmony_ci * Calculates the EEPROM checksum by reading/adding each word of the EEPROM 7818c2ecf20Sopenharmony_ci * and then verifies that the sum of the EEPROM is equal to 0xBABA. 7828c2ecf20Sopenharmony_ci **/ 7838c2ecf20Sopenharmony_cistatic s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw) 7848c2ecf20Sopenharmony_ci{ 7858c2ecf20Sopenharmony_ci if (hw->nvm.type == e1000_nvm_flash_hw) 7868c2ecf20Sopenharmony_ci e1000_fix_nvm_checksum_82571(hw); 7878c2ecf20Sopenharmony_ci 7888c2ecf20Sopenharmony_ci return e1000e_validate_nvm_checksum_generic(hw); 7898c2ecf20Sopenharmony_ci} 7908c2ecf20Sopenharmony_ci 7918c2ecf20Sopenharmony_ci/** 7928c2ecf20Sopenharmony_ci * e1000_write_nvm_eewr_82571 - Write to EEPROM for 82573 silicon 7938c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 7948c2ecf20Sopenharmony_ci * @offset: offset within the EEPROM to be written to 7958c2ecf20Sopenharmony_ci * @words: number of words to write 7968c2ecf20Sopenharmony_ci * @data: 16 bit word(s) to be written to the EEPROM 7978c2ecf20Sopenharmony_ci * 7988c2ecf20Sopenharmony_ci * After checking for invalid values, poll the EEPROM to ensure the previous 7998c2ecf20Sopenharmony_ci * command has completed before trying to write the next word. After write 8008c2ecf20Sopenharmony_ci * poll for completion. 8018c2ecf20Sopenharmony_ci * 8028c2ecf20Sopenharmony_ci * If e1000e_update_nvm_checksum is not called after this function, the 8038c2ecf20Sopenharmony_ci * EEPROM will most likely contain an invalid checksum. 8048c2ecf20Sopenharmony_ci **/ 8058c2ecf20Sopenharmony_cistatic s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, 8068c2ecf20Sopenharmony_ci u16 words, u16 *data) 8078c2ecf20Sopenharmony_ci{ 8088c2ecf20Sopenharmony_ci struct e1000_nvm_info *nvm = &hw->nvm; 8098c2ecf20Sopenharmony_ci u32 i, eewr = 0; 8108c2ecf20Sopenharmony_ci s32 ret_val = 0; 8118c2ecf20Sopenharmony_ci 8128c2ecf20Sopenharmony_ci /* A check for invalid values: offset too large, too many words, 8138c2ecf20Sopenharmony_ci * and not enough words. 8148c2ecf20Sopenharmony_ci */ 8158c2ecf20Sopenharmony_ci if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 8168c2ecf20Sopenharmony_ci (words == 0)) { 8178c2ecf20Sopenharmony_ci e_dbg("nvm parameter(s) out of bounds\n"); 8188c2ecf20Sopenharmony_ci return -E1000_ERR_NVM; 8198c2ecf20Sopenharmony_ci } 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_ci for (i = 0; i < words; i++) { 8228c2ecf20Sopenharmony_ci eewr = ((data[i] << E1000_NVM_RW_REG_DATA) | 8238c2ecf20Sopenharmony_ci ((offset + i) << E1000_NVM_RW_ADDR_SHIFT) | 8248c2ecf20Sopenharmony_ci E1000_NVM_RW_REG_START); 8258c2ecf20Sopenharmony_ci 8268c2ecf20Sopenharmony_ci ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE); 8278c2ecf20Sopenharmony_ci if (ret_val) 8288c2ecf20Sopenharmony_ci break; 8298c2ecf20Sopenharmony_ci 8308c2ecf20Sopenharmony_ci ew32(EEWR, eewr); 8318c2ecf20Sopenharmony_ci 8328c2ecf20Sopenharmony_ci ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE); 8338c2ecf20Sopenharmony_ci if (ret_val) 8348c2ecf20Sopenharmony_ci break; 8358c2ecf20Sopenharmony_ci } 8368c2ecf20Sopenharmony_ci 8378c2ecf20Sopenharmony_ci return ret_val; 8388c2ecf20Sopenharmony_ci} 8398c2ecf20Sopenharmony_ci 8408c2ecf20Sopenharmony_ci/** 8418c2ecf20Sopenharmony_ci * e1000_get_cfg_done_82571 - Poll for configuration done 8428c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 8438c2ecf20Sopenharmony_ci * 8448c2ecf20Sopenharmony_ci * Reads the management control register for the config done bit to be set. 8458c2ecf20Sopenharmony_ci **/ 8468c2ecf20Sopenharmony_cistatic s32 e1000_get_cfg_done_82571(struct e1000_hw *hw) 8478c2ecf20Sopenharmony_ci{ 8488c2ecf20Sopenharmony_ci s32 timeout = PHY_CFG_TIMEOUT; 8498c2ecf20Sopenharmony_ci 8508c2ecf20Sopenharmony_ci while (timeout) { 8518c2ecf20Sopenharmony_ci if (er32(EEMNGCTL) & E1000_NVM_CFG_DONE_PORT_0) 8528c2ecf20Sopenharmony_ci break; 8538c2ecf20Sopenharmony_ci usleep_range(1000, 2000); 8548c2ecf20Sopenharmony_ci timeout--; 8558c2ecf20Sopenharmony_ci } 8568c2ecf20Sopenharmony_ci if (!timeout) { 8578c2ecf20Sopenharmony_ci e_dbg("MNG configuration cycle has not completed.\n"); 8588c2ecf20Sopenharmony_ci return -E1000_ERR_RESET; 8598c2ecf20Sopenharmony_ci } 8608c2ecf20Sopenharmony_ci 8618c2ecf20Sopenharmony_ci return 0; 8628c2ecf20Sopenharmony_ci} 8638c2ecf20Sopenharmony_ci 8648c2ecf20Sopenharmony_ci/** 8658c2ecf20Sopenharmony_ci * e1000_set_d0_lplu_state_82571 - Set Low Power Linkup D0 state 8668c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 8678c2ecf20Sopenharmony_ci * @active: true to enable LPLU, false to disable 8688c2ecf20Sopenharmony_ci * 8698c2ecf20Sopenharmony_ci * Sets the LPLU D0 state according to the active flag. When activating LPLU 8708c2ecf20Sopenharmony_ci * this function also disables smart speed and vice versa. LPLU will not be 8718c2ecf20Sopenharmony_ci * activated unless the device autonegotiation advertisement meets standards 8728c2ecf20Sopenharmony_ci * of either 10 or 10/100 or 10/100/1000 at all duplexes. This is a function 8738c2ecf20Sopenharmony_ci * pointer entry point only called by PHY setup routines. 8748c2ecf20Sopenharmony_ci **/ 8758c2ecf20Sopenharmony_cistatic s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) 8768c2ecf20Sopenharmony_ci{ 8778c2ecf20Sopenharmony_ci struct e1000_phy_info *phy = &hw->phy; 8788c2ecf20Sopenharmony_ci s32 ret_val; 8798c2ecf20Sopenharmony_ci u16 data; 8808c2ecf20Sopenharmony_ci 8818c2ecf20Sopenharmony_ci ret_val = e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &data); 8828c2ecf20Sopenharmony_ci if (ret_val) 8838c2ecf20Sopenharmony_ci return ret_val; 8848c2ecf20Sopenharmony_ci 8858c2ecf20Sopenharmony_ci if (active) { 8868c2ecf20Sopenharmony_ci data |= IGP02E1000_PM_D0_LPLU; 8878c2ecf20Sopenharmony_ci ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data); 8888c2ecf20Sopenharmony_ci if (ret_val) 8898c2ecf20Sopenharmony_ci return ret_val; 8908c2ecf20Sopenharmony_ci 8918c2ecf20Sopenharmony_ci /* When LPLU is enabled, we should disable SmartSpeed */ 8928c2ecf20Sopenharmony_ci ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data); 8938c2ecf20Sopenharmony_ci if (ret_val) 8948c2ecf20Sopenharmony_ci return ret_val; 8958c2ecf20Sopenharmony_ci data &= ~IGP01E1000_PSCFR_SMART_SPEED; 8968c2ecf20Sopenharmony_ci ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data); 8978c2ecf20Sopenharmony_ci if (ret_val) 8988c2ecf20Sopenharmony_ci return ret_val; 8998c2ecf20Sopenharmony_ci } else { 9008c2ecf20Sopenharmony_ci data &= ~IGP02E1000_PM_D0_LPLU; 9018c2ecf20Sopenharmony_ci ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data); 9028c2ecf20Sopenharmony_ci if (ret_val) 9038c2ecf20Sopenharmony_ci return ret_val; 9048c2ecf20Sopenharmony_ci /* LPLU and SmartSpeed are mutually exclusive. LPLU is used 9058c2ecf20Sopenharmony_ci * during Dx states where the power conservation is most 9068c2ecf20Sopenharmony_ci * important. During driver activity we should enable 9078c2ecf20Sopenharmony_ci * SmartSpeed, so performance is maintained. 9088c2ecf20Sopenharmony_ci */ 9098c2ecf20Sopenharmony_ci if (phy->smart_speed == e1000_smart_speed_on) { 9108c2ecf20Sopenharmony_ci ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, 9118c2ecf20Sopenharmony_ci &data); 9128c2ecf20Sopenharmony_ci if (ret_val) 9138c2ecf20Sopenharmony_ci return ret_val; 9148c2ecf20Sopenharmony_ci 9158c2ecf20Sopenharmony_ci data |= IGP01E1000_PSCFR_SMART_SPEED; 9168c2ecf20Sopenharmony_ci ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, 9178c2ecf20Sopenharmony_ci data); 9188c2ecf20Sopenharmony_ci if (ret_val) 9198c2ecf20Sopenharmony_ci return ret_val; 9208c2ecf20Sopenharmony_ci } else if (phy->smart_speed == e1000_smart_speed_off) { 9218c2ecf20Sopenharmony_ci ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, 9228c2ecf20Sopenharmony_ci &data); 9238c2ecf20Sopenharmony_ci if (ret_val) 9248c2ecf20Sopenharmony_ci return ret_val; 9258c2ecf20Sopenharmony_ci 9268c2ecf20Sopenharmony_ci data &= ~IGP01E1000_PSCFR_SMART_SPEED; 9278c2ecf20Sopenharmony_ci ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, 9288c2ecf20Sopenharmony_ci data); 9298c2ecf20Sopenharmony_ci if (ret_val) 9308c2ecf20Sopenharmony_ci return ret_val; 9318c2ecf20Sopenharmony_ci } 9328c2ecf20Sopenharmony_ci } 9338c2ecf20Sopenharmony_ci 9348c2ecf20Sopenharmony_ci return 0; 9358c2ecf20Sopenharmony_ci} 9368c2ecf20Sopenharmony_ci 9378c2ecf20Sopenharmony_ci/** 9388c2ecf20Sopenharmony_ci * e1000_reset_hw_82571 - Reset hardware 9398c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 9408c2ecf20Sopenharmony_ci * 9418c2ecf20Sopenharmony_ci * This resets the hardware into a known state. 9428c2ecf20Sopenharmony_ci **/ 9438c2ecf20Sopenharmony_cistatic s32 e1000_reset_hw_82571(struct e1000_hw *hw) 9448c2ecf20Sopenharmony_ci{ 9458c2ecf20Sopenharmony_ci u32 ctrl, ctrl_ext, eecd, tctl; 9468c2ecf20Sopenharmony_ci s32 ret_val; 9478c2ecf20Sopenharmony_ci 9488c2ecf20Sopenharmony_ci /* Prevent the PCI-E bus from sticking if there is no TLP connection 9498c2ecf20Sopenharmony_ci * on the last TLP read/write transaction when MAC is reset. 9508c2ecf20Sopenharmony_ci */ 9518c2ecf20Sopenharmony_ci ret_val = e1000e_disable_pcie_master(hw); 9528c2ecf20Sopenharmony_ci if (ret_val) 9538c2ecf20Sopenharmony_ci e_dbg("PCI-E Master disable polling has failed.\n"); 9548c2ecf20Sopenharmony_ci 9558c2ecf20Sopenharmony_ci e_dbg("Masking off all interrupts\n"); 9568c2ecf20Sopenharmony_ci ew32(IMC, 0xffffffff); 9578c2ecf20Sopenharmony_ci 9588c2ecf20Sopenharmony_ci ew32(RCTL, 0); 9598c2ecf20Sopenharmony_ci tctl = er32(TCTL); 9608c2ecf20Sopenharmony_ci tctl &= ~E1000_TCTL_EN; 9618c2ecf20Sopenharmony_ci ew32(TCTL, tctl); 9628c2ecf20Sopenharmony_ci e1e_flush(); 9638c2ecf20Sopenharmony_ci 9648c2ecf20Sopenharmony_ci usleep_range(10000, 11000); 9658c2ecf20Sopenharmony_ci 9668c2ecf20Sopenharmony_ci /* Must acquire the MDIO ownership before MAC reset. 9678c2ecf20Sopenharmony_ci * Ownership defaults to firmware after a reset. 9688c2ecf20Sopenharmony_ci */ 9698c2ecf20Sopenharmony_ci switch (hw->mac.type) { 9708c2ecf20Sopenharmony_ci case e1000_82573: 9718c2ecf20Sopenharmony_ci ret_val = e1000_get_hw_semaphore_82573(hw); 9728c2ecf20Sopenharmony_ci break; 9738c2ecf20Sopenharmony_ci case e1000_82574: 9748c2ecf20Sopenharmony_ci case e1000_82583: 9758c2ecf20Sopenharmony_ci ret_val = e1000_get_hw_semaphore_82574(hw); 9768c2ecf20Sopenharmony_ci break; 9778c2ecf20Sopenharmony_ci default: 9788c2ecf20Sopenharmony_ci break; 9798c2ecf20Sopenharmony_ci } 9808c2ecf20Sopenharmony_ci 9818c2ecf20Sopenharmony_ci ctrl = er32(CTRL); 9828c2ecf20Sopenharmony_ci 9838c2ecf20Sopenharmony_ci e_dbg("Issuing a global reset to MAC\n"); 9848c2ecf20Sopenharmony_ci ew32(CTRL, ctrl | E1000_CTRL_RST); 9858c2ecf20Sopenharmony_ci 9868c2ecf20Sopenharmony_ci /* Must release MDIO ownership and mutex after MAC reset. */ 9878c2ecf20Sopenharmony_ci switch (hw->mac.type) { 9888c2ecf20Sopenharmony_ci case e1000_82573: 9898c2ecf20Sopenharmony_ci /* Release mutex only if the hw semaphore is acquired */ 9908c2ecf20Sopenharmony_ci if (!ret_val) 9918c2ecf20Sopenharmony_ci e1000_put_hw_semaphore_82573(hw); 9928c2ecf20Sopenharmony_ci break; 9938c2ecf20Sopenharmony_ci case e1000_82574: 9948c2ecf20Sopenharmony_ci case e1000_82583: 9958c2ecf20Sopenharmony_ci /* Release mutex only if the hw semaphore is acquired */ 9968c2ecf20Sopenharmony_ci if (!ret_val) 9978c2ecf20Sopenharmony_ci e1000_put_hw_semaphore_82574(hw); 9988c2ecf20Sopenharmony_ci break; 9998c2ecf20Sopenharmony_ci default: 10008c2ecf20Sopenharmony_ci break; 10018c2ecf20Sopenharmony_ci } 10028c2ecf20Sopenharmony_ci 10038c2ecf20Sopenharmony_ci if (hw->nvm.type == e1000_nvm_flash_hw) { 10048c2ecf20Sopenharmony_ci usleep_range(10, 20); 10058c2ecf20Sopenharmony_ci ctrl_ext = er32(CTRL_EXT); 10068c2ecf20Sopenharmony_ci ctrl_ext |= E1000_CTRL_EXT_EE_RST; 10078c2ecf20Sopenharmony_ci ew32(CTRL_EXT, ctrl_ext); 10088c2ecf20Sopenharmony_ci e1e_flush(); 10098c2ecf20Sopenharmony_ci } 10108c2ecf20Sopenharmony_ci 10118c2ecf20Sopenharmony_ci ret_val = e1000e_get_auto_rd_done(hw); 10128c2ecf20Sopenharmony_ci if (ret_val) 10138c2ecf20Sopenharmony_ci /* We don't want to continue accessing MAC registers. */ 10148c2ecf20Sopenharmony_ci return ret_val; 10158c2ecf20Sopenharmony_ci 10168c2ecf20Sopenharmony_ci /* Phy configuration from NVM just starts after EECD_AUTO_RD is set. 10178c2ecf20Sopenharmony_ci * Need to wait for Phy configuration completion before accessing 10188c2ecf20Sopenharmony_ci * NVM and Phy. 10198c2ecf20Sopenharmony_ci */ 10208c2ecf20Sopenharmony_ci 10218c2ecf20Sopenharmony_ci switch (hw->mac.type) { 10228c2ecf20Sopenharmony_ci case e1000_82571: 10238c2ecf20Sopenharmony_ci case e1000_82572: 10248c2ecf20Sopenharmony_ci /* REQ and GNT bits need to be cleared when using AUTO_RD 10258c2ecf20Sopenharmony_ci * to access the EEPROM. 10268c2ecf20Sopenharmony_ci */ 10278c2ecf20Sopenharmony_ci eecd = er32(EECD); 10288c2ecf20Sopenharmony_ci eecd &= ~(E1000_EECD_REQ | E1000_EECD_GNT); 10298c2ecf20Sopenharmony_ci ew32(EECD, eecd); 10308c2ecf20Sopenharmony_ci break; 10318c2ecf20Sopenharmony_ci case e1000_82573: 10328c2ecf20Sopenharmony_ci case e1000_82574: 10338c2ecf20Sopenharmony_ci case e1000_82583: 10348c2ecf20Sopenharmony_ci msleep(25); 10358c2ecf20Sopenharmony_ci break; 10368c2ecf20Sopenharmony_ci default: 10378c2ecf20Sopenharmony_ci break; 10388c2ecf20Sopenharmony_ci } 10398c2ecf20Sopenharmony_ci 10408c2ecf20Sopenharmony_ci /* Clear any pending interrupt events. */ 10418c2ecf20Sopenharmony_ci ew32(IMC, 0xffffffff); 10428c2ecf20Sopenharmony_ci er32(ICR); 10438c2ecf20Sopenharmony_ci 10448c2ecf20Sopenharmony_ci if (hw->mac.type == e1000_82571) { 10458c2ecf20Sopenharmony_ci /* Install any alternate MAC address into RAR0 */ 10468c2ecf20Sopenharmony_ci ret_val = e1000_check_alt_mac_addr_generic(hw); 10478c2ecf20Sopenharmony_ci if (ret_val) 10488c2ecf20Sopenharmony_ci return ret_val; 10498c2ecf20Sopenharmony_ci 10508c2ecf20Sopenharmony_ci e1000e_set_laa_state_82571(hw, true); 10518c2ecf20Sopenharmony_ci } 10528c2ecf20Sopenharmony_ci 10538c2ecf20Sopenharmony_ci /* Reinitialize the 82571 serdes link state machine */ 10548c2ecf20Sopenharmony_ci if (hw->phy.media_type == e1000_media_type_internal_serdes) 10558c2ecf20Sopenharmony_ci hw->mac.serdes_link_state = e1000_serdes_link_down; 10568c2ecf20Sopenharmony_ci 10578c2ecf20Sopenharmony_ci return 0; 10588c2ecf20Sopenharmony_ci} 10598c2ecf20Sopenharmony_ci 10608c2ecf20Sopenharmony_ci/** 10618c2ecf20Sopenharmony_ci * e1000_init_hw_82571 - Initialize hardware 10628c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 10638c2ecf20Sopenharmony_ci * 10648c2ecf20Sopenharmony_ci * This inits the hardware readying it for operation. 10658c2ecf20Sopenharmony_ci **/ 10668c2ecf20Sopenharmony_cistatic s32 e1000_init_hw_82571(struct e1000_hw *hw) 10678c2ecf20Sopenharmony_ci{ 10688c2ecf20Sopenharmony_ci struct e1000_mac_info *mac = &hw->mac; 10698c2ecf20Sopenharmony_ci u32 reg_data; 10708c2ecf20Sopenharmony_ci s32 ret_val; 10718c2ecf20Sopenharmony_ci u16 i, rar_count = mac->rar_entry_count; 10728c2ecf20Sopenharmony_ci 10738c2ecf20Sopenharmony_ci e1000_initialize_hw_bits_82571(hw); 10748c2ecf20Sopenharmony_ci 10758c2ecf20Sopenharmony_ci /* Initialize identification LED */ 10768c2ecf20Sopenharmony_ci ret_val = mac->ops.id_led_init(hw); 10778c2ecf20Sopenharmony_ci /* An error is not fatal and we should not stop init due to this */ 10788c2ecf20Sopenharmony_ci if (ret_val) 10798c2ecf20Sopenharmony_ci e_dbg("Error initializing identification LED\n"); 10808c2ecf20Sopenharmony_ci 10818c2ecf20Sopenharmony_ci /* Disabling VLAN filtering */ 10828c2ecf20Sopenharmony_ci e_dbg("Initializing the IEEE VLAN\n"); 10838c2ecf20Sopenharmony_ci mac->ops.clear_vfta(hw); 10848c2ecf20Sopenharmony_ci 10858c2ecf20Sopenharmony_ci /* Setup the receive address. 10868c2ecf20Sopenharmony_ci * If, however, a locally administered address was assigned to the 10878c2ecf20Sopenharmony_ci * 82571, we must reserve a RAR for it to work around an issue where 10888c2ecf20Sopenharmony_ci * resetting one port will reload the MAC on the other port. 10898c2ecf20Sopenharmony_ci */ 10908c2ecf20Sopenharmony_ci if (e1000e_get_laa_state_82571(hw)) 10918c2ecf20Sopenharmony_ci rar_count--; 10928c2ecf20Sopenharmony_ci e1000e_init_rx_addrs(hw, rar_count); 10938c2ecf20Sopenharmony_ci 10948c2ecf20Sopenharmony_ci /* Zero out the Multicast HASH table */ 10958c2ecf20Sopenharmony_ci e_dbg("Zeroing the MTA\n"); 10968c2ecf20Sopenharmony_ci for (i = 0; i < mac->mta_reg_count; i++) 10978c2ecf20Sopenharmony_ci E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); 10988c2ecf20Sopenharmony_ci 10998c2ecf20Sopenharmony_ci /* Setup link and flow control */ 11008c2ecf20Sopenharmony_ci ret_val = mac->ops.setup_link(hw); 11018c2ecf20Sopenharmony_ci 11028c2ecf20Sopenharmony_ci /* Set the transmit descriptor write-back policy */ 11038c2ecf20Sopenharmony_ci reg_data = er32(TXDCTL(0)); 11048c2ecf20Sopenharmony_ci reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) | 11058c2ecf20Sopenharmony_ci E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC); 11068c2ecf20Sopenharmony_ci ew32(TXDCTL(0), reg_data); 11078c2ecf20Sopenharmony_ci 11088c2ecf20Sopenharmony_ci /* ...for both queues. */ 11098c2ecf20Sopenharmony_ci switch (mac->type) { 11108c2ecf20Sopenharmony_ci case e1000_82573: 11118c2ecf20Sopenharmony_ci e1000e_enable_tx_pkt_filtering(hw); 11128c2ecf20Sopenharmony_ci fallthrough; 11138c2ecf20Sopenharmony_ci case e1000_82574: 11148c2ecf20Sopenharmony_ci case e1000_82583: 11158c2ecf20Sopenharmony_ci reg_data = er32(GCR); 11168c2ecf20Sopenharmony_ci reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX; 11178c2ecf20Sopenharmony_ci ew32(GCR, reg_data); 11188c2ecf20Sopenharmony_ci break; 11198c2ecf20Sopenharmony_ci default: 11208c2ecf20Sopenharmony_ci reg_data = er32(TXDCTL(1)); 11218c2ecf20Sopenharmony_ci reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) | 11228c2ecf20Sopenharmony_ci E1000_TXDCTL_FULL_TX_DESC_WB | 11238c2ecf20Sopenharmony_ci E1000_TXDCTL_COUNT_DESC); 11248c2ecf20Sopenharmony_ci ew32(TXDCTL(1), reg_data); 11258c2ecf20Sopenharmony_ci break; 11268c2ecf20Sopenharmony_ci } 11278c2ecf20Sopenharmony_ci 11288c2ecf20Sopenharmony_ci /* Clear all of the statistics registers (clear on read). It is 11298c2ecf20Sopenharmony_ci * important that we do this after we have tried to establish link 11308c2ecf20Sopenharmony_ci * because the symbol error count will increment wildly if there 11318c2ecf20Sopenharmony_ci * is no link. 11328c2ecf20Sopenharmony_ci */ 11338c2ecf20Sopenharmony_ci e1000_clear_hw_cntrs_82571(hw); 11348c2ecf20Sopenharmony_ci 11358c2ecf20Sopenharmony_ci return ret_val; 11368c2ecf20Sopenharmony_ci} 11378c2ecf20Sopenharmony_ci 11388c2ecf20Sopenharmony_ci/** 11398c2ecf20Sopenharmony_ci * e1000_initialize_hw_bits_82571 - Initialize hardware-dependent bits 11408c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 11418c2ecf20Sopenharmony_ci * 11428c2ecf20Sopenharmony_ci * Initializes required hardware-dependent bits needed for normal operation. 11438c2ecf20Sopenharmony_ci **/ 11448c2ecf20Sopenharmony_cistatic void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) 11458c2ecf20Sopenharmony_ci{ 11468c2ecf20Sopenharmony_ci u32 reg; 11478c2ecf20Sopenharmony_ci 11488c2ecf20Sopenharmony_ci /* Transmit Descriptor Control 0 */ 11498c2ecf20Sopenharmony_ci reg = er32(TXDCTL(0)); 11508c2ecf20Sopenharmony_ci reg |= BIT(22); 11518c2ecf20Sopenharmony_ci ew32(TXDCTL(0), reg); 11528c2ecf20Sopenharmony_ci 11538c2ecf20Sopenharmony_ci /* Transmit Descriptor Control 1 */ 11548c2ecf20Sopenharmony_ci reg = er32(TXDCTL(1)); 11558c2ecf20Sopenharmony_ci reg |= BIT(22); 11568c2ecf20Sopenharmony_ci ew32(TXDCTL(1), reg); 11578c2ecf20Sopenharmony_ci 11588c2ecf20Sopenharmony_ci /* Transmit Arbitration Control 0 */ 11598c2ecf20Sopenharmony_ci reg = er32(TARC(0)); 11608c2ecf20Sopenharmony_ci reg &= ~(0xF << 27); /* 30:27 */ 11618c2ecf20Sopenharmony_ci switch (hw->mac.type) { 11628c2ecf20Sopenharmony_ci case e1000_82571: 11638c2ecf20Sopenharmony_ci case e1000_82572: 11648c2ecf20Sopenharmony_ci reg |= BIT(23) | BIT(24) | BIT(25) | BIT(26); 11658c2ecf20Sopenharmony_ci break; 11668c2ecf20Sopenharmony_ci case e1000_82574: 11678c2ecf20Sopenharmony_ci case e1000_82583: 11688c2ecf20Sopenharmony_ci reg |= BIT(26); 11698c2ecf20Sopenharmony_ci break; 11708c2ecf20Sopenharmony_ci default: 11718c2ecf20Sopenharmony_ci break; 11728c2ecf20Sopenharmony_ci } 11738c2ecf20Sopenharmony_ci ew32(TARC(0), reg); 11748c2ecf20Sopenharmony_ci 11758c2ecf20Sopenharmony_ci /* Transmit Arbitration Control 1 */ 11768c2ecf20Sopenharmony_ci reg = er32(TARC(1)); 11778c2ecf20Sopenharmony_ci switch (hw->mac.type) { 11788c2ecf20Sopenharmony_ci case e1000_82571: 11798c2ecf20Sopenharmony_ci case e1000_82572: 11808c2ecf20Sopenharmony_ci reg &= ~(BIT(29) | BIT(30)); 11818c2ecf20Sopenharmony_ci reg |= BIT(22) | BIT(24) | BIT(25) | BIT(26); 11828c2ecf20Sopenharmony_ci if (er32(TCTL) & E1000_TCTL_MULR) 11838c2ecf20Sopenharmony_ci reg &= ~BIT(28); 11848c2ecf20Sopenharmony_ci else 11858c2ecf20Sopenharmony_ci reg |= BIT(28); 11868c2ecf20Sopenharmony_ci ew32(TARC(1), reg); 11878c2ecf20Sopenharmony_ci break; 11888c2ecf20Sopenharmony_ci default: 11898c2ecf20Sopenharmony_ci break; 11908c2ecf20Sopenharmony_ci } 11918c2ecf20Sopenharmony_ci 11928c2ecf20Sopenharmony_ci /* Device Control */ 11938c2ecf20Sopenharmony_ci switch (hw->mac.type) { 11948c2ecf20Sopenharmony_ci case e1000_82573: 11958c2ecf20Sopenharmony_ci case e1000_82574: 11968c2ecf20Sopenharmony_ci case e1000_82583: 11978c2ecf20Sopenharmony_ci reg = er32(CTRL); 11988c2ecf20Sopenharmony_ci reg &= ~BIT(29); 11998c2ecf20Sopenharmony_ci ew32(CTRL, reg); 12008c2ecf20Sopenharmony_ci break; 12018c2ecf20Sopenharmony_ci default: 12028c2ecf20Sopenharmony_ci break; 12038c2ecf20Sopenharmony_ci } 12048c2ecf20Sopenharmony_ci 12058c2ecf20Sopenharmony_ci /* Extended Device Control */ 12068c2ecf20Sopenharmony_ci switch (hw->mac.type) { 12078c2ecf20Sopenharmony_ci case e1000_82573: 12088c2ecf20Sopenharmony_ci case e1000_82574: 12098c2ecf20Sopenharmony_ci case e1000_82583: 12108c2ecf20Sopenharmony_ci reg = er32(CTRL_EXT); 12118c2ecf20Sopenharmony_ci reg &= ~BIT(23); 12128c2ecf20Sopenharmony_ci reg |= BIT(22); 12138c2ecf20Sopenharmony_ci ew32(CTRL_EXT, reg); 12148c2ecf20Sopenharmony_ci break; 12158c2ecf20Sopenharmony_ci default: 12168c2ecf20Sopenharmony_ci break; 12178c2ecf20Sopenharmony_ci } 12188c2ecf20Sopenharmony_ci 12198c2ecf20Sopenharmony_ci if (hw->mac.type == e1000_82571) { 12208c2ecf20Sopenharmony_ci reg = er32(PBA_ECC); 12218c2ecf20Sopenharmony_ci reg |= E1000_PBA_ECC_CORR_EN; 12228c2ecf20Sopenharmony_ci ew32(PBA_ECC, reg); 12238c2ecf20Sopenharmony_ci } 12248c2ecf20Sopenharmony_ci 12258c2ecf20Sopenharmony_ci /* Workaround for hardware errata. 12268c2ecf20Sopenharmony_ci * Ensure that DMA Dynamic Clock gating is disabled on 82571 and 82572 12278c2ecf20Sopenharmony_ci */ 12288c2ecf20Sopenharmony_ci if ((hw->mac.type == e1000_82571) || (hw->mac.type == e1000_82572)) { 12298c2ecf20Sopenharmony_ci reg = er32(CTRL_EXT); 12308c2ecf20Sopenharmony_ci reg &= ~E1000_CTRL_EXT_DMA_DYN_CLK_EN; 12318c2ecf20Sopenharmony_ci ew32(CTRL_EXT, reg); 12328c2ecf20Sopenharmony_ci } 12338c2ecf20Sopenharmony_ci 12348c2ecf20Sopenharmony_ci /* Disable IPv6 extension header parsing because some malformed 12358c2ecf20Sopenharmony_ci * IPv6 headers can hang the Rx. 12368c2ecf20Sopenharmony_ci */ 12378c2ecf20Sopenharmony_ci if (hw->mac.type <= e1000_82573) { 12388c2ecf20Sopenharmony_ci reg = er32(RFCTL); 12398c2ecf20Sopenharmony_ci reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS); 12408c2ecf20Sopenharmony_ci ew32(RFCTL, reg); 12418c2ecf20Sopenharmony_ci } 12428c2ecf20Sopenharmony_ci 12438c2ecf20Sopenharmony_ci /* PCI-Ex Control Registers */ 12448c2ecf20Sopenharmony_ci switch (hw->mac.type) { 12458c2ecf20Sopenharmony_ci case e1000_82574: 12468c2ecf20Sopenharmony_ci case e1000_82583: 12478c2ecf20Sopenharmony_ci reg = er32(GCR); 12488c2ecf20Sopenharmony_ci reg |= BIT(22); 12498c2ecf20Sopenharmony_ci ew32(GCR, reg); 12508c2ecf20Sopenharmony_ci 12518c2ecf20Sopenharmony_ci /* Workaround for hardware errata. 12528c2ecf20Sopenharmony_ci * apply workaround for hardware errata documented in errata 12538c2ecf20Sopenharmony_ci * docs Fixes issue where some error prone or unreliable PCIe 12548c2ecf20Sopenharmony_ci * completions are occurring, particularly with ASPM enabled. 12558c2ecf20Sopenharmony_ci * Without fix, issue can cause Tx timeouts. 12568c2ecf20Sopenharmony_ci */ 12578c2ecf20Sopenharmony_ci reg = er32(GCR2); 12588c2ecf20Sopenharmony_ci reg |= 1; 12598c2ecf20Sopenharmony_ci ew32(GCR2, reg); 12608c2ecf20Sopenharmony_ci break; 12618c2ecf20Sopenharmony_ci default: 12628c2ecf20Sopenharmony_ci break; 12638c2ecf20Sopenharmony_ci } 12648c2ecf20Sopenharmony_ci} 12658c2ecf20Sopenharmony_ci 12668c2ecf20Sopenharmony_ci/** 12678c2ecf20Sopenharmony_ci * e1000_clear_vfta_82571 - Clear VLAN filter table 12688c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 12698c2ecf20Sopenharmony_ci * 12708c2ecf20Sopenharmony_ci * Clears the register array which contains the VLAN filter table by 12718c2ecf20Sopenharmony_ci * setting all the values to 0. 12728c2ecf20Sopenharmony_ci **/ 12738c2ecf20Sopenharmony_cistatic void e1000_clear_vfta_82571(struct e1000_hw *hw) 12748c2ecf20Sopenharmony_ci{ 12758c2ecf20Sopenharmony_ci u32 offset; 12768c2ecf20Sopenharmony_ci u32 vfta_value = 0; 12778c2ecf20Sopenharmony_ci u32 vfta_offset = 0; 12788c2ecf20Sopenharmony_ci u32 vfta_bit_in_reg = 0; 12798c2ecf20Sopenharmony_ci 12808c2ecf20Sopenharmony_ci switch (hw->mac.type) { 12818c2ecf20Sopenharmony_ci case e1000_82573: 12828c2ecf20Sopenharmony_ci case e1000_82574: 12838c2ecf20Sopenharmony_ci case e1000_82583: 12848c2ecf20Sopenharmony_ci if (hw->mng_cookie.vlan_id != 0) { 12858c2ecf20Sopenharmony_ci /* The VFTA is a 4096b bit-field, each identifying 12868c2ecf20Sopenharmony_ci * a single VLAN ID. The following operations 12878c2ecf20Sopenharmony_ci * determine which 32b entry (i.e. offset) into the 12888c2ecf20Sopenharmony_ci * array we want to set the VLAN ID (i.e. bit) of 12898c2ecf20Sopenharmony_ci * the manageability unit. 12908c2ecf20Sopenharmony_ci */ 12918c2ecf20Sopenharmony_ci vfta_offset = (hw->mng_cookie.vlan_id >> 12928c2ecf20Sopenharmony_ci E1000_VFTA_ENTRY_SHIFT) & 12938c2ecf20Sopenharmony_ci E1000_VFTA_ENTRY_MASK; 12948c2ecf20Sopenharmony_ci vfta_bit_in_reg = 12958c2ecf20Sopenharmony_ci BIT(hw->mng_cookie.vlan_id & 12968c2ecf20Sopenharmony_ci E1000_VFTA_ENTRY_BIT_SHIFT_MASK); 12978c2ecf20Sopenharmony_ci } 12988c2ecf20Sopenharmony_ci break; 12998c2ecf20Sopenharmony_ci default: 13008c2ecf20Sopenharmony_ci break; 13018c2ecf20Sopenharmony_ci } 13028c2ecf20Sopenharmony_ci for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { 13038c2ecf20Sopenharmony_ci /* If the offset we want to clear is the same offset of the 13048c2ecf20Sopenharmony_ci * manageability VLAN ID, then clear all bits except that of 13058c2ecf20Sopenharmony_ci * the manageability unit. 13068c2ecf20Sopenharmony_ci */ 13078c2ecf20Sopenharmony_ci vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0; 13088c2ecf20Sopenharmony_ci E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, vfta_value); 13098c2ecf20Sopenharmony_ci e1e_flush(); 13108c2ecf20Sopenharmony_ci } 13118c2ecf20Sopenharmony_ci} 13128c2ecf20Sopenharmony_ci 13138c2ecf20Sopenharmony_ci/** 13148c2ecf20Sopenharmony_ci * e1000_check_mng_mode_82574 - Check manageability is enabled 13158c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 13168c2ecf20Sopenharmony_ci * 13178c2ecf20Sopenharmony_ci * Reads the NVM Initialization Control Word 2 and returns true 13188c2ecf20Sopenharmony_ci * (>0) if any manageability is enabled, else false (0). 13198c2ecf20Sopenharmony_ci **/ 13208c2ecf20Sopenharmony_cistatic bool e1000_check_mng_mode_82574(struct e1000_hw *hw) 13218c2ecf20Sopenharmony_ci{ 13228c2ecf20Sopenharmony_ci u16 data; 13238c2ecf20Sopenharmony_ci 13248c2ecf20Sopenharmony_ci e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); 13258c2ecf20Sopenharmony_ci return (data & E1000_NVM_INIT_CTRL2_MNGM) != 0; 13268c2ecf20Sopenharmony_ci} 13278c2ecf20Sopenharmony_ci 13288c2ecf20Sopenharmony_ci/** 13298c2ecf20Sopenharmony_ci * e1000_led_on_82574 - Turn LED on 13308c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 13318c2ecf20Sopenharmony_ci * 13328c2ecf20Sopenharmony_ci * Turn LED on. 13338c2ecf20Sopenharmony_ci **/ 13348c2ecf20Sopenharmony_cistatic s32 e1000_led_on_82574(struct e1000_hw *hw) 13358c2ecf20Sopenharmony_ci{ 13368c2ecf20Sopenharmony_ci u32 ctrl; 13378c2ecf20Sopenharmony_ci u32 i; 13388c2ecf20Sopenharmony_ci 13398c2ecf20Sopenharmony_ci ctrl = hw->mac.ledctl_mode2; 13408c2ecf20Sopenharmony_ci if (!(E1000_STATUS_LU & er32(STATUS))) { 13418c2ecf20Sopenharmony_ci /* If no link, then turn LED on by setting the invert bit 13428c2ecf20Sopenharmony_ci * for each LED that's "on" (0x0E) in ledctl_mode2. 13438c2ecf20Sopenharmony_ci */ 13448c2ecf20Sopenharmony_ci for (i = 0; i < 4; i++) 13458c2ecf20Sopenharmony_ci if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) == 13468c2ecf20Sopenharmony_ci E1000_LEDCTL_MODE_LED_ON) 13478c2ecf20Sopenharmony_ci ctrl |= (E1000_LEDCTL_LED0_IVRT << (i * 8)); 13488c2ecf20Sopenharmony_ci } 13498c2ecf20Sopenharmony_ci ew32(LEDCTL, ctrl); 13508c2ecf20Sopenharmony_ci 13518c2ecf20Sopenharmony_ci return 0; 13528c2ecf20Sopenharmony_ci} 13538c2ecf20Sopenharmony_ci 13548c2ecf20Sopenharmony_ci/** 13558c2ecf20Sopenharmony_ci * e1000_check_phy_82574 - check 82574 phy hung state 13568c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 13578c2ecf20Sopenharmony_ci * 13588c2ecf20Sopenharmony_ci * Returns whether phy is hung or not 13598c2ecf20Sopenharmony_ci **/ 13608c2ecf20Sopenharmony_cibool e1000_check_phy_82574(struct e1000_hw *hw) 13618c2ecf20Sopenharmony_ci{ 13628c2ecf20Sopenharmony_ci u16 status_1kbt = 0; 13638c2ecf20Sopenharmony_ci u16 receive_errors = 0; 13648c2ecf20Sopenharmony_ci s32 ret_val; 13658c2ecf20Sopenharmony_ci 13668c2ecf20Sopenharmony_ci /* Read PHY Receive Error counter first, if its is max - all F's then 13678c2ecf20Sopenharmony_ci * read the Base1000T status register If both are max then PHY is hung. 13688c2ecf20Sopenharmony_ci */ 13698c2ecf20Sopenharmony_ci ret_val = e1e_rphy(hw, E1000_RECEIVE_ERROR_COUNTER, &receive_errors); 13708c2ecf20Sopenharmony_ci if (ret_val) 13718c2ecf20Sopenharmony_ci return false; 13728c2ecf20Sopenharmony_ci if (receive_errors == E1000_RECEIVE_ERROR_MAX) { 13738c2ecf20Sopenharmony_ci ret_val = e1e_rphy(hw, E1000_BASE1000T_STATUS, &status_1kbt); 13748c2ecf20Sopenharmony_ci if (ret_val) 13758c2ecf20Sopenharmony_ci return false; 13768c2ecf20Sopenharmony_ci if ((status_1kbt & E1000_IDLE_ERROR_COUNT_MASK) == 13778c2ecf20Sopenharmony_ci E1000_IDLE_ERROR_COUNT_MASK) 13788c2ecf20Sopenharmony_ci return true; 13798c2ecf20Sopenharmony_ci } 13808c2ecf20Sopenharmony_ci 13818c2ecf20Sopenharmony_ci return false; 13828c2ecf20Sopenharmony_ci} 13838c2ecf20Sopenharmony_ci 13848c2ecf20Sopenharmony_ci/** 13858c2ecf20Sopenharmony_ci * e1000_setup_link_82571 - Setup flow control and link settings 13868c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 13878c2ecf20Sopenharmony_ci * 13888c2ecf20Sopenharmony_ci * Determines which flow control settings to use, then configures flow 13898c2ecf20Sopenharmony_ci * control. Calls the appropriate media-specific link configuration 13908c2ecf20Sopenharmony_ci * function. Assuming the adapter has a valid link partner, a valid link 13918c2ecf20Sopenharmony_ci * should be established. Assumes the hardware has previously been reset 13928c2ecf20Sopenharmony_ci * and the transmitter and receiver are not enabled. 13938c2ecf20Sopenharmony_ci **/ 13948c2ecf20Sopenharmony_cistatic s32 e1000_setup_link_82571(struct e1000_hw *hw) 13958c2ecf20Sopenharmony_ci{ 13968c2ecf20Sopenharmony_ci /* 82573 does not have a word in the NVM to determine 13978c2ecf20Sopenharmony_ci * the default flow control setting, so we explicitly 13988c2ecf20Sopenharmony_ci * set it to full. 13998c2ecf20Sopenharmony_ci */ 14008c2ecf20Sopenharmony_ci switch (hw->mac.type) { 14018c2ecf20Sopenharmony_ci case e1000_82573: 14028c2ecf20Sopenharmony_ci case e1000_82574: 14038c2ecf20Sopenharmony_ci case e1000_82583: 14048c2ecf20Sopenharmony_ci if (hw->fc.requested_mode == e1000_fc_default) 14058c2ecf20Sopenharmony_ci hw->fc.requested_mode = e1000_fc_full; 14068c2ecf20Sopenharmony_ci break; 14078c2ecf20Sopenharmony_ci default: 14088c2ecf20Sopenharmony_ci break; 14098c2ecf20Sopenharmony_ci } 14108c2ecf20Sopenharmony_ci 14118c2ecf20Sopenharmony_ci return e1000e_setup_link_generic(hw); 14128c2ecf20Sopenharmony_ci} 14138c2ecf20Sopenharmony_ci 14148c2ecf20Sopenharmony_ci/** 14158c2ecf20Sopenharmony_ci * e1000_setup_copper_link_82571 - Configure copper link settings 14168c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 14178c2ecf20Sopenharmony_ci * 14188c2ecf20Sopenharmony_ci * Configures the link for auto-neg or forced speed and duplex. Then we check 14198c2ecf20Sopenharmony_ci * for link, once link is established calls to configure collision distance 14208c2ecf20Sopenharmony_ci * and flow control are called. 14218c2ecf20Sopenharmony_ci **/ 14228c2ecf20Sopenharmony_cistatic s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) 14238c2ecf20Sopenharmony_ci{ 14248c2ecf20Sopenharmony_ci u32 ctrl; 14258c2ecf20Sopenharmony_ci s32 ret_val; 14268c2ecf20Sopenharmony_ci 14278c2ecf20Sopenharmony_ci ctrl = er32(CTRL); 14288c2ecf20Sopenharmony_ci ctrl |= E1000_CTRL_SLU; 14298c2ecf20Sopenharmony_ci ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); 14308c2ecf20Sopenharmony_ci ew32(CTRL, ctrl); 14318c2ecf20Sopenharmony_ci 14328c2ecf20Sopenharmony_ci switch (hw->phy.type) { 14338c2ecf20Sopenharmony_ci case e1000_phy_m88: 14348c2ecf20Sopenharmony_ci case e1000_phy_bm: 14358c2ecf20Sopenharmony_ci ret_val = e1000e_copper_link_setup_m88(hw); 14368c2ecf20Sopenharmony_ci break; 14378c2ecf20Sopenharmony_ci case e1000_phy_igp_2: 14388c2ecf20Sopenharmony_ci ret_val = e1000e_copper_link_setup_igp(hw); 14398c2ecf20Sopenharmony_ci break; 14408c2ecf20Sopenharmony_ci default: 14418c2ecf20Sopenharmony_ci return -E1000_ERR_PHY; 14428c2ecf20Sopenharmony_ci } 14438c2ecf20Sopenharmony_ci 14448c2ecf20Sopenharmony_ci if (ret_val) 14458c2ecf20Sopenharmony_ci return ret_val; 14468c2ecf20Sopenharmony_ci 14478c2ecf20Sopenharmony_ci return e1000e_setup_copper_link(hw); 14488c2ecf20Sopenharmony_ci} 14498c2ecf20Sopenharmony_ci 14508c2ecf20Sopenharmony_ci/** 14518c2ecf20Sopenharmony_ci * e1000_setup_fiber_serdes_link_82571 - Setup link for fiber/serdes 14528c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 14538c2ecf20Sopenharmony_ci * 14548c2ecf20Sopenharmony_ci * Configures collision distance and flow control for fiber and serdes links. 14558c2ecf20Sopenharmony_ci * Upon successful setup, poll for link. 14568c2ecf20Sopenharmony_ci **/ 14578c2ecf20Sopenharmony_cistatic s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) 14588c2ecf20Sopenharmony_ci{ 14598c2ecf20Sopenharmony_ci switch (hw->mac.type) { 14608c2ecf20Sopenharmony_ci case e1000_82571: 14618c2ecf20Sopenharmony_ci case e1000_82572: 14628c2ecf20Sopenharmony_ci /* If SerDes loopback mode is entered, there is no form 14638c2ecf20Sopenharmony_ci * of reset to take the adapter out of that mode. So we 14648c2ecf20Sopenharmony_ci * have to explicitly take the adapter out of loopback 14658c2ecf20Sopenharmony_ci * mode. This prevents drivers from twiddling their thumbs 14668c2ecf20Sopenharmony_ci * if another tool failed to take it out of loopback mode. 14678c2ecf20Sopenharmony_ci */ 14688c2ecf20Sopenharmony_ci ew32(SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK); 14698c2ecf20Sopenharmony_ci break; 14708c2ecf20Sopenharmony_ci default: 14718c2ecf20Sopenharmony_ci break; 14728c2ecf20Sopenharmony_ci } 14738c2ecf20Sopenharmony_ci 14748c2ecf20Sopenharmony_ci return e1000e_setup_fiber_serdes_link(hw); 14758c2ecf20Sopenharmony_ci} 14768c2ecf20Sopenharmony_ci 14778c2ecf20Sopenharmony_ci/** 14788c2ecf20Sopenharmony_ci * e1000_check_for_serdes_link_82571 - Check for link (Serdes) 14798c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 14808c2ecf20Sopenharmony_ci * 14818c2ecf20Sopenharmony_ci * Reports the link state as up or down. 14828c2ecf20Sopenharmony_ci * 14838c2ecf20Sopenharmony_ci * If autonegotiation is supported by the link partner, the link state is 14848c2ecf20Sopenharmony_ci * determined by the result of autonegotiation. This is the most likely case. 14858c2ecf20Sopenharmony_ci * If autonegotiation is not supported by the link partner, and the link 14868c2ecf20Sopenharmony_ci * has a valid signal, force the link up. 14878c2ecf20Sopenharmony_ci * 14888c2ecf20Sopenharmony_ci * The link state is represented internally here by 4 states: 14898c2ecf20Sopenharmony_ci * 14908c2ecf20Sopenharmony_ci * 1) down 14918c2ecf20Sopenharmony_ci * 2) autoneg_progress 14928c2ecf20Sopenharmony_ci * 3) autoneg_complete (the link successfully autonegotiated) 14938c2ecf20Sopenharmony_ci * 4) forced_up (the link has been forced up, it did not autonegotiate) 14948c2ecf20Sopenharmony_ci * 14958c2ecf20Sopenharmony_ci **/ 14968c2ecf20Sopenharmony_cistatic s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) 14978c2ecf20Sopenharmony_ci{ 14988c2ecf20Sopenharmony_ci struct e1000_mac_info *mac = &hw->mac; 14998c2ecf20Sopenharmony_ci u32 rxcw; 15008c2ecf20Sopenharmony_ci u32 ctrl; 15018c2ecf20Sopenharmony_ci u32 status; 15028c2ecf20Sopenharmony_ci u32 txcw; 15038c2ecf20Sopenharmony_ci u32 i; 15048c2ecf20Sopenharmony_ci s32 ret_val = 0; 15058c2ecf20Sopenharmony_ci 15068c2ecf20Sopenharmony_ci ctrl = er32(CTRL); 15078c2ecf20Sopenharmony_ci status = er32(STATUS); 15088c2ecf20Sopenharmony_ci er32(RXCW); 15098c2ecf20Sopenharmony_ci /* SYNCH bit and IV bit are sticky */ 15108c2ecf20Sopenharmony_ci usleep_range(10, 20); 15118c2ecf20Sopenharmony_ci rxcw = er32(RXCW); 15128c2ecf20Sopenharmony_ci 15138c2ecf20Sopenharmony_ci if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) { 15148c2ecf20Sopenharmony_ci /* Receiver is synchronized with no invalid bits. */ 15158c2ecf20Sopenharmony_ci switch (mac->serdes_link_state) { 15168c2ecf20Sopenharmony_ci case e1000_serdes_link_autoneg_complete: 15178c2ecf20Sopenharmony_ci if (!(status & E1000_STATUS_LU)) { 15188c2ecf20Sopenharmony_ci /* We have lost link, retry autoneg before 15198c2ecf20Sopenharmony_ci * reporting link failure 15208c2ecf20Sopenharmony_ci */ 15218c2ecf20Sopenharmony_ci mac->serdes_link_state = 15228c2ecf20Sopenharmony_ci e1000_serdes_link_autoneg_progress; 15238c2ecf20Sopenharmony_ci mac->serdes_has_link = false; 15248c2ecf20Sopenharmony_ci e_dbg("AN_UP -> AN_PROG\n"); 15258c2ecf20Sopenharmony_ci } else { 15268c2ecf20Sopenharmony_ci mac->serdes_has_link = true; 15278c2ecf20Sopenharmony_ci } 15288c2ecf20Sopenharmony_ci break; 15298c2ecf20Sopenharmony_ci 15308c2ecf20Sopenharmony_ci case e1000_serdes_link_forced_up: 15318c2ecf20Sopenharmony_ci /* If we are receiving /C/ ordered sets, re-enable 15328c2ecf20Sopenharmony_ci * auto-negotiation in the TXCW register and disable 15338c2ecf20Sopenharmony_ci * forced link in the Device Control register in an 15348c2ecf20Sopenharmony_ci * attempt to auto-negotiate with our link partner. 15358c2ecf20Sopenharmony_ci */ 15368c2ecf20Sopenharmony_ci if (rxcw & E1000_RXCW_C) { 15378c2ecf20Sopenharmony_ci /* Enable autoneg, and unforce link up */ 15388c2ecf20Sopenharmony_ci ew32(TXCW, mac->txcw); 15398c2ecf20Sopenharmony_ci ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); 15408c2ecf20Sopenharmony_ci mac->serdes_link_state = 15418c2ecf20Sopenharmony_ci e1000_serdes_link_autoneg_progress; 15428c2ecf20Sopenharmony_ci mac->serdes_has_link = false; 15438c2ecf20Sopenharmony_ci e_dbg("FORCED_UP -> AN_PROG\n"); 15448c2ecf20Sopenharmony_ci } else { 15458c2ecf20Sopenharmony_ci mac->serdes_has_link = true; 15468c2ecf20Sopenharmony_ci } 15478c2ecf20Sopenharmony_ci break; 15488c2ecf20Sopenharmony_ci 15498c2ecf20Sopenharmony_ci case e1000_serdes_link_autoneg_progress: 15508c2ecf20Sopenharmony_ci if (rxcw & E1000_RXCW_C) { 15518c2ecf20Sopenharmony_ci /* We received /C/ ordered sets, meaning the 15528c2ecf20Sopenharmony_ci * link partner has autonegotiated, and we can 15538c2ecf20Sopenharmony_ci * trust the Link Up (LU) status bit. 15548c2ecf20Sopenharmony_ci */ 15558c2ecf20Sopenharmony_ci if (status & E1000_STATUS_LU) { 15568c2ecf20Sopenharmony_ci mac->serdes_link_state = 15578c2ecf20Sopenharmony_ci e1000_serdes_link_autoneg_complete; 15588c2ecf20Sopenharmony_ci e_dbg("AN_PROG -> AN_UP\n"); 15598c2ecf20Sopenharmony_ci mac->serdes_has_link = true; 15608c2ecf20Sopenharmony_ci } else { 15618c2ecf20Sopenharmony_ci /* Autoneg completed, but failed. */ 15628c2ecf20Sopenharmony_ci mac->serdes_link_state = 15638c2ecf20Sopenharmony_ci e1000_serdes_link_down; 15648c2ecf20Sopenharmony_ci e_dbg("AN_PROG -> DOWN\n"); 15658c2ecf20Sopenharmony_ci } 15668c2ecf20Sopenharmony_ci } else { 15678c2ecf20Sopenharmony_ci /* The link partner did not autoneg. 15688c2ecf20Sopenharmony_ci * Force link up and full duplex, and change 15698c2ecf20Sopenharmony_ci * state to forced. 15708c2ecf20Sopenharmony_ci */ 15718c2ecf20Sopenharmony_ci ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); 15728c2ecf20Sopenharmony_ci ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); 15738c2ecf20Sopenharmony_ci ew32(CTRL, ctrl); 15748c2ecf20Sopenharmony_ci 15758c2ecf20Sopenharmony_ci /* Configure Flow Control after link up. */ 15768c2ecf20Sopenharmony_ci ret_val = e1000e_config_fc_after_link_up(hw); 15778c2ecf20Sopenharmony_ci if (ret_val) { 15788c2ecf20Sopenharmony_ci e_dbg("Error config flow control\n"); 15798c2ecf20Sopenharmony_ci break; 15808c2ecf20Sopenharmony_ci } 15818c2ecf20Sopenharmony_ci mac->serdes_link_state = 15828c2ecf20Sopenharmony_ci e1000_serdes_link_forced_up; 15838c2ecf20Sopenharmony_ci mac->serdes_has_link = true; 15848c2ecf20Sopenharmony_ci e_dbg("AN_PROG -> FORCED_UP\n"); 15858c2ecf20Sopenharmony_ci } 15868c2ecf20Sopenharmony_ci break; 15878c2ecf20Sopenharmony_ci 15888c2ecf20Sopenharmony_ci case e1000_serdes_link_down: 15898c2ecf20Sopenharmony_ci default: 15908c2ecf20Sopenharmony_ci /* The link was down but the receiver has now gained 15918c2ecf20Sopenharmony_ci * valid sync, so lets see if we can bring the link 15928c2ecf20Sopenharmony_ci * up. 15938c2ecf20Sopenharmony_ci */ 15948c2ecf20Sopenharmony_ci ew32(TXCW, mac->txcw); 15958c2ecf20Sopenharmony_ci ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); 15968c2ecf20Sopenharmony_ci mac->serdes_link_state = 15978c2ecf20Sopenharmony_ci e1000_serdes_link_autoneg_progress; 15988c2ecf20Sopenharmony_ci mac->serdes_has_link = false; 15998c2ecf20Sopenharmony_ci e_dbg("DOWN -> AN_PROG\n"); 16008c2ecf20Sopenharmony_ci break; 16018c2ecf20Sopenharmony_ci } 16028c2ecf20Sopenharmony_ci } else { 16038c2ecf20Sopenharmony_ci if (!(rxcw & E1000_RXCW_SYNCH)) { 16048c2ecf20Sopenharmony_ci mac->serdes_has_link = false; 16058c2ecf20Sopenharmony_ci mac->serdes_link_state = e1000_serdes_link_down; 16068c2ecf20Sopenharmony_ci e_dbg("ANYSTATE -> DOWN\n"); 16078c2ecf20Sopenharmony_ci } else { 16088c2ecf20Sopenharmony_ci /* Check several times, if SYNCH bit and CONFIG 16098c2ecf20Sopenharmony_ci * bit both are consistently 1 then simply ignore 16108c2ecf20Sopenharmony_ci * the IV bit and restart Autoneg 16118c2ecf20Sopenharmony_ci */ 16128c2ecf20Sopenharmony_ci for (i = 0; i < AN_RETRY_COUNT; i++) { 16138c2ecf20Sopenharmony_ci usleep_range(10, 20); 16148c2ecf20Sopenharmony_ci rxcw = er32(RXCW); 16158c2ecf20Sopenharmony_ci if ((rxcw & E1000_RXCW_SYNCH) && 16168c2ecf20Sopenharmony_ci (rxcw & E1000_RXCW_C)) 16178c2ecf20Sopenharmony_ci continue; 16188c2ecf20Sopenharmony_ci 16198c2ecf20Sopenharmony_ci if (rxcw & E1000_RXCW_IV) { 16208c2ecf20Sopenharmony_ci mac->serdes_has_link = false; 16218c2ecf20Sopenharmony_ci mac->serdes_link_state = 16228c2ecf20Sopenharmony_ci e1000_serdes_link_down; 16238c2ecf20Sopenharmony_ci e_dbg("ANYSTATE -> DOWN\n"); 16248c2ecf20Sopenharmony_ci break; 16258c2ecf20Sopenharmony_ci } 16268c2ecf20Sopenharmony_ci } 16278c2ecf20Sopenharmony_ci 16288c2ecf20Sopenharmony_ci if (i == AN_RETRY_COUNT) { 16298c2ecf20Sopenharmony_ci txcw = er32(TXCW); 16308c2ecf20Sopenharmony_ci txcw |= E1000_TXCW_ANE; 16318c2ecf20Sopenharmony_ci ew32(TXCW, txcw); 16328c2ecf20Sopenharmony_ci mac->serdes_link_state = 16338c2ecf20Sopenharmony_ci e1000_serdes_link_autoneg_progress; 16348c2ecf20Sopenharmony_ci mac->serdes_has_link = false; 16358c2ecf20Sopenharmony_ci e_dbg("ANYSTATE -> AN_PROG\n"); 16368c2ecf20Sopenharmony_ci } 16378c2ecf20Sopenharmony_ci } 16388c2ecf20Sopenharmony_ci } 16398c2ecf20Sopenharmony_ci 16408c2ecf20Sopenharmony_ci return ret_val; 16418c2ecf20Sopenharmony_ci} 16428c2ecf20Sopenharmony_ci 16438c2ecf20Sopenharmony_ci/** 16448c2ecf20Sopenharmony_ci * e1000_valid_led_default_82571 - Verify a valid default LED config 16458c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 16468c2ecf20Sopenharmony_ci * @data: pointer to the NVM (EEPROM) 16478c2ecf20Sopenharmony_ci * 16488c2ecf20Sopenharmony_ci * Read the EEPROM for the current default LED configuration. If the 16498c2ecf20Sopenharmony_ci * LED configuration is not valid, set to a valid LED configuration. 16508c2ecf20Sopenharmony_ci **/ 16518c2ecf20Sopenharmony_cistatic s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data) 16528c2ecf20Sopenharmony_ci{ 16538c2ecf20Sopenharmony_ci s32 ret_val; 16548c2ecf20Sopenharmony_ci 16558c2ecf20Sopenharmony_ci ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data); 16568c2ecf20Sopenharmony_ci if (ret_val) { 16578c2ecf20Sopenharmony_ci e_dbg("NVM Read Error\n"); 16588c2ecf20Sopenharmony_ci return ret_val; 16598c2ecf20Sopenharmony_ci } 16608c2ecf20Sopenharmony_ci 16618c2ecf20Sopenharmony_ci switch (hw->mac.type) { 16628c2ecf20Sopenharmony_ci case e1000_82573: 16638c2ecf20Sopenharmony_ci case e1000_82574: 16648c2ecf20Sopenharmony_ci case e1000_82583: 16658c2ecf20Sopenharmony_ci if (*data == ID_LED_RESERVED_F746) 16668c2ecf20Sopenharmony_ci *data = ID_LED_DEFAULT_82573; 16678c2ecf20Sopenharmony_ci break; 16688c2ecf20Sopenharmony_ci default: 16698c2ecf20Sopenharmony_ci if (*data == ID_LED_RESERVED_0000 || 16708c2ecf20Sopenharmony_ci *data == ID_LED_RESERVED_FFFF) 16718c2ecf20Sopenharmony_ci *data = ID_LED_DEFAULT; 16728c2ecf20Sopenharmony_ci break; 16738c2ecf20Sopenharmony_ci } 16748c2ecf20Sopenharmony_ci 16758c2ecf20Sopenharmony_ci return 0; 16768c2ecf20Sopenharmony_ci} 16778c2ecf20Sopenharmony_ci 16788c2ecf20Sopenharmony_ci/** 16798c2ecf20Sopenharmony_ci * e1000e_get_laa_state_82571 - Get locally administered address state 16808c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 16818c2ecf20Sopenharmony_ci * 16828c2ecf20Sopenharmony_ci * Retrieve and return the current locally administered address state. 16838c2ecf20Sopenharmony_ci **/ 16848c2ecf20Sopenharmony_cibool e1000e_get_laa_state_82571(struct e1000_hw *hw) 16858c2ecf20Sopenharmony_ci{ 16868c2ecf20Sopenharmony_ci if (hw->mac.type != e1000_82571) 16878c2ecf20Sopenharmony_ci return false; 16888c2ecf20Sopenharmony_ci 16898c2ecf20Sopenharmony_ci return hw->dev_spec.e82571.laa_is_present; 16908c2ecf20Sopenharmony_ci} 16918c2ecf20Sopenharmony_ci 16928c2ecf20Sopenharmony_ci/** 16938c2ecf20Sopenharmony_ci * e1000e_set_laa_state_82571 - Set locally administered address state 16948c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 16958c2ecf20Sopenharmony_ci * @state: enable/disable locally administered address 16968c2ecf20Sopenharmony_ci * 16978c2ecf20Sopenharmony_ci * Enable/Disable the current locally administered address state. 16988c2ecf20Sopenharmony_ci **/ 16998c2ecf20Sopenharmony_civoid e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state) 17008c2ecf20Sopenharmony_ci{ 17018c2ecf20Sopenharmony_ci if (hw->mac.type != e1000_82571) 17028c2ecf20Sopenharmony_ci return; 17038c2ecf20Sopenharmony_ci 17048c2ecf20Sopenharmony_ci hw->dev_spec.e82571.laa_is_present = state; 17058c2ecf20Sopenharmony_ci 17068c2ecf20Sopenharmony_ci /* If workaround is activated... */ 17078c2ecf20Sopenharmony_ci if (state) 17088c2ecf20Sopenharmony_ci /* Hold a copy of the LAA in RAR[14] This is done so that 17098c2ecf20Sopenharmony_ci * between the time RAR[0] gets clobbered and the time it 17108c2ecf20Sopenharmony_ci * gets fixed, the actual LAA is in one of the RARs and no 17118c2ecf20Sopenharmony_ci * incoming packets directed to this port are dropped. 17128c2ecf20Sopenharmony_ci * Eventually the LAA will be in RAR[0] and RAR[14]. 17138c2ecf20Sopenharmony_ci */ 17148c2ecf20Sopenharmony_ci hw->mac.ops.rar_set(hw, hw->mac.addr, 17158c2ecf20Sopenharmony_ci hw->mac.rar_entry_count - 1); 17168c2ecf20Sopenharmony_ci} 17178c2ecf20Sopenharmony_ci 17188c2ecf20Sopenharmony_ci/** 17198c2ecf20Sopenharmony_ci * e1000_fix_nvm_checksum_82571 - Fix EEPROM checksum 17208c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 17218c2ecf20Sopenharmony_ci * 17228c2ecf20Sopenharmony_ci * Verifies that the EEPROM has completed the update. After updating the 17238c2ecf20Sopenharmony_ci * EEPROM, we need to check bit 15 in work 0x23 for the checksum fix. If 17248c2ecf20Sopenharmony_ci * the checksum fix is not implemented, we need to set the bit and update 17258c2ecf20Sopenharmony_ci * the checksum. Otherwise, if bit 15 is set and the checksum is incorrect, 17268c2ecf20Sopenharmony_ci * we need to return bad checksum. 17278c2ecf20Sopenharmony_ci **/ 17288c2ecf20Sopenharmony_cistatic s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw) 17298c2ecf20Sopenharmony_ci{ 17308c2ecf20Sopenharmony_ci struct e1000_nvm_info *nvm = &hw->nvm; 17318c2ecf20Sopenharmony_ci s32 ret_val; 17328c2ecf20Sopenharmony_ci u16 data; 17338c2ecf20Sopenharmony_ci 17348c2ecf20Sopenharmony_ci if (nvm->type != e1000_nvm_flash_hw) 17358c2ecf20Sopenharmony_ci return 0; 17368c2ecf20Sopenharmony_ci 17378c2ecf20Sopenharmony_ci /* Check bit 4 of word 10h. If it is 0, firmware is done updating 17388c2ecf20Sopenharmony_ci * 10h-12h. Checksum may need to be fixed. 17398c2ecf20Sopenharmony_ci */ 17408c2ecf20Sopenharmony_ci ret_val = e1000_read_nvm(hw, 0x10, 1, &data); 17418c2ecf20Sopenharmony_ci if (ret_val) 17428c2ecf20Sopenharmony_ci return ret_val; 17438c2ecf20Sopenharmony_ci 17448c2ecf20Sopenharmony_ci if (!(data & 0x10)) { 17458c2ecf20Sopenharmony_ci /* Read 0x23 and check bit 15. This bit is a 1 17468c2ecf20Sopenharmony_ci * when the checksum has already been fixed. If 17478c2ecf20Sopenharmony_ci * the checksum is still wrong and this bit is a 17488c2ecf20Sopenharmony_ci * 1, we need to return bad checksum. Otherwise, 17498c2ecf20Sopenharmony_ci * we need to set this bit to a 1 and update the 17508c2ecf20Sopenharmony_ci * checksum. 17518c2ecf20Sopenharmony_ci */ 17528c2ecf20Sopenharmony_ci ret_val = e1000_read_nvm(hw, 0x23, 1, &data); 17538c2ecf20Sopenharmony_ci if (ret_val) 17548c2ecf20Sopenharmony_ci return ret_val; 17558c2ecf20Sopenharmony_ci 17568c2ecf20Sopenharmony_ci if (!(data & 0x8000)) { 17578c2ecf20Sopenharmony_ci data |= 0x8000; 17588c2ecf20Sopenharmony_ci ret_val = e1000_write_nvm(hw, 0x23, 1, &data); 17598c2ecf20Sopenharmony_ci if (ret_val) 17608c2ecf20Sopenharmony_ci return ret_val; 17618c2ecf20Sopenharmony_ci ret_val = e1000e_update_nvm_checksum(hw); 17628c2ecf20Sopenharmony_ci if (ret_val) 17638c2ecf20Sopenharmony_ci return ret_val; 17648c2ecf20Sopenharmony_ci } 17658c2ecf20Sopenharmony_ci } 17668c2ecf20Sopenharmony_ci 17678c2ecf20Sopenharmony_ci return 0; 17688c2ecf20Sopenharmony_ci} 17698c2ecf20Sopenharmony_ci 17708c2ecf20Sopenharmony_ci/** 17718c2ecf20Sopenharmony_ci * e1000_read_mac_addr_82571 - Read device MAC address 17728c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 17738c2ecf20Sopenharmony_ci **/ 17748c2ecf20Sopenharmony_cistatic s32 e1000_read_mac_addr_82571(struct e1000_hw *hw) 17758c2ecf20Sopenharmony_ci{ 17768c2ecf20Sopenharmony_ci if (hw->mac.type == e1000_82571) { 17778c2ecf20Sopenharmony_ci s32 ret_val; 17788c2ecf20Sopenharmony_ci 17798c2ecf20Sopenharmony_ci /* If there's an alternate MAC address place it in RAR0 17808c2ecf20Sopenharmony_ci * so that it will override the Si installed default perm 17818c2ecf20Sopenharmony_ci * address. 17828c2ecf20Sopenharmony_ci */ 17838c2ecf20Sopenharmony_ci ret_val = e1000_check_alt_mac_addr_generic(hw); 17848c2ecf20Sopenharmony_ci if (ret_val) 17858c2ecf20Sopenharmony_ci return ret_val; 17868c2ecf20Sopenharmony_ci } 17878c2ecf20Sopenharmony_ci 17888c2ecf20Sopenharmony_ci return e1000_read_mac_addr_generic(hw); 17898c2ecf20Sopenharmony_ci} 17908c2ecf20Sopenharmony_ci 17918c2ecf20Sopenharmony_ci/** 17928c2ecf20Sopenharmony_ci * e1000_power_down_phy_copper_82571 - Remove link during PHY power down 17938c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 17948c2ecf20Sopenharmony_ci * 17958c2ecf20Sopenharmony_ci * In the case of a PHY power down to save power, or to turn off link during a 17968c2ecf20Sopenharmony_ci * driver unload, or wake on lan is not enabled, remove the link. 17978c2ecf20Sopenharmony_ci **/ 17988c2ecf20Sopenharmony_cistatic void e1000_power_down_phy_copper_82571(struct e1000_hw *hw) 17998c2ecf20Sopenharmony_ci{ 18008c2ecf20Sopenharmony_ci struct e1000_phy_info *phy = &hw->phy; 18018c2ecf20Sopenharmony_ci struct e1000_mac_info *mac = &hw->mac; 18028c2ecf20Sopenharmony_ci 18038c2ecf20Sopenharmony_ci if (!phy->ops.check_reset_block) 18048c2ecf20Sopenharmony_ci return; 18058c2ecf20Sopenharmony_ci 18068c2ecf20Sopenharmony_ci /* If the management interface is not enabled, then power down */ 18078c2ecf20Sopenharmony_ci if (!(mac->ops.check_mng_mode(hw) || phy->ops.check_reset_block(hw))) 18088c2ecf20Sopenharmony_ci e1000_power_down_phy_copper(hw); 18098c2ecf20Sopenharmony_ci} 18108c2ecf20Sopenharmony_ci 18118c2ecf20Sopenharmony_ci/** 18128c2ecf20Sopenharmony_ci * e1000_clear_hw_cntrs_82571 - Clear device specific hardware counters 18138c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 18148c2ecf20Sopenharmony_ci * 18158c2ecf20Sopenharmony_ci * Clears the hardware counters by reading the counter registers. 18168c2ecf20Sopenharmony_ci **/ 18178c2ecf20Sopenharmony_cistatic void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw) 18188c2ecf20Sopenharmony_ci{ 18198c2ecf20Sopenharmony_ci e1000e_clear_hw_cntrs_base(hw); 18208c2ecf20Sopenharmony_ci 18218c2ecf20Sopenharmony_ci er32(PRC64); 18228c2ecf20Sopenharmony_ci er32(PRC127); 18238c2ecf20Sopenharmony_ci er32(PRC255); 18248c2ecf20Sopenharmony_ci er32(PRC511); 18258c2ecf20Sopenharmony_ci er32(PRC1023); 18268c2ecf20Sopenharmony_ci er32(PRC1522); 18278c2ecf20Sopenharmony_ci er32(PTC64); 18288c2ecf20Sopenharmony_ci er32(PTC127); 18298c2ecf20Sopenharmony_ci er32(PTC255); 18308c2ecf20Sopenharmony_ci er32(PTC511); 18318c2ecf20Sopenharmony_ci er32(PTC1023); 18328c2ecf20Sopenharmony_ci er32(PTC1522); 18338c2ecf20Sopenharmony_ci 18348c2ecf20Sopenharmony_ci er32(ALGNERRC); 18358c2ecf20Sopenharmony_ci er32(RXERRC); 18368c2ecf20Sopenharmony_ci er32(TNCRS); 18378c2ecf20Sopenharmony_ci er32(CEXTERR); 18388c2ecf20Sopenharmony_ci er32(TSCTC); 18398c2ecf20Sopenharmony_ci er32(TSCTFC); 18408c2ecf20Sopenharmony_ci 18418c2ecf20Sopenharmony_ci er32(MGTPRC); 18428c2ecf20Sopenharmony_ci er32(MGTPDC); 18438c2ecf20Sopenharmony_ci er32(MGTPTC); 18448c2ecf20Sopenharmony_ci 18458c2ecf20Sopenharmony_ci er32(IAC); 18468c2ecf20Sopenharmony_ci er32(ICRXOC); 18478c2ecf20Sopenharmony_ci 18488c2ecf20Sopenharmony_ci er32(ICRXPTC); 18498c2ecf20Sopenharmony_ci er32(ICRXATC); 18508c2ecf20Sopenharmony_ci er32(ICTXPTC); 18518c2ecf20Sopenharmony_ci er32(ICTXATC); 18528c2ecf20Sopenharmony_ci er32(ICTXQEC); 18538c2ecf20Sopenharmony_ci er32(ICTXQMTC); 18548c2ecf20Sopenharmony_ci er32(ICRXDMTC); 18558c2ecf20Sopenharmony_ci} 18568c2ecf20Sopenharmony_ci 18578c2ecf20Sopenharmony_cistatic const struct e1000_mac_operations e82571_mac_ops = { 18588c2ecf20Sopenharmony_ci /* .check_mng_mode: mac type dependent */ 18598c2ecf20Sopenharmony_ci /* .check_for_link: media type dependent */ 18608c2ecf20Sopenharmony_ci .id_led_init = e1000e_id_led_init_generic, 18618c2ecf20Sopenharmony_ci .cleanup_led = e1000e_cleanup_led_generic, 18628c2ecf20Sopenharmony_ci .clear_hw_cntrs = e1000_clear_hw_cntrs_82571, 18638c2ecf20Sopenharmony_ci .get_bus_info = e1000e_get_bus_info_pcie, 18648c2ecf20Sopenharmony_ci .set_lan_id = e1000_set_lan_id_multi_port_pcie, 18658c2ecf20Sopenharmony_ci /* .get_link_up_info: media type dependent */ 18668c2ecf20Sopenharmony_ci /* .led_on: mac type dependent */ 18678c2ecf20Sopenharmony_ci .led_off = e1000e_led_off_generic, 18688c2ecf20Sopenharmony_ci .update_mc_addr_list = e1000e_update_mc_addr_list_generic, 18698c2ecf20Sopenharmony_ci .write_vfta = e1000_write_vfta_generic, 18708c2ecf20Sopenharmony_ci .clear_vfta = e1000_clear_vfta_82571, 18718c2ecf20Sopenharmony_ci .reset_hw = e1000_reset_hw_82571, 18728c2ecf20Sopenharmony_ci .init_hw = e1000_init_hw_82571, 18738c2ecf20Sopenharmony_ci .setup_link = e1000_setup_link_82571, 18748c2ecf20Sopenharmony_ci /* .setup_physical_interface: media type dependent */ 18758c2ecf20Sopenharmony_ci .setup_led = e1000e_setup_led_generic, 18768c2ecf20Sopenharmony_ci .config_collision_dist = e1000e_config_collision_dist_generic, 18778c2ecf20Sopenharmony_ci .read_mac_addr = e1000_read_mac_addr_82571, 18788c2ecf20Sopenharmony_ci .rar_set = e1000e_rar_set_generic, 18798c2ecf20Sopenharmony_ci .rar_get_count = e1000e_rar_get_count_generic, 18808c2ecf20Sopenharmony_ci}; 18818c2ecf20Sopenharmony_ci 18828c2ecf20Sopenharmony_cistatic const struct e1000_phy_operations e82_phy_ops_igp = { 18838c2ecf20Sopenharmony_ci .acquire = e1000_get_hw_semaphore_82571, 18848c2ecf20Sopenharmony_ci .check_polarity = e1000_check_polarity_igp, 18858c2ecf20Sopenharmony_ci .check_reset_block = e1000e_check_reset_block_generic, 18868c2ecf20Sopenharmony_ci .commit = NULL, 18878c2ecf20Sopenharmony_ci .force_speed_duplex = e1000e_phy_force_speed_duplex_igp, 18888c2ecf20Sopenharmony_ci .get_cfg_done = e1000_get_cfg_done_82571, 18898c2ecf20Sopenharmony_ci .get_cable_length = e1000e_get_cable_length_igp_2, 18908c2ecf20Sopenharmony_ci .get_info = e1000e_get_phy_info_igp, 18918c2ecf20Sopenharmony_ci .read_reg = e1000e_read_phy_reg_igp, 18928c2ecf20Sopenharmony_ci .release = e1000_put_hw_semaphore_82571, 18938c2ecf20Sopenharmony_ci .reset = e1000e_phy_hw_reset_generic, 18948c2ecf20Sopenharmony_ci .set_d0_lplu_state = e1000_set_d0_lplu_state_82571, 18958c2ecf20Sopenharmony_ci .set_d3_lplu_state = e1000e_set_d3_lplu_state, 18968c2ecf20Sopenharmony_ci .write_reg = e1000e_write_phy_reg_igp, 18978c2ecf20Sopenharmony_ci .cfg_on_link_up = NULL, 18988c2ecf20Sopenharmony_ci}; 18998c2ecf20Sopenharmony_ci 19008c2ecf20Sopenharmony_cistatic const struct e1000_phy_operations e82_phy_ops_m88 = { 19018c2ecf20Sopenharmony_ci .acquire = e1000_get_hw_semaphore_82571, 19028c2ecf20Sopenharmony_ci .check_polarity = e1000_check_polarity_m88, 19038c2ecf20Sopenharmony_ci .check_reset_block = e1000e_check_reset_block_generic, 19048c2ecf20Sopenharmony_ci .commit = e1000e_phy_sw_reset, 19058c2ecf20Sopenharmony_ci .force_speed_duplex = e1000e_phy_force_speed_duplex_m88, 19068c2ecf20Sopenharmony_ci .get_cfg_done = e1000e_get_cfg_done_generic, 19078c2ecf20Sopenharmony_ci .get_cable_length = e1000e_get_cable_length_m88, 19088c2ecf20Sopenharmony_ci .get_info = e1000e_get_phy_info_m88, 19098c2ecf20Sopenharmony_ci .read_reg = e1000e_read_phy_reg_m88, 19108c2ecf20Sopenharmony_ci .release = e1000_put_hw_semaphore_82571, 19118c2ecf20Sopenharmony_ci .reset = e1000e_phy_hw_reset_generic, 19128c2ecf20Sopenharmony_ci .set_d0_lplu_state = e1000_set_d0_lplu_state_82571, 19138c2ecf20Sopenharmony_ci .set_d3_lplu_state = e1000e_set_d3_lplu_state, 19148c2ecf20Sopenharmony_ci .write_reg = e1000e_write_phy_reg_m88, 19158c2ecf20Sopenharmony_ci .cfg_on_link_up = NULL, 19168c2ecf20Sopenharmony_ci}; 19178c2ecf20Sopenharmony_ci 19188c2ecf20Sopenharmony_cistatic const struct e1000_phy_operations e82_phy_ops_bm = { 19198c2ecf20Sopenharmony_ci .acquire = e1000_get_hw_semaphore_82571, 19208c2ecf20Sopenharmony_ci .check_polarity = e1000_check_polarity_m88, 19218c2ecf20Sopenharmony_ci .check_reset_block = e1000e_check_reset_block_generic, 19228c2ecf20Sopenharmony_ci .commit = e1000e_phy_sw_reset, 19238c2ecf20Sopenharmony_ci .force_speed_duplex = e1000e_phy_force_speed_duplex_m88, 19248c2ecf20Sopenharmony_ci .get_cfg_done = e1000e_get_cfg_done_generic, 19258c2ecf20Sopenharmony_ci .get_cable_length = e1000e_get_cable_length_m88, 19268c2ecf20Sopenharmony_ci .get_info = e1000e_get_phy_info_m88, 19278c2ecf20Sopenharmony_ci .read_reg = e1000e_read_phy_reg_bm2, 19288c2ecf20Sopenharmony_ci .release = e1000_put_hw_semaphore_82571, 19298c2ecf20Sopenharmony_ci .reset = e1000e_phy_hw_reset_generic, 19308c2ecf20Sopenharmony_ci .set_d0_lplu_state = e1000_set_d0_lplu_state_82571, 19318c2ecf20Sopenharmony_ci .set_d3_lplu_state = e1000e_set_d3_lplu_state, 19328c2ecf20Sopenharmony_ci .write_reg = e1000e_write_phy_reg_bm2, 19338c2ecf20Sopenharmony_ci .cfg_on_link_up = NULL, 19348c2ecf20Sopenharmony_ci}; 19358c2ecf20Sopenharmony_ci 19368c2ecf20Sopenharmony_cistatic const struct e1000_nvm_operations e82571_nvm_ops = { 19378c2ecf20Sopenharmony_ci .acquire = e1000_acquire_nvm_82571, 19388c2ecf20Sopenharmony_ci .read = e1000e_read_nvm_eerd, 19398c2ecf20Sopenharmony_ci .release = e1000_release_nvm_82571, 19408c2ecf20Sopenharmony_ci .reload = e1000e_reload_nvm_generic, 19418c2ecf20Sopenharmony_ci .update = e1000_update_nvm_checksum_82571, 19428c2ecf20Sopenharmony_ci .valid_led_default = e1000_valid_led_default_82571, 19438c2ecf20Sopenharmony_ci .validate = e1000_validate_nvm_checksum_82571, 19448c2ecf20Sopenharmony_ci .write = e1000_write_nvm_82571, 19458c2ecf20Sopenharmony_ci}; 19468c2ecf20Sopenharmony_ci 19478c2ecf20Sopenharmony_ciconst struct e1000_info e1000_82571_info = { 19488c2ecf20Sopenharmony_ci .mac = e1000_82571, 19498c2ecf20Sopenharmony_ci .flags = FLAG_HAS_HW_VLAN_FILTER 19508c2ecf20Sopenharmony_ci | FLAG_HAS_JUMBO_FRAMES 19518c2ecf20Sopenharmony_ci | FLAG_HAS_WOL 19528c2ecf20Sopenharmony_ci | FLAG_APME_IN_CTRL3 19538c2ecf20Sopenharmony_ci | FLAG_HAS_CTRLEXT_ON_LOAD 19548c2ecf20Sopenharmony_ci | FLAG_HAS_SMART_POWER_DOWN 19558c2ecf20Sopenharmony_ci | FLAG_RESET_OVERWRITES_LAA /* errata */ 19568c2ecf20Sopenharmony_ci | FLAG_TARC_SPEED_MODE_BIT /* errata */ 19578c2ecf20Sopenharmony_ci | FLAG_APME_CHECK_PORT_B, 19588c2ecf20Sopenharmony_ci .flags2 = FLAG2_DISABLE_ASPM_L1 /* errata 13 */ 19598c2ecf20Sopenharmony_ci | FLAG2_DMA_BURST, 19608c2ecf20Sopenharmony_ci .pba = 38, 19618c2ecf20Sopenharmony_ci .max_hw_frame_size = DEFAULT_JUMBO, 19628c2ecf20Sopenharmony_ci .get_variants = e1000_get_variants_82571, 19638c2ecf20Sopenharmony_ci .mac_ops = &e82571_mac_ops, 19648c2ecf20Sopenharmony_ci .phy_ops = &e82_phy_ops_igp, 19658c2ecf20Sopenharmony_ci .nvm_ops = &e82571_nvm_ops, 19668c2ecf20Sopenharmony_ci}; 19678c2ecf20Sopenharmony_ci 19688c2ecf20Sopenharmony_ciconst struct e1000_info e1000_82572_info = { 19698c2ecf20Sopenharmony_ci .mac = e1000_82572, 19708c2ecf20Sopenharmony_ci .flags = FLAG_HAS_HW_VLAN_FILTER 19718c2ecf20Sopenharmony_ci | FLAG_HAS_JUMBO_FRAMES 19728c2ecf20Sopenharmony_ci | FLAG_HAS_WOL 19738c2ecf20Sopenharmony_ci | FLAG_APME_IN_CTRL3 19748c2ecf20Sopenharmony_ci | FLAG_HAS_CTRLEXT_ON_LOAD 19758c2ecf20Sopenharmony_ci | FLAG_TARC_SPEED_MODE_BIT, /* errata */ 19768c2ecf20Sopenharmony_ci .flags2 = FLAG2_DISABLE_ASPM_L1 /* errata 13 */ 19778c2ecf20Sopenharmony_ci | FLAG2_DMA_BURST, 19788c2ecf20Sopenharmony_ci .pba = 38, 19798c2ecf20Sopenharmony_ci .max_hw_frame_size = DEFAULT_JUMBO, 19808c2ecf20Sopenharmony_ci .get_variants = e1000_get_variants_82571, 19818c2ecf20Sopenharmony_ci .mac_ops = &e82571_mac_ops, 19828c2ecf20Sopenharmony_ci .phy_ops = &e82_phy_ops_igp, 19838c2ecf20Sopenharmony_ci .nvm_ops = &e82571_nvm_ops, 19848c2ecf20Sopenharmony_ci}; 19858c2ecf20Sopenharmony_ci 19868c2ecf20Sopenharmony_ciconst struct e1000_info e1000_82573_info = { 19878c2ecf20Sopenharmony_ci .mac = e1000_82573, 19888c2ecf20Sopenharmony_ci .flags = FLAG_HAS_HW_VLAN_FILTER 19898c2ecf20Sopenharmony_ci | FLAG_HAS_WOL 19908c2ecf20Sopenharmony_ci | FLAG_APME_IN_CTRL3 19918c2ecf20Sopenharmony_ci | FLAG_HAS_SMART_POWER_DOWN 19928c2ecf20Sopenharmony_ci | FLAG_HAS_AMT 19938c2ecf20Sopenharmony_ci | FLAG_HAS_SWSM_ON_LOAD, 19948c2ecf20Sopenharmony_ci .flags2 = FLAG2_DISABLE_ASPM_L1 19958c2ecf20Sopenharmony_ci | FLAG2_DISABLE_ASPM_L0S, 19968c2ecf20Sopenharmony_ci .pba = 20, 19978c2ecf20Sopenharmony_ci .max_hw_frame_size = VLAN_ETH_FRAME_LEN + ETH_FCS_LEN, 19988c2ecf20Sopenharmony_ci .get_variants = e1000_get_variants_82571, 19998c2ecf20Sopenharmony_ci .mac_ops = &e82571_mac_ops, 20008c2ecf20Sopenharmony_ci .phy_ops = &e82_phy_ops_m88, 20018c2ecf20Sopenharmony_ci .nvm_ops = &e82571_nvm_ops, 20028c2ecf20Sopenharmony_ci}; 20038c2ecf20Sopenharmony_ci 20048c2ecf20Sopenharmony_ciconst struct e1000_info e1000_82574_info = { 20058c2ecf20Sopenharmony_ci .mac = e1000_82574, 20068c2ecf20Sopenharmony_ci .flags = FLAG_HAS_HW_VLAN_FILTER 20078c2ecf20Sopenharmony_ci | FLAG_HAS_MSIX 20088c2ecf20Sopenharmony_ci | FLAG_HAS_JUMBO_FRAMES 20098c2ecf20Sopenharmony_ci | FLAG_HAS_WOL 20108c2ecf20Sopenharmony_ci | FLAG_HAS_HW_TIMESTAMP 20118c2ecf20Sopenharmony_ci | FLAG_APME_IN_CTRL3 20128c2ecf20Sopenharmony_ci | FLAG_HAS_SMART_POWER_DOWN 20138c2ecf20Sopenharmony_ci | FLAG_HAS_AMT 20148c2ecf20Sopenharmony_ci | FLAG_HAS_CTRLEXT_ON_LOAD, 20158c2ecf20Sopenharmony_ci .flags2 = FLAG2_CHECK_PHY_HANG 20168c2ecf20Sopenharmony_ci | FLAG2_DISABLE_ASPM_L0S 20178c2ecf20Sopenharmony_ci | FLAG2_DISABLE_ASPM_L1 20188c2ecf20Sopenharmony_ci | FLAG2_NO_DISABLE_RX 20198c2ecf20Sopenharmony_ci | FLAG2_DMA_BURST 20208c2ecf20Sopenharmony_ci | FLAG2_CHECK_SYSTIM_OVERFLOW, 20218c2ecf20Sopenharmony_ci .pba = 32, 20228c2ecf20Sopenharmony_ci .max_hw_frame_size = DEFAULT_JUMBO, 20238c2ecf20Sopenharmony_ci .get_variants = e1000_get_variants_82571, 20248c2ecf20Sopenharmony_ci .mac_ops = &e82571_mac_ops, 20258c2ecf20Sopenharmony_ci .phy_ops = &e82_phy_ops_bm, 20268c2ecf20Sopenharmony_ci .nvm_ops = &e82571_nvm_ops, 20278c2ecf20Sopenharmony_ci}; 20288c2ecf20Sopenharmony_ci 20298c2ecf20Sopenharmony_ciconst struct e1000_info e1000_82583_info = { 20308c2ecf20Sopenharmony_ci .mac = e1000_82583, 20318c2ecf20Sopenharmony_ci .flags = FLAG_HAS_HW_VLAN_FILTER 20328c2ecf20Sopenharmony_ci | FLAG_HAS_WOL 20338c2ecf20Sopenharmony_ci | FLAG_HAS_HW_TIMESTAMP 20348c2ecf20Sopenharmony_ci | FLAG_APME_IN_CTRL3 20358c2ecf20Sopenharmony_ci | FLAG_HAS_SMART_POWER_DOWN 20368c2ecf20Sopenharmony_ci | FLAG_HAS_AMT 20378c2ecf20Sopenharmony_ci | FLAG_HAS_JUMBO_FRAMES 20388c2ecf20Sopenharmony_ci | FLAG_HAS_CTRLEXT_ON_LOAD, 20398c2ecf20Sopenharmony_ci .flags2 = FLAG2_DISABLE_ASPM_L0S 20408c2ecf20Sopenharmony_ci | FLAG2_DISABLE_ASPM_L1 20418c2ecf20Sopenharmony_ci | FLAG2_NO_DISABLE_RX 20428c2ecf20Sopenharmony_ci | FLAG2_CHECK_SYSTIM_OVERFLOW, 20438c2ecf20Sopenharmony_ci .pba = 32, 20448c2ecf20Sopenharmony_ci .max_hw_frame_size = DEFAULT_JUMBO, 20458c2ecf20Sopenharmony_ci .get_variants = e1000_get_variants_82571, 20468c2ecf20Sopenharmony_ci .mac_ops = &e82571_mac_ops, 20478c2ecf20Sopenharmony_ci .phy_ops = &e82_phy_ops_bm, 20488c2ecf20Sopenharmony_ci .nvm_ops = &e82571_nvm_ops, 20498c2ecf20Sopenharmony_ci}; 2050