1179055Sjfv/****************************************************************************** 2171384Sjfv 3283620Serj Copyright (c) 2001-2015, Intel Corporation 4171384Sjfv All rights reserved. 5171384Sjfv 6171384Sjfv Redistribution and use in source and binary forms, with or without 7171384Sjfv modification, are permitted provided that the following conditions are met: 8171384Sjfv 9171384Sjfv 1. Redistributions of source code must retain the above copyright notice, 10171384Sjfv this list of conditions and the following disclaimer. 11171384Sjfv 12171384Sjfv 2. Redistributions in binary form must reproduce the above copyright 13171384Sjfv notice, this list of conditions and the following disclaimer in the 14171384Sjfv documentation and/or other materials provided with the distribution. 15171384Sjfv 16171384Sjfv 3. Neither the name of the Intel Corporation nor the names of its 17171384Sjfv contributors may be used to endorse or promote products derived from 18171384Sjfv this software without specific prior written permission. 19171384Sjfv 20171384Sjfv THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21171384Sjfv AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22171384Sjfv IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23171384Sjfv ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24171384Sjfv LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25171384Sjfv CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26171384Sjfv SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27171384Sjfv INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28171384Sjfv CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29171384Sjfv ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30171384Sjfv POSSIBILITY OF SUCH DAMAGE. 31171384Sjfv 32179055Sjfv******************************************************************************/ 33179055Sjfv/*$FreeBSD: releng/10.3/sys/dev/ixgbe/ixgbe_phy.c 295528 2016-02-11 16:54:23Z smh $*/ 34171384Sjfv 35171384Sjfv#include "ixgbe_api.h" 36171384Sjfv#include "ixgbe_common.h" 37171384Sjfv#include "ixgbe_phy.h" 38171384Sjfv 39190873Sjfvstatic void ixgbe_i2c_start(struct ixgbe_hw *hw); 40190873Sjfvstatic void ixgbe_i2c_stop(struct ixgbe_hw *hw); 41190873Sjfvstatic s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data); 42190873Sjfvstatic s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data); 43190873Sjfvstatic s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw); 44190873Sjfvstatic s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data); 45190873Sjfvstatic s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data); 46230775Sjfvstatic void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl); 47190873Sjfvstatic void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl); 48190873Sjfvstatic s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data); 49283620Serjstatic bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl); 50247822Sjfvstatic s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset, 51247822Sjfv u8 *sff8472_data); 52190873Sjfv 53171384Sjfv/** 54283620Serj * ixgbe_out_i2c_byte_ack - Send I2C byte with ack 55283620Serj * @hw: pointer to the hardware structure 56283620Serj * @byte: byte to send 57283620Serj * 58283620Serj * Returns an error code on error. 59283620Serj */ 60283620Serjstatic s32 ixgbe_out_i2c_byte_ack(struct ixgbe_hw *hw, u8 byte) 61283620Serj{ 62283620Serj s32 status; 63283620Serj 64283620Serj status = ixgbe_clock_out_i2c_byte(hw, byte); 65283620Serj if (status) 66283620Serj return status; 67283620Serj return ixgbe_get_i2c_ack(hw); 68283620Serj} 69283620Serj 70283620Serj/** 71283620Serj * ixgbe_in_i2c_byte_ack - Receive an I2C byte and send ack 72283620Serj * @hw: pointer to the hardware structure 73283620Serj * @byte: pointer to a u8 to receive the byte 74283620Serj * 75283620Serj * Returns an error code on error. 76283620Serj */ 77283620Serjstatic s32 ixgbe_in_i2c_byte_ack(struct ixgbe_hw *hw, u8 *byte) 78283620Serj{ 79283620Serj s32 status; 80283620Serj 81283620Serj status = ixgbe_clock_in_i2c_byte(hw, byte); 82283620Serj if (status) 83283620Serj return status; 84283620Serj /* ACK */ 85283620Serj return ixgbe_clock_out_i2c_bit(hw, FALSE); 86283620Serj} 87283620Serj 88283620Serj/** 89283620Serj * ixgbe_ones_comp_byte_add - Perform one's complement addition 90283620Serj * @add1 - addend 1 91283620Serj * @add2 - addend 2 92283620Serj * 93283620Serj * Returns one's complement 8-bit sum. 94283620Serj */ 95283620Serjstatic u8 ixgbe_ones_comp_byte_add(u8 add1, u8 add2) 96283620Serj{ 97283620Serj u16 sum = add1 + add2; 98283620Serj 99283620Serj sum = (sum & 0xFF) + (sum >> 8); 100283620Serj return sum & 0xFF; 101283620Serj} 102283620Serj 103283620Serj/** 104283620Serj * ixgbe_read_i2c_combined_generic_int - Perform I2C read combined operation 105283620Serj * @hw: pointer to the hardware structure 106283620Serj * @addr: I2C bus address to read from 107283620Serj * @reg: I2C device register to read from 108283620Serj * @val: pointer to location to receive read value 109283620Serj * @lock: TRUE if to take and release semaphore 110283620Serj * 111283620Serj * Returns an error code on error. 112283620Serj */ 113283620Serjstatic s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, 114283620Serj u16 reg, u16 *val, bool lock) 115283620Serj{ 116283620Serj u32 swfw_mask = hw->phy.phy_semaphore_mask; 117283620Serj int max_retry = 10; 118283620Serj int retry = 0; 119283620Serj u8 csum_byte; 120283620Serj u8 high_bits; 121283620Serj u8 low_bits; 122283620Serj u8 reg_high; 123283620Serj u8 csum; 124283620Serj 125283620Serj if (hw->mac.type >= ixgbe_mac_X550) 126283620Serj max_retry = 3; 127283620Serj reg_high = ((reg >> 7) & 0xFE) | 1; /* Indicate read combined */ 128283620Serj csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF); 129283620Serj csum = ~csum; 130283620Serj do { 131283620Serj if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) 132283620Serj return IXGBE_ERR_SWFW_SYNC; 133283620Serj ixgbe_i2c_start(hw); 134283620Serj /* Device Address and write indication */ 135283620Serj if (ixgbe_out_i2c_byte_ack(hw, addr)) 136283620Serj goto fail; 137283620Serj /* Write bits 14:8 */ 138283620Serj if (ixgbe_out_i2c_byte_ack(hw, reg_high)) 139283620Serj goto fail; 140283620Serj /* Write bits 7:0 */ 141283620Serj if (ixgbe_out_i2c_byte_ack(hw, reg & 0xFF)) 142283620Serj goto fail; 143283620Serj /* Write csum */ 144283620Serj if (ixgbe_out_i2c_byte_ack(hw, csum)) 145283620Serj goto fail; 146283620Serj /* Re-start condition */ 147283620Serj ixgbe_i2c_start(hw); 148283620Serj /* Device Address and read indication */ 149283620Serj if (ixgbe_out_i2c_byte_ack(hw, addr | 1)) 150283620Serj goto fail; 151283620Serj /* Get upper bits */ 152283620Serj if (ixgbe_in_i2c_byte_ack(hw, &high_bits)) 153283620Serj goto fail; 154283620Serj /* Get low bits */ 155283620Serj if (ixgbe_in_i2c_byte_ack(hw, &low_bits)) 156283620Serj goto fail; 157283620Serj /* Get csum */ 158283620Serj if (ixgbe_clock_in_i2c_byte(hw, &csum_byte)) 159283620Serj goto fail; 160283620Serj /* NACK */ 161283620Serj if (ixgbe_clock_out_i2c_bit(hw, FALSE)) 162283620Serj goto fail; 163283620Serj ixgbe_i2c_stop(hw); 164283620Serj if (lock) 165283620Serj hw->mac.ops.release_swfw_sync(hw, swfw_mask); 166283620Serj *val = (high_bits << 8) | low_bits; 167283620Serj return 0; 168283620Serj 169283620Serjfail: 170283620Serj ixgbe_i2c_bus_clear(hw); 171283620Serj if (lock) 172283620Serj hw->mac.ops.release_swfw_sync(hw, swfw_mask); 173283620Serj retry++; 174283620Serj if (retry < max_retry) 175283620Serj DEBUGOUT("I2C byte read combined error - Retrying.\n"); 176283620Serj else 177283620Serj DEBUGOUT("I2C byte read combined error.\n"); 178283620Serj } while (retry < max_retry); 179283620Serj 180283620Serj return IXGBE_ERR_I2C; 181283620Serj} 182283620Serj 183283620Serj/** 184283620Serj * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation 185283620Serj * @hw: pointer to the hardware structure 186283620Serj * @addr: I2C bus address to read from 187283620Serj * @reg: I2C device register to read from 188283620Serj * @val: pointer to location to receive read value 189283620Serj * 190283620Serj * Returns an error code on error. 191283620Serj **/ 192283620Serjstatic s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr, 193283620Serj u16 reg, u16 *val) 194283620Serj{ 195283620Serj return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, TRUE); 196283620Serj} 197283620Serj 198283620Serj/** 199283620Serj * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation 200283620Serj * @hw: pointer to the hardware structure 201283620Serj * @addr: I2C bus address to read from 202283620Serj * @reg: I2C device register to read from 203283620Serj * @val: pointer to location to receive read value 204283620Serj * 205283620Serj * Returns an error code on error. 206283620Serj **/ 207283620Serjstatic s32 208283620Serjixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr, 209283620Serj u16 reg, u16 *val) 210283620Serj{ 211283620Serj return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, FALSE); 212283620Serj} 213283620Serj 214283620Serj/** 215283620Serj * ixgbe_write_i2c_combined_generic_int - Perform I2C write combined operation 216283620Serj * @hw: pointer to the hardware structure 217283620Serj * @addr: I2C bus address to write to 218283620Serj * @reg: I2C device register to write to 219283620Serj * @val: value to write 220283620Serj * @lock: TRUE if to take and release semaphore 221283620Serj * 222283620Serj * Returns an error code on error. 223283620Serj */ 224283620Serjstatic s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, 225283620Serj u16 reg, u16 val, bool lock) 226283620Serj{ 227283620Serj u32 swfw_mask = hw->phy.phy_semaphore_mask; 228283620Serj int max_retry = 1; 229283620Serj int retry = 0; 230283620Serj u8 reg_high; 231283620Serj u8 csum; 232283620Serj 233283620Serj reg_high = (reg >> 7) & 0xFE; /* Indicate write combined */ 234283620Serj csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF); 235283620Serj csum = ixgbe_ones_comp_byte_add(csum, val >> 8); 236283620Serj csum = ixgbe_ones_comp_byte_add(csum, val & 0xFF); 237283620Serj csum = ~csum; 238283620Serj do { 239283620Serj if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) 240283620Serj return IXGBE_ERR_SWFW_SYNC; 241283620Serj ixgbe_i2c_start(hw); 242283620Serj /* Device Address and write indication */ 243283620Serj if (ixgbe_out_i2c_byte_ack(hw, addr)) 244283620Serj goto fail; 245283620Serj /* Write bits 14:8 */ 246283620Serj if (ixgbe_out_i2c_byte_ack(hw, reg_high)) 247283620Serj goto fail; 248283620Serj /* Write bits 7:0 */ 249283620Serj if (ixgbe_out_i2c_byte_ack(hw, reg & 0xFF)) 250283620Serj goto fail; 251283620Serj /* Write data 15:8 */ 252283620Serj if (ixgbe_out_i2c_byte_ack(hw, val >> 8)) 253283620Serj goto fail; 254283620Serj /* Write data 7:0 */ 255283620Serj if (ixgbe_out_i2c_byte_ack(hw, val & 0xFF)) 256283620Serj goto fail; 257283620Serj /* Write csum */ 258283620Serj if (ixgbe_out_i2c_byte_ack(hw, csum)) 259283620Serj goto fail; 260283620Serj ixgbe_i2c_stop(hw); 261283620Serj if (lock) 262283620Serj hw->mac.ops.release_swfw_sync(hw, swfw_mask); 263283620Serj return 0; 264283620Serj 265283620Serjfail: 266283620Serj ixgbe_i2c_bus_clear(hw); 267283620Serj if (lock) 268283620Serj hw->mac.ops.release_swfw_sync(hw, swfw_mask); 269283620Serj retry++; 270283620Serj if (retry < max_retry) 271283620Serj DEBUGOUT("I2C byte write combined error - Retrying.\n"); 272283620Serj else 273283620Serj DEBUGOUT("I2C byte write combined error.\n"); 274283620Serj } while (retry < max_retry); 275283620Serj 276283620Serj return IXGBE_ERR_I2C; 277283620Serj} 278283620Serj 279283620Serj/** 280283620Serj * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation 281283620Serj * @hw: pointer to the hardware structure 282283620Serj * @addr: I2C bus address to write to 283283620Serj * @reg: I2C device register to write to 284283620Serj * @val: value to write 285283620Serj * 286283620Serj * Returns an error code on error. 287283620Serj **/ 288283620Serjstatic s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw, 289283620Serj u8 addr, u16 reg, u16 val) 290283620Serj{ 291283620Serj return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, TRUE); 292283620Serj} 293283620Serj 294283620Serj/** 295283620Serj * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation 296283620Serj * @hw: pointer to the hardware structure 297283620Serj * @addr: I2C bus address to write to 298283620Serj * @reg: I2C device register to write to 299283620Serj * @val: value to write 300283620Serj * 301283620Serj * Returns an error code on error. 302283620Serj **/ 303283620Serjstatic s32 304283620Serjixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, 305283620Serj u8 addr, u16 reg, u16 val) 306283620Serj{ 307283620Serj return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, FALSE); 308283620Serj} 309283620Serj 310283620Serj/** 311179055Sjfv * ixgbe_init_phy_ops_generic - Inits PHY function ptrs 312179055Sjfv * @hw: pointer to the hardware structure 313179055Sjfv * 314179055Sjfv * Initialize the function pointers. 315171384Sjfv **/ 316179055Sjfvs32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw) 317171384Sjfv{ 318179055Sjfv struct ixgbe_phy_info *phy = &hw->phy; 319171384Sjfv 320200239Sjfv DEBUGFUNC("ixgbe_init_phy_ops_generic"); 321200239Sjfv 322179055Sjfv /* PHY */ 323283620Serj phy->ops.identify = ixgbe_identify_phy_generic; 324283620Serj phy->ops.reset = ixgbe_reset_phy_generic; 325283620Serj phy->ops.read_reg = ixgbe_read_phy_reg_generic; 326283620Serj phy->ops.write_reg = ixgbe_write_phy_reg_generic; 327283620Serj phy->ops.read_reg_mdi = ixgbe_read_phy_reg_mdi; 328283620Serj phy->ops.write_reg_mdi = ixgbe_write_phy_reg_mdi; 329283620Serj phy->ops.setup_link = ixgbe_setup_phy_link_generic; 330283620Serj phy->ops.setup_link_speed = ixgbe_setup_phy_link_speed_generic; 331179055Sjfv phy->ops.check_link = NULL; 332200239Sjfv phy->ops.get_firmware_version = ixgbe_get_phy_firmware_version_generic; 333283620Serj phy->ops.read_i2c_byte = ixgbe_read_i2c_byte_generic; 334283620Serj phy->ops.write_i2c_byte = ixgbe_write_i2c_byte_generic; 335283620Serj phy->ops.read_i2c_sff8472 = ixgbe_read_i2c_sff8472_generic; 336283620Serj phy->ops.read_i2c_eeprom = ixgbe_read_i2c_eeprom_generic; 337283620Serj phy->ops.write_i2c_eeprom = ixgbe_write_i2c_eeprom_generic; 338283620Serj phy->ops.i2c_bus_clear = ixgbe_i2c_bus_clear; 339283620Serj phy->ops.identify_sfp = ixgbe_identify_module_generic; 340185352Sjfv phy->sfp_type = ixgbe_sfp_type_unknown; 341283620Serj phy->ops.read_i2c_combined = ixgbe_read_i2c_combined_generic; 342283620Serj phy->ops.write_i2c_combined = ixgbe_write_i2c_combined_generic; 343283620Serj phy->ops.read_i2c_combined_unlocked = 344283620Serj ixgbe_read_i2c_combined_generic_unlocked; 345283620Serj phy->ops.write_i2c_combined_unlocked = 346283620Serj ixgbe_write_i2c_combined_generic_unlocked; 347283620Serj phy->ops.read_i2c_byte_unlocked = ixgbe_read_i2c_byte_generic_unlocked; 348283620Serj phy->ops.write_i2c_byte_unlocked = 349283620Serj ixgbe_write_i2c_byte_generic_unlocked; 350283620Serj phy->ops.check_overtemp = ixgbe_tn_check_overtemp; 351171384Sjfv return IXGBE_SUCCESS; 352171384Sjfv} 353171384Sjfv 354171384Sjfv/** 355171384Sjfv * ixgbe_identify_phy_generic - Get physical layer module 356171384Sjfv * @hw: pointer to hardware structure 357171384Sjfv * 358171384Sjfv * Determines the physical layer module found on the current adapter. 359171384Sjfv **/ 360171384Sjfvs32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) 361171384Sjfv{ 362171384Sjfv s32 status = IXGBE_ERR_PHY_ADDR_INVALID; 363171384Sjfv u32 phy_addr; 364190873Sjfv u16 ext_ability = 0; 365171384Sjfv 366200239Sjfv DEBUGFUNC("ixgbe_identify_phy_generic"); 367200239Sjfv 368283620Serj if (!hw->phy.phy_semaphore_mask) { 369283620Serj if (hw->bus.lan_id) 370283620Serj hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM; 371283620Serj else 372283620Serj hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM; 373283620Serj } 374283620Serj 375179055Sjfv if (hw->phy.type == ixgbe_phy_unknown) { 376179055Sjfv for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { 377179055Sjfv if (ixgbe_validate_phy_addr(hw, phy_addr)) { 378179055Sjfv hw->phy.addr = phy_addr; 379179055Sjfv ixgbe_get_phy_id(hw); 380179055Sjfv hw->phy.type = 381230775Sjfv ixgbe_get_phy_type_from_id(hw->phy.id); 382190873Sjfv 383190873Sjfv if (hw->phy.type == ixgbe_phy_unknown) { 384190873Sjfv hw->phy.ops.read_reg(hw, 385190873Sjfv IXGBE_MDIO_PHY_EXT_ABILITY, 386230775Sjfv IXGBE_MDIO_PMA_PMD_DEV_TYPE, 387230775Sjfv &ext_ability); 388190873Sjfv if (ext_ability & 389215911Sjfv (IXGBE_MDIO_PHY_10GBASET_ABILITY | 390215911Sjfv IXGBE_MDIO_PHY_1000BASET_ABILITY)) 391190873Sjfv hw->phy.type = 392230775Sjfv ixgbe_phy_cu_unknown; 393190873Sjfv else 394190873Sjfv hw->phy.type = 395230775Sjfv ixgbe_phy_generic; 396190873Sjfv } 397190873Sjfv 398179055Sjfv status = IXGBE_SUCCESS; 399179055Sjfv break; 400179055Sjfv } 401171384Sjfv } 402283620Serj 403283620Serj /* Certain media types do not have a phy so an address will not 404283620Serj * be found and the code will take this path. Caller has to 405283620Serj * decide if it is an error or not. 406283620Serj */ 407251964Sjfv if (status != IXGBE_SUCCESS) { 408190873Sjfv hw->phy.addr = 0; 409251964Sjfv } 410179055Sjfv } else { 411179055Sjfv status = IXGBE_SUCCESS; 412171384Sjfv } 413179055Sjfv 414171384Sjfv return status; 415171384Sjfv} 416171384Sjfv 417171384Sjfv/** 418283620Serj * ixgbe_check_reset_blocked - check status of MNG FW veto bit 419283620Serj * @hw: pointer to the hardware structure 420283620Serj * 421283620Serj * This function checks the MMNGC.MNG_VETO bit to see if there are 422283620Serj * any constraints on link from manageability. For MAC's that don't 423283620Serj * have this bit just return faluse since the link can not be blocked 424283620Serj * via this method. 425283620Serj **/ 426283620Serjs32 ixgbe_check_reset_blocked(struct ixgbe_hw *hw) 427283620Serj{ 428283620Serj u32 mmngc; 429283620Serj 430283620Serj DEBUGFUNC("ixgbe_check_reset_blocked"); 431283620Serj 432283620Serj /* If we don't have this bit, it can't be blocking */ 433283620Serj if (hw->mac.type == ixgbe_mac_82598EB) 434283620Serj return FALSE; 435283620Serj 436283620Serj mmngc = IXGBE_READ_REG(hw, IXGBE_MMNGC); 437283620Serj if (mmngc & IXGBE_MMNGC_MNG_VETO) { 438283620Serj ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, 439283620Serj "MNG_VETO bit detected.\n"); 440283620Serj return TRUE; 441283620Serj } 442283620Serj 443283620Serj return FALSE; 444283620Serj} 445283620Serj 446283620Serj/** 447171384Sjfv * ixgbe_validate_phy_addr - Determines phy address is valid 448171384Sjfv * @hw: pointer to hardware structure 449171384Sjfv * 450171384Sjfv **/ 451171384Sjfvbool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr) 452171384Sjfv{ 453171384Sjfv u16 phy_id = 0; 454171384Sjfv bool valid = FALSE; 455171384Sjfv 456200239Sjfv DEBUGFUNC("ixgbe_validate_phy_addr"); 457200239Sjfv 458171384Sjfv hw->phy.addr = phy_addr; 459179055Sjfv hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, 460230775Sjfv IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id); 461171384Sjfv 462171384Sjfv if (phy_id != 0xFFFF && phy_id != 0x0) 463171384Sjfv valid = TRUE; 464171384Sjfv 465171384Sjfv return valid; 466171384Sjfv} 467171384Sjfv 468171384Sjfv/** 469171384Sjfv * ixgbe_get_phy_id - Get the phy type 470171384Sjfv * @hw: pointer to hardware structure 471171384Sjfv * 472171384Sjfv **/ 473171384Sjfvs32 ixgbe_get_phy_id(struct ixgbe_hw *hw) 474171384Sjfv{ 475171384Sjfv u32 status; 476171384Sjfv u16 phy_id_high = 0; 477171384Sjfv u16 phy_id_low = 0; 478171384Sjfv 479200239Sjfv DEBUGFUNC("ixgbe_get_phy_id"); 480200239Sjfv 481179055Sjfv status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, 482230775Sjfv IXGBE_MDIO_PMA_PMD_DEV_TYPE, 483230775Sjfv &phy_id_high); 484171384Sjfv 485171384Sjfv if (status == IXGBE_SUCCESS) { 486171384Sjfv hw->phy.id = (u32)(phy_id_high << 16); 487179055Sjfv status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW, 488230775Sjfv IXGBE_MDIO_PMA_PMD_DEV_TYPE, 489230775Sjfv &phy_id_low); 490171384Sjfv hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK); 491171384Sjfv hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK); 492171384Sjfv } 493171384Sjfv return status; 494171384Sjfv} 495171384Sjfv 496171384Sjfv/** 497171384Sjfv * ixgbe_get_phy_type_from_id - Get the phy type 498171384Sjfv * @hw: pointer to hardware structure 499171384Sjfv * 500171384Sjfv **/ 501171384Sjfvenum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) 502171384Sjfv{ 503171384Sjfv enum ixgbe_phy_type phy_type; 504171384Sjfv 505200239Sjfv DEBUGFUNC("ixgbe_get_phy_type_from_id"); 506200239Sjfv 507171384Sjfv switch (phy_id) { 508179055Sjfv case TN1010_PHY_ID: 509179055Sjfv phy_type = ixgbe_phy_tn; 510179055Sjfv break; 511295524Ssbruno case X550_PHY_ID1: 512295524Ssbruno case X550_PHY_ID2: 513295524Ssbruno case X550_PHY_ID3: 514230775Sjfv case X540_PHY_ID: 515190873Sjfv phy_type = ixgbe_phy_aq; 516190873Sjfv break; 517171384Sjfv case QT2022_PHY_ID: 518171384Sjfv phy_type = ixgbe_phy_qt; 519171384Sjfv break; 520185352Sjfv case ATH_PHY_ID: 521185352Sjfv phy_type = ixgbe_phy_nl; 522185352Sjfv break; 523283620Serj case X557_PHY_ID: 524283620Serj phy_type = ixgbe_phy_x550em_ext_t; 525283620Serj break; 526171384Sjfv default: 527171384Sjfv phy_type = ixgbe_phy_unknown; 528171384Sjfv break; 529171384Sjfv } 530171384Sjfv 531179055Sjfv DEBUGOUT1("phy type found is %d\n", phy_type); 532171384Sjfv return phy_type; 533171384Sjfv} 534171384Sjfv 535171384Sjfv/** 536171384Sjfv * ixgbe_reset_phy_generic - Performs a PHY reset 537171384Sjfv * @hw: pointer to hardware structure 538171384Sjfv **/ 539171384Sjfvs32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) 540171384Sjfv{ 541190873Sjfv u32 i; 542190873Sjfv u16 ctrl = 0; 543190873Sjfv s32 status = IXGBE_SUCCESS; 544190873Sjfv 545200239Sjfv DEBUGFUNC("ixgbe_reset_phy_generic"); 546200239Sjfv 547190873Sjfv if (hw->phy.type == ixgbe_phy_unknown) 548190873Sjfv status = ixgbe_identify_phy_generic(hw); 549190873Sjfv 550190873Sjfv if (status != IXGBE_SUCCESS || hw->phy.type == ixgbe_phy_none) 551190873Sjfv goto out; 552190873Sjfv 553215911Sjfv /* Don't reset PHY if it's shut down due to overtemp. */ 554215911Sjfv if (!hw->phy.reset_if_overtemp && 555215911Sjfv (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw))) 556215911Sjfv goto out; 557215911Sjfv 558283620Serj /* Blocked by MNG FW so bail */ 559283620Serj if (ixgbe_check_reset_blocked(hw)) 560283620Serj goto out; 561283620Serj 562171384Sjfv /* 563171384Sjfv * Perform soft PHY reset to the PHY_XS. 564171384Sjfv * This will cause a soft reset to the PHY 565171384Sjfv */ 566190873Sjfv hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, 567230775Sjfv IXGBE_MDIO_PHY_XS_DEV_TYPE, 568230775Sjfv IXGBE_MDIO_PHY_XS_RESET); 569190873Sjfv 570205720Sjfv /* 571205720Sjfv * Poll for reset bit to self-clear indicating reset is complete. 572205720Sjfv * Some PHYs could take up to 3 seconds to complete and need about 573205720Sjfv * 1.7 usec delay after the reset is complete. 574205720Sjfv */ 575205720Sjfv for (i = 0; i < 30; i++) { 576205720Sjfv msec_delay(100); 577190873Sjfv hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, 578230775Sjfv IXGBE_MDIO_PHY_XS_DEV_TYPE, &ctrl); 579205720Sjfv if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) { 580205720Sjfv usec_delay(2); 581190873Sjfv break; 582205720Sjfv } 583190873Sjfv } 584190873Sjfv 585190873Sjfv if (ctrl & IXGBE_MDIO_PHY_XS_RESET) { 586190873Sjfv status = IXGBE_ERR_RESET_FAILED; 587251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 588251964Sjfv "PHY reset polling failed to complete.\n"); 589190873Sjfv } 590190873Sjfv 591190873Sjfvout: 592190873Sjfv return status; 593171384Sjfv} 594171384Sjfv 595171384Sjfv/** 596251964Sjfv * ixgbe_read_phy_mdi - Reads a value from a specified PHY register without 597251964Sjfv * the SWFW lock 598251964Sjfv * @hw: pointer to hardware structure 599251964Sjfv * @reg_addr: 32 bit address of PHY register to read 600251964Sjfv * @phy_data: Pointer to read data from PHY register 601251964Sjfv **/ 602251964Sjfvs32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, 603251964Sjfv u16 *phy_data) 604251964Sjfv{ 605251964Sjfv u32 i, data, command; 606251964Sjfv 607251964Sjfv /* Setup and write the address cycle command */ 608251964Sjfv command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | 609251964Sjfv (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | 610251964Sjfv (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | 611251964Sjfv (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); 612251964Sjfv 613251964Sjfv IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); 614251964Sjfv 615251964Sjfv /* 616251964Sjfv * Check every 10 usec to see if the address cycle completed. 617251964Sjfv * The MDI Command bit will clear when the operation is 618251964Sjfv * complete 619251964Sjfv */ 620251964Sjfv for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { 621251964Sjfv usec_delay(10); 622251964Sjfv 623251964Sjfv command = IXGBE_READ_REG(hw, IXGBE_MSCA); 624251964Sjfv if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) 625251964Sjfv break; 626251964Sjfv } 627251964Sjfv 628251964Sjfv 629251964Sjfv if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { 630251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY address command did not complete.\n"); 631251964Sjfv return IXGBE_ERR_PHY; 632251964Sjfv } 633251964Sjfv 634251964Sjfv /* 635251964Sjfv * Address cycle complete, setup and write the read 636251964Sjfv * command 637251964Sjfv */ 638251964Sjfv command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | 639251964Sjfv (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | 640251964Sjfv (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | 641251964Sjfv (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND)); 642251964Sjfv 643251964Sjfv IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); 644251964Sjfv 645251964Sjfv /* 646251964Sjfv * Check every 10 usec to see if the address cycle 647251964Sjfv * completed. The MDI Command bit will clear when the 648251964Sjfv * operation is complete 649251964Sjfv */ 650251964Sjfv for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { 651251964Sjfv usec_delay(10); 652251964Sjfv 653251964Sjfv command = IXGBE_READ_REG(hw, IXGBE_MSCA); 654251964Sjfv if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) 655251964Sjfv break; 656251964Sjfv } 657251964Sjfv 658251964Sjfv if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { 659251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY read command didn't complete\n"); 660251964Sjfv return IXGBE_ERR_PHY; 661251964Sjfv } 662251964Sjfv 663251964Sjfv /* 664251964Sjfv * Read operation is complete. Get the data 665251964Sjfv * from MSRWD 666251964Sjfv */ 667251964Sjfv data = IXGBE_READ_REG(hw, IXGBE_MSRWD); 668251964Sjfv data >>= IXGBE_MSRWD_READ_DATA_SHIFT; 669251964Sjfv *phy_data = (u16)(data); 670251964Sjfv 671251964Sjfv return IXGBE_SUCCESS; 672251964Sjfv} 673251964Sjfv 674251964Sjfv/** 675171384Sjfv * ixgbe_read_phy_reg_generic - Reads a value from a specified PHY register 676251964Sjfv * using the SWFW lock - this function is needed in most cases 677171384Sjfv * @hw: pointer to hardware structure 678171384Sjfv * @reg_addr: 32 bit address of PHY register to read 679171384Sjfv * @phy_data: Pointer to read data from PHY register 680171384Sjfv **/ 681171384Sjfvs32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, 682230775Sjfv u32 device_type, u16 *phy_data) 683171384Sjfv{ 684251964Sjfv s32 status; 685283620Serj u32 gssr = hw->phy.phy_semaphore_mask; 686171384Sjfv 687200239Sjfv DEBUGFUNC("ixgbe_read_phy_reg_generic"); 688200239Sjfv 689251964Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == IXGBE_SUCCESS) { 690251964Sjfv status = ixgbe_read_phy_reg_mdi(hw, reg_addr, device_type, 691251964Sjfv phy_data); 692251964Sjfv hw->mac.ops.release_swfw_sync(hw, gssr); 693251964Sjfv } else { 694171384Sjfv status = IXGBE_ERR_SWFW_SYNC; 695251964Sjfv } 696171384Sjfv 697251964Sjfv return status; 698251964Sjfv} 699171384Sjfv 700251964Sjfv/** 701251964Sjfv * ixgbe_write_phy_reg_mdi - Writes a value to specified PHY register 702251964Sjfv * without SWFW lock 703251964Sjfv * @hw: pointer to hardware structure 704251964Sjfv * @reg_addr: 32 bit PHY register to write 705251964Sjfv * @device_type: 5 bit device type 706251964Sjfv * @phy_data: Data to write to the PHY register 707251964Sjfv **/ 708251964Sjfvs32 ixgbe_write_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, 709251964Sjfv u32 device_type, u16 phy_data) 710251964Sjfv{ 711251964Sjfv u32 i, command; 712171384Sjfv 713251964Sjfv /* Put the data in the MDI single read and write data register*/ 714251964Sjfv IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data); 715171384Sjfv 716251964Sjfv /* Setup and write the address cycle command */ 717251964Sjfv command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | 718251964Sjfv (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | 719251964Sjfv (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | 720251964Sjfv (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); 721171384Sjfv 722251964Sjfv IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); 723171384Sjfv 724251964Sjfv /* 725251964Sjfv * Check every 10 usec to see if the address cycle completed. 726251964Sjfv * The MDI Command bit will clear when the operation is 727251964Sjfv * complete 728251964Sjfv */ 729251964Sjfv for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { 730251964Sjfv usec_delay(10); 731171384Sjfv 732251964Sjfv command = IXGBE_READ_REG(hw, IXGBE_MSCA); 733251964Sjfv if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) 734251964Sjfv break; 735251964Sjfv } 736171384Sjfv 737251964Sjfv if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { 738251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY address cmd didn't complete\n"); 739251964Sjfv return IXGBE_ERR_PHY; 740251964Sjfv } 741171384Sjfv 742251964Sjfv /* 743251964Sjfv * Address cycle complete, setup and write the write 744251964Sjfv * command 745251964Sjfv */ 746251964Sjfv command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | 747251964Sjfv (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | 748251964Sjfv (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | 749251964Sjfv (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND)); 750171384Sjfv 751251964Sjfv IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); 752171384Sjfv 753251964Sjfv /* 754251964Sjfv * Check every 10 usec to see if the address cycle 755251964Sjfv * completed. The MDI Command bit will clear when the 756251964Sjfv * operation is complete 757251964Sjfv */ 758251964Sjfv for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { 759251964Sjfv usec_delay(10); 760171384Sjfv 761251964Sjfv command = IXGBE_READ_REG(hw, IXGBE_MSCA); 762251964Sjfv if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) 763251964Sjfv break; 764251964Sjfv } 765171384Sjfv 766251964Sjfv if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { 767251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY write cmd didn't complete\n"); 768251964Sjfv return IXGBE_ERR_PHY; 769171384Sjfv } 770179055Sjfv 771251964Sjfv return IXGBE_SUCCESS; 772171384Sjfv} 773171384Sjfv 774171384Sjfv/** 775171384Sjfv * ixgbe_write_phy_reg_generic - Writes a value to specified PHY register 776251964Sjfv * using SWFW lock- this function is needed in most cases 777171384Sjfv * @hw: pointer to hardware structure 778171384Sjfv * @reg_addr: 32 bit PHY register to write 779171384Sjfv * @device_type: 5 bit device type 780171384Sjfv * @phy_data: Data to write to the PHY register 781171384Sjfv **/ 782171384Sjfvs32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, 783230775Sjfv u32 device_type, u16 phy_data) 784171384Sjfv{ 785251964Sjfv s32 status; 786283620Serj u32 gssr = hw->phy.phy_semaphore_mask; 787171384Sjfv 788200239Sjfv DEBUGFUNC("ixgbe_write_phy_reg_generic"); 789200239Sjfv 790251964Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == IXGBE_SUCCESS) { 791251964Sjfv status = ixgbe_write_phy_reg_mdi(hw, reg_addr, device_type, 792251964Sjfv phy_data); 793251964Sjfv hw->mac.ops.release_swfw_sync(hw, gssr); 794251964Sjfv } else { 795171384Sjfv status = IXGBE_ERR_SWFW_SYNC; 796171384Sjfv } 797171384Sjfv 798171384Sjfv return status; 799171384Sjfv} 800171384Sjfv 801171384Sjfv/** 802283620Serj * ixgbe_setup_phy_link_generic - Set and restart auto-neg 803215911Sjfv * @hw: pointer to hardware structure 804171384Sjfv * 805283620Serj * Restart auto-negotiation and PHY and waits for completion. 806171384Sjfv **/ 807179055Sjfvs32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) 808171384Sjfv{ 809194875Sjfv s32 status = IXGBE_SUCCESS; 810179055Sjfv u16 autoneg_reg = IXGBE_MII_AUTONEG_REG; 811200239Sjfv bool autoneg = FALSE; 812200239Sjfv ixgbe_link_speed speed; 813179055Sjfv 814200239Sjfv DEBUGFUNC("ixgbe_setup_phy_link_generic"); 815179055Sjfv 816200239Sjfv ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg); 817179055Sjfv 818200239Sjfv if (speed & IXGBE_LINK_SPEED_10GB_FULL) { 819200239Sjfv /* Set or unset auto-negotiation 10G advertisement */ 820200239Sjfv hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, 821230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 822230775Sjfv &autoneg_reg); 823179055Sjfv 824200239Sjfv autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE; 825200239Sjfv if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) 826200239Sjfv autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE; 827200239Sjfv 828200239Sjfv hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, 829230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 830230775Sjfv autoneg_reg); 831200239Sjfv } 832200239Sjfv 833283620Serj if (hw->mac.type == ixgbe_mac_X550) { 834283620Serj if (speed & IXGBE_LINK_SPEED_5GB_FULL) { 835295524Ssbruno /* Set or unset auto-negotiation 5G advertisement */ 836283620Serj hw->phy.ops.read_reg(hw, 837283620Serj IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, 838283620Serj IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 839283620Serj &autoneg_reg); 840283620Serj 841283620Serj autoneg_reg &= ~IXGBE_MII_5GBASE_T_ADVERTISE; 842283620Serj if (hw->phy.autoneg_advertised & 843283620Serj IXGBE_LINK_SPEED_5GB_FULL) 844283620Serj autoneg_reg |= IXGBE_MII_5GBASE_T_ADVERTISE; 845283620Serj 846283620Serj hw->phy.ops.write_reg(hw, 847283620Serj IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, 848283620Serj IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 849283620Serj autoneg_reg); 850283620Serj } 851283620Serj 852283620Serj if (speed & IXGBE_LINK_SPEED_2_5GB_FULL) { 853295524Ssbruno /* Set or unset auto-negotiation 2.5G advertisement */ 854283620Serj hw->phy.ops.read_reg(hw, 855283620Serj IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, 856283620Serj IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 857283620Serj &autoneg_reg); 858283620Serj 859283620Serj autoneg_reg &= ~IXGBE_MII_2_5GBASE_T_ADVERTISE; 860283620Serj if (hw->phy.autoneg_advertised & 861283620Serj IXGBE_LINK_SPEED_2_5GB_FULL) 862283620Serj autoneg_reg |= IXGBE_MII_2_5GBASE_T_ADVERTISE; 863283620Serj 864283620Serj hw->phy.ops.write_reg(hw, 865283620Serj IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, 866283620Serj IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 867283620Serj autoneg_reg); 868283620Serj } 869283620Serj } 870283620Serj 871200239Sjfv if (speed & IXGBE_LINK_SPEED_1GB_FULL) { 872200239Sjfv /* Set or unset auto-negotiation 1G advertisement */ 873200239Sjfv hw->phy.ops.read_reg(hw, 874230775Sjfv IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, 875230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 876230775Sjfv &autoneg_reg); 877200239Sjfv 878200239Sjfv autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE; 879200239Sjfv if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) 880200239Sjfv autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE; 881200239Sjfv 882200239Sjfv hw->phy.ops.write_reg(hw, 883230775Sjfv IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, 884230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 885230775Sjfv autoneg_reg); 886200239Sjfv } 887200239Sjfv 888200239Sjfv if (speed & IXGBE_LINK_SPEED_100_FULL) { 889200239Sjfv /* Set or unset auto-negotiation 100M advertisement */ 890200239Sjfv hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, 891230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 892230775Sjfv &autoneg_reg); 893200239Sjfv 894230775Sjfv autoneg_reg &= ~(IXGBE_MII_100BASE_T_ADVERTISE | 895230775Sjfv IXGBE_MII_100BASE_T_ADVERTISE_HALF); 896200239Sjfv if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) 897200239Sjfv autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE; 898200239Sjfv 899200239Sjfv hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, 900230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 901230775Sjfv autoneg_reg); 902200239Sjfv } 903200239Sjfv 904283620Serj /* Blocked by MNG FW so don't reset PHY */ 905283620Serj if (ixgbe_check_reset_blocked(hw)) 906283620Serj return status; 907283620Serj 908283620Serj /* Restart PHY auto-negotiation. */ 909179055Sjfv hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, 910230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); 911179055Sjfv 912179055Sjfv autoneg_reg |= IXGBE_MII_RESTART; 913179055Sjfv 914179055Sjfv hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, 915230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); 916179055Sjfv 917179055Sjfv return status; 918171384Sjfv} 919171384Sjfv 920171384Sjfv/** 921179055Sjfv * ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities 922171384Sjfv * @hw: pointer to hardware structure 923179055Sjfv * @speed: new link speed 924179055Sjfv **/ 925179055Sjfvs32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, 926230775Sjfv ixgbe_link_speed speed, 927230775Sjfv bool autoneg_wait_to_complete) 928179055Sjfv{ 929247822Sjfv UNREFERENCED_1PARAMETER(autoneg_wait_to_complete); 930179055Sjfv 931200239Sjfv DEBUGFUNC("ixgbe_setup_phy_link_speed_generic"); 932200239Sjfv 933179055Sjfv /* 934179055Sjfv * Clear autoneg_advertised and set new values based on input link 935179055Sjfv * speed. 936179055Sjfv */ 937179055Sjfv hw->phy.autoneg_advertised = 0; 938179055Sjfv 939185352Sjfv if (speed & IXGBE_LINK_SPEED_10GB_FULL) 940179055Sjfv hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL; 941185352Sjfv 942283620Serj if (speed & IXGBE_LINK_SPEED_5GB_FULL) 943283620Serj hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_5GB_FULL; 944283620Serj 945283620Serj if (speed & IXGBE_LINK_SPEED_2_5GB_FULL) 946283620Serj hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_2_5GB_FULL; 947283620Serj 948185352Sjfv if (speed & IXGBE_LINK_SPEED_1GB_FULL) 949179055Sjfv hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL; 950179055Sjfv 951190873Sjfv if (speed & IXGBE_LINK_SPEED_100_FULL) 952190873Sjfv hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL; 953190873Sjfv 954179055Sjfv /* Setup link based on the new speed settings */ 955295524Ssbruno ixgbe_setup_phy_link(hw); 956179055Sjfv 957179055Sjfv return IXGBE_SUCCESS; 958179055Sjfv} 959179055Sjfv 960179055Sjfv/** 961295524Ssbruno * ixgbe_get_copper_speeds_supported - Get copper link speeds from phy 962295524Ssbruno * @hw: pointer to hardware structure 963295524Ssbruno * 964295524Ssbruno * Determines the supported link capabilities by reading the PHY auto 965295524Ssbruno * negotiation register. 966295524Ssbruno **/ 967295524Ssbrunostatic s32 ixgbe_get_copper_speeds_supported(struct ixgbe_hw *hw) 968295524Ssbruno{ 969295524Ssbruno s32 status; 970295524Ssbruno u16 speed_ability; 971295524Ssbruno 972295524Ssbruno status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY, 973295524Ssbruno IXGBE_MDIO_PMA_PMD_DEV_TYPE, 974295524Ssbruno &speed_ability); 975295524Ssbruno if (status) 976295524Ssbruno return status; 977295524Ssbruno 978295524Ssbruno if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G) 979295524Ssbruno hw->phy.speeds_supported |= IXGBE_LINK_SPEED_10GB_FULL; 980295524Ssbruno if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G) 981295524Ssbruno hw->phy.speeds_supported |= IXGBE_LINK_SPEED_1GB_FULL; 982295524Ssbruno if (speed_ability & IXGBE_MDIO_PHY_SPEED_100M) 983295524Ssbruno hw->phy.speeds_supported |= IXGBE_LINK_SPEED_100_FULL; 984295524Ssbruno 985295524Ssbruno switch (hw->mac.type) { 986295524Ssbruno case ixgbe_mac_X550: 987295524Ssbruno hw->phy.speeds_supported |= IXGBE_LINK_SPEED_2_5GB_FULL; 988295524Ssbruno hw->phy.speeds_supported |= IXGBE_LINK_SPEED_5GB_FULL; 989295524Ssbruno break; 990295524Ssbruno case ixgbe_mac_X550EM_x: 991295524Ssbruno hw->phy.speeds_supported &= ~IXGBE_LINK_SPEED_100_FULL; 992295524Ssbruno break; 993295524Ssbruno default: 994295524Ssbruno break; 995295524Ssbruno } 996295524Ssbruno 997295524Ssbruno return status; 998295524Ssbruno} 999295524Ssbruno 1000295524Ssbruno/** 1001190873Sjfv * ixgbe_get_copper_link_capabilities_generic - Determines link capabilities 1002190873Sjfv * @hw: pointer to hardware structure 1003190873Sjfv * @speed: pointer to link speed 1004190873Sjfv * @autoneg: boolean auto-negotiation value 1005190873Sjfv **/ 1006190873Sjfvs32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, 1007230775Sjfv ixgbe_link_speed *speed, 1008230775Sjfv bool *autoneg) 1009190873Sjfv{ 1010295524Ssbruno s32 status = IXGBE_SUCCESS; 1011190873Sjfv 1012200239Sjfv DEBUGFUNC("ixgbe_get_copper_link_capabilities_generic"); 1013200239Sjfv 1014190873Sjfv *autoneg = TRUE; 1015295524Ssbruno if (!hw->phy.speeds_supported) 1016295524Ssbruno status = ixgbe_get_copper_speeds_supported(hw); 1017190873Sjfv 1018295524Ssbruno *speed = hw->phy.speeds_supported; 1019190873Sjfv return status; 1020190873Sjfv} 1021190873Sjfv 1022190873Sjfv/** 1023179055Sjfv * ixgbe_check_phy_link_tnx - Determine link and speed status 1024179055Sjfv * @hw: pointer to hardware structure 1025171384Sjfv * 1026179055Sjfv * Reads the VS1 register to determine if link is up and the current speed for 1027171384Sjfv * the PHY. 1028171384Sjfv **/ 1029179055Sjfvs32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed, 1030230775Sjfv bool *link_up) 1031171384Sjfv{ 1032179055Sjfv s32 status = IXGBE_SUCCESS; 1033179055Sjfv u32 time_out; 1034179055Sjfv u32 max_time_out = 10; 1035179055Sjfv u16 phy_link = 0; 1036179055Sjfv u16 phy_speed = 0; 1037179055Sjfv u16 phy_data = 0; 1038179055Sjfv 1039200239Sjfv DEBUGFUNC("ixgbe_check_phy_link_tnx"); 1040200239Sjfv 1041179055Sjfv /* Initialize speed and link to default case */ 1042179055Sjfv *link_up = FALSE; 1043179055Sjfv *speed = IXGBE_LINK_SPEED_10GB_FULL; 1044179055Sjfv 1045179055Sjfv /* 1046179055Sjfv * Check current speed and link status of the PHY register. 1047179055Sjfv * This is a vendor specific register and may have to 1048179055Sjfv * be changed for other copper PHYs. 1049179055Sjfv */ 1050179055Sjfv for (time_out = 0; time_out < max_time_out; time_out++) { 1051179055Sjfv usec_delay(10); 1052179055Sjfv status = hw->phy.ops.read_reg(hw, 1053230775Sjfv IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS, 1054230775Sjfv IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 1055230775Sjfv &phy_data); 1056230775Sjfv phy_link = phy_data & IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS; 1057179055Sjfv phy_speed = phy_data & 1058230775Sjfv IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS; 1059179055Sjfv if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) { 1060179055Sjfv *link_up = TRUE; 1061179055Sjfv if (phy_speed == 1062179055Sjfv IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS) 1063179055Sjfv *speed = IXGBE_LINK_SPEED_1GB_FULL; 1064179055Sjfv break; 1065179055Sjfv } 1066179055Sjfv } 1067179055Sjfv 1068179055Sjfv return status; 1069171384Sjfv} 1070171384Sjfv 1071171384Sjfv/** 1072283620Serj * ixgbe_setup_phy_link_tnx - Set and restart auto-neg 1073200239Sjfv * @hw: pointer to hardware structure 1074200239Sjfv * 1075283620Serj * Restart auto-negotiation and PHY and waits for completion. 1076200239Sjfv **/ 1077200239Sjfvs32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw) 1078200239Sjfv{ 1079200239Sjfv s32 status = IXGBE_SUCCESS; 1080200239Sjfv u16 autoneg_reg = IXGBE_MII_AUTONEG_REG; 1081200239Sjfv bool autoneg = FALSE; 1082200239Sjfv ixgbe_link_speed speed; 1083200239Sjfv 1084200239Sjfv DEBUGFUNC("ixgbe_setup_phy_link_tnx"); 1085200239Sjfv 1086200239Sjfv ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg); 1087200239Sjfv 1088200239Sjfv if (speed & IXGBE_LINK_SPEED_10GB_FULL) { 1089200239Sjfv /* Set or unset auto-negotiation 10G advertisement */ 1090200239Sjfv hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, 1091230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 1092230775Sjfv &autoneg_reg); 1093200239Sjfv 1094200239Sjfv autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE; 1095200239Sjfv if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) 1096200239Sjfv autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE; 1097200239Sjfv 1098200239Sjfv hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, 1099230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 1100230775Sjfv autoneg_reg); 1101200239Sjfv } 1102200239Sjfv 1103200239Sjfv if (speed & IXGBE_LINK_SPEED_1GB_FULL) { 1104200239Sjfv /* Set or unset auto-negotiation 1G advertisement */ 1105200239Sjfv hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG, 1106230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 1107230775Sjfv &autoneg_reg); 1108200239Sjfv 1109200239Sjfv autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX; 1110200239Sjfv if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) 1111200239Sjfv autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX; 1112200239Sjfv 1113200239Sjfv hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG, 1114230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 1115230775Sjfv autoneg_reg); 1116200239Sjfv } 1117200239Sjfv 1118200239Sjfv if (speed & IXGBE_LINK_SPEED_100_FULL) { 1119200239Sjfv /* Set or unset auto-negotiation 100M advertisement */ 1120200239Sjfv hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, 1121230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 1122230775Sjfv &autoneg_reg); 1123200239Sjfv 1124200239Sjfv autoneg_reg &= ~IXGBE_MII_100BASE_T_ADVERTISE; 1125200239Sjfv if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) 1126200239Sjfv autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE; 1127200239Sjfv 1128200239Sjfv hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, 1129230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 1130230775Sjfv autoneg_reg); 1131200239Sjfv } 1132200239Sjfv 1133283620Serj /* Blocked by MNG FW so don't reset PHY */ 1134283620Serj if (ixgbe_check_reset_blocked(hw)) 1135283620Serj return status; 1136283620Serj 1137283620Serj /* Restart PHY auto-negotiation. */ 1138200239Sjfv hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, 1139230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); 1140200239Sjfv 1141200239Sjfv autoneg_reg |= IXGBE_MII_RESTART; 1142200239Sjfv 1143200239Sjfv hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, 1144230775Sjfv IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); 1145200239Sjfv 1146200239Sjfv return status; 1147200239Sjfv} 1148200239Sjfv 1149200239Sjfv/** 1150179055Sjfv * ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version 1151171384Sjfv * @hw: pointer to hardware structure 1152179055Sjfv * @firmware_version: pointer to the PHY Firmware Version 1153171384Sjfv **/ 1154179055Sjfvs32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, 1155230775Sjfv u16 *firmware_version) 1156171384Sjfv{ 1157283620Serj s32 status; 1158179055Sjfv 1159200239Sjfv DEBUGFUNC("ixgbe_get_phy_firmware_version_tnx"); 1160200239Sjfv 1161179055Sjfv status = hw->phy.ops.read_reg(hw, TNX_FW_REV, 1162230775Sjfv IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 1163230775Sjfv firmware_version); 1164179055Sjfv 1165179055Sjfv return status; 1166171384Sjfv} 1167171384Sjfv 1168185352Sjfv/** 1169200239Sjfv * ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version 1170190873Sjfv * @hw: pointer to hardware structure 1171190873Sjfv * @firmware_version: pointer to the PHY Firmware Version 1172190873Sjfv **/ 1173200239Sjfvs32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, 1174230775Sjfv u16 *firmware_version) 1175190873Sjfv{ 1176283620Serj s32 status; 1177190873Sjfv 1178200239Sjfv DEBUGFUNC("ixgbe_get_phy_firmware_version_generic"); 1179200239Sjfv 1180190873Sjfv status = hw->phy.ops.read_reg(hw, AQ_FW_REV, 1181230775Sjfv IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 1182230775Sjfv firmware_version); 1183190873Sjfv 1184190873Sjfv return status; 1185190873Sjfv} 1186190873Sjfv 1187190873Sjfv/** 1188185352Sjfv * ixgbe_reset_phy_nl - Performs a PHY reset 1189185352Sjfv * @hw: pointer to hardware structure 1190185352Sjfv **/ 1191185352Sjfvs32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) 1192185352Sjfv{ 1193185352Sjfv u16 phy_offset, control, eword, edata, block_crc; 1194185352Sjfv bool end_data = FALSE; 1195185352Sjfv u16 list_offset, data_offset; 1196185352Sjfv u16 phy_data = 0; 1197185352Sjfv s32 ret_val = IXGBE_SUCCESS; 1198185352Sjfv u32 i; 1199185352Sjfv 1200200239Sjfv DEBUGFUNC("ixgbe_reset_phy_nl"); 1201200239Sjfv 1202283620Serj /* Blocked by MNG FW so bail */ 1203283620Serj if (ixgbe_check_reset_blocked(hw)) 1204283620Serj goto out; 1205283620Serj 1206185352Sjfv hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, 1207230775Sjfv IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data); 1208185352Sjfv 1209185352Sjfv /* reset the PHY and poll for completion */ 1210185352Sjfv hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, 1211230775Sjfv IXGBE_MDIO_PHY_XS_DEV_TYPE, 1212230775Sjfv (phy_data | IXGBE_MDIO_PHY_XS_RESET)); 1213185352Sjfv 1214185352Sjfv for (i = 0; i < 100; i++) { 1215185352Sjfv hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, 1216230775Sjfv IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data); 1217185352Sjfv if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) == 0) 1218185352Sjfv break; 1219185352Sjfv msec_delay(10); 1220185352Sjfv } 1221185352Sjfv 1222185352Sjfv if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) != 0) { 1223185352Sjfv DEBUGOUT("PHY reset did not complete.\n"); 1224185352Sjfv ret_val = IXGBE_ERR_PHY; 1225185352Sjfv goto out; 1226185352Sjfv } 1227185352Sjfv 1228185352Sjfv /* Get init offsets */ 1229185352Sjfv ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset, 1230230775Sjfv &data_offset); 1231185352Sjfv if (ret_val != IXGBE_SUCCESS) 1232185352Sjfv goto out; 1233185352Sjfv 1234185352Sjfv ret_val = hw->eeprom.ops.read(hw, data_offset, &block_crc); 1235185352Sjfv data_offset++; 1236185352Sjfv while (!end_data) { 1237185352Sjfv /* 1238185352Sjfv * Read control word from PHY init contents offset 1239185352Sjfv */ 1240185352Sjfv ret_val = hw->eeprom.ops.read(hw, data_offset, &eword); 1241251964Sjfv if (ret_val) 1242251964Sjfv goto err_eeprom; 1243185352Sjfv control = (eword & IXGBE_CONTROL_MASK_NL) >> 1244230775Sjfv IXGBE_CONTROL_SHIFT_NL; 1245185352Sjfv edata = eword & IXGBE_DATA_MASK_NL; 1246185352Sjfv switch (control) { 1247185352Sjfv case IXGBE_DELAY_NL: 1248185352Sjfv data_offset++; 1249185352Sjfv DEBUGOUT1("DELAY: %d MS\n", edata); 1250185352Sjfv msec_delay(edata); 1251185352Sjfv break; 1252185352Sjfv case IXGBE_DATA_NL: 1253230775Sjfv DEBUGOUT("DATA:\n"); 1254185352Sjfv data_offset++; 1255251964Sjfv ret_val = hw->eeprom.ops.read(hw, data_offset, 1256251964Sjfv &phy_offset); 1257251964Sjfv if (ret_val) 1258251964Sjfv goto err_eeprom; 1259251964Sjfv data_offset++; 1260185352Sjfv for (i = 0; i < edata; i++) { 1261251964Sjfv ret_val = hw->eeprom.ops.read(hw, data_offset, 1262251964Sjfv &eword); 1263251964Sjfv if (ret_val) 1264251964Sjfv goto err_eeprom; 1265185352Sjfv hw->phy.ops.write_reg(hw, phy_offset, 1266230775Sjfv IXGBE_TWINAX_DEV, eword); 1267185352Sjfv DEBUGOUT2("Wrote %4.4x to %4.4x\n", eword, 1268230775Sjfv phy_offset); 1269185352Sjfv data_offset++; 1270185352Sjfv phy_offset++; 1271185352Sjfv } 1272185352Sjfv break; 1273185352Sjfv case IXGBE_CONTROL_NL: 1274185352Sjfv data_offset++; 1275230775Sjfv DEBUGOUT("CONTROL:\n"); 1276185352Sjfv if (edata == IXGBE_CONTROL_EOL_NL) { 1277185352Sjfv DEBUGOUT("EOL\n"); 1278185352Sjfv end_data = TRUE; 1279185352Sjfv } else if (edata == IXGBE_CONTROL_SOL_NL) { 1280185352Sjfv DEBUGOUT("SOL\n"); 1281185352Sjfv } else { 1282185352Sjfv DEBUGOUT("Bad control value\n"); 1283185352Sjfv ret_val = IXGBE_ERR_PHY; 1284185352Sjfv goto out; 1285185352Sjfv } 1286185352Sjfv break; 1287185352Sjfv default: 1288185352Sjfv DEBUGOUT("Bad control type\n"); 1289185352Sjfv ret_val = IXGBE_ERR_PHY; 1290185352Sjfv goto out; 1291185352Sjfv } 1292185352Sjfv } 1293185352Sjfv 1294185352Sjfvout: 1295185352Sjfv return ret_val; 1296251964Sjfv 1297251964Sjfverr_eeprom: 1298251964Sjfv ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, 1299251964Sjfv "eeprom read at offset %d failed", data_offset); 1300251964Sjfv return IXGBE_ERR_PHY; 1301185352Sjfv} 1302185352Sjfv 1303185352Sjfv/** 1304230775Sjfv * ixgbe_identify_module_generic - Identifies module type 1305230775Sjfv * @hw: pointer to hardware structure 1306230775Sjfv * 1307230775Sjfv * Determines HW type and calls appropriate function. 1308230775Sjfv **/ 1309230775Sjfvs32 ixgbe_identify_module_generic(struct ixgbe_hw *hw) 1310230775Sjfv{ 1311230775Sjfv s32 status = IXGBE_ERR_SFP_NOT_PRESENT; 1312230775Sjfv 1313230775Sjfv DEBUGFUNC("ixgbe_identify_module_generic"); 1314230775Sjfv 1315230775Sjfv switch (hw->mac.ops.get_media_type(hw)) { 1316230775Sjfv case ixgbe_media_type_fiber: 1317230775Sjfv status = ixgbe_identify_sfp_module_generic(hw); 1318230775Sjfv break; 1319230775Sjfv 1320283620Serj case ixgbe_media_type_fiber_qsfp: 1321283620Serj status = ixgbe_identify_qsfp_module_generic(hw); 1322283620Serj break; 1323230775Sjfv 1324230775Sjfv default: 1325230775Sjfv hw->phy.sfp_type = ixgbe_sfp_type_not_present; 1326230775Sjfv status = IXGBE_ERR_SFP_NOT_PRESENT; 1327230775Sjfv break; 1328230775Sjfv } 1329230775Sjfv 1330230775Sjfv return status; 1331230775Sjfv} 1332230775Sjfv 1333230775Sjfv/** 1334185352Sjfv * ixgbe_identify_sfp_module_generic - Identifies SFP modules 1335185352Sjfv * @hw: pointer to hardware structure 1336185352Sjfv * 1337185352Sjfv * Searches for and identifies the SFP module and assigns appropriate PHY type. 1338185352Sjfv **/ 1339185352Sjfvs32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) 1340185352Sjfv{ 1341185352Sjfv s32 status = IXGBE_ERR_PHY_ADDR_INVALID; 1342185352Sjfv u32 vendor_oui = 0; 1343190873Sjfv enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type; 1344185352Sjfv u8 identifier = 0; 1345185352Sjfv u8 comp_codes_1g = 0; 1346185352Sjfv u8 comp_codes_10g = 0; 1347190873Sjfv u8 oui_bytes[3] = {0, 0, 0}; 1348194875Sjfv u8 cable_tech = 0; 1349205720Sjfv u8 cable_spec = 0; 1350190873Sjfv u16 enforce_sfp = 0; 1351185352Sjfv 1352200239Sjfv DEBUGFUNC("ixgbe_identify_sfp_module_generic"); 1353200239Sjfv 1354194875Sjfv if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) { 1355194875Sjfv hw->phy.sfp_type = ixgbe_sfp_type_not_present; 1356194875Sjfv status = IXGBE_ERR_SFP_NOT_PRESENT; 1357194875Sjfv goto out; 1358215911Sjfv } 1359194875Sjfv 1360283620Serj /* LAN ID is needed for I2C access */ 1361283620Serj hw->mac.ops.set_lan_id(hw); 1362283620Serj 1363215911Sjfv status = hw->phy.ops.read_i2c_eeprom(hw, 1364230775Sjfv IXGBE_SFF_IDENTIFIER, 1365230775Sjfv &identifier); 1366185352Sjfv 1367247822Sjfv if (status != IXGBE_SUCCESS) 1368215911Sjfv goto err_read_i2c_eeprom; 1369185352Sjfv 1370194875Sjfv if (identifier != IXGBE_SFF_IDENTIFIER_SFP) { 1371194875Sjfv hw->phy.type = ixgbe_phy_sfp_unsupported; 1372194875Sjfv status = IXGBE_ERR_SFP_NOT_SUPPORTED; 1373194875Sjfv } else { 1374215911Sjfv status = hw->phy.ops.read_i2c_eeprom(hw, 1375230775Sjfv IXGBE_SFF_1GBE_COMP_CODES, 1376230775Sjfv &comp_codes_1g); 1377185352Sjfv 1378247822Sjfv if (status != IXGBE_SUCCESS) 1379215911Sjfv goto err_read_i2c_eeprom; 1380215911Sjfv 1381215911Sjfv status = hw->phy.ops.read_i2c_eeprom(hw, 1382230775Sjfv IXGBE_SFF_10GBE_COMP_CODES, 1383230775Sjfv &comp_codes_10g); 1384215911Sjfv 1385247822Sjfv if (status != IXGBE_SUCCESS) 1386215911Sjfv goto err_read_i2c_eeprom; 1387215911Sjfv status = hw->phy.ops.read_i2c_eeprom(hw, 1388230775Sjfv IXGBE_SFF_CABLE_TECHNOLOGY, 1389230775Sjfv &cable_tech); 1390215911Sjfv 1391247822Sjfv if (status != IXGBE_SUCCESS) 1392215911Sjfv goto err_read_i2c_eeprom; 1393215911Sjfv 1394185352Sjfv /* ID Module 1395185352Sjfv * ========= 1396185352Sjfv * 0 SFP_DA_CU 1397185352Sjfv * 1 SFP_SR 1398185352Sjfv * 2 SFP_LR 1399190873Sjfv * 3 SFP_DA_CORE0 - 82599-specific 1400190873Sjfv * 4 SFP_DA_CORE1 - 82599-specific 1401190873Sjfv * 5 SFP_SR/LR_CORE0 - 82599-specific 1402190873Sjfv * 6 SFP_SR/LR_CORE1 - 82599-specific 1403205720Sjfv * 7 SFP_act_lmt_DA_CORE0 - 82599-specific 1404205720Sjfv * 8 SFP_act_lmt_DA_CORE1 - 82599-specific 1405215911Sjfv * 9 SFP_1g_cu_CORE0 - 82599-specific 1406215911Sjfv * 10 SFP_1g_cu_CORE1 - 82599-specific 1407238149Sjfv * 11 SFP_1g_sx_CORE0 - 82599-specific 1408238149Sjfv * 12 SFP_1g_sx_CORE1 - 82599-specific 1409185352Sjfv */ 1410190873Sjfv if (hw->mac.type == ixgbe_mac_82598EB) { 1411194875Sjfv if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) 1412190873Sjfv hw->phy.sfp_type = ixgbe_sfp_type_da_cu; 1413190873Sjfv else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) 1414190873Sjfv hw->phy.sfp_type = ixgbe_sfp_type_sr; 1415190873Sjfv else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) 1416190873Sjfv hw->phy.sfp_type = ixgbe_sfp_type_lr; 1417190873Sjfv else 1418190873Sjfv hw->phy.sfp_type = ixgbe_sfp_type_unknown; 1419283620Serj } else { 1420205720Sjfv if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) { 1421190873Sjfv if (hw->bus.lan_id == 0) 1422190873Sjfv hw->phy.sfp_type = 1423230775Sjfv ixgbe_sfp_type_da_cu_core0; 1424190873Sjfv else 1425190873Sjfv hw->phy.sfp_type = 1426230775Sjfv ixgbe_sfp_type_da_cu_core1; 1427205720Sjfv } else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) { 1428205720Sjfv hw->phy.ops.read_i2c_eeprom( 1429205720Sjfv hw, IXGBE_SFF_CABLE_SPEC_COMP, 1430205720Sjfv &cable_spec); 1431205720Sjfv if (cable_spec & 1432215911Sjfv IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) { 1433205720Sjfv if (hw->bus.lan_id == 0) 1434205720Sjfv hw->phy.sfp_type = 1435205720Sjfv ixgbe_sfp_type_da_act_lmt_core0; 1436205720Sjfv else 1437205720Sjfv hw->phy.sfp_type = 1438205720Sjfv ixgbe_sfp_type_da_act_lmt_core1; 1439215911Sjfv } else { 1440190873Sjfv hw->phy.sfp_type = 1441230775Sjfv ixgbe_sfp_type_unknown; 1442215911Sjfv } 1443205720Sjfv } else if (comp_codes_10g & 1444205720Sjfv (IXGBE_SFF_10GBASESR_CAPABLE | 1445215911Sjfv IXGBE_SFF_10GBASELR_CAPABLE)) { 1446190873Sjfv if (hw->bus.lan_id == 0) 1447190873Sjfv hw->phy.sfp_type = 1448230775Sjfv ixgbe_sfp_type_srlr_core0; 1449190873Sjfv else 1450190873Sjfv hw->phy.sfp_type = 1451230775Sjfv ixgbe_sfp_type_srlr_core1; 1452215911Sjfv } else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) { 1453215911Sjfv if (hw->bus.lan_id == 0) 1454215911Sjfv hw->phy.sfp_type = 1455215911Sjfv ixgbe_sfp_type_1g_cu_core0; 1456215911Sjfv else 1457215911Sjfv hw->phy.sfp_type = 1458215911Sjfv ixgbe_sfp_type_1g_cu_core1; 1459238149Sjfv } else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) { 1460238149Sjfv if (hw->bus.lan_id == 0) 1461238149Sjfv hw->phy.sfp_type = 1462238149Sjfv ixgbe_sfp_type_1g_sx_core0; 1463238149Sjfv else 1464238149Sjfv hw->phy.sfp_type = 1465238149Sjfv ixgbe_sfp_type_1g_sx_core1; 1466283620Serj } else if (comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) { 1467283620Serj if (hw->bus.lan_id == 0) 1468283620Serj hw->phy.sfp_type = 1469283620Serj ixgbe_sfp_type_1g_lx_core0; 1470283620Serj else 1471283620Serj hw->phy.sfp_type = 1472283620Serj ixgbe_sfp_type_1g_lx_core1; 1473205720Sjfv } else { 1474190873Sjfv hw->phy.sfp_type = ixgbe_sfp_type_unknown; 1475205720Sjfv } 1476190873Sjfv } 1477185352Sjfv 1478190873Sjfv if (hw->phy.sfp_type != stored_sfp_type) 1479190873Sjfv hw->phy.sfp_setup_needed = TRUE; 1480190873Sjfv 1481185352Sjfv /* Determine if the SFP+ PHY is dual speed or not. */ 1482194875Sjfv hw->phy.multispeed_fiber = FALSE; 1483190873Sjfv if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) && 1484190873Sjfv (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) || 1485190873Sjfv ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) && 1486190873Sjfv (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE))) 1487185352Sjfv hw->phy.multispeed_fiber = TRUE; 1488200239Sjfv 1489185352Sjfv /* Determine PHY vendor */ 1490190873Sjfv if (hw->phy.type != ixgbe_phy_nl) { 1491185352Sjfv hw->phy.id = identifier; 1492215911Sjfv status = hw->phy.ops.read_i2c_eeprom(hw, 1493230775Sjfv IXGBE_SFF_VENDOR_OUI_BYTE0, 1494230775Sjfv &oui_bytes[0]); 1495215911Sjfv 1496247822Sjfv if (status != IXGBE_SUCCESS) 1497215911Sjfv goto err_read_i2c_eeprom; 1498215911Sjfv 1499215911Sjfv status = hw->phy.ops.read_i2c_eeprom(hw, 1500230775Sjfv IXGBE_SFF_VENDOR_OUI_BYTE1, 1501230775Sjfv &oui_bytes[1]); 1502215911Sjfv 1503247822Sjfv if (status != IXGBE_SUCCESS) 1504215911Sjfv goto err_read_i2c_eeprom; 1505215911Sjfv 1506215911Sjfv status = hw->phy.ops.read_i2c_eeprom(hw, 1507230775Sjfv IXGBE_SFF_VENDOR_OUI_BYTE2, 1508230775Sjfv &oui_bytes[2]); 1509185352Sjfv 1510247822Sjfv if (status != IXGBE_SUCCESS) 1511215911Sjfv goto err_read_i2c_eeprom; 1512215911Sjfv 1513185352Sjfv vendor_oui = 1514215911Sjfv ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) | 1515215911Sjfv (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) | 1516215911Sjfv (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT)); 1517185352Sjfv 1518185352Sjfv switch (vendor_oui) { 1519185352Sjfv case IXGBE_SFF_VENDOR_OUI_TYCO: 1520194875Sjfv if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) 1521205720Sjfv hw->phy.type = 1522230775Sjfv ixgbe_phy_sfp_passive_tyco; 1523185352Sjfv break; 1524185352Sjfv case IXGBE_SFF_VENDOR_OUI_FTL: 1525205720Sjfv if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) 1526205720Sjfv hw->phy.type = ixgbe_phy_sfp_ftl_active; 1527205720Sjfv else 1528205720Sjfv hw->phy.type = ixgbe_phy_sfp_ftl; 1529185352Sjfv break; 1530185352Sjfv case IXGBE_SFF_VENDOR_OUI_AVAGO: 1531185352Sjfv hw->phy.type = ixgbe_phy_sfp_avago; 1532185352Sjfv break; 1533190873Sjfv case IXGBE_SFF_VENDOR_OUI_INTEL: 1534190873Sjfv hw->phy.type = ixgbe_phy_sfp_intel; 1535190873Sjfv break; 1536185352Sjfv default: 1537194875Sjfv if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) 1538205720Sjfv hw->phy.type = 1539230775Sjfv ixgbe_phy_sfp_passive_unknown; 1540205720Sjfv else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) 1541205720Sjfv hw->phy.type = 1542205720Sjfv ixgbe_phy_sfp_active_unknown; 1543185352Sjfv else 1544185352Sjfv hw->phy.type = ixgbe_phy_sfp_unknown; 1545185352Sjfv break; 1546185352Sjfv } 1547185352Sjfv } 1548190873Sjfv 1549205720Sjfv /* Allow any DA cable vendor */ 1550205720Sjfv if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE | 1551205720Sjfv IXGBE_SFF_DA_ACTIVE_CABLE)) { 1552194875Sjfv status = IXGBE_SUCCESS; 1553194875Sjfv goto out; 1554194875Sjfv } 1555194875Sjfv 1556215911Sjfv /* Verify supported 1G SFP modules */ 1557215911Sjfv if (comp_codes_10g == 0 && 1558215911Sjfv !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || 1559238149Sjfv hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || 1560283620Serj hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || 1561283620Serj hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || 1562251964Sjfv hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || 1563238149Sjfv hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { 1564190873Sjfv hw->phy.type = ixgbe_phy_sfp_unsupported; 1565190873Sjfv status = IXGBE_ERR_SFP_NOT_SUPPORTED; 1566190873Sjfv goto out; 1567190873Sjfv } 1568194875Sjfv 1569194875Sjfv /* Anything else 82598-based is supported */ 1570194875Sjfv if (hw->mac.type == ixgbe_mac_82598EB) { 1571190873Sjfv status = IXGBE_SUCCESS; 1572190873Sjfv goto out; 1573190873Sjfv } 1574190873Sjfv 1575190873Sjfv ixgbe_get_device_caps(hw, &enforce_sfp); 1576215911Sjfv if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) && 1577251964Sjfv !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || 1578251964Sjfv hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || 1579283620Serj hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || 1580283620Serj hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || 1581251964Sjfv hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || 1582251964Sjfv hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { 1583190873Sjfv /* Make sure we're a supported PHY type */ 1584190873Sjfv if (hw->phy.type == ixgbe_phy_sfp_intel) { 1585190873Sjfv status = IXGBE_SUCCESS; 1586190873Sjfv } else { 1587247056Sdes if (hw->allow_unsupported_sfp == TRUE) { 1588247056Sdes EWARN(hw, "WARNING: Intel (R) Network " 1589247056Sdes "Connections are quality tested " 1590247056Sdes "using Intel (R) Ethernet Optics." 1591247056Sdes " Using untested modules is not " 1592247056Sdes "supported and may cause unstable" 1593247056Sdes " operation or damage to the " 1594247056Sdes "module or the adapter. Intel " 1595247056Sdes "Corporation is not responsible " 1596247056Sdes "for any harm caused by using " 1597247056Sdes "untested modules.\n", status); 1598247056Sdes status = IXGBE_SUCCESS; 1599247056Sdes } else { 1600247056Sdes DEBUGOUT("SFP+ module not supported\n"); 1601247056Sdes hw->phy.type = 1602247056Sdes ixgbe_phy_sfp_unsupported; 1603247056Sdes status = IXGBE_ERR_SFP_NOT_SUPPORTED; 1604247056Sdes } 1605190873Sjfv } 1606190873Sjfv } else { 1607190873Sjfv status = IXGBE_SUCCESS; 1608190873Sjfv } 1609185352Sjfv } 1610185352Sjfv 1611185352Sjfvout: 1612185352Sjfv return status; 1613215911Sjfv 1614215911Sjfverr_read_i2c_eeprom: 1615215911Sjfv hw->phy.sfp_type = ixgbe_sfp_type_not_present; 1616215911Sjfv if (hw->phy.type != ixgbe_phy_nl) { 1617215911Sjfv hw->phy.id = 0; 1618215911Sjfv hw->phy.type = ixgbe_phy_unknown; 1619215911Sjfv } 1620215911Sjfv return IXGBE_ERR_SFP_NOT_PRESENT; 1621185352Sjfv} 1622185352Sjfv 1623283620Serj/** 1624283620Serj * ixgbe_get_supported_phy_sfp_layer_generic - Returns physical layer type 1625283620Serj * @hw: pointer to hardware structure 1626283620Serj * 1627283620Serj * Determines physical layer capabilities of the current SFP. 1628283620Serj */ 1629283620Serjs32 ixgbe_get_supported_phy_sfp_layer_generic(struct ixgbe_hw *hw) 1630283620Serj{ 1631283620Serj u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; 1632283620Serj u8 comp_codes_10g = 0; 1633283620Serj u8 comp_codes_1g = 0; 1634230775Sjfv 1635283620Serj DEBUGFUNC("ixgbe_get_supported_phy_sfp_layer_generic"); 1636230775Sjfv 1637283620Serj hw->phy.ops.identify_sfp(hw); 1638283620Serj if (hw->phy.sfp_type == ixgbe_sfp_type_not_present) 1639283620Serj return physical_layer; 1640283620Serj 1641283620Serj switch (hw->phy.type) { 1642283620Serj case ixgbe_phy_sfp_passive_tyco: 1643283620Serj case ixgbe_phy_sfp_passive_unknown: 1644283620Serj case ixgbe_phy_qsfp_passive_unknown: 1645283620Serj physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; 1646283620Serj break; 1647283620Serj case ixgbe_phy_sfp_ftl_active: 1648283620Serj case ixgbe_phy_sfp_active_unknown: 1649283620Serj case ixgbe_phy_qsfp_active_unknown: 1650283620Serj physical_layer = IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA; 1651283620Serj break; 1652283620Serj case ixgbe_phy_sfp_avago: 1653283620Serj case ixgbe_phy_sfp_ftl: 1654283620Serj case ixgbe_phy_sfp_intel: 1655283620Serj case ixgbe_phy_sfp_unknown: 1656283620Serj hw->phy.ops.read_i2c_eeprom(hw, 1657283620Serj IXGBE_SFF_1GBE_COMP_CODES, &comp_codes_1g); 1658283620Serj hw->phy.ops.read_i2c_eeprom(hw, 1659283620Serj IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g); 1660283620Serj if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) 1661283620Serj physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; 1662283620Serj else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) 1663283620Serj physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; 1664283620Serj else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) 1665283620Serj physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T; 1666283620Serj else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) 1667283620Serj physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_SX; 1668283620Serj break; 1669283620Serj case ixgbe_phy_qsfp_intel: 1670283620Serj case ixgbe_phy_qsfp_unknown: 1671283620Serj hw->phy.ops.read_i2c_eeprom(hw, 1672283620Serj IXGBE_SFF_QSFP_10GBE_COMP, &comp_codes_10g); 1673283620Serj if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) 1674283620Serj physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; 1675283620Serj else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) 1676283620Serj physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; 1677283620Serj break; 1678283620Serj default: 1679283620Serj break; 1680283620Serj } 1681283620Serj 1682283620Serj return physical_layer; 1683283620Serj} 1684283620Serj 1685185352Sjfv/** 1686283620Serj * ixgbe_identify_qsfp_module_generic - Identifies QSFP modules 1687283620Serj * @hw: pointer to hardware structure 1688283620Serj * 1689283620Serj * Searches for and identifies the QSFP module and assigns appropriate PHY type 1690283620Serj **/ 1691283620Serjs32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw) 1692283620Serj{ 1693283620Serj s32 status = IXGBE_ERR_PHY_ADDR_INVALID; 1694283620Serj u32 vendor_oui = 0; 1695283620Serj enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type; 1696283620Serj u8 identifier = 0; 1697283620Serj u8 comp_codes_1g = 0; 1698283620Serj u8 comp_codes_10g = 0; 1699283620Serj u8 oui_bytes[3] = {0, 0, 0}; 1700283620Serj u16 enforce_sfp = 0; 1701283620Serj u8 connector = 0; 1702283620Serj u8 cable_length = 0; 1703283620Serj u8 device_tech = 0; 1704283620Serj bool active_cable = FALSE; 1705283620Serj 1706283620Serj DEBUGFUNC("ixgbe_identify_qsfp_module_generic"); 1707283620Serj 1708283620Serj if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber_qsfp) { 1709283620Serj hw->phy.sfp_type = ixgbe_sfp_type_not_present; 1710283620Serj status = IXGBE_ERR_SFP_NOT_PRESENT; 1711283620Serj goto out; 1712283620Serj } 1713283620Serj 1714283620Serj /* LAN ID is needed for I2C access */ 1715283620Serj hw->mac.ops.set_lan_id(hw); 1716283620Serj 1717283620Serj status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER, 1718283620Serj &identifier); 1719283620Serj 1720283620Serj if (status != IXGBE_SUCCESS) 1721283620Serj goto err_read_i2c_eeprom; 1722283620Serj 1723283620Serj if (identifier != IXGBE_SFF_IDENTIFIER_QSFP_PLUS) { 1724283620Serj hw->phy.type = ixgbe_phy_sfp_unsupported; 1725283620Serj status = IXGBE_ERR_SFP_NOT_SUPPORTED; 1726283620Serj goto out; 1727283620Serj } 1728283620Serj 1729283620Serj hw->phy.id = identifier; 1730283620Serj 1731283620Serj status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_QSFP_10GBE_COMP, 1732283620Serj &comp_codes_10g); 1733283620Serj 1734283620Serj if (status != IXGBE_SUCCESS) 1735283620Serj goto err_read_i2c_eeprom; 1736283620Serj 1737283620Serj status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_QSFP_1GBE_COMP, 1738283620Serj &comp_codes_1g); 1739283620Serj 1740283620Serj if (status != IXGBE_SUCCESS) 1741283620Serj goto err_read_i2c_eeprom; 1742283620Serj 1743283620Serj if (comp_codes_10g & IXGBE_SFF_QSFP_DA_PASSIVE_CABLE) { 1744283620Serj hw->phy.type = ixgbe_phy_qsfp_passive_unknown; 1745283620Serj if (hw->bus.lan_id == 0) 1746283620Serj hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core0; 1747283620Serj else 1748283620Serj hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core1; 1749283620Serj } else if (comp_codes_10g & (IXGBE_SFF_10GBASESR_CAPABLE | 1750283620Serj IXGBE_SFF_10GBASELR_CAPABLE)) { 1751283620Serj if (hw->bus.lan_id == 0) 1752283620Serj hw->phy.sfp_type = ixgbe_sfp_type_srlr_core0; 1753283620Serj else 1754283620Serj hw->phy.sfp_type = ixgbe_sfp_type_srlr_core1; 1755283620Serj } else { 1756283620Serj if (comp_codes_10g & IXGBE_SFF_QSFP_DA_ACTIVE_CABLE) 1757283620Serj active_cable = TRUE; 1758283620Serj 1759283620Serj if (!active_cable) { 1760283620Serj /* check for active DA cables that pre-date 1761283620Serj * SFF-8436 v3.6 */ 1762283620Serj hw->phy.ops.read_i2c_eeprom(hw, 1763283620Serj IXGBE_SFF_QSFP_CONNECTOR, 1764283620Serj &connector); 1765283620Serj 1766283620Serj hw->phy.ops.read_i2c_eeprom(hw, 1767283620Serj IXGBE_SFF_QSFP_CABLE_LENGTH, 1768283620Serj &cable_length); 1769283620Serj 1770283620Serj hw->phy.ops.read_i2c_eeprom(hw, 1771283620Serj IXGBE_SFF_QSFP_DEVICE_TECH, 1772283620Serj &device_tech); 1773283620Serj 1774283620Serj if ((connector == 1775283620Serj IXGBE_SFF_QSFP_CONNECTOR_NOT_SEPARABLE) && 1776283620Serj (cable_length > 0) && 1777283620Serj ((device_tech >> 4) == 1778283620Serj IXGBE_SFF_QSFP_TRANSMITER_850NM_VCSEL)) 1779283620Serj active_cable = TRUE; 1780283620Serj } 1781283620Serj 1782283620Serj if (active_cable) { 1783283620Serj hw->phy.type = ixgbe_phy_qsfp_active_unknown; 1784283620Serj if (hw->bus.lan_id == 0) 1785283620Serj hw->phy.sfp_type = 1786283620Serj ixgbe_sfp_type_da_act_lmt_core0; 1787283620Serj else 1788283620Serj hw->phy.sfp_type = 1789283620Serj ixgbe_sfp_type_da_act_lmt_core1; 1790283620Serj } else { 1791283620Serj /* unsupported module type */ 1792283620Serj hw->phy.type = ixgbe_phy_sfp_unsupported; 1793283620Serj status = IXGBE_ERR_SFP_NOT_SUPPORTED; 1794283620Serj goto out; 1795283620Serj } 1796283620Serj } 1797283620Serj 1798283620Serj if (hw->phy.sfp_type != stored_sfp_type) 1799283620Serj hw->phy.sfp_setup_needed = TRUE; 1800283620Serj 1801283620Serj /* Determine if the QSFP+ PHY is dual speed or not. */ 1802283620Serj hw->phy.multispeed_fiber = FALSE; 1803283620Serj if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) && 1804283620Serj (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) || 1805283620Serj ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) && 1806283620Serj (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE))) 1807283620Serj hw->phy.multispeed_fiber = TRUE; 1808283620Serj 1809283620Serj /* Determine PHY vendor for optical modules */ 1810283620Serj if (comp_codes_10g & (IXGBE_SFF_10GBASESR_CAPABLE | 1811283620Serj IXGBE_SFF_10GBASELR_CAPABLE)) { 1812283620Serj status = hw->phy.ops.read_i2c_eeprom(hw, 1813283620Serj IXGBE_SFF_QSFP_VENDOR_OUI_BYTE0, 1814283620Serj &oui_bytes[0]); 1815283620Serj 1816283620Serj if (status != IXGBE_SUCCESS) 1817283620Serj goto err_read_i2c_eeprom; 1818283620Serj 1819283620Serj status = hw->phy.ops.read_i2c_eeprom(hw, 1820283620Serj IXGBE_SFF_QSFP_VENDOR_OUI_BYTE1, 1821283620Serj &oui_bytes[1]); 1822283620Serj 1823283620Serj if (status != IXGBE_SUCCESS) 1824283620Serj goto err_read_i2c_eeprom; 1825283620Serj 1826283620Serj status = hw->phy.ops.read_i2c_eeprom(hw, 1827283620Serj IXGBE_SFF_QSFP_VENDOR_OUI_BYTE2, 1828283620Serj &oui_bytes[2]); 1829283620Serj 1830283620Serj if (status != IXGBE_SUCCESS) 1831283620Serj goto err_read_i2c_eeprom; 1832283620Serj 1833283620Serj vendor_oui = 1834283620Serj ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) | 1835283620Serj (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) | 1836283620Serj (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT)); 1837283620Serj 1838283620Serj if (vendor_oui == IXGBE_SFF_VENDOR_OUI_INTEL) 1839283620Serj hw->phy.type = ixgbe_phy_qsfp_intel; 1840283620Serj else 1841283620Serj hw->phy.type = ixgbe_phy_qsfp_unknown; 1842283620Serj 1843283620Serj ixgbe_get_device_caps(hw, &enforce_sfp); 1844283620Serj if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) { 1845283620Serj /* Make sure we're a supported PHY type */ 1846283620Serj if (hw->phy.type == ixgbe_phy_qsfp_intel) { 1847283620Serj status = IXGBE_SUCCESS; 1848283620Serj } else { 1849283620Serj if (hw->allow_unsupported_sfp == TRUE) { 1850283620Serj EWARN(hw, "WARNING: Intel (R) Network " 1851283620Serj "Connections are quality tested " 1852283620Serj "using Intel (R) Ethernet Optics." 1853283620Serj " Using untested modules is not " 1854283620Serj "supported and may cause unstable" 1855283620Serj " operation or damage to the " 1856283620Serj "module or the adapter. Intel " 1857283620Serj "Corporation is not responsible " 1858283620Serj "for any harm caused by using " 1859283620Serj "untested modules.\n", status); 1860283620Serj status = IXGBE_SUCCESS; 1861283620Serj } else { 1862283620Serj DEBUGOUT("QSFP module not supported\n"); 1863283620Serj hw->phy.type = 1864283620Serj ixgbe_phy_sfp_unsupported; 1865283620Serj status = IXGBE_ERR_SFP_NOT_SUPPORTED; 1866283620Serj } 1867283620Serj } 1868283620Serj } else { 1869283620Serj status = IXGBE_SUCCESS; 1870283620Serj } 1871283620Serj } 1872283620Serj 1873283620Serjout: 1874283620Serj return status; 1875283620Serj 1876283620Serjerr_read_i2c_eeprom: 1877283620Serj hw->phy.sfp_type = ixgbe_sfp_type_not_present; 1878283620Serj hw->phy.id = 0; 1879283620Serj hw->phy.type = ixgbe_phy_unknown; 1880283620Serj 1881283620Serj return IXGBE_ERR_SFP_NOT_PRESENT; 1882283620Serj} 1883283620Serj 1884283620Serj 1885283620Serj/** 1886185352Sjfv * ixgbe_get_sfp_init_sequence_offsets - Provides offset of PHY init sequence 1887185352Sjfv * @hw: pointer to hardware structure 1888185352Sjfv * @list_offset: offset to the SFP ID list 1889185352Sjfv * @data_offset: offset to the SFP data block 1890185352Sjfv * 1891185352Sjfv * Checks the MAC's EEPROM to see if it supports a given SFP+ module type, if 1892185352Sjfv * so it returns the offsets to the phy init sequence block. 1893185352Sjfv **/ 1894185352Sjfvs32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, 1895230775Sjfv u16 *list_offset, 1896230775Sjfv u16 *data_offset) 1897185352Sjfv{ 1898185352Sjfv u16 sfp_id; 1899205720Sjfv u16 sfp_type = hw->phy.sfp_type; 1900185352Sjfv 1901200239Sjfv DEBUGFUNC("ixgbe_get_sfp_init_sequence_offsets"); 1902200239Sjfv 1903185352Sjfv if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) 1904185352Sjfv return IXGBE_ERR_SFP_NOT_SUPPORTED; 1905185352Sjfv 1906185352Sjfv if (hw->phy.sfp_type == ixgbe_sfp_type_not_present) 1907185352Sjfv return IXGBE_ERR_SFP_NOT_PRESENT; 1908185352Sjfv 1909185352Sjfv if ((hw->device_id == IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM) && 1910185352Sjfv (hw->phy.sfp_type == ixgbe_sfp_type_da_cu)) 1911185352Sjfv return IXGBE_ERR_SFP_NOT_SUPPORTED; 1912185352Sjfv 1913215911Sjfv /* 1914215911Sjfv * Limiting active cables and 1G Phys must be initialized as 1915215911Sjfv * SR modules 1916215911Sjfv */ 1917215911Sjfv if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 || 1918283620Serj sfp_type == ixgbe_sfp_type_1g_lx_core0 || 1919238149Sjfv sfp_type == ixgbe_sfp_type_1g_cu_core0 || 1920238149Sjfv sfp_type == ixgbe_sfp_type_1g_sx_core0) 1921205720Sjfv sfp_type = ixgbe_sfp_type_srlr_core0; 1922215911Sjfv else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 || 1923283620Serj sfp_type == ixgbe_sfp_type_1g_lx_core1 || 1924238149Sjfv sfp_type == ixgbe_sfp_type_1g_cu_core1 || 1925238149Sjfv sfp_type == ixgbe_sfp_type_1g_sx_core1) 1926205720Sjfv sfp_type = ixgbe_sfp_type_srlr_core1; 1927205720Sjfv 1928185352Sjfv /* Read offset to PHY init contents */ 1929251964Sjfv if (hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset)) { 1930251964Sjfv ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, 1931251964Sjfv "eeprom read at offset %d failed", 1932251964Sjfv IXGBE_PHY_INIT_OFFSET_NL); 1933251964Sjfv return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT; 1934251964Sjfv } 1935185352Sjfv 1936185352Sjfv if ((!*list_offset) || (*list_offset == 0xFFFF)) 1937190873Sjfv return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT; 1938185352Sjfv 1939185352Sjfv /* Shift offset to first ID word */ 1940185352Sjfv (*list_offset)++; 1941185352Sjfv 1942185352Sjfv /* 1943185352Sjfv * Find the matching SFP ID in the EEPROM 1944185352Sjfv * and program the init sequence 1945185352Sjfv */ 1946251964Sjfv if (hw->eeprom.ops.read(hw, *list_offset, &sfp_id)) 1947251964Sjfv goto err_phy; 1948185352Sjfv 1949185352Sjfv while (sfp_id != IXGBE_PHY_INIT_END_NL) { 1950205720Sjfv if (sfp_id == sfp_type) { 1951185352Sjfv (*list_offset)++; 1952251964Sjfv if (hw->eeprom.ops.read(hw, *list_offset, data_offset)) 1953251964Sjfv goto err_phy; 1954185352Sjfv if ((!*data_offset) || (*data_offset == 0xFFFF)) { 1955185352Sjfv DEBUGOUT("SFP+ module not supported\n"); 1956185352Sjfv return IXGBE_ERR_SFP_NOT_SUPPORTED; 1957185352Sjfv } else { 1958185352Sjfv break; 1959185352Sjfv } 1960185352Sjfv } else { 1961185352Sjfv (*list_offset) += 2; 1962185352Sjfv if (hw->eeprom.ops.read(hw, *list_offset, &sfp_id)) 1963251964Sjfv goto err_phy; 1964185352Sjfv } 1965185352Sjfv } 1966185352Sjfv 1967185352Sjfv if (sfp_id == IXGBE_PHY_INIT_END_NL) { 1968185352Sjfv DEBUGOUT("No matching SFP+ module found\n"); 1969185352Sjfv return IXGBE_ERR_SFP_NOT_SUPPORTED; 1970185352Sjfv } 1971185352Sjfv 1972185352Sjfv return IXGBE_SUCCESS; 1973251964Sjfv 1974251964Sjfverr_phy: 1975251964Sjfv ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, 1976251964Sjfv "eeprom read at offset %d failed", *list_offset); 1977251964Sjfv return IXGBE_ERR_PHY; 1978185352Sjfv} 1979185352Sjfv 1980190873Sjfv/** 1981190873Sjfv * ixgbe_read_i2c_eeprom_generic - Reads 8 bit EEPROM word over I2C interface 1982190873Sjfv * @hw: pointer to hardware structure 1983190873Sjfv * @byte_offset: EEPROM byte offset to read 1984190873Sjfv * @eeprom_data: value read 1985190873Sjfv * 1986190873Sjfv * Performs byte read operation to SFP module's EEPROM over I2C interface. 1987190873Sjfv **/ 1988190873Sjfvs32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, 1989230775Sjfv u8 *eeprom_data) 1990190873Sjfv{ 1991190873Sjfv DEBUGFUNC("ixgbe_read_i2c_eeprom_generic"); 1992190873Sjfv 1993190873Sjfv return hw->phy.ops.read_i2c_byte(hw, byte_offset, 1994230775Sjfv IXGBE_I2C_EEPROM_DEV_ADDR, 1995230775Sjfv eeprom_data); 1996190873Sjfv} 1997190873Sjfv 1998190873Sjfv/** 1999247822Sjfv * ixgbe_read_i2c_sff8472_generic - Reads 8 bit word over I2C interface 2000247822Sjfv * @hw: pointer to hardware structure 2001247822Sjfv * @byte_offset: byte offset at address 0xA2 2002247822Sjfv * @eeprom_data: value read 2003247822Sjfv * 2004247822Sjfv * Performs byte read operation to SFP module's SFF-8472 data over I2C 2005247822Sjfv **/ 2006247822Sjfvstatic s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset, 2007247822Sjfv u8 *sff8472_data) 2008247822Sjfv{ 2009247822Sjfv return hw->phy.ops.read_i2c_byte(hw, byte_offset, 2010247822Sjfv IXGBE_I2C_EEPROM_DEV_ADDR2, 2011247822Sjfv sff8472_data); 2012247822Sjfv} 2013247822Sjfv 2014247822Sjfv/** 2015190873Sjfv * ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface 2016190873Sjfv * @hw: pointer to hardware structure 2017190873Sjfv * @byte_offset: EEPROM byte offset to write 2018190873Sjfv * @eeprom_data: value to write 2019190873Sjfv * 2020190873Sjfv * Performs byte write operation to SFP module's EEPROM over I2C interface. 2021190873Sjfv **/ 2022190873Sjfvs32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, 2023230775Sjfv u8 eeprom_data) 2024190873Sjfv{ 2025190873Sjfv DEBUGFUNC("ixgbe_write_i2c_eeprom_generic"); 2026190873Sjfv 2027190873Sjfv return hw->phy.ops.write_i2c_byte(hw, byte_offset, 2028230775Sjfv IXGBE_I2C_EEPROM_DEV_ADDR, 2029230775Sjfv eeprom_data); 2030190873Sjfv} 2031190873Sjfv 2032190873Sjfv/** 2033283620Serj * ixgbe_is_sfp_probe - Returns TRUE if SFP is being detected 2034283620Serj * @hw: pointer to hardware structure 2035283620Serj * @offset: eeprom offset to be read 2036283620Serj * @addr: I2C address to be read 2037283620Serj */ 2038283620Serjstatic bool ixgbe_is_sfp_probe(struct ixgbe_hw *hw, u8 offset, u8 addr) 2039283620Serj{ 2040283620Serj if (addr == IXGBE_I2C_EEPROM_DEV_ADDR && 2041283620Serj offset == IXGBE_SFF_IDENTIFIER && 2042283620Serj hw->phy.sfp_type == ixgbe_sfp_type_not_present) 2043283620Serj return TRUE; 2044283620Serj return FALSE; 2045283620Serj} 2046283620Serj 2047283620Serj/** 2048283620Serj * ixgbe_read_i2c_byte_generic_int - Reads 8 bit word over I2C 2049190873Sjfv * @hw: pointer to hardware structure 2050190873Sjfv * @byte_offset: byte offset to read 2051190873Sjfv * @data: value read 2052283620Serj * @lock: TRUE if to take and release semaphore 2053190873Sjfv * 2054190873Sjfv * Performs byte read operation to SFP module's EEPROM over I2C interface at 2055230775Sjfv * a specified device address. 2056190873Sjfv **/ 2057283620Serjstatic s32 ixgbe_read_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset, 2058283620Serj u8 dev_addr, u8 *data, bool lock) 2059190873Sjfv{ 2060283620Serj s32 status; 2061194875Sjfv u32 max_retry = 10; 2062190873Sjfv u32 retry = 0; 2063283620Serj u32 swfw_mask = hw->phy.phy_semaphore_mask; 2064190873Sjfv bool nack = 1; 2065230775Sjfv *data = 0; 2066190873Sjfv 2067190873Sjfv DEBUGFUNC("ixgbe_read_i2c_byte_generic"); 2068190873Sjfv 2069283620Serj if (hw->mac.type >= ixgbe_mac_X550) 2070283620Serj max_retry = 3; 2071283620Serj if (ixgbe_is_sfp_probe(hw, byte_offset, dev_addr)) 2072283620Serj max_retry = IXGBE_SFP_DETECT_RETRIES; 2073190873Sjfv 2074190873Sjfv do { 2075283620Serj if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) 2076283620Serj return IXGBE_ERR_SWFW_SYNC; 2077194875Sjfv 2078190873Sjfv ixgbe_i2c_start(hw); 2079190873Sjfv 2080190873Sjfv /* Device Address and write indication */ 2081190873Sjfv status = ixgbe_clock_out_i2c_byte(hw, dev_addr); 2082190873Sjfv if (status != IXGBE_SUCCESS) 2083190873Sjfv goto fail; 2084190873Sjfv 2085190873Sjfv status = ixgbe_get_i2c_ack(hw); 2086190873Sjfv if (status != IXGBE_SUCCESS) 2087190873Sjfv goto fail; 2088190873Sjfv 2089190873Sjfv status = ixgbe_clock_out_i2c_byte(hw, byte_offset); 2090190873Sjfv if (status != IXGBE_SUCCESS) 2091190873Sjfv goto fail; 2092190873Sjfv 2093190873Sjfv status = ixgbe_get_i2c_ack(hw); 2094190873Sjfv if (status != IXGBE_SUCCESS) 2095190873Sjfv goto fail; 2096190873Sjfv 2097190873Sjfv ixgbe_i2c_start(hw); 2098190873Sjfv 2099190873Sjfv /* Device Address and read indication */ 2100190873Sjfv status = ixgbe_clock_out_i2c_byte(hw, (dev_addr | 0x1)); 2101190873Sjfv if (status != IXGBE_SUCCESS) 2102190873Sjfv goto fail; 2103190873Sjfv 2104190873Sjfv status = ixgbe_get_i2c_ack(hw); 2105190873Sjfv if (status != IXGBE_SUCCESS) 2106190873Sjfv goto fail; 2107190873Sjfv 2108190873Sjfv status = ixgbe_clock_in_i2c_byte(hw, data); 2109190873Sjfv if (status != IXGBE_SUCCESS) 2110190873Sjfv goto fail; 2111190873Sjfv 2112190873Sjfv status = ixgbe_clock_out_i2c_bit(hw, nack); 2113190873Sjfv if (status != IXGBE_SUCCESS) 2114190873Sjfv goto fail; 2115190873Sjfv 2116190873Sjfv ixgbe_i2c_stop(hw); 2117283620Serj if (lock) 2118283620Serj hw->mac.ops.release_swfw_sync(hw, swfw_mask); 2119283620Serj return IXGBE_SUCCESS; 2120190873Sjfv 2121190873Sjfvfail: 2122247822Sjfv ixgbe_i2c_bus_clear(hw); 2123283620Serj if (lock) { 2124283620Serj hw->mac.ops.release_swfw_sync(hw, swfw_mask); 2125283620Serj msec_delay(100); 2126283620Serj } 2127190873Sjfv retry++; 2128190873Sjfv if (retry < max_retry) 2129190873Sjfv DEBUGOUT("I2C byte read error - Retrying.\n"); 2130190873Sjfv else 2131190873Sjfv DEBUGOUT("I2C byte read error.\n"); 2132190873Sjfv 2133190873Sjfv } while (retry < max_retry); 2134190873Sjfv 2135190873Sjfv return status; 2136190873Sjfv} 2137190873Sjfv 2138190873Sjfv/** 2139283620Serj * ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C 2140190873Sjfv * @hw: pointer to hardware structure 2141283620Serj * @byte_offset: byte offset to read 2142283620Serj * @data: value read 2143283620Serj * 2144283620Serj * Performs byte read operation to SFP module's EEPROM over I2C interface at 2145283620Serj * a specified device address. 2146283620Serj **/ 2147283620Serjs32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, 2148283620Serj u8 dev_addr, u8 *data) 2149283620Serj{ 2150283620Serj return ixgbe_read_i2c_byte_generic_int(hw, byte_offset, dev_addr, 2151283620Serj data, TRUE); 2152283620Serj} 2153283620Serj 2154283620Serj/** 2155283620Serj * ixgbe_read_i2c_byte_generic_unlocked - Reads 8 bit word over I2C 2156283620Serj * @hw: pointer to hardware structure 2157283620Serj * @byte_offset: byte offset to read 2158283620Serj * @data: value read 2159283620Serj * 2160283620Serj * Performs byte read operation to SFP module's EEPROM over I2C interface at 2161283620Serj * a specified device address. 2162283620Serj **/ 2163283620Serjs32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset, 2164283620Serj u8 dev_addr, u8 *data) 2165283620Serj{ 2166283620Serj return ixgbe_read_i2c_byte_generic_int(hw, byte_offset, dev_addr, 2167283620Serj data, FALSE); 2168283620Serj} 2169283620Serj 2170283620Serj/** 2171283620Serj * ixgbe_write_i2c_byte_generic_int - Writes 8 bit word over I2C 2172283620Serj * @hw: pointer to hardware structure 2173190873Sjfv * @byte_offset: byte offset to write 2174190873Sjfv * @data: value to write 2175283620Serj * @lock: TRUE if to take and release semaphore 2176190873Sjfv * 2177190873Sjfv * Performs byte write operation to SFP module's EEPROM over I2C interface at 2178190873Sjfv * a specified device address. 2179190873Sjfv **/ 2180283620Serjstatic s32 ixgbe_write_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset, 2181283620Serj u8 dev_addr, u8 data, bool lock) 2182190873Sjfv{ 2183283620Serj s32 status; 2184190873Sjfv u32 max_retry = 1; 2185190873Sjfv u32 retry = 0; 2186283620Serj u32 swfw_mask = hw->phy.phy_semaphore_mask; 2187190873Sjfv 2188190873Sjfv DEBUGFUNC("ixgbe_write_i2c_byte_generic"); 2189190873Sjfv 2190283620Serj if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != 2191283620Serj IXGBE_SUCCESS) 2192283620Serj return IXGBE_ERR_SWFW_SYNC; 2193190873Sjfv 2194190873Sjfv do { 2195190873Sjfv ixgbe_i2c_start(hw); 2196190873Sjfv 2197190873Sjfv status = ixgbe_clock_out_i2c_byte(hw, dev_addr); 2198190873Sjfv if (status != IXGBE_SUCCESS) 2199190873Sjfv goto fail; 2200190873Sjfv 2201190873Sjfv status = ixgbe_get_i2c_ack(hw); 2202190873Sjfv if (status != IXGBE_SUCCESS) 2203190873Sjfv goto fail; 2204190873Sjfv 2205190873Sjfv status = ixgbe_clock_out_i2c_byte(hw, byte_offset); 2206190873Sjfv if (status != IXGBE_SUCCESS) 2207190873Sjfv goto fail; 2208190873Sjfv 2209190873Sjfv status = ixgbe_get_i2c_ack(hw); 2210190873Sjfv if (status != IXGBE_SUCCESS) 2211190873Sjfv goto fail; 2212190873Sjfv 2213190873Sjfv status = ixgbe_clock_out_i2c_byte(hw, data); 2214190873Sjfv if (status != IXGBE_SUCCESS) 2215190873Sjfv goto fail; 2216190873Sjfv 2217190873Sjfv status = ixgbe_get_i2c_ack(hw); 2218190873Sjfv if (status != IXGBE_SUCCESS) 2219190873Sjfv goto fail; 2220190873Sjfv 2221190873Sjfv ixgbe_i2c_stop(hw); 2222283620Serj if (lock) 2223283620Serj hw->mac.ops.release_swfw_sync(hw, swfw_mask); 2224283620Serj return IXGBE_SUCCESS; 2225190873Sjfv 2226190873Sjfvfail: 2227190873Sjfv ixgbe_i2c_bus_clear(hw); 2228190873Sjfv retry++; 2229190873Sjfv if (retry < max_retry) 2230190873Sjfv DEBUGOUT("I2C byte write error - Retrying.\n"); 2231190873Sjfv else 2232190873Sjfv DEBUGOUT("I2C byte write error.\n"); 2233190873Sjfv } while (retry < max_retry); 2234190873Sjfv 2235283620Serj if (lock) 2236283620Serj hw->mac.ops.release_swfw_sync(hw, swfw_mask); 2237190873Sjfv 2238190873Sjfv return status; 2239190873Sjfv} 2240190873Sjfv 2241190873Sjfv/** 2242283620Serj * ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C 2243283620Serj * @hw: pointer to hardware structure 2244283620Serj * @byte_offset: byte offset to write 2245283620Serj * @data: value to write 2246283620Serj * 2247283620Serj * Performs byte write operation to SFP module's EEPROM over I2C interface at 2248283620Serj * a specified device address. 2249283620Serj **/ 2250283620Serjs32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, 2251283620Serj u8 dev_addr, u8 data) 2252283620Serj{ 2253283620Serj return ixgbe_write_i2c_byte_generic_int(hw, byte_offset, dev_addr, 2254283620Serj data, TRUE); 2255283620Serj} 2256283620Serj 2257283620Serj/** 2258283620Serj * ixgbe_write_i2c_byte_generic_unlocked - Writes 8 bit word over I2C 2259283620Serj * @hw: pointer to hardware structure 2260283620Serj * @byte_offset: byte offset to write 2261283620Serj * @data: value to write 2262283620Serj * 2263283620Serj * Performs byte write operation to SFP module's EEPROM over I2C interface at 2264283620Serj * a specified device address. 2265283620Serj **/ 2266283620Serjs32 ixgbe_write_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset, 2267283620Serj u8 dev_addr, u8 data) 2268283620Serj{ 2269283620Serj return ixgbe_write_i2c_byte_generic_int(hw, byte_offset, dev_addr, 2270283620Serj data, FALSE); 2271283620Serj} 2272283620Serj 2273283620Serj/** 2274190873Sjfv * ixgbe_i2c_start - Sets I2C start condition 2275190873Sjfv * @hw: pointer to hardware structure 2276190873Sjfv * 2277190873Sjfv * Sets I2C start condition (High -> Low on SDA while SCL is High) 2278283620Serj * Set bit-bang mode on X550 hardware. 2279190873Sjfv **/ 2280190873Sjfvstatic void ixgbe_i2c_start(struct ixgbe_hw *hw) 2281190873Sjfv{ 2282283620Serj u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); 2283190873Sjfv 2284190873Sjfv DEBUGFUNC("ixgbe_i2c_start"); 2285190873Sjfv 2286283620Serj i2cctl |= IXGBE_I2C_BB_EN_BY_MAC(hw); 2287283620Serj 2288190873Sjfv /* Start condition must begin with data and clock high */ 2289190873Sjfv ixgbe_set_i2c_data(hw, &i2cctl, 1); 2290190873Sjfv ixgbe_raise_i2c_clk(hw, &i2cctl); 2291190873Sjfv 2292190873Sjfv /* Setup time for start condition (4.7us) */ 2293190873Sjfv usec_delay(IXGBE_I2C_T_SU_STA); 2294190873Sjfv 2295190873Sjfv ixgbe_set_i2c_data(hw, &i2cctl, 0); 2296190873Sjfv 2297190873Sjfv /* Hold time for start condition (4us) */ 2298190873Sjfv usec_delay(IXGBE_I2C_T_HD_STA); 2299190873Sjfv 2300190873Sjfv ixgbe_lower_i2c_clk(hw, &i2cctl); 2301190873Sjfv 2302190873Sjfv /* Minimum low period of clock is 4.7 us */ 2303190873Sjfv usec_delay(IXGBE_I2C_T_LOW); 2304190873Sjfv 2305190873Sjfv} 2306190873Sjfv 2307190873Sjfv/** 2308190873Sjfv * ixgbe_i2c_stop - Sets I2C stop condition 2309190873Sjfv * @hw: pointer to hardware structure 2310190873Sjfv * 2311190873Sjfv * Sets I2C stop condition (Low -> High on SDA while SCL is High) 2312283620Serj * Disables bit-bang mode and negates data output enable on X550 2313283620Serj * hardware. 2314190873Sjfv **/ 2315190873Sjfvstatic void ixgbe_i2c_stop(struct ixgbe_hw *hw) 2316190873Sjfv{ 2317283620Serj u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); 2318283620Serj u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw); 2319283620Serj u32 clk_oe_bit = IXGBE_I2C_CLK_OE_N_EN_BY_MAC(hw); 2320283620Serj u32 bb_en_bit = IXGBE_I2C_BB_EN_BY_MAC(hw); 2321190873Sjfv 2322190873Sjfv DEBUGFUNC("ixgbe_i2c_stop"); 2323190873Sjfv 2324190873Sjfv /* Stop condition must begin with data low and clock high */ 2325190873Sjfv ixgbe_set_i2c_data(hw, &i2cctl, 0); 2326190873Sjfv ixgbe_raise_i2c_clk(hw, &i2cctl); 2327190873Sjfv 2328190873Sjfv /* Setup time for stop condition (4us) */ 2329190873Sjfv usec_delay(IXGBE_I2C_T_SU_STO); 2330190873Sjfv 2331190873Sjfv ixgbe_set_i2c_data(hw, &i2cctl, 1); 2332190873Sjfv 2333190873Sjfv /* bus free time between stop and start (4.7us)*/ 2334190873Sjfv usec_delay(IXGBE_I2C_T_BUF); 2335283620Serj 2336283620Serj if (bb_en_bit || data_oe_bit || clk_oe_bit) { 2337283620Serj i2cctl &= ~bb_en_bit; 2338283620Serj i2cctl |= data_oe_bit | clk_oe_bit; 2339283620Serj IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl); 2340283620Serj IXGBE_WRITE_FLUSH(hw); 2341283620Serj } 2342190873Sjfv} 2343190873Sjfv 2344190873Sjfv/** 2345190873Sjfv * ixgbe_clock_in_i2c_byte - Clocks in one byte via I2C 2346190873Sjfv * @hw: pointer to hardware structure 2347190873Sjfv * @data: data byte to clock in 2348190873Sjfv * 2349190873Sjfv * Clocks in one byte data via I2C data/clock 2350190873Sjfv **/ 2351190873Sjfvstatic s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data) 2352190873Sjfv{ 2353190873Sjfv s32 i; 2354190873Sjfv bool bit = 0; 2355190873Sjfv 2356190873Sjfv DEBUGFUNC("ixgbe_clock_in_i2c_byte"); 2357190873Sjfv 2358283620Serj *data = 0; 2359190873Sjfv for (i = 7; i >= 0; i--) { 2360230775Sjfv ixgbe_clock_in_i2c_bit(hw, &bit); 2361215911Sjfv *data |= bit << i; 2362190873Sjfv } 2363190873Sjfv 2364230775Sjfv return IXGBE_SUCCESS; 2365190873Sjfv} 2366190873Sjfv 2367190873Sjfv/** 2368190873Sjfv * ixgbe_clock_out_i2c_byte - Clocks out one byte via I2C 2369190873Sjfv * @hw: pointer to hardware structure 2370190873Sjfv * @data: data byte clocked out 2371190873Sjfv * 2372190873Sjfv * Clocks out one byte data via I2C data/clock 2373190873Sjfv **/ 2374190873Sjfvstatic s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data) 2375190873Sjfv{ 2376190873Sjfv s32 status = IXGBE_SUCCESS; 2377190873Sjfv s32 i; 2378190873Sjfv u32 i2cctl; 2379283620Serj bool bit; 2380190873Sjfv 2381190873Sjfv DEBUGFUNC("ixgbe_clock_out_i2c_byte"); 2382190873Sjfv 2383190873Sjfv for (i = 7; i >= 0; i--) { 2384190873Sjfv bit = (data >> i) & 0x1; 2385190873Sjfv status = ixgbe_clock_out_i2c_bit(hw, bit); 2386190873Sjfv 2387190873Sjfv if (status != IXGBE_SUCCESS) 2388190873Sjfv break; 2389190873Sjfv } 2390190873Sjfv 2391190873Sjfv /* Release SDA line (set high) */ 2392283620Serj i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); 2393283620Serj i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw); 2394283620Serj i2cctl |= IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw); 2395283620Serj IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl); 2396230775Sjfv IXGBE_WRITE_FLUSH(hw); 2397190873Sjfv 2398190873Sjfv return status; 2399190873Sjfv} 2400190873Sjfv 2401190873Sjfv/** 2402190873Sjfv * ixgbe_get_i2c_ack - Polls for I2C ACK 2403190873Sjfv * @hw: pointer to hardware structure 2404190873Sjfv * 2405190873Sjfv * Clocks in/out one bit via I2C data/clock 2406190873Sjfv **/ 2407190873Sjfvstatic s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw) 2408190873Sjfv{ 2409283620Serj u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw); 2410230775Sjfv s32 status = IXGBE_SUCCESS; 2411190873Sjfv u32 i = 0; 2412283620Serj u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); 2413190873Sjfv u32 timeout = 10; 2414190873Sjfv bool ack = 1; 2415190873Sjfv 2416190873Sjfv DEBUGFUNC("ixgbe_get_i2c_ack"); 2417190873Sjfv 2418283620Serj if (data_oe_bit) { 2419283620Serj i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw); 2420283620Serj i2cctl |= data_oe_bit; 2421283620Serj IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl); 2422283620Serj IXGBE_WRITE_FLUSH(hw); 2423283620Serj } 2424230775Sjfv ixgbe_raise_i2c_clk(hw, &i2cctl); 2425190873Sjfv 2426190873Sjfv /* Minimum high period of clock is 4us */ 2427190873Sjfv usec_delay(IXGBE_I2C_T_HIGH); 2428190873Sjfv 2429190873Sjfv /* Poll for ACK. Note that ACK in I2C spec is 2430190873Sjfv * transition from 1 to 0 */ 2431190873Sjfv for (i = 0; i < timeout; i++) { 2432283620Serj i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); 2433283620Serj ack = ixgbe_get_i2c_data(hw, &i2cctl); 2434190873Sjfv 2435190873Sjfv usec_delay(1); 2436283620Serj if (!ack) 2437190873Sjfv break; 2438190873Sjfv } 2439190873Sjfv 2440283620Serj if (ack) { 2441283620Serj DEBUGOUT("I2C ack was not received.\n"); 2442190873Sjfv status = IXGBE_ERR_I2C; 2443190873Sjfv } 2444190873Sjfv 2445190873Sjfv ixgbe_lower_i2c_clk(hw, &i2cctl); 2446190873Sjfv 2447190873Sjfv /* Minimum low period of clock is 4.7 us */ 2448190873Sjfv usec_delay(IXGBE_I2C_T_LOW); 2449190873Sjfv 2450190873Sjfv return status; 2451190873Sjfv} 2452190873Sjfv 2453190873Sjfv/** 2454190873Sjfv * ixgbe_clock_in_i2c_bit - Clocks in one bit via I2C data/clock 2455190873Sjfv * @hw: pointer to hardware structure 2456190873Sjfv * @data: read data value 2457190873Sjfv * 2458190873Sjfv * Clocks in one bit via I2C data/clock 2459190873Sjfv **/ 2460190873Sjfvstatic s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data) 2461190873Sjfv{ 2462283620Serj u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); 2463283620Serj u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw); 2464190873Sjfv 2465200239Sjfv DEBUGFUNC("ixgbe_clock_in_i2c_bit"); 2466200239Sjfv 2467283620Serj if (data_oe_bit) { 2468283620Serj i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw); 2469283620Serj i2cctl |= data_oe_bit; 2470283620Serj IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl); 2471283620Serj IXGBE_WRITE_FLUSH(hw); 2472283620Serj } 2473230775Sjfv ixgbe_raise_i2c_clk(hw, &i2cctl); 2474190873Sjfv 2475190873Sjfv /* Minimum high period of clock is 4us */ 2476190873Sjfv usec_delay(IXGBE_I2C_T_HIGH); 2477190873Sjfv 2478283620Serj i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); 2479283620Serj *data = ixgbe_get_i2c_data(hw, &i2cctl); 2480190873Sjfv 2481190873Sjfv ixgbe_lower_i2c_clk(hw, &i2cctl); 2482190873Sjfv 2483190873Sjfv /* Minimum low period of clock is 4.7 us */ 2484190873Sjfv usec_delay(IXGBE_I2C_T_LOW); 2485190873Sjfv 2486230775Sjfv return IXGBE_SUCCESS; 2487190873Sjfv} 2488190873Sjfv 2489190873Sjfv/** 2490190873Sjfv * ixgbe_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock 2491190873Sjfv * @hw: pointer to hardware structure 2492190873Sjfv * @data: data value to write 2493190873Sjfv * 2494190873Sjfv * Clocks out one bit via I2C data/clock 2495190873Sjfv **/ 2496190873Sjfvstatic s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data) 2497190873Sjfv{ 2498190873Sjfv s32 status; 2499283620Serj u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); 2500190873Sjfv 2501200239Sjfv DEBUGFUNC("ixgbe_clock_out_i2c_bit"); 2502200239Sjfv 2503190873Sjfv status = ixgbe_set_i2c_data(hw, &i2cctl, data); 2504190873Sjfv if (status == IXGBE_SUCCESS) { 2505230775Sjfv ixgbe_raise_i2c_clk(hw, &i2cctl); 2506190873Sjfv 2507190873Sjfv /* Minimum high period of clock is 4us */ 2508190873Sjfv usec_delay(IXGBE_I2C_T_HIGH); 2509190873Sjfv 2510190873Sjfv ixgbe_lower_i2c_clk(hw, &i2cctl); 2511190873Sjfv 2512190873Sjfv /* Minimum low period of clock is 4.7 us. 2513190873Sjfv * This also takes care of the data hold time. 2514190873Sjfv */ 2515190873Sjfv usec_delay(IXGBE_I2C_T_LOW); 2516190873Sjfv } else { 2517190873Sjfv status = IXGBE_ERR_I2C; 2518251964Sjfv ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, 2519251964Sjfv "I2C data was not set to %X\n", data); 2520190873Sjfv } 2521190873Sjfv 2522190873Sjfv return status; 2523190873Sjfv} 2524283620Serj 2525190873Sjfv/** 2526190873Sjfv * ixgbe_raise_i2c_clk - Raises the I2C SCL clock 2527190873Sjfv * @hw: pointer to hardware structure 2528190873Sjfv * @i2cctl: Current value of I2CCTL register 2529190873Sjfv * 2530190873Sjfv * Raises the I2C clock line '0'->'1' 2531283620Serj * Negates the I2C clock output enable on X550 hardware. 2532190873Sjfv **/ 2533230775Sjfvstatic void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) 2534190873Sjfv{ 2535283620Serj u32 clk_oe_bit = IXGBE_I2C_CLK_OE_N_EN_BY_MAC(hw); 2536238149Sjfv u32 i = 0; 2537238149Sjfv u32 timeout = IXGBE_I2C_CLOCK_STRETCHING_TIMEOUT; 2538238149Sjfv u32 i2cctl_r = 0; 2539238149Sjfv 2540200239Sjfv DEBUGFUNC("ixgbe_raise_i2c_clk"); 2541200239Sjfv 2542283620Serj if (clk_oe_bit) { 2543283620Serj *i2cctl |= clk_oe_bit; 2544283620Serj IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); 2545283620Serj } 2546283620Serj 2547238149Sjfv for (i = 0; i < timeout; i++) { 2548283620Serj *i2cctl |= IXGBE_I2C_CLK_OUT_BY_MAC(hw); 2549190873Sjfv 2550283620Serj IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); 2551238149Sjfv IXGBE_WRITE_FLUSH(hw); 2552238149Sjfv /* SCL rise time (1000ns) */ 2553238149Sjfv usec_delay(IXGBE_I2C_T_RISE); 2554190873Sjfv 2555283620Serj i2cctl_r = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); 2556283620Serj if (i2cctl_r & IXGBE_I2C_CLK_IN_BY_MAC(hw)) 2557238149Sjfv break; 2558238149Sjfv } 2559190873Sjfv} 2560190873Sjfv 2561190873Sjfv/** 2562190873Sjfv * ixgbe_lower_i2c_clk - Lowers the I2C SCL clock 2563190873Sjfv * @hw: pointer to hardware structure 2564190873Sjfv * @i2cctl: Current value of I2CCTL register 2565190873Sjfv * 2566190873Sjfv * Lowers the I2C clock line '1'->'0' 2567283620Serj * Asserts the I2C clock output enable on X550 hardware. 2568190873Sjfv **/ 2569190873Sjfvstatic void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) 2570190873Sjfv{ 2571200239Sjfv DEBUGFUNC("ixgbe_lower_i2c_clk"); 2572200239Sjfv 2573283620Serj *i2cctl &= ~(IXGBE_I2C_CLK_OUT_BY_MAC(hw)); 2574283620Serj *i2cctl &= ~IXGBE_I2C_CLK_OE_N_EN_BY_MAC(hw); 2575190873Sjfv 2576283620Serj IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); 2577230775Sjfv IXGBE_WRITE_FLUSH(hw); 2578190873Sjfv 2579190873Sjfv /* SCL fall time (300ns) */ 2580190873Sjfv usec_delay(IXGBE_I2C_T_FALL); 2581190873Sjfv} 2582190873Sjfv 2583190873Sjfv/** 2584190873Sjfv * ixgbe_set_i2c_data - Sets the I2C data bit 2585190873Sjfv * @hw: pointer to hardware structure 2586190873Sjfv * @i2cctl: Current value of I2CCTL register 2587190873Sjfv * @data: I2C data value (0 or 1) to set 2588190873Sjfv * 2589190873Sjfv * Sets the I2C data bit 2590283620Serj * Asserts the I2C data output enable on X550 hardware. 2591190873Sjfv **/ 2592190873Sjfvstatic s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data) 2593190873Sjfv{ 2594283620Serj u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw); 2595190873Sjfv s32 status = IXGBE_SUCCESS; 2596190873Sjfv 2597200239Sjfv DEBUGFUNC("ixgbe_set_i2c_data"); 2598200239Sjfv 2599190873Sjfv if (data) 2600283620Serj *i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw); 2601190873Sjfv else 2602283620Serj *i2cctl &= ~(IXGBE_I2C_DATA_OUT_BY_MAC(hw)); 2603283620Serj *i2cctl &= ~data_oe_bit; 2604190873Sjfv 2605283620Serj IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); 2606230775Sjfv IXGBE_WRITE_FLUSH(hw); 2607190873Sjfv 2608190873Sjfv /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */ 2609190873Sjfv usec_delay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA); 2610190873Sjfv 2611283620Serj if (!data) /* Can't verify data in this case */ 2612283620Serj return IXGBE_SUCCESS; 2613283620Serj if (data_oe_bit) { 2614283620Serj *i2cctl |= data_oe_bit; 2615283620Serj IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); 2616283620Serj IXGBE_WRITE_FLUSH(hw); 2617283620Serj } 2618283620Serj 2619190873Sjfv /* Verify data was set correctly */ 2620283620Serj *i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); 2621283620Serj if (data != ixgbe_get_i2c_data(hw, i2cctl)) { 2622190873Sjfv status = IXGBE_ERR_I2C; 2623251964Sjfv ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, 2624251964Sjfv "Error - I2C data was not set to %X.\n", 2625251964Sjfv data); 2626190873Sjfv } 2627190873Sjfv 2628190873Sjfv return status; 2629190873Sjfv} 2630190873Sjfv 2631190873Sjfv/** 2632190873Sjfv * ixgbe_get_i2c_data - Reads the I2C SDA data bit 2633190873Sjfv * @hw: pointer to hardware structure 2634190873Sjfv * @i2cctl: Current value of I2CCTL register 2635190873Sjfv * 2636190873Sjfv * Returns the I2C data bit value 2637283620Serj * Negates the I2C data output enable on X550 hardware. 2638190873Sjfv **/ 2639283620Serjstatic bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl) 2640190873Sjfv{ 2641283620Serj u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw); 2642190873Sjfv bool data; 2643190873Sjfv 2644200239Sjfv DEBUGFUNC("ixgbe_get_i2c_data"); 2645200239Sjfv 2646283620Serj if (data_oe_bit) { 2647283620Serj *i2cctl |= data_oe_bit; 2648283620Serj IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); 2649283620Serj IXGBE_WRITE_FLUSH(hw); 2650283620Serj usec_delay(IXGBE_I2C_T_FALL); 2651283620Serj } 2652283620Serj 2653283620Serj if (*i2cctl & IXGBE_I2C_DATA_IN_BY_MAC(hw)) 2654190873Sjfv data = 1; 2655190873Sjfv else 2656190873Sjfv data = 0; 2657190873Sjfv 2658190873Sjfv return data; 2659190873Sjfv} 2660190873Sjfv 2661190873Sjfv/** 2662190873Sjfv * ixgbe_i2c_bus_clear - Clears the I2C bus 2663190873Sjfv * @hw: pointer to hardware structure 2664190873Sjfv * 2665190873Sjfv * Clears the I2C bus by sending nine clock pulses. 2666190873Sjfv * Used when data line is stuck low. 2667190873Sjfv **/ 2668190873Sjfvvoid ixgbe_i2c_bus_clear(struct ixgbe_hw *hw) 2669190873Sjfv{ 2670283620Serj u32 i2cctl; 2671190873Sjfv u32 i; 2672190873Sjfv 2673190873Sjfv DEBUGFUNC("ixgbe_i2c_bus_clear"); 2674190873Sjfv 2675190873Sjfv ixgbe_i2c_start(hw); 2676283620Serj i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); 2677190873Sjfv 2678190873Sjfv ixgbe_set_i2c_data(hw, &i2cctl, 1); 2679190873Sjfv 2680190873Sjfv for (i = 0; i < 9; i++) { 2681190873Sjfv ixgbe_raise_i2c_clk(hw, &i2cctl); 2682190873Sjfv 2683190873Sjfv /* Min high period of clock is 4us */ 2684190873Sjfv usec_delay(IXGBE_I2C_T_HIGH); 2685190873Sjfv 2686190873Sjfv ixgbe_lower_i2c_clk(hw, &i2cctl); 2687190873Sjfv 2688190873Sjfv /* Min low period of clock is 4.7us*/ 2689190873Sjfv usec_delay(IXGBE_I2C_T_LOW); 2690190873Sjfv } 2691190873Sjfv 2692190873Sjfv ixgbe_i2c_start(hw); 2693190873Sjfv 2694190873Sjfv /* Put the i2c bus back to default state */ 2695190873Sjfv ixgbe_i2c_stop(hw); 2696190873Sjfv} 2697205720Sjfv 2698205720Sjfv/** 2699238149Sjfv * ixgbe_tn_check_overtemp - Checks if an overtemp occurred. 2700205720Sjfv * @hw: pointer to hardware structure 2701205720Sjfv * 2702205720Sjfv * Checks if the LASI temp alarm status was triggered due to overtemp 2703205720Sjfv **/ 2704205720Sjfvs32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw) 2705205720Sjfv{ 2706205720Sjfv s32 status = IXGBE_SUCCESS; 2707205720Sjfv u16 phy_data = 0; 2708205720Sjfv 2709205720Sjfv DEBUGFUNC("ixgbe_tn_check_overtemp"); 2710205720Sjfv 2711205720Sjfv if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM) 2712205720Sjfv goto out; 2713205720Sjfv 2714205720Sjfv /* Check that the LASI temp alarm status was triggered */ 2715205720Sjfv hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG, 2716205720Sjfv IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_data); 2717205720Sjfv 2718205720Sjfv if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM)) 2719205720Sjfv goto out; 2720205720Sjfv 2721205720Sjfv status = IXGBE_ERR_OVERTEMP; 2722251964Sjfv ERROR_REPORT1(IXGBE_ERROR_CAUTION, "Device over temperature"); 2723205720Sjfvout: 2724205720Sjfv return status; 2725205720Sjfv} 2726283620Serj 2727283620Serj/** 2728283620Serj * ixgbe_set_copper_phy_power - Control power for copper phy 2729283620Serj * @hw: pointer to hardware structure 2730283620Serj * @on: TRUE for on, FALSE for off 2731283620Serj */ 2732283620Serjs32 ixgbe_set_copper_phy_power(struct ixgbe_hw *hw, bool on) 2733283620Serj{ 2734283620Serj u32 status; 2735283620Serj u16 reg; 2736283620Serj 2737295528Ssmh if (!on && ixgbe_mng_present(hw)) 2738295528Ssmh return 0; 2739295528Ssmh 2740283620Serj status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL, 2741283620Serj IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 2742283620Serj ®); 2743283620Serj if (status) 2744283620Serj return status; 2745283620Serj 2746283620Serj if (on) { 2747283620Serj reg &= ~IXGBE_MDIO_PHY_SET_LOW_POWER_MODE; 2748283620Serj } else { 2749283620Serj if (ixgbe_check_reset_blocked(hw)) 2750283620Serj return 0; 2751283620Serj reg |= IXGBE_MDIO_PHY_SET_LOW_POWER_MODE; 2752283620Serj } 2753283620Serj 2754283620Serj status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL, 2755283620Serj IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 2756283620Serj reg); 2757283620Serj return status; 2758283620Serj} 2759