1 /* $OpenBSD: ixgbe_x550.c,v 1.9 2024/05/13 01:15:51 jsg Exp $ */ 2 3 /****************************************************************************** 4 5 Copyright (c) 2001-2017, Intel Corporation 6 All rights reserved. 7 8 Redistribution and use in source and binary forms, with or without 9 modification, are permitted provided that the following conditions are met: 10 11 1. Redistributions of source code must retain the above copyright notice, 12 this list of conditions and the following disclaimer. 13 14 2. Redistributions in binary form must reproduce the above copyright 15 notice, this list of conditions and the following disclaimer in the 16 documentation and/or other materials provided with the distribution. 17 18 3. Neither the name of the Intel Corporation nor the names of its 19 contributors may be used to endorse or promote products derived from 20 this software without specific prior written permission. 21 22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 26 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 POSSIBILITY OF SUCH DAMAGE. 33 34 ******************************************************************************/ 35 /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_x550.c 333870 2018-05-19 05:57:26Z mmacy $*/ 36 37 #include <dev/pci/ixgbe.h> 38 #include <dev/pci/ixgbe_type.h> 39 40 extern int32_t ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw); 41 extern int32_t ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, uint32_t mask); 42 extern void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, uint32_t mask); 43 44 int32_t ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *, uint32_t mask); 45 void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *, uint32_t mask); 46 int32_t ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw); 47 48 int32_t ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, 49 ixgbe_link_speed speed, 50 bool autoneg_wait_to_complete); 51 52 int32_t ixgbe_dmac_config_X550(struct ixgbe_hw *hw); 53 int32_t ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw); 54 int32_t ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw); 55 56 int32_t ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw); 57 int32_t ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw); 58 int32_t ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw); 59 int32_t ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw); 60 int32_t ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, uint16_t *buffer, 61 uint32_t buffer_size); 62 int32_t ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, 63 uint16_t *checksum_val); 64 int32_t ixgbe_update_flash_X550(struct ixgbe_hw *hw); 65 int32_t ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, uint16_t offset, 66 uint16_t data); 67 int32_t ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, 68 uint16_t offset, uint16_t words, 69 uint16_t *data); 70 int32_t ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, uint16_t offset, 71 uint16_t *data); 72 int32_t ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, uint16_t offset, 73 uint16_t data); 74 void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable, 75 unsigned int pool); 76 int32_t ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, uint32_t reg_addr, 77 uint32_t device_type, uint32_t data); 78 int32_t ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, uint32_t reg_addr, 79 uint32_t device_type, uint32_t *data); 80 int32_t ixgbe_get_phy_token(struct ixgbe_hw *); 81 int32_t ixgbe_put_phy_token(struct ixgbe_hw *); 82 int32_t ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr, 83 uint32_t device_type, uint32_t data); 84 int32_t ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr, 85 uint32_t device_type, uint32_t *data); 86 enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw); 87 int32_t ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw); 88 int32_t ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw, 89 ixgbe_link_speed *speed, 90 bool *autoneg); 91 void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw); 92 int32_t ixgbe_reset_hw_X550em(struct ixgbe_hw *hw); 93 int32_t ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw); 94 int32_t ixgbe_setup_kr_x550em(struct ixgbe_hw *hw); 95 int32_t ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw); 96 int32_t ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw); 97 int32_t ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw); 98 uint64_t ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw); 99 void ixgbe_disable_rx_x550(struct ixgbe_hw *hw); 100 int32_t ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed); 101 int32_t ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw); 102 int32_t ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, uint32_t mask); 103 void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, uint32_t mask); 104 int32_t ixgbe_setup_fc_X550em(struct ixgbe_hw *hw); 105 int32_t ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw, 106 ixgbe_link_speed speed, 107 bool autoneg_wait_to_complete); 108 int32_t ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr, 109 uint32_t device_type, uint16_t *phy_data); 110 int32_t ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr, 111 uint32_t device_type, uint16_t phy_data); 112 int32_t ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw); 113 void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw); 114 void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw); 115 void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw); 116 int32_t ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw); 117 int32_t ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw, 118 ixgbe_link_speed speed, 119 bool autoneg_wait_to_complete); 120 int32_t ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed, 121 bool *link_up, bool link_up_wait_to_complete); 122 int32_t ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw); 123 int32_t ixgbe_identify_sfp_module_X550em(struct ixgbe_hw *hw); 124 int32_t ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, uint32_t led_idx); 125 int32_t ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, uint32_t led_idx); 126 127 int32_t ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed); 128 129 130 /** 131 * ixgbe_init_ops_X550 - Inits func ptrs and MAC type 132 * @hw: pointer to hardware structure 133 * 134 * Initialize the function pointers and assign the MAC type for X550. 135 * Does not touch the hardware. 136 **/ 137 int32_t ixgbe_init_ops_X550(struct ixgbe_hw *hw) 138 { 139 struct ixgbe_mac_info *mac = &hw->mac; 140 struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 141 int32_t ret_val; 142 143 DEBUGFUNC("ixgbe_init_ops_X550"); 144 145 ret_val = ixgbe_init_ops_X540(hw); 146 mac->ops.dmac_config = ixgbe_dmac_config_X550; 147 mac->ops.dmac_config_tcs = ixgbe_dmac_config_tcs_X550; 148 mac->ops.dmac_update_tcs = ixgbe_dmac_update_tcs_X550; 149 mac->ops.setup_eee = NULL; 150 mac->ops.set_source_address_pruning = 151 ixgbe_set_source_address_pruning_X550; 152 153 eeprom->ops.init_params = ixgbe_init_eeprom_params_X550; 154 eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550; 155 eeprom->ops.read = ixgbe_read_ee_hostif_X550; 156 eeprom->ops.write = ixgbe_write_ee_hostif_X550; 157 eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550; 158 eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550; 159 160 mac->ops.disable_rx = ixgbe_disable_rx_x550; 161 switch (hw->device_id) { 162 case IXGBE_DEV_ID_X550EM_X_1G_T: 163 hw->mac.ops.led_on = NULL; 164 hw->mac.ops.led_off = NULL; 165 break; 166 case IXGBE_DEV_ID_X550EM_X_10G_T: 167 case IXGBE_DEV_ID_X550EM_A_10G_T: 168 hw->mac.ops.led_on = ixgbe_led_on_t_X550em; 169 hw->mac.ops.led_off = ixgbe_led_off_t_X550em; 170 break; 171 default: 172 break; 173 } 174 return ret_val; 175 } 176 177 /** 178 * ixgbe_read_cs4227 - Read CS4227 register 179 * @hw: pointer to hardware structure 180 * @reg: register number to write 181 * @value: pointer to receive value read 182 * 183 * Returns status code 184 **/ 185 int32_t ixgbe_read_cs4227(struct ixgbe_hw *hw, uint16_t reg, uint16_t *value) 186 { 187 return hw->link.ops.read_link_unlocked(hw, hw->link.addr, reg, value); 188 } 189 190 /** 191 * ixgbe_write_cs4227 - Write CS4227 register 192 * @hw: pointer to hardware structure 193 * @reg: register number to write 194 * @value: value to write to register 195 * 196 * Returns status code 197 **/ 198 int32_t ixgbe_write_cs4227(struct ixgbe_hw *hw, uint16_t reg, uint16_t value) 199 { 200 return hw->link.ops.write_link_unlocked(hw, hw->link.addr, reg, value); 201 } 202 203 /** 204 * ixgbe_read_pe - Read register from port expander 205 * @hw: pointer to hardware structure 206 * @reg: register number to read 207 * @value: pointer to receive read value 208 * 209 * Returns status code 210 **/ 211 int32_t ixgbe_read_pe(struct ixgbe_hw *hw, uint8_t reg, uint8_t *value) 212 { 213 int32_t status = IXGBE_NOT_IMPLEMENTED; 214 215 if (hw->phy.ops.read_i2c_byte_unlocked) 216 status = hw->phy.ops.read_i2c_byte_unlocked(hw, reg, IXGBE_PE, 217 value); 218 if (status != IXGBE_SUCCESS) 219 ERROR_REPORT2(IXGBE_ERROR_CAUTION, 220 "port expander access failed with %d\n", status); 221 return status; 222 } 223 224 /** 225 * ixgbe_write_pe - Write register to port expander 226 * @hw: pointer to hardware structure 227 * @reg: register number to write 228 * @value: value to write 229 * 230 * Returns status code 231 **/ 232 int32_t ixgbe_write_pe(struct ixgbe_hw *hw, uint8_t reg, uint8_t value) 233 { 234 int32_t status = IXGBE_NOT_IMPLEMENTED; 235 236 if (hw->phy.ops.write_i2c_byte_unlocked) 237 status = hw->phy.ops.write_i2c_byte_unlocked(hw, reg, IXGBE_PE, 238 value); 239 if (status != IXGBE_SUCCESS) 240 ERROR_REPORT2(IXGBE_ERROR_CAUTION, 241 "port expander access failed with %d\n", status); 242 return status; 243 } 244 245 /** 246 * ixgbe_reset_cs4227 - Reset CS4227 using port expander 247 * @hw: pointer to hardware structure 248 * 249 * This function assumes that the caller has acquired the proper semaphore. 250 * Returns error code 251 **/ 252 int32_t ixgbe_reset_cs4227(struct ixgbe_hw *hw) 253 { 254 int32_t status; 255 uint32_t retry; 256 uint16_t value; 257 uint8_t reg; 258 259 /* Trigger hard reset. */ 260 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®); 261 if (status != IXGBE_SUCCESS) 262 return status; 263 reg |= IXGBE_PE_BIT1; 264 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg); 265 if (status != IXGBE_SUCCESS) 266 return status; 267 268 status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, ®); 269 if (status != IXGBE_SUCCESS) 270 return status; 271 reg &= ~IXGBE_PE_BIT1; 272 status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg); 273 if (status != IXGBE_SUCCESS) 274 return status; 275 276 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®); 277 if (status != IXGBE_SUCCESS) 278 return status; 279 reg &= ~IXGBE_PE_BIT1; 280 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg); 281 if (status != IXGBE_SUCCESS) 282 return status; 283 284 usec_delay(IXGBE_CS4227_RESET_HOLD); 285 286 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®); 287 if (status != IXGBE_SUCCESS) 288 return status; 289 reg |= IXGBE_PE_BIT1; 290 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg); 291 if (status != IXGBE_SUCCESS) 292 return status; 293 294 /* Wait for the reset to complete. */ 295 msec_delay(IXGBE_CS4227_RESET_DELAY); 296 for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) { 297 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS, 298 &value); 299 if (status == IXGBE_SUCCESS && 300 value == IXGBE_CS4227_EEPROM_LOAD_OK) 301 break; 302 msec_delay(IXGBE_CS4227_CHECK_DELAY); 303 } 304 if (retry == IXGBE_CS4227_RETRIES) { 305 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, 306 "CS4227 reset did not complete."); 307 return IXGBE_ERR_PHY; 308 } 309 310 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value); 311 if (status != IXGBE_SUCCESS || 312 !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) { 313 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, 314 "CS4227 EEPROM did not load successfully."); 315 return IXGBE_ERR_PHY; 316 } 317 318 return IXGBE_SUCCESS; 319 } 320 321 /** 322 * ixgbe_check_cs4227 - Check CS4227 and reset as needed 323 * @hw: pointer to hardware structure 324 **/ 325 void ixgbe_check_cs4227(struct ixgbe_hw *hw) 326 { 327 int32_t status = IXGBE_SUCCESS; 328 uint32_t swfw_mask = hw->phy.phy_semaphore_mask; 329 uint16_t value = 0; 330 uint8_t retry; 331 332 for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) { 333 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); 334 if (status != IXGBE_SUCCESS) { 335 ERROR_REPORT2(IXGBE_ERROR_CAUTION, 336 "semaphore failed with %d", status); 337 msec_delay(IXGBE_CS4227_CHECK_DELAY); 338 continue; 339 } 340 341 /* Get status of reset flow. */ 342 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value); 343 344 if (status == IXGBE_SUCCESS && 345 value == IXGBE_CS4227_RESET_COMPLETE) 346 goto out; 347 348 if (status != IXGBE_SUCCESS || 349 value != IXGBE_CS4227_RESET_PENDING) 350 break; 351 352 /* Reset is pending. Wait and check again. */ 353 hw->mac.ops.release_swfw_sync(hw, swfw_mask); 354 msec_delay(IXGBE_CS4227_CHECK_DELAY); 355 } 356 357 /* If still pending, assume other instance failed. */ 358 if (retry == IXGBE_CS4227_RETRIES) { 359 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); 360 if (status != IXGBE_SUCCESS) { 361 ERROR_REPORT2(IXGBE_ERROR_CAUTION, 362 "semaphore failed with %d", status); 363 return; 364 } 365 } 366 367 /* Reset the CS4227. */ 368 status = ixgbe_reset_cs4227(hw); 369 if (status != IXGBE_SUCCESS) { 370 ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, 371 "CS4227 reset failed: %d", status); 372 goto out; 373 } 374 375 /* Reset takes so long, temporarily release semaphore in case the 376 * other driver instance is waiting for the reset indication. 377 */ 378 ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH, 379 IXGBE_CS4227_RESET_PENDING); 380 hw->mac.ops.release_swfw_sync(hw, swfw_mask); 381 msec_delay(10); 382 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); 383 if (status != IXGBE_SUCCESS) { 384 ERROR_REPORT2(IXGBE_ERROR_CAUTION, 385 "semaphore failed with %d", status); 386 return; 387 } 388 389 /* Record completion for next time. */ 390 status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH, 391 IXGBE_CS4227_RESET_COMPLETE); 392 393 out: 394 hw->mac.ops.release_swfw_sync(hw, swfw_mask); 395 msec_delay(hw->eeprom.semaphore_delay); 396 } 397 398 /** 399 * ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control 400 * @hw: pointer to hardware structure 401 **/ 402 void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw) 403 { 404 uint32_t esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); 405 406 if (hw->bus.lan_id) { 407 esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1); 408 esdp |= IXGBE_ESDP_SDP1_DIR; 409 } 410 esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR); 411 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); 412 IXGBE_WRITE_FLUSH(hw); 413 } 414 415 /** 416 * ixgbe_identify_phy_x550em - Get PHY type based on device id 417 * @hw: pointer to hardware structure 418 * 419 * Returns error code 420 */ 421 int32_t ixgbe_identify_phy_x550em(struct ixgbe_hw *hw) 422 { 423 hw->mac.ops.set_lan_id(hw); 424 425 ixgbe_read_mng_if_sel_x550em(hw); 426 427 switch (hw->device_id) { 428 case IXGBE_DEV_ID_X550EM_A_SFP: 429 return ixgbe_identify_module_generic(hw); 430 case IXGBE_DEV_ID_X550EM_X_SFP: 431 /* set up for CS4227 usage */ 432 ixgbe_setup_mux_ctl(hw); 433 ixgbe_check_cs4227(hw); 434 /* Fallthrough */ 435 436 case IXGBE_DEV_ID_X550EM_A_SFP_N: 437 return ixgbe_identify_module_generic(hw); 438 break; 439 case IXGBE_DEV_ID_X550EM_X_KX4: 440 hw->phy.type = ixgbe_phy_x550em_kx4; 441 break; 442 case IXGBE_DEV_ID_X550EM_X_XFI: 443 hw->phy.type = ixgbe_phy_x550em_xfi; 444 break; 445 case IXGBE_DEV_ID_X550EM_X_KR: 446 case IXGBE_DEV_ID_X550EM_A_KR: 447 case IXGBE_DEV_ID_X550EM_A_KR_L: 448 hw->phy.type = ixgbe_phy_x550em_kr; 449 break; 450 case IXGBE_DEV_ID_X550EM_A_10G_T: 451 case IXGBE_DEV_ID_X550EM_X_10G_T: 452 return ixgbe_identify_phy_generic(hw); 453 case IXGBE_DEV_ID_X550EM_X_1G_T: 454 hw->phy.type = ixgbe_phy_ext_1g_t; 455 break; 456 case IXGBE_DEV_ID_X550EM_A_1G_T: 457 case IXGBE_DEV_ID_X550EM_A_1G_T_L: 458 hw->phy.type = ixgbe_phy_fw; 459 if (hw->bus.lan_id) 460 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM; 461 else 462 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM; 463 break; 464 default: 465 break; 466 } 467 return IXGBE_SUCCESS; 468 } 469 470 /** 471 * ixgbe_fw_phy_activity - Perform an activity on a PHY 472 * @hw: pointer to hardware structure 473 * @activity: activity to perform 474 * @data: Pointer to 4 32-bit words of data 475 */ 476 int32_t ixgbe_fw_phy_activity(struct ixgbe_hw *hw, uint16_t activity, 477 uint32_t (*data)[FW_PHY_ACT_DATA_COUNT]) 478 { 479 union { 480 struct ixgbe_hic_phy_activity_req cmd; 481 struct ixgbe_hic_phy_activity_resp rsp; 482 } hic; 483 uint16_t retries = FW_PHY_ACT_RETRIES; 484 int32_t rc; 485 uint16_t i; 486 487 do { 488 memset(&hic, 0, sizeof(hic)); 489 hic.cmd.hdr.cmd = FW_PHY_ACT_REQ_CMD; 490 hic.cmd.hdr.buf_len = FW_PHY_ACT_REQ_LEN; 491 hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; 492 hic.cmd.port_number = hw->bus.lan_id; 493 hic.cmd.activity_id = htole16(activity); 494 for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i) 495 hic.cmd.data[i] = htobe32((*data)[i]); 496 497 rc = ixgbe_host_interface_command(hw, (uint32_t *)&hic.cmd, 498 sizeof(hic.cmd), 499 IXGBE_HI_COMMAND_TIMEOUT, 500 TRUE); 501 if (rc != IXGBE_SUCCESS) 502 return rc; 503 if (hic.rsp.hdr.cmd_or_resp.ret_status == 504 FW_CEM_RESP_STATUS_SUCCESS) { 505 for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i) 506 (*data)[i] = betoh32(hic.rsp.data[i]); 507 return IXGBE_SUCCESS; 508 } 509 usec_delay(20); 510 --retries; 511 } while (retries > 0); 512 513 return IXGBE_ERR_HOST_INTERFACE_COMMAND; 514 } 515 516 static const struct { 517 uint16_t fw_speed; 518 ixgbe_link_speed phy_speed; 519 } ixgbe_fw_map[] = { 520 { FW_PHY_ACT_LINK_SPEED_10, IXGBE_LINK_SPEED_10_FULL }, 521 { FW_PHY_ACT_LINK_SPEED_100, IXGBE_LINK_SPEED_100_FULL }, 522 { FW_PHY_ACT_LINK_SPEED_1G, IXGBE_LINK_SPEED_1GB_FULL }, 523 { FW_PHY_ACT_LINK_SPEED_2_5G, IXGBE_LINK_SPEED_2_5GB_FULL }, 524 { FW_PHY_ACT_LINK_SPEED_5G, IXGBE_LINK_SPEED_5GB_FULL }, 525 { FW_PHY_ACT_LINK_SPEED_10G, IXGBE_LINK_SPEED_10GB_FULL }, 526 }; 527 528 /** 529 * ixgbe_get_phy_id_fw - Get the phy ID via firmware command 530 * @hw: pointer to hardware structure 531 * 532 * Returns error code 533 */ 534 int32_t ixgbe_get_phy_id_fw(struct ixgbe_hw *hw) 535 { 536 uint32_t info[FW_PHY_ACT_DATA_COUNT] = { 0 }; 537 uint16_t phy_speeds; 538 uint16_t phy_id_lo; 539 int32_t rc; 540 uint16_t i; 541 542 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_PHY_INFO, &info); 543 if (rc) 544 return rc; 545 546 hw->phy.speeds_supported = 0; 547 phy_speeds = info[0] & FW_PHY_INFO_SPEED_MASK; 548 for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) { 549 if (phy_speeds & ixgbe_fw_map[i].fw_speed) 550 hw->phy.speeds_supported |= ixgbe_fw_map[i].phy_speed; 551 } 552 if (!hw->phy.autoneg_advertised) 553 hw->phy.autoneg_advertised = hw->phy.speeds_supported; 554 555 hw->phy.id = info[0] & FW_PHY_INFO_ID_HI_MASK; 556 phy_id_lo = info[1] & FW_PHY_INFO_ID_LO_MASK; 557 hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK; 558 hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK; 559 if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK) 560 return IXGBE_ERR_PHY_ADDR_INVALID; 561 return IXGBE_SUCCESS; 562 } 563 564 /** 565 * ixgbe_identify_phy_fw - Get PHY type based on firmware command 566 * @hw: pointer to hardware structure 567 * 568 * Returns error code 569 */ 570 int32_t ixgbe_identify_phy_fw(struct ixgbe_hw *hw) 571 { 572 if (hw->bus.lan_id) 573 hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM; 574 else 575 hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM; 576 577 hw->phy.type = ixgbe_phy_fw; 578 hw->phy.ops.read_reg = NULL; 579 hw->phy.ops.write_reg = NULL; 580 return ixgbe_get_phy_id_fw(hw); 581 } 582 583 /** 584 * ixgbe_shutdown_fw_phy - Shutdown a firmware-controlled PHY 585 * @hw: pointer to hardware structure 586 * 587 * Returns error code 588 */ 589 int32_t ixgbe_shutdown_fw_phy(struct ixgbe_hw *hw) 590 { 591 uint32_t setup[FW_PHY_ACT_DATA_COUNT] = { 0 }; 592 593 setup[0] = FW_PHY_ACT_FORCE_LINK_DOWN_OFF; 594 return ixgbe_fw_phy_activity(hw, FW_PHY_ACT_FORCE_LINK_DOWN, &setup); 595 } 596 597 int32_t ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, uint32_t reg_addr, 598 uint32_t device_type, uint16_t *phy_data) 599 { 600 return IXGBE_NOT_IMPLEMENTED; 601 } 602 603 int32_t ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, uint32_t reg_addr, 604 uint32_t device_type, uint16_t phy_data) 605 { 606 return IXGBE_NOT_IMPLEMENTED; 607 } 608 609 /** 610 * ixgbe_init_ops_X550EM - Inits func ptrs and MAC type 611 * @hw: pointer to hardware structure 612 * 613 * Initialize the function pointers and for MAC type X550EM. 614 * Does not touch the hardware. 615 **/ 616 int32_t ixgbe_init_ops_X550EM(struct ixgbe_hw *hw) 617 { 618 struct ixgbe_mac_info *mac = &hw->mac; 619 struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 620 struct ixgbe_phy_info *phy = &hw->phy; 621 int32_t ret_val; 622 623 DEBUGFUNC("ixgbe_init_ops_X550EM"); 624 625 /* Similar to X550 so start there. */ 626 ret_val = ixgbe_init_ops_X550(hw); 627 628 /* Since this function eventually calls 629 * ixgbe_init_ops_540 by design, we are setting 630 * the pointers to NULL explicitly here to overwrite 631 * the values being set in the x540 function. 632 */ 633 634 /* IPsec not supported in x550EM */ 635 mac->ops.disable_sec_rx_path = NULL; 636 mac->ops.enable_sec_rx_path = NULL; 637 638 /* AUTOC register is not present in x550EM. */ 639 mac->ops.prot_autoc_read = NULL; 640 mac->ops.prot_autoc_write = NULL; 641 642 /* X550EM bus type is internal*/ 643 hw->bus.type = ixgbe_bus_type_internal; 644 mac->ops.get_bus_info = ixgbe_get_bus_info_X550em; 645 646 647 mac->ops.get_media_type = ixgbe_get_media_type_X550em; 648 mac->ops.setup_sfp = ixgbe_setup_sfp_modules_X550em; 649 mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_X550em; 650 mac->ops.reset_hw = ixgbe_reset_hw_X550em; 651 mac->ops.get_supported_physical_layer = 652 ixgbe_get_supported_physical_layer_X550em; 653 654 if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) 655 mac->ops.setup_fc = ixgbe_setup_fc_generic; 656 else 657 mac->ops.setup_fc = ixgbe_setup_fc_X550em; 658 659 /* PHY */ 660 phy->ops.init = ixgbe_init_phy_ops_X550em; 661 switch (hw->device_id) { 662 case IXGBE_DEV_ID_X550EM_A_1G_T: 663 case IXGBE_DEV_ID_X550EM_A_1G_T_L: 664 mac->ops.setup_fc = NULL; 665 phy->ops.identify = ixgbe_identify_phy_fw; 666 phy->ops.set_phy_power = NULL; 667 phy->ops.get_firmware_version = NULL; 668 break; 669 case IXGBE_DEV_ID_X550EM_X_1G_T: 670 mac->ops.setup_fc = NULL; 671 phy->ops.identify = ixgbe_identify_phy_x550em; 672 phy->ops.set_phy_power = NULL; 673 break; 674 default: 675 phy->ops.identify = ixgbe_identify_phy_x550em; 676 } 677 678 if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper) 679 phy->ops.set_phy_power = NULL; 680 681 682 /* EEPROM */ 683 eeprom->ops.init_params = ixgbe_init_eeprom_params_X540; 684 eeprom->ops.read = ixgbe_read_ee_hostif_X550; 685 eeprom->ops.write = ixgbe_write_ee_hostif_X550; 686 eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550; 687 eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550; 688 eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550; 689 690 return ret_val; 691 } 692 693 /** 694 * ixgbe_setup_fw_link - Setup firmware-controlled PHYs 695 * @hw: pointer to hardware structure 696 */ 697 int32_t ixgbe_setup_fw_link(struct ixgbe_hw *hw) 698 { 699 uint32_t setup[FW_PHY_ACT_DATA_COUNT] = { 0 }; 700 int32_t rc; 701 uint16_t i; 702 703 if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw)) 704 return 0; 705 706 if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { 707 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, 708 "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); 709 return IXGBE_ERR_INVALID_LINK_SETTINGS; 710 } 711 712 switch (hw->fc.requested_mode) { 713 case ixgbe_fc_full: 714 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX << 715 FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT; 716 break; 717 case ixgbe_fc_rx_pause: 718 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RX << 719 FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT; 720 break; 721 case ixgbe_fc_tx_pause: 722 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_TX << 723 FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT; 724 break; 725 default: 726 break; 727 } 728 729 for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) { 730 if (hw->phy.autoneg_advertised & ixgbe_fw_map[i].phy_speed) 731 setup[0] |= ixgbe_fw_map[i].fw_speed; 732 } 733 setup[0] |= FW_PHY_ACT_SETUP_LINK_HP | FW_PHY_ACT_SETUP_LINK_AN; 734 735 if (hw->phy.eee_speeds_advertised) 736 setup[0] |= FW_PHY_ACT_SETUP_LINK_EEE; 737 738 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup); 739 if (rc) 740 return rc; 741 if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN) 742 return IXGBE_ERR_OVERTEMP; 743 return IXGBE_SUCCESS; 744 } 745 746 /** 747 * ixgbe_fc_autoneg_fw _ Set up flow control for FW-controlled PHYs 748 * @hw: pointer to hardware structure 749 * 750 * Called at init time to set up flow control. 751 */ 752 int32_t ixgbe_fc_autoneg_fw(struct ixgbe_hw *hw) 753 { 754 if (hw->fc.requested_mode == ixgbe_fc_default) 755 hw->fc.requested_mode = ixgbe_fc_full; 756 757 return ixgbe_setup_fw_link(hw); 758 } 759 760 /** 761 * ixgbe_setup_eee_fw - Enable/disable EEE support 762 * @hw: pointer to the HW structure 763 * @enable_eee: boolean flag to enable EEE 764 * 765 * Enable/disable EEE based on enable_eee flag. 766 * This function controls EEE for firmware-based PHY implementations. 767 */ 768 int32_t ixgbe_setup_eee_fw(struct ixgbe_hw *hw, bool enable_eee) 769 { 770 if (!!hw->phy.eee_speeds_advertised == enable_eee) 771 return IXGBE_SUCCESS; 772 if (enable_eee) 773 hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported; 774 else 775 hw->phy.eee_speeds_advertised = 0; 776 return hw->phy.ops.setup_link(hw); 777 } 778 779 /** 780 * ixgbe_init_ops_X550EM_a - Inits func ptrs and MAC type 781 * @hw: pointer to hardware structure 782 * 783 * Initialize the function pointers and for MAC type X550EM_a. 784 * Does not touch the hardware. 785 **/ 786 int32_t ixgbe_init_ops_X550EM_a(struct ixgbe_hw *hw) 787 { 788 struct ixgbe_mac_info *mac = &hw->mac; 789 int32_t ret_val; 790 791 DEBUGFUNC("ixgbe_init_ops_X550EM_a"); 792 793 /* Start with generic X550EM init */ 794 ret_val = ixgbe_init_ops_X550EM(hw); 795 796 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII || 797 hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L) { 798 mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550; 799 mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550; 800 } else { 801 mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550a; 802 mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550a; 803 } 804 mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550a; 805 mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550a; 806 807 switch (mac->ops.get_media_type(hw)) { 808 case ixgbe_media_type_fiber: 809 mac->ops.setup_fc = NULL; 810 mac->ops.fc_autoneg = ixgbe_fc_autoneg_fiber_x550em_a; 811 break; 812 case ixgbe_media_type_backplane: 813 mac->ops.fc_autoneg = ixgbe_fc_autoneg_backplane_x550em_a; 814 mac->ops.setup_fc = ixgbe_setup_fc_backplane_x550em_a; 815 break; 816 default: 817 break; 818 } 819 820 switch (hw->device_id) { 821 case IXGBE_DEV_ID_X550EM_A_1G_T: 822 case IXGBE_DEV_ID_X550EM_A_1G_T_L: 823 mac->ops.fc_autoneg = ixgbe_fc_autoneg_sgmii_x550em_a; 824 mac->ops.setup_fc = ixgbe_fc_autoneg_fw; 825 mac->ops.setup_eee = ixgbe_setup_eee_fw; 826 hw->phy.eee_speeds_supported = IXGBE_LINK_SPEED_100_FULL | 827 IXGBE_LINK_SPEED_1GB_FULL; 828 hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported; 829 break; 830 default: 831 break; 832 } 833 834 return ret_val; 835 } 836 837 /** 838 * ixgbe_init_ops_X550EM_x - Inits func ptrs and MAC type 839 * @hw: pointer to hardware structure 840 * 841 * Initialize the function pointers and for MAC type X550EM_x. 842 * Does not touch the hardware. 843 **/ 844 int32_t ixgbe_init_ops_X550EM_x(struct ixgbe_hw *hw) 845 { 846 struct ixgbe_mac_info *mac = &hw->mac; 847 struct ixgbe_link_info *link = &hw->link; 848 int32_t ret_val; 849 850 DEBUGFUNC("ixgbe_init_ops_X550EM_x"); 851 852 /* Start with generic X550EM init */ 853 ret_val = ixgbe_init_ops_X550EM(hw); 854 855 mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550; 856 mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550; 857 mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550em; 858 mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550em; 859 link->ops.read_link = ixgbe_read_i2c_combined_generic; 860 link->ops.read_link_unlocked = ixgbe_read_i2c_combined_generic_unlocked; 861 link->ops.write_link = ixgbe_write_i2c_combined_generic; 862 link->ops.write_link_unlocked = 863 ixgbe_write_i2c_combined_generic_unlocked; 864 link->addr = IXGBE_CS4227; 865 866 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T) { 867 mac->ops.setup_fc = NULL; 868 mac->ops.setup_eee = NULL; 869 } 870 871 return ret_val; 872 } 873 874 /** 875 * ixgbe_dmac_config_X550 876 * @hw: pointer to hardware structure 877 * 878 * Configure DMA coalescing. If enabling dmac, dmac is activated. 879 * When disabling dmac, dmac enable dmac bit is cleared. 880 **/ 881 int32_t ixgbe_dmac_config_X550(struct ixgbe_hw *hw) 882 { 883 uint32_t reg; 884 885 DEBUGFUNC("ixgbe_dmac_config_X550"); 886 887 /* Disable DMA coalescing before configuring */ 888 reg = IXGBE_READ_REG(hw, IXGBE_DMACR); 889 reg &= ~IXGBE_DMACR_DMAC_EN; 890 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg); 891 892 /* Disable DMA Coalescing if the watchdog timer is 0 */ 893 if (!hw->mac.dmac_config.watchdog_timer) 894 goto out; 895 896 ixgbe_dmac_config_tcs_X550(hw); 897 898 /* Configure DMA Coalescing Control Register */ 899 reg = IXGBE_READ_REG(hw, IXGBE_DMACR); 900 901 /* Set the watchdog timer in units of 40.96 usec */ 902 reg &= ~IXGBE_DMACR_DMACWT_MASK; 903 reg |= (hw->mac.dmac_config.watchdog_timer * 100) / 4096; 904 905 reg &= ~IXGBE_DMACR_HIGH_PRI_TC_MASK; 906 reg |= IXGBE_DMACR_EN_MNG_IND; 907 908 /* Enable DMA coalescing after configuration */ 909 reg |= IXGBE_DMACR_DMAC_EN; 910 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg); 911 912 out: 913 return IXGBE_SUCCESS; 914 } 915 916 /** 917 * ixgbe_dmac_config_tcs_X550 918 * @hw: pointer to hardware structure 919 * 920 * Configure DMA coalescing threshold per TC. The dmac enable bit must 921 * be cleared before configuring. 922 **/ 923 int32_t ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw) 924 { 925 uint32_t tc, reg, pb_headroom, rx_pb_size, maxframe_size_kb; 926 927 DEBUGFUNC("ixgbe_dmac_config_tcs_X550"); 928 929 /* Configure DMA coalescing enabled */ 930 switch (hw->mac.dmac_config.link_speed) { 931 case IXGBE_LINK_SPEED_10_FULL: 932 case IXGBE_LINK_SPEED_100_FULL: 933 pb_headroom = IXGBE_DMACRXT_100M; 934 break; 935 case IXGBE_LINK_SPEED_1GB_FULL: 936 pb_headroom = IXGBE_DMACRXT_1G; 937 break; 938 default: 939 pb_headroom = IXGBE_DMACRXT_10G; 940 break; 941 } 942 943 maxframe_size_kb = ((IXGBE_READ_REG(hw, IXGBE_MAXFRS) >> 944 IXGBE_MHADD_MFS_SHIFT) / 1024); 945 946 /* Set the per Rx packet buffer receive threshold */ 947 for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) { 948 reg = IXGBE_READ_REG(hw, IXGBE_DMCTH(tc)); 949 reg &= ~IXGBE_DMCTH_DMACRXT_MASK; 950 951 if (tc < hw->mac.dmac_config.num_tcs) { 952 /* Get Rx PB size */ 953 rx_pb_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(tc)); 954 rx_pb_size = (rx_pb_size & IXGBE_RXPBSIZE_MASK) >> 955 IXGBE_RXPBSIZE_SHIFT; 956 957 /* Calculate receive buffer threshold in kilobytes */ 958 if (rx_pb_size > pb_headroom) 959 rx_pb_size = rx_pb_size - pb_headroom; 960 else 961 rx_pb_size = 0; 962 963 /* Minimum of MFS shall be set for DMCTH */ 964 reg |= (rx_pb_size > maxframe_size_kb) ? 965 rx_pb_size : maxframe_size_kb; 966 } 967 IXGBE_WRITE_REG(hw, IXGBE_DMCTH(tc), reg); 968 } 969 return IXGBE_SUCCESS; 970 } 971 972 /** 973 * ixgbe_dmac_update_tcs_X550 974 * @hw: pointer to hardware structure 975 * 976 * Disables dmac, updates per TC settings, and then enables dmac. 977 **/ 978 int32_t ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw) 979 { 980 uint32_t reg; 981 982 DEBUGFUNC("ixgbe_dmac_update_tcs_X550"); 983 984 /* Disable DMA coalescing before configuring */ 985 reg = IXGBE_READ_REG(hw, IXGBE_DMACR); 986 reg &= ~IXGBE_DMACR_DMAC_EN; 987 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg); 988 989 ixgbe_dmac_config_tcs_X550(hw); 990 991 /* Enable DMA coalescing after configuration */ 992 reg = IXGBE_READ_REG(hw, IXGBE_DMACR); 993 reg |= IXGBE_DMACR_DMAC_EN; 994 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg); 995 996 return IXGBE_SUCCESS; 997 } 998 999 /** 1000 * ixgbe_init_eeprom_params_X550 - Initialize EEPROM params 1001 * @hw: pointer to hardware structure 1002 * 1003 * Initializes the EEPROM parameters ixgbe_eeprom_info within the 1004 * ixgbe_hw struct in order to set up EEPROM access. 1005 **/ 1006 int32_t ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw) 1007 { 1008 struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 1009 uint32_t eec; 1010 uint16_t eeprom_size; 1011 1012 DEBUGFUNC("ixgbe_init_eeprom_params_X550"); 1013 1014 if (eeprom->type == ixgbe_eeprom_uninitialized) { 1015 eeprom->semaphore_delay = 10; 1016 eeprom->type = ixgbe_flash; 1017 1018 eec = IXGBE_READ_REG(hw, IXGBE_EEC); 1019 eeprom_size = (uint16_t)((eec & IXGBE_EEC_SIZE) >> 1020 IXGBE_EEC_SIZE_SHIFT); 1021 eeprom->word_size = 1 << (eeprom_size + 1022 IXGBE_EEPROM_WORD_SIZE_SHIFT); 1023 1024 DEBUGOUT2("Eeprom params: type = %d, size = %d\n", 1025 eeprom->type, eeprom->word_size); 1026 } 1027 1028 return IXGBE_SUCCESS; 1029 } 1030 1031 /** 1032 * ixgbe_set_source_address_pruning_X550 - Enable/Disable source address pruning 1033 * @hw: pointer to hardware structure 1034 * @enable: enable or disable source address pruning 1035 * @pool: Rx pool to set source address pruning for 1036 **/ 1037 void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable, 1038 unsigned int pool) 1039 { 1040 uint64_t pfflp; 1041 1042 /* max rx pool is 63 */ 1043 if (pool > 63) 1044 return; 1045 1046 pfflp = (uint64_t)IXGBE_READ_REG(hw, IXGBE_PFFLPL); 1047 pfflp |= (uint64_t)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32; 1048 1049 if (enable) 1050 pfflp |= (1ULL << pool); 1051 else 1052 pfflp &= ~(1ULL << pool); 1053 1054 IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (uint32_t)pfflp); 1055 IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (uint32_t)(pfflp >> 32)); 1056 } 1057 1058 /** 1059 * ixgbe_iosf_wait - Wait for IOSF command completion 1060 * @hw: pointer to hardware structure 1061 * @ctrl: pointer to location to receive final IOSF control value 1062 * 1063 * Returns failing status on timeout 1064 * 1065 * Note: ctrl can be NULL if the IOSF control register value is not needed 1066 **/ 1067 int32_t ixgbe_iosf_wait(struct ixgbe_hw *hw, uint32_t *ctrl) 1068 { 1069 uint32_t i, command = 0; 1070 1071 /* Check every 10 usec to see if the address cycle completed. 1072 * The SB IOSF BUSY bit will clear when the operation is 1073 * complete 1074 */ 1075 for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { 1076 command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL); 1077 if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0) 1078 break; 1079 usec_delay(10); 1080 } 1081 if (ctrl) 1082 *ctrl = command; 1083 if (i == IXGBE_MDIO_COMMAND_TIMEOUT) { 1084 ERROR_REPORT1(IXGBE_ERROR_POLLING, "Wait timed out\n"); 1085 return IXGBE_ERR_PHY; 1086 } 1087 1088 return IXGBE_SUCCESS; 1089 } 1090 1091 /** 1092 * ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register 1093 * of the IOSF device 1094 * @hw: pointer to hardware structure 1095 * @reg_addr: 32 bit PHY register to write 1096 * @device_type: 3 bit device type 1097 * @data: Data to write to the register 1098 **/ 1099 int32_t ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, uint32_t reg_addr, 1100 uint32_t device_type, uint32_t data) 1101 { 1102 uint32_t gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM; 1103 uint32_t command, error __unused; 1104 int32_t ret; 1105 1106 ret = hw->mac.ops.acquire_swfw_sync(hw, gssr); 1107 if (ret != IXGBE_SUCCESS) 1108 return ret; 1109 1110 ret = ixgbe_iosf_wait(hw, NULL); 1111 if (ret != IXGBE_SUCCESS) 1112 goto out; 1113 1114 command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) | 1115 (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT)); 1116 1117 /* Write IOSF control register */ 1118 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command); 1119 1120 /* Write IOSF data register */ 1121 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data); 1122 1123 ret = ixgbe_iosf_wait(hw, &command); 1124 1125 if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) { 1126 error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >> 1127 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT; 1128 ERROR_REPORT2(IXGBE_ERROR_POLLING, 1129 "Failed to write, error %x\n", error); 1130 ret = IXGBE_ERR_PHY; 1131 } 1132 1133 out: 1134 hw->mac.ops.release_swfw_sync(hw, gssr); 1135 return ret; 1136 } 1137 1138 /** 1139 * ixgbe_read_iosf_sb_reg_x550 - Reads specified register of the IOSF device 1140 * @hw: pointer to hardware structure 1141 * @reg_addr: 32 bit PHY register to write 1142 * @device_type: 3 bit device type 1143 * @data: Pointer to read data from the register 1144 **/ 1145 int32_t ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, uint32_t reg_addr, 1146 uint32_t device_type, uint32_t *data) 1147 { 1148 uint32_t gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM; 1149 uint32_t command, error __unused; 1150 int32_t ret; 1151 1152 ret = hw->mac.ops.acquire_swfw_sync(hw, gssr); 1153 if (ret != IXGBE_SUCCESS) 1154 return ret; 1155 1156 ret = ixgbe_iosf_wait(hw, NULL); 1157 if (ret != IXGBE_SUCCESS) 1158 goto out; 1159 1160 command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) | 1161 (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT)); 1162 1163 /* Write IOSF control register */ 1164 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command); 1165 1166 ret = ixgbe_iosf_wait(hw, &command); 1167 1168 if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) { 1169 error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >> 1170 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT; 1171 ERROR_REPORT2(IXGBE_ERROR_POLLING, 1172 "Failed to read, error %x\n", error); 1173 ret = IXGBE_ERR_PHY; 1174 } 1175 1176 if (ret == IXGBE_SUCCESS) 1177 *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA); 1178 1179 out: 1180 hw->mac.ops.release_swfw_sync(hw, gssr); 1181 return ret; 1182 } 1183 1184 /** 1185 * ixgbe_get_phy_token - Get the token for shared phy access 1186 * @hw: Pointer to hardware structure 1187 */ 1188 1189 int32_t ixgbe_get_phy_token(struct ixgbe_hw *hw) 1190 { 1191 struct ixgbe_hic_phy_token_req token_cmd; 1192 int32_t status; 1193 1194 token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD; 1195 token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN; 1196 token_cmd.hdr.cmd_or_resp.cmd_resv = 0; 1197 token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; 1198 token_cmd.port_number = hw->bus.lan_id; 1199 token_cmd.command_type = FW_PHY_TOKEN_REQ; 1200 token_cmd.pad = 0; 1201 status = ixgbe_host_interface_command(hw, (uint32_t *)&token_cmd, 1202 sizeof(token_cmd), 1203 IXGBE_HI_COMMAND_TIMEOUT, 1204 TRUE); 1205 if (status) { 1206 DEBUGOUT1("Issuing host interface command failed with Status = %d\n", 1207 status); 1208 return status; 1209 } 1210 if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK) 1211 return IXGBE_SUCCESS; 1212 if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY) { 1213 DEBUGOUT1("Host interface command returned 0x%08x , returning IXGBE_ERR_FW_RESP_INVALID\n", 1214 token_cmd.hdr.cmd_or_resp.ret_status); 1215 return IXGBE_ERR_FW_RESP_INVALID; 1216 } 1217 1218 DEBUGOUT("Returning IXGBE_ERR_TOKEN_RETRY\n"); 1219 return IXGBE_ERR_TOKEN_RETRY; 1220 } 1221 1222 /** 1223 * ixgbe_put_phy_token - Put the token for shared phy access 1224 * @hw: Pointer to hardware structure 1225 */ 1226 1227 int32_t ixgbe_put_phy_token(struct ixgbe_hw *hw) 1228 { 1229 struct ixgbe_hic_phy_token_req token_cmd; 1230 int32_t status; 1231 1232 token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD; 1233 token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN; 1234 token_cmd.hdr.cmd_or_resp.cmd_resv = 0; 1235 token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; 1236 token_cmd.port_number = hw->bus.lan_id; 1237 token_cmd.command_type = FW_PHY_TOKEN_REL; 1238 token_cmd.pad = 0; 1239 status = ixgbe_host_interface_command(hw, (uint32_t *)&token_cmd, 1240 sizeof(token_cmd), 1241 IXGBE_HI_COMMAND_TIMEOUT, 1242 TRUE); 1243 if (status) 1244 return status; 1245 if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK) 1246 return IXGBE_SUCCESS; 1247 1248 DEBUGOUT("Put PHY Token host interface command failed"); 1249 return IXGBE_ERR_FW_RESP_INVALID; 1250 } 1251 1252 /** 1253 * ixgbe_write_iosf_sb_reg_x550a - Writes a value to specified register 1254 * of the IOSF device 1255 * @hw: pointer to hardware structure 1256 * @reg_addr: 32 bit PHY register to write 1257 * @device_type: 3 bit device type 1258 * @data: Data to write to the register 1259 **/ 1260 int32_t ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr, 1261 uint32_t device_type, uint32_t data) 1262 { 1263 struct ixgbe_hic_internal_phy_req write_cmd; 1264 int32_t status; 1265 1266 memset(&write_cmd, 0, sizeof(write_cmd)); 1267 write_cmd.hdr.cmd = FW_INT_PHY_REQ_CMD; 1268 write_cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN; 1269 write_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; 1270 write_cmd.port_number = hw->bus.lan_id; 1271 write_cmd.command_type = FW_INT_PHY_REQ_WRITE; 1272 write_cmd.address = htobe16(reg_addr); 1273 write_cmd.write_data = htobe32(data); 1274 1275 status = ixgbe_host_interface_command(hw, (uint32_t *)&write_cmd, 1276 sizeof(write_cmd), 1277 IXGBE_HI_COMMAND_TIMEOUT, FALSE); 1278 1279 return status; 1280 } 1281 1282 /** 1283 * ixgbe_read_iosf_sb_reg_x550a - Reads specified register of the IOSF device 1284 * @hw: pointer to hardware structure 1285 * @reg_addr: 32 bit PHY register to write 1286 * @device_type: 3 bit device type 1287 * @data: Pointer to read data from the register 1288 **/ 1289 int32_t ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr, 1290 uint32_t device_type, uint32_t *data) 1291 { 1292 union { 1293 struct ixgbe_hic_internal_phy_req cmd; 1294 struct ixgbe_hic_internal_phy_resp rsp; 1295 } hic; 1296 int32_t status; 1297 1298 memset(&hic, 0, sizeof(hic)); 1299 hic.cmd.hdr.cmd = FW_INT_PHY_REQ_CMD; 1300 hic.cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN; 1301 hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; 1302 hic.cmd.port_number = hw->bus.lan_id; 1303 hic.cmd.command_type = FW_INT_PHY_REQ_READ; 1304 hic.cmd.address = htobe16(reg_addr); 1305 1306 status = ixgbe_host_interface_command(hw, (uint32_t *)&hic.cmd, 1307 sizeof(hic.cmd), 1308 IXGBE_HI_COMMAND_TIMEOUT, TRUE); 1309 1310 /* Extract the register value from the response. */ 1311 *data = betoh32(hic.rsp.read_data); 1312 1313 return status; 1314 } 1315 1316 /** 1317 * ixgbe_get_media_type_X550em - Get media type 1318 * @hw: pointer to hardware structure 1319 * 1320 * Returns the media type (fiber, copper, backplane) 1321 */ 1322 enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw) 1323 { 1324 enum ixgbe_media_type media_type; 1325 1326 DEBUGFUNC("ixgbe_get_media_type_X550em"); 1327 1328 /* Detect if there is a copper PHY attached. */ 1329 switch (hw->device_id) { 1330 case IXGBE_DEV_ID_X550EM_X_KR: 1331 case IXGBE_DEV_ID_X550EM_X_KX4: 1332 case IXGBE_DEV_ID_X550EM_X_XFI: 1333 case IXGBE_DEV_ID_X550EM_A_KR: 1334 case IXGBE_DEV_ID_X550EM_A_KR_L: 1335 media_type = ixgbe_media_type_backplane; 1336 break; 1337 case IXGBE_DEV_ID_X550EM_X_SFP: 1338 case IXGBE_DEV_ID_X550EM_A_SFP: 1339 case IXGBE_DEV_ID_X550EM_A_SFP_N: 1340 case IXGBE_DEV_ID_X550EM_A_QSFP: 1341 case IXGBE_DEV_ID_X550EM_A_QSFP_N: 1342 media_type = ixgbe_media_type_fiber; 1343 break; 1344 case IXGBE_DEV_ID_X550EM_X_1G_T: 1345 case IXGBE_DEV_ID_X550EM_X_10G_T: 1346 case IXGBE_DEV_ID_X550EM_A_10G_T: 1347 media_type = ixgbe_media_type_copper; 1348 break; 1349 case IXGBE_DEV_ID_X550EM_A_SGMII: 1350 case IXGBE_DEV_ID_X550EM_A_SGMII_L: 1351 media_type = ixgbe_media_type_backplane; 1352 hw->phy.type = ixgbe_phy_sgmii; 1353 break; 1354 case IXGBE_DEV_ID_X550EM_A_1G_T: 1355 case IXGBE_DEV_ID_X550EM_A_1G_T_L: 1356 media_type = ixgbe_media_type_copper; 1357 break; 1358 default: 1359 media_type = ixgbe_media_type_unknown; 1360 break; 1361 } 1362 return media_type; 1363 } 1364 1365 /** 1366 * ixgbe_supported_sfp_modules_X550em - Check if SFP module type is supported 1367 * @hw: pointer to hardware structure 1368 * @linear: TRUE if SFP module is linear 1369 */ 1370 int32_t ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear) 1371 { 1372 DEBUGFUNC("ixgbe_supported_sfp_modules_X550em"); 1373 1374 switch (hw->phy.sfp_type) { 1375 case ixgbe_sfp_type_not_present: 1376 return IXGBE_ERR_SFP_NOT_PRESENT; 1377 case ixgbe_sfp_type_da_cu_core0: 1378 case ixgbe_sfp_type_da_cu_core1: 1379 *linear = TRUE; 1380 break; 1381 case ixgbe_sfp_type_srlr_core0: 1382 case ixgbe_sfp_type_srlr_core1: 1383 case ixgbe_sfp_type_da_act_lmt_core0: 1384 case ixgbe_sfp_type_da_act_lmt_core1: 1385 case ixgbe_sfp_type_1g_sx_core0: 1386 case ixgbe_sfp_type_1g_sx_core1: 1387 case ixgbe_sfp_type_1g_lx_core0: 1388 case ixgbe_sfp_type_1g_lx_core1: 1389 *linear = FALSE; 1390 break; 1391 case ixgbe_sfp_type_unknown: 1392 case ixgbe_sfp_type_1g_cu_core0: 1393 case ixgbe_sfp_type_1g_cu_core1: 1394 default: 1395 return IXGBE_ERR_SFP_NOT_SUPPORTED; 1396 } 1397 1398 return IXGBE_SUCCESS; 1399 } 1400 1401 /** 1402 * ixgbe_identify_sfp_module_X550em - Identifies SFP modules 1403 * @hw: pointer to hardware structure 1404 * 1405 * Searches for and identifies the SFP module and assigns appropriate PHY type. 1406 **/ 1407 int32_t ixgbe_identify_sfp_module_X550em(struct ixgbe_hw *hw) 1408 { 1409 int32_t status; 1410 bool linear; 1411 1412 DEBUGFUNC("ixgbe_identify_sfp_module_X550em"); 1413 1414 status = ixgbe_identify_module_generic(hw); 1415 1416 if (status != IXGBE_SUCCESS) 1417 return status; 1418 1419 /* Check if SFP module is supported */ 1420 status = ixgbe_supported_sfp_modules_X550em(hw, &linear); 1421 1422 return status; 1423 } 1424 1425 /** 1426 * ixgbe_setup_sfp_modules_X550em - Setup MAC link ops 1427 * @hw: pointer to hardware structure 1428 */ 1429 int32_t ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw) 1430 { 1431 int32_t status; 1432 bool linear; 1433 1434 DEBUGFUNC("ixgbe_setup_sfp_modules_X550em"); 1435 1436 /* Check if SFP module is supported */ 1437 status = ixgbe_supported_sfp_modules_X550em(hw, &linear); 1438 1439 if (status != IXGBE_SUCCESS) 1440 return status; 1441 1442 ixgbe_init_mac_link_ops_X550em(hw); 1443 hw->phy.ops.reset = NULL; 1444 1445 return IXGBE_SUCCESS; 1446 } 1447 1448 /** 1449 * ixgbe_restart_an_internal_phy_x550em - restart autonegotiation for the 1450 * internal PHY 1451 * @hw: pointer to hardware structure 1452 **/ 1453 int32_t ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw *hw) 1454 { 1455 int32_t status; 1456 uint32_t link_ctrl; 1457 1458 /* Restart auto-negotiation. */ 1459 status = hw->mac.ops.read_iosf_sb_reg(hw, 1460 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 1461 IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl); 1462 1463 if (status) { 1464 DEBUGOUT("Auto-negotiation did not complete\n"); 1465 return status; 1466 } 1467 1468 link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART; 1469 status = hw->mac.ops.write_iosf_sb_reg(hw, 1470 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 1471 IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl); 1472 1473 if (hw->mac.type == ixgbe_mac_X550EM_a) { 1474 uint32_t flx_mask_st20; 1475 1476 /* Indicate to FW that AN restart has been asserted */ 1477 status = hw->mac.ops.read_iosf_sb_reg(hw, 1478 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), 1479 IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_mask_st20); 1480 1481 if (status) { 1482 DEBUGOUT("Auto-negotiation did not complete\n"); 1483 return status; 1484 } 1485 1486 flx_mask_st20 |= IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART; 1487 status = hw->mac.ops.write_iosf_sb_reg(hw, 1488 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), 1489 IXGBE_SB_IOSF_TARGET_KR_PHY, flx_mask_st20); 1490 } 1491 1492 return status; 1493 } 1494 1495 /** 1496 * ixgbe_setup_sgmii - Set up link for sgmii 1497 * @hw: pointer to hardware structure 1498 * @speed: new link speed 1499 * @autoneg_wait: TRUE when waiting for completion is needed 1500 */ 1501 int32_t ixgbe_setup_sgmii(struct ixgbe_hw *hw, ixgbe_link_speed speed, 1502 bool autoneg_wait) 1503 { 1504 struct ixgbe_mac_info *mac = &hw->mac; 1505 uint32_t lval, sval, flx_val; 1506 int32_t rc; 1507 1508 rc = mac->ops.read_iosf_sb_reg(hw, 1509 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 1510 IXGBE_SB_IOSF_TARGET_KR_PHY, &lval); 1511 if (rc) 1512 return rc; 1513 1514 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; 1515 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; 1516 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN; 1517 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN; 1518 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G; 1519 rc = mac->ops.write_iosf_sb_reg(hw, 1520 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 1521 IXGBE_SB_IOSF_TARGET_KR_PHY, lval); 1522 if (rc) 1523 return rc; 1524 1525 rc = mac->ops.read_iosf_sb_reg(hw, 1526 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id), 1527 IXGBE_SB_IOSF_TARGET_KR_PHY, &sval); 1528 if (rc) 1529 return rc; 1530 1531 sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D; 1532 sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D; 1533 rc = mac->ops.write_iosf_sb_reg(hw, 1534 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id), 1535 IXGBE_SB_IOSF_TARGET_KR_PHY, sval); 1536 if (rc) 1537 return rc; 1538 1539 rc = mac->ops.read_iosf_sb_reg(hw, 1540 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), 1541 IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val); 1542 if (rc) 1543 return rc; 1544 1545 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; 1546 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G; 1547 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; 1548 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; 1549 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; 1550 1551 rc = mac->ops.write_iosf_sb_reg(hw, 1552 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), 1553 IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val); 1554 if (rc) 1555 return rc; 1556 1557 rc = ixgbe_restart_an_internal_phy_x550em(hw); 1558 if (rc) 1559 return rc; 1560 1561 return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait); 1562 } 1563 1564 /** 1565 * ixgbe_setup_sgmii_fw - Set up link for internal PHY SGMII auto-negotiation 1566 * @hw: pointer to hardware structure 1567 * @speed: new link speed 1568 * @autoneg_wait: TRUE when waiting for completion is needed 1569 */ 1570 int32_t ixgbe_setup_sgmii_fw(struct ixgbe_hw *hw, ixgbe_link_speed speed, 1571 bool autoneg_wait) 1572 { 1573 struct ixgbe_mac_info *mac = &hw->mac; 1574 uint32_t lval, sval, flx_val; 1575 int32_t rc; 1576 1577 rc = mac->ops.read_iosf_sb_reg(hw, 1578 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 1579 IXGBE_SB_IOSF_TARGET_KR_PHY, &lval); 1580 if (rc) 1581 return rc; 1582 1583 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; 1584 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; 1585 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN; 1586 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN; 1587 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G; 1588 rc = mac->ops.write_iosf_sb_reg(hw, 1589 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 1590 IXGBE_SB_IOSF_TARGET_KR_PHY, lval); 1591 if (rc) 1592 return rc; 1593 1594 rc = mac->ops.read_iosf_sb_reg(hw, 1595 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id), 1596 IXGBE_SB_IOSF_TARGET_KR_PHY, &sval); 1597 if (rc) 1598 return rc; 1599 1600 sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D; 1601 sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D; 1602 rc = mac->ops.write_iosf_sb_reg(hw, 1603 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id), 1604 IXGBE_SB_IOSF_TARGET_KR_PHY, sval); 1605 if (rc) 1606 return rc; 1607 1608 rc = mac->ops.write_iosf_sb_reg(hw, 1609 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 1610 IXGBE_SB_IOSF_TARGET_KR_PHY, lval); 1611 if (rc) 1612 return rc; 1613 1614 rc = mac->ops.read_iosf_sb_reg(hw, 1615 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), 1616 IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val); 1617 if (rc) 1618 return rc; 1619 1620 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; 1621 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN; 1622 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; 1623 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; 1624 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; 1625 1626 rc = mac->ops.write_iosf_sb_reg(hw, 1627 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), 1628 IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val); 1629 if (rc) 1630 return rc; 1631 1632 rc = ixgbe_restart_an_internal_phy_x550em(hw); 1633 1634 return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait); 1635 } 1636 1637 /** 1638 * ixgbe_init_mac_link_ops_X550em - init mac link function pointers 1639 * @hw: pointer to hardware structure 1640 */ 1641 void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) 1642 { 1643 struct ixgbe_mac_info *mac = &hw->mac; 1644 1645 DEBUGFUNC("ixgbe_init_mac_link_ops_X550em"); 1646 1647 switch (hw->mac.ops.get_media_type(hw)) { 1648 case ixgbe_media_type_fiber: 1649 /* CS4227 does not support autoneg, so disable the laser control 1650 * functions for SFP+ fiber 1651 */ 1652 mac->ops.disable_tx_laser = NULL; 1653 mac->ops.enable_tx_laser = NULL; 1654 mac->ops.flap_tx_laser = NULL; 1655 mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber; 1656 mac->ops.set_rate_select_speed = 1657 ixgbe_set_soft_rate_select_speed; 1658 1659 if ((hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) || 1660 (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP)) 1661 mac->ops.setup_mac_link = 1662 ixgbe_setup_mac_link_sfp_x550a; 1663 else 1664 mac->ops.setup_mac_link = 1665 ixgbe_setup_mac_link_sfp_x550em; 1666 break; 1667 case ixgbe_media_type_copper: 1668 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T) 1669 break; 1670 if (hw->mac.type == ixgbe_mac_X550EM_a) { 1671 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T || 1672 hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) { 1673 mac->ops.setup_link = ixgbe_setup_sgmii_fw; 1674 mac->ops.check_link = 1675 ixgbe_check_mac_link_generic; 1676 } else { 1677 mac->ops.setup_link = 1678 ixgbe_setup_mac_link_t_X550em; 1679 } 1680 } else { 1681 mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em; 1682 mac->ops.check_link = ixgbe_check_link_t_X550em; 1683 } 1684 break; 1685 case ixgbe_media_type_backplane: 1686 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII || 1687 hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L) 1688 mac->ops.setup_link = ixgbe_setup_sgmii; 1689 break; 1690 default: 1691 break; 1692 } 1693 } 1694 1695 /** 1696 * ixgbe_get_link_capabilities_x550em - Determines link capabilities 1697 * @hw: pointer to hardware structure 1698 * @speed: pointer to link speed 1699 * @autoneg: TRUE when autoneg or autotry is enabled 1700 */ 1701 int32_t ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw, 1702 ixgbe_link_speed *speed, 1703 bool *autoneg) 1704 { 1705 DEBUGFUNC("ixgbe_get_link_capabilities_X550em"); 1706 1707 1708 if (hw->phy.type == ixgbe_phy_fw) { 1709 *autoneg = TRUE; 1710 *speed = hw->phy.speeds_supported; 1711 return 0; 1712 } 1713 1714 /* SFP */ 1715 if (hw->phy.media_type == ixgbe_media_type_fiber) { 1716 1717 /* CS4227 SFP must not enable auto-negotiation */ 1718 *autoneg = FALSE; 1719 1720 /* Check if 1G SFP module. */ 1721 if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || 1722 hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1 1723 || hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || 1724 hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) { 1725 *speed = IXGBE_LINK_SPEED_1GB_FULL; 1726 return IXGBE_SUCCESS; 1727 } 1728 1729 /* Link capabilities are based on SFP */ 1730 if (hw->phy.multispeed_fiber) 1731 *speed = IXGBE_LINK_SPEED_10GB_FULL | 1732 IXGBE_LINK_SPEED_1GB_FULL; 1733 else 1734 *speed = IXGBE_LINK_SPEED_10GB_FULL; 1735 } else { 1736 switch (hw->phy.type) { 1737 case ixgbe_phy_ext_1g_t: 1738 case ixgbe_phy_sgmii: 1739 *speed = IXGBE_LINK_SPEED_1GB_FULL; 1740 break; 1741 case ixgbe_phy_x550em_kr: 1742 if (hw->mac.type == ixgbe_mac_X550EM_a) { 1743 /* check different backplane modes */ 1744 if (hw->phy.nw_mng_if_sel & 1745 IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) { 1746 *speed = IXGBE_LINK_SPEED_2_5GB_FULL; 1747 break; 1748 } else if (hw->device_id == 1749 IXGBE_DEV_ID_X550EM_A_KR_L) { 1750 *speed = IXGBE_LINK_SPEED_1GB_FULL; 1751 break; 1752 } 1753 } 1754 /* fall through */ 1755 default: 1756 *speed = IXGBE_LINK_SPEED_10GB_FULL | 1757 IXGBE_LINK_SPEED_1GB_FULL; 1758 break; 1759 } 1760 *autoneg = TRUE; 1761 } 1762 1763 return IXGBE_SUCCESS; 1764 } 1765 1766 /** 1767 * ixgbe_get_lasi_ext_t_x550em - Determime external Base T PHY interrupt cause 1768 * @hw: pointer to hardware structure 1769 * @lsc: pointer to boolean flag which indicates whether external Base T 1770 * PHY interrupt is lsc 1771 * 1772 * Determime if external Base T PHY interrupt cause is high temperature 1773 * failure alarm or link status change. 1774 * 1775 * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature 1776 * failure alarm, else return PHY access status. 1777 */ 1778 int32_t ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc) 1779 { 1780 uint32_t status; 1781 uint16_t reg; 1782 1783 *lsc = FALSE; 1784 1785 /* Vendor alarm triggered */ 1786 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG, 1787 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 1788 ®); 1789 1790 if (status != IXGBE_SUCCESS || 1791 !(reg & IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN)) 1792 return status; 1793 1794 /* Vendor Auto-Neg alarm triggered or Global alarm 1 triggered */ 1795 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG, 1796 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 1797 ®); 1798 1799 if (status != IXGBE_SUCCESS || 1800 !(reg & (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN | 1801 IXGBE_MDIO_GLOBAL_ALARM_1_INT))) 1802 return status; 1803 1804 /* Global alarm triggered */ 1805 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1, 1806 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 1807 ®); 1808 1809 if (status != IXGBE_SUCCESS) 1810 return status; 1811 1812 /* If high temperature failure, then return over temp error and exit */ 1813 if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) { 1814 /* power down the PHY in case the PHY FW didn't already */ 1815 ixgbe_set_copper_phy_power(hw, FALSE); 1816 return IXGBE_ERR_OVERTEMP; 1817 } else if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) { 1818 /* device fault alarm triggered */ 1819 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG, 1820 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 1821 ®); 1822 1823 if (status != IXGBE_SUCCESS) 1824 return status; 1825 1826 /* if device fault was due to high temp alarm handle and exit */ 1827 if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) { 1828 /* power down the PHY in case the PHY FW didn't */ 1829 ixgbe_set_copper_phy_power(hw, FALSE); 1830 return IXGBE_ERR_OVERTEMP; 1831 } 1832 } 1833 1834 /* Vendor alarm 2 triggered */ 1835 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG, 1836 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®); 1837 1838 if (status != IXGBE_SUCCESS || 1839 !(reg & IXGBE_MDIO_GLOBAL_STD_ALM2_INT)) 1840 return status; 1841 1842 /* link connect/disconnect event occurred */ 1843 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2, 1844 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®); 1845 1846 if (status != IXGBE_SUCCESS) 1847 return status; 1848 1849 /* Indicate LSC */ 1850 if (reg & IXGBE_MDIO_AUTO_NEG_VEN_LSC) 1851 *lsc = TRUE; 1852 1853 return IXGBE_SUCCESS; 1854 } 1855 1856 /** 1857 * ixgbe_enable_lasi_ext_t_x550em - Enable external Base T PHY interrupts 1858 * @hw: pointer to hardware structure 1859 * 1860 * Enable link status change and temperature failure alarm for the external 1861 * Base T PHY 1862 * 1863 * Returns PHY access status 1864 */ 1865 int32_t ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw) 1866 { 1867 uint32_t status; 1868 uint16_t reg; 1869 bool lsc; 1870 1871 /* Clear interrupt flags */ 1872 status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc); 1873 1874 /* Enable link status change alarm */ 1875 1876 /* Enable the LASI interrupts on X552 devices to receive notifications 1877 * of the link configurations of the external PHY and correspondingly 1878 * support the configuration of the internal iXFI link, since iXFI does 1879 * not support auto-negotiation. This is not required for X553 devices 1880 * having KR support, which performs auto-negotiations and which is used 1881 * as the internal link to the external PHY. Hence adding a check here 1882 * to avoid enabling LASI interrupts for X553 devices. 1883 */ 1884 if (hw->mac.type != ixgbe_mac_X550EM_a) { 1885 status = hw->phy.ops.read_reg(hw, 1886 IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK, 1887 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®); 1888 1889 if (status != IXGBE_SUCCESS) 1890 return status; 1891 1892 reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN; 1893 1894 status = hw->phy.ops.write_reg(hw, 1895 IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK, 1896 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg); 1897 1898 if (status != IXGBE_SUCCESS) 1899 return status; 1900 } 1901 1902 /* Enable high temperature failure and global fault alarms */ 1903 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK, 1904 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 1905 ®); 1906 1907 if (status != IXGBE_SUCCESS) 1908 return status; 1909 1910 reg |= (IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN | 1911 IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN); 1912 1913 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK, 1914 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 1915 reg); 1916 1917 if (status != IXGBE_SUCCESS) 1918 return status; 1919 1920 /* Enable vendor Auto-Neg alarm and Global Interrupt Mask 1 alarm */ 1921 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK, 1922 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 1923 ®); 1924 1925 if (status != IXGBE_SUCCESS) 1926 return status; 1927 1928 reg |= (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN | 1929 IXGBE_MDIO_GLOBAL_ALARM_1_INT); 1930 1931 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK, 1932 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 1933 reg); 1934 1935 if (status != IXGBE_SUCCESS) 1936 return status; 1937 1938 /* Enable chip-wide vendor alarm */ 1939 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK, 1940 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 1941 ®); 1942 1943 if (status != IXGBE_SUCCESS) 1944 return status; 1945 1946 reg |= IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN; 1947 1948 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK, 1949 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 1950 reg); 1951 1952 return status; 1953 } 1954 1955 /** 1956 * ixgbe_setup_kr_speed_x550em - Configure the KR PHY for link speed. 1957 * @hw: pointer to hardware structure 1958 * @speed: link speed 1959 * 1960 * Configures the integrated KR PHY. 1961 **/ 1962 int32_t ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw, 1963 ixgbe_link_speed speed) 1964 { 1965 int32_t status; 1966 uint32_t reg_val; 1967 1968 status = hw->mac.ops.read_iosf_sb_reg(hw, 1969 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 1970 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 1971 if (status) 1972 return status; 1973 1974 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; 1975 reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR | 1976 IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX); 1977 1978 /* Advertise 10G support. */ 1979 if (speed & IXGBE_LINK_SPEED_10GB_FULL) 1980 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR; 1981 1982 /* Advertise 1G support. */ 1983 if (speed & IXGBE_LINK_SPEED_1GB_FULL) 1984 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX; 1985 1986 status = hw->mac.ops.write_iosf_sb_reg(hw, 1987 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 1988 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 1989 1990 if (hw->mac.type == ixgbe_mac_X550EM_a) { 1991 /* Set lane mode to KR auto negotiation */ 1992 status = hw->mac.ops.read_iosf_sb_reg(hw, 1993 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), 1994 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 1995 1996 if (status) 1997 return status; 1998 1999 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; 2000 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN; 2001 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; 2002 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; 2003 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; 2004 2005 status = hw->mac.ops.write_iosf_sb_reg(hw, 2006 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), 2007 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 2008 } 2009 2010 return ixgbe_restart_an_internal_phy_x550em(hw); 2011 } 2012 2013 /** 2014 * ixgbe_reset_phy_fw - Reset firmware-controlled PHYs 2015 * @hw: pointer to hardware structure 2016 */ 2017 int32_t ixgbe_reset_phy_fw(struct ixgbe_hw *hw) 2018 { 2019 uint32_t store[FW_PHY_ACT_DATA_COUNT] = { 0 }; 2020 int32_t rc; 2021 2022 if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw)) 2023 return IXGBE_SUCCESS; 2024 2025 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_PHY_SW_RESET, &store); 2026 if (rc) 2027 return rc; 2028 memset(store, 0, sizeof(store)); 2029 2030 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_INIT_PHY, &store); 2031 if (rc) 2032 return rc; 2033 2034 return ixgbe_setup_fw_link(hw); 2035 } 2036 2037 /** 2038 * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp 2039 * @hw: pointer to hardware structure 2040 */ 2041 int32_t ixgbe_check_overtemp_fw(struct ixgbe_hw *hw) 2042 { 2043 uint32_t store[FW_PHY_ACT_DATA_COUNT] = { 0 }; 2044 int32_t rc; 2045 2046 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store); 2047 if (rc) 2048 return rc; 2049 2050 if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) { 2051 ixgbe_shutdown_fw_phy(hw); 2052 return IXGBE_ERR_OVERTEMP; 2053 } 2054 return IXGBE_SUCCESS; 2055 } 2056 2057 /** 2058 * ixgbe_read_mng_if_sel_x550em - Read NW_MNG_IF_SEL register 2059 * @hw: pointer to hardware structure 2060 * 2061 * Read NW_MNG_IF_SEL register and save field values, and check for valid field 2062 * values. 2063 **/ 2064 int32_t ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw) 2065 { 2066 /* Save NW management interface connected on board. This is used 2067 * to determine internal PHY mode. 2068 */ 2069 hw->phy.nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL); 2070 2071 /* If X552 (X550EM_a) and MDIO is connected to external PHY, then set 2072 * PHY address. This register field was has only been used for X552. 2073 */ 2074 if (hw->mac.type == ixgbe_mac_X550EM_a && 2075 hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_MDIO_ACT) { 2076 hw->phy.addr = (hw->phy.nw_mng_if_sel & 2077 IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >> 2078 IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT; 2079 } 2080 2081 return IXGBE_SUCCESS; 2082 } 2083 2084 /** 2085 * ixgbe_init_phy_ops_X550em - PHY/SFP specific init 2086 * @hw: pointer to hardware structure 2087 * 2088 * Initialize any function pointers that were not able to be 2089 * set during init_shared_code because the PHY/SFP type was 2090 * not known. Perform the SFP init if necessary. 2091 */ 2092 int32_t ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw) 2093 { 2094 struct ixgbe_phy_info *phy = &hw->phy; 2095 int32_t ret_val; 2096 2097 DEBUGFUNC("ixgbe_init_phy_ops_X550em"); 2098 2099 hw->mac.ops.set_lan_id(hw); 2100 ixgbe_read_mng_if_sel_x550em(hw); 2101 2102 if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) { 2103 phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM; 2104 ixgbe_setup_mux_ctl(hw); 2105 phy->ops.identify_sfp = ixgbe_identify_sfp_module_X550em; 2106 } 2107 2108 switch (hw->device_id) { 2109 case IXGBE_DEV_ID_X550EM_A_1G_T: 2110 case IXGBE_DEV_ID_X550EM_A_1G_T_L: 2111 phy->ops.read_reg_mdi = NULL; 2112 phy->ops.write_reg_mdi = NULL; 2113 hw->phy.ops.read_reg = NULL; 2114 hw->phy.ops.write_reg = NULL; 2115 phy->ops.check_overtemp = ixgbe_check_overtemp_fw; 2116 if (hw->bus.lan_id) 2117 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM; 2118 else 2119 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM; 2120 2121 break; 2122 case IXGBE_DEV_ID_X550EM_A_10G_T: 2123 case IXGBE_DEV_ID_X550EM_A_SFP: 2124 hw->phy.ops.read_reg = ixgbe_read_phy_reg_x550a; 2125 hw->phy.ops.write_reg = ixgbe_write_phy_reg_x550a; 2126 if (hw->bus.lan_id) 2127 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM; 2128 else 2129 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM; 2130 break; 2131 case IXGBE_DEV_ID_X550EM_X_SFP: 2132 /* set up for CS4227 usage */ 2133 hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM; 2134 break; 2135 case IXGBE_DEV_ID_X550EM_X_1G_T: 2136 phy->ops.read_reg_mdi = NULL; 2137 phy->ops.write_reg_mdi = NULL; 2138 default: 2139 break; 2140 } 2141 2142 /* Identify the PHY or SFP module */ 2143 ret_val = phy->ops.identify(hw); 2144 if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED || 2145 ret_val == IXGBE_ERR_PHY_ADDR_INVALID) 2146 return ret_val; 2147 2148 /* Setup function pointers based on detected hardware */ 2149 ixgbe_init_mac_link_ops_X550em(hw); 2150 if (phy->sfp_type != ixgbe_sfp_type_unknown) 2151 phy->ops.reset = NULL; 2152 2153 /* Set functions pointers based on phy type */ 2154 switch (hw->phy.type) { 2155 case ixgbe_phy_x550em_kx4: 2156 phy->ops.setup_link = NULL; 2157 phy->ops.read_reg = ixgbe_read_phy_reg_x550em; 2158 phy->ops.write_reg = ixgbe_write_phy_reg_x550em; 2159 break; 2160 case ixgbe_phy_x550em_kr: 2161 phy->ops.setup_link = ixgbe_setup_kr_x550em; 2162 phy->ops.read_reg = ixgbe_read_phy_reg_x550em; 2163 phy->ops.write_reg = ixgbe_write_phy_reg_x550em; 2164 break; 2165 case ixgbe_phy_ext_1g_t: 2166 /* link is managed by FW */ 2167 phy->ops.setup_link = NULL; 2168 phy->ops.reset = NULL; 2169 break; 2170 case ixgbe_phy_x550em_xfi: 2171 /* link is managed by HW */ 2172 phy->ops.setup_link = NULL; 2173 phy->ops.read_reg = ixgbe_read_phy_reg_x550em; 2174 phy->ops.write_reg = ixgbe_write_phy_reg_x550em; 2175 break; 2176 case ixgbe_phy_x550em_ext_t: 2177 /* If internal link mode is XFI, then setup iXFI internal link, 2178 * else setup KR now. 2179 */ 2180 phy->ops.setup_internal_link = 2181 ixgbe_setup_internal_phy_t_x550em; 2182 2183 /* setup SW LPLU only for first revision of X550EM_x */ 2184 if ((hw->mac.type == ixgbe_mac_X550EM_x) && 2185 !(IXGBE_FUSES0_REV_MASK & 2186 IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)))) 2187 phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em; 2188 2189 phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em; 2190 phy->ops.reset = ixgbe_reset_phy_t_X550em; 2191 break; 2192 case ixgbe_phy_sgmii: 2193 phy->ops.setup_link = NULL; 2194 break; 2195 case ixgbe_phy_fw: 2196 phy->ops.setup_link = ixgbe_setup_fw_link; 2197 phy->ops.reset = ixgbe_reset_phy_fw; 2198 break; 2199 default: 2200 break; 2201 } 2202 return ret_val; 2203 } 2204 2205 /** 2206 * ixgbe_set_mdio_speed - Set MDIO clock speed 2207 * @hw: pointer to hardware structure 2208 */ 2209 void ixgbe_set_mdio_speed(struct ixgbe_hw *hw) 2210 { 2211 uint32_t hlreg0; 2212 2213 switch (hw->device_id) { 2214 case IXGBE_DEV_ID_X550EM_X_10G_T: 2215 case IXGBE_DEV_ID_X550EM_A_SGMII: 2216 case IXGBE_DEV_ID_X550EM_A_SGMII_L: 2217 case IXGBE_DEV_ID_X550EM_A_10G_T: 2218 case IXGBE_DEV_ID_X550EM_A_SFP: 2219 case IXGBE_DEV_ID_X550EM_A_QSFP: 2220 /* Config MDIO clock speed before the first MDIO PHY access */ 2221 hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); 2222 hlreg0 &= ~IXGBE_HLREG0_MDCSPD; 2223 IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); 2224 break; 2225 case IXGBE_DEV_ID_X550EM_A_1G_T: 2226 case IXGBE_DEV_ID_X550EM_A_1G_T_L: 2227 /* Select fast MDIO clock speed for these devices */ 2228 hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); 2229 hlreg0 |= IXGBE_HLREG0_MDCSPD; 2230 IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); 2231 break; 2232 default: 2233 break; 2234 } 2235 } 2236 2237 /** 2238 * ixgbe_reset_hw_X550em - Perform hardware reset 2239 * @hw: pointer to hardware structure 2240 * 2241 * Resets the hardware by resetting the transmit and receive units, masks 2242 * and clears all interrupts, perform a PHY reset, and perform a link (MAC) 2243 * reset. 2244 */ 2245 int32_t ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) 2246 { 2247 ixgbe_link_speed link_speed; 2248 int32_t status; 2249 uint32_t ctrl = 0; 2250 uint32_t i; 2251 bool link_up = FALSE; 2252 uint32_t swfw_mask = hw->phy.phy_semaphore_mask; 2253 2254 DEBUGFUNC("ixgbe_reset_hw_X550em"); 2255 2256 /* Call adapter stop to disable Tx/Rx and clear interrupts */ 2257 status = hw->mac.ops.stop_adapter(hw); 2258 if (status != IXGBE_SUCCESS) { 2259 DEBUGOUT1("Failed to stop adapter, STATUS = %d\n", status); 2260 return status; 2261 } 2262 /* flush pending Tx transactions */ 2263 ixgbe_clear_tx_pending(hw); 2264 2265 ixgbe_set_mdio_speed(hw); 2266 2267 /* PHY ops must be identified and initialized prior to reset */ 2268 status = hw->phy.ops.init(hw); 2269 2270 if (status) 2271 DEBUGOUT1("Failed to initialize PHY ops, STATUS = %d\n", 2272 status); 2273 2274 if (status == IXGBE_ERR_SFP_NOT_SUPPORTED || 2275 status == IXGBE_ERR_PHY_ADDR_INVALID) { 2276 DEBUGOUT("Returning from reset HW due to PHY init failure\n"); 2277 return status; 2278 } 2279 2280 /* start the external PHY */ 2281 if (hw->phy.type == ixgbe_phy_x550em_ext_t) { 2282 status = ixgbe_init_ext_t_x550em(hw); 2283 if (status) { 2284 DEBUGOUT1("Failed to start the external PHY, STATUS = %d\n", 2285 status); 2286 return status; 2287 } 2288 } 2289 2290 /* Setup SFP module if there is one present. */ 2291 if (hw->phy.sfp_setup_needed) { 2292 status = hw->mac.ops.setup_sfp(hw); 2293 hw->phy.sfp_setup_needed = FALSE; 2294 } 2295 2296 if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) 2297 return status; 2298 2299 /* Reset PHY */ 2300 if (!hw->phy.reset_disable && hw->phy.ops.reset) { 2301 if (hw->phy.ops.reset(hw) == IXGBE_ERR_OVERTEMP) 2302 return IXGBE_ERR_OVERTEMP; 2303 } 2304 2305 mac_reset_top: 2306 /* Issue global reset to the MAC. Needs to be SW reset if link is up. 2307 * If link reset is used when link is up, it might reset the PHY when 2308 * mng is using it. If link is down or the flag to force full link 2309 * reset is set, then perform link reset. 2310 */ 2311 ctrl = IXGBE_CTRL_LNK_RST; 2312 if (!hw->force_full_reset) { 2313 hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE); 2314 if (link_up) 2315 ctrl = IXGBE_CTRL_RST; 2316 } 2317 2318 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); 2319 if (status != IXGBE_SUCCESS) { 2320 ERROR_REPORT2(IXGBE_ERROR_CAUTION, 2321 "semaphore failed with %d", status); 2322 return IXGBE_ERR_SWFW_SYNC; 2323 } 2324 ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); 2325 IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); 2326 IXGBE_WRITE_FLUSH(hw); 2327 hw->mac.ops.release_swfw_sync(hw, swfw_mask); 2328 2329 /* Poll for reset bit to self-clear meaning reset is complete */ 2330 for (i = 0; i < 10; i++) { 2331 usec_delay(1); 2332 ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); 2333 if (!(ctrl & IXGBE_CTRL_RST_MASK)) 2334 break; 2335 } 2336 2337 if (ctrl & IXGBE_CTRL_RST_MASK) { 2338 status = IXGBE_ERR_RESET_FAILED; 2339 DEBUGOUT("Reset polling failed to complete.\n"); 2340 } 2341 2342 msec_delay(50); 2343 2344 /* Double resets are required for recovery from certain error 2345 * conditions. Between resets, it is necessary to stall to 2346 * allow time for any pending HW events to complete. 2347 */ 2348 if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { 2349 hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; 2350 goto mac_reset_top; 2351 } 2352 2353 /* Store the permanent mac address */ 2354 hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); 2355 2356 /* Store MAC address from RAR0, clear receive address registers, and 2357 * clear the multicast table. Also reset num_rar_entries to 128, 2358 * since we modify this value when programming the SAN MAC address. 2359 */ 2360 hw->mac.num_rar_entries = 128; 2361 hw->mac.ops.init_rx_addrs(hw); 2362 2363 ixgbe_set_mdio_speed(hw); 2364 2365 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP) 2366 ixgbe_setup_mux_ctl(hw); 2367 2368 if (status != IXGBE_SUCCESS) 2369 DEBUGOUT1("Reset HW failed, STATUS = %d\n", status); 2370 2371 return status; 2372 } 2373 2374 /** 2375 * ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY. 2376 * @hw: pointer to hardware structure 2377 */ 2378 int32_t ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw) 2379 { 2380 uint32_t status; 2381 uint16_t reg; 2382 2383 status = hw->phy.ops.read_reg(hw, 2384 IXGBE_MDIO_TX_VENDOR_ALARMS_3, 2385 IXGBE_MDIO_PMA_PMD_DEV_TYPE, 2386 ®); 2387 2388 if (status != IXGBE_SUCCESS) 2389 return status; 2390 2391 /* If PHY FW reset completed bit is set then this is the first 2392 * SW instance after a power on so the PHY FW must be un-stalled. 2393 */ 2394 if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) { 2395 status = hw->phy.ops.read_reg(hw, 2396 IXGBE_MDIO_GLOBAL_RES_PR_10, 2397 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 2398 ®); 2399 2400 if (status != IXGBE_SUCCESS) 2401 return status; 2402 2403 reg &= ~IXGBE_MDIO_POWER_UP_STALL; 2404 2405 status = hw->phy.ops.write_reg(hw, 2406 IXGBE_MDIO_GLOBAL_RES_PR_10, 2407 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 2408 reg); 2409 2410 if (status != IXGBE_SUCCESS) 2411 return status; 2412 } 2413 2414 return status; 2415 } 2416 2417 /** 2418 * ixgbe_setup_kr_x550em - Configure the KR PHY. 2419 * @hw: pointer to hardware structure 2420 **/ 2421 int32_t ixgbe_setup_kr_x550em(struct ixgbe_hw *hw) 2422 { 2423 /* leave link alone for 2.5G */ 2424 if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL) 2425 return IXGBE_SUCCESS; 2426 2427 if (ixgbe_check_reset_blocked(hw)) 2428 return 0; 2429 2430 return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised); 2431 } 2432 2433 /** 2434 * ixgbe_setup_mac_link_sfp_x550em - Setup internal/external the PHY for SFP 2435 * @hw: pointer to hardware structure 2436 * @speed: new link speed 2437 * @autoneg_wait_to_complete: unused 2438 * 2439 * Configure the external PHY and the integrated KR PHY for SFP support. 2440 **/ 2441 int32_t ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw, 2442 ixgbe_link_speed speed, 2443 bool autoneg_wait_to_complete) 2444 { 2445 int32_t ret_val; 2446 uint16_t reg_slice, reg_val; 2447 bool setup_linear = FALSE; 2448 2449 /* Check if SFP module is supported and linear */ 2450 ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear); 2451 2452 /* If no SFP module present, then return success. Return success since 2453 * there is no reason to configure CS4227 and SFP not present error is 2454 * not excepted in the setup MAC link flow. 2455 */ 2456 if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) 2457 return IXGBE_SUCCESS; 2458 2459 if (ret_val != IXGBE_SUCCESS) 2460 return ret_val; 2461 2462 /* Configure internal PHY for KR/KX. */ 2463 ixgbe_setup_kr_speed_x550em(hw, speed); 2464 2465 /* Configure CS4227 LINE side to proper mode. */ 2466 reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + 2467 (hw->bus.lan_id << 12); 2468 if (setup_linear) 2469 reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1; 2470 else 2471 reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; 2472 ret_val = hw->link.ops.write_link(hw, hw->link.addr, reg_slice, 2473 reg_val); 2474 return ret_val; 2475 } 2476 2477 /** 2478 * ixgbe_setup_sfi_x550a - Configure the internal PHY for native SFI mode 2479 * @hw: pointer to hardware structure 2480 * @speed: the link speed to force 2481 * 2482 * Configures the integrated PHY for native SFI mode. Used to connect the 2483 * internal PHY directly to an SFP cage, without autonegotiation. 2484 **/ 2485 int32_t ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed) 2486 { 2487 struct ixgbe_mac_info *mac = &hw->mac; 2488 int32_t status; 2489 uint32_t reg_val; 2490 2491 /* Disable all AN and force speed to 10G Serial. */ 2492 status = mac->ops.read_iosf_sb_reg(hw, 2493 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), 2494 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 2495 if (status != IXGBE_SUCCESS) 2496 return status; 2497 2498 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; 2499 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; 2500 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; 2501 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; 2502 2503 /* Select forced link speed for internal PHY. */ 2504 switch (*speed) { 2505 case IXGBE_LINK_SPEED_10GB_FULL: 2506 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G; 2507 break; 2508 case IXGBE_LINK_SPEED_1GB_FULL: 2509 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G; 2510 break; 2511 default: 2512 /* Other link speeds are not supported by internal PHY. */ 2513 return IXGBE_ERR_LINK_SETUP; 2514 } 2515 2516 status = mac->ops.write_iosf_sb_reg(hw, 2517 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), 2518 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 2519 2520 /* Toggle port SW reset by AN reset. */ 2521 status = ixgbe_restart_an_internal_phy_x550em(hw); 2522 2523 return status; 2524 } 2525 2526 /** 2527 * ixgbe_setup_mac_link_sfp_x550a - Setup internal PHY for SFP 2528 * @hw: pointer to hardware structure 2529 * @speed: new link speed 2530 * @autoneg_wait_to_complete: unused 2531 * 2532 * Configure the integrated PHY for SFP support. 2533 **/ 2534 int32_t ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, 2535 ixgbe_link_speed speed, 2536 bool autoneg_wait_to_complete) 2537 { 2538 int32_t ret_val; 2539 uint16_t reg_phy_ext; 2540 bool setup_linear = FALSE; 2541 uint32_t reg_slice, reg_phy_int, slice_offset; 2542 2543 /* Check if SFP module is supported and linear */ 2544 ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear); 2545 2546 /* If no SFP module present, then return success. Return success since 2547 * SFP not present error is not excepted in the setup MAC link flow. 2548 */ 2549 if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) 2550 return IXGBE_SUCCESS; 2551 2552 if (ret_val != IXGBE_SUCCESS) 2553 return ret_val; 2554 2555 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) { 2556 /* Configure internal PHY for native SFI based on module type */ 2557 ret_val = hw->mac.ops.read_iosf_sb_reg(hw, 2558 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), 2559 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_phy_int); 2560 2561 if (ret_val != IXGBE_SUCCESS) 2562 return ret_val; 2563 2564 reg_phy_int &= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA; 2565 if (!setup_linear) 2566 reg_phy_int |= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR; 2567 2568 ret_val = hw->mac.ops.write_iosf_sb_reg(hw, 2569 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), 2570 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int); 2571 2572 if (ret_val != IXGBE_SUCCESS) 2573 return ret_val; 2574 2575 /* Setup SFI internal link. */ 2576 ret_val = ixgbe_setup_sfi_x550a(hw, &speed); 2577 } else { 2578 /* Configure internal PHY for KR/KX. */ 2579 ixgbe_setup_kr_speed_x550em(hw, speed); 2580 2581 if (hw->phy.addr == 0x0 || hw->phy.addr == 0xFFFF) { 2582 /* Find Address */ 2583 DEBUGOUT("Invalid NW_MNG_IF_SEL.MDIO_PHY_ADD value\n"); 2584 return IXGBE_ERR_PHY_ADDR_INVALID; 2585 } 2586 2587 /* Get external PHY SKU id */ 2588 ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_EFUSE_PDF_SKU, 2589 IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext); 2590 2591 if (ret_val != IXGBE_SUCCESS) 2592 return ret_val; 2593 2594 /* When configuring quad port CS4223, the MAC instance is part 2595 * of the slice offset. 2596 */ 2597 if (reg_phy_ext == IXGBE_CS4223_SKU_ID) 2598 slice_offset = (hw->bus.lan_id + 2599 (hw->bus.instance_id << 1)) << 12; 2600 else 2601 slice_offset = hw->bus.lan_id << 12; 2602 2603 /* Configure CS4227/CS4223 LINE side to proper mode. */ 2604 reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + slice_offset; 2605 2606 ret_val = hw->phy.ops.read_reg(hw, reg_slice, 2607 IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext); 2608 2609 if (ret_val != IXGBE_SUCCESS) 2610 return ret_val; 2611 2612 reg_phy_ext &= ~((IXGBE_CS4227_EDC_MODE_CX1 << 1) | 2613 (IXGBE_CS4227_EDC_MODE_SR << 1)); 2614 2615 if (setup_linear) 2616 reg_phy_ext = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1; 2617 else 2618 reg_phy_ext = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; 2619 ret_val = hw->phy.ops.write_reg(hw, reg_slice, 2620 IXGBE_MDIO_ZERO_DEV_TYPE, reg_phy_ext); 2621 2622 /* Flush previous write with a read */ 2623 ret_val = hw->phy.ops.read_reg(hw, reg_slice, 2624 IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext); 2625 } 2626 return ret_val; 2627 } 2628 2629 /** 2630 * ixgbe_setup_ixfi_x550em_x - MAC specific iXFI configuration 2631 * @hw: pointer to hardware structure 2632 * 2633 * iXfI configuration needed for ixgbe_mac_X550EM_x devices. 2634 **/ 2635 int32_t ixgbe_setup_ixfi_x550em_x(struct ixgbe_hw *hw) 2636 { 2637 struct ixgbe_mac_info *mac = &hw->mac; 2638 int32_t status; 2639 uint32_t reg_val; 2640 2641 /* Disable training protocol FSM. */ 2642 status = mac->ops.read_iosf_sb_reg(hw, 2643 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), 2644 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 2645 if (status != IXGBE_SUCCESS) 2646 return status; 2647 reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL; 2648 status = mac->ops.write_iosf_sb_reg(hw, 2649 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), 2650 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 2651 if (status != IXGBE_SUCCESS) 2652 return status; 2653 2654 /* Disable Flex from training TXFFE. */ 2655 status = mac->ops.read_iosf_sb_reg(hw, 2656 IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id), 2657 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 2658 if (status != IXGBE_SUCCESS) 2659 return status; 2660 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN; 2661 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN; 2662 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN; 2663 status = mac->ops.write_iosf_sb_reg(hw, 2664 IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id), 2665 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 2666 if (status != IXGBE_SUCCESS) 2667 return status; 2668 status = mac->ops.read_iosf_sb_reg(hw, 2669 IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id), 2670 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 2671 if (status != IXGBE_SUCCESS) 2672 return status; 2673 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN; 2674 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN; 2675 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN; 2676 status = mac->ops.write_iosf_sb_reg(hw, 2677 IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id), 2678 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 2679 if (status != IXGBE_SUCCESS) 2680 return status; 2681 2682 /* Enable override for coefficients. */ 2683 status = mac->ops.read_iosf_sb_reg(hw, 2684 IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id), 2685 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 2686 if (status != IXGBE_SUCCESS) 2687 return status; 2688 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN; 2689 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN; 2690 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN; 2691 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN; 2692 status = mac->ops.write_iosf_sb_reg(hw, 2693 IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id), 2694 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 2695 return status; 2696 } 2697 2698 /** 2699 * ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode. 2700 * @hw: pointer to hardware structure 2701 * @speed: the link speed to force 2702 * 2703 * Configures the integrated KR PHY to use iXFI mode. Used to connect an 2704 * internal and external PHY at a specific speed, without autonegotiation. 2705 **/ 2706 int32_t ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed) 2707 { 2708 struct ixgbe_mac_info *mac = &hw->mac; 2709 int32_t status; 2710 uint32_t reg_val; 2711 2712 /* iXFI is only supported with X552 */ 2713 if (mac->type != ixgbe_mac_X550EM_x) 2714 return IXGBE_ERR_LINK_SETUP; 2715 2716 /* Disable AN and force speed to 10G Serial. */ 2717 status = mac->ops.read_iosf_sb_reg(hw, 2718 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 2719 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 2720 if (status != IXGBE_SUCCESS) 2721 return status; 2722 2723 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; 2724 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; 2725 2726 /* Select forced link speed for internal PHY. */ 2727 switch (*speed) { 2728 case IXGBE_LINK_SPEED_10GB_FULL: 2729 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G; 2730 break; 2731 case IXGBE_LINK_SPEED_1GB_FULL: 2732 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G; 2733 break; 2734 default: 2735 /* Other link speeds are not supported by internal KR PHY. */ 2736 return IXGBE_ERR_LINK_SETUP; 2737 } 2738 2739 status = mac->ops.write_iosf_sb_reg(hw, 2740 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 2741 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 2742 if (status != IXGBE_SUCCESS) 2743 return status; 2744 2745 /* Additional configuration needed for x550em_x */ 2746 if (hw->mac.type == ixgbe_mac_X550EM_x) { 2747 status = ixgbe_setup_ixfi_x550em_x(hw); 2748 if (status != IXGBE_SUCCESS) 2749 return status; 2750 } 2751 2752 /* Toggle port SW reset by AN reset. */ 2753 status = ixgbe_restart_an_internal_phy_x550em(hw); 2754 2755 return status; 2756 } 2757 2758 /** 2759 * ixgbe_ext_phy_t_x550em_get_link - Get ext phy link status 2760 * @hw: address of hardware structure 2761 * @link_up: address of boolean to indicate link status 2762 * 2763 * Returns error code if unable to get link status. 2764 */ 2765 int32_t ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up) 2766 { 2767 uint32_t ret; 2768 uint16_t autoneg_status; 2769 2770 *link_up = FALSE; 2771 2772 /* read this twice back to back to indicate current status */ 2773 ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, 2774 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 2775 &autoneg_status); 2776 if (ret != IXGBE_SUCCESS) 2777 return ret; 2778 2779 ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, 2780 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 2781 &autoneg_status); 2782 if (ret != IXGBE_SUCCESS) 2783 return ret; 2784 2785 *link_up = !!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS); 2786 2787 return IXGBE_SUCCESS; 2788 } 2789 2790 /** 2791 * ixgbe_setup_internal_phy_t_x550em - Configure KR PHY to X557 link 2792 * @hw: point to hardware structure 2793 * 2794 * Configures the link between the integrated KR PHY and the external X557 PHY 2795 * The driver will call this function when it gets a link status change 2796 * interrupt from the X557 PHY. This function configures the link speed 2797 * between the PHYs to match the link speed of the BASE-T link. 2798 * 2799 * A return of a non-zero value indicates an error, and the base driver should 2800 * not report link up. 2801 */ 2802 int32_t ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw) 2803 { 2804 ixgbe_link_speed force_speed; 2805 bool link_up; 2806 uint32_t status; 2807 uint16_t speed; 2808 2809 if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) 2810 return IXGBE_ERR_CONFIG; 2811 2812 if (hw->mac.type == ixgbe_mac_X550EM_x && 2813 !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) { 2814 /* If link is down, there is no setup necessary so return */ 2815 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); 2816 if (status != IXGBE_SUCCESS) 2817 return status; 2818 2819 if (!link_up) 2820 return IXGBE_SUCCESS; 2821 2822 status = hw->phy.ops.read_reg(hw, 2823 IXGBE_MDIO_AUTO_NEG_VENDOR_STAT, 2824 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 2825 &speed); 2826 if (status != IXGBE_SUCCESS) 2827 return status; 2828 2829 /* If link is still down - no setup is required so return */ 2830 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); 2831 if (status != IXGBE_SUCCESS) 2832 return status; 2833 if (!link_up) 2834 return IXGBE_SUCCESS; 2835 2836 /* clear everything but the speed and duplex bits */ 2837 speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK; 2838 2839 switch (speed) { 2840 case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL: 2841 force_speed = IXGBE_LINK_SPEED_10GB_FULL; 2842 break; 2843 case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL: 2844 force_speed = IXGBE_LINK_SPEED_1GB_FULL; 2845 break; 2846 default: 2847 /* Internal PHY does not support anything else */ 2848 return IXGBE_ERR_INVALID_LINK_SETTINGS; 2849 } 2850 2851 return ixgbe_setup_ixfi_x550em(hw, &force_speed); 2852 } else { 2853 speed = IXGBE_LINK_SPEED_10GB_FULL | 2854 IXGBE_LINK_SPEED_1GB_FULL; 2855 return ixgbe_setup_kr_speed_x550em(hw, speed); 2856 } 2857 } 2858 2859 /** 2860 * ixgbe_setup_phy_loopback_x550em - Configure the KR PHY for loopback. 2861 * @hw: pointer to hardware structure 2862 * 2863 * Configures the integrated KR PHY to use internal loopback mode. 2864 **/ 2865 int32_t ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw) 2866 { 2867 int32_t status; 2868 uint32_t reg_val; 2869 2870 /* Disable AN and force speed to 10G Serial. */ 2871 status = hw->mac.ops.read_iosf_sb_reg(hw, 2872 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 2873 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 2874 if (status != IXGBE_SUCCESS) 2875 return status; 2876 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; 2877 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; 2878 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G; 2879 status = hw->mac.ops.write_iosf_sb_reg(hw, 2880 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 2881 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 2882 if (status != IXGBE_SUCCESS) 2883 return status; 2884 2885 /* Set near-end loopback clocks. */ 2886 status = hw->mac.ops.read_iosf_sb_reg(hw, 2887 IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id), 2888 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 2889 if (status != IXGBE_SUCCESS) 2890 return status; 2891 reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B; 2892 reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS; 2893 status = hw->mac.ops.write_iosf_sb_reg(hw, 2894 IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id), 2895 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 2896 if (status != IXGBE_SUCCESS) 2897 return status; 2898 2899 /* Set loopback enable. */ 2900 status = hw->mac.ops.read_iosf_sb_reg(hw, 2901 IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id), 2902 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 2903 if (status != IXGBE_SUCCESS) 2904 return status; 2905 reg_val |= IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK; 2906 status = hw->mac.ops.write_iosf_sb_reg(hw, 2907 IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id), 2908 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 2909 if (status != IXGBE_SUCCESS) 2910 return status; 2911 2912 /* Training bypass. */ 2913 status = hw->mac.ops.read_iosf_sb_reg(hw, 2914 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), 2915 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 2916 if (status != IXGBE_SUCCESS) 2917 return status; 2918 reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS; 2919 status = hw->mac.ops.write_iosf_sb_reg(hw, 2920 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), 2921 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 2922 2923 return status; 2924 } 2925 2926 /** 2927 * ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command 2928 * assuming that the semaphore is already obtained. 2929 * @hw: pointer to hardware structure 2930 * @offset: offset of word in the EEPROM to read 2931 * @data: word read from the EEPROM 2932 * 2933 * Reads a 16 bit word from the EEPROM using the hostif. 2934 **/ 2935 int32_t ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, uint16_t offset,uint16_t *data) 2936 { 2937 const uint32_t mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM; 2938 struct ixgbe_hic_read_shadow_ram buffer; 2939 int32_t status; 2940 2941 DEBUGFUNC("ixgbe_read_ee_hostif_X550"); 2942 buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD; 2943 buffer.hdr.req.buf_lenh = 0; 2944 buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN; 2945 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; 2946 2947 /* convert offset from words to bytes */ 2948 buffer.address = htobe32(offset * 2); 2949 /* one word */ 2950 buffer.length = htobe16(sizeof(uint16_t)); 2951 buffer.pad2 = 0; 2952 buffer.pad3 = 0; 2953 2954 status = hw->mac.ops.acquire_swfw_sync(hw, mask); 2955 if (status) 2956 return status; 2957 2958 status = ixgbe_hic_unlocked(hw, (uint32_t *)&buffer, sizeof(buffer), 2959 IXGBE_HI_COMMAND_TIMEOUT); 2960 if (!status) { 2961 *data = (uint16_t)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, 2962 FW_NVM_DATA_OFFSET); 2963 } 2964 2965 hw->mac.ops.release_swfw_sync(hw, mask); 2966 return status; 2967 } 2968 2969 /** 2970 * ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif 2971 * @hw: pointer to hardware structure 2972 * @offset: offset of word in the EEPROM to read 2973 * @words: number of words 2974 * @data: word(s) read from the EEPROM 2975 * 2976 * Reads a 16 bit word(s) from the EEPROM using the hostif. 2977 **/ 2978 int32_t ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, 2979 uint16_t offset, uint16_t words, 2980 uint16_t *data) 2981 { 2982 const uint32_t mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM; 2983 struct ixgbe_hic_read_shadow_ram buffer; 2984 uint32_t current_word = 0; 2985 uint16_t words_to_read; 2986 int32_t status; 2987 uint32_t i; 2988 2989 DEBUGFUNC("ixgbe_read_ee_hostif_buffer_X550"); 2990 2991 /* Take semaphore for the entire operation. */ 2992 status = hw->mac.ops.acquire_swfw_sync(hw, mask); 2993 if (status) { 2994 DEBUGOUT("EEPROM read buffer - semaphore failed\n"); 2995 return status; 2996 } 2997 2998 while (words) { 2999 if (words > FW_MAX_READ_BUFFER_SIZE / 2) 3000 words_to_read = FW_MAX_READ_BUFFER_SIZE / 2; 3001 else 3002 words_to_read = words; 3003 3004 buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD; 3005 buffer.hdr.req.buf_lenh = 0; 3006 buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN; 3007 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; 3008 3009 /* convert offset from words to bytes */ 3010 buffer.address = htobe32((offset + current_word) * 2); 3011 buffer.length = htobe16(words_to_read * 2); 3012 buffer.pad2 = 0; 3013 buffer.pad3 = 0; 3014 3015 status = ixgbe_hic_unlocked(hw, (uint32_t *)&buffer, sizeof(buffer), 3016 IXGBE_HI_COMMAND_TIMEOUT); 3017 3018 if (status) { 3019 DEBUGOUT("Host interface command failed\n"); 3020 goto out; 3021 } 3022 3023 for (i = 0; i < words_to_read; i++) { 3024 uint32_t reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) + 3025 2 * i; 3026 uint32_t value = IXGBE_READ_REG(hw, reg); 3027 3028 data[current_word] = (uint16_t)(value & 0xffff); 3029 current_word++; 3030 i++; 3031 if (i < words_to_read) { 3032 value >>= 16; 3033 data[current_word] = (uint16_t)(value & 0xffff); 3034 current_word++; 3035 } 3036 } 3037 words -= words_to_read; 3038 } 3039 3040 out: 3041 hw->mac.ops.release_swfw_sync(hw, mask); 3042 return status; 3043 } 3044 3045 /** 3046 * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif 3047 * @hw: pointer to hardware structure 3048 * @offset: offset of word in the EEPROM to write 3049 * @data: word write to the EEPROM 3050 * 3051 * Write a 16 bit word to the EEPROM using the hostif. 3052 **/ 3053 int32_t ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, uint16_t offset, 3054 uint16_t data) 3055 { 3056 int32_t status; 3057 struct ixgbe_hic_write_shadow_ram buffer; 3058 3059 DEBUGFUNC("ixgbe_write_ee_hostif_data_X550"); 3060 3061 buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD; 3062 buffer.hdr.req.buf_lenh = 0; 3063 buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN; 3064 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; 3065 3066 /* one word */ 3067 buffer.length = htobe16(sizeof(uint16_t)); 3068 buffer.data = data; 3069 buffer.address = htobe32(offset * 2); 3070 3071 status = ixgbe_host_interface_command(hw, (uint32_t *)&buffer, 3072 sizeof(buffer), 3073 IXGBE_HI_COMMAND_TIMEOUT, FALSE); 3074 3075 return status; 3076 } 3077 3078 /** 3079 * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif 3080 * @hw: pointer to hardware structure 3081 * @offset: offset of word in the EEPROM to write 3082 * @data: word write to the EEPROM 3083 * 3084 * Write a 16 bit word to the EEPROM using the hostif. 3085 **/ 3086 int32_t ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, uint16_t offset, 3087 uint16_t data) 3088 { 3089 int32_t status = IXGBE_SUCCESS; 3090 3091 DEBUGFUNC("ixgbe_write_ee_hostif_X550"); 3092 3093 if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 3094 IXGBE_SUCCESS) { 3095 status = ixgbe_write_ee_hostif_data_X550(hw, offset, data); 3096 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 3097 } else { 3098 DEBUGOUT("write ee hostif failed to get semaphore"); 3099 status = IXGBE_ERR_SWFW_SYNC; 3100 } 3101 3102 return status; 3103 } 3104 3105 /** 3106 * ixgbe_checksum_ptr_x550 - Checksum one pointer region 3107 * @hw: pointer to hardware structure 3108 * @ptr: pointer offset in eeprom 3109 * @size: size of section pointed by ptr, if 0 first word will be used as size 3110 * @csum: address of checksum to update 3111 * @buffer: pointer to buffer containing calculated checksum 3112 * @buffer_size: size of buffer 3113 * 3114 * Returns error status for any failure 3115 */ 3116 int32_t ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, uint16_t ptr, 3117 uint16_t size, uint16_t *csum, uint16_t *buffer, 3118 uint32_t buffer_size) 3119 { 3120 uint16_t buf[256]; 3121 int32_t status; 3122 uint16_t length, bufsz, i, start; 3123 uint16_t *local_buffer; 3124 3125 bufsz = sizeof(buf) / sizeof(buf[0]); 3126 3127 /* Read a chunk at the pointer location */ 3128 if (!buffer) { 3129 status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf); 3130 if (status) { 3131 DEBUGOUT("Failed to read EEPROM image\n"); 3132 return status; 3133 } 3134 local_buffer = buf; 3135 } else { 3136 if (buffer_size < ptr) 3137 return IXGBE_ERR_PARAM; 3138 local_buffer = &buffer[ptr]; 3139 } 3140 3141 if (size) { 3142 start = 0; 3143 length = size; 3144 } else { 3145 start = 1; 3146 length = local_buffer[0]; 3147 3148 /* Skip pointer section if length is invalid. */ 3149 if (length == 0xFFFF || length == 0 || 3150 (ptr + length) >= hw->eeprom.word_size) 3151 return IXGBE_SUCCESS; 3152 } 3153 3154 if (buffer && ((uint32_t)start + (uint32_t)length > buffer_size)) 3155 return IXGBE_ERR_PARAM; 3156 3157 for (i = start; length; i++, length--) { 3158 if (i == bufsz && !buffer) { 3159 ptr += bufsz; 3160 i = 0; 3161 if (length < bufsz) 3162 bufsz = length; 3163 3164 /* Read a chunk at the pointer location */ 3165 status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, 3166 bufsz, buf); 3167 if (status) { 3168 DEBUGOUT("Failed to read EEPROM image\n"); 3169 return status; 3170 } 3171 } 3172 *csum += local_buffer[i]; 3173 } 3174 return IXGBE_SUCCESS; 3175 } 3176 3177 /** 3178 * ixgbe_calc_checksum_X550 - Calculates and returns the checksum 3179 * @hw: pointer to hardware structure 3180 * @buffer: pointer to buffer containing calculated checksum 3181 * @buffer_size: size of buffer 3182 * 3183 * Returns a negative error code on error, or the 16-bit checksum 3184 **/ 3185 int32_t ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, uint16_t *buffer, 3186 uint32_t buffer_size) 3187 { 3188 uint16_t eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1]; 3189 uint16_t *local_buffer; 3190 int32_t status; 3191 uint16_t checksum = 0; 3192 uint16_t pointer, i, size; 3193 3194 DEBUGFUNC("ixgbe_calc_eeprom_checksum_X550"); 3195 3196 hw->eeprom.ops.init_params(hw); 3197 3198 if (!buffer) { 3199 /* Read pointer area */ 3200 status = ixgbe_read_ee_hostif_buffer_X550(hw, 0, 3201 IXGBE_EEPROM_LAST_WORD + 1, 3202 eeprom_ptrs); 3203 if (status) { 3204 DEBUGOUT("Failed to read EEPROM image\n"); 3205 return status; 3206 } 3207 local_buffer = eeprom_ptrs; 3208 } else { 3209 if (buffer_size < IXGBE_EEPROM_LAST_WORD) 3210 return IXGBE_ERR_PARAM; 3211 local_buffer = buffer; 3212 } 3213 3214 /* 3215 * For X550 hardware include 0x0-0x41 in the checksum, skip the 3216 * checksum word itself 3217 */ 3218 for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++) 3219 if (i != IXGBE_EEPROM_CHECKSUM) 3220 checksum += local_buffer[i]; 3221 3222 /* 3223 * Include all data from pointers 0x3, 0x6-0xE. This excludes the 3224 * FW, PHY module, and PCIe Expansion/Option ROM pointers. 3225 */ 3226 for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) { 3227 if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR) 3228 continue; 3229 3230 pointer = local_buffer[i]; 3231 3232 /* Skip pointer section if the pointer is invalid. */ 3233 if (pointer == 0xFFFF || pointer == 0 || 3234 pointer >= hw->eeprom.word_size) 3235 continue; 3236 3237 switch (i) { 3238 case IXGBE_PCIE_GENERAL_PTR: 3239 size = IXGBE_IXGBE_PCIE_GENERAL_SIZE; 3240 break; 3241 case IXGBE_PCIE_CONFIG0_PTR: 3242 case IXGBE_PCIE_CONFIG1_PTR: 3243 size = IXGBE_PCIE_CONFIG_SIZE; 3244 break; 3245 default: 3246 size = 0; 3247 break; 3248 } 3249 3250 status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum, 3251 buffer, buffer_size); 3252 if (status) 3253 return status; 3254 } 3255 3256 checksum = (uint16_t)IXGBE_EEPROM_SUM - checksum; 3257 3258 return (int32_t)checksum; 3259 } 3260 3261 /** 3262 * ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum 3263 * @hw: pointer to hardware structure 3264 * 3265 * Returns a negative error code on error, or the 16-bit checksum 3266 **/ 3267 int32_t ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw) 3268 { 3269 return ixgbe_calc_checksum_X550(hw, NULL, 0); 3270 } 3271 3272 /** 3273 * ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum 3274 * @hw: pointer to hardware structure 3275 * @checksum_val: calculated checksum 3276 * 3277 * Performs checksum calculation and validates the EEPROM checksum. If the 3278 * caller does not need checksum_val, the value can be NULL. 3279 **/ 3280 int32_t ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, uint16_t *checksum_val) 3281 { 3282 int32_t status; 3283 uint16_t checksum; 3284 uint16_t read_checksum = 0; 3285 3286 DEBUGFUNC("ixgbe_validate_eeprom_checksum_X550"); 3287 3288 /* Read the first word from the EEPROM. If this times out or fails, do 3289 * not continue or we could be in for a very long wait while every 3290 * EEPROM read fails 3291 */ 3292 status = hw->eeprom.ops.read(hw, 0, &checksum); 3293 if (status) { 3294 DEBUGOUT("EEPROM read failed\n"); 3295 return status; 3296 } 3297 3298 status = hw->eeprom.ops.calc_checksum(hw); 3299 if (status < 0) 3300 return status; 3301 3302 checksum = (uint16_t)(status & 0xffff); 3303 3304 status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM, 3305 &read_checksum); 3306 if (status) 3307 return status; 3308 3309 /* Verify read checksum from EEPROM is the same as 3310 * calculated checksum 3311 */ 3312 if (read_checksum != checksum) { 3313 status = IXGBE_ERR_EEPROM_CHECKSUM; 3314 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, 3315 "Invalid EEPROM checksum"); 3316 } 3317 3318 /* If the user cares, return the calculated checksum */ 3319 if (checksum_val) 3320 *checksum_val = checksum; 3321 3322 return status; 3323 } 3324 3325 /** 3326 * ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash 3327 * @hw: pointer to hardware structure 3328 * 3329 * After writing EEPROM to shadow RAM using EEWR register, software calculates 3330 * checksum and updates the EEPROM and instructs the hardware to update 3331 * the flash. 3332 **/ 3333 int32_t ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw) 3334 { 3335 int32_t status; 3336 uint16_t checksum = 0; 3337 3338 DEBUGFUNC("ixgbe_update_eeprom_checksum_X550"); 3339 3340 /* Read the first word from the EEPROM. If this times out or fails, do 3341 * not continue or we could be in for a very long wait while every 3342 * EEPROM read fails 3343 */ 3344 status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum); 3345 if (status) { 3346 DEBUGOUT("EEPROM read failed\n"); 3347 return status; 3348 } 3349 3350 status = ixgbe_calc_eeprom_checksum_X550(hw); 3351 if (status < 0) 3352 return status; 3353 3354 checksum = (uint16_t)(status & 0xffff); 3355 3356 status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM, 3357 checksum); 3358 if (status) 3359 return status; 3360 3361 status = ixgbe_update_flash_X550(hw); 3362 3363 return status; 3364 } 3365 3366 /** 3367 * ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device 3368 * @hw: pointer to hardware structure 3369 * 3370 * Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash. 3371 **/ 3372 int32_t ixgbe_update_flash_X550(struct ixgbe_hw *hw) 3373 { 3374 int32_t status = IXGBE_SUCCESS; 3375 union ixgbe_hic_hdr2 buffer; 3376 3377 DEBUGFUNC("ixgbe_update_flash_X550"); 3378 3379 buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD; 3380 buffer.req.buf_lenh = 0; 3381 buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN; 3382 buffer.req.checksum = FW_DEFAULT_CHECKSUM; 3383 3384 status = ixgbe_host_interface_command(hw, (uint32_t *)&buffer, 3385 sizeof(buffer), 3386 IXGBE_HI_COMMAND_TIMEOUT, FALSE); 3387 3388 return status; 3389 } 3390 3391 /** 3392 * ixgbe_get_supported_physical_layer_X550em - Returns physical layer type 3393 * @hw: pointer to hardware structure 3394 * 3395 * Determines physical layer capabilities of the current configuration. 3396 **/ 3397 uint64_t ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw) 3398 { 3399 uint64_t physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; 3400 uint16_t ext_ability = 0; 3401 3402 DEBUGFUNC("ixgbe_get_supported_physical_layer_X550em"); 3403 3404 hw->phy.ops.identify(hw); 3405 3406 switch (hw->phy.type) { 3407 case ixgbe_phy_x550em_kr: 3408 if (hw->mac.type == ixgbe_mac_X550EM_a) { 3409 if (hw->phy.nw_mng_if_sel & 3410 IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) { 3411 physical_layer = 3412 IXGBE_PHYSICAL_LAYER_2500BASE_KX; 3413 break; 3414 } else if (hw->device_id == 3415 IXGBE_DEV_ID_X550EM_A_KR_L) { 3416 physical_layer = 3417 IXGBE_PHYSICAL_LAYER_1000BASE_KX; 3418 break; 3419 } 3420 } 3421 /* fall through */ 3422 case ixgbe_phy_x550em_xfi: 3423 physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR | 3424 IXGBE_PHYSICAL_LAYER_1000BASE_KX; 3425 break; 3426 case ixgbe_phy_x550em_kx4: 3427 physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4 | 3428 IXGBE_PHYSICAL_LAYER_1000BASE_KX; 3429 break; 3430 case ixgbe_phy_x550em_ext_t: 3431 hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, 3432 IXGBE_MDIO_PMA_PMD_DEV_TYPE, 3433 &ext_ability); 3434 if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) 3435 physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; 3436 if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) 3437 physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; 3438 break; 3439 case ixgbe_phy_fw: 3440 if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_1GB_FULL) 3441 physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; 3442 if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_100_FULL) 3443 physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; 3444 if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_10_FULL) 3445 physical_layer |= IXGBE_PHYSICAL_LAYER_10BASE_T; 3446 break; 3447 case ixgbe_phy_sgmii: 3448 physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX; 3449 break; 3450 case ixgbe_phy_ext_1g_t: 3451 physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T; 3452 break; 3453 default: 3454 break; 3455 } 3456 3457 if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) 3458 physical_layer = ixgbe_get_supported_phy_sfp_layer_generic(hw); 3459 3460 return physical_layer; 3461 } 3462 3463 /** 3464 * ixgbe_get_bus_info_x550em - Set PCI bus info 3465 * @hw: pointer to hardware structure 3466 * 3467 * Sets bus link width and speed to unknown because X550em is 3468 * not a PCI device. 3469 **/ 3470 int32_t ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw) 3471 { 3472 3473 DEBUGFUNC("ixgbe_get_bus_info_x550em"); 3474 3475 hw->bus.width = ixgbe_bus_width_unknown; 3476 hw->bus.speed = ixgbe_bus_speed_unknown; 3477 3478 hw->mac.ops.set_lan_id(hw); 3479 3480 return IXGBE_SUCCESS; 3481 } 3482 3483 /** 3484 * ixgbe_disable_rx_x550 - Disable RX unit 3485 * @hw: pointer to hardware structure 3486 * 3487 * Enables the Rx DMA unit for x550 3488 **/ 3489 void ixgbe_disable_rx_x550(struct ixgbe_hw *hw) 3490 { 3491 uint32_t rxctrl, pfdtxgswc; 3492 int32_t status; 3493 struct ixgbe_hic_disable_rxen fw_cmd; 3494 3495 DEBUGFUNC("ixgbe_enable_rx_dma_x550"); 3496 3497 rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); 3498 if (rxctrl & IXGBE_RXCTRL_RXEN) { 3499 pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC); 3500 if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) { 3501 pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN; 3502 IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc); 3503 hw->mac.set_lben = TRUE; 3504 } else { 3505 hw->mac.set_lben = FALSE; 3506 } 3507 3508 fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD; 3509 fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN; 3510 fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; 3511 fw_cmd.port_number = (uint8_t)hw->bus.lan_id; 3512 3513 status = ixgbe_host_interface_command(hw, (uint32_t *)&fw_cmd, 3514 sizeof(struct ixgbe_hic_disable_rxen), 3515 IXGBE_HI_COMMAND_TIMEOUT, TRUE); 3516 3517 /* If we fail - disable RX using register write */ 3518 if (status) { 3519 rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); 3520 if (rxctrl & IXGBE_RXCTRL_RXEN) { 3521 rxctrl &= ~IXGBE_RXCTRL_RXEN; 3522 IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl); 3523 } 3524 } 3525 } 3526 } 3527 3528 /** 3529 * ixgbe_enter_lplu_x550em - Transition to low power states 3530 * @hw: pointer to hardware structure 3531 * 3532 * Configures Low Power Link Up on transition to low power states 3533 * (from D0 to non-D0). Link is required to enter LPLU so avoid resetting the 3534 * X557 PHY immediately prior to entering LPLU. 3535 **/ 3536 int32_t ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw) 3537 { 3538 uint16_t an_10g_cntl_reg, autoneg_reg, speed; 3539 int32_t status; 3540 ixgbe_link_speed lcd_speed; 3541 uint32_t save_autoneg; 3542 bool link_up; 3543 3544 /* SW LPLU not required on later HW revisions. */ 3545 if ((hw->mac.type == ixgbe_mac_X550EM_x) && 3546 (IXGBE_FUSES0_REV_MASK & 3547 IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)))) 3548 return IXGBE_SUCCESS; 3549 3550 /* If blocked by MNG FW, then don't restart AN */ 3551 if (ixgbe_check_reset_blocked(hw)) 3552 return IXGBE_SUCCESS; 3553 3554 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); 3555 if (status != IXGBE_SUCCESS) 3556 return status; 3557 3558 status = hw->eeprom.ops.read(hw, NVM_INIT_CTRL_3, &hw->eeprom.ctrl_word_3); 3559 if (status != IXGBE_SUCCESS) 3560 return status; 3561 3562 /* If link is down, LPLU disabled in NVM, WoL disabled, or manageability 3563 * disabled, then force link down by entering low power mode. 3564 */ 3565 if (!link_up || !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) || 3566 !(hw->wol_enabled || ixgbe_mng_present(hw))) 3567 return ixgbe_set_copper_phy_power(hw, FALSE); 3568 3569 /* Determine LCD */ 3570 status = ixgbe_get_lcd_t_x550em(hw, &lcd_speed); 3571 3572 if (status != IXGBE_SUCCESS) 3573 return status; 3574 3575 /* If no valid LCD link speed, then force link down and exit. */ 3576 if (lcd_speed == IXGBE_LINK_SPEED_UNKNOWN) 3577 return ixgbe_set_copper_phy_power(hw, FALSE); 3578 3579 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT, 3580 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 3581 &speed); 3582 3583 if (status != IXGBE_SUCCESS) 3584 return status; 3585 3586 /* If no link now, speed is invalid so take link down */ 3587 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); 3588 if (status != IXGBE_SUCCESS) 3589 return ixgbe_set_copper_phy_power(hw, FALSE); 3590 3591 /* clear everything but the speed bits */ 3592 speed &= IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK; 3593 3594 /* If current speed is already LCD, then exit. */ 3595 if (((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB) && 3596 (lcd_speed == IXGBE_LINK_SPEED_1GB_FULL)) || 3597 ((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB) && 3598 (lcd_speed == IXGBE_LINK_SPEED_10GB_FULL))) 3599 return status; 3600 3601 /* Clear AN completed indication */ 3602 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM, 3603 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 3604 &autoneg_reg); 3605 3606 if (status != IXGBE_SUCCESS) 3607 return status; 3608 3609 status = hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, 3610 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 3611 &an_10g_cntl_reg); 3612 3613 if (status != IXGBE_SUCCESS) 3614 return status; 3615 3616 status = hw->phy.ops.read_reg(hw, 3617 IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, 3618 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 3619 &autoneg_reg); 3620 3621 if (status != IXGBE_SUCCESS) 3622 return status; 3623 3624 save_autoneg = hw->phy.autoneg_advertised; 3625 3626 /* Setup link at least common link speed */ 3627 status = hw->mac.ops.setup_link(hw, lcd_speed, FALSE); 3628 3629 /* restore autoneg from before setting lplu speed */ 3630 hw->phy.autoneg_advertised = save_autoneg; 3631 3632 return status; 3633 } 3634 3635 /** 3636 * ixgbe_get_lcd_x550em - Determine lowest common denominator 3637 * @hw: pointer to hardware structure 3638 * @lcd_speed: pointer to lowest common link speed 3639 * 3640 * Determine lowest common link speed with link partner. 3641 **/ 3642 int32_t ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed) 3643 { 3644 uint16_t an_lp_status; 3645 int32_t status; 3646 uint16_t word = hw->eeprom.ctrl_word_3; 3647 3648 *lcd_speed = IXGBE_LINK_SPEED_UNKNOWN; 3649 3650 status = hw->phy.ops.read_reg(hw, IXGBE_AUTO_NEG_LP_STATUS, 3651 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 3652 &an_lp_status); 3653 3654 if (status != IXGBE_SUCCESS) 3655 return status; 3656 3657 /* If link partner advertised 1G, return 1G */ 3658 if (an_lp_status & IXGBE_AUTO_NEG_LP_1000BASE_CAP) { 3659 *lcd_speed = IXGBE_LINK_SPEED_1GB_FULL; 3660 return status; 3661 } 3662 3663 /* If 10G disabled for LPLU via NVM D10GMP, then return no valid LCD */ 3664 if ((hw->bus.lan_id && (word & NVM_INIT_CTRL_3_D10GMP_PORT1)) || 3665 (word & NVM_INIT_CTRL_3_D10GMP_PORT0)) 3666 return status; 3667 3668 /* Link partner not capable of lower speeds, return 10G */ 3669 *lcd_speed = IXGBE_LINK_SPEED_10GB_FULL; 3670 return status; 3671 } 3672 3673 /** 3674 * ixgbe_setup_fc_X550em - Set up flow control 3675 * @hw: pointer to hardware structure 3676 * 3677 * Called at init time to set up flow control. 3678 **/ 3679 int32_t ixgbe_setup_fc_X550em(struct ixgbe_hw *hw) 3680 { 3681 int32_t ret_val = IXGBE_SUCCESS; 3682 uint32_t pause, asm_dir, reg_val; 3683 3684 DEBUGFUNC("ixgbe_setup_fc_X550em"); 3685 3686 /* Validate the requested mode */ 3687 if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { 3688 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, 3689 "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); 3690 ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; 3691 goto out; 3692 } 3693 3694 /* 10gig parts do not have a word in the EEPROM to determine the 3695 * default flow control setting, so we explicitly set it to full. 3696 */ 3697 if (hw->fc.requested_mode == ixgbe_fc_default) 3698 hw->fc.requested_mode = ixgbe_fc_full; 3699 3700 /* Determine PAUSE and ASM_DIR bits. */ 3701 switch (hw->fc.requested_mode) { 3702 case ixgbe_fc_none: 3703 pause = 0; 3704 asm_dir = 0; 3705 break; 3706 case ixgbe_fc_tx_pause: 3707 pause = 0; 3708 asm_dir = 1; 3709 break; 3710 case ixgbe_fc_rx_pause: 3711 /* Rx Flow control is enabled and Tx Flow control is 3712 * disabled by software override. Since there really 3713 * isn't a way to advertise that we are capable of RX 3714 * Pause ONLY, we will advertise that we support both 3715 * symmetric and asymmetric Rx PAUSE, as such we fall 3716 * through to the fc_full statement. Later, we will 3717 * disable the adapter's ability to send PAUSE frames. 3718 */ 3719 case ixgbe_fc_full: 3720 pause = 1; 3721 asm_dir = 1; 3722 break; 3723 default: 3724 ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, 3725 "Flow control param set incorrectly\n"); 3726 ret_val = IXGBE_ERR_CONFIG; 3727 goto out; 3728 } 3729 3730 switch (hw->device_id) { 3731 case IXGBE_DEV_ID_X550EM_X_KR: 3732 case IXGBE_DEV_ID_X550EM_A_KR: 3733 case IXGBE_DEV_ID_X550EM_A_KR_L: 3734 ret_val = hw->mac.ops.read_iosf_sb_reg(hw, 3735 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), 3736 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 3737 if (ret_val != IXGBE_SUCCESS) 3738 goto out; 3739 reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE | 3740 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE); 3741 if (pause) 3742 reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE; 3743 if (asm_dir) 3744 reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE; 3745 ret_val = hw->mac.ops.write_iosf_sb_reg(hw, 3746 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), 3747 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 3748 3749 /* This device does not fully support AN. */ 3750 hw->fc.disable_fc_autoneg = TRUE; 3751 break; 3752 case IXGBE_DEV_ID_X550EM_X_XFI: 3753 hw->fc.disable_fc_autoneg = TRUE; 3754 break; 3755 default: 3756 break; 3757 } 3758 3759 out: 3760 return ret_val; 3761 } 3762 3763 /** 3764 * ixgbe_fc_autoneg_backplane_x550em_a - Enable flow control IEEE clause 37 3765 * @hw: pointer to hardware structure 3766 * 3767 * Enable flow control according to IEEE clause 37. 3768 **/ 3769 void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw) 3770 { 3771 uint32_t link_s1, lp_an_page_low, an_cntl_1; 3772 int32_t status = IXGBE_ERR_FC_NOT_NEGOTIATED; 3773 ixgbe_link_speed speed; 3774 bool link_up; 3775 3776 /* AN should have completed when the cable was plugged in. 3777 * Look for reasons to bail out. Bail out if: 3778 * - FC autoneg is disabled, or if 3779 * - link is not up. 3780 */ 3781 if (hw->fc.disable_fc_autoneg) { 3782 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, 3783 "Flow control autoneg is disabled"); 3784 goto out; 3785 } 3786 3787 hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); 3788 if (!link_up) { 3789 ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down"); 3790 goto out; 3791 } 3792 3793 /* Check at auto-negotiation has completed */ 3794 status = hw->mac.ops.read_iosf_sb_reg(hw, 3795 IXGBE_KRM_LINK_S1(hw->bus.lan_id), 3796 IXGBE_SB_IOSF_TARGET_KR_PHY, &link_s1); 3797 3798 if (status != IXGBE_SUCCESS || 3799 (link_s1 & IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE) == 0) { 3800 DEBUGOUT("Auto-Negotiation did not complete\n"); 3801 status = IXGBE_ERR_FC_NOT_NEGOTIATED; 3802 goto out; 3803 } 3804 3805 /* Read the 10g AN autoc and LP ability registers and resolve 3806 * local flow control settings accordingly 3807 */ 3808 status = hw->mac.ops.read_iosf_sb_reg(hw, 3809 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), 3810 IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl_1); 3811 3812 if (status != IXGBE_SUCCESS) { 3813 DEBUGOUT("Auto-Negotiation did not complete\n"); 3814 goto out; 3815 } 3816 3817 status = hw->mac.ops.read_iosf_sb_reg(hw, 3818 IXGBE_KRM_LP_BASE_PAGE_HIGH(hw->bus.lan_id), 3819 IXGBE_SB_IOSF_TARGET_KR_PHY, &lp_an_page_low); 3820 3821 if (status != IXGBE_SUCCESS) { 3822 DEBUGOUT("Auto-Negotiation did not complete\n"); 3823 goto out; 3824 } 3825 3826 status = ixgbe_negotiate_fc(hw, an_cntl_1, lp_an_page_low, 3827 IXGBE_KRM_AN_CNTL_1_SYM_PAUSE, 3828 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE, 3829 IXGBE_KRM_LP_BASE_PAGE_HIGH_SYM_PAUSE, 3830 IXGBE_KRM_LP_BASE_PAGE_HIGH_ASM_PAUSE); 3831 3832 out: 3833 if (status == IXGBE_SUCCESS) { 3834 hw->fc.fc_was_autonegged = TRUE; 3835 } else { 3836 hw->fc.fc_was_autonegged = FALSE; 3837 hw->fc.current_mode = hw->fc.requested_mode; 3838 } 3839 } 3840 3841 /** 3842 * ixgbe_fc_autoneg_fiber_x550em_a - passthrough FC settings 3843 * @hw: pointer to hardware structure 3844 * 3845 **/ 3846 void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw) 3847 { 3848 hw->fc.fc_was_autonegged = FALSE; 3849 hw->fc.current_mode = hw->fc.requested_mode; 3850 } 3851 3852 /** 3853 * ixgbe_fc_autoneg_sgmii_x550em_a - Enable flow control IEEE clause 37 3854 * @hw: pointer to hardware structure 3855 * 3856 * Enable flow control according to IEEE clause 37. 3857 **/ 3858 void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw) 3859 { 3860 int32_t status = IXGBE_ERR_FC_NOT_NEGOTIATED; 3861 uint32_t info[FW_PHY_ACT_DATA_COUNT] = { 0 }; 3862 ixgbe_link_speed speed; 3863 bool link_up; 3864 3865 /* AN should have completed when the cable was plugged in. 3866 * Look for reasons to bail out. Bail out if: 3867 * - FC autoneg is disabled, or if 3868 * - link is not up. 3869 */ 3870 if (hw->fc.disable_fc_autoneg) { 3871 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, 3872 "Flow control autoneg is disabled"); 3873 goto out; 3874 } 3875 3876 hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); 3877 if (!link_up) { 3878 ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down"); 3879 goto out; 3880 } 3881 3882 /* Check if auto-negotiation has completed */ 3883 status = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &info); 3884 if (status != IXGBE_SUCCESS || 3885 !(info[0] & FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE)) { 3886 DEBUGOUT("Auto-Negotiation did not complete\n"); 3887 status = IXGBE_ERR_FC_NOT_NEGOTIATED; 3888 goto out; 3889 } 3890 3891 /* Negotiate the flow control */ 3892 status = ixgbe_negotiate_fc(hw, info[0], info[0], 3893 FW_PHY_ACT_GET_LINK_INFO_FC_RX, 3894 FW_PHY_ACT_GET_LINK_INFO_FC_TX, 3895 FW_PHY_ACT_GET_LINK_INFO_LP_FC_RX, 3896 FW_PHY_ACT_GET_LINK_INFO_LP_FC_TX); 3897 3898 out: 3899 if (status == IXGBE_SUCCESS) { 3900 hw->fc.fc_was_autonegged = TRUE; 3901 } else { 3902 hw->fc.fc_was_autonegged = FALSE; 3903 hw->fc.current_mode = hw->fc.requested_mode; 3904 } 3905 } 3906 3907 /** 3908 * ixgbe_setup_fc_backplane_x550em_a - Set up flow control 3909 * @hw: pointer to hardware structure 3910 * 3911 * Called at init time to set up flow control. 3912 **/ 3913 int32_t ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw) 3914 { 3915 int32_t status = IXGBE_SUCCESS; 3916 uint32_t an_cntl = 0; 3917 3918 DEBUGFUNC("ixgbe_setup_fc_backplane_x550em_a"); 3919 3920 /* Validate the requested mode */ 3921 if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { 3922 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, 3923 "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); 3924 return IXGBE_ERR_INVALID_LINK_SETTINGS; 3925 } 3926 3927 if (hw->fc.requested_mode == ixgbe_fc_default) 3928 hw->fc.requested_mode = ixgbe_fc_full; 3929 3930 /* Set up the 1G and 10G flow control advertisement registers so the 3931 * HW will be able to do FC autoneg once the cable is plugged in. If 3932 * we link at 10G, the 1G advertisement is harmless and vice versa. 3933 */ 3934 status = hw->mac.ops.read_iosf_sb_reg(hw, 3935 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), 3936 IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl); 3937 3938 if (status != IXGBE_SUCCESS) { 3939 DEBUGOUT("Auto-Negotiation did not complete\n"); 3940 return status; 3941 } 3942 3943 /* The possible values of fc.requested_mode are: 3944 * 0: Flow control is completely disabled 3945 * 1: Rx flow control is enabled (we can receive pause frames, 3946 * but not send pause frames). 3947 * 2: Tx flow control is enabled (we can send pause frames but 3948 * we do not support receiving pause frames). 3949 * 3: Both Rx and Tx flow control (symmetric) are enabled. 3950 * other: Invalid. 3951 */ 3952 switch (hw->fc.requested_mode) { 3953 case ixgbe_fc_none: 3954 /* Flow control completely disabled by software override. */ 3955 an_cntl &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE | 3956 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE); 3957 break; 3958 case ixgbe_fc_tx_pause: 3959 /* Tx Flow control is enabled, and Rx Flow control is 3960 * disabled by software override. 3961 */ 3962 an_cntl |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE; 3963 an_cntl &= ~IXGBE_KRM_AN_CNTL_1_SYM_PAUSE; 3964 break; 3965 case ixgbe_fc_rx_pause: 3966 /* Rx Flow control is enabled and Tx Flow control is 3967 * disabled by software override. Since there really 3968 * isn't a way to advertise that we are capable of RX 3969 * Pause ONLY, we will advertise that we support both 3970 * symmetric and asymmetric Rx PAUSE, as such we fall 3971 * through to the fc_full statement. Later, we will 3972 * disable the adapter's ability to send PAUSE frames. 3973 */ 3974 case ixgbe_fc_full: 3975 /* Flow control (both Rx and Tx) is enabled by SW override. */ 3976 an_cntl |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE | 3977 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE; 3978 break; 3979 default: 3980 ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, 3981 "Flow control param set incorrectly\n"); 3982 return IXGBE_ERR_CONFIG; 3983 } 3984 3985 status = hw->mac.ops.write_iosf_sb_reg(hw, 3986 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), 3987 IXGBE_SB_IOSF_TARGET_KR_PHY, an_cntl); 3988 3989 /* Restart auto-negotiation. */ 3990 status = ixgbe_restart_an_internal_phy_x550em(hw); 3991 3992 return status; 3993 } 3994 3995 /** 3996 * ixgbe_set_mux - Set mux for port 1 access with CS4227 3997 * @hw: pointer to hardware structure 3998 * @state: set mux if 1, clear if 0 3999 */ 4000 void ixgbe_set_mux(struct ixgbe_hw *hw, uint8_t state) 4001 { 4002 uint32_t esdp; 4003 4004 if (!hw->bus.lan_id) 4005 return; 4006 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); 4007 if (state) 4008 esdp |= IXGBE_ESDP_SDP1; 4009 else 4010 esdp &= ~IXGBE_ESDP_SDP1; 4011 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); 4012 IXGBE_WRITE_FLUSH(hw); 4013 } 4014 4015 /** 4016 * ixgbe_acquire_swfw_sync_X550em - Acquire SWFW semaphore 4017 * @hw: pointer to hardware structure 4018 * @mask: Mask to specify which semaphore to acquire 4019 * 4020 * Acquires the SWFW semaphore and sets the I2C MUX 4021 **/ 4022 int32_t ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, uint32_t mask) 4023 { 4024 int32_t status; 4025 4026 DEBUGFUNC("ixgbe_acquire_swfw_sync_X550em"); 4027 4028 status = ixgbe_acquire_swfw_sync_X540(hw, mask); 4029 if (status) 4030 return status; 4031 4032 if (mask & IXGBE_GSSR_I2C_MASK) 4033 ixgbe_set_mux(hw, 1); 4034 4035 return IXGBE_SUCCESS; 4036 } 4037 4038 /** 4039 * ixgbe_release_swfw_sync_X550em - Release SWFW semaphore 4040 * @hw: pointer to hardware structure 4041 * @mask: Mask to specify which semaphore to release 4042 * 4043 * Releases the SWFW semaphore and sets the I2C MUX 4044 **/ 4045 void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, uint32_t mask) 4046 { 4047 DEBUGFUNC("ixgbe_release_swfw_sync_X550em"); 4048 4049 if (mask & IXGBE_GSSR_I2C_MASK) 4050 ixgbe_set_mux(hw, 0); 4051 4052 ixgbe_release_swfw_sync_X540(hw, mask); 4053 } 4054 4055 /** 4056 * ixgbe_acquire_swfw_sync_X550a - Acquire SWFW semaphore 4057 * @hw: pointer to hardware structure 4058 * @mask: Mask to specify which semaphore to acquire 4059 * 4060 * Acquires the SWFW semaphore and get the shared phy token as needed 4061 */ 4062 int32_t ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *hw, uint32_t mask) 4063 { 4064 uint32_t hmask = mask & ~IXGBE_GSSR_TOKEN_SM; 4065 int retries = FW_PHY_TOKEN_RETRIES; 4066 int32_t status = IXGBE_SUCCESS; 4067 4068 DEBUGFUNC("ixgbe_acquire_swfw_sync_X550a"); 4069 4070 while (--retries) { 4071 status = IXGBE_SUCCESS; 4072 if (hmask) 4073 status = ixgbe_acquire_swfw_sync_X540(hw, hmask); 4074 if (status) { 4075 DEBUGOUT1("Could not acquire SWFW semaphore, Status = %d\n", 4076 status); 4077 return status; 4078 } 4079 if (!(mask & IXGBE_GSSR_TOKEN_SM)) 4080 return IXGBE_SUCCESS; 4081 4082 status = ixgbe_get_phy_token(hw); 4083 if (status == IXGBE_ERR_TOKEN_RETRY) 4084 DEBUGOUT1("Could not acquire PHY token, Status = %d\n", 4085 status); 4086 4087 if (status == IXGBE_SUCCESS) 4088 return IXGBE_SUCCESS; 4089 4090 if (hmask) 4091 ixgbe_release_swfw_sync_X540(hw, hmask); 4092 4093 if (status != IXGBE_ERR_TOKEN_RETRY) { 4094 DEBUGOUT1("Unable to retry acquiring the PHY token, Status = %d\n", 4095 status); 4096 return status; 4097 } 4098 } 4099 4100 DEBUGOUT1("Semaphore acquisition retries failed!: PHY ID = 0x%08X\n", 4101 hw->phy.id); 4102 return status; 4103 } 4104 4105 /** 4106 * ixgbe_release_swfw_sync_X550a - Release SWFW semaphore 4107 * @hw: pointer to hardware structure 4108 * @mask: Mask to specify which semaphore to release 4109 * 4110 * Releases the SWFW semaphore and puts the shared phy token as needed 4111 */ 4112 void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *hw, uint32_t mask) 4113 { 4114 uint32_t hmask = mask & ~IXGBE_GSSR_TOKEN_SM; 4115 4116 DEBUGFUNC("ixgbe_release_swfw_sync_X550a"); 4117 4118 if (mask & IXGBE_GSSR_TOKEN_SM) 4119 ixgbe_put_phy_token(hw); 4120 4121 if (hmask) 4122 ixgbe_release_swfw_sync_X540(hw, hmask); 4123 } 4124 4125 /** 4126 * ixgbe_read_phy_reg_x550a - Reads specified PHY register 4127 * @hw: pointer to hardware structure 4128 * @reg_addr: 32 bit address of PHY register to read 4129 * @device_type: 5 bit device type 4130 * @phy_data: Pointer to read data from PHY register 4131 * 4132 * Reads a value from a specified PHY register using the SWFW lock and PHY 4133 * Token. The PHY Token is needed since the MDIO is shared between to MAC 4134 * instances. 4135 **/ 4136 int32_t ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr, 4137 uint32_t device_type, uint16_t *phy_data) 4138 { 4139 int32_t status; 4140 uint32_t mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM; 4141 4142 DEBUGFUNC("ixgbe_read_phy_reg_x550a"); 4143 4144 if (hw->mac.ops.acquire_swfw_sync(hw, mask)) 4145 return IXGBE_ERR_SWFW_SYNC; 4146 4147 status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data); 4148 4149 hw->mac.ops.release_swfw_sync(hw, mask); 4150 4151 return status; 4152 } 4153 4154 /** 4155 * ixgbe_write_phy_reg_x550a - Writes specified PHY register 4156 * @hw: pointer to hardware structure 4157 * @reg_addr: 32 bit PHY register to write 4158 * @device_type: 5 bit device type 4159 * @phy_data: Data to write to the PHY register 4160 * 4161 * Writes a value to specified PHY register using the SWFW lock and PHY Token. 4162 * The PHY Token is needed since the MDIO is shared between to MAC instances. 4163 **/ 4164 int32_t ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr, 4165 uint32_t device_type, uint16_t phy_data) 4166 { 4167 int32_t status; 4168 uint32_t mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM; 4169 4170 DEBUGFUNC("ixgbe_write_phy_reg_x550a"); 4171 4172 if (hw->mac.ops.acquire_swfw_sync(hw, mask) == IXGBE_SUCCESS) { 4173 status = hw->phy.ops.write_reg_mdi(hw, reg_addr, device_type, 4174 phy_data); 4175 hw->mac.ops.release_swfw_sync(hw, mask); 4176 } else { 4177 status = IXGBE_ERR_SWFW_SYNC; 4178 } 4179 4180 return status; 4181 } 4182 4183 /** 4184 * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt 4185 * @hw: pointer to hardware structure 4186 * 4187 * Handle external Base T PHY interrupt. If high temperature 4188 * failure alarm then return error, else if link status change 4189 * then setup internal/external PHY link 4190 * 4191 * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature 4192 * failure alarm, else return PHY access status. 4193 */ 4194 int32_t ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw) 4195 { 4196 bool lsc; 4197 uint32_t status; 4198 4199 status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc); 4200 4201 if (status != IXGBE_SUCCESS) 4202 return status; 4203 4204 if (lsc) 4205 return hw->phy.ops.setup_internal_link(hw); 4206 4207 return IXGBE_SUCCESS; 4208 } 4209 4210 /** 4211 * ixgbe_setup_mac_link_t_X550em - Sets the auto advertised link speed 4212 * @hw: pointer to hardware structure 4213 * @speed: new link speed 4214 * @autoneg_wait_to_complete: TRUE when waiting for completion is needed 4215 * 4216 * Setup internal/external PHY link speed based on link speed, then set 4217 * external PHY auto advertised link speed. 4218 * 4219 * Returns error status for any failure 4220 **/ 4221 int32_t ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw, 4222 ixgbe_link_speed speed, 4223 bool autoneg_wait_to_complete) 4224 { 4225 int32_t status; 4226 ixgbe_link_speed force_speed; 4227 4228 DEBUGFUNC("ixgbe_setup_mac_link_t_X550em"); 4229 4230 /* Setup internal/external PHY link speed to iXFI (10G), unless 4231 * only 1G is auto advertised then setup KX link. 4232 */ 4233 if (speed & IXGBE_LINK_SPEED_10GB_FULL) 4234 force_speed = IXGBE_LINK_SPEED_10GB_FULL; 4235 else 4236 force_speed = IXGBE_LINK_SPEED_1GB_FULL; 4237 4238 /* If X552 and internal link mode is XFI, then setup XFI internal link. 4239 */ 4240 if (hw->mac.type == ixgbe_mac_X550EM_x && 4241 !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) { 4242 status = ixgbe_setup_ixfi_x550em(hw, &force_speed); 4243 4244 if (status != IXGBE_SUCCESS) 4245 return status; 4246 } 4247 4248 return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete); 4249 } 4250 4251 /** 4252 * ixgbe_check_link_t_X550em - Determine link and speed status 4253 * @hw: pointer to hardware structure 4254 * @speed: pointer to link speed 4255 * @link_up: TRUE when link is up 4256 * @link_up_wait_to_complete: bool used to wait for link up or not 4257 * 4258 * Check that both the MAC and X557 external PHY have link. 4259 **/ 4260 int32_t ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed, 4261 bool *link_up, bool link_up_wait_to_complete) 4262 { 4263 uint32_t status; 4264 uint16_t i, autoneg_status = 0; 4265 4266 if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) 4267 return IXGBE_ERR_CONFIG; 4268 4269 status = ixgbe_check_mac_link_generic(hw, speed, link_up, 4270 link_up_wait_to_complete); 4271 4272 /* If check link fails or MAC link is not up, then return */ 4273 if (status != IXGBE_SUCCESS || !(*link_up)) 4274 return status; 4275 4276 /* MAC link is up, so check external PHY link. 4277 * X557 PHY. Link status is latching low, and can only be used to detect 4278 * link drop, and not the current status of the link without performing 4279 * back-to-back reads. 4280 */ 4281 for (i = 0; i < 2; i++) { 4282 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, 4283 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 4284 &autoneg_status); 4285 4286 if (status != IXGBE_SUCCESS) 4287 return status; 4288 } 4289 4290 /* If external PHY link is not up, then indicate link not up */ 4291 if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS)) 4292 *link_up = FALSE; 4293 4294 return IXGBE_SUCCESS; 4295 } 4296 4297 /** 4298 * ixgbe_reset_phy_t_X550em - Performs X557 PHY reset and enables LASI 4299 * @hw: pointer to hardware structure 4300 **/ 4301 int32_t ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw) 4302 { 4303 int32_t status; 4304 4305 status = ixgbe_reset_phy_generic(hw); 4306 4307 if (status != IXGBE_SUCCESS) 4308 return status; 4309 4310 /* Configure Link Status Alarm and Temperature Threshold interrupts */ 4311 return ixgbe_enable_lasi_ext_t_x550em(hw); 4312 } 4313 4314 /** 4315 * ixgbe_led_on_t_X550em - Turns on the software controllable LEDs. 4316 * @hw: pointer to hardware structure 4317 * @led_idx: led number to turn on 4318 **/ 4319 int32_t ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, uint32_t led_idx) 4320 { 4321 uint16_t phy_data; 4322 4323 DEBUGFUNC("ixgbe_led_on_t_X550em"); 4324 4325 if (led_idx >= IXGBE_X557_MAX_LED_INDEX) 4326 return IXGBE_ERR_PARAM; 4327 4328 if (hw->phy.id == 0) 4329 ixgbe_identify_phy(hw); 4330 4331 /* To turn on the LED, set mode to ON. */ 4332 hw->phy.ops.read_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, 4333 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data); 4334 phy_data |= IXGBE_X557_LED_MANUAL_SET_MASK; 4335 hw->phy.ops.write_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, 4336 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data); 4337 4338 /* Some designs have the LEDs wired to the MAC */ 4339 return ixgbe_led_on_generic(hw, led_idx); 4340 } 4341 4342 /** 4343 * ixgbe_led_off_t_X550em - Turns off the software controllable LEDs. 4344 * @hw: pointer to hardware structure 4345 * @led_idx: led number to turn off 4346 **/ 4347 int32_t ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, uint32_t led_idx) 4348 { 4349 uint16_t phy_data; 4350 4351 DEBUGFUNC("ixgbe_led_off_t_X550em"); 4352 4353 if (led_idx >= IXGBE_X557_MAX_LED_INDEX) 4354 return IXGBE_ERR_PARAM; 4355 4356 if (hw->phy.id == 0) 4357 ixgbe_identify_phy(hw); 4358 4359 /* To turn on the LED, set mode to ON. */ 4360 hw->phy.ops.read_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, 4361 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data); 4362 phy_data &= ~IXGBE_X557_LED_MANUAL_SET_MASK; 4363 hw->phy.ops.write_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, 4364 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data); 4365 4366 /* Some designs have the LEDs wired to the MAC */ 4367 return ixgbe_led_off_generic(hw, led_idx); 4368 } 4369