16a14ee0cSDon Skidmore /******************************************************************************* 26a14ee0cSDon Skidmore * 36a14ee0cSDon Skidmore * Intel 10 Gigabit PCI Express Linux driver 46a14ee0cSDon Skidmore * Copyright(c) 1999 - 2014 Intel Corporation. 56a14ee0cSDon Skidmore * 66a14ee0cSDon Skidmore * This program is free software; you can redistribute it and/or modify it 76a14ee0cSDon Skidmore * under the terms and conditions of the GNU General Public License, 86a14ee0cSDon Skidmore * version 2, as published by the Free Software Foundation. 96a14ee0cSDon Skidmore * 106a14ee0cSDon Skidmore * This program is distributed in the hope it will be useful, but WITHOUT 116a14ee0cSDon Skidmore * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 126a14ee0cSDon Skidmore * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 136a14ee0cSDon Skidmore * more details. 146a14ee0cSDon Skidmore * 156a14ee0cSDon Skidmore * The full GNU General Public License is included in this distribution in 166a14ee0cSDon Skidmore * the file called "COPYING". 176a14ee0cSDon Skidmore * 186a14ee0cSDon Skidmore * Contact Information: 196a14ee0cSDon Skidmore * Linux NICS <linux.nics@intel.com> 206a14ee0cSDon Skidmore * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 216a14ee0cSDon Skidmore * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 226a14ee0cSDon Skidmore * 236a14ee0cSDon Skidmore ******************************************************************************/ 246a14ee0cSDon Skidmore #include "ixgbe_x540.h" 256a14ee0cSDon Skidmore #include "ixgbe_type.h" 266a14ee0cSDon Skidmore #include "ixgbe_common.h" 276a14ee0cSDon Skidmore #include "ixgbe_phy.h" 286a14ee0cSDon Skidmore 296a14ee0cSDon Skidmore /** ixgbe_identify_phy_x550em - Get PHY type based on device id 306a14ee0cSDon Skidmore * @hw: pointer to hardware structure 316a14ee0cSDon Skidmore * 326a14ee0cSDon Skidmore * Returns error code 336a14ee0cSDon Skidmore */ 346a14ee0cSDon Skidmore static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw) 356a14ee0cSDon Skidmore { 366a14ee0cSDon Skidmore u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); 376a14ee0cSDon Skidmore 386a14ee0cSDon Skidmore switch (hw->device_id) { 396a14ee0cSDon Skidmore case IXGBE_DEV_ID_X550EM_X_SFP: 406a14ee0cSDon Skidmore /* set up for CS4227 usage */ 416a14ee0cSDon Skidmore hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM; 426a14ee0cSDon Skidmore if (hw->bus.lan_id) { 436a14ee0cSDon Skidmore esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1); 446a14ee0cSDon Skidmore esdp |= IXGBE_ESDP_SDP1_DIR; 456a14ee0cSDon Skidmore } 466a14ee0cSDon Skidmore esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR); 476a14ee0cSDon Skidmore IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); 486a14ee0cSDon Skidmore 496a14ee0cSDon Skidmore return ixgbe_identify_module_generic(hw); 506a14ee0cSDon Skidmore case IXGBE_DEV_ID_X550EM_X_KX4: 516a14ee0cSDon Skidmore hw->phy.type = ixgbe_phy_x550em_kx4; 526a14ee0cSDon Skidmore break; 536a14ee0cSDon Skidmore case IXGBE_DEV_ID_X550EM_X_KR: 546a14ee0cSDon Skidmore hw->phy.type = ixgbe_phy_x550em_kr; 556a14ee0cSDon Skidmore break; 566a14ee0cSDon Skidmore case IXGBE_DEV_ID_X550EM_X_1G_T: 576a14ee0cSDon Skidmore case IXGBE_DEV_ID_X550EM_X_10G_T: 586a14ee0cSDon Skidmore return ixgbe_identify_phy_generic(hw); 596a14ee0cSDon Skidmore default: 606a14ee0cSDon Skidmore break; 616a14ee0cSDon Skidmore } 626a14ee0cSDon Skidmore return 0; 636a14ee0cSDon Skidmore } 646a14ee0cSDon Skidmore 656a14ee0cSDon Skidmore static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, 666a14ee0cSDon Skidmore u32 device_type, u16 *phy_data) 676a14ee0cSDon Skidmore { 686a14ee0cSDon Skidmore return IXGBE_NOT_IMPLEMENTED; 696a14ee0cSDon Skidmore } 706a14ee0cSDon Skidmore 716a14ee0cSDon Skidmore static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, 726a14ee0cSDon Skidmore u32 device_type, u16 phy_data) 736a14ee0cSDon Skidmore { 746a14ee0cSDon Skidmore return IXGBE_NOT_IMPLEMENTED; 756a14ee0cSDon Skidmore } 766a14ee0cSDon Skidmore 776a14ee0cSDon Skidmore /** ixgbe_init_eeprom_params_X550 - Initialize EEPROM params 786a14ee0cSDon Skidmore * @hw: pointer to hardware structure 796a14ee0cSDon Skidmore * 806a14ee0cSDon Skidmore * Initializes the EEPROM parameters ixgbe_eeprom_info within the 816a14ee0cSDon Skidmore * ixgbe_hw struct in order to set up EEPROM access. 826a14ee0cSDon Skidmore **/ 836a14ee0cSDon Skidmore s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw) 846a14ee0cSDon Skidmore { 856a14ee0cSDon Skidmore struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 866a14ee0cSDon Skidmore u32 eec; 876a14ee0cSDon Skidmore u16 eeprom_size; 886a14ee0cSDon Skidmore 896a14ee0cSDon Skidmore if (eeprom->type == ixgbe_eeprom_uninitialized) { 906a14ee0cSDon Skidmore eeprom->semaphore_delay = 10; 916a14ee0cSDon Skidmore eeprom->type = ixgbe_flash; 926a14ee0cSDon Skidmore 936a14ee0cSDon Skidmore eec = IXGBE_READ_REG(hw, IXGBE_EEC); 946a14ee0cSDon Skidmore eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> 956a14ee0cSDon Skidmore IXGBE_EEC_SIZE_SHIFT); 966a14ee0cSDon Skidmore eeprom->word_size = 1 << (eeprom_size + 976a14ee0cSDon Skidmore IXGBE_EEPROM_WORD_SIZE_SHIFT); 986a14ee0cSDon Skidmore 996a14ee0cSDon Skidmore hw_dbg(hw, "Eeprom params: type = %d, size = %d\n", 1006a14ee0cSDon Skidmore eeprom->type, eeprom->word_size); 1016a14ee0cSDon Skidmore } 1026a14ee0cSDon Skidmore 1036a14ee0cSDon Skidmore return 0; 1046a14ee0cSDon Skidmore } 1056a14ee0cSDon Skidmore 1066a14ee0cSDon Skidmore /** ixgbe_read_iosf_sb_reg_x550 - Writes a value to specified register of the 1076a14ee0cSDon Skidmore * IOSF device 1086a14ee0cSDon Skidmore * @hw: pointer to hardware structure 1096a14ee0cSDon Skidmore * @reg_addr: 32 bit PHY register to write 1106a14ee0cSDon Skidmore * @device_type: 3 bit device type 1116a14ee0cSDon Skidmore * @phy_data: Pointer to read data from the register 1126a14ee0cSDon Skidmore **/ 1136a14ee0cSDon Skidmore s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, 1146a14ee0cSDon Skidmore u32 device_type, u32 *data) 1156a14ee0cSDon Skidmore { 1166a14ee0cSDon Skidmore u32 i, command, error; 1176a14ee0cSDon Skidmore 1186a14ee0cSDon Skidmore command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) | 1196a14ee0cSDon Skidmore (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT)); 1206a14ee0cSDon Skidmore 1216a14ee0cSDon Skidmore /* Write IOSF control register */ 1226a14ee0cSDon Skidmore IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command); 1236a14ee0cSDon Skidmore 1246a14ee0cSDon Skidmore /* Check every 10 usec to see if the address cycle completed. 1256a14ee0cSDon Skidmore * The SB IOSF BUSY bit will clear when the operation is 1266a14ee0cSDon Skidmore * complete 1276a14ee0cSDon Skidmore */ 1286a14ee0cSDon Skidmore for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { 1296a14ee0cSDon Skidmore usleep_range(10, 20); 1306a14ee0cSDon Skidmore 1316a14ee0cSDon Skidmore command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL); 1326a14ee0cSDon Skidmore if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0) 1336a14ee0cSDon Skidmore break; 1346a14ee0cSDon Skidmore } 1356a14ee0cSDon Skidmore 1366a14ee0cSDon Skidmore if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) { 1376a14ee0cSDon Skidmore error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >> 1386a14ee0cSDon Skidmore IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT; 1396a14ee0cSDon Skidmore hw_dbg(hw, "Failed to read, error %x\n", error); 1406a14ee0cSDon Skidmore return IXGBE_ERR_PHY; 1416a14ee0cSDon Skidmore } 1426a14ee0cSDon Skidmore 1436a14ee0cSDon Skidmore if (i == IXGBE_MDIO_COMMAND_TIMEOUT) { 1446a14ee0cSDon Skidmore hw_dbg(hw, "Read timed out\n"); 1456a14ee0cSDon Skidmore return IXGBE_ERR_PHY; 1466a14ee0cSDon Skidmore } 1476a14ee0cSDon Skidmore 1486a14ee0cSDon Skidmore *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA); 1496a14ee0cSDon Skidmore 1506a14ee0cSDon Skidmore return 0; 1516a14ee0cSDon Skidmore } 1526a14ee0cSDon Skidmore 1536a14ee0cSDon Skidmore /** ixgbe_read_ee_hostif_data_X550 - Read EEPROM word using a host interface 1546a14ee0cSDon Skidmore * command assuming that the semaphore is already obtained. 1556a14ee0cSDon Skidmore * @hw: pointer to hardware structure 1566a14ee0cSDon Skidmore * @offset: offset of word in the EEPROM to read 1576a14ee0cSDon Skidmore * @data: word read from the EEPROM 1586a14ee0cSDon Skidmore * 1596a14ee0cSDon Skidmore * Reads a 16 bit word from the EEPROM using the hostif. 1606a14ee0cSDon Skidmore **/ 1616a14ee0cSDon Skidmore s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset, u16 *data) 1626a14ee0cSDon Skidmore { 1636a14ee0cSDon Skidmore s32 status; 1646a14ee0cSDon Skidmore struct ixgbe_hic_read_shadow_ram buffer; 1656a14ee0cSDon Skidmore 1666a14ee0cSDon Skidmore buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD; 1676a14ee0cSDon Skidmore buffer.hdr.req.buf_lenh = 0; 1686a14ee0cSDon Skidmore buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN; 1696a14ee0cSDon Skidmore buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; 1706a14ee0cSDon Skidmore 1716a14ee0cSDon Skidmore /* convert offset from words to bytes */ 1726a14ee0cSDon Skidmore buffer.address = cpu_to_be32(offset * 2); 1736a14ee0cSDon Skidmore /* one word */ 1746a14ee0cSDon Skidmore buffer.length = cpu_to_be16(sizeof(u16)); 1756a14ee0cSDon Skidmore 1766a14ee0cSDon Skidmore status = ixgbe_host_interface_command(hw, (u32 *)&buffer, 1776a14ee0cSDon Skidmore sizeof(buffer), 1786a14ee0cSDon Skidmore IXGBE_HI_COMMAND_TIMEOUT, false); 1796a14ee0cSDon Skidmore if (status) 1806a14ee0cSDon Skidmore return status; 1816a14ee0cSDon Skidmore 1826a14ee0cSDon Skidmore *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, 1836a14ee0cSDon Skidmore FW_NVM_DATA_OFFSET); 1846a14ee0cSDon Skidmore 1856a14ee0cSDon Skidmore return 0; 1866a14ee0cSDon Skidmore } 1876a14ee0cSDon Skidmore 1886a14ee0cSDon Skidmore /** ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif 1896a14ee0cSDon Skidmore * @hw: pointer to hardware structure 1906a14ee0cSDon Skidmore * @offset: offset of word in the EEPROM to read 1916a14ee0cSDon Skidmore * @words: number of words 1926a14ee0cSDon Skidmore * @data: word(s) read from the EEPROM 1936a14ee0cSDon Skidmore * 1946a14ee0cSDon Skidmore * Reads a 16 bit word(s) from the EEPROM using the hostif. 1956a14ee0cSDon Skidmore **/ 1966a14ee0cSDon Skidmore s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, 1976a14ee0cSDon Skidmore u16 offset, u16 words, u16 *data) 1986a14ee0cSDon Skidmore { 1996a14ee0cSDon Skidmore struct ixgbe_hic_read_shadow_ram buffer; 2006a14ee0cSDon Skidmore u32 current_word = 0; 2016a14ee0cSDon Skidmore u16 words_to_read; 2026a14ee0cSDon Skidmore s32 status; 2036a14ee0cSDon Skidmore u32 i; 2046a14ee0cSDon Skidmore 2056a14ee0cSDon Skidmore /* Take semaphore for the entire operation. */ 2066a14ee0cSDon Skidmore status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 2076a14ee0cSDon Skidmore if (status) { 2086a14ee0cSDon Skidmore hw_dbg(hw, "EEPROM read buffer - semaphore failed\n"); 2096a14ee0cSDon Skidmore return status; 2106a14ee0cSDon Skidmore } 2116a14ee0cSDon Skidmore 2126a14ee0cSDon Skidmore while (words) { 2136a14ee0cSDon Skidmore if (words > FW_MAX_READ_BUFFER_SIZE / 2) 2146a14ee0cSDon Skidmore words_to_read = FW_MAX_READ_BUFFER_SIZE / 2; 2156a14ee0cSDon Skidmore else 2166a14ee0cSDon Skidmore words_to_read = words; 2176a14ee0cSDon Skidmore 2186a14ee0cSDon Skidmore buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD; 2196a14ee0cSDon Skidmore buffer.hdr.req.buf_lenh = 0; 2206a14ee0cSDon Skidmore buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN; 2216a14ee0cSDon Skidmore buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; 2226a14ee0cSDon Skidmore 2236a14ee0cSDon Skidmore /* convert offset from words to bytes */ 2246a14ee0cSDon Skidmore buffer.address = cpu_to_be32((offset + current_word) * 2); 2256a14ee0cSDon Skidmore buffer.length = cpu_to_be16(words_to_read * 2); 2266a14ee0cSDon Skidmore 2276a14ee0cSDon Skidmore status = ixgbe_host_interface_command(hw, (u32 *)&buffer, 2286a14ee0cSDon Skidmore sizeof(buffer), 2296a14ee0cSDon Skidmore IXGBE_HI_COMMAND_TIMEOUT, 2306a14ee0cSDon Skidmore false); 2316a14ee0cSDon Skidmore if (status) { 2326a14ee0cSDon Skidmore hw_dbg(hw, "Host interface command failed\n"); 2336a14ee0cSDon Skidmore goto out; 2346a14ee0cSDon Skidmore } 2356a14ee0cSDon Skidmore 2366a14ee0cSDon Skidmore for (i = 0; i < words_to_read; i++) { 2376a14ee0cSDon Skidmore u32 reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) + 2386a14ee0cSDon Skidmore 2 * i; 2396a14ee0cSDon Skidmore u32 value = IXGBE_READ_REG(hw, reg); 2406a14ee0cSDon Skidmore 2416a14ee0cSDon Skidmore data[current_word] = (u16)(value & 0xffff); 2426a14ee0cSDon Skidmore current_word++; 2436a14ee0cSDon Skidmore i++; 2446a14ee0cSDon Skidmore if (i < words_to_read) { 2456a14ee0cSDon Skidmore value >>= 16; 2466a14ee0cSDon Skidmore data[current_word] = (u16)(value & 0xffff); 2476a14ee0cSDon Skidmore current_word++; 2486a14ee0cSDon Skidmore } 2496a14ee0cSDon Skidmore } 2506a14ee0cSDon Skidmore words -= words_to_read; 2516a14ee0cSDon Skidmore } 2526a14ee0cSDon Skidmore 2536a14ee0cSDon Skidmore out: 2546a14ee0cSDon Skidmore hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 2556a14ee0cSDon Skidmore return status; 2566a14ee0cSDon Skidmore } 2576a14ee0cSDon Skidmore 2586a14ee0cSDon Skidmore /** ixgbe_checksum_ptr_x550 - Checksum one pointer region 2596a14ee0cSDon Skidmore * @hw: pointer to hardware structure 2606a14ee0cSDon Skidmore * @ptr: pointer offset in eeprom 2616a14ee0cSDon Skidmore * @size: size of section pointed by ptr, if 0 first word will be used as size 2626a14ee0cSDon Skidmore * @csum: address of checksum to update 2636a14ee0cSDon Skidmore * 2646a14ee0cSDon Skidmore * Returns error status for any failure 2656a14ee0cSDon Skidmore **/ 2666a14ee0cSDon Skidmore static s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr, 2676a14ee0cSDon Skidmore u16 size, u16 *csum, u16 *buffer, 2686a14ee0cSDon Skidmore u32 buffer_size) 2696a14ee0cSDon Skidmore { 2706a14ee0cSDon Skidmore u16 buf[256]; 2716a14ee0cSDon Skidmore s32 status; 2726a14ee0cSDon Skidmore u16 length, bufsz, i, start; 2736a14ee0cSDon Skidmore u16 *local_buffer; 2746a14ee0cSDon Skidmore 2756a14ee0cSDon Skidmore bufsz = sizeof(buf) / sizeof(buf[0]); 2766a14ee0cSDon Skidmore 2776a14ee0cSDon Skidmore /* Read a chunk at the pointer location */ 2786a14ee0cSDon Skidmore if (!buffer) { 2796a14ee0cSDon Skidmore status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf); 2806a14ee0cSDon Skidmore if (status) { 2816a14ee0cSDon Skidmore hw_dbg(hw, "Failed to read EEPROM image\n"); 2826a14ee0cSDon Skidmore return status; 2836a14ee0cSDon Skidmore } 2846a14ee0cSDon Skidmore local_buffer = buf; 2856a14ee0cSDon Skidmore } else { 2866a14ee0cSDon Skidmore if (buffer_size < ptr) 2876a14ee0cSDon Skidmore return IXGBE_ERR_PARAM; 2886a14ee0cSDon Skidmore local_buffer = &buffer[ptr]; 2896a14ee0cSDon Skidmore } 2906a14ee0cSDon Skidmore 2916a14ee0cSDon Skidmore if (size) { 2926a14ee0cSDon Skidmore start = 0; 2936a14ee0cSDon Skidmore length = size; 2946a14ee0cSDon Skidmore } else { 2956a14ee0cSDon Skidmore start = 1; 2966a14ee0cSDon Skidmore length = local_buffer[0]; 2976a14ee0cSDon Skidmore 2986a14ee0cSDon Skidmore /* Skip pointer section if length is invalid. */ 2996a14ee0cSDon Skidmore if (length == 0xFFFF || length == 0 || 3006a14ee0cSDon Skidmore (ptr + length) >= hw->eeprom.word_size) 3016a14ee0cSDon Skidmore return 0; 3026a14ee0cSDon Skidmore } 3036a14ee0cSDon Skidmore 3046a14ee0cSDon Skidmore if (buffer && ((u32)start + (u32)length > buffer_size)) 3056a14ee0cSDon Skidmore return IXGBE_ERR_PARAM; 3066a14ee0cSDon Skidmore 3076a14ee0cSDon Skidmore for (i = start; length; i++, length--) { 3086a14ee0cSDon Skidmore if (i == bufsz && !buffer) { 3096a14ee0cSDon Skidmore ptr += bufsz; 3106a14ee0cSDon Skidmore i = 0; 3116a14ee0cSDon Skidmore if (length < bufsz) 3126a14ee0cSDon Skidmore bufsz = length; 3136a14ee0cSDon Skidmore 3146a14ee0cSDon Skidmore /* Read a chunk at the pointer location */ 3156a14ee0cSDon Skidmore status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, 3166a14ee0cSDon Skidmore bufsz, buf); 3176a14ee0cSDon Skidmore if (status) { 3186a14ee0cSDon Skidmore hw_dbg(hw, "Failed to read EEPROM image\n"); 3196a14ee0cSDon Skidmore return status; 3206a14ee0cSDon Skidmore } 3216a14ee0cSDon Skidmore } 3226a14ee0cSDon Skidmore *csum += local_buffer[i]; 3236a14ee0cSDon Skidmore } 3246a14ee0cSDon Skidmore return 0; 3256a14ee0cSDon Skidmore } 3266a14ee0cSDon Skidmore 3276a14ee0cSDon Skidmore /** ixgbe_calc_checksum_X550 - Calculates and returns the checksum 3286a14ee0cSDon Skidmore * @hw: pointer to hardware structure 3296a14ee0cSDon Skidmore * @buffer: pointer to buffer containing calculated checksum 3306a14ee0cSDon Skidmore * @buffer_size: size of buffer 3316a14ee0cSDon Skidmore * 3326a14ee0cSDon Skidmore * Returns a negative error code on error, or the 16-bit checksum 3336a14ee0cSDon Skidmore **/ 3346a14ee0cSDon Skidmore s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer, u32 buffer_size) 3356a14ee0cSDon Skidmore { 3366a14ee0cSDon Skidmore u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1]; 3376a14ee0cSDon Skidmore u16 *local_buffer; 3386a14ee0cSDon Skidmore s32 status; 3396a14ee0cSDon Skidmore u16 checksum = 0; 3406a14ee0cSDon Skidmore u16 pointer, i, size; 3416a14ee0cSDon Skidmore 3426a14ee0cSDon Skidmore hw->eeprom.ops.init_params(hw); 3436a14ee0cSDon Skidmore 3446a14ee0cSDon Skidmore if (!buffer) { 3456a14ee0cSDon Skidmore /* Read pointer area */ 3466a14ee0cSDon Skidmore status = ixgbe_read_ee_hostif_buffer_X550(hw, 0, 3476a14ee0cSDon Skidmore IXGBE_EEPROM_LAST_WORD + 1, 3486a14ee0cSDon Skidmore eeprom_ptrs); 3496a14ee0cSDon Skidmore if (status) { 3506a14ee0cSDon Skidmore hw_dbg(hw, "Failed to read EEPROM image\n"); 3516a14ee0cSDon Skidmore return status; 3526a14ee0cSDon Skidmore } 3536a14ee0cSDon Skidmore local_buffer = eeprom_ptrs; 3546a14ee0cSDon Skidmore } else { 3556a14ee0cSDon Skidmore if (buffer_size < IXGBE_EEPROM_LAST_WORD) 3566a14ee0cSDon Skidmore return IXGBE_ERR_PARAM; 3576a14ee0cSDon Skidmore local_buffer = buffer; 3586a14ee0cSDon Skidmore } 3596a14ee0cSDon Skidmore 3606a14ee0cSDon Skidmore /* For X550 hardware include 0x0-0x41 in the checksum, skip the 3616a14ee0cSDon Skidmore * checksum word itself 3626a14ee0cSDon Skidmore */ 3636a14ee0cSDon Skidmore for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++) 3646a14ee0cSDon Skidmore if (i != IXGBE_EEPROM_CHECKSUM) 3656a14ee0cSDon Skidmore checksum += local_buffer[i]; 3666a14ee0cSDon Skidmore 3676a14ee0cSDon Skidmore /* Include all data from pointers 0x3, 0x6-0xE. This excludes the 3686a14ee0cSDon Skidmore * FW, PHY module, and PCIe Expansion/Option ROM pointers. 3696a14ee0cSDon Skidmore */ 3706a14ee0cSDon Skidmore for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) { 3716a14ee0cSDon Skidmore if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR) 3726a14ee0cSDon Skidmore continue; 3736a14ee0cSDon Skidmore 3746a14ee0cSDon Skidmore pointer = local_buffer[i]; 3756a14ee0cSDon Skidmore 3766a14ee0cSDon Skidmore /* Skip pointer section if the pointer is invalid. */ 3776a14ee0cSDon Skidmore if (pointer == 0xFFFF || pointer == 0 || 3786a14ee0cSDon Skidmore pointer >= hw->eeprom.word_size) 3796a14ee0cSDon Skidmore continue; 3806a14ee0cSDon Skidmore 3816a14ee0cSDon Skidmore switch (i) { 3826a14ee0cSDon Skidmore case IXGBE_PCIE_GENERAL_PTR: 3836a14ee0cSDon Skidmore size = IXGBE_IXGBE_PCIE_GENERAL_SIZE; 3846a14ee0cSDon Skidmore break; 3856a14ee0cSDon Skidmore case IXGBE_PCIE_CONFIG0_PTR: 3866a14ee0cSDon Skidmore case IXGBE_PCIE_CONFIG1_PTR: 3876a14ee0cSDon Skidmore size = IXGBE_PCIE_CONFIG_SIZE; 3886a14ee0cSDon Skidmore break; 3896a14ee0cSDon Skidmore default: 3906a14ee0cSDon Skidmore size = 0; 3916a14ee0cSDon Skidmore break; 3926a14ee0cSDon Skidmore } 3936a14ee0cSDon Skidmore 3946a14ee0cSDon Skidmore status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum, 3956a14ee0cSDon Skidmore buffer, buffer_size); 3966a14ee0cSDon Skidmore if (status) 3976a14ee0cSDon Skidmore return status; 3986a14ee0cSDon Skidmore } 3996a14ee0cSDon Skidmore 4006a14ee0cSDon Skidmore checksum = (u16)IXGBE_EEPROM_SUM - checksum; 4016a14ee0cSDon Skidmore 4026a14ee0cSDon Skidmore return (s32)checksum; 4036a14ee0cSDon Skidmore } 4046a14ee0cSDon Skidmore 4056a14ee0cSDon Skidmore /** ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum 4066a14ee0cSDon Skidmore * @hw: pointer to hardware structure 4076a14ee0cSDon Skidmore * 4086a14ee0cSDon Skidmore * Returns a negative error code on error, or the 16-bit checksum 4096a14ee0cSDon Skidmore **/ 4106a14ee0cSDon Skidmore s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw) 4116a14ee0cSDon Skidmore { 4126a14ee0cSDon Skidmore return ixgbe_calc_checksum_X550(hw, NULL, 0); 4136a14ee0cSDon Skidmore } 4146a14ee0cSDon Skidmore 4156a14ee0cSDon Skidmore /** ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command 4166a14ee0cSDon Skidmore * @hw: pointer to hardware structure 4176a14ee0cSDon Skidmore * @offset: offset of word in the EEPROM to read 4186a14ee0cSDon Skidmore * @data: word read from the EEPROM 4196a14ee0cSDon Skidmore * 4206a14ee0cSDon Skidmore * Reads a 16 bit word from the EEPROM using the hostif. 4216a14ee0cSDon Skidmore **/ 4226a14ee0cSDon Skidmore s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 *data) 4236a14ee0cSDon Skidmore { 4246a14ee0cSDon Skidmore s32 status = 0; 4256a14ee0cSDon Skidmore 4266a14ee0cSDon Skidmore if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) { 4276a14ee0cSDon Skidmore status = ixgbe_read_ee_hostif_data_X550(hw, offset, data); 4286a14ee0cSDon Skidmore hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 4296a14ee0cSDon Skidmore } else { 4306a14ee0cSDon Skidmore status = IXGBE_ERR_SWFW_SYNC; 4316a14ee0cSDon Skidmore } 4326a14ee0cSDon Skidmore 4336a14ee0cSDon Skidmore return status; 4346a14ee0cSDon Skidmore } 4356a14ee0cSDon Skidmore 4366a14ee0cSDon Skidmore /** ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum 4376a14ee0cSDon Skidmore * @hw: pointer to hardware structure 4386a14ee0cSDon Skidmore * @checksum_val: calculated checksum 4396a14ee0cSDon Skidmore * 4406a14ee0cSDon Skidmore * Performs checksum calculation and validates the EEPROM checksum. If the 4416a14ee0cSDon Skidmore * caller does not need checksum_val, the value can be NULL. 4426a14ee0cSDon Skidmore **/ 4436a14ee0cSDon Skidmore s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, u16 *checksum_val) 4446a14ee0cSDon Skidmore { 4456a14ee0cSDon Skidmore s32 status; 4466a14ee0cSDon Skidmore u16 checksum; 4476a14ee0cSDon Skidmore u16 read_checksum = 0; 4486a14ee0cSDon Skidmore 4496a14ee0cSDon Skidmore /* Read the first word from the EEPROM. If this times out or fails, do 4506a14ee0cSDon Skidmore * not continue or we could be in for a very long wait while every 4516a14ee0cSDon Skidmore * EEPROM read fails 4526a14ee0cSDon Skidmore */ 4536a14ee0cSDon Skidmore status = hw->eeprom.ops.read(hw, 0, &checksum); 4546a14ee0cSDon Skidmore if (status) { 4556a14ee0cSDon Skidmore hw_dbg(hw, "EEPROM read failed\n"); 4566a14ee0cSDon Skidmore return status; 4576a14ee0cSDon Skidmore } 4586a14ee0cSDon Skidmore 4596a14ee0cSDon Skidmore status = hw->eeprom.ops.calc_checksum(hw); 4606a14ee0cSDon Skidmore if (status < 0) 4616a14ee0cSDon Skidmore return status; 4626a14ee0cSDon Skidmore 4636a14ee0cSDon Skidmore checksum = (u16)(status & 0xffff); 4646a14ee0cSDon Skidmore 4656a14ee0cSDon Skidmore status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM, 4666a14ee0cSDon Skidmore &read_checksum); 4676a14ee0cSDon Skidmore if (status) 4686a14ee0cSDon Skidmore return status; 4696a14ee0cSDon Skidmore 4706a14ee0cSDon Skidmore /* Verify read checksum from EEPROM is the same as 4716a14ee0cSDon Skidmore * calculated checksum 4726a14ee0cSDon Skidmore */ 4736a14ee0cSDon Skidmore if (read_checksum != checksum) { 4746a14ee0cSDon Skidmore status = IXGBE_ERR_EEPROM_CHECKSUM; 4756a14ee0cSDon Skidmore hw_dbg(hw, "Invalid EEPROM checksum"); 4766a14ee0cSDon Skidmore } 4776a14ee0cSDon Skidmore 4786a14ee0cSDon Skidmore /* If the user cares, return the calculated checksum */ 4796a14ee0cSDon Skidmore if (checksum_val) 4806a14ee0cSDon Skidmore *checksum_val = checksum; 4816a14ee0cSDon Skidmore 4826a14ee0cSDon Skidmore return status; 4836a14ee0cSDon Skidmore } 4846a14ee0cSDon Skidmore 4856a14ee0cSDon Skidmore /** ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif 4866a14ee0cSDon Skidmore * @hw: pointer to hardware structure 4876a14ee0cSDon Skidmore * @offset: offset of word in the EEPROM to write 4886a14ee0cSDon Skidmore * @data: word write to the EEPROM 4896a14ee0cSDon Skidmore * 4906a14ee0cSDon Skidmore * Write a 16 bit word to the EEPROM using the hostif. 4916a14ee0cSDon Skidmore **/ 4926a14ee0cSDon Skidmore s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset, u16 data) 4936a14ee0cSDon Skidmore { 4946a14ee0cSDon Skidmore s32 status; 4956a14ee0cSDon Skidmore struct ixgbe_hic_write_shadow_ram buffer; 4966a14ee0cSDon Skidmore 4976a14ee0cSDon Skidmore buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD; 4986a14ee0cSDon Skidmore buffer.hdr.req.buf_lenh = 0; 4996a14ee0cSDon Skidmore buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN; 5006a14ee0cSDon Skidmore buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; 5016a14ee0cSDon Skidmore 5026a14ee0cSDon Skidmore /* one word */ 5036a14ee0cSDon Skidmore buffer.length = cpu_to_be16(sizeof(u16)); 5046a14ee0cSDon Skidmore buffer.data = data; 5056a14ee0cSDon Skidmore buffer.address = cpu_to_be32(offset * 2); 5066a14ee0cSDon Skidmore 5076a14ee0cSDon Skidmore status = ixgbe_host_interface_command(hw, (u32 *)&buffer, 5086a14ee0cSDon Skidmore sizeof(buffer), 5096a14ee0cSDon Skidmore IXGBE_HI_COMMAND_TIMEOUT, false); 5106a14ee0cSDon Skidmore return status; 5116a14ee0cSDon Skidmore } 5126a14ee0cSDon Skidmore 5136a14ee0cSDon Skidmore /** ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif 5146a14ee0cSDon Skidmore * @hw: pointer to hardware structure 5156a14ee0cSDon Skidmore * @offset: offset of word in the EEPROM to write 5166a14ee0cSDon Skidmore * @data: word write to the EEPROM 5176a14ee0cSDon Skidmore * 5186a14ee0cSDon Skidmore * Write a 16 bit word to the EEPROM using the hostif. 5196a14ee0cSDon Skidmore **/ 5206a14ee0cSDon Skidmore s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 data) 5216a14ee0cSDon Skidmore { 5226a14ee0cSDon Skidmore s32 status = 0; 5236a14ee0cSDon Skidmore 5246a14ee0cSDon Skidmore if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) { 5256a14ee0cSDon Skidmore status = ixgbe_write_ee_hostif_data_X550(hw, offset, data); 5266a14ee0cSDon Skidmore hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 5276a14ee0cSDon Skidmore } else { 5286a14ee0cSDon Skidmore hw_dbg(hw, "write ee hostif failed to get semaphore"); 5296a14ee0cSDon Skidmore status = IXGBE_ERR_SWFW_SYNC; 5306a14ee0cSDon Skidmore } 5316a14ee0cSDon Skidmore 5326a14ee0cSDon Skidmore return status; 5336a14ee0cSDon Skidmore } 5346a14ee0cSDon Skidmore 5356a14ee0cSDon Skidmore /** ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device 5366a14ee0cSDon Skidmore * @hw: pointer to hardware structure 5376a14ee0cSDon Skidmore * 5386a14ee0cSDon Skidmore * Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash. 5396a14ee0cSDon Skidmore **/ 5406a14ee0cSDon Skidmore s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw) 5416a14ee0cSDon Skidmore { 5426a14ee0cSDon Skidmore s32 status = 0; 5436a14ee0cSDon Skidmore union ixgbe_hic_hdr2 buffer; 5446a14ee0cSDon Skidmore 5456a14ee0cSDon Skidmore buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD; 5466a14ee0cSDon Skidmore buffer.req.buf_lenh = 0; 5476a14ee0cSDon Skidmore buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN; 5486a14ee0cSDon Skidmore buffer.req.checksum = FW_DEFAULT_CHECKSUM; 5496a14ee0cSDon Skidmore 5506a14ee0cSDon Skidmore status = ixgbe_host_interface_command(hw, (u32 *)&buffer, 5516a14ee0cSDon Skidmore sizeof(buffer), 5526a14ee0cSDon Skidmore IXGBE_HI_COMMAND_TIMEOUT, false); 5536a14ee0cSDon Skidmore return status; 5546a14ee0cSDon Skidmore } 5556a14ee0cSDon Skidmore 5566a14ee0cSDon Skidmore /** ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash 5576a14ee0cSDon Skidmore * @hw: pointer to hardware structure 5586a14ee0cSDon Skidmore * 5596a14ee0cSDon Skidmore * After writing EEPROM to shadow RAM using EEWR register, software calculates 5606a14ee0cSDon Skidmore * checksum and updates the EEPROM and instructs the hardware to update 5616a14ee0cSDon Skidmore * the flash. 5626a14ee0cSDon Skidmore **/ 5636a14ee0cSDon Skidmore s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw) 5646a14ee0cSDon Skidmore { 5656a14ee0cSDon Skidmore s32 status; 5666a14ee0cSDon Skidmore u16 checksum = 0; 5676a14ee0cSDon Skidmore 5686a14ee0cSDon Skidmore /* Read the first word from the EEPROM. If this times out or fails, do 5696a14ee0cSDon Skidmore * not continue or we could be in for a very long wait while every 5706a14ee0cSDon Skidmore * EEPROM read fails 5716a14ee0cSDon Skidmore */ 5726a14ee0cSDon Skidmore status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum); 5736a14ee0cSDon Skidmore if (status) { 5746a14ee0cSDon Skidmore hw_dbg(hw, "EEPROM read failed\n"); 5756a14ee0cSDon Skidmore return status; 5766a14ee0cSDon Skidmore } 5776a14ee0cSDon Skidmore 5786a14ee0cSDon Skidmore status = ixgbe_calc_eeprom_checksum_X550(hw); 5796a14ee0cSDon Skidmore if (status < 0) 5806a14ee0cSDon Skidmore return status; 5816a14ee0cSDon Skidmore 5826a14ee0cSDon Skidmore checksum = (u16)(status & 0xffff); 5836a14ee0cSDon Skidmore 5846a14ee0cSDon Skidmore status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM, 5856a14ee0cSDon Skidmore checksum); 5866a14ee0cSDon Skidmore if (status) 5876a14ee0cSDon Skidmore return status; 5886a14ee0cSDon Skidmore 5896a14ee0cSDon Skidmore status = ixgbe_update_flash_X550(hw); 5906a14ee0cSDon Skidmore 5916a14ee0cSDon Skidmore return status; 5926a14ee0cSDon Skidmore } 5936a14ee0cSDon Skidmore 5946a14ee0cSDon Skidmore /** ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hostif 5956a14ee0cSDon Skidmore * @hw: pointer to hardware structure 5966a14ee0cSDon Skidmore * @offset: offset of word in the EEPROM to write 5976a14ee0cSDon Skidmore * @words: number of words 5986a14ee0cSDon Skidmore * @data: word(s) write to the EEPROM 5996a14ee0cSDon Skidmore * 6006a14ee0cSDon Skidmore * 6016a14ee0cSDon Skidmore * Write a 16 bit word(s) to the EEPROM using the hostif. 6026a14ee0cSDon Skidmore **/ 6036a14ee0cSDon Skidmore s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw, 6046a14ee0cSDon Skidmore u16 offset, u16 words, u16 *data) 6056a14ee0cSDon Skidmore { 6066a14ee0cSDon Skidmore s32 status = 0; 6076a14ee0cSDon Skidmore u32 i = 0; 6086a14ee0cSDon Skidmore 6096a14ee0cSDon Skidmore /* Take semaphore for the entire operation. */ 6106a14ee0cSDon Skidmore status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 6116a14ee0cSDon Skidmore if (status) { 6126a14ee0cSDon Skidmore hw_dbg(hw, "EEPROM write buffer - semaphore failed\n"); 6136a14ee0cSDon Skidmore return status; 6146a14ee0cSDon Skidmore } 6156a14ee0cSDon Skidmore 6166a14ee0cSDon Skidmore for (i = 0; i < words; i++) { 6176a14ee0cSDon Skidmore status = ixgbe_write_ee_hostif_data_X550(hw, offset + i, 6186a14ee0cSDon Skidmore data[i]); 6196a14ee0cSDon Skidmore if (status) { 6206a14ee0cSDon Skidmore hw_dbg(hw, "Eeprom buffered write failed\n"); 6216a14ee0cSDon Skidmore break; 6226a14ee0cSDon Skidmore } 6236a14ee0cSDon Skidmore } 6246a14ee0cSDon Skidmore 6256a14ee0cSDon Skidmore hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 6266a14ee0cSDon Skidmore 6276a14ee0cSDon Skidmore return status; 6286a14ee0cSDon Skidmore } 6296a14ee0cSDon Skidmore 6306a14ee0cSDon Skidmore /** ixgbe_init_mac_link_ops_X550em - init mac link function pointers 6316a14ee0cSDon Skidmore * @hw: pointer to hardware structure 6326a14ee0cSDon Skidmore **/ 6336a14ee0cSDon Skidmore void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) 6346a14ee0cSDon Skidmore { 6356a14ee0cSDon Skidmore struct ixgbe_mac_info *mac = &hw->mac; 6366a14ee0cSDon Skidmore 6376a14ee0cSDon Skidmore /* CS4227 does not support autoneg, so disable the laser control 6386a14ee0cSDon Skidmore * functions for SFP+ fiber 6396a14ee0cSDon Skidmore */ 6406a14ee0cSDon Skidmore if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP) { 6416a14ee0cSDon Skidmore mac->ops.disable_tx_laser = NULL; 6426a14ee0cSDon Skidmore mac->ops.enable_tx_laser = NULL; 6436a14ee0cSDon Skidmore mac->ops.flap_tx_laser = NULL; 6446a14ee0cSDon Skidmore } 6456a14ee0cSDon Skidmore } 6466a14ee0cSDon Skidmore 6476a14ee0cSDon Skidmore /** ixgbe_setup_sfp_modules_X550em - Setup SFP module 6486a14ee0cSDon Skidmore * @hw: pointer to hardware structure 6496a14ee0cSDon Skidmore */ 6506a14ee0cSDon Skidmore s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw) 6516a14ee0cSDon Skidmore { 6526a14ee0cSDon Skidmore bool setup_linear; 6536a14ee0cSDon Skidmore u16 reg_slice, edc_mode; 6546a14ee0cSDon Skidmore s32 ret_val; 6556a14ee0cSDon Skidmore 6566a14ee0cSDon Skidmore switch (hw->phy.sfp_type) { 6576a14ee0cSDon Skidmore case ixgbe_sfp_type_unknown: 6586a14ee0cSDon Skidmore return 0; 6596a14ee0cSDon Skidmore case ixgbe_sfp_type_not_present: 6606a14ee0cSDon Skidmore return IXGBE_ERR_SFP_NOT_PRESENT; 6616a14ee0cSDon Skidmore case ixgbe_sfp_type_da_cu_core0: 6626a14ee0cSDon Skidmore case ixgbe_sfp_type_da_cu_core1: 6636a14ee0cSDon Skidmore setup_linear = true; 6646a14ee0cSDon Skidmore break; 6656a14ee0cSDon Skidmore case ixgbe_sfp_type_srlr_core0: 6666a14ee0cSDon Skidmore case ixgbe_sfp_type_srlr_core1: 6676a14ee0cSDon Skidmore case ixgbe_sfp_type_da_act_lmt_core0: 6686a14ee0cSDon Skidmore case ixgbe_sfp_type_da_act_lmt_core1: 6696a14ee0cSDon Skidmore case ixgbe_sfp_type_1g_sx_core0: 6706a14ee0cSDon Skidmore case ixgbe_sfp_type_1g_sx_core1: 6716a14ee0cSDon Skidmore setup_linear = false; 6726a14ee0cSDon Skidmore break; 6736a14ee0cSDon Skidmore default: 6746a14ee0cSDon Skidmore return IXGBE_ERR_SFP_NOT_SUPPORTED; 6756a14ee0cSDon Skidmore } 6766a14ee0cSDon Skidmore 6776a14ee0cSDon Skidmore ixgbe_init_mac_link_ops_X550em(hw); 6786a14ee0cSDon Skidmore hw->phy.ops.reset = NULL; 6796a14ee0cSDon Skidmore 6806a14ee0cSDon Skidmore /* The CS4227 slice address is the base address + the port-pair reg 6816a14ee0cSDon Skidmore * offset. I.e. Slice 0 = 0x12B0 and slice 1 = 0x22B0. 6826a14ee0cSDon Skidmore */ 6836a14ee0cSDon Skidmore reg_slice = IXGBE_CS4227_SPARE24_LSB + (hw->bus.lan_id << 12); 6846a14ee0cSDon Skidmore 6856a14ee0cSDon Skidmore if (setup_linear) 6866a14ee0cSDon Skidmore edc_mode = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1; 6876a14ee0cSDon Skidmore else 6886a14ee0cSDon Skidmore edc_mode = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; 6896a14ee0cSDon Skidmore 6906a14ee0cSDon Skidmore /* Configure CS4227 for connection type. */ 6916a14ee0cSDon Skidmore ret_val = hw->phy.ops.write_i2c_combined(hw, IXGBE_CS4227, reg_slice, 6926a14ee0cSDon Skidmore edc_mode); 6936a14ee0cSDon Skidmore 6946a14ee0cSDon Skidmore if (ret_val) 6956a14ee0cSDon Skidmore ret_val = hw->phy.ops.write_i2c_combined(hw, 0x80, reg_slice, 6966a14ee0cSDon Skidmore edc_mode); 6976a14ee0cSDon Skidmore 6986a14ee0cSDon Skidmore return ret_val; 6996a14ee0cSDon Skidmore } 7006a14ee0cSDon Skidmore 7016a14ee0cSDon Skidmore /** ixgbe_get_link_capabilities_x550em - Determines link capabilities 7026a14ee0cSDon Skidmore * @hw: pointer to hardware structure 7036a14ee0cSDon Skidmore * @speed: pointer to link speed 7046a14ee0cSDon Skidmore * @autoneg: true when autoneg or autotry is enabled 7056a14ee0cSDon Skidmore **/ 7066a14ee0cSDon Skidmore s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw, 7076a14ee0cSDon Skidmore ixgbe_link_speed *speed, 7086a14ee0cSDon Skidmore bool *autoneg) 7096a14ee0cSDon Skidmore { 7106a14ee0cSDon Skidmore /* SFP */ 7116a14ee0cSDon Skidmore if (hw->phy.media_type == ixgbe_media_type_fiber) { 7126a14ee0cSDon Skidmore /* CS4227 SFP must not enable auto-negotiation */ 7136a14ee0cSDon Skidmore *autoneg = false; 7146a14ee0cSDon Skidmore 7156a14ee0cSDon Skidmore if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || 7166a14ee0cSDon Skidmore hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) { 7176a14ee0cSDon Skidmore *speed = IXGBE_LINK_SPEED_1GB_FULL; 7186a14ee0cSDon Skidmore return 0; 7196a14ee0cSDon Skidmore } 7206a14ee0cSDon Skidmore 7216a14ee0cSDon Skidmore /* Link capabilities are based on SFP */ 7226a14ee0cSDon Skidmore if (hw->phy.multispeed_fiber) 7236a14ee0cSDon Skidmore *speed = IXGBE_LINK_SPEED_10GB_FULL | 7246a14ee0cSDon Skidmore IXGBE_LINK_SPEED_1GB_FULL; 7256a14ee0cSDon Skidmore else 7266a14ee0cSDon Skidmore *speed = IXGBE_LINK_SPEED_10GB_FULL; 7276a14ee0cSDon Skidmore } else { 7286a14ee0cSDon Skidmore *speed = IXGBE_LINK_SPEED_10GB_FULL | 7296a14ee0cSDon Skidmore IXGBE_LINK_SPEED_1GB_FULL; 7306a14ee0cSDon Skidmore *autoneg = true; 7316a14ee0cSDon Skidmore } 7326a14ee0cSDon Skidmore return 0; 7336a14ee0cSDon Skidmore } 7346a14ee0cSDon Skidmore 7356a14ee0cSDon Skidmore /** ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register of the 7366a14ee0cSDon Skidmore * IOSF device 7376a14ee0cSDon Skidmore * 7386a14ee0cSDon Skidmore * @hw: pointer to hardware structure 7396a14ee0cSDon Skidmore * @reg_addr: 32 bit PHY register to write 7406a14ee0cSDon Skidmore * @device_type: 3 bit device type 7416a14ee0cSDon Skidmore * @data: Data to write to the register 7426a14ee0cSDon Skidmore **/ 7436a14ee0cSDon Skidmore s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, 7446a14ee0cSDon Skidmore u32 device_type, u32 data) 7456a14ee0cSDon Skidmore { 7466a14ee0cSDon Skidmore u32 i, command, error; 7476a14ee0cSDon Skidmore 7486a14ee0cSDon Skidmore command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) | 7496a14ee0cSDon Skidmore (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT)); 7506a14ee0cSDon Skidmore 7516a14ee0cSDon Skidmore /* Write IOSF control register */ 7526a14ee0cSDon Skidmore IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command); 7536a14ee0cSDon Skidmore 7546a14ee0cSDon Skidmore /* Write IOSF data register */ 7556a14ee0cSDon Skidmore IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data); 7566a14ee0cSDon Skidmore 7576a14ee0cSDon Skidmore /* Check every 10 usec to see if the address cycle completed. 7586a14ee0cSDon Skidmore * The SB IOSF BUSY bit will clear when the operation is 7596a14ee0cSDon Skidmore * complete 7606a14ee0cSDon Skidmore */ 7616a14ee0cSDon Skidmore for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { 7626a14ee0cSDon Skidmore usleep_range(10, 20); 7636a14ee0cSDon Skidmore 7646a14ee0cSDon Skidmore command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL); 7656a14ee0cSDon Skidmore if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0) 7666a14ee0cSDon Skidmore break; 7676a14ee0cSDon Skidmore } 7686a14ee0cSDon Skidmore 7696a14ee0cSDon Skidmore if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) { 7706a14ee0cSDon Skidmore error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >> 7716a14ee0cSDon Skidmore IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT; 7726a14ee0cSDon Skidmore hw_dbg(hw, "Failed to write, error %x\n", error); 7736a14ee0cSDon Skidmore return IXGBE_ERR_PHY; 7746a14ee0cSDon Skidmore } 7756a14ee0cSDon Skidmore 7766a14ee0cSDon Skidmore if (i == IXGBE_MDIO_COMMAND_TIMEOUT) { 7776a14ee0cSDon Skidmore hw_dbg(hw, "Write timed out\n"); 7786a14ee0cSDon Skidmore return IXGBE_ERR_PHY; 7796a14ee0cSDon Skidmore } 7806a14ee0cSDon Skidmore 7816a14ee0cSDon Skidmore return 0; 7826a14ee0cSDon Skidmore } 7836a14ee0cSDon Skidmore 7846a14ee0cSDon Skidmore /** ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode. 7856a14ee0cSDon Skidmore * @hw: pointer to hardware structure 7866a14ee0cSDon Skidmore * @speed: the link speed to force 7876a14ee0cSDon Skidmore * 7886a14ee0cSDon Skidmore * Configures the integrated KR PHY to use iXFI mode. Used to connect an 7896a14ee0cSDon Skidmore * internal and external PHY at a specific speed, without autonegotiation. 7906a14ee0cSDon Skidmore **/ 7916a14ee0cSDon Skidmore static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed) 7926a14ee0cSDon Skidmore { 7936a14ee0cSDon Skidmore s32 status; 7946a14ee0cSDon Skidmore u32 reg_val; 7956a14ee0cSDon Skidmore 7966a14ee0cSDon Skidmore /* Disable AN and force speed to 10G Serial. */ 7976a14ee0cSDon Skidmore status = ixgbe_read_iosf_sb_reg_x550(hw, 7986a14ee0cSDon Skidmore IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 7996a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 8006a14ee0cSDon Skidmore if (status) 8016a14ee0cSDon Skidmore return status; 8026a14ee0cSDon Skidmore 8036a14ee0cSDon Skidmore reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; 8046a14ee0cSDon Skidmore reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; 8056a14ee0cSDon Skidmore 8066a14ee0cSDon Skidmore /* Select forced link speed for internal PHY. */ 8076a14ee0cSDon Skidmore switch (*speed) { 8086a14ee0cSDon Skidmore case IXGBE_LINK_SPEED_10GB_FULL: 8096a14ee0cSDon Skidmore reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G; 8106a14ee0cSDon Skidmore break; 8116a14ee0cSDon Skidmore case IXGBE_LINK_SPEED_1GB_FULL: 8126a14ee0cSDon Skidmore reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G; 8136a14ee0cSDon Skidmore break; 8146a14ee0cSDon Skidmore default: 8156a14ee0cSDon Skidmore /* Other link speeds are not supported by internal KR PHY. */ 8166a14ee0cSDon Skidmore return IXGBE_ERR_LINK_SETUP; 8176a14ee0cSDon Skidmore } 8186a14ee0cSDon Skidmore 8196a14ee0cSDon Skidmore status = ixgbe_write_iosf_sb_reg_x550(hw, 8206a14ee0cSDon Skidmore IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), 8216a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 8226a14ee0cSDon Skidmore if (status) 8236a14ee0cSDon Skidmore return status; 8246a14ee0cSDon Skidmore 8256a14ee0cSDon Skidmore /* Disable training protocol FSM. */ 8266a14ee0cSDon Skidmore status = ixgbe_read_iosf_sb_reg_x550(hw, 8276a14ee0cSDon Skidmore IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), 8286a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 8296a14ee0cSDon Skidmore if (status) 8306a14ee0cSDon Skidmore return status; 8316a14ee0cSDon Skidmore 8326a14ee0cSDon Skidmore reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL; 8336a14ee0cSDon Skidmore status = ixgbe_write_iosf_sb_reg_x550(hw, 8346a14ee0cSDon Skidmore IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), 8356a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 8366a14ee0cSDon Skidmore if (status) 8376a14ee0cSDon Skidmore return status; 8386a14ee0cSDon Skidmore 8396a14ee0cSDon Skidmore /* Disable Flex from training TXFFE. */ 8406a14ee0cSDon Skidmore status = ixgbe_read_iosf_sb_reg_x550(hw, 8416a14ee0cSDon Skidmore IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id), 8426a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 8436a14ee0cSDon Skidmore if (status) 8446a14ee0cSDon Skidmore return status; 8456a14ee0cSDon Skidmore 8466a14ee0cSDon Skidmore reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN; 8476a14ee0cSDon Skidmore reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN; 8486a14ee0cSDon Skidmore reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN; 8496a14ee0cSDon Skidmore status = ixgbe_write_iosf_sb_reg_x550(hw, 8506a14ee0cSDon Skidmore IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id), 8516a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 8526a14ee0cSDon Skidmore if (status) 8536a14ee0cSDon Skidmore return status; 8546a14ee0cSDon Skidmore 8556a14ee0cSDon Skidmore status = ixgbe_read_iosf_sb_reg_x550(hw, 8566a14ee0cSDon Skidmore IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id), 8576a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 8586a14ee0cSDon Skidmore if (status) 8596a14ee0cSDon Skidmore return status; 8606a14ee0cSDon Skidmore 8616a14ee0cSDon Skidmore reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN; 8626a14ee0cSDon Skidmore reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN; 8636a14ee0cSDon Skidmore reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN; 8646a14ee0cSDon Skidmore status = ixgbe_write_iosf_sb_reg_x550(hw, 8656a14ee0cSDon Skidmore IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id), 8666a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 8676a14ee0cSDon Skidmore if (status) 8686a14ee0cSDon Skidmore return status; 8696a14ee0cSDon Skidmore 8706a14ee0cSDon Skidmore /* Enable override for coefficients. */ 8716a14ee0cSDon Skidmore status = ixgbe_read_iosf_sb_reg_x550(hw, 8726a14ee0cSDon Skidmore IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id), 8736a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 8746a14ee0cSDon Skidmore if (status) 8756a14ee0cSDon Skidmore return status; 8766a14ee0cSDon Skidmore 8776a14ee0cSDon Skidmore reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN; 8786a14ee0cSDon Skidmore reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN; 8796a14ee0cSDon Skidmore reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN; 8806a14ee0cSDon Skidmore reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN; 8816a14ee0cSDon Skidmore status = ixgbe_write_iosf_sb_reg_x550(hw, 8826a14ee0cSDon Skidmore IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id), 8836a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 8846a14ee0cSDon Skidmore if (status) 8856a14ee0cSDon Skidmore return status; 8866a14ee0cSDon Skidmore 8876a14ee0cSDon Skidmore /* Toggle port SW reset by AN reset. */ 8886a14ee0cSDon Skidmore status = ixgbe_read_iosf_sb_reg_x550(hw, 8896a14ee0cSDon Skidmore IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 8906a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 8916a14ee0cSDon Skidmore if (status) 8926a14ee0cSDon Skidmore return status; 8936a14ee0cSDon Skidmore 8946a14ee0cSDon Skidmore reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART; 8956a14ee0cSDon Skidmore status = ixgbe_write_iosf_sb_reg_x550(hw, 8966a14ee0cSDon Skidmore IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 8976a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 8986a14ee0cSDon Skidmore 8996a14ee0cSDon Skidmore return status; 9006a14ee0cSDon Skidmore } 9016a14ee0cSDon Skidmore 9026a14ee0cSDon Skidmore /** ixgbe_setup_kx4_x550em - Configure the KX4 PHY. 9036a14ee0cSDon Skidmore * @hw: pointer to hardware structure 9046a14ee0cSDon Skidmore * 9056a14ee0cSDon Skidmore * Configures the integrated KX4 PHY. 9066a14ee0cSDon Skidmore **/ 9076a14ee0cSDon Skidmore s32 ixgbe_setup_kx4_x550em(struct ixgbe_hw *hw) 9086a14ee0cSDon Skidmore { 9096a14ee0cSDon Skidmore s32 status; 9106a14ee0cSDon Skidmore u32 reg_val; 9116a14ee0cSDon Skidmore 9126a14ee0cSDon Skidmore status = ixgbe_read_iosf_sb_reg_x550(hw, IXGBE_KX4_LINK_CNTL_1, 9136a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KX4_PCS0 + 9146a14ee0cSDon Skidmore hw->bus.lan_id, ®_val); 9156a14ee0cSDon Skidmore if (status) 9166a14ee0cSDon Skidmore return status; 9176a14ee0cSDon Skidmore 9186a14ee0cSDon Skidmore reg_val &= ~(IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX4 | 9196a14ee0cSDon Skidmore IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX); 9206a14ee0cSDon Skidmore 9216a14ee0cSDon Skidmore reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_ENABLE; 9226a14ee0cSDon Skidmore 9236a14ee0cSDon Skidmore /* Advertise 10G support. */ 9246a14ee0cSDon Skidmore if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) 9256a14ee0cSDon Skidmore reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX4; 9266a14ee0cSDon Skidmore 9276a14ee0cSDon Skidmore /* Advertise 1G support. */ 9286a14ee0cSDon Skidmore if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) 9296a14ee0cSDon Skidmore reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX; 9306a14ee0cSDon Skidmore 9316a14ee0cSDon Skidmore /* Restart auto-negotiation. */ 9326a14ee0cSDon Skidmore reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_RESTART; 9336a14ee0cSDon Skidmore status = ixgbe_write_iosf_sb_reg_x550(hw, IXGBE_KX4_LINK_CNTL_1, 9346a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KX4_PCS0 + 9356a14ee0cSDon Skidmore hw->bus.lan_id, reg_val); 9366a14ee0cSDon Skidmore 9376a14ee0cSDon Skidmore return status; 9386a14ee0cSDon Skidmore } 9396a14ee0cSDon Skidmore 9406a14ee0cSDon Skidmore /** ixgbe_setup_kr_x550em - Configure the KR PHY. 9416a14ee0cSDon Skidmore * @hw: pointer to hardware structure 9426a14ee0cSDon Skidmore * 9436a14ee0cSDon Skidmore * Configures the integrated KR PHY. 9446a14ee0cSDon Skidmore **/ 9456a14ee0cSDon Skidmore s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw) 9466a14ee0cSDon Skidmore { 9476a14ee0cSDon Skidmore s32 status; 9486a14ee0cSDon Skidmore u32 reg_val; 9496a14ee0cSDon Skidmore 9506a14ee0cSDon Skidmore status = ixgbe_read_iosf_sb_reg_x550(hw, 9516a14ee0cSDon Skidmore IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 9526a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); 9536a14ee0cSDon Skidmore if (status) 9546a14ee0cSDon Skidmore return status; 9556a14ee0cSDon Skidmore 9566a14ee0cSDon Skidmore reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; 9576a14ee0cSDon Skidmore reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_FEC_REQ; 9586a14ee0cSDon Skidmore reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC; 9596a14ee0cSDon Skidmore reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR | 9606a14ee0cSDon Skidmore IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX); 9616a14ee0cSDon Skidmore 9626a14ee0cSDon Skidmore /* Advertise 10G support. */ 9636a14ee0cSDon Skidmore if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) 9646a14ee0cSDon Skidmore reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR; 9656a14ee0cSDon Skidmore 9666a14ee0cSDon Skidmore /* Advertise 1G support. */ 9676a14ee0cSDon Skidmore if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) 9686a14ee0cSDon Skidmore reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX; 9696a14ee0cSDon Skidmore 9706a14ee0cSDon Skidmore /* Restart auto-negotiation. */ 9716a14ee0cSDon Skidmore reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART; 9726a14ee0cSDon Skidmore status = ixgbe_write_iosf_sb_reg_x550(hw, 9736a14ee0cSDon Skidmore IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), 9746a14ee0cSDon Skidmore IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); 9756a14ee0cSDon Skidmore 9766a14ee0cSDon Skidmore return status; 9776a14ee0cSDon Skidmore } 9786a14ee0cSDon Skidmore 9796a14ee0cSDon Skidmore /** ixgbe_setup_internal_phy_x550em - Configure integrated KR PHY 9806a14ee0cSDon Skidmore * @hw: point to hardware structure 9816a14ee0cSDon Skidmore * 9826a14ee0cSDon Skidmore * Configures the integrated KR PHY to talk to the external PHY. The base 9836a14ee0cSDon Skidmore * driver will call this function when it gets notification via interrupt from 9846a14ee0cSDon Skidmore * the external PHY. This function forces the internal PHY into iXFI mode at 9856a14ee0cSDon Skidmore * the correct speed. 9866a14ee0cSDon Skidmore * 9876a14ee0cSDon Skidmore * A return of a non-zero value indicates an error, and the base driver should 9886a14ee0cSDon Skidmore * not report link up. 9896a14ee0cSDon Skidmore **/ 9906a14ee0cSDon Skidmore s32 ixgbe_setup_internal_phy_x550em(struct ixgbe_hw *hw) 9916a14ee0cSDon Skidmore { 9926a14ee0cSDon Skidmore u32 status; 9936a14ee0cSDon Skidmore u16 lasi, autoneg_status, speed; 9946a14ee0cSDon Skidmore ixgbe_link_speed force_speed; 9956a14ee0cSDon Skidmore 9966a14ee0cSDon Skidmore /* Verify that the external link status has changed */ 9976a14ee0cSDon Skidmore status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_XENPAK_LASI_STATUS, 9986a14ee0cSDon Skidmore IXGBE_MDIO_PMA_PMD_DEV_TYPE, &lasi); 9996a14ee0cSDon Skidmore if (status) 10006a14ee0cSDon Skidmore return status; 10016a14ee0cSDon Skidmore 10026a14ee0cSDon Skidmore /* If there was no change in link status, we can just exit */ 10036a14ee0cSDon Skidmore if (!(lasi & IXGBE_XENPAK_LASI_LINK_STATUS_ALARM)) 10046a14ee0cSDon Skidmore return 0; 10056a14ee0cSDon Skidmore 10066a14ee0cSDon Skidmore /* we read this twice back to back to indicate current status */ 10076a14ee0cSDon Skidmore status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, 10086a14ee0cSDon Skidmore IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 10096a14ee0cSDon Skidmore &autoneg_status); 10106a14ee0cSDon Skidmore if (status) 10116a14ee0cSDon Skidmore return status; 10126a14ee0cSDon Skidmore 10136a14ee0cSDon Skidmore status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, 10146a14ee0cSDon Skidmore IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 10156a14ee0cSDon Skidmore &autoneg_status); 10166a14ee0cSDon Skidmore if (status) 10176a14ee0cSDon Skidmore return status; 10186a14ee0cSDon Skidmore 10196a14ee0cSDon Skidmore /* If link is not up return an error indicating treat link as down */ 10206a14ee0cSDon Skidmore if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS)) 10216a14ee0cSDon Skidmore return IXGBE_ERR_INVALID_LINK_SETTINGS; 10226a14ee0cSDon Skidmore 10236a14ee0cSDon Skidmore status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT, 10246a14ee0cSDon Skidmore IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 10256a14ee0cSDon Skidmore &speed); 10266a14ee0cSDon Skidmore 10276a14ee0cSDon Skidmore /* clear everything but the speed and duplex bits */ 10286a14ee0cSDon Skidmore speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK; 10296a14ee0cSDon Skidmore 10306a14ee0cSDon Skidmore switch (speed) { 10316a14ee0cSDon Skidmore case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL: 10326a14ee0cSDon Skidmore force_speed = IXGBE_LINK_SPEED_10GB_FULL; 10336a14ee0cSDon Skidmore break; 10346a14ee0cSDon Skidmore case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL: 10356a14ee0cSDon Skidmore force_speed = IXGBE_LINK_SPEED_1GB_FULL; 10366a14ee0cSDon Skidmore break; 10376a14ee0cSDon Skidmore default: 10386a14ee0cSDon Skidmore /* Internal PHY does not support anything else */ 10396a14ee0cSDon Skidmore return IXGBE_ERR_INVALID_LINK_SETTINGS; 10406a14ee0cSDon Skidmore } 10416a14ee0cSDon Skidmore 10426a14ee0cSDon Skidmore return ixgbe_setup_ixfi_x550em(hw, &force_speed); 10436a14ee0cSDon Skidmore } 10446a14ee0cSDon Skidmore 10456a14ee0cSDon Skidmore /** ixgbe_init_phy_ops_X550em - PHY/SFP specific init 10466a14ee0cSDon Skidmore * @hw: pointer to hardware structure 10476a14ee0cSDon Skidmore * 10486a14ee0cSDon Skidmore * Initialize any function pointers that were not able to be 10496a14ee0cSDon Skidmore * set during init_shared_code because the PHY/SFP type was 10506a14ee0cSDon Skidmore * not known. Perform the SFP init if necessary. 10516a14ee0cSDon Skidmore **/ 10526a14ee0cSDon Skidmore s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw) 10536a14ee0cSDon Skidmore { 10546a14ee0cSDon Skidmore struct ixgbe_phy_info *phy = &hw->phy; 10556a14ee0cSDon Skidmore s32 ret_val; 10566a14ee0cSDon Skidmore u32 esdp; 10576a14ee0cSDon Skidmore 10586a14ee0cSDon Skidmore if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP) { 10596a14ee0cSDon Skidmore esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); 10606a14ee0cSDon Skidmore phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM; 10616a14ee0cSDon Skidmore 10626a14ee0cSDon Skidmore if (hw->bus.lan_id) { 10636a14ee0cSDon Skidmore esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1); 10646a14ee0cSDon Skidmore esdp |= IXGBE_ESDP_SDP1_DIR; 10656a14ee0cSDon Skidmore } 10666a14ee0cSDon Skidmore esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR); 10676a14ee0cSDon Skidmore IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); 10686a14ee0cSDon Skidmore } 10696a14ee0cSDon Skidmore 10706a14ee0cSDon Skidmore /* Identify the PHY or SFP module */ 10716a14ee0cSDon Skidmore ret_val = phy->ops.identify(hw); 10726a14ee0cSDon Skidmore 10736a14ee0cSDon Skidmore /* Setup function pointers based on detected SFP module and speeds */ 10746a14ee0cSDon Skidmore ixgbe_init_mac_link_ops_X550em(hw); 10756a14ee0cSDon Skidmore if (phy->sfp_type != ixgbe_sfp_type_unknown) 10766a14ee0cSDon Skidmore phy->ops.reset = NULL; 10776a14ee0cSDon Skidmore 10786a14ee0cSDon Skidmore /* Set functions pointers based on phy type */ 10796a14ee0cSDon Skidmore switch (hw->phy.type) { 10806a14ee0cSDon Skidmore case ixgbe_phy_x550em_kx4: 10816a14ee0cSDon Skidmore phy->ops.setup_link = ixgbe_setup_kx4_x550em; 10826a14ee0cSDon Skidmore phy->ops.read_reg = ixgbe_read_phy_reg_x550em; 10836a14ee0cSDon Skidmore phy->ops.write_reg = ixgbe_write_phy_reg_x550em; 10846a14ee0cSDon Skidmore break; 10856a14ee0cSDon Skidmore case ixgbe_phy_x550em_kr: 10866a14ee0cSDon Skidmore phy->ops.setup_link = ixgbe_setup_kr_x550em; 10876a14ee0cSDon Skidmore phy->ops.read_reg = ixgbe_read_phy_reg_x550em; 10886a14ee0cSDon Skidmore phy->ops.write_reg = ixgbe_write_phy_reg_x550em; 10896a14ee0cSDon Skidmore break; 10906a14ee0cSDon Skidmore case ixgbe_phy_x550em_ext_t: 10916a14ee0cSDon Skidmore phy->ops.setup_internal_link = ixgbe_setup_internal_phy_x550em; 10926a14ee0cSDon Skidmore break; 10936a14ee0cSDon Skidmore default: 10946a14ee0cSDon Skidmore break; 10956a14ee0cSDon Skidmore } 10966a14ee0cSDon Skidmore return ret_val; 10976a14ee0cSDon Skidmore } 10986a14ee0cSDon Skidmore 10996a14ee0cSDon Skidmore /** ixgbe_get_media_type_X550em - Get media type 11006a14ee0cSDon Skidmore * @hw: pointer to hardware structure 11016a14ee0cSDon Skidmore * 11026a14ee0cSDon Skidmore * Returns the media type (fiber, copper, backplane) 11036a14ee0cSDon Skidmore * 11046a14ee0cSDon Skidmore */ 11056a14ee0cSDon Skidmore enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw) 11066a14ee0cSDon Skidmore { 11076a14ee0cSDon Skidmore enum ixgbe_media_type media_type; 11086a14ee0cSDon Skidmore 11096a14ee0cSDon Skidmore /* Detect if there is a copper PHY attached. */ 11106a14ee0cSDon Skidmore switch (hw->device_id) { 11116a14ee0cSDon Skidmore case IXGBE_DEV_ID_X550EM_X_KR: 11126a14ee0cSDon Skidmore case IXGBE_DEV_ID_X550EM_X_KX4: 11136a14ee0cSDon Skidmore media_type = ixgbe_media_type_backplane; 11146a14ee0cSDon Skidmore break; 11156a14ee0cSDon Skidmore case IXGBE_DEV_ID_X550EM_X_SFP: 11166a14ee0cSDon Skidmore media_type = ixgbe_media_type_fiber; 11176a14ee0cSDon Skidmore break; 11186a14ee0cSDon Skidmore case IXGBE_DEV_ID_X550EM_X_1G_T: 11196a14ee0cSDon Skidmore case IXGBE_DEV_ID_X550EM_X_10G_T: 11206a14ee0cSDon Skidmore media_type = ixgbe_media_type_copper; 11216a14ee0cSDon Skidmore break; 11226a14ee0cSDon Skidmore default: 11236a14ee0cSDon Skidmore media_type = ixgbe_media_type_unknown; 11246a14ee0cSDon Skidmore break; 11256a14ee0cSDon Skidmore } 11266a14ee0cSDon Skidmore return media_type; 11276a14ee0cSDon Skidmore } 11286a14ee0cSDon Skidmore 11296a14ee0cSDon Skidmore /** ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY. 11306a14ee0cSDon Skidmore ** @hw: pointer to hardware structure 11316a14ee0cSDon Skidmore **/ 11326a14ee0cSDon Skidmore s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw) 11336a14ee0cSDon Skidmore { 11346a14ee0cSDon Skidmore u32 status; 11356a14ee0cSDon Skidmore u16 reg; 11366a14ee0cSDon Skidmore u32 retries = 2; 11376a14ee0cSDon Skidmore 11386a14ee0cSDon Skidmore do { 11396a14ee0cSDon Skidmore /* decrement retries counter and exit if we hit 0 */ 11406a14ee0cSDon Skidmore if (retries < 1) { 11416a14ee0cSDon Skidmore hw_dbg(hw, "External PHY not yet finished resetting."); 11426a14ee0cSDon Skidmore return IXGBE_ERR_PHY; 11436a14ee0cSDon Skidmore } 11446a14ee0cSDon Skidmore retries--; 11456a14ee0cSDon Skidmore 11466a14ee0cSDon Skidmore status = hw->phy.ops.read_reg(hw, 11476a14ee0cSDon Skidmore IXGBE_MDIO_TX_VENDOR_ALARMS_3, 11486a14ee0cSDon Skidmore IXGBE_MDIO_PMA_PMD_DEV_TYPE, 11496a14ee0cSDon Skidmore ®); 11506a14ee0cSDon Skidmore if (status) 11516a14ee0cSDon Skidmore return status; 11526a14ee0cSDon Skidmore 11536a14ee0cSDon Skidmore /* Verify PHY FW reset has completed */ 11546a14ee0cSDon Skidmore } while ((reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) != 1); 11556a14ee0cSDon Skidmore 11566a14ee0cSDon Skidmore /* Set port to low power mode */ 11576a14ee0cSDon Skidmore status = hw->phy.ops.read_reg(hw, 11586a14ee0cSDon Skidmore IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL, 11596a14ee0cSDon Skidmore IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 11606a14ee0cSDon Skidmore ®); 11616a14ee0cSDon Skidmore if (status) 11626a14ee0cSDon Skidmore return status; 11636a14ee0cSDon Skidmore 11646a14ee0cSDon Skidmore /* Enable the transmitter */ 11656a14ee0cSDon Skidmore status = hw->phy.ops.read_reg(hw, 11666a14ee0cSDon Skidmore IXGBE_MDIO_PMD_STD_TX_DISABLE_CNTR, 11676a14ee0cSDon Skidmore IXGBE_MDIO_PMA_PMD_DEV_TYPE, 11686a14ee0cSDon Skidmore ®); 11696a14ee0cSDon Skidmore if (status) 11706a14ee0cSDon Skidmore return status; 11716a14ee0cSDon Skidmore 11726a14ee0cSDon Skidmore reg &= ~IXGBE_MDIO_PMD_GLOBAL_TX_DISABLE; 11736a14ee0cSDon Skidmore 11746a14ee0cSDon Skidmore status = hw->phy.ops.write_reg(hw, 11756a14ee0cSDon Skidmore IXGBE_MDIO_PMD_STD_TX_DISABLE_CNTR, 11766a14ee0cSDon Skidmore IXGBE_MDIO_PMA_PMD_DEV_TYPE, 11776a14ee0cSDon Skidmore reg); 11786a14ee0cSDon Skidmore if (status) 11796a14ee0cSDon Skidmore return status; 11806a14ee0cSDon Skidmore 11816a14ee0cSDon Skidmore /* Un-stall the PHY FW */ 11826a14ee0cSDon Skidmore status = hw->phy.ops.read_reg(hw, 11836a14ee0cSDon Skidmore IXGBE_MDIO_GLOBAL_RES_PR_10, 11846a14ee0cSDon Skidmore IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 11856a14ee0cSDon Skidmore ®); 11866a14ee0cSDon Skidmore if (status) 11876a14ee0cSDon Skidmore return status; 11886a14ee0cSDon Skidmore 11896a14ee0cSDon Skidmore reg &= ~IXGBE_MDIO_POWER_UP_STALL; 11906a14ee0cSDon Skidmore 11916a14ee0cSDon Skidmore status = hw->phy.ops.write_reg(hw, 11926a14ee0cSDon Skidmore IXGBE_MDIO_GLOBAL_RES_PR_10, 11936a14ee0cSDon Skidmore IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, 11946a14ee0cSDon Skidmore reg); 11956a14ee0cSDon Skidmore return status; 11966a14ee0cSDon Skidmore } 11976a14ee0cSDon Skidmore 11986a14ee0cSDon Skidmore /** ixgbe_reset_hw_X550em - Perform hardware reset 11996a14ee0cSDon Skidmore ** @hw: pointer to hardware structure 12006a14ee0cSDon Skidmore ** 12016a14ee0cSDon Skidmore ** Resets the hardware by resetting the transmit and receive units, masks 12026a14ee0cSDon Skidmore ** and clears all interrupts, perform a PHY reset, and perform a link (MAC) 12036a14ee0cSDon Skidmore ** reset. 12046a14ee0cSDon Skidmore **/ 12056a14ee0cSDon Skidmore s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) 12066a14ee0cSDon Skidmore { 12076a14ee0cSDon Skidmore ixgbe_link_speed link_speed; 12086a14ee0cSDon Skidmore s32 status; 12096a14ee0cSDon Skidmore u32 ctrl = 0; 12106a14ee0cSDon Skidmore u32 i; 12116a14ee0cSDon Skidmore bool link_up = false; 12126a14ee0cSDon Skidmore 12136a14ee0cSDon Skidmore /* Call adapter stop to disable Tx/Rx and clear interrupts */ 12146a14ee0cSDon Skidmore status = hw->mac.ops.stop_adapter(hw); 12156a14ee0cSDon Skidmore if (status) 12166a14ee0cSDon Skidmore return status; 12176a14ee0cSDon Skidmore 12186a14ee0cSDon Skidmore /* flush pending Tx transactions */ 12196a14ee0cSDon Skidmore ixgbe_clear_tx_pending(hw); 12206a14ee0cSDon Skidmore 12216a14ee0cSDon Skidmore /* PHY ops must be identified and initialized prior to reset */ 12226a14ee0cSDon Skidmore 12236a14ee0cSDon Skidmore /* Identify PHY and related function pointers */ 12246a14ee0cSDon Skidmore status = hw->phy.ops.init(hw); 12256a14ee0cSDon Skidmore 12266a14ee0cSDon Skidmore /* start the external PHY */ 12276a14ee0cSDon Skidmore if (hw->phy.type == ixgbe_phy_x550em_ext_t) { 12286a14ee0cSDon Skidmore status = ixgbe_init_ext_t_x550em(hw); 12296a14ee0cSDon Skidmore if (status) 12306a14ee0cSDon Skidmore return status; 12316a14ee0cSDon Skidmore } 12326a14ee0cSDon Skidmore 12336a14ee0cSDon Skidmore /* Setup SFP module if there is one present. */ 12346a14ee0cSDon Skidmore if (hw->phy.sfp_setup_needed) { 12356a14ee0cSDon Skidmore status = hw->mac.ops.setup_sfp(hw); 12366a14ee0cSDon Skidmore hw->phy.sfp_setup_needed = false; 12376a14ee0cSDon Skidmore } 12386a14ee0cSDon Skidmore 12396a14ee0cSDon Skidmore /* Reset PHY */ 12406a14ee0cSDon Skidmore if (!hw->phy.reset_disable && hw->phy.ops.reset) 12416a14ee0cSDon Skidmore hw->phy.ops.reset(hw); 12426a14ee0cSDon Skidmore 12436a14ee0cSDon Skidmore mac_reset_top: 12446a14ee0cSDon Skidmore /* Issue global reset to the MAC. Needs to be SW reset if link is up. 12456a14ee0cSDon Skidmore * If link reset is used when link is up, it might reset the PHY when 12466a14ee0cSDon Skidmore * mng is using it. If link is down or the flag to force full link 12476a14ee0cSDon Skidmore * reset is set, then perform link reset. 12486a14ee0cSDon Skidmore */ 12496a14ee0cSDon Skidmore ctrl = IXGBE_CTRL_LNK_RST; 12506a14ee0cSDon Skidmore 12516a14ee0cSDon Skidmore if (!hw->force_full_reset) { 12526a14ee0cSDon Skidmore hw->mac.ops.check_link(hw, &link_speed, &link_up, false); 12536a14ee0cSDon Skidmore if (link_up) 12546a14ee0cSDon Skidmore ctrl = IXGBE_CTRL_RST; 12556a14ee0cSDon Skidmore } 12566a14ee0cSDon Skidmore 12576a14ee0cSDon Skidmore ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); 12586a14ee0cSDon Skidmore IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); 12596a14ee0cSDon Skidmore IXGBE_WRITE_FLUSH(hw); 12606a14ee0cSDon Skidmore 12616a14ee0cSDon Skidmore /* Poll for reset bit to self-clear meaning reset is complete */ 12626a14ee0cSDon Skidmore for (i = 0; i < 10; i++) { 12636a14ee0cSDon Skidmore udelay(1); 12646a14ee0cSDon Skidmore ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); 12656a14ee0cSDon Skidmore if (!(ctrl & IXGBE_CTRL_RST_MASK)) 12666a14ee0cSDon Skidmore break; 12676a14ee0cSDon Skidmore } 12686a14ee0cSDon Skidmore 12696a14ee0cSDon Skidmore if (ctrl & IXGBE_CTRL_RST_MASK) { 12706a14ee0cSDon Skidmore status = IXGBE_ERR_RESET_FAILED; 12716a14ee0cSDon Skidmore hw_dbg(hw, "Reset polling failed to complete.\n"); 12726a14ee0cSDon Skidmore } 12736a14ee0cSDon Skidmore 12746a14ee0cSDon Skidmore msleep(50); 12756a14ee0cSDon Skidmore 12766a14ee0cSDon Skidmore /* Double resets are required for recovery from certain error 12776a14ee0cSDon Skidmore * clear the multicast table. Also reset num_rar_entries to 128, 12786a14ee0cSDon Skidmore * since we modify this value when programming the SAN MAC address. 12796a14ee0cSDon Skidmore */ 12806a14ee0cSDon Skidmore if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { 12816a14ee0cSDon Skidmore hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; 12826a14ee0cSDon Skidmore goto mac_reset_top; 12836a14ee0cSDon Skidmore } 12846a14ee0cSDon Skidmore 12856a14ee0cSDon Skidmore /* Store the permanent mac address */ 12866a14ee0cSDon Skidmore hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); 12876a14ee0cSDon Skidmore 12886a14ee0cSDon Skidmore /* Store MAC address from RAR0, clear receive address registers, and 12896a14ee0cSDon Skidmore * clear the multicast table. Also reset num_rar_entries to 128, 12906a14ee0cSDon Skidmore * since we modify this value when programming the SAN MAC address. 12916a14ee0cSDon Skidmore */ 12926a14ee0cSDon Skidmore hw->mac.num_rar_entries = 128; 12936a14ee0cSDon Skidmore hw->mac.ops.init_rx_addrs(hw); 12946a14ee0cSDon Skidmore 12956a14ee0cSDon Skidmore return status; 12966a14ee0cSDon Skidmore } 12976a14ee0cSDon Skidmore 12986a14ee0cSDon Skidmore #define X550_COMMON_MAC \ 12996a14ee0cSDon Skidmore .init_hw = &ixgbe_init_hw_generic, \ 13006a14ee0cSDon Skidmore .start_hw = &ixgbe_start_hw_X540, \ 13016a14ee0cSDon Skidmore .clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic, \ 13026a14ee0cSDon Skidmore .enable_rx_dma = &ixgbe_enable_rx_dma_generic, \ 13036a14ee0cSDon Skidmore .get_mac_addr = &ixgbe_get_mac_addr_generic, \ 13046a14ee0cSDon Skidmore .get_device_caps = &ixgbe_get_device_caps_generic, \ 13056a14ee0cSDon Skidmore .stop_adapter = &ixgbe_stop_adapter_generic, \ 13066a14ee0cSDon Skidmore .get_bus_info = &ixgbe_get_bus_info_generic, \ 13076a14ee0cSDon Skidmore .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie, \ 13086a14ee0cSDon Skidmore .read_analog_reg8 = NULL, \ 13096a14ee0cSDon Skidmore .write_analog_reg8 = NULL, \ 13106a14ee0cSDon Skidmore .set_rxpba = &ixgbe_set_rxpba_generic, \ 13116a14ee0cSDon Skidmore .check_link = &ixgbe_check_mac_link_generic, \ 13126a14ee0cSDon Skidmore .led_on = &ixgbe_led_on_generic, \ 13136a14ee0cSDon Skidmore .led_off = &ixgbe_led_off_generic, \ 13146a14ee0cSDon Skidmore .blink_led_start = &ixgbe_blink_led_start_X540, \ 13156a14ee0cSDon Skidmore .blink_led_stop = &ixgbe_blink_led_stop_X540, \ 13166a14ee0cSDon Skidmore .set_rar = &ixgbe_set_rar_generic, \ 13176a14ee0cSDon Skidmore .clear_rar = &ixgbe_clear_rar_generic, \ 13186a14ee0cSDon Skidmore .set_vmdq = &ixgbe_set_vmdq_generic, \ 13196a14ee0cSDon Skidmore .set_vmdq_san_mac = &ixgbe_set_vmdq_san_mac_generic, \ 13206a14ee0cSDon Skidmore .clear_vmdq = &ixgbe_clear_vmdq_generic, \ 13216a14ee0cSDon Skidmore .init_rx_addrs = &ixgbe_init_rx_addrs_generic, \ 13226a14ee0cSDon Skidmore .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic, \ 13236a14ee0cSDon Skidmore .enable_mc = &ixgbe_enable_mc_generic, \ 13246a14ee0cSDon Skidmore .disable_mc = &ixgbe_disable_mc_generic, \ 13256a14ee0cSDon Skidmore .clear_vfta = &ixgbe_clear_vfta_generic, \ 13266a14ee0cSDon Skidmore .set_vfta = &ixgbe_set_vfta_generic, \ 13276a14ee0cSDon Skidmore .fc_enable = &ixgbe_fc_enable_generic, \ 13286a14ee0cSDon Skidmore .set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic, \ 13296a14ee0cSDon Skidmore .init_uta_tables = &ixgbe_init_uta_tables_generic, \ 13306a14ee0cSDon Skidmore .set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing, \ 13316a14ee0cSDon Skidmore .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing, \ 13326a14ee0cSDon Skidmore .acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X540, \ 13336a14ee0cSDon Skidmore .release_swfw_sync = &ixgbe_release_swfw_sync_X540, \ 13346a14ee0cSDon Skidmore .disable_rx_buff = &ixgbe_disable_rx_buff_generic, \ 13356a14ee0cSDon Skidmore .enable_rx_buff = &ixgbe_enable_rx_buff_generic, \ 13366a14ee0cSDon Skidmore .get_thermal_sensor_data = NULL, \ 13376a14ee0cSDon Skidmore .init_thermal_sensor_thresh = NULL, \ 13386a14ee0cSDon Skidmore .prot_autoc_read = &prot_autoc_read_generic, \ 13396a14ee0cSDon Skidmore .prot_autoc_write = &prot_autoc_write_generic, \ 13406a14ee0cSDon Skidmore 13416a14ee0cSDon Skidmore static struct ixgbe_mac_operations mac_ops_X550 = { 13426a14ee0cSDon Skidmore X550_COMMON_MAC 13436a14ee0cSDon Skidmore .reset_hw = &ixgbe_reset_hw_X540, 13446a14ee0cSDon Skidmore .get_media_type = &ixgbe_get_media_type_X540, 13456a14ee0cSDon Skidmore .get_san_mac_addr = &ixgbe_get_san_mac_addr_generic, 13466a14ee0cSDon Skidmore .get_wwn_prefix = &ixgbe_get_wwn_prefix_generic, 13476a14ee0cSDon Skidmore .setup_link = &ixgbe_setup_mac_link_X540, 13486a14ee0cSDon Skidmore .set_rxpba = &ixgbe_set_rxpba_generic, 13496a14ee0cSDon Skidmore .get_link_capabilities = &ixgbe_get_copper_link_capabilities_generic, 13506a14ee0cSDon Skidmore .setup_sfp = NULL, 13516a14ee0cSDon Skidmore }; 13526a14ee0cSDon Skidmore 13536a14ee0cSDon Skidmore static struct ixgbe_mac_operations mac_ops_X550EM_x = { 13546a14ee0cSDon Skidmore X550_COMMON_MAC 13556a14ee0cSDon Skidmore .reset_hw = &ixgbe_reset_hw_X550em, 13566a14ee0cSDon Skidmore .get_media_type = &ixgbe_get_media_type_X550em, 13576a14ee0cSDon Skidmore .get_san_mac_addr = NULL, 13586a14ee0cSDon Skidmore .get_wwn_prefix = NULL, 13596a14ee0cSDon Skidmore .setup_link = NULL, /* defined later */ 13606a14ee0cSDon Skidmore .get_link_capabilities = &ixgbe_get_link_capabilities_X550em, 13616a14ee0cSDon Skidmore .setup_sfp = ixgbe_setup_sfp_modules_X550em, 13626a14ee0cSDon Skidmore 13636a14ee0cSDon Skidmore }; 13646a14ee0cSDon Skidmore 13656a14ee0cSDon Skidmore #define X550_COMMON_EEP \ 13666a14ee0cSDon Skidmore .read = &ixgbe_read_ee_hostif_X550, \ 13676a14ee0cSDon Skidmore .read_buffer = &ixgbe_read_ee_hostif_buffer_X550, \ 13686a14ee0cSDon Skidmore .write = &ixgbe_write_ee_hostif_X550, \ 13696a14ee0cSDon Skidmore .write_buffer = &ixgbe_write_ee_hostif_buffer_X550, \ 13706a14ee0cSDon Skidmore .validate_checksum = &ixgbe_validate_eeprom_checksum_X550, \ 13716a14ee0cSDon Skidmore .update_checksum = &ixgbe_update_eeprom_checksum_X550, \ 13726a14ee0cSDon Skidmore .calc_checksum = &ixgbe_calc_eeprom_checksum_X550, \ 13736a14ee0cSDon Skidmore 13746a14ee0cSDon Skidmore static struct ixgbe_eeprom_operations eeprom_ops_X550 = { 13756a14ee0cSDon Skidmore X550_COMMON_EEP 13766a14ee0cSDon Skidmore .init_params = &ixgbe_init_eeprom_params_X550, 13776a14ee0cSDon Skidmore }; 13786a14ee0cSDon Skidmore 13796a14ee0cSDon Skidmore static struct ixgbe_eeprom_operations eeprom_ops_X550EM_x = { 13806a14ee0cSDon Skidmore X550_COMMON_EEP 13816a14ee0cSDon Skidmore .init_params = &ixgbe_init_eeprom_params_X540, 13826a14ee0cSDon Skidmore }; 13836a14ee0cSDon Skidmore 13846a14ee0cSDon Skidmore #define X550_COMMON_PHY \ 13856a14ee0cSDon Skidmore .identify_sfp = &ixgbe_identify_module_generic, \ 13866a14ee0cSDon Skidmore .reset = NULL, \ 13876a14ee0cSDon Skidmore .setup_link_speed = &ixgbe_setup_phy_link_speed_generic, \ 13886a14ee0cSDon Skidmore .read_i2c_byte = &ixgbe_read_i2c_byte_generic, \ 13896a14ee0cSDon Skidmore .write_i2c_byte = &ixgbe_write_i2c_byte_generic, \ 13906a14ee0cSDon Skidmore .read_i2c_sff8472 = &ixgbe_read_i2c_sff8472_generic, \ 13916a14ee0cSDon Skidmore .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic, \ 13926a14ee0cSDon Skidmore .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic, \ 13936a14ee0cSDon Skidmore .check_overtemp = &ixgbe_tn_check_overtemp, \ 13946a14ee0cSDon Skidmore .get_firmware_version = &ixgbe_get_phy_firmware_version_generic, 13956a14ee0cSDon Skidmore 13966a14ee0cSDon Skidmore static struct ixgbe_phy_operations phy_ops_X550 = { 13976a14ee0cSDon Skidmore X550_COMMON_PHY 13986a14ee0cSDon Skidmore .init = NULL, 13996a14ee0cSDon Skidmore .identify = &ixgbe_identify_phy_generic, 14006a14ee0cSDon Skidmore .read_reg = &ixgbe_read_phy_reg_generic, 14016a14ee0cSDon Skidmore .write_reg = &ixgbe_write_phy_reg_generic, 14026a14ee0cSDon Skidmore .setup_link = &ixgbe_setup_phy_link_generic, 14036a14ee0cSDon Skidmore .read_i2c_combined = &ixgbe_read_i2c_combined_generic, 14046a14ee0cSDon Skidmore .write_i2c_combined = &ixgbe_write_i2c_combined_generic, 14056a14ee0cSDon Skidmore }; 14066a14ee0cSDon Skidmore 14076a14ee0cSDon Skidmore static struct ixgbe_phy_operations phy_ops_X550EM_x = { 14086a14ee0cSDon Skidmore X550_COMMON_PHY 14096a14ee0cSDon Skidmore .init = &ixgbe_init_phy_ops_X550em, 14106a14ee0cSDon Skidmore .identify = &ixgbe_identify_phy_x550em, 14116a14ee0cSDon Skidmore .read_reg = NULL, /* defined later */ 14126a14ee0cSDon Skidmore .write_reg = NULL, /* defined later */ 14136a14ee0cSDon Skidmore .setup_link = NULL, /* defined later */ 14146a14ee0cSDon Skidmore }; 14156a14ee0cSDon Skidmore 14166a14ee0cSDon Skidmore struct ixgbe_info ixgbe_X550_info = { 14176a14ee0cSDon Skidmore .mac = ixgbe_mac_X550, 14186a14ee0cSDon Skidmore .get_invariants = &ixgbe_get_invariants_X540, 14196a14ee0cSDon Skidmore .mac_ops = &mac_ops_X550, 14206a14ee0cSDon Skidmore .eeprom_ops = &eeprom_ops_X550, 14216a14ee0cSDon Skidmore .phy_ops = &phy_ops_X550, 14226a14ee0cSDon Skidmore .mbx_ops = &mbx_ops_generic, 14236a14ee0cSDon Skidmore }; 14246a14ee0cSDon Skidmore 14256a14ee0cSDon Skidmore struct ixgbe_info ixgbe_X550EM_x_info = { 14266a14ee0cSDon Skidmore .mac = ixgbe_mac_X550EM_x, 14276a14ee0cSDon Skidmore .get_invariants = &ixgbe_get_invariants_X540, 14286a14ee0cSDon Skidmore .mac_ops = &mac_ops_X550EM_x, 14296a14ee0cSDon Skidmore .eeprom_ops = &eeprom_ops_X550EM_x, 14306a14ee0cSDon Skidmore .phy_ops = &phy_ops_X550EM_x, 14316a14ee0cSDon Skidmore .mbx_ops = &mbx_ops_generic, 14326a14ee0cSDon Skidmore }; 1433