Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(c) 2015-2025 Beijing WangXun Technology Co., Ltd. 3 : : * Copyright(c) 2010-2017 Intel Corporation 4 : : */ 5 : : 6 : : #include "txgbe_type.h" 7 : : #include "txgbe_mbx.h" 8 : : #include "txgbe_phy.h" 9 : : #include "txgbe_dcb.h" 10 : : #include "txgbe_vf.h" 11 : : #include "txgbe_eeprom.h" 12 : : #include "txgbe_mng.h" 13 : : #include "txgbe_hw.h" 14 : : #include "txgbe_aml.h" 15 : : #include "txgbe_aml40.h" 16 : : #include "txgbe_e56.h" 17 : : #include "txgbe_e56_bp.h" 18 : : 19 : 0 : void txgbe_init_ops_aml40(struct txgbe_hw *hw) 20 : : { 21 : : struct txgbe_mac_info *mac = &hw->mac; 22 : : struct txgbe_phy_info *phy = &hw->phy; 23 : : struct txgbe_mbx_info *mbx = &hw->mbx; 24 : : 25 : 0 : txgbe_init_ops_generic(hw); 26 : : 27 : : /* PHY */ 28 : 0 : phy->get_media_type = txgbe_get_media_type_aml40; 29 : 0 : phy->setup_link_core = txgbe_setup_phy_link_aml40; 30 : : 31 : : /* LINK */ 32 : 0 : mac->init_mac_link_ops = txgbe_init_mac_link_ops_aml40; 33 : 0 : mac->get_link_capabilities = txgbe_get_link_capabilities_aml40; 34 : 0 : mac->check_link = txgbe_check_mac_link_aml40; 35 : : 36 : : /* FW interaction */ 37 : 0 : mbx->host_interface_command = txgbe_host_interface_command_aml; 38 : 0 : } 39 : : 40 : 0 : s32 txgbe_check_mac_link_aml40(struct txgbe_hw *hw, u32 *speed, 41 : : bool *link_up, bool link_up_wait_to_complete) 42 : : { 43 : : u32 links_reg, links_orig; 44 : : u32 i; 45 : : 46 : : /* clear the old state */ 47 : : links_orig = rd32(hw, TXGBE_PORTSTAT); 48 : : 49 : : links_reg = rd32(hw, TXGBE_PORTSTAT); 50 : : 51 [ # # ]: 0 : if (links_orig != links_reg) { 52 : 0 : DEBUGOUT("LINKS changed from %08X to %08X", 53 : : links_orig, links_reg); 54 : : } 55 : : 56 [ # # ]: 0 : if (link_up_wait_to_complete) { 57 [ # # ]: 0 : for (i = 0; i < hw->mac.max_link_up_time; i++) { 58 [ # # ]: 0 : if (!hw->link_valid) { 59 : 0 : *link_up = false; 60 : : 61 : : msleep(100); 62 : 0 : continue; 63 : : } 64 : : 65 [ # # ]: 0 : if (!(links_reg & TXGBE_PORTSTAT_UP)) { 66 : 0 : *link_up = false; 67 : : } else { 68 : 0 : *link_up = true; 69 : 0 : break; 70 : : } 71 : : msec_delay(100); 72 : : links_reg = rd32(hw, TXGBE_PORTSTAT); 73 : : } 74 : : } else { 75 [ # # ]: 0 : if (links_reg & TXGBE_PORTSTAT_UP) 76 : 0 : *link_up = true; 77 : : else 78 : 0 : *link_up = false; 79 : : } 80 : : 81 [ # # ]: 0 : if (!hw->link_valid) 82 : 0 : *link_up = false; 83 : : 84 [ # # ]: 0 : if (*link_up) { 85 [ # # ]: 0 : if ((links_reg & TXGBE_CFG_PORT_ST_AML_LINK_40G) == 86 : : TXGBE_CFG_PORT_ST_AML_LINK_40G) 87 : 0 : *speed = TXGBE_LINK_SPEED_40GB_FULL; 88 : : } else { 89 : 0 : *speed = TXGBE_LINK_SPEED_UNKNOWN; 90 : : } 91 : : 92 : 0 : return 0; 93 : : } 94 : : 95 : 0 : s32 txgbe_get_link_capabilities_aml40(struct txgbe_hw *hw, 96 : : u32 *speed, 97 : : bool *autoneg) 98 : : { 99 [ # # ]: 0 : if (hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core0 || 100 : : hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core1) { 101 : 0 : *speed = TXGBE_LINK_SPEED_40GB_FULL; 102 : 0 : *autoneg = true; 103 [ # # ]: 0 : } else if (txgbe_is_backplane(hw)) { 104 : 0 : *speed = TXGBE_LINK_SPEED_40GB_FULL; 105 : 0 : *autoneg = true; 106 : : } else { 107 : : /* 108 : : * Temporary workaround: set speed to 40G even if sfp not present 109 : : * to avoid TXGBE_ERR_LINK_SETUP returned by setup_mac_link, but 110 : : * a more reasonable solution is don't execute setup_mac_link when 111 : : * sfp module not present. 112 : : */ 113 : 0 : *speed = TXGBE_LINK_SPEED_40GB_FULL; 114 : 0 : *autoneg = true; 115 : : } 116 : : 117 : 0 : return 0; 118 : : } 119 : : 120 : 0 : u32 txgbe_get_media_type_aml40(struct txgbe_hw *hw) 121 : : { 122 : 0 : u8 device_type = hw->subsystem_device_id & 0xF0; 123 : : enum txgbe_media_type media_type; 124 : : 125 [ # # # ]: 0 : switch (device_type) { 126 : : case TXGBE_DEV_ID_KR_KX_KX4: 127 : : media_type = txgbe_media_type_backplane; 128 : : break; 129 : 0 : case TXGBE_DEV_ID_SFP: 130 : : media_type = txgbe_media_type_fiber_qsfp; 131 : 0 : break; 132 : 0 : default: 133 : : media_type = txgbe_media_type_unknown; 134 : 0 : break; 135 : : } 136 : : 137 : 0 : return media_type; 138 : : } 139 : : 140 : 0 : s32 txgbe_setup_phy_link_aml40(struct txgbe_hw *hw, 141 : : u32 speed, 142 : : bool autoneg_wait_to_complete, 143 : : bool *need_reset) 144 : : { 145 : 0 : bool autoneg = false; 146 : : s32 status = 0; 147 : : s32 ret_status = 0; 148 : 0 : u32 link_speed = TXGBE_LINK_SPEED_UNKNOWN; 149 : 0 : bool link_up = false; 150 : : int i; 151 : 0 : u32 link_capabilities = TXGBE_LINK_SPEED_UNKNOWN; 152 : : u32 value; 153 : : 154 : 0 : *need_reset = false; 155 : : 156 [ # # # # ]: 0 : if (hw->phy.sfp_type == txgbe_sfp_type_not_present && !txgbe_is_backplane(hw)) 157 : 0 : hw->phy.identify_sfp(hw); 158 : : 159 : : /* Check to see if speed passed in is supported. */ 160 : 0 : status = hw->mac.get_link_capabilities(hw, 161 : : &link_capabilities, &autoneg); 162 [ # # ]: 0 : if (status) 163 : : return status; 164 : : 165 : 0 : speed &= link_capabilities; 166 [ # # ]: 0 : if (speed == TXGBE_LINK_SPEED_UNKNOWN) 167 : : return TXGBE_ERR_LINK_SETUP; 168 : : 169 [ # # ]: 0 : if (txgbe_xpcs_an_enabled(hw)) { 170 : 0 : txgbe_e56_check_phy_link(hw, &link_speed, &link_up); 171 [ # # # # : 0 : if (link_up && hw->an_done && !autoneg_wait_to_complete) # # ] 172 : : return status; 173 : 0 : rte_spinlock_lock(&hw->phy_lock); 174 : 0 : txgbe_e56_set_phy_link_mode(hw, 40, autoneg_wait_to_complete); 175 : : rte_spinlock_unlock(&hw->phy_lock); 176 : 0 : return status; 177 : : } 178 : : 179 [ # # # # ]: 0 : if (txgbe_is_backplane(hw) || txgbe_is_dac_cable(hw) || 180 [ # # ]: 0 : hw->phy.ffe_set) { 181 : 0 : rte_spinlock_lock(&hw->phy_lock); 182 : 0 : txgbe_e56_tx_ffe_cfg(hw, speed); 183 : : rte_spinlock_unlock(&hw->phy_lock); 184 : : } 185 : : 186 [ # # ]: 0 : for (i = 0; i < 4; i++) { 187 : 0 : txgbe_e56_check_phy_link(hw, &link_speed, &link_up); 188 [ # # ]: 0 : if (link_up) 189 : : break; 190 : : msleep(250); 191 : : } 192 : : 193 [ # # # # ]: 0 : if (link_speed == speed && link_up) 194 : 0 : goto out; 195 : : 196 : 0 : rte_spinlock_lock(&hw->phy_lock); 197 : 0 : ret_status = txgbe_set_link_to_amlite(hw, speed); 198 [ # # ]: 0 : if (ret_status == TXGBE_ERR_TIMEOUT) 199 : 0 : hw->link_valid = false; 200 : : rte_spinlock_unlock(&hw->phy_lock); 201 : : 202 [ # # ]: 0 : for (i = 0; i < 4; i++) { 203 : 0 : txgbe_e56_check_phy_link(hw, &link_speed, &link_up); 204 [ # # ]: 0 : if (link_up) 205 : 0 : goto out; 206 : : msleep(250); 207 : : } 208 : : 209 : 0 : out: 210 [ # # ]: 0 : if (link_up) { 211 : : value = rd32(hw, TXGBE_PORTSTAT); 212 [ # # ]: 0 : if (!(value & TXGBE_PORTSTAT_UP)) { 213 : 0 : DEBUGOUT("MAC link 0x14404: 0x%x", value); 214 : 0 : *need_reset = true; 215 : : value = rd32(hw, 0x110b0); 216 : 0 : DEBUGOUT("MAC intr status 0x110b0: 0x%x", value); 217 : : } 218 : : } else { 219 : 0 : *need_reset = true; 220 : 0 : DEBUGOUT("Link reconfiguration required. Reset scheduled in 2000ms."); 221 : : } 222 : : 223 : : return status; 224 : : } 225 : : 226 : 0 : void txgbe_init_mac_link_ops_aml40(struct txgbe_hw *hw) 227 : : { 228 : : struct txgbe_mac_info *mac = &hw->mac; 229 : : 230 : 0 : mac->disable_tx_laser = 231 : : txgbe_disable_tx_laser_multispeed_fiber; 232 : 0 : mac->enable_tx_laser = 233 : : txgbe_enable_tx_laser_multispeed_fiber; 234 : 0 : mac->flap_tx_laser = 235 : : txgbe_flap_tx_laser_multispeed_fiber; 236 : : 237 : 0 : mac->set_rate_select_speed = txgbe_set_hard_rate_select_speed; 238 : 0 : }