19c80d176SSepherosa Ziehau /******************************************************************************
29c80d176SSepherosa Ziehau
3*01a55482SSepherosa Ziehau Copyright (c) 2001-2019, Intel Corporation
49c80d176SSepherosa Ziehau All rights reserved.
59c80d176SSepherosa Ziehau
69c80d176SSepherosa Ziehau Redistribution and use in source and binary forms, with or without
79c80d176SSepherosa Ziehau modification, are permitted provided that the following conditions are met:
89c80d176SSepherosa Ziehau
99c80d176SSepherosa Ziehau 1. Redistributions of source code must retain the above copyright notice,
109c80d176SSepherosa Ziehau this list of conditions and the following disclaimer.
119c80d176SSepherosa Ziehau
129c80d176SSepherosa Ziehau 2. Redistributions in binary form must reproduce the above copyright
139c80d176SSepherosa Ziehau notice, this list of conditions and the following disclaimer in the
149c80d176SSepherosa Ziehau documentation and/or other materials provided with the distribution.
159c80d176SSepherosa Ziehau
169c80d176SSepherosa Ziehau 3. Neither the name of the Intel Corporation nor the names of its
179c80d176SSepherosa Ziehau contributors may be used to endorse or promote products derived from
189c80d176SSepherosa Ziehau this software without specific prior written permission.
199c80d176SSepherosa Ziehau
209c80d176SSepherosa Ziehau THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
219c80d176SSepherosa Ziehau AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
229c80d176SSepherosa Ziehau IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
239c80d176SSepherosa Ziehau ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
249c80d176SSepherosa Ziehau LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
259c80d176SSepherosa Ziehau CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
269c80d176SSepherosa Ziehau SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
279c80d176SSepherosa Ziehau INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
289c80d176SSepherosa Ziehau CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
299c80d176SSepherosa Ziehau ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
309c80d176SSepherosa Ziehau POSSIBILITY OF SUCH DAMAGE.
319c80d176SSepherosa Ziehau
329c80d176SSepherosa Ziehau ******************************************************************************/
3374dc3754SSepherosa Ziehau /*$FreeBSD$*/
349c80d176SSepherosa Ziehau
359c80d176SSepherosa Ziehau #include "e1000_api.h"
369c80d176SSepherosa Ziehau
37379ebbe7SSepherosa Ziehau static s32 e1000_wait_autoneg(struct e1000_hw *hw);
389c80d176SSepherosa Ziehau static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
396d5e2922SSepherosa Ziehau u16 *data, bool read, bool page_set);
406a5a645eSSepherosa Ziehau static u32 e1000_get_phy_addr_for_hv_page(u32 page);
416a5a645eSSepherosa Ziehau static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
426a5a645eSSepherosa Ziehau u16 *data, bool read);
436a5a645eSSepherosa Ziehau
449c80d176SSepherosa Ziehau /* Cable length tables */
456d5e2922SSepherosa Ziehau static const u16 e1000_m88_cable_length_table[] = {
466d5e2922SSepherosa Ziehau 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
479c80d176SSepherosa Ziehau #define M88E1000_CABLE_LENGTH_TABLE_SIZE \
489c80d176SSepherosa Ziehau (sizeof(e1000_m88_cable_length_table) / \
499c80d176SSepherosa Ziehau sizeof(e1000_m88_cable_length_table[0]))
509c80d176SSepherosa Ziehau
516d5e2922SSepherosa Ziehau static const u16 e1000_igp_2_cable_length_table[] = {
526d5e2922SSepherosa Ziehau 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 0, 0, 0, 3,
536d5e2922SSepherosa Ziehau 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41, 6, 10, 14, 18, 22,
546d5e2922SSepherosa Ziehau 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61, 21, 26, 31, 35, 40,
556d5e2922SSepherosa Ziehau 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82, 40, 45, 51, 56, 61,
566d5e2922SSepherosa Ziehau 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104, 60, 66, 72, 77, 82,
576d5e2922SSepherosa Ziehau 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121, 83, 89, 95,
586d5e2922SSepherosa Ziehau 100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121,
596d5e2922SSepherosa Ziehau 124};
609c80d176SSepherosa Ziehau #define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
619c80d176SSepherosa Ziehau (sizeof(e1000_igp_2_cable_length_table) / \
629c80d176SSepherosa Ziehau sizeof(e1000_igp_2_cable_length_table[0]))
639c80d176SSepherosa Ziehau
649c80d176SSepherosa Ziehau /**
659c80d176SSepherosa Ziehau * e1000_init_phy_ops_generic - Initialize PHY function pointers
669c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
679c80d176SSepherosa Ziehau *
689c80d176SSepherosa Ziehau * Setups up the function pointers to no-op functions
699c80d176SSepherosa Ziehau **/
e1000_init_phy_ops_generic(struct e1000_hw * hw)709c80d176SSepherosa Ziehau void e1000_init_phy_ops_generic(struct e1000_hw *hw)
719c80d176SSepherosa Ziehau {
729c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
739c80d176SSepherosa Ziehau DEBUGFUNC("e1000_init_phy_ops_generic");
749c80d176SSepherosa Ziehau
759c80d176SSepherosa Ziehau /* Initialize function pointers */
769c80d176SSepherosa Ziehau phy->ops.init_params = e1000_null_ops_generic;
779c80d176SSepherosa Ziehau phy->ops.acquire = e1000_null_ops_generic;
789c80d176SSepherosa Ziehau phy->ops.check_polarity = e1000_null_ops_generic;
799c80d176SSepherosa Ziehau phy->ops.check_reset_block = e1000_null_ops_generic;
809c80d176SSepherosa Ziehau phy->ops.commit = e1000_null_ops_generic;
819c80d176SSepherosa Ziehau phy->ops.force_speed_duplex = e1000_null_ops_generic;
829c80d176SSepherosa Ziehau phy->ops.get_cfg_done = e1000_null_ops_generic;
839c80d176SSepherosa Ziehau phy->ops.get_cable_length = e1000_null_ops_generic;
849c80d176SSepherosa Ziehau phy->ops.get_info = e1000_null_ops_generic;
856d5e2922SSepherosa Ziehau phy->ops.set_page = e1000_null_set_page;
869c80d176SSepherosa Ziehau phy->ops.read_reg = e1000_null_read_reg;
876a5a645eSSepherosa Ziehau phy->ops.read_reg_locked = e1000_null_read_reg;
886d5e2922SSepherosa Ziehau phy->ops.read_reg_page = e1000_null_read_reg;
899c80d176SSepherosa Ziehau phy->ops.release = e1000_null_phy_generic;
909c80d176SSepherosa Ziehau phy->ops.reset = e1000_null_ops_generic;
919c80d176SSepherosa Ziehau phy->ops.set_d0_lplu_state = e1000_null_lplu_state;
929c80d176SSepherosa Ziehau phy->ops.set_d3_lplu_state = e1000_null_lplu_state;
939c80d176SSepherosa Ziehau phy->ops.write_reg = e1000_null_write_reg;
946a5a645eSSepherosa Ziehau phy->ops.write_reg_locked = e1000_null_write_reg;
956d5e2922SSepherosa Ziehau phy->ops.write_reg_page = e1000_null_write_reg;
969c80d176SSepherosa Ziehau phy->ops.power_up = e1000_null_phy_generic;
979c80d176SSepherosa Ziehau phy->ops.power_down = e1000_null_phy_generic;
989c80d176SSepherosa Ziehau phy->ops.cfg_on_link_up = e1000_null_ops_generic;
994be59a01SSepherosa Ziehau phy->ops.read_i2c_byte = e1000_read_i2c_byte_null;
1004be59a01SSepherosa Ziehau phy->ops.write_i2c_byte = e1000_write_i2c_byte_null;
1019c80d176SSepherosa Ziehau }
1029c80d176SSepherosa Ziehau
1039c80d176SSepherosa Ziehau /**
1046d5e2922SSepherosa Ziehau * e1000_null_set_page - No-op function, return 0
1056d5e2922SSepherosa Ziehau * @hw: pointer to the HW structure
106*01a55482SSepherosa Ziehau * @data: dummy variable
1076d5e2922SSepherosa Ziehau **/
e1000_null_set_page(struct e1000_hw E1000_UNUSEDARG * hw,u16 E1000_UNUSEDARG data)108379ebbe7SSepherosa Ziehau s32 e1000_null_set_page(struct e1000_hw E1000_UNUSEDARG *hw,
109379ebbe7SSepherosa Ziehau u16 E1000_UNUSEDARG data)
1106d5e2922SSepherosa Ziehau {
1116d5e2922SSepherosa Ziehau DEBUGFUNC("e1000_null_set_page");
1126d5e2922SSepherosa Ziehau return E1000_SUCCESS;
1136d5e2922SSepherosa Ziehau }
1146d5e2922SSepherosa Ziehau
1156d5e2922SSepherosa Ziehau /**
1169c80d176SSepherosa Ziehau * e1000_null_read_reg - No-op function, return 0
1179c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
118*01a55482SSepherosa Ziehau * @offset: dummy variable
119*01a55482SSepherosa Ziehau * @data: dummy variable
1209c80d176SSepherosa Ziehau **/
e1000_null_read_reg(struct e1000_hw E1000_UNUSEDARG * hw,u32 E1000_UNUSEDARG offset,u16 E1000_UNUSEDARG * data)121379ebbe7SSepherosa Ziehau s32 e1000_null_read_reg(struct e1000_hw E1000_UNUSEDARG *hw,
122379ebbe7SSepherosa Ziehau u32 E1000_UNUSEDARG offset, u16 E1000_UNUSEDARG *data)
1239c80d176SSepherosa Ziehau {
1249c80d176SSepherosa Ziehau DEBUGFUNC("e1000_null_read_reg");
1259c80d176SSepherosa Ziehau return E1000_SUCCESS;
1269c80d176SSepherosa Ziehau }
1279c80d176SSepherosa Ziehau
1289c80d176SSepherosa Ziehau /**
1299c80d176SSepherosa Ziehau * e1000_null_phy_generic - No-op function, return void
1309c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
1319c80d176SSepherosa Ziehau **/
e1000_null_phy_generic(struct e1000_hw E1000_UNUSEDARG * hw)132379ebbe7SSepherosa Ziehau void e1000_null_phy_generic(struct e1000_hw E1000_UNUSEDARG *hw)
1339c80d176SSepherosa Ziehau {
1349c80d176SSepherosa Ziehau DEBUGFUNC("e1000_null_phy_generic");
1359c80d176SSepherosa Ziehau return;
1369c80d176SSepherosa Ziehau }
1379c80d176SSepherosa Ziehau
1389c80d176SSepherosa Ziehau /**
1399c80d176SSepherosa Ziehau * e1000_null_lplu_state - No-op function, return 0
1409c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
141*01a55482SSepherosa Ziehau * @active: dummy variable
1429c80d176SSepherosa Ziehau **/
e1000_null_lplu_state(struct e1000_hw E1000_UNUSEDARG * hw,bool E1000_UNUSEDARG active)143379ebbe7SSepherosa Ziehau s32 e1000_null_lplu_state(struct e1000_hw E1000_UNUSEDARG *hw,
144379ebbe7SSepherosa Ziehau bool E1000_UNUSEDARG active)
1459c80d176SSepherosa Ziehau {
1469c80d176SSepherosa Ziehau DEBUGFUNC("e1000_null_lplu_state");
1479c80d176SSepherosa Ziehau return E1000_SUCCESS;
1489c80d176SSepherosa Ziehau }
1499c80d176SSepherosa Ziehau
1509c80d176SSepherosa Ziehau /**
1519c80d176SSepherosa Ziehau * e1000_null_write_reg - No-op function, return 0
1529c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
153*01a55482SSepherosa Ziehau * @offset: dummy variable
154*01a55482SSepherosa Ziehau * @data: dummy variable
1559c80d176SSepherosa Ziehau **/
e1000_null_write_reg(struct e1000_hw E1000_UNUSEDARG * hw,u32 E1000_UNUSEDARG offset,u16 E1000_UNUSEDARG data)156379ebbe7SSepherosa Ziehau s32 e1000_null_write_reg(struct e1000_hw E1000_UNUSEDARG *hw,
157379ebbe7SSepherosa Ziehau u32 E1000_UNUSEDARG offset, u16 E1000_UNUSEDARG data)
1589c80d176SSepherosa Ziehau {
1599c80d176SSepherosa Ziehau DEBUGFUNC("e1000_null_write_reg");
1609c80d176SSepherosa Ziehau return E1000_SUCCESS;
1619c80d176SSepherosa Ziehau }
1629c80d176SSepherosa Ziehau
1639c80d176SSepherosa Ziehau /**
1644be59a01SSepherosa Ziehau * e1000_read_i2c_byte_null - No-op function, return 0
1654be59a01SSepherosa Ziehau * @hw: pointer to hardware structure
1664be59a01SSepherosa Ziehau * @byte_offset: byte offset to write
1674be59a01SSepherosa Ziehau * @dev_addr: device address
1684be59a01SSepherosa Ziehau * @data: data value read
1694be59a01SSepherosa Ziehau *
1704be59a01SSepherosa Ziehau **/
e1000_read_i2c_byte_null(struct e1000_hw E1000_UNUSEDARG * hw,u8 E1000_UNUSEDARG byte_offset,u8 E1000_UNUSEDARG dev_addr,u8 E1000_UNUSEDARG * data)171379ebbe7SSepherosa Ziehau s32 e1000_read_i2c_byte_null(struct e1000_hw E1000_UNUSEDARG *hw,
172379ebbe7SSepherosa Ziehau u8 E1000_UNUSEDARG byte_offset,
173379ebbe7SSepherosa Ziehau u8 E1000_UNUSEDARG dev_addr,
174379ebbe7SSepherosa Ziehau u8 E1000_UNUSEDARG *data)
1754be59a01SSepherosa Ziehau {
1764be59a01SSepherosa Ziehau DEBUGFUNC("e1000_read_i2c_byte_null");
1774be59a01SSepherosa Ziehau return E1000_SUCCESS;
1784be59a01SSepherosa Ziehau }
1794be59a01SSepherosa Ziehau
1804be59a01SSepherosa Ziehau /**
1814be59a01SSepherosa Ziehau * e1000_write_i2c_byte_null - No-op function, return 0
1824be59a01SSepherosa Ziehau * @hw: pointer to hardware structure
1834be59a01SSepherosa Ziehau * @byte_offset: byte offset to write
1844be59a01SSepherosa Ziehau * @dev_addr: device address
1854be59a01SSepherosa Ziehau * @data: data value to write
1864be59a01SSepherosa Ziehau *
1874be59a01SSepherosa Ziehau **/
e1000_write_i2c_byte_null(struct e1000_hw E1000_UNUSEDARG * hw,u8 E1000_UNUSEDARG byte_offset,u8 E1000_UNUSEDARG dev_addr,u8 E1000_UNUSEDARG data)188379ebbe7SSepherosa Ziehau s32 e1000_write_i2c_byte_null(struct e1000_hw E1000_UNUSEDARG *hw,
189379ebbe7SSepherosa Ziehau u8 E1000_UNUSEDARG byte_offset,
190379ebbe7SSepherosa Ziehau u8 E1000_UNUSEDARG dev_addr,
191379ebbe7SSepherosa Ziehau u8 E1000_UNUSEDARG data)
1924be59a01SSepherosa Ziehau {
1934be59a01SSepherosa Ziehau DEBUGFUNC("e1000_write_i2c_byte_null");
1944be59a01SSepherosa Ziehau return E1000_SUCCESS;
1954be59a01SSepherosa Ziehau }
1964be59a01SSepherosa Ziehau
1974be59a01SSepherosa Ziehau /**
1989c80d176SSepherosa Ziehau * e1000_check_reset_block_generic - Check if PHY reset is blocked
1999c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
2009c80d176SSepherosa Ziehau *
2019c80d176SSepherosa Ziehau * Read the PHY management control register and check whether a PHY reset
2029c80d176SSepherosa Ziehau * is blocked. If a reset is not blocked return E1000_SUCCESS, otherwise
2039c80d176SSepherosa Ziehau * return E1000_BLK_PHY_RESET (12).
2049c80d176SSepherosa Ziehau **/
e1000_check_reset_block_generic(struct e1000_hw * hw)2059c80d176SSepherosa Ziehau s32 e1000_check_reset_block_generic(struct e1000_hw *hw)
2069c80d176SSepherosa Ziehau {
2079c80d176SSepherosa Ziehau u32 manc;
2089c80d176SSepherosa Ziehau
2099c80d176SSepherosa Ziehau DEBUGFUNC("e1000_check_reset_block");
2109c80d176SSepherosa Ziehau
2119c80d176SSepherosa Ziehau manc = E1000_READ_REG(hw, E1000_MANC);
2129c80d176SSepherosa Ziehau
2139c80d176SSepherosa Ziehau return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
2149c80d176SSepherosa Ziehau E1000_BLK_PHY_RESET : E1000_SUCCESS;
2159c80d176SSepherosa Ziehau }
2169c80d176SSepherosa Ziehau
2179c80d176SSepherosa Ziehau /**
2189c80d176SSepherosa Ziehau * e1000_get_phy_id - Retrieve the PHY ID and revision
2199c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
2209c80d176SSepherosa Ziehau *
2219c80d176SSepherosa Ziehau * Reads the PHY registers and stores the PHY ID and possibly the PHY
2229c80d176SSepherosa Ziehau * revision in the hardware structure.
2239c80d176SSepherosa Ziehau **/
e1000_get_phy_id(struct e1000_hw * hw)2249c80d176SSepherosa Ziehau s32 e1000_get_phy_id(struct e1000_hw *hw)
2259c80d176SSepherosa Ziehau {
2269c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
2279c80d176SSepherosa Ziehau s32 ret_val = E1000_SUCCESS;
2289c80d176SSepherosa Ziehau u16 phy_id;
2296a5a645eSSepherosa Ziehau u16 retry_count = 0;
2309c80d176SSepherosa Ziehau
2319c80d176SSepherosa Ziehau DEBUGFUNC("e1000_get_phy_id");
2329c80d176SSepherosa Ziehau
2334be59a01SSepherosa Ziehau if (!phy->ops.read_reg)
2344be59a01SSepherosa Ziehau return E1000_SUCCESS;
2359c80d176SSepherosa Ziehau
2366a5a645eSSepherosa Ziehau while (retry_count < 2) {
2379c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
2389c80d176SSepherosa Ziehau if (ret_val)
2394be59a01SSepherosa Ziehau return ret_val;
2409c80d176SSepherosa Ziehau
2419c80d176SSepherosa Ziehau phy->id = (u32)(phy_id << 16);
2429c80d176SSepherosa Ziehau usec_delay(20);
2439c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
2449c80d176SSepherosa Ziehau if (ret_val)
2454be59a01SSepherosa Ziehau return ret_val;
2469c80d176SSepherosa Ziehau
2479c80d176SSepherosa Ziehau phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
2489c80d176SSepherosa Ziehau phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
2499c80d176SSepherosa Ziehau
2506a5a645eSSepherosa Ziehau if (phy->id != 0 && phy->id != PHY_REVISION_MASK)
2514be59a01SSepherosa Ziehau return E1000_SUCCESS;
2526a5a645eSSepherosa Ziehau
2536a5a645eSSepherosa Ziehau retry_count++;
2546a5a645eSSepherosa Ziehau }
2554be59a01SSepherosa Ziehau
2564be59a01SSepherosa Ziehau return E1000_SUCCESS;
2579c80d176SSepherosa Ziehau }
2589c80d176SSepherosa Ziehau
2599c80d176SSepherosa Ziehau /**
2609c80d176SSepherosa Ziehau * e1000_phy_reset_dsp_generic - Reset PHY DSP
2619c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
2629c80d176SSepherosa Ziehau *
2639c80d176SSepherosa Ziehau * Reset the digital signal processor.
2649c80d176SSepherosa Ziehau **/
e1000_phy_reset_dsp_generic(struct e1000_hw * hw)2659c80d176SSepherosa Ziehau s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw)
2669c80d176SSepherosa Ziehau {
2674be59a01SSepherosa Ziehau s32 ret_val;
2689c80d176SSepherosa Ziehau
2699c80d176SSepherosa Ziehau DEBUGFUNC("e1000_phy_reset_dsp_generic");
2709c80d176SSepherosa Ziehau
2714be59a01SSepherosa Ziehau if (!hw->phy.ops.write_reg)
2724be59a01SSepherosa Ziehau return E1000_SUCCESS;
2739c80d176SSepherosa Ziehau
2749c80d176SSepherosa Ziehau ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
2759c80d176SSepherosa Ziehau if (ret_val)
2769c80d176SSepherosa Ziehau return ret_val;
2774be59a01SSepherosa Ziehau
2784be59a01SSepherosa Ziehau return hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0);
2799c80d176SSepherosa Ziehau }
2809c80d176SSepherosa Ziehau
2819c80d176SSepherosa Ziehau /**
2829c80d176SSepherosa Ziehau * e1000_read_phy_reg_mdic - Read MDI control register
2839c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
2849c80d176SSepherosa Ziehau * @offset: register offset to be read
2859c80d176SSepherosa Ziehau * @data: pointer to the read data
2869c80d176SSepherosa Ziehau *
2879c80d176SSepherosa Ziehau * Reads the MDI control register in the PHY at offset and stores the
2889c80d176SSepherosa Ziehau * information read to data.
2899c80d176SSepherosa Ziehau **/
e1000_read_phy_reg_mdic(struct e1000_hw * hw,u32 offset,u16 * data)2909c80d176SSepherosa Ziehau s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
2919c80d176SSepherosa Ziehau {
2929c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
2939c80d176SSepherosa Ziehau u32 i, mdic = 0;
2949c80d176SSepherosa Ziehau
2959c80d176SSepherosa Ziehau DEBUGFUNC("e1000_read_phy_reg_mdic");
2969c80d176SSepherosa Ziehau
2976a5a645eSSepherosa Ziehau if (offset > MAX_PHY_REG_ADDRESS) {
2986a5a645eSSepherosa Ziehau DEBUGOUT1("PHY Address %d is out of range\n", offset);
2996a5a645eSSepherosa Ziehau return -E1000_ERR_PARAM;
3006a5a645eSSepherosa Ziehau }
3016a5a645eSSepherosa Ziehau
302379ebbe7SSepherosa Ziehau /* Set up Op-code, Phy Address, and register offset in the MDI
3039c80d176SSepherosa Ziehau * Control register. The MAC will take care of interfacing with the
3049c80d176SSepherosa Ziehau * PHY to retrieve the desired data.
3059c80d176SSepherosa Ziehau */
3069c80d176SSepherosa Ziehau mdic = ((offset << E1000_MDIC_REG_SHIFT) |
3079c80d176SSepherosa Ziehau (phy->addr << E1000_MDIC_PHY_SHIFT) |
3089c80d176SSepherosa Ziehau (E1000_MDIC_OP_READ));
3099c80d176SSepherosa Ziehau
3109c80d176SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_MDIC, mdic);
3119c80d176SSepherosa Ziehau
312379ebbe7SSepherosa Ziehau /* Poll the ready bit to see if the MDI read completed
3139c80d176SSepherosa Ziehau * Increasing the time out as testing showed failures with
3149c80d176SSepherosa Ziehau * the lower time out
3159c80d176SSepherosa Ziehau */
3169c80d176SSepherosa Ziehau for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
3174765c386SMichael Neumann usec_delay_irq(50);
3189c80d176SSepherosa Ziehau mdic = E1000_READ_REG(hw, E1000_MDIC);
3199c80d176SSepherosa Ziehau if (mdic & E1000_MDIC_READY)
3209c80d176SSepherosa Ziehau break;
3219c80d176SSepherosa Ziehau }
3229c80d176SSepherosa Ziehau if (!(mdic & E1000_MDIC_READY)) {
3239c80d176SSepherosa Ziehau DEBUGOUT("MDI Read did not complete\n");
3244be59a01SSepherosa Ziehau return -E1000_ERR_PHY;
3259c80d176SSepherosa Ziehau }
3269c80d176SSepherosa Ziehau if (mdic & E1000_MDIC_ERROR) {
3279c80d176SSepherosa Ziehau DEBUGOUT("MDI Error\n");
3284be59a01SSepherosa Ziehau return -E1000_ERR_PHY;
3299c80d176SSepherosa Ziehau }
330379ebbe7SSepherosa Ziehau if (((mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT) != offset) {
331379ebbe7SSepherosa Ziehau DEBUGOUT2("MDI Read offset error - requested %d, returned %d\n",
332379ebbe7SSepherosa Ziehau offset,
333379ebbe7SSepherosa Ziehau (mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT);
334379ebbe7SSepherosa Ziehau return -E1000_ERR_PHY;
335379ebbe7SSepherosa Ziehau }
3369c80d176SSepherosa Ziehau *data = (u16) mdic;
3379c80d176SSepherosa Ziehau
338379ebbe7SSepherosa Ziehau /* Allow some time after each MDIC transaction to avoid
3396a5a645eSSepherosa Ziehau * reading duplicate data in the next MDIC transaction.
3406a5a645eSSepherosa Ziehau */
3416a5a645eSSepherosa Ziehau if (hw->mac.type == e1000_pch2lan)
3424765c386SMichael Neumann usec_delay_irq(100);
3436a5a645eSSepherosa Ziehau
3444be59a01SSepherosa Ziehau return E1000_SUCCESS;
3459c80d176SSepherosa Ziehau }
3469c80d176SSepherosa Ziehau
3479c80d176SSepherosa Ziehau /**
3489c80d176SSepherosa Ziehau * e1000_write_phy_reg_mdic - Write MDI control register
3499c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
3509c80d176SSepherosa Ziehau * @offset: register offset to write to
3519c80d176SSepherosa Ziehau * @data: data to write to register at offset
3529c80d176SSepherosa Ziehau *
3539c80d176SSepherosa Ziehau * Writes data to MDI control register in the PHY at offset.
3549c80d176SSepherosa Ziehau **/
e1000_write_phy_reg_mdic(struct e1000_hw * hw,u32 offset,u16 data)3559c80d176SSepherosa Ziehau s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
3569c80d176SSepherosa Ziehau {
3579c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
3589c80d176SSepherosa Ziehau u32 i, mdic = 0;
3599c80d176SSepherosa Ziehau
3609c80d176SSepherosa Ziehau DEBUGFUNC("e1000_write_phy_reg_mdic");
3619c80d176SSepherosa Ziehau
3626a5a645eSSepherosa Ziehau if (offset > MAX_PHY_REG_ADDRESS) {
3636a5a645eSSepherosa Ziehau DEBUGOUT1("PHY Address %d is out of range\n", offset);
3646a5a645eSSepherosa Ziehau return -E1000_ERR_PARAM;
3656a5a645eSSepherosa Ziehau }
3666a5a645eSSepherosa Ziehau
367379ebbe7SSepherosa Ziehau /* Set up Op-code, Phy Address, and register offset in the MDI
3689c80d176SSepherosa Ziehau * Control register. The MAC will take care of interfacing with the
3699c80d176SSepherosa Ziehau * PHY to retrieve the desired data.
3709c80d176SSepherosa Ziehau */
3719c80d176SSepherosa Ziehau mdic = (((u32)data) |
3729c80d176SSepherosa Ziehau (offset << E1000_MDIC_REG_SHIFT) |
3739c80d176SSepherosa Ziehau (phy->addr << E1000_MDIC_PHY_SHIFT) |
3749c80d176SSepherosa Ziehau (E1000_MDIC_OP_WRITE));
3759c80d176SSepherosa Ziehau
3769c80d176SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_MDIC, mdic);
3779c80d176SSepherosa Ziehau
378379ebbe7SSepherosa Ziehau /* Poll the ready bit to see if the MDI read completed
3799c80d176SSepherosa Ziehau * Increasing the time out as testing showed failures with
3809c80d176SSepherosa Ziehau * the lower time out
3819c80d176SSepherosa Ziehau */
3829c80d176SSepherosa Ziehau for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
3834765c386SMichael Neumann usec_delay_irq(50);
3849c80d176SSepherosa Ziehau mdic = E1000_READ_REG(hw, E1000_MDIC);
3859c80d176SSepherosa Ziehau if (mdic & E1000_MDIC_READY)
3869c80d176SSepherosa Ziehau break;
3879c80d176SSepherosa Ziehau }
3889c80d176SSepherosa Ziehau if (!(mdic & E1000_MDIC_READY)) {
3899c80d176SSepherosa Ziehau DEBUGOUT("MDI Write did not complete\n");
3904be59a01SSepherosa Ziehau return -E1000_ERR_PHY;
3919c80d176SSepherosa Ziehau }
3929c80d176SSepherosa Ziehau if (mdic & E1000_MDIC_ERROR) {
3939c80d176SSepherosa Ziehau DEBUGOUT("MDI Error\n");
3944be59a01SSepherosa Ziehau return -E1000_ERR_PHY;
3959c80d176SSepherosa Ziehau }
396379ebbe7SSepherosa Ziehau if (((mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT) != offset) {
397379ebbe7SSepherosa Ziehau DEBUGOUT2("MDI Write offset error - requested %d, returned %d\n",
398379ebbe7SSepherosa Ziehau offset,
399379ebbe7SSepherosa Ziehau (mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT);
400379ebbe7SSepherosa Ziehau return -E1000_ERR_PHY;
401379ebbe7SSepherosa Ziehau }
4029c80d176SSepherosa Ziehau
403379ebbe7SSepherosa Ziehau /* Allow some time after each MDIC transaction to avoid
4046a5a645eSSepherosa Ziehau * reading duplicate data in the next MDIC transaction.
4056a5a645eSSepherosa Ziehau */
4066a5a645eSSepherosa Ziehau if (hw->mac.type == e1000_pch2lan)
4074765c386SMichael Neumann usec_delay_irq(100);
4086a5a645eSSepherosa Ziehau
4094be59a01SSepherosa Ziehau return E1000_SUCCESS;
4109c80d176SSepherosa Ziehau }
4119c80d176SSepherosa Ziehau
4129c80d176SSepherosa Ziehau /**
41362583d18SSepherosa Ziehau * e1000_read_phy_reg_i2c - Read PHY register using i2c
41462583d18SSepherosa Ziehau * @hw: pointer to the HW structure
41562583d18SSepherosa Ziehau * @offset: register offset to be read
41662583d18SSepherosa Ziehau * @data: pointer to the read data
41762583d18SSepherosa Ziehau *
41862583d18SSepherosa Ziehau * Reads the PHY register at offset using the i2c interface and stores the
41962583d18SSepherosa Ziehau * retrieved information in data.
42062583d18SSepherosa Ziehau **/
e1000_read_phy_reg_i2c(struct e1000_hw * hw,u32 offset,u16 * data)42162583d18SSepherosa Ziehau s32 e1000_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data)
42262583d18SSepherosa Ziehau {
42362583d18SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
42462583d18SSepherosa Ziehau u32 i, i2ccmd = 0;
42562583d18SSepherosa Ziehau
42662583d18SSepherosa Ziehau DEBUGFUNC("e1000_read_phy_reg_i2c");
42762583d18SSepherosa Ziehau
428379ebbe7SSepherosa Ziehau /* Set up Op-code, Phy Address, and register address in the I2CCMD
42962583d18SSepherosa Ziehau * register. The MAC will take care of interfacing with the
43062583d18SSepherosa Ziehau * PHY to retrieve the desired data.
43162583d18SSepherosa Ziehau */
43262583d18SSepherosa Ziehau i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
43362583d18SSepherosa Ziehau (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
43462583d18SSepherosa Ziehau (E1000_I2CCMD_OPCODE_READ));
43562583d18SSepherosa Ziehau
43662583d18SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd);
43762583d18SSepherosa Ziehau
43862583d18SSepherosa Ziehau /* Poll the ready bit to see if the I2C read completed */
43962583d18SSepherosa Ziehau for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
44062583d18SSepherosa Ziehau usec_delay(50);
44162583d18SSepherosa Ziehau i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD);
44262583d18SSepherosa Ziehau if (i2ccmd & E1000_I2CCMD_READY)
44362583d18SSepherosa Ziehau break;
44462583d18SSepherosa Ziehau }
44562583d18SSepherosa Ziehau if (!(i2ccmd & E1000_I2CCMD_READY)) {
44662583d18SSepherosa Ziehau DEBUGOUT("I2CCMD Read did not complete\n");
44762583d18SSepherosa Ziehau return -E1000_ERR_PHY;
44862583d18SSepherosa Ziehau }
44962583d18SSepherosa Ziehau if (i2ccmd & E1000_I2CCMD_ERROR) {
45062583d18SSepherosa Ziehau DEBUGOUT("I2CCMD Error bit set\n");
45162583d18SSepherosa Ziehau return -E1000_ERR_PHY;
45262583d18SSepherosa Ziehau }
45362583d18SSepherosa Ziehau
45462583d18SSepherosa Ziehau /* Need to byte-swap the 16-bit value. */
45562583d18SSepherosa Ziehau *data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00);
45662583d18SSepherosa Ziehau
45762583d18SSepherosa Ziehau return E1000_SUCCESS;
45862583d18SSepherosa Ziehau }
45962583d18SSepherosa Ziehau
46062583d18SSepherosa Ziehau /**
46162583d18SSepherosa Ziehau * e1000_write_phy_reg_i2c - Write PHY register using i2c
46262583d18SSepherosa Ziehau * @hw: pointer to the HW structure
46362583d18SSepherosa Ziehau * @offset: register offset to write to
46462583d18SSepherosa Ziehau * @data: data to write at register offset
46562583d18SSepherosa Ziehau *
46662583d18SSepherosa Ziehau * Writes the data to PHY register at the offset using the i2c interface.
46762583d18SSepherosa Ziehau **/
e1000_write_phy_reg_i2c(struct e1000_hw * hw,u32 offset,u16 data)46862583d18SSepherosa Ziehau s32 e1000_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data)
46962583d18SSepherosa Ziehau {
47062583d18SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
47162583d18SSepherosa Ziehau u32 i, i2ccmd = 0;
47262583d18SSepherosa Ziehau u16 phy_data_swapped;
47362583d18SSepherosa Ziehau
47462583d18SSepherosa Ziehau DEBUGFUNC("e1000_write_phy_reg_i2c");
47562583d18SSepherosa Ziehau
4764be59a01SSepherosa Ziehau /* Prevent overwritting SFP I2C EEPROM which is at A0 address.*/
4774be59a01SSepherosa Ziehau if ((hw->phy.addr == 0) || (hw->phy.addr > 7)) {
4784be59a01SSepherosa Ziehau DEBUGOUT1("PHY I2C Address %d is out of range.\n",
4794be59a01SSepherosa Ziehau hw->phy.addr);
4804be59a01SSepherosa Ziehau return -E1000_ERR_CONFIG;
4814be59a01SSepherosa Ziehau }
4824be59a01SSepherosa Ziehau
48362583d18SSepherosa Ziehau /* Swap the data bytes for the I2C interface */
48462583d18SSepherosa Ziehau phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00);
48562583d18SSepherosa Ziehau
486379ebbe7SSepherosa Ziehau /* Set up Op-code, Phy Address, and register address in the I2CCMD
48762583d18SSepherosa Ziehau * register. The MAC will take care of interfacing with the
48862583d18SSepherosa Ziehau * PHY to retrieve the desired data.
48962583d18SSepherosa Ziehau */
49062583d18SSepherosa Ziehau i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
49162583d18SSepherosa Ziehau (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
49262583d18SSepherosa Ziehau E1000_I2CCMD_OPCODE_WRITE |
49362583d18SSepherosa Ziehau phy_data_swapped);
49462583d18SSepherosa Ziehau
49562583d18SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd);
49662583d18SSepherosa Ziehau
49762583d18SSepherosa Ziehau /* Poll the ready bit to see if the I2C read completed */
49862583d18SSepherosa Ziehau for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
49962583d18SSepherosa Ziehau usec_delay(50);
50062583d18SSepherosa Ziehau i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD);
50162583d18SSepherosa Ziehau if (i2ccmd & E1000_I2CCMD_READY)
50262583d18SSepherosa Ziehau break;
50362583d18SSepherosa Ziehau }
50462583d18SSepherosa Ziehau if (!(i2ccmd & E1000_I2CCMD_READY)) {
50562583d18SSepherosa Ziehau DEBUGOUT("I2CCMD Write did not complete\n");
50662583d18SSepherosa Ziehau return -E1000_ERR_PHY;
50762583d18SSepherosa Ziehau }
50862583d18SSepherosa Ziehau if (i2ccmd & E1000_I2CCMD_ERROR) {
50962583d18SSepherosa Ziehau DEBUGOUT("I2CCMD Error bit set\n");
51062583d18SSepherosa Ziehau return -E1000_ERR_PHY;
51162583d18SSepherosa Ziehau }
51262583d18SSepherosa Ziehau
51362583d18SSepherosa Ziehau return E1000_SUCCESS;
51462583d18SSepherosa Ziehau }
51562583d18SSepherosa Ziehau
51662583d18SSepherosa Ziehau /**
5174be59a01SSepherosa Ziehau * e1000_read_sfp_data_byte - Reads SFP module data.
5184be59a01SSepherosa Ziehau * @hw: pointer to the HW structure
5194be59a01SSepherosa Ziehau * @offset: byte location offset to be read
5204be59a01SSepherosa Ziehau * @data: read data buffer pointer
5214be59a01SSepherosa Ziehau *
5224be59a01SSepherosa Ziehau * Reads one byte from SFP module data stored
5234be59a01SSepherosa Ziehau * in SFP resided EEPROM memory or SFP diagnostic area.
5244be59a01SSepherosa Ziehau * Function should be called with
5254be59a01SSepherosa Ziehau * E1000_I2CCMD_SFP_DATA_ADDR(<byte offset>) for SFP module database access
5264be59a01SSepherosa Ziehau * E1000_I2CCMD_SFP_DIAG_ADDR(<byte offset>) for SFP diagnostics parameters
5274be59a01SSepherosa Ziehau * access
5284be59a01SSepherosa Ziehau **/
e1000_read_sfp_data_byte(struct e1000_hw * hw,u16 offset,u8 * data)5294be59a01SSepherosa Ziehau s32 e1000_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data)
5304be59a01SSepherosa Ziehau {
5314be59a01SSepherosa Ziehau u32 i = 0;
5324be59a01SSepherosa Ziehau u32 i2ccmd = 0;
5334be59a01SSepherosa Ziehau u32 data_local = 0;
5344be59a01SSepherosa Ziehau
5354be59a01SSepherosa Ziehau DEBUGFUNC("e1000_read_sfp_data_byte");
5364be59a01SSepherosa Ziehau
5374be59a01SSepherosa Ziehau if (offset > E1000_I2CCMD_SFP_DIAG_ADDR(255)) {
5384be59a01SSepherosa Ziehau DEBUGOUT("I2CCMD command address exceeds upper limit\n");
5394be59a01SSepherosa Ziehau return -E1000_ERR_PHY;
5404be59a01SSepherosa Ziehau }
5414be59a01SSepherosa Ziehau
542379ebbe7SSepherosa Ziehau /* Set up Op-code, EEPROM Address,in the I2CCMD
5434be59a01SSepherosa Ziehau * register. The MAC will take care of interfacing with the
5444be59a01SSepherosa Ziehau * EEPROM to retrieve the desired data.
5454be59a01SSepherosa Ziehau */
5464be59a01SSepherosa Ziehau i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
5474be59a01SSepherosa Ziehau E1000_I2CCMD_OPCODE_READ);
5484be59a01SSepherosa Ziehau
5494be59a01SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd);
5504be59a01SSepherosa Ziehau
5514be59a01SSepherosa Ziehau /* Poll the ready bit to see if the I2C read completed */
5524be59a01SSepherosa Ziehau for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
5534be59a01SSepherosa Ziehau usec_delay(50);
5544be59a01SSepherosa Ziehau data_local = E1000_READ_REG(hw, E1000_I2CCMD);
5554be59a01SSepherosa Ziehau if (data_local & E1000_I2CCMD_READY)
5564be59a01SSepherosa Ziehau break;
5574be59a01SSepherosa Ziehau }
5584be59a01SSepherosa Ziehau if (!(data_local & E1000_I2CCMD_READY)) {
5594be59a01SSepherosa Ziehau DEBUGOUT("I2CCMD Read did not complete\n");
5604be59a01SSepherosa Ziehau return -E1000_ERR_PHY;
5614be59a01SSepherosa Ziehau }
5624be59a01SSepherosa Ziehau if (data_local & E1000_I2CCMD_ERROR) {
5634be59a01SSepherosa Ziehau DEBUGOUT("I2CCMD Error bit set\n");
5644be59a01SSepherosa Ziehau return -E1000_ERR_PHY;
5654be59a01SSepherosa Ziehau }
5664be59a01SSepherosa Ziehau *data = (u8) data_local & 0xFF;
5674be59a01SSepherosa Ziehau
5684be59a01SSepherosa Ziehau return E1000_SUCCESS;
5694be59a01SSepherosa Ziehau }
5704be59a01SSepherosa Ziehau
5714be59a01SSepherosa Ziehau /**
5724be59a01SSepherosa Ziehau * e1000_write_sfp_data_byte - Writes SFP module data.
5734be59a01SSepherosa Ziehau * @hw: pointer to the HW structure
5744be59a01SSepherosa Ziehau * @offset: byte location offset to write to
5754be59a01SSepherosa Ziehau * @data: data to write
5764be59a01SSepherosa Ziehau *
5774be59a01SSepherosa Ziehau * Writes one byte to SFP module data stored
5784be59a01SSepherosa Ziehau * in SFP resided EEPROM memory or SFP diagnostic area.
5794be59a01SSepherosa Ziehau * Function should be called with
5804be59a01SSepherosa Ziehau * E1000_I2CCMD_SFP_DATA_ADDR(<byte offset>) for SFP module database access
5814be59a01SSepherosa Ziehau * E1000_I2CCMD_SFP_DIAG_ADDR(<byte offset>) for SFP diagnostics parameters
5824be59a01SSepherosa Ziehau * access
5834be59a01SSepherosa Ziehau **/
e1000_write_sfp_data_byte(struct e1000_hw * hw,u16 offset,u8 data)5844be59a01SSepherosa Ziehau s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data)
5854be59a01SSepherosa Ziehau {
5864be59a01SSepherosa Ziehau u32 i = 0;
5874be59a01SSepherosa Ziehau u32 i2ccmd = 0;
5884be59a01SSepherosa Ziehau u32 data_local = 0;
5894be59a01SSepherosa Ziehau
5904be59a01SSepherosa Ziehau DEBUGFUNC("e1000_write_sfp_data_byte");
5914be59a01SSepherosa Ziehau
5924be59a01SSepherosa Ziehau if (offset > E1000_I2CCMD_SFP_DIAG_ADDR(255)) {
5934be59a01SSepherosa Ziehau DEBUGOUT("I2CCMD command address exceeds upper limit\n");
5944be59a01SSepherosa Ziehau return -E1000_ERR_PHY;
5954be59a01SSepherosa Ziehau }
596379ebbe7SSepherosa Ziehau /* The programming interface is 16 bits wide
5974be59a01SSepherosa Ziehau * so we need to read the whole word first
5984be59a01SSepherosa Ziehau * then update appropriate byte lane and write
5994be59a01SSepherosa Ziehau * the updated word back.
6004be59a01SSepherosa Ziehau */
601379ebbe7SSepherosa Ziehau /* Set up Op-code, EEPROM Address,in the I2CCMD
6024be59a01SSepherosa Ziehau * register. The MAC will take care of interfacing
6034be59a01SSepherosa Ziehau * with an EEPROM to write the data given.
6044be59a01SSepherosa Ziehau */
6054be59a01SSepherosa Ziehau i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
6064be59a01SSepherosa Ziehau E1000_I2CCMD_OPCODE_READ);
6074be59a01SSepherosa Ziehau /* Set a command to read single word */
6084be59a01SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd);
6094be59a01SSepherosa Ziehau for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
6104be59a01SSepherosa Ziehau usec_delay(50);
611379ebbe7SSepherosa Ziehau /* Poll the ready bit to see if lastly
6124be59a01SSepherosa Ziehau * launched I2C operation completed
6134be59a01SSepherosa Ziehau */
6144be59a01SSepherosa Ziehau i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD);
6154be59a01SSepherosa Ziehau if (i2ccmd & E1000_I2CCMD_READY) {
6164be59a01SSepherosa Ziehau /* Check if this is READ or WRITE phase */
6174be59a01SSepherosa Ziehau if ((i2ccmd & E1000_I2CCMD_OPCODE_READ) ==
6184be59a01SSepherosa Ziehau E1000_I2CCMD_OPCODE_READ) {
619379ebbe7SSepherosa Ziehau /* Write the selected byte
6204be59a01SSepherosa Ziehau * lane and update whole word
6214be59a01SSepherosa Ziehau */
6224be59a01SSepherosa Ziehau data_local = i2ccmd & 0xFF00;
6234be59a01SSepherosa Ziehau data_local |= data;
6244be59a01SSepherosa Ziehau i2ccmd = ((offset <<
6254be59a01SSepherosa Ziehau E1000_I2CCMD_REG_ADDR_SHIFT) |
6264be59a01SSepherosa Ziehau E1000_I2CCMD_OPCODE_WRITE | data_local);
6274be59a01SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd);
6284be59a01SSepherosa Ziehau } else {
6294be59a01SSepherosa Ziehau break;
6304be59a01SSepherosa Ziehau }
6314be59a01SSepherosa Ziehau }
6324be59a01SSepherosa Ziehau }
6334be59a01SSepherosa Ziehau if (!(i2ccmd & E1000_I2CCMD_READY)) {
6344be59a01SSepherosa Ziehau DEBUGOUT("I2CCMD Write did not complete\n");
6354be59a01SSepherosa Ziehau return -E1000_ERR_PHY;
6364be59a01SSepherosa Ziehau }
6374be59a01SSepherosa Ziehau if (i2ccmd & E1000_I2CCMD_ERROR) {
6384be59a01SSepherosa Ziehau DEBUGOUT("I2CCMD Error bit set\n");
6394be59a01SSepherosa Ziehau return -E1000_ERR_PHY;
6404be59a01SSepherosa Ziehau }
6414be59a01SSepherosa Ziehau return E1000_SUCCESS;
6424be59a01SSepherosa Ziehau }
6434be59a01SSepherosa Ziehau
6444be59a01SSepherosa Ziehau /**
6459c80d176SSepherosa Ziehau * e1000_read_phy_reg_m88 - Read m88 PHY register
6469c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
6479c80d176SSepherosa Ziehau * @offset: register offset to be read
6489c80d176SSepherosa Ziehau * @data: pointer to the read data
6499c80d176SSepherosa Ziehau *
6509c80d176SSepherosa Ziehau * Acquires semaphore, if necessary, then reads the PHY register at offset
6519c80d176SSepherosa Ziehau * and storing the retrieved information in data. Release any acquired
6529c80d176SSepherosa Ziehau * semaphores before exiting.
6539c80d176SSepherosa Ziehau **/
e1000_read_phy_reg_m88(struct e1000_hw * hw,u32 offset,u16 * data)6549c80d176SSepherosa Ziehau s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data)
6559c80d176SSepherosa Ziehau {
6564be59a01SSepherosa Ziehau s32 ret_val;
6579c80d176SSepherosa Ziehau
6589c80d176SSepherosa Ziehau DEBUGFUNC("e1000_read_phy_reg_m88");
6599c80d176SSepherosa Ziehau
6604be59a01SSepherosa Ziehau if (!hw->phy.ops.acquire)
6614be59a01SSepherosa Ziehau return E1000_SUCCESS;
6629c80d176SSepherosa Ziehau
6639c80d176SSepherosa Ziehau ret_val = hw->phy.ops.acquire(hw);
6649c80d176SSepherosa Ziehau if (ret_val)
6654be59a01SSepherosa Ziehau return ret_val;
6669c80d176SSepherosa Ziehau
6679c80d176SSepherosa Ziehau ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
6689c80d176SSepherosa Ziehau data);
6699c80d176SSepherosa Ziehau
6709c80d176SSepherosa Ziehau hw->phy.ops.release(hw);
6719c80d176SSepherosa Ziehau
6729c80d176SSepherosa Ziehau return ret_val;
6739c80d176SSepherosa Ziehau }
6749c80d176SSepherosa Ziehau
6759c80d176SSepherosa Ziehau /**
6769c80d176SSepherosa Ziehau * e1000_write_phy_reg_m88 - Write m88 PHY register
6779c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
6789c80d176SSepherosa Ziehau * @offset: register offset to write to
6799c80d176SSepherosa Ziehau * @data: data to write at register offset
6809c80d176SSepherosa Ziehau *
6819c80d176SSepherosa Ziehau * Acquires semaphore, if necessary, then writes the data to PHY register
6829c80d176SSepherosa Ziehau * at the offset. Release any acquired semaphores before exiting.
6839c80d176SSepherosa Ziehau **/
e1000_write_phy_reg_m88(struct e1000_hw * hw,u32 offset,u16 data)6849c80d176SSepherosa Ziehau s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data)
6859c80d176SSepherosa Ziehau {
6864be59a01SSepherosa Ziehau s32 ret_val;
6879c80d176SSepherosa Ziehau
6889c80d176SSepherosa Ziehau DEBUGFUNC("e1000_write_phy_reg_m88");
6899c80d176SSepherosa Ziehau
6904be59a01SSepherosa Ziehau if (!hw->phy.ops.acquire)
6914be59a01SSepherosa Ziehau return E1000_SUCCESS;
6929c80d176SSepherosa Ziehau
6939c80d176SSepherosa Ziehau ret_val = hw->phy.ops.acquire(hw);
6949c80d176SSepherosa Ziehau if (ret_val)
6954be59a01SSepherosa Ziehau return ret_val;
6969c80d176SSepherosa Ziehau
6979c80d176SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
6989c80d176SSepherosa Ziehau data);
6999c80d176SSepherosa Ziehau
7009c80d176SSepherosa Ziehau hw->phy.ops.release(hw);
7019c80d176SSepherosa Ziehau
7029c80d176SSepherosa Ziehau return ret_val;
7039c80d176SSepherosa Ziehau }
7049c80d176SSepherosa Ziehau
7059c80d176SSepherosa Ziehau /**
7066d5e2922SSepherosa Ziehau * e1000_set_page_igp - Set page as on IGP-like PHY(s)
7076d5e2922SSepherosa Ziehau * @hw: pointer to the HW structure
7086d5e2922SSepherosa Ziehau * @page: page to set (shifted left when necessary)
7096d5e2922SSepherosa Ziehau *
7106d5e2922SSepherosa Ziehau * Sets PHY page required for PHY register access. Assumes semaphore is
7116d5e2922SSepherosa Ziehau * already acquired. Note, this function sets phy.addr to 1 so the caller
7126d5e2922SSepherosa Ziehau * must set it appropriately (if necessary) after this function returns.
7136d5e2922SSepherosa Ziehau **/
e1000_set_page_igp(struct e1000_hw * hw,u16 page)7146d5e2922SSepherosa Ziehau s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page)
7156d5e2922SSepherosa Ziehau {
7166d5e2922SSepherosa Ziehau DEBUGFUNC("e1000_set_page_igp");
7176d5e2922SSepherosa Ziehau
7186d5e2922SSepherosa Ziehau DEBUGOUT1("Setting page 0x%x\n", page);
7196d5e2922SSepherosa Ziehau
7206d5e2922SSepherosa Ziehau hw->phy.addr = 1;
7216d5e2922SSepherosa Ziehau
7226d5e2922SSepherosa Ziehau return e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, page);
7236d5e2922SSepherosa Ziehau }
7246d5e2922SSepherosa Ziehau
7256d5e2922SSepherosa Ziehau /**
7266a5a645eSSepherosa Ziehau * __e1000_read_phy_reg_igp - Read igp PHY register
7279c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
7289c80d176SSepherosa Ziehau * @offset: register offset to be read
7299c80d176SSepherosa Ziehau * @data: pointer to the read data
7306a5a645eSSepherosa Ziehau * @locked: semaphore has already been acquired or not
7319c80d176SSepherosa Ziehau *
7329c80d176SSepherosa Ziehau * Acquires semaphore, if necessary, then reads the PHY register at offset
7336a5a645eSSepherosa Ziehau * and stores the retrieved information in data. Release any acquired
7349c80d176SSepherosa Ziehau * semaphores before exiting.
7359c80d176SSepherosa Ziehau **/
__e1000_read_phy_reg_igp(struct e1000_hw * hw,u32 offset,u16 * data,bool locked)7366a5a645eSSepherosa Ziehau static s32 __e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data,
7376a5a645eSSepherosa Ziehau bool locked)
7389c80d176SSepherosa Ziehau {
7399c80d176SSepherosa Ziehau s32 ret_val = E1000_SUCCESS;
7409c80d176SSepherosa Ziehau
7416a5a645eSSepherosa Ziehau DEBUGFUNC("__e1000_read_phy_reg_igp");
7429c80d176SSepherosa Ziehau
7436a5a645eSSepherosa Ziehau if (!locked) {
7444be59a01SSepherosa Ziehau if (!hw->phy.ops.acquire)
7454be59a01SSepherosa Ziehau return E1000_SUCCESS;
7469c80d176SSepherosa Ziehau
7479c80d176SSepherosa Ziehau ret_val = hw->phy.ops.acquire(hw);
7489c80d176SSepherosa Ziehau if (ret_val)
7494be59a01SSepherosa Ziehau return ret_val;
7506a5a645eSSepherosa Ziehau }
7519c80d176SSepherosa Ziehau
7524be59a01SSepherosa Ziehau if (offset > MAX_PHY_MULTI_PAGE_REG)
7539c80d176SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw,
7549c80d176SSepherosa Ziehau IGP01E1000_PHY_PAGE_SELECT,
7559c80d176SSepherosa Ziehau (u16)offset);
7564be59a01SSepherosa Ziehau if (!ret_val)
7574be59a01SSepherosa Ziehau ret_val = e1000_read_phy_reg_mdic(hw,
7584be59a01SSepherosa Ziehau MAX_PHY_REG_ADDRESS & offset,
7599c80d176SSepherosa Ziehau data);
7606a5a645eSSepherosa Ziehau if (!locked)
7616a5a645eSSepherosa Ziehau hw->phy.ops.release(hw);
7624be59a01SSepherosa Ziehau
7636a5a645eSSepherosa Ziehau return ret_val;
7646a5a645eSSepherosa Ziehau }
7656a5a645eSSepherosa Ziehau
7666a5a645eSSepherosa Ziehau /**
7676a5a645eSSepherosa Ziehau * e1000_read_phy_reg_igp - Read igp PHY register
7686a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
7696a5a645eSSepherosa Ziehau * @offset: register offset to be read
7706a5a645eSSepherosa Ziehau * @data: pointer to the read data
7716a5a645eSSepherosa Ziehau *
7726a5a645eSSepherosa Ziehau * Acquires semaphore then reads the PHY register at offset and stores the
7736a5a645eSSepherosa Ziehau * retrieved information in data.
7746a5a645eSSepherosa Ziehau * Release the acquired semaphore before exiting.
7756a5a645eSSepherosa Ziehau **/
e1000_read_phy_reg_igp(struct e1000_hw * hw,u32 offset,u16 * data)7766a5a645eSSepherosa Ziehau s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
7776a5a645eSSepherosa Ziehau {
7786a5a645eSSepherosa Ziehau return __e1000_read_phy_reg_igp(hw, offset, data, FALSE);
7796a5a645eSSepherosa Ziehau }
7806a5a645eSSepherosa Ziehau
7816a5a645eSSepherosa Ziehau /**
7826a5a645eSSepherosa Ziehau * e1000_read_phy_reg_igp_locked - Read igp PHY register
7836a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
7846a5a645eSSepherosa Ziehau * @offset: register offset to be read
7856a5a645eSSepherosa Ziehau * @data: pointer to the read data
7866a5a645eSSepherosa Ziehau *
7876a5a645eSSepherosa Ziehau * Reads the PHY register at offset and stores the retrieved information
7886a5a645eSSepherosa Ziehau * in data. Assumes semaphore already acquired.
7896a5a645eSSepherosa Ziehau **/
e1000_read_phy_reg_igp_locked(struct e1000_hw * hw,u32 offset,u16 * data)7906a5a645eSSepherosa Ziehau s32 e1000_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data)
7916a5a645eSSepherosa Ziehau {
7926a5a645eSSepherosa Ziehau return __e1000_read_phy_reg_igp(hw, offset, data, TRUE);
7936a5a645eSSepherosa Ziehau }
7946a5a645eSSepherosa Ziehau
7956a5a645eSSepherosa Ziehau /**
7966a5a645eSSepherosa Ziehau * e1000_write_phy_reg_igp - Write igp PHY register
7976a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
7986a5a645eSSepherosa Ziehau * @offset: register offset to write to
7996a5a645eSSepherosa Ziehau * @data: data to write at register offset
8006a5a645eSSepherosa Ziehau * @locked: semaphore has already been acquired or not
8016a5a645eSSepherosa Ziehau *
8026a5a645eSSepherosa Ziehau * Acquires semaphore, if necessary, then writes the data to PHY register
8036a5a645eSSepherosa Ziehau * at the offset. Release any acquired semaphores before exiting.
8046a5a645eSSepherosa Ziehau **/
__e1000_write_phy_reg_igp(struct e1000_hw * hw,u32 offset,u16 data,bool locked)8056a5a645eSSepherosa Ziehau static s32 __e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data,
8066a5a645eSSepherosa Ziehau bool locked)
8076a5a645eSSepherosa Ziehau {
8086a5a645eSSepherosa Ziehau s32 ret_val = E1000_SUCCESS;
8096a5a645eSSepherosa Ziehau
8106a5a645eSSepherosa Ziehau DEBUGFUNC("e1000_write_phy_reg_igp");
8116a5a645eSSepherosa Ziehau
8126a5a645eSSepherosa Ziehau if (!locked) {
8134be59a01SSepherosa Ziehau if (!hw->phy.ops.acquire)
8144be59a01SSepherosa Ziehau return E1000_SUCCESS;
8156a5a645eSSepherosa Ziehau
8166a5a645eSSepherosa Ziehau ret_val = hw->phy.ops.acquire(hw);
8176a5a645eSSepherosa Ziehau if (ret_val)
8184be59a01SSepherosa Ziehau return ret_val;
8196a5a645eSSepherosa Ziehau }
8206a5a645eSSepherosa Ziehau
8214be59a01SSepherosa Ziehau if (offset > MAX_PHY_MULTI_PAGE_REG)
8226a5a645eSSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw,
8236a5a645eSSepherosa Ziehau IGP01E1000_PHY_PAGE_SELECT,
8246a5a645eSSepherosa Ziehau (u16)offset);
8254be59a01SSepherosa Ziehau if (!ret_val)
8264be59a01SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS &
8274be59a01SSepherosa Ziehau offset,
8286a5a645eSSepherosa Ziehau data);
8296a5a645eSSepherosa Ziehau if (!locked)
8309c80d176SSepherosa Ziehau hw->phy.ops.release(hw);
8319c80d176SSepherosa Ziehau
8329c80d176SSepherosa Ziehau return ret_val;
8339c80d176SSepherosa Ziehau }
8349c80d176SSepherosa Ziehau
8359c80d176SSepherosa Ziehau /**
8369c80d176SSepherosa Ziehau * e1000_write_phy_reg_igp - Write igp PHY register
8379c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
8389c80d176SSepherosa Ziehau * @offset: register offset to write to
8399c80d176SSepherosa Ziehau * @data: data to write at register offset
8409c80d176SSepherosa Ziehau *
8416a5a645eSSepherosa Ziehau * Acquires semaphore then writes the data to PHY register
8429c80d176SSepherosa Ziehau * at the offset. Release any acquired semaphores before exiting.
8439c80d176SSepherosa Ziehau **/
e1000_write_phy_reg_igp(struct e1000_hw * hw,u32 offset,u16 data)8449c80d176SSepherosa Ziehau s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
8459c80d176SSepherosa Ziehau {
8466a5a645eSSepherosa Ziehau return __e1000_write_phy_reg_igp(hw, offset, data, FALSE);
8476a5a645eSSepherosa Ziehau }
8486a5a645eSSepherosa Ziehau
8496a5a645eSSepherosa Ziehau /**
8506a5a645eSSepherosa Ziehau * e1000_write_phy_reg_igp_locked - Write igp PHY register
8516a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
8526a5a645eSSepherosa Ziehau * @offset: register offset to write to
8536a5a645eSSepherosa Ziehau * @data: data to write at register offset
8546a5a645eSSepherosa Ziehau *
8556a5a645eSSepherosa Ziehau * Writes the data to PHY register at the offset.
8566a5a645eSSepherosa Ziehau * Assumes semaphore already acquired.
8576a5a645eSSepherosa Ziehau **/
e1000_write_phy_reg_igp_locked(struct e1000_hw * hw,u32 offset,u16 data)8586a5a645eSSepherosa Ziehau s32 e1000_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data)
8596a5a645eSSepherosa Ziehau {
8606a5a645eSSepherosa Ziehau return __e1000_write_phy_reg_igp(hw, offset, data, TRUE);
8616a5a645eSSepherosa Ziehau }
8626a5a645eSSepherosa Ziehau
8636a5a645eSSepherosa Ziehau /**
8646a5a645eSSepherosa Ziehau * __e1000_read_kmrn_reg - Read kumeran register
8656a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
8666a5a645eSSepherosa Ziehau * @offset: register offset to be read
8676a5a645eSSepherosa Ziehau * @data: pointer to the read data
8686a5a645eSSepherosa Ziehau * @locked: semaphore has already been acquired or not
8696a5a645eSSepherosa Ziehau *
8706a5a645eSSepherosa Ziehau * Acquires semaphore, if necessary. Then reads the PHY register at offset
8716a5a645eSSepherosa Ziehau * using the kumeran interface. The information retrieved is stored in data.
8726a5a645eSSepherosa Ziehau * Release any acquired semaphores before exiting.
8736a5a645eSSepherosa Ziehau **/
__e1000_read_kmrn_reg(struct e1000_hw * hw,u32 offset,u16 * data,bool locked)8746a5a645eSSepherosa Ziehau static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data,
8756a5a645eSSepherosa Ziehau bool locked)
8766a5a645eSSepherosa Ziehau {
8776a5a645eSSepherosa Ziehau u32 kmrnctrlsta;
8789c80d176SSepherosa Ziehau
8796a5a645eSSepherosa Ziehau DEBUGFUNC("__e1000_read_kmrn_reg");
8809c80d176SSepherosa Ziehau
8816a5a645eSSepherosa Ziehau if (!locked) {
8824be59a01SSepherosa Ziehau s32 ret_val = E1000_SUCCESS;
8834be59a01SSepherosa Ziehau
8844be59a01SSepherosa Ziehau if (!hw->phy.ops.acquire)
8854be59a01SSepherosa Ziehau return E1000_SUCCESS;
8869c80d176SSepherosa Ziehau
8879c80d176SSepherosa Ziehau ret_val = hw->phy.ops.acquire(hw);
8889c80d176SSepherosa Ziehau if (ret_val)
8894be59a01SSepherosa Ziehau return ret_val;
8909c80d176SSepherosa Ziehau }
8919c80d176SSepherosa Ziehau
8926a5a645eSSepherosa Ziehau kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
8936a5a645eSSepherosa Ziehau E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
8946a5a645eSSepherosa Ziehau E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
8954be59a01SSepherosa Ziehau E1000_WRITE_FLUSH(hw);
8969c80d176SSepherosa Ziehau
8976a5a645eSSepherosa Ziehau usec_delay(2);
8986a5a645eSSepherosa Ziehau
8996a5a645eSSepherosa Ziehau kmrnctrlsta = E1000_READ_REG(hw, E1000_KMRNCTRLSTA);
9006a5a645eSSepherosa Ziehau *data = (u16)kmrnctrlsta;
9016a5a645eSSepherosa Ziehau
9026a5a645eSSepherosa Ziehau if (!locked)
9039c80d176SSepherosa Ziehau hw->phy.ops.release(hw);
9049c80d176SSepherosa Ziehau
9054be59a01SSepherosa Ziehau return E1000_SUCCESS;
9069c80d176SSepherosa Ziehau }
9079c80d176SSepherosa Ziehau
9089c80d176SSepherosa Ziehau /**
9099c80d176SSepherosa Ziehau * e1000_read_kmrn_reg_generic - Read kumeran register
9109c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
9119c80d176SSepherosa Ziehau * @offset: register offset to be read
9129c80d176SSepherosa Ziehau * @data: pointer to the read data
9139c80d176SSepherosa Ziehau *
9146a5a645eSSepherosa Ziehau * Acquires semaphore then reads the PHY register at offset using the
9156a5a645eSSepherosa Ziehau * kumeran interface. The information retrieved is stored in data.
9166a5a645eSSepherosa Ziehau * Release the acquired semaphore before exiting.
9179c80d176SSepherosa Ziehau **/
e1000_read_kmrn_reg_generic(struct e1000_hw * hw,u32 offset,u16 * data)9189c80d176SSepherosa Ziehau s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data)
9199c80d176SSepherosa Ziehau {
9206a5a645eSSepherosa Ziehau return __e1000_read_kmrn_reg(hw, offset, data, FALSE);
9216a5a645eSSepherosa Ziehau }
9226a5a645eSSepherosa Ziehau
9236a5a645eSSepherosa Ziehau /**
9246a5a645eSSepherosa Ziehau * e1000_read_kmrn_reg_locked - Read kumeran register
9256a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
9266a5a645eSSepherosa Ziehau * @offset: register offset to be read
9276a5a645eSSepherosa Ziehau * @data: pointer to the read data
9286a5a645eSSepherosa Ziehau *
9296a5a645eSSepherosa Ziehau * Reads the PHY register at offset using the kumeran interface. The
9306a5a645eSSepherosa Ziehau * information retrieved is stored in data.
9316a5a645eSSepherosa Ziehau * Assumes semaphore already acquired.
9326a5a645eSSepherosa Ziehau **/
e1000_read_kmrn_reg_locked(struct e1000_hw * hw,u32 offset,u16 * data)9336a5a645eSSepherosa Ziehau s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data)
9346a5a645eSSepherosa Ziehau {
9356a5a645eSSepherosa Ziehau return __e1000_read_kmrn_reg(hw, offset, data, TRUE);
9366a5a645eSSepherosa Ziehau }
9376a5a645eSSepherosa Ziehau
9386a5a645eSSepherosa Ziehau /**
9396a5a645eSSepherosa Ziehau * __e1000_write_kmrn_reg - Write kumeran register
9406a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
9416a5a645eSSepherosa Ziehau * @offset: register offset to write to
9426a5a645eSSepherosa Ziehau * @data: data to write at register offset
9436a5a645eSSepherosa Ziehau * @locked: semaphore has already been acquired or not
9446a5a645eSSepherosa Ziehau *
9456a5a645eSSepherosa Ziehau * Acquires semaphore, if necessary. Then write the data to PHY register
9466a5a645eSSepherosa Ziehau * at the offset using the kumeran interface. Release any acquired semaphores
9476a5a645eSSepherosa Ziehau * before exiting.
9486a5a645eSSepherosa Ziehau **/
__e1000_write_kmrn_reg(struct e1000_hw * hw,u32 offset,u16 data,bool locked)9496a5a645eSSepherosa Ziehau static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data,
9506a5a645eSSepherosa Ziehau bool locked)
9516a5a645eSSepherosa Ziehau {
9529c80d176SSepherosa Ziehau u32 kmrnctrlsta;
9539c80d176SSepherosa Ziehau
9546a5a645eSSepherosa Ziehau DEBUGFUNC("e1000_write_kmrn_reg_generic");
9559c80d176SSepherosa Ziehau
9566a5a645eSSepherosa Ziehau if (!locked) {
9574be59a01SSepherosa Ziehau s32 ret_val = E1000_SUCCESS;
9584be59a01SSepherosa Ziehau
9594be59a01SSepherosa Ziehau if (!hw->phy.ops.acquire)
9604be59a01SSepherosa Ziehau return E1000_SUCCESS;
9619c80d176SSepherosa Ziehau
9629c80d176SSepherosa Ziehau ret_val = hw->phy.ops.acquire(hw);
9639c80d176SSepherosa Ziehau if (ret_val)
9644be59a01SSepherosa Ziehau return ret_val;
9656a5a645eSSepherosa Ziehau }
9669c80d176SSepherosa Ziehau
9679c80d176SSepherosa Ziehau kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
9686a5a645eSSepherosa Ziehau E1000_KMRNCTRLSTA_OFFSET) | data;
9699c80d176SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
9704be59a01SSepherosa Ziehau E1000_WRITE_FLUSH(hw);
9719c80d176SSepherosa Ziehau
9729c80d176SSepherosa Ziehau usec_delay(2);
9739c80d176SSepherosa Ziehau
9746a5a645eSSepherosa Ziehau if (!locked)
9759c80d176SSepherosa Ziehau hw->phy.ops.release(hw);
9769c80d176SSepherosa Ziehau
9774be59a01SSepherosa Ziehau return E1000_SUCCESS;
9789c80d176SSepherosa Ziehau }
9799c80d176SSepherosa Ziehau
9809c80d176SSepherosa Ziehau /**
9819c80d176SSepherosa Ziehau * e1000_write_kmrn_reg_generic - Write kumeran register
9829c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
9839c80d176SSepherosa Ziehau * @offset: register offset to write to
9849c80d176SSepherosa Ziehau * @data: data to write at register offset
9859c80d176SSepherosa Ziehau *
9866a5a645eSSepherosa Ziehau * Acquires semaphore then writes the data to the PHY register at the offset
9876a5a645eSSepherosa Ziehau * using the kumeran interface. Release the acquired semaphore before exiting.
9889c80d176SSepherosa Ziehau **/
e1000_write_kmrn_reg_generic(struct e1000_hw * hw,u32 offset,u16 data)9899c80d176SSepherosa Ziehau s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data)
9909c80d176SSepherosa Ziehau {
9916a5a645eSSepherosa Ziehau return __e1000_write_kmrn_reg(hw, offset, data, FALSE);
9926a5a645eSSepherosa Ziehau }
9939c80d176SSepherosa Ziehau
9946a5a645eSSepherosa Ziehau /**
9956a5a645eSSepherosa Ziehau * e1000_write_kmrn_reg_locked - Write kumeran register
9966a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
9976a5a645eSSepherosa Ziehau * @offset: register offset to write to
9986a5a645eSSepherosa Ziehau * @data: data to write at register offset
9996a5a645eSSepherosa Ziehau *
10006a5a645eSSepherosa Ziehau * Write the data to PHY register at the offset using the kumeran interface.
10016a5a645eSSepherosa Ziehau * Assumes semaphore already acquired.
10026a5a645eSSepherosa Ziehau **/
e1000_write_kmrn_reg_locked(struct e1000_hw * hw,u32 offset,u16 data)10036a5a645eSSepherosa Ziehau s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data)
10046a5a645eSSepherosa Ziehau {
10056a5a645eSSepherosa Ziehau return __e1000_write_kmrn_reg(hw, offset, data, TRUE);
10066a5a645eSSepherosa Ziehau }
10079c80d176SSepherosa Ziehau
10086a5a645eSSepherosa Ziehau /**
10094be59a01SSepherosa Ziehau * e1000_set_master_slave_mode - Setup PHY for Master/slave mode
10104be59a01SSepherosa Ziehau * @hw: pointer to the HW structure
10114be59a01SSepherosa Ziehau *
10124be59a01SSepherosa Ziehau * Sets up Master/slave mode
10134be59a01SSepherosa Ziehau **/
e1000_set_master_slave_mode(struct e1000_hw * hw)10144be59a01SSepherosa Ziehau static s32 e1000_set_master_slave_mode(struct e1000_hw *hw)
10154be59a01SSepherosa Ziehau {
10164be59a01SSepherosa Ziehau s32 ret_val;
10174be59a01SSepherosa Ziehau u16 phy_data;
10184be59a01SSepherosa Ziehau
10194be59a01SSepherosa Ziehau /* Resolve Master/Slave mode */
10204be59a01SSepherosa Ziehau ret_val = hw->phy.ops.read_reg(hw, PHY_1000T_CTRL, &phy_data);
10214be59a01SSepherosa Ziehau if (ret_val)
10224be59a01SSepherosa Ziehau return ret_val;
10234be59a01SSepherosa Ziehau
10244be59a01SSepherosa Ziehau /* load defaults for future use */
10254be59a01SSepherosa Ziehau hw->phy.original_ms_type = (phy_data & CR_1000T_MS_ENABLE) ?
10264be59a01SSepherosa Ziehau ((phy_data & CR_1000T_MS_VALUE) ?
10274be59a01SSepherosa Ziehau e1000_ms_force_master :
10284be59a01SSepherosa Ziehau e1000_ms_force_slave) : e1000_ms_auto;
10294be59a01SSepherosa Ziehau
10304be59a01SSepherosa Ziehau switch (hw->phy.ms_type) {
10314be59a01SSepherosa Ziehau case e1000_ms_force_master:
10324be59a01SSepherosa Ziehau phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
10334be59a01SSepherosa Ziehau break;
10344be59a01SSepherosa Ziehau case e1000_ms_force_slave:
10354be59a01SSepherosa Ziehau phy_data |= CR_1000T_MS_ENABLE;
10364be59a01SSepherosa Ziehau phy_data &= ~(CR_1000T_MS_VALUE);
10374be59a01SSepherosa Ziehau break;
10384be59a01SSepherosa Ziehau case e1000_ms_auto:
10394be59a01SSepherosa Ziehau phy_data &= ~CR_1000T_MS_ENABLE;
10404be59a01SSepherosa Ziehau /* fall-through */
10414be59a01SSepherosa Ziehau default:
10424be59a01SSepherosa Ziehau break;
10434be59a01SSepherosa Ziehau }
10444be59a01SSepherosa Ziehau
10454be59a01SSepherosa Ziehau return hw->phy.ops.write_reg(hw, PHY_1000T_CTRL, phy_data);
10464be59a01SSepherosa Ziehau }
10474be59a01SSepherosa Ziehau
10484be59a01SSepherosa Ziehau /**
10496a5a645eSSepherosa Ziehau * e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link
10506a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
10516a5a645eSSepherosa Ziehau *
10526a5a645eSSepherosa Ziehau * Sets up Carrier-sense on Transmit and downshift values.
10536a5a645eSSepherosa Ziehau **/
e1000_copper_link_setup_82577(struct e1000_hw * hw)10546a5a645eSSepherosa Ziehau s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
10556a5a645eSSepherosa Ziehau {
10566a5a645eSSepherosa Ziehau s32 ret_val;
10576a5a645eSSepherosa Ziehau u16 phy_data;
10586a5a645eSSepherosa Ziehau
10596a5a645eSSepherosa Ziehau DEBUGFUNC("e1000_copper_link_setup_82577");
10606a5a645eSSepherosa Ziehau
10616a5a645eSSepherosa Ziehau if (hw->phy.type == e1000_phy_82580) {
10626a5a645eSSepherosa Ziehau ret_val = hw->phy.ops.reset(hw);
10636a5a645eSSepherosa Ziehau if (ret_val) {
10646a5a645eSSepherosa Ziehau DEBUGOUT("Error resetting the PHY.\n");
10654be59a01SSepherosa Ziehau return ret_val;
10666a5a645eSSepherosa Ziehau }
10676a5a645eSSepherosa Ziehau }
10686a5a645eSSepherosa Ziehau
10694765c386SMichael Neumann /* Enable CRS on Tx. This must be set for half-duplex operation. */
10706a5a645eSSepherosa Ziehau ret_val = hw->phy.ops.read_reg(hw, I82577_CFG_REG, &phy_data);
10719c80d176SSepherosa Ziehau if (ret_val)
10724be59a01SSepherosa Ziehau return ret_val;
10739c80d176SSepherosa Ziehau
10746a5a645eSSepherosa Ziehau phy_data |= I82577_CFG_ASSERT_CRS_ON_TX;
10759c80d176SSepherosa Ziehau
10766a5a645eSSepherosa Ziehau /* Enable downshift */
10776a5a645eSSepherosa Ziehau phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
10786a5a645eSSepherosa Ziehau
10796a5a645eSSepherosa Ziehau ret_val = hw->phy.ops.write_reg(hw, I82577_CFG_REG, phy_data);
10804be59a01SSepherosa Ziehau if (ret_val)
10819c80d176SSepherosa Ziehau return ret_val;
10824be59a01SSepherosa Ziehau
10834be59a01SSepherosa Ziehau /* Set MDI/MDIX mode */
10844be59a01SSepherosa Ziehau ret_val = hw->phy.ops.read_reg(hw, I82577_PHY_CTRL_2, &phy_data);
10854be59a01SSepherosa Ziehau if (ret_val)
10864be59a01SSepherosa Ziehau return ret_val;
10874be59a01SSepherosa Ziehau phy_data &= ~I82577_PHY_CTRL2_MDIX_CFG_MASK;
1088379ebbe7SSepherosa Ziehau /* Options:
10894be59a01SSepherosa Ziehau * 0 - Auto (default)
10904be59a01SSepherosa Ziehau * 1 - MDI mode
10914be59a01SSepherosa Ziehau * 2 - MDI-X mode
10924be59a01SSepherosa Ziehau */
10934be59a01SSepherosa Ziehau switch (hw->phy.mdix) {
10944be59a01SSepherosa Ziehau case 1:
10954be59a01SSepherosa Ziehau break;
10964be59a01SSepherosa Ziehau case 2:
10974be59a01SSepherosa Ziehau phy_data |= I82577_PHY_CTRL2_MANUAL_MDIX;
10984be59a01SSepherosa Ziehau break;
10994be59a01SSepherosa Ziehau case 0:
11004be59a01SSepherosa Ziehau default:
11014be59a01SSepherosa Ziehau phy_data |= I82577_PHY_CTRL2_AUTO_MDI_MDIX;
11024be59a01SSepherosa Ziehau break;
11034be59a01SSepherosa Ziehau }
11044be59a01SSepherosa Ziehau ret_val = hw->phy.ops.write_reg(hw, I82577_PHY_CTRL_2, phy_data);
11054be59a01SSepherosa Ziehau if (ret_val)
11064be59a01SSepherosa Ziehau return ret_val;
11074be59a01SSepherosa Ziehau
11084be59a01SSepherosa Ziehau return e1000_set_master_slave_mode(hw);
11099c80d176SSepherosa Ziehau }
11109c80d176SSepherosa Ziehau
11119c80d176SSepherosa Ziehau /**
11129c80d176SSepherosa Ziehau * e1000_copper_link_setup_m88 - Setup m88 PHY's for copper link
11139c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
11149c80d176SSepherosa Ziehau *
11159c80d176SSepherosa Ziehau * Sets up MDI/MDI-X and polarity for m88 PHY's. If necessary, transmit clock
11169c80d176SSepherosa Ziehau * and downshift values are set also.
11179c80d176SSepherosa Ziehau **/
e1000_copper_link_setup_m88(struct e1000_hw * hw)11189c80d176SSepherosa Ziehau s32 e1000_copper_link_setup_m88(struct e1000_hw *hw)
11199c80d176SSepherosa Ziehau {
11209c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
11219c80d176SSepherosa Ziehau s32 ret_val;
11229c80d176SSepherosa Ziehau u16 phy_data;
11239c80d176SSepherosa Ziehau
11249c80d176SSepherosa Ziehau DEBUGFUNC("e1000_copper_link_setup_m88");
11259c80d176SSepherosa Ziehau
11269c80d176SSepherosa Ziehau
11276a5a645eSSepherosa Ziehau /* Enable CRS on Tx. This must be set for half-duplex operation. */
11289c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
11299c80d176SSepherosa Ziehau if (ret_val)
11304be59a01SSepherosa Ziehau return ret_val;
11319c80d176SSepherosa Ziehau
11326a5a645eSSepherosa Ziehau /* For BM PHY this bit is downshift enable */
11336d5e2922SSepherosa Ziehau if (phy->type != e1000_phy_bm)
11346d5e2922SSepherosa Ziehau phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
11359c80d176SSepherosa Ziehau
1136379ebbe7SSepherosa Ziehau /* Options:
11379c80d176SSepherosa Ziehau * MDI/MDI-X = 0 (default)
11389c80d176SSepherosa Ziehau * 0 - Auto for all speeds
11399c80d176SSepherosa Ziehau * 1 - MDI mode
11409c80d176SSepherosa Ziehau * 2 - MDI-X mode
11419c80d176SSepherosa Ziehau * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
11429c80d176SSepherosa Ziehau */
11439c80d176SSepherosa Ziehau phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
11449c80d176SSepherosa Ziehau
11459c80d176SSepherosa Ziehau switch (phy->mdix) {
11469c80d176SSepherosa Ziehau case 1:
11479c80d176SSepherosa Ziehau phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
11489c80d176SSepherosa Ziehau break;
11499c80d176SSepherosa Ziehau case 2:
11509c80d176SSepherosa Ziehau phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
11519c80d176SSepherosa Ziehau break;
11529c80d176SSepherosa Ziehau case 3:
11539c80d176SSepherosa Ziehau phy_data |= M88E1000_PSCR_AUTO_X_1000T;
11549c80d176SSepherosa Ziehau break;
11559c80d176SSepherosa Ziehau case 0:
11569c80d176SSepherosa Ziehau default:
11579c80d176SSepherosa Ziehau phy_data |= M88E1000_PSCR_AUTO_X_MODE;
11589c80d176SSepherosa Ziehau break;
11599c80d176SSepherosa Ziehau }
11609c80d176SSepherosa Ziehau
1161379ebbe7SSepherosa Ziehau /* Options:
11629c80d176SSepherosa Ziehau * disable_polarity_correction = 0 (default)
11639c80d176SSepherosa Ziehau * Automatic Correction for Reversed Cable Polarity
11649c80d176SSepherosa Ziehau * 0 - Disabled
11659c80d176SSepherosa Ziehau * 1 - Enabled
11669c80d176SSepherosa Ziehau */
11679c80d176SSepherosa Ziehau phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
11684be59a01SSepherosa Ziehau if (phy->disable_polarity_correction)
11699c80d176SSepherosa Ziehau phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
11709c80d176SSepherosa Ziehau
11719c80d176SSepherosa Ziehau /* Enable downshift on BM (disabled by default) */
11724be59a01SSepherosa Ziehau if (phy->type == e1000_phy_bm) {
11734be59a01SSepherosa Ziehau /* For 82574/82583, first disable then enable downshift */
11744be59a01SSepherosa Ziehau if (phy->id == BME1000_E_PHY_ID_R2) {
11754be59a01SSepherosa Ziehau phy_data &= ~BME1000_PSCR_ENABLE_DOWNSHIFT;
11764be59a01SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL,
11774be59a01SSepherosa Ziehau phy_data);
11784be59a01SSepherosa Ziehau if (ret_val)
11794be59a01SSepherosa Ziehau return ret_val;
11804be59a01SSepherosa Ziehau /* Commit the changes. */
11814be59a01SSepherosa Ziehau ret_val = phy->ops.commit(hw);
11824be59a01SSepherosa Ziehau if (ret_val) {
11834be59a01SSepherosa Ziehau DEBUGOUT("Error committing the PHY changes\n");
11844be59a01SSepherosa Ziehau return ret_val;
11854be59a01SSepherosa Ziehau }
11864be59a01SSepherosa Ziehau }
11874be59a01SSepherosa Ziehau
11889c80d176SSepherosa Ziehau phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT;
11894be59a01SSepherosa Ziehau }
11909c80d176SSepherosa Ziehau
11919c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
11929c80d176SSepherosa Ziehau if (ret_val)
11934be59a01SSepherosa Ziehau return ret_val;
11949c80d176SSepherosa Ziehau
119565aebe9fSSepherosa Ziehau if (phy->revision < E1000_REVISION_4 &&
119665aebe9fSSepherosa Ziehau (hw->mac.type >= e1000_82575 ||
119765aebe9fSSepherosa Ziehau (phy->type == e1000_phy_m88 && phy->id != BME1000_E_PHY_ID_R2))) {
1198379ebbe7SSepherosa Ziehau /* Force TX_CLK in the Extended PHY Specific Control Register
11999c80d176SSepherosa Ziehau * to 25MHz clock.
12009c80d176SSepherosa Ziehau */
12019c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
12029c80d176SSepherosa Ziehau &phy_data);
12039c80d176SSepherosa Ziehau if (ret_val)
12044be59a01SSepherosa Ziehau return ret_val;
12059c80d176SSepherosa Ziehau
12069c80d176SSepherosa Ziehau phy_data |= M88E1000_EPSCR_TX_CLK_25;
12079c80d176SSepherosa Ziehau
12089c80d176SSepherosa Ziehau if ((phy->revision == E1000_REVISION_2) &&
12099c80d176SSepherosa Ziehau (phy->id == M88E1111_I_PHY_ID)) {
12109c80d176SSepherosa Ziehau /* 82573L PHY - set the downshift counter to 5x. */
12119c80d176SSepherosa Ziehau phy_data &= ~M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK;
12129c80d176SSepherosa Ziehau phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
12139c80d176SSepherosa Ziehau } else {
12149c80d176SSepherosa Ziehau /* Configure Master and Slave downshift values */
12159c80d176SSepherosa Ziehau phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
12169c80d176SSepherosa Ziehau M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
12179c80d176SSepherosa Ziehau phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
12189c80d176SSepherosa Ziehau M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
12199c80d176SSepherosa Ziehau }
12209c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
12219c80d176SSepherosa Ziehau phy_data);
12229c80d176SSepherosa Ziehau if (ret_val)
12234be59a01SSepherosa Ziehau return ret_val;
12249c80d176SSepherosa Ziehau }
12259c80d176SSepherosa Ziehau
12269c80d176SSepherosa Ziehau if ((phy->type == e1000_phy_bm) && (phy->id == BME1000_E_PHY_ID_R2)) {
12279c80d176SSepherosa Ziehau /* Set PHY page 0, register 29 to 0x0003 */
12289c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, 29, 0x0003);
12299c80d176SSepherosa Ziehau if (ret_val)
12304be59a01SSepherosa Ziehau return ret_val;
12319c80d176SSepherosa Ziehau
12329c80d176SSepherosa Ziehau /* Set PHY page 0, register 30 to 0x0000 */
12339c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, 30, 0x0000);
12349c80d176SSepherosa Ziehau if (ret_val)
12354be59a01SSepherosa Ziehau return ret_val;
12369c80d176SSepherosa Ziehau }
12379c80d176SSepherosa Ziehau
12389c80d176SSepherosa Ziehau /* Commit the changes. */
12399c80d176SSepherosa Ziehau ret_val = phy->ops.commit(hw);
12409c80d176SSepherosa Ziehau if (ret_val) {
12419c80d176SSepherosa Ziehau DEBUGOUT("Error committing the PHY changes\n");
12424be59a01SSepherosa Ziehau return ret_val;
12439c80d176SSepherosa Ziehau }
12449c80d176SSepherosa Ziehau
12456a5a645eSSepherosa Ziehau if (phy->type == e1000_phy_82578) {
12466a5a645eSSepherosa Ziehau ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
12476a5a645eSSepherosa Ziehau &phy_data);
12486a5a645eSSepherosa Ziehau if (ret_val)
12494be59a01SSepherosa Ziehau return ret_val;
12506a5a645eSSepherosa Ziehau
12516a5a645eSSepherosa Ziehau /* 82578 PHY - set the downshift count to 1x. */
12526a5a645eSSepherosa Ziehau phy_data |= I82578_EPSCR_DOWNSHIFT_ENABLE;
12536a5a645eSSepherosa Ziehau phy_data &= ~I82578_EPSCR_DOWNSHIFT_COUNTER_MASK;
12546a5a645eSSepherosa Ziehau ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
12556a5a645eSSepherosa Ziehau phy_data);
12566a5a645eSSepherosa Ziehau if (ret_val)
12574be59a01SSepherosa Ziehau return ret_val;
12586a5a645eSSepherosa Ziehau }
12596a5a645eSSepherosa Ziehau
12604be59a01SSepherosa Ziehau return E1000_SUCCESS;
12614be59a01SSepherosa Ziehau }
12624be59a01SSepherosa Ziehau
12639c80d176SSepherosa Ziehau /**
126462583d18SSepherosa Ziehau * e1000_copper_link_setup_m88_gen2 - Setup m88 PHY's for copper link
126562583d18SSepherosa Ziehau * @hw: pointer to the HW structure
126662583d18SSepherosa Ziehau *
126762583d18SSepherosa Ziehau * Sets up MDI/MDI-X and polarity for i347-AT4, m88e1322 and m88e1112 PHY's.
126862583d18SSepherosa Ziehau * Also enables and sets the downshift parameters.
126962583d18SSepherosa Ziehau **/
e1000_copper_link_setup_m88_gen2(struct e1000_hw * hw)127062583d18SSepherosa Ziehau s32 e1000_copper_link_setup_m88_gen2(struct e1000_hw *hw)
127162583d18SSepherosa Ziehau {
127262583d18SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
127362583d18SSepherosa Ziehau s32 ret_val;
127462583d18SSepherosa Ziehau u16 phy_data;
127562583d18SSepherosa Ziehau
127662583d18SSepherosa Ziehau DEBUGFUNC("e1000_copper_link_setup_m88_gen2");
127762583d18SSepherosa Ziehau
127862583d18SSepherosa Ziehau
127962583d18SSepherosa Ziehau /* Enable CRS on Tx. This must be set for half-duplex operation. */
128062583d18SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
128162583d18SSepherosa Ziehau if (ret_val)
12824be59a01SSepherosa Ziehau return ret_val;
128362583d18SSepherosa Ziehau
1284379ebbe7SSepherosa Ziehau /* Options:
128562583d18SSepherosa Ziehau * MDI/MDI-X = 0 (default)
128662583d18SSepherosa Ziehau * 0 - Auto for all speeds
128762583d18SSepherosa Ziehau * 1 - MDI mode
128862583d18SSepherosa Ziehau * 2 - MDI-X mode
128962583d18SSepherosa Ziehau * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
129062583d18SSepherosa Ziehau */
129162583d18SSepherosa Ziehau phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
129262583d18SSepherosa Ziehau
129362583d18SSepherosa Ziehau switch (phy->mdix) {
129462583d18SSepherosa Ziehau case 1:
129562583d18SSepherosa Ziehau phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
129662583d18SSepherosa Ziehau break;
129762583d18SSepherosa Ziehau case 2:
129862583d18SSepherosa Ziehau phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
129962583d18SSepherosa Ziehau break;
130062583d18SSepherosa Ziehau case 3:
130162583d18SSepherosa Ziehau /* M88E1112 does not support this mode) */
130262583d18SSepherosa Ziehau if (phy->id != M88E1112_E_PHY_ID) {
130362583d18SSepherosa Ziehau phy_data |= M88E1000_PSCR_AUTO_X_1000T;
130462583d18SSepherosa Ziehau break;
130562583d18SSepherosa Ziehau }
130662583d18SSepherosa Ziehau case 0:
130762583d18SSepherosa Ziehau default:
130862583d18SSepherosa Ziehau phy_data |= M88E1000_PSCR_AUTO_X_MODE;
130962583d18SSepherosa Ziehau break;
131062583d18SSepherosa Ziehau }
131162583d18SSepherosa Ziehau
1312379ebbe7SSepherosa Ziehau /* Options:
131362583d18SSepherosa Ziehau * disable_polarity_correction = 0 (default)
131462583d18SSepherosa Ziehau * Automatic Correction for Reversed Cable Polarity
131562583d18SSepherosa Ziehau * 0 - Disabled
131662583d18SSepherosa Ziehau * 1 - Enabled
131762583d18SSepherosa Ziehau */
131862583d18SSepherosa Ziehau phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
13194be59a01SSepherosa Ziehau if (phy->disable_polarity_correction)
132062583d18SSepherosa Ziehau phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
132162583d18SSepherosa Ziehau
132262583d18SSepherosa Ziehau /* Enable downshift and setting it to X6 */
1323ba0123e0SSepherosa Ziehau if (phy->id == M88E1543_E_PHY_ID) {
1324ba0123e0SSepherosa Ziehau phy_data &= ~I347AT4_PSCR_DOWNSHIFT_ENABLE;
1325ba0123e0SSepherosa Ziehau ret_val =
1326ba0123e0SSepherosa Ziehau phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
1327ba0123e0SSepherosa Ziehau if (ret_val)
1328ba0123e0SSepherosa Ziehau return ret_val;
1329ba0123e0SSepherosa Ziehau
1330ba0123e0SSepherosa Ziehau ret_val = phy->ops.commit(hw);
1331ba0123e0SSepherosa Ziehau if (ret_val) {
1332ba0123e0SSepherosa Ziehau DEBUGOUT("Error committing the PHY changes\n");
1333ba0123e0SSepherosa Ziehau return ret_val;
1334ba0123e0SSepherosa Ziehau }
1335ba0123e0SSepherosa Ziehau }
1336ba0123e0SSepherosa Ziehau
133762583d18SSepherosa Ziehau phy_data &= ~I347AT4_PSCR_DOWNSHIFT_MASK;
133862583d18SSepherosa Ziehau phy_data |= I347AT4_PSCR_DOWNSHIFT_6X;
133962583d18SSepherosa Ziehau phy_data |= I347AT4_PSCR_DOWNSHIFT_ENABLE;
134062583d18SSepherosa Ziehau
134162583d18SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
134262583d18SSepherosa Ziehau if (ret_val)
13434be59a01SSepherosa Ziehau return ret_val;
134462583d18SSepherosa Ziehau
134562583d18SSepherosa Ziehau /* Commit the changes. */
134662583d18SSepherosa Ziehau ret_val = phy->ops.commit(hw);
134762583d18SSepherosa Ziehau if (ret_val) {
134862583d18SSepherosa Ziehau DEBUGOUT("Error committing the PHY changes\n");
13494be59a01SSepherosa Ziehau return ret_val;
135062583d18SSepherosa Ziehau }
135162583d18SSepherosa Ziehau
13524765c386SMichael Neumann ret_val = e1000_set_master_slave_mode(hw);
13534765c386SMichael Neumann if (ret_val)
13544765c386SMichael Neumann return ret_val;
13554765c386SMichael Neumann
13564be59a01SSepherosa Ziehau return E1000_SUCCESS;
135762583d18SSepherosa Ziehau }
135862583d18SSepherosa Ziehau
135962583d18SSepherosa Ziehau /**
13609c80d176SSepherosa Ziehau * e1000_copper_link_setup_igp - Setup igp PHY's for copper link
13619c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
13629c80d176SSepherosa Ziehau *
13639c80d176SSepherosa Ziehau * Sets up LPLU, MDI/MDI-X, polarity, Smartspeed and Master/Slave config for
13649c80d176SSepherosa Ziehau * igp PHY's.
13659c80d176SSepherosa Ziehau **/
e1000_copper_link_setup_igp(struct e1000_hw * hw)13669c80d176SSepherosa Ziehau s32 e1000_copper_link_setup_igp(struct e1000_hw *hw)
13679c80d176SSepherosa Ziehau {
13689c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
13699c80d176SSepherosa Ziehau s32 ret_val;
13709c80d176SSepherosa Ziehau u16 data;
13719c80d176SSepherosa Ziehau
13729c80d176SSepherosa Ziehau DEBUGFUNC("e1000_copper_link_setup_igp");
13739c80d176SSepherosa Ziehau
13749c80d176SSepherosa Ziehau
13759c80d176SSepherosa Ziehau ret_val = hw->phy.ops.reset(hw);
13769c80d176SSepherosa Ziehau if (ret_val) {
13779c80d176SSepherosa Ziehau DEBUGOUT("Error resetting the PHY.\n");
13784be59a01SSepherosa Ziehau return ret_val;
13799c80d176SSepherosa Ziehau }
13809c80d176SSepherosa Ziehau
1381379ebbe7SSepherosa Ziehau /* Wait 100ms for MAC to configure PHY from NVM settings, to avoid
13829c80d176SSepherosa Ziehau * timeout issues when LFS is enabled.
13839c80d176SSepherosa Ziehau */
13849c80d176SSepherosa Ziehau msec_delay(100);
13859c80d176SSepherosa Ziehau
1386379ebbe7SSepherosa Ziehau /* The NVM settings will configure LPLU in D3 for
13879c80d176SSepherosa Ziehau * non-IGP1 PHYs.
13889c80d176SSepherosa Ziehau */
13899c80d176SSepherosa Ziehau if (phy->type == e1000_phy_igp) {
13909c80d176SSepherosa Ziehau /* disable lplu d3 during driver init */
13919c80d176SSepherosa Ziehau ret_val = hw->phy.ops.set_d3_lplu_state(hw, FALSE);
13929c80d176SSepherosa Ziehau if (ret_val) {
13939c80d176SSepherosa Ziehau DEBUGOUT("Error Disabling LPLU D3\n");
13944be59a01SSepherosa Ziehau return ret_val;
13959c80d176SSepherosa Ziehau }
13969c80d176SSepherosa Ziehau }
13979c80d176SSepherosa Ziehau
13989c80d176SSepherosa Ziehau /* disable lplu d0 during driver init */
13999c80d176SSepherosa Ziehau if (hw->phy.ops.set_d0_lplu_state) {
14009c80d176SSepherosa Ziehau ret_val = hw->phy.ops.set_d0_lplu_state(hw, FALSE);
14019c80d176SSepherosa Ziehau if (ret_val) {
14029c80d176SSepherosa Ziehau DEBUGOUT("Error Disabling LPLU D0\n");
14034be59a01SSepherosa Ziehau return ret_val;
14049c80d176SSepherosa Ziehau }
14059c80d176SSepherosa Ziehau }
14069c80d176SSepherosa Ziehau /* Configure mdi-mdix settings */
14079c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data);
14089c80d176SSepherosa Ziehau if (ret_val)
14094be59a01SSepherosa Ziehau return ret_val;
14109c80d176SSepherosa Ziehau
14119c80d176SSepherosa Ziehau data &= ~IGP01E1000_PSCR_AUTO_MDIX;
14129c80d176SSepherosa Ziehau
14139c80d176SSepherosa Ziehau switch (phy->mdix) {
14149c80d176SSepherosa Ziehau case 1:
14159c80d176SSepherosa Ziehau data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
14169c80d176SSepherosa Ziehau break;
14179c80d176SSepherosa Ziehau case 2:
14189c80d176SSepherosa Ziehau data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
14199c80d176SSepherosa Ziehau break;
14209c80d176SSepherosa Ziehau case 0:
14219c80d176SSepherosa Ziehau default:
14229c80d176SSepherosa Ziehau data |= IGP01E1000_PSCR_AUTO_MDIX;
14239c80d176SSepherosa Ziehau break;
14249c80d176SSepherosa Ziehau }
14259c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, data);
14269c80d176SSepherosa Ziehau if (ret_val)
14274be59a01SSepherosa Ziehau return ret_val;
14289c80d176SSepherosa Ziehau
14299c80d176SSepherosa Ziehau /* set auto-master slave resolution settings */
14309c80d176SSepherosa Ziehau if (hw->mac.autoneg) {
1431379ebbe7SSepherosa Ziehau /* when autonegotiation advertisement is only 1000Mbps then we
14329c80d176SSepherosa Ziehau * should disable SmartSpeed and enable Auto MasterSlave
14339c80d176SSepherosa Ziehau * resolution as hardware default.
14349c80d176SSepherosa Ziehau */
14359c80d176SSepherosa Ziehau if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
14369c80d176SSepherosa Ziehau /* Disable SmartSpeed */
14379c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw,
14389c80d176SSepherosa Ziehau IGP01E1000_PHY_PORT_CONFIG,
14399c80d176SSepherosa Ziehau &data);
14409c80d176SSepherosa Ziehau if (ret_val)
14414be59a01SSepherosa Ziehau return ret_val;
14429c80d176SSepherosa Ziehau
14439c80d176SSepherosa Ziehau data &= ~IGP01E1000_PSCFR_SMART_SPEED;
14449c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw,
14459c80d176SSepherosa Ziehau IGP01E1000_PHY_PORT_CONFIG,
14469c80d176SSepherosa Ziehau data);
14479c80d176SSepherosa Ziehau if (ret_val)
14484be59a01SSepherosa Ziehau return ret_val;
14499c80d176SSepherosa Ziehau
14509c80d176SSepherosa Ziehau /* Set auto Master/Slave resolution process */
14519c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data);
14529c80d176SSepherosa Ziehau if (ret_val)
14534be59a01SSepherosa Ziehau return ret_val;
14549c80d176SSepherosa Ziehau
14559c80d176SSepherosa Ziehau data &= ~CR_1000T_MS_ENABLE;
14569c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data);
14579c80d176SSepherosa Ziehau if (ret_val)
14589c80d176SSepherosa Ziehau return ret_val;
14599c80d176SSepherosa Ziehau }
14609c80d176SSepherosa Ziehau
14614be59a01SSepherosa Ziehau ret_val = e1000_set_master_slave_mode(hw);
14629c80d176SSepherosa Ziehau }
14639c80d176SSepherosa Ziehau
14649c80d176SSepherosa Ziehau return ret_val;
14659c80d176SSepherosa Ziehau }
14669c80d176SSepherosa Ziehau
14679c80d176SSepherosa Ziehau /**
14689c80d176SSepherosa Ziehau * e1000_phy_setup_autoneg - Configure PHY for auto-negotiation
14699c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
14709c80d176SSepherosa Ziehau *
14719c80d176SSepherosa Ziehau * Reads the MII auto-neg advertisement register and/or the 1000T control
14729c80d176SSepherosa Ziehau * register and if the PHY is already setup for auto-negotiation, then
14739c80d176SSepherosa Ziehau * return successful. Otherwise, setup advertisement and flow control to
14749c80d176SSepherosa Ziehau * the appropriate values for the wanted auto-negotiation.
14759c80d176SSepherosa Ziehau **/
e1000_phy_setup_autoneg(struct e1000_hw * hw)14769c80d176SSepherosa Ziehau s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
14779c80d176SSepherosa Ziehau {
14789c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
14799c80d176SSepherosa Ziehau s32 ret_val;
14809c80d176SSepherosa Ziehau u16 mii_autoneg_adv_reg;
14819c80d176SSepherosa Ziehau u16 mii_1000t_ctrl_reg = 0;
14829c80d176SSepherosa Ziehau
14839c80d176SSepherosa Ziehau DEBUGFUNC("e1000_phy_setup_autoneg");
14849c80d176SSepherosa Ziehau
14859c80d176SSepherosa Ziehau phy->autoneg_advertised &= phy->autoneg_mask;
14869c80d176SSepherosa Ziehau
14879c80d176SSepherosa Ziehau /* Read the MII Auto-Neg Advertisement Register (Address 4). */
14889c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
14899c80d176SSepherosa Ziehau if (ret_val)
14904be59a01SSepherosa Ziehau return ret_val;
14919c80d176SSepherosa Ziehau
14929c80d176SSepherosa Ziehau if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
14939c80d176SSepherosa Ziehau /* Read the MII 1000Base-T Control Register (Address 9). */
14949c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL,
14959c80d176SSepherosa Ziehau &mii_1000t_ctrl_reg);
14969c80d176SSepherosa Ziehau if (ret_val)
14974be59a01SSepherosa Ziehau return ret_val;
14989c80d176SSepherosa Ziehau }
14999c80d176SSepherosa Ziehau
1500379ebbe7SSepherosa Ziehau /* Need to parse both autoneg_advertised and fc and set up
15019c80d176SSepherosa Ziehau * the appropriate PHY registers. First we will parse for
15029c80d176SSepherosa Ziehau * autoneg_advertised software override. Since we can advertise
15039c80d176SSepherosa Ziehau * a plethora of combinations, we need to check each bit
15049c80d176SSepherosa Ziehau * individually.
15059c80d176SSepherosa Ziehau */
15069c80d176SSepherosa Ziehau
1507379ebbe7SSepherosa Ziehau /* First we clear all the 10/100 mb speed bits in the Auto-Neg
15089c80d176SSepherosa Ziehau * Advertisement Register (Address 4) and the 1000 mb speed bits in
15099c80d176SSepherosa Ziehau * the 1000Base-T Control Register (Address 9).
15109c80d176SSepherosa Ziehau */
15119c80d176SSepherosa Ziehau mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS |
15129c80d176SSepherosa Ziehau NWAY_AR_100TX_HD_CAPS |
15139c80d176SSepherosa Ziehau NWAY_AR_10T_FD_CAPS |
15149c80d176SSepherosa Ziehau NWAY_AR_10T_HD_CAPS);
15159c80d176SSepherosa Ziehau mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
15169c80d176SSepherosa Ziehau
15179c80d176SSepherosa Ziehau DEBUGOUT1("autoneg_advertised %x\n", phy->autoneg_advertised);
15189c80d176SSepherosa Ziehau
15199c80d176SSepherosa Ziehau /* Do we want to advertise 10 Mb Half Duplex? */
15209c80d176SSepherosa Ziehau if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
15219c80d176SSepherosa Ziehau DEBUGOUT("Advertise 10mb Half duplex\n");
15229c80d176SSepherosa Ziehau mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
15239c80d176SSepherosa Ziehau }
15249c80d176SSepherosa Ziehau
15259c80d176SSepherosa Ziehau /* Do we want to advertise 10 Mb Full Duplex? */
15269c80d176SSepherosa Ziehau if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
15279c80d176SSepherosa Ziehau DEBUGOUT("Advertise 10mb Full duplex\n");
15289c80d176SSepherosa Ziehau mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
15299c80d176SSepherosa Ziehau }
15309c80d176SSepherosa Ziehau
15319c80d176SSepherosa Ziehau /* Do we want to advertise 100 Mb Half Duplex? */
15329c80d176SSepherosa Ziehau if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
15339c80d176SSepherosa Ziehau DEBUGOUT("Advertise 100mb Half duplex\n");
15349c80d176SSepherosa Ziehau mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
15359c80d176SSepherosa Ziehau }
15369c80d176SSepherosa Ziehau
15379c80d176SSepherosa Ziehau /* Do we want to advertise 100 Mb Full Duplex? */
15389c80d176SSepherosa Ziehau if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
15399c80d176SSepherosa Ziehau DEBUGOUT("Advertise 100mb Full duplex\n");
15409c80d176SSepherosa Ziehau mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
15419c80d176SSepherosa Ziehau }
15429c80d176SSepherosa Ziehau
15439c80d176SSepherosa Ziehau /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
15449c80d176SSepherosa Ziehau if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
15459c80d176SSepherosa Ziehau DEBUGOUT("Advertise 1000mb Half duplex request denied!\n");
15469c80d176SSepherosa Ziehau
15479c80d176SSepherosa Ziehau /* Do we want to advertise 1000 Mb Full Duplex? */
15489c80d176SSepherosa Ziehau if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
15499c80d176SSepherosa Ziehau DEBUGOUT("Advertise 1000mb Full duplex\n");
15509c80d176SSepherosa Ziehau mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
15519c80d176SSepherosa Ziehau }
15529c80d176SSepherosa Ziehau
1553379ebbe7SSepherosa Ziehau /* Check for a software override of the flow control settings, and
15549c80d176SSepherosa Ziehau * setup the PHY advertisement registers accordingly. If
15559c80d176SSepherosa Ziehau * auto-negotiation is enabled, then software will have to set the
15569c80d176SSepherosa Ziehau * "PAUSE" bits to the correct value in the Auto-Negotiation
15579c80d176SSepherosa Ziehau * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-
15589c80d176SSepherosa Ziehau * negotiation.
15599c80d176SSepherosa Ziehau *
15609c80d176SSepherosa Ziehau * The possible values of the "fc" parameter are:
15619c80d176SSepherosa Ziehau * 0: Flow control is completely disabled
15629c80d176SSepherosa Ziehau * 1: Rx flow control is enabled (we can receive pause frames
15639c80d176SSepherosa Ziehau * but not send pause frames).
15649c80d176SSepherosa Ziehau * 2: Tx flow control is enabled (we can send pause frames
15659c80d176SSepherosa Ziehau * but we do not support receiving pause frames).
15669c80d176SSepherosa Ziehau * 3: Both Rx and Tx flow control (symmetric) are enabled.
15679c80d176SSepherosa Ziehau * other: No software override. The flow control configuration
15689c80d176SSepherosa Ziehau * in the EEPROM is used.
15699c80d176SSepherosa Ziehau */
15709c80d176SSepherosa Ziehau switch (hw->fc.current_mode) {
15719c80d176SSepherosa Ziehau case e1000_fc_none:
1572379ebbe7SSepherosa Ziehau /* Flow control (Rx & Tx) is completely disabled by a
15739c80d176SSepherosa Ziehau * software over-ride.
15749c80d176SSepherosa Ziehau */
15759c80d176SSepherosa Ziehau mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
15769c80d176SSepherosa Ziehau break;
15779c80d176SSepherosa Ziehau case e1000_fc_rx_pause:
1578379ebbe7SSepherosa Ziehau /* Rx Flow control is enabled, and Tx Flow control is
15799c80d176SSepherosa Ziehau * disabled, by a software over-ride.
15809c80d176SSepherosa Ziehau *
15819c80d176SSepherosa Ziehau * Since there really isn't a way to advertise that we are
15829c80d176SSepherosa Ziehau * capable of Rx Pause ONLY, we will advertise that we
15839c80d176SSepherosa Ziehau * support both symmetric and asymmetric Rx PAUSE. Later
15849c80d176SSepherosa Ziehau * (in e1000_config_fc_after_link_up) we will disable the
15859c80d176SSepherosa Ziehau * hw's ability to send PAUSE frames.
15869c80d176SSepherosa Ziehau */
15879c80d176SSepherosa Ziehau mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
15889c80d176SSepherosa Ziehau break;
15899c80d176SSepherosa Ziehau case e1000_fc_tx_pause:
1590379ebbe7SSepherosa Ziehau /* Tx Flow control is enabled, and Rx Flow control is
15919c80d176SSepherosa Ziehau * disabled, by a software over-ride.
15929c80d176SSepherosa Ziehau */
15939c80d176SSepherosa Ziehau mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
15949c80d176SSepherosa Ziehau mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
15959c80d176SSepherosa Ziehau break;
15969c80d176SSepherosa Ziehau case e1000_fc_full:
1597379ebbe7SSepherosa Ziehau /* Flow control (both Rx and Tx) is enabled by a software
15989c80d176SSepherosa Ziehau * over-ride.
15999c80d176SSepherosa Ziehau */
16009c80d176SSepherosa Ziehau mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
16019c80d176SSepherosa Ziehau break;
16029c80d176SSepherosa Ziehau default:
16039c80d176SSepherosa Ziehau DEBUGOUT("Flow control param set incorrectly\n");
16044be59a01SSepherosa Ziehau return -E1000_ERR_CONFIG;
16059c80d176SSepherosa Ziehau }
16069c80d176SSepherosa Ziehau
16079c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
16089c80d176SSepherosa Ziehau if (ret_val)
16094be59a01SSepherosa Ziehau return ret_val;
16109c80d176SSepherosa Ziehau
16119c80d176SSepherosa Ziehau DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
16129c80d176SSepherosa Ziehau
16134be59a01SSepherosa Ziehau if (phy->autoneg_mask & ADVERTISE_1000_FULL)
16144be59a01SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL,
16159c80d176SSepherosa Ziehau mii_1000t_ctrl_reg);
16164be59a01SSepherosa Ziehau
16174be59a01SSepherosa Ziehau return ret_val;
16189c80d176SSepherosa Ziehau }
16199c80d176SSepherosa Ziehau
16204be59a01SSepherosa Ziehau /**
16214be59a01SSepherosa Ziehau * e1000_copper_link_autoneg - Setup/Enable autoneg for copper link
16224be59a01SSepherosa Ziehau * @hw: pointer to the HW structure
16234be59a01SSepherosa Ziehau *
16244be59a01SSepherosa Ziehau * Performs initial bounds checking on autoneg advertisement parameter, then
16254be59a01SSepherosa Ziehau * configure to advertise the full capability. Setup the PHY to autoneg
16264be59a01SSepherosa Ziehau * and restart the negotiation process between the link partner. If
16274be59a01SSepherosa Ziehau * autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
16284be59a01SSepherosa Ziehau **/
e1000_copper_link_autoneg(struct e1000_hw * hw)16294be59a01SSepherosa Ziehau s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
16304be59a01SSepherosa Ziehau {
16314be59a01SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
16324be59a01SSepherosa Ziehau s32 ret_val;
16334be59a01SSepherosa Ziehau u16 phy_ctrl;
16344be59a01SSepherosa Ziehau
16354be59a01SSepherosa Ziehau DEBUGFUNC("e1000_copper_link_autoneg");
16364be59a01SSepherosa Ziehau
1637379ebbe7SSepherosa Ziehau /* Perform some bounds checking on the autoneg advertisement
16384be59a01SSepherosa Ziehau * parameter.
16394be59a01SSepherosa Ziehau */
16404be59a01SSepherosa Ziehau phy->autoneg_advertised &= phy->autoneg_mask;
16414be59a01SSepherosa Ziehau
1642379ebbe7SSepherosa Ziehau /* If autoneg_advertised is zero, we assume it was not defaulted
16434be59a01SSepherosa Ziehau * by the calling code so we set to advertise full capability.
16444be59a01SSepherosa Ziehau */
16454be59a01SSepherosa Ziehau if (!phy->autoneg_advertised)
16464be59a01SSepherosa Ziehau phy->autoneg_advertised = phy->autoneg_mask;
16474be59a01SSepherosa Ziehau
16484be59a01SSepherosa Ziehau DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
16494be59a01SSepherosa Ziehau ret_val = e1000_phy_setup_autoneg(hw);
16504be59a01SSepherosa Ziehau if (ret_val) {
16514be59a01SSepherosa Ziehau DEBUGOUT("Error Setting up Auto-Negotiation\n");
16524be59a01SSepherosa Ziehau return ret_val;
16534be59a01SSepherosa Ziehau }
16544be59a01SSepherosa Ziehau DEBUGOUT("Restarting Auto-Neg\n");
16554be59a01SSepherosa Ziehau
1656379ebbe7SSepherosa Ziehau /* Restart auto-negotiation by setting the Auto Neg Enable bit and
16574be59a01SSepherosa Ziehau * the Auto Neg Restart bit in the PHY control register.
16584be59a01SSepherosa Ziehau */
16594be59a01SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
16604be59a01SSepherosa Ziehau if (ret_val)
16614be59a01SSepherosa Ziehau return ret_val;
16624be59a01SSepherosa Ziehau
16634be59a01SSepherosa Ziehau phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
16644be59a01SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
16654be59a01SSepherosa Ziehau if (ret_val)
16664be59a01SSepherosa Ziehau return ret_val;
16674be59a01SSepherosa Ziehau
1668379ebbe7SSepherosa Ziehau /* Does the user want to wait for Auto-Neg to complete here, or
16694be59a01SSepherosa Ziehau * check at a later time (for example, callback routine).
16704be59a01SSepherosa Ziehau */
16714be59a01SSepherosa Ziehau if (phy->autoneg_wait_to_complete) {
1672379ebbe7SSepherosa Ziehau ret_val = e1000_wait_autoneg(hw);
16734be59a01SSepherosa Ziehau if (ret_val) {
16744be59a01SSepherosa Ziehau DEBUGOUT("Error while waiting for autoneg to complete\n");
16754be59a01SSepherosa Ziehau return ret_val;
16764be59a01SSepherosa Ziehau }
16774be59a01SSepherosa Ziehau }
16784be59a01SSepherosa Ziehau
16794be59a01SSepherosa Ziehau hw->mac.get_link_status = TRUE;
16804be59a01SSepherosa Ziehau
16819c80d176SSepherosa Ziehau return ret_val;
16829c80d176SSepherosa Ziehau }
16839c80d176SSepherosa Ziehau
16849c80d176SSepherosa Ziehau /**
16859c80d176SSepherosa Ziehau * e1000_setup_copper_link_generic - Configure copper link settings
16869c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
16879c80d176SSepherosa Ziehau *
16889c80d176SSepherosa Ziehau * Calls the appropriate function to configure the link for auto-neg or forced
16899c80d176SSepherosa Ziehau * speed and duplex. Then we check for link, once link is established calls
16909c80d176SSepherosa Ziehau * to configure collision distance and flow control are called. If link is
16919c80d176SSepherosa Ziehau * not established, we return -E1000_ERR_PHY (-2).
16929c80d176SSepherosa Ziehau **/
e1000_setup_copper_link_generic(struct e1000_hw * hw)16939c80d176SSepherosa Ziehau s32 e1000_setup_copper_link_generic(struct e1000_hw *hw)
16949c80d176SSepherosa Ziehau {
16959c80d176SSepherosa Ziehau s32 ret_val;
16969c80d176SSepherosa Ziehau bool link;
16979c80d176SSepherosa Ziehau
16989c80d176SSepherosa Ziehau DEBUGFUNC("e1000_setup_copper_link_generic");
16999c80d176SSepherosa Ziehau
17009c80d176SSepherosa Ziehau if (hw->mac.autoneg) {
1701379ebbe7SSepherosa Ziehau /* Setup autoneg and flow control advertisement and perform
17029c80d176SSepherosa Ziehau * autonegotiation.
17039c80d176SSepherosa Ziehau */
17049c80d176SSepherosa Ziehau ret_val = e1000_copper_link_autoneg(hw);
17059c80d176SSepherosa Ziehau if (ret_val)
17064be59a01SSepherosa Ziehau return ret_val;
17079c80d176SSepherosa Ziehau } else {
1708379ebbe7SSepherosa Ziehau /* PHY will be set to 10H, 10F, 100H or 100F
17099c80d176SSepherosa Ziehau * depending on user settings.
17109c80d176SSepherosa Ziehau */
17119c80d176SSepherosa Ziehau DEBUGOUT("Forcing Speed and Duplex\n");
17129c80d176SSepherosa Ziehau ret_val = hw->phy.ops.force_speed_duplex(hw);
17139c80d176SSepherosa Ziehau if (ret_val) {
17149c80d176SSepherosa Ziehau DEBUGOUT("Error Forcing Speed and Duplex\n");
17154be59a01SSepherosa Ziehau return ret_val;
17169c80d176SSepherosa Ziehau }
17179c80d176SSepherosa Ziehau }
17189c80d176SSepherosa Ziehau
1719379ebbe7SSepherosa Ziehau /* Check link status. Wait up to 100 microseconds for link to become
17209c80d176SSepherosa Ziehau * valid.
17219c80d176SSepherosa Ziehau */
17224be59a01SSepherosa Ziehau ret_val = e1000_phy_has_link_generic(hw, COPPER_LINK_UP_LIMIT, 10,
17239c80d176SSepherosa Ziehau &link);
17249c80d176SSepherosa Ziehau if (ret_val)
17254be59a01SSepherosa Ziehau return ret_val;
17269c80d176SSepherosa Ziehau
17279c80d176SSepherosa Ziehau if (link) {
17289c80d176SSepherosa Ziehau DEBUGOUT("Valid link established!!!\n");
17294be59a01SSepherosa Ziehau hw->mac.ops.config_collision_dist(hw);
17309c80d176SSepherosa Ziehau ret_val = e1000_config_fc_after_link_up_generic(hw);
17319c80d176SSepherosa Ziehau } else {
17329c80d176SSepherosa Ziehau DEBUGOUT("Unable to establish link!!!\n");
17339c80d176SSepherosa Ziehau }
17349c80d176SSepherosa Ziehau
17359c80d176SSepherosa Ziehau return ret_val;
17369c80d176SSepherosa Ziehau }
17379c80d176SSepherosa Ziehau
17389c80d176SSepherosa Ziehau /**
17399c80d176SSepherosa Ziehau * e1000_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY
17409c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
17419c80d176SSepherosa Ziehau *
17429c80d176SSepherosa Ziehau * Calls the PHY setup function to force speed and duplex. Clears the
17439c80d176SSepherosa Ziehau * auto-crossover to force MDI manually. Waits for link and returns
17449c80d176SSepherosa Ziehau * successful if link up is successful, else -E1000_ERR_PHY (-2).
17459c80d176SSepherosa Ziehau **/
e1000_phy_force_speed_duplex_igp(struct e1000_hw * hw)17469c80d176SSepherosa Ziehau s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw)
17479c80d176SSepherosa Ziehau {
17489c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
17499c80d176SSepherosa Ziehau s32 ret_val;
17509c80d176SSepherosa Ziehau u16 phy_data;
17519c80d176SSepherosa Ziehau bool link;
17529c80d176SSepherosa Ziehau
17539c80d176SSepherosa Ziehau DEBUGFUNC("e1000_phy_force_speed_duplex_igp");
17549c80d176SSepherosa Ziehau
17559c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
17569c80d176SSepherosa Ziehau if (ret_val)
17574be59a01SSepherosa Ziehau return ret_val;
17589c80d176SSepherosa Ziehau
17599c80d176SSepherosa Ziehau e1000_phy_force_speed_duplex_setup(hw, &phy_data);
17609c80d176SSepherosa Ziehau
17619c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
17629c80d176SSepherosa Ziehau if (ret_val)
17634be59a01SSepherosa Ziehau return ret_val;
17649c80d176SSepherosa Ziehau
1765379ebbe7SSepherosa Ziehau /* Clear Auto-Crossover to force MDI manually. IGP requires MDI
17669c80d176SSepherosa Ziehau * forced whenever speed and duplex are forced.
17679c80d176SSepherosa Ziehau */
17689c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
17699c80d176SSepherosa Ziehau if (ret_val)
17704be59a01SSepherosa Ziehau return ret_val;
17719c80d176SSepherosa Ziehau
17729c80d176SSepherosa Ziehau phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
17739c80d176SSepherosa Ziehau phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
17749c80d176SSepherosa Ziehau
17759c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
17769c80d176SSepherosa Ziehau if (ret_val)
17774be59a01SSepherosa Ziehau return ret_val;
17789c80d176SSepherosa Ziehau
17799c80d176SSepherosa Ziehau DEBUGOUT1("IGP PSCR: %X\n", phy_data);
17809c80d176SSepherosa Ziehau
17819c80d176SSepherosa Ziehau usec_delay(1);
17829c80d176SSepherosa Ziehau
17839c80d176SSepherosa Ziehau if (phy->autoneg_wait_to_complete) {
17849c80d176SSepherosa Ziehau DEBUGOUT("Waiting for forced speed/duplex link on IGP phy.\n");
17859c80d176SSepherosa Ziehau
17864be59a01SSepherosa Ziehau ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
17874be59a01SSepherosa Ziehau 100000, &link);
17889c80d176SSepherosa Ziehau if (ret_val)
17894be59a01SSepherosa Ziehau return ret_val;
17909c80d176SSepherosa Ziehau
17919c80d176SSepherosa Ziehau if (!link)
17929c80d176SSepherosa Ziehau DEBUGOUT("Link taking longer than expected.\n");
17939c80d176SSepherosa Ziehau
17949c80d176SSepherosa Ziehau /* Try once more */
17954be59a01SSepherosa Ziehau ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
17964be59a01SSepherosa Ziehau 100000, &link);
17979c80d176SSepherosa Ziehau }
17989c80d176SSepherosa Ziehau
17999c80d176SSepherosa Ziehau return ret_val;
18009c80d176SSepherosa Ziehau }
18019c80d176SSepherosa Ziehau
18029c80d176SSepherosa Ziehau /**
18039c80d176SSepherosa Ziehau * e1000_phy_force_speed_duplex_m88 - Force speed/duplex for m88 PHY
18049c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
18059c80d176SSepherosa Ziehau *
18069c80d176SSepherosa Ziehau * Calls the PHY setup function to force speed and duplex. Clears the
18079c80d176SSepherosa Ziehau * auto-crossover to force MDI manually. Resets the PHY to commit the
18089c80d176SSepherosa Ziehau * changes. If time expires while waiting for link up, we reset the DSP.
18099c80d176SSepherosa Ziehau * After reset, TX_CLK and CRS on Tx must be set. Return successful upon
18109c80d176SSepherosa Ziehau * successful completion, else return corresponding error code.
18119c80d176SSepherosa Ziehau **/
e1000_phy_force_speed_duplex_m88(struct e1000_hw * hw)18129c80d176SSepherosa Ziehau s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
18139c80d176SSepherosa Ziehau {
18149c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
18159c80d176SSepherosa Ziehau s32 ret_val;
18169c80d176SSepherosa Ziehau u16 phy_data;
18179c80d176SSepherosa Ziehau bool link;
18189c80d176SSepherosa Ziehau
18199c80d176SSepherosa Ziehau DEBUGFUNC("e1000_phy_force_speed_duplex_m88");
18209c80d176SSepherosa Ziehau
18214be59a01SSepherosa Ziehau /* I210 and I211 devices support Auto-Crossover in forced operation. */
18224be59a01SSepherosa Ziehau if (phy->type != e1000_phy_i210) {
1823379ebbe7SSepherosa Ziehau /* Clear Auto-Crossover to force MDI manually. M88E1000
18244be59a01SSepherosa Ziehau * requires MDI forced whenever speed and duplex are forced.
18259c80d176SSepherosa Ziehau */
18264be59a01SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL,
18274be59a01SSepherosa Ziehau &phy_data);
18289c80d176SSepherosa Ziehau if (ret_val)
18294be59a01SSepherosa Ziehau return ret_val;
18309c80d176SSepherosa Ziehau
18319c80d176SSepherosa Ziehau phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
18324be59a01SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL,
18334be59a01SSepherosa Ziehau phy_data);
18349c80d176SSepherosa Ziehau if (ret_val)
18354be59a01SSepherosa Ziehau return ret_val;
18369c80d176SSepherosa Ziehau
18379c80d176SSepherosa Ziehau DEBUGOUT1("M88E1000 PSCR: %X\n", phy_data);
1838a40fda39SSepherosa Ziehau }
18399c80d176SSepherosa Ziehau
18409c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
18419c80d176SSepherosa Ziehau if (ret_val)
18424be59a01SSepherosa Ziehau return ret_val;
18439c80d176SSepherosa Ziehau
18449c80d176SSepherosa Ziehau e1000_phy_force_speed_duplex_setup(hw, &phy_data);
18459c80d176SSepherosa Ziehau
18469c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
18479c80d176SSepherosa Ziehau if (ret_val)
18484be59a01SSepherosa Ziehau return ret_val;
18499c80d176SSepherosa Ziehau
18509c80d176SSepherosa Ziehau /* Reset the phy to commit changes. */
18519c80d176SSepherosa Ziehau ret_val = hw->phy.ops.commit(hw);
18529c80d176SSepherosa Ziehau if (ret_val)
18534be59a01SSepherosa Ziehau return ret_val;
18549c80d176SSepherosa Ziehau
18559c80d176SSepherosa Ziehau if (phy->autoneg_wait_to_complete) {
18569c80d176SSepherosa Ziehau DEBUGOUT("Waiting for forced speed/duplex link on M88 phy.\n");
18579c80d176SSepherosa Ziehau
18589c80d176SSepherosa Ziehau ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
18599c80d176SSepherosa Ziehau 100000, &link);
18609c80d176SSepherosa Ziehau if (ret_val)
18614be59a01SSepherosa Ziehau return ret_val;
18629c80d176SSepherosa Ziehau
18639c80d176SSepherosa Ziehau if (!link) {
18644be59a01SSepherosa Ziehau bool reset_dsp = TRUE;
18654be59a01SSepherosa Ziehau
18664be59a01SSepherosa Ziehau switch (hw->phy.id) {
18674be59a01SSepherosa Ziehau case I347AT4_E_PHY_ID:
18684be59a01SSepherosa Ziehau case M88E1340M_E_PHY_ID:
18694be59a01SSepherosa Ziehau case M88E1112_E_PHY_ID:
1870ba0123e0SSepherosa Ziehau case M88E1543_E_PHY_ID:
1871ba0123e0SSepherosa Ziehau case M88E1512_E_PHY_ID:
18724be59a01SSepherosa Ziehau case I210_I_PHY_ID:
18734be59a01SSepherosa Ziehau reset_dsp = FALSE;
18744be59a01SSepherosa Ziehau break;
18754be59a01SSepherosa Ziehau default:
18764be59a01SSepherosa Ziehau if (hw->phy.type != e1000_phy_m88)
18774be59a01SSepherosa Ziehau reset_dsp = FALSE;
18784be59a01SSepherosa Ziehau break;
18794be59a01SSepherosa Ziehau }
18804be59a01SSepherosa Ziehau
18814be59a01SSepherosa Ziehau if (!reset_dsp) {
18826a5a645eSSepherosa Ziehau DEBUGOUT("Link taking longer than expected.\n");
18836a5a645eSSepherosa Ziehau } else {
1884379ebbe7SSepherosa Ziehau /* We didn't get link.
18859c80d176SSepherosa Ziehau * Reset the DSP and cross our fingers.
18869c80d176SSepherosa Ziehau */
18879c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw,
18889c80d176SSepherosa Ziehau M88E1000_PHY_PAGE_SELECT,
18899c80d176SSepherosa Ziehau 0x001d);
18909c80d176SSepherosa Ziehau if (ret_val)
18914be59a01SSepherosa Ziehau return ret_val;
18929c80d176SSepherosa Ziehau ret_val = e1000_phy_reset_dsp_generic(hw);
18939c80d176SSepherosa Ziehau if (ret_val)
18944be59a01SSepherosa Ziehau return ret_val;
18959c80d176SSepherosa Ziehau }
18966a5a645eSSepherosa Ziehau }
18979c80d176SSepherosa Ziehau
18989c80d176SSepherosa Ziehau /* Try once more */
18999c80d176SSepherosa Ziehau ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
19009c80d176SSepherosa Ziehau 100000, &link);
19019c80d176SSepherosa Ziehau if (ret_val)
19024be59a01SSepherosa Ziehau return ret_val;
19039c80d176SSepherosa Ziehau }
19049c80d176SSepherosa Ziehau
19054be59a01SSepherosa Ziehau if (hw->phy.type != e1000_phy_m88)
19064be59a01SSepherosa Ziehau return E1000_SUCCESS;
19074be59a01SSepherosa Ziehau
19084be59a01SSepherosa Ziehau if (hw->phy.id == I347AT4_E_PHY_ID ||
190962583d18SSepherosa Ziehau hw->phy.id == M88E1340M_E_PHY_ID ||
191062583d18SSepherosa Ziehau hw->phy.id == M88E1112_E_PHY_ID)
19114be59a01SSepherosa Ziehau return E1000_SUCCESS;
19124be59a01SSepherosa Ziehau if (hw->phy.id == I210_I_PHY_ID)
19134be59a01SSepherosa Ziehau return E1000_SUCCESS;
1914ba0123e0SSepherosa Ziehau if ((hw->phy.id == M88E1543_E_PHY_ID) ||
1915ba0123e0SSepherosa Ziehau (hw->phy.id == M88E1512_E_PHY_ID))
1916379ebbe7SSepherosa Ziehau return E1000_SUCCESS;
19179c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
19189c80d176SSepherosa Ziehau if (ret_val)
19194be59a01SSepherosa Ziehau return ret_val;
19209c80d176SSepherosa Ziehau
1921379ebbe7SSepherosa Ziehau /* Resetting the phy means we need to re-force TX_CLK in the
19229c80d176SSepherosa Ziehau * Extended PHY Specific Control Register to 25MHz clock from
19239c80d176SSepherosa Ziehau * the reset value of 2.5MHz.
19249c80d176SSepherosa Ziehau */
19259c80d176SSepherosa Ziehau phy_data |= M88E1000_EPSCR_TX_CLK_25;
19269c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
19279c80d176SSepherosa Ziehau if (ret_val)
19284be59a01SSepherosa Ziehau return ret_val;
19299c80d176SSepherosa Ziehau
1930379ebbe7SSepherosa Ziehau /* In addition, we must re-enable CRS on Tx for both half and full
19319c80d176SSepherosa Ziehau * duplex.
19329c80d176SSepherosa Ziehau */
19339c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
19349c80d176SSepherosa Ziehau if (ret_val)
19354be59a01SSepherosa Ziehau return ret_val;
19369c80d176SSepherosa Ziehau
19379c80d176SSepherosa Ziehau phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
19389c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
19399c80d176SSepherosa Ziehau
19409c80d176SSepherosa Ziehau return ret_val;
19419c80d176SSepherosa Ziehau }
19429c80d176SSepherosa Ziehau
19439c80d176SSepherosa Ziehau /**
19446a5a645eSSepherosa Ziehau * e1000_phy_force_speed_duplex_ife - Force PHY speed & duplex
19456a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
19466a5a645eSSepherosa Ziehau *
19476a5a645eSSepherosa Ziehau * Forces the speed and duplex settings of the PHY.
19486a5a645eSSepherosa Ziehau * This is a function pointer entry point only called by
19496a5a645eSSepherosa Ziehau * PHY setup routines.
19506a5a645eSSepherosa Ziehau **/
e1000_phy_force_speed_duplex_ife(struct e1000_hw * hw)19516a5a645eSSepherosa Ziehau s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw)
19526a5a645eSSepherosa Ziehau {
19536a5a645eSSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
19546a5a645eSSepherosa Ziehau s32 ret_val;
19556a5a645eSSepherosa Ziehau u16 data;
19566a5a645eSSepherosa Ziehau bool link;
19576a5a645eSSepherosa Ziehau
19586a5a645eSSepherosa Ziehau DEBUGFUNC("e1000_phy_force_speed_duplex_ife");
19596a5a645eSSepherosa Ziehau
19606a5a645eSSepherosa Ziehau ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &data);
19616a5a645eSSepherosa Ziehau if (ret_val)
19624be59a01SSepherosa Ziehau return ret_val;
19636a5a645eSSepherosa Ziehau
19646a5a645eSSepherosa Ziehau e1000_phy_force_speed_duplex_setup(hw, &data);
19656a5a645eSSepherosa Ziehau
19666a5a645eSSepherosa Ziehau ret_val = phy->ops.write_reg(hw, PHY_CONTROL, data);
19676a5a645eSSepherosa Ziehau if (ret_val)
19684be59a01SSepherosa Ziehau return ret_val;
19696a5a645eSSepherosa Ziehau
19706a5a645eSSepherosa Ziehau /* Disable MDI-X support for 10/100 */
19716a5a645eSSepherosa Ziehau ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data);
19726a5a645eSSepherosa Ziehau if (ret_val)
19734be59a01SSepherosa Ziehau return ret_val;
19746a5a645eSSepherosa Ziehau
19756a5a645eSSepherosa Ziehau data &= ~IFE_PMC_AUTO_MDIX;
19766a5a645eSSepherosa Ziehau data &= ~IFE_PMC_FORCE_MDIX;
19776a5a645eSSepherosa Ziehau
19786a5a645eSSepherosa Ziehau ret_val = phy->ops.write_reg(hw, IFE_PHY_MDIX_CONTROL, data);
19796a5a645eSSepherosa Ziehau if (ret_val)
19804be59a01SSepherosa Ziehau return ret_val;
19816a5a645eSSepherosa Ziehau
19826a5a645eSSepherosa Ziehau DEBUGOUT1("IFE PMC: %X\n", data);
19836a5a645eSSepherosa Ziehau
19846a5a645eSSepherosa Ziehau usec_delay(1);
19856a5a645eSSepherosa Ziehau
19866a5a645eSSepherosa Ziehau if (phy->autoneg_wait_to_complete) {
19876a5a645eSSepherosa Ziehau DEBUGOUT("Waiting for forced speed/duplex link on IFE phy.\n");
19886a5a645eSSepherosa Ziehau
19894be59a01SSepherosa Ziehau ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
19904be59a01SSepherosa Ziehau 100000, &link);
19916a5a645eSSepherosa Ziehau if (ret_val)
19924be59a01SSepherosa Ziehau return ret_val;
19936a5a645eSSepherosa Ziehau
19946a5a645eSSepherosa Ziehau if (!link)
19956a5a645eSSepherosa Ziehau DEBUGOUT("Link taking longer than expected.\n");
19966a5a645eSSepherosa Ziehau
19976a5a645eSSepherosa Ziehau /* Try once more */
19984be59a01SSepherosa Ziehau ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
19994be59a01SSepherosa Ziehau 100000, &link);
20006a5a645eSSepherosa Ziehau if (ret_val)
20014be59a01SSepherosa Ziehau return ret_val;
20026a5a645eSSepherosa Ziehau }
20036a5a645eSSepherosa Ziehau
20044be59a01SSepherosa Ziehau return E1000_SUCCESS;
20056a5a645eSSepherosa Ziehau }
20066a5a645eSSepherosa Ziehau
20076a5a645eSSepherosa Ziehau /**
20089c80d176SSepherosa Ziehau * e1000_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
20099c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
20109c80d176SSepherosa Ziehau * @phy_ctrl: pointer to current value of PHY_CONTROL
20119c80d176SSepherosa Ziehau *
20129c80d176SSepherosa Ziehau * Forces speed and duplex on the PHY by doing the following: disable flow
20139c80d176SSepherosa Ziehau * control, force speed/duplex on the MAC, disable auto speed detection,
20149c80d176SSepherosa Ziehau * disable auto-negotiation, configure duplex, configure speed, configure
20159c80d176SSepherosa Ziehau * the collision distance, write configuration to CTRL register. The
20169c80d176SSepherosa Ziehau * caller must write to the PHY_CONTROL register for these settings to
20179c80d176SSepherosa Ziehau * take affect.
20189c80d176SSepherosa Ziehau **/
e1000_phy_force_speed_duplex_setup(struct e1000_hw * hw,u16 * phy_ctrl)20199c80d176SSepherosa Ziehau void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl)
20209c80d176SSepherosa Ziehau {
20219c80d176SSepherosa Ziehau struct e1000_mac_info *mac = &hw->mac;
20229c80d176SSepherosa Ziehau u32 ctrl;
20239c80d176SSepherosa Ziehau
20249c80d176SSepherosa Ziehau DEBUGFUNC("e1000_phy_force_speed_duplex_setup");
20259c80d176SSepherosa Ziehau
20269c80d176SSepherosa Ziehau /* Turn off flow control when forcing speed/duplex */
20279c80d176SSepherosa Ziehau hw->fc.current_mode = e1000_fc_none;
20289c80d176SSepherosa Ziehau
20299c80d176SSepherosa Ziehau /* Force speed/duplex on the mac */
20309c80d176SSepherosa Ziehau ctrl = E1000_READ_REG(hw, E1000_CTRL);
20319c80d176SSepherosa Ziehau ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
20329c80d176SSepherosa Ziehau ctrl &= ~E1000_CTRL_SPD_SEL;
20339c80d176SSepherosa Ziehau
20349c80d176SSepherosa Ziehau /* Disable Auto Speed Detection */
20359c80d176SSepherosa Ziehau ctrl &= ~E1000_CTRL_ASDE;
20369c80d176SSepherosa Ziehau
20379c80d176SSepherosa Ziehau /* Disable autoneg on the phy */
20389c80d176SSepherosa Ziehau *phy_ctrl &= ~MII_CR_AUTO_NEG_EN;
20399c80d176SSepherosa Ziehau
20409c80d176SSepherosa Ziehau /* Forcing Full or Half Duplex? */
20419c80d176SSepherosa Ziehau if (mac->forced_speed_duplex & E1000_ALL_HALF_DUPLEX) {
20429c80d176SSepherosa Ziehau ctrl &= ~E1000_CTRL_FD;
20439c80d176SSepherosa Ziehau *phy_ctrl &= ~MII_CR_FULL_DUPLEX;
20449c80d176SSepherosa Ziehau DEBUGOUT("Half Duplex\n");
20459c80d176SSepherosa Ziehau } else {
20469c80d176SSepherosa Ziehau ctrl |= E1000_CTRL_FD;
20479c80d176SSepherosa Ziehau *phy_ctrl |= MII_CR_FULL_DUPLEX;
20489c80d176SSepherosa Ziehau DEBUGOUT("Full Duplex\n");
20499c80d176SSepherosa Ziehau }
20509c80d176SSepherosa Ziehau
20519c80d176SSepherosa Ziehau /* Forcing 10mb or 100mb? */
20529c80d176SSepherosa Ziehau if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) {
20539c80d176SSepherosa Ziehau ctrl |= E1000_CTRL_SPD_100;
20549c80d176SSepherosa Ziehau *phy_ctrl |= MII_CR_SPEED_100;
2055379ebbe7SSepherosa Ziehau *phy_ctrl &= ~MII_CR_SPEED_1000;
20569c80d176SSepherosa Ziehau DEBUGOUT("Forcing 100mb\n");
20579c80d176SSepherosa Ziehau } else {
20589c80d176SSepherosa Ziehau ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
20599c80d176SSepherosa Ziehau *phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
20609c80d176SSepherosa Ziehau DEBUGOUT("Forcing 10mb\n");
20619c80d176SSepherosa Ziehau }
20629c80d176SSepherosa Ziehau
20634be59a01SSepherosa Ziehau hw->mac.ops.config_collision_dist(hw);
20649c80d176SSepherosa Ziehau
20659c80d176SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
20669c80d176SSepherosa Ziehau }
20679c80d176SSepherosa Ziehau
20689c80d176SSepherosa Ziehau /**
20699c80d176SSepherosa Ziehau * e1000_set_d3_lplu_state_generic - Sets low power link up state for D3
20709c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
20719c80d176SSepherosa Ziehau * @active: boolean used to enable/disable lplu
20729c80d176SSepherosa Ziehau *
20739c80d176SSepherosa Ziehau * Success returns 0, Failure returns 1
20749c80d176SSepherosa Ziehau *
20759c80d176SSepherosa Ziehau * The low power link up (lplu) state is set to the power management level D3
20769c80d176SSepherosa Ziehau * and SmartSpeed is disabled when active is TRUE, else clear lplu for D3
20779c80d176SSepherosa Ziehau * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU
20789c80d176SSepherosa Ziehau * is used during Dx states where the power conservation is most important.
20799c80d176SSepherosa Ziehau * During driver activity, SmartSpeed should be enabled so performance is
20809c80d176SSepherosa Ziehau * maintained.
20819c80d176SSepherosa Ziehau **/
e1000_set_d3_lplu_state_generic(struct e1000_hw * hw,bool active)20829c80d176SSepherosa Ziehau s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active)
20839c80d176SSepherosa Ziehau {
20849c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
20854be59a01SSepherosa Ziehau s32 ret_val;
20869c80d176SSepherosa Ziehau u16 data;
20879c80d176SSepherosa Ziehau
20889c80d176SSepherosa Ziehau DEBUGFUNC("e1000_set_d3_lplu_state_generic");
20899c80d176SSepherosa Ziehau
20904be59a01SSepherosa Ziehau if (!hw->phy.ops.read_reg)
20914be59a01SSepherosa Ziehau return E1000_SUCCESS;
20929c80d176SSepherosa Ziehau
20939c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
20949c80d176SSepherosa Ziehau if (ret_val)
20954be59a01SSepherosa Ziehau return ret_val;
20969c80d176SSepherosa Ziehau
20979c80d176SSepherosa Ziehau if (!active) {
20989c80d176SSepherosa Ziehau data &= ~IGP02E1000_PM_D3_LPLU;
20999c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
21009c80d176SSepherosa Ziehau data);
21019c80d176SSepherosa Ziehau if (ret_val)
21024be59a01SSepherosa Ziehau return ret_val;
2103379ebbe7SSepherosa Ziehau /* LPLU and SmartSpeed are mutually exclusive. LPLU is used
21049c80d176SSepherosa Ziehau * during Dx states where the power conservation is most
21059c80d176SSepherosa Ziehau * important. During driver activity we should enable
21069c80d176SSepherosa Ziehau * SmartSpeed, so performance is maintained.
21079c80d176SSepherosa Ziehau */
21089c80d176SSepherosa Ziehau if (phy->smart_speed == e1000_smart_speed_on) {
21099c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw,
21109c80d176SSepherosa Ziehau IGP01E1000_PHY_PORT_CONFIG,
21119c80d176SSepherosa Ziehau &data);
21129c80d176SSepherosa Ziehau if (ret_val)
21134be59a01SSepherosa Ziehau return ret_val;
21149c80d176SSepherosa Ziehau
21159c80d176SSepherosa Ziehau data |= IGP01E1000_PSCFR_SMART_SPEED;
21169c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw,
21179c80d176SSepherosa Ziehau IGP01E1000_PHY_PORT_CONFIG,
21189c80d176SSepherosa Ziehau data);
21199c80d176SSepherosa Ziehau if (ret_val)
21204be59a01SSepherosa Ziehau return ret_val;
21219c80d176SSepherosa Ziehau } else if (phy->smart_speed == e1000_smart_speed_off) {
21229c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw,
21239c80d176SSepherosa Ziehau IGP01E1000_PHY_PORT_CONFIG,
21249c80d176SSepherosa Ziehau &data);
21259c80d176SSepherosa Ziehau if (ret_val)
21264be59a01SSepherosa Ziehau return ret_val;
21279c80d176SSepherosa Ziehau
21289c80d176SSepherosa Ziehau data &= ~IGP01E1000_PSCFR_SMART_SPEED;
21299c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw,
21309c80d176SSepherosa Ziehau IGP01E1000_PHY_PORT_CONFIG,
21319c80d176SSepherosa Ziehau data);
21329c80d176SSepherosa Ziehau if (ret_val)
21334be59a01SSepherosa Ziehau return ret_val;
21349c80d176SSepherosa Ziehau }
21359c80d176SSepherosa Ziehau } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
21369c80d176SSepherosa Ziehau (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
21379c80d176SSepherosa Ziehau (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
21389c80d176SSepherosa Ziehau data |= IGP02E1000_PM_D3_LPLU;
21399c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
21409c80d176SSepherosa Ziehau data);
21419c80d176SSepherosa Ziehau if (ret_val)
21424be59a01SSepherosa Ziehau return ret_val;
21439c80d176SSepherosa Ziehau
21449c80d176SSepherosa Ziehau /* When LPLU is enabled, we should disable SmartSpeed */
21459c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
21469c80d176SSepherosa Ziehau &data);
21479c80d176SSepherosa Ziehau if (ret_val)
21484be59a01SSepherosa Ziehau return ret_val;
21499c80d176SSepherosa Ziehau
21509c80d176SSepherosa Ziehau data &= ~IGP01E1000_PSCFR_SMART_SPEED;
21519c80d176SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
21529c80d176SSepherosa Ziehau data);
21539c80d176SSepherosa Ziehau }
21549c80d176SSepherosa Ziehau
21559c80d176SSepherosa Ziehau return ret_val;
21569c80d176SSepherosa Ziehau }
21579c80d176SSepherosa Ziehau
21589c80d176SSepherosa Ziehau /**
21599c80d176SSepherosa Ziehau * e1000_check_downshift_generic - Checks whether a downshift in speed occurred
21609c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
21619c80d176SSepherosa Ziehau *
21629c80d176SSepherosa Ziehau * Success returns 0, Failure returns 1
21639c80d176SSepherosa Ziehau *
21649c80d176SSepherosa Ziehau * A downshift is detected by querying the PHY link health.
21659c80d176SSepherosa Ziehau **/
e1000_check_downshift_generic(struct e1000_hw * hw)21669c80d176SSepherosa Ziehau s32 e1000_check_downshift_generic(struct e1000_hw *hw)
21679c80d176SSepherosa Ziehau {
21689c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
21699c80d176SSepherosa Ziehau s32 ret_val;
21709c80d176SSepherosa Ziehau u16 phy_data, offset, mask;
21719c80d176SSepherosa Ziehau
21729c80d176SSepherosa Ziehau DEBUGFUNC("e1000_check_downshift_generic");
21739c80d176SSepherosa Ziehau
21749c80d176SSepherosa Ziehau switch (phy->type) {
21754be59a01SSepherosa Ziehau case e1000_phy_i210:
21769c80d176SSepherosa Ziehau case e1000_phy_m88:
21779c80d176SSepherosa Ziehau case e1000_phy_gg82563:
21789c80d176SSepherosa Ziehau case e1000_phy_bm:
21796a5a645eSSepherosa Ziehau case e1000_phy_82578:
21809c80d176SSepherosa Ziehau offset = M88E1000_PHY_SPEC_STATUS;
21819c80d176SSepherosa Ziehau mask = M88E1000_PSSR_DOWNSHIFT;
21829c80d176SSepherosa Ziehau break;
21839c80d176SSepherosa Ziehau case e1000_phy_igp:
21846a5a645eSSepherosa Ziehau case e1000_phy_igp_2:
21859c80d176SSepherosa Ziehau case e1000_phy_igp_3:
21869c80d176SSepherosa Ziehau offset = IGP01E1000_PHY_LINK_HEALTH;
21879c80d176SSepherosa Ziehau mask = IGP01E1000_PLHR_SS_DOWNGRADE;
21889c80d176SSepherosa Ziehau break;
21899c80d176SSepherosa Ziehau default:
21909c80d176SSepherosa Ziehau /* speed downshift not supported */
21919c80d176SSepherosa Ziehau phy->speed_downgraded = FALSE;
21924be59a01SSepherosa Ziehau return E1000_SUCCESS;
21939c80d176SSepherosa Ziehau }
21949c80d176SSepherosa Ziehau
21959c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, offset, &phy_data);
21969c80d176SSepherosa Ziehau
21979c80d176SSepherosa Ziehau if (!ret_val)
21984be59a01SSepherosa Ziehau phy->speed_downgraded = !!(phy_data & mask);
21999c80d176SSepherosa Ziehau
22009c80d176SSepherosa Ziehau return ret_val;
22019c80d176SSepherosa Ziehau }
22029c80d176SSepherosa Ziehau
22039c80d176SSepherosa Ziehau /**
22049c80d176SSepherosa Ziehau * e1000_check_polarity_m88 - Checks the polarity.
22059c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
22069c80d176SSepherosa Ziehau *
22079c80d176SSepherosa Ziehau * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
22089c80d176SSepherosa Ziehau *
22099c80d176SSepherosa Ziehau * Polarity is determined based on the PHY specific status register.
22109c80d176SSepherosa Ziehau **/
e1000_check_polarity_m88(struct e1000_hw * hw)22119c80d176SSepherosa Ziehau s32 e1000_check_polarity_m88(struct e1000_hw *hw)
22129c80d176SSepherosa Ziehau {
22139c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
22149c80d176SSepherosa Ziehau s32 ret_val;
22159c80d176SSepherosa Ziehau u16 data;
22169c80d176SSepherosa Ziehau
22179c80d176SSepherosa Ziehau DEBUGFUNC("e1000_check_polarity_m88");
22189c80d176SSepherosa Ziehau
22199c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
22209c80d176SSepherosa Ziehau
22219c80d176SSepherosa Ziehau if (!ret_val)
2222379ebbe7SSepherosa Ziehau phy->cable_polarity = ((data & M88E1000_PSSR_REV_POLARITY)
22239c80d176SSepherosa Ziehau ? e1000_rev_polarity_reversed
2224379ebbe7SSepherosa Ziehau : e1000_rev_polarity_normal);
22259c80d176SSepherosa Ziehau
22269c80d176SSepherosa Ziehau return ret_val;
22279c80d176SSepherosa Ziehau }
22289c80d176SSepherosa Ziehau
22299c80d176SSepherosa Ziehau /**
22309c80d176SSepherosa Ziehau * e1000_check_polarity_igp - Checks the polarity.
22319c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
22329c80d176SSepherosa Ziehau *
22339c80d176SSepherosa Ziehau * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
22349c80d176SSepherosa Ziehau *
22359c80d176SSepherosa Ziehau * Polarity is determined based on the PHY port status register, and the
22369c80d176SSepherosa Ziehau * current speed (since there is no polarity at 100Mbps).
22379c80d176SSepherosa Ziehau **/
e1000_check_polarity_igp(struct e1000_hw * hw)22389c80d176SSepherosa Ziehau s32 e1000_check_polarity_igp(struct e1000_hw *hw)
22399c80d176SSepherosa Ziehau {
22409c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
22419c80d176SSepherosa Ziehau s32 ret_val;
22429c80d176SSepherosa Ziehau u16 data, offset, mask;
22439c80d176SSepherosa Ziehau
22449c80d176SSepherosa Ziehau DEBUGFUNC("e1000_check_polarity_igp");
22459c80d176SSepherosa Ziehau
2246379ebbe7SSepherosa Ziehau /* Polarity is determined based on the speed of
22479c80d176SSepherosa Ziehau * our connection.
22489c80d176SSepherosa Ziehau */
22499c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
22509c80d176SSepherosa Ziehau if (ret_val)
22514be59a01SSepherosa Ziehau return ret_val;
22529c80d176SSepherosa Ziehau
22539c80d176SSepherosa Ziehau if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
22549c80d176SSepherosa Ziehau IGP01E1000_PSSR_SPEED_1000MBPS) {
22559c80d176SSepherosa Ziehau offset = IGP01E1000_PHY_PCS_INIT_REG;
22569c80d176SSepherosa Ziehau mask = IGP01E1000_PHY_POLARITY_MASK;
22579c80d176SSepherosa Ziehau } else {
2258379ebbe7SSepherosa Ziehau /* This really only applies to 10Mbps since
22599c80d176SSepherosa Ziehau * there is no polarity for 100Mbps (always 0).
22609c80d176SSepherosa Ziehau */
22619c80d176SSepherosa Ziehau offset = IGP01E1000_PHY_PORT_STATUS;
22629c80d176SSepherosa Ziehau mask = IGP01E1000_PSSR_POLARITY_REVERSED;
22639c80d176SSepherosa Ziehau }
22649c80d176SSepherosa Ziehau
22659c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, offset, &data);
22669c80d176SSepherosa Ziehau
22679c80d176SSepherosa Ziehau if (!ret_val)
2268379ebbe7SSepherosa Ziehau phy->cable_polarity = ((data & mask)
22699c80d176SSepherosa Ziehau ? e1000_rev_polarity_reversed
2270379ebbe7SSepherosa Ziehau : e1000_rev_polarity_normal);
22719c80d176SSepherosa Ziehau
22729c80d176SSepherosa Ziehau return ret_val;
22739c80d176SSepherosa Ziehau }
22749c80d176SSepherosa Ziehau
22759c80d176SSepherosa Ziehau /**
22766a5a645eSSepherosa Ziehau * e1000_check_polarity_ife - Check cable polarity for IFE PHY
22776a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
22786a5a645eSSepherosa Ziehau *
22796a5a645eSSepherosa Ziehau * Polarity is determined on the polarity reversal feature being enabled.
22806a5a645eSSepherosa Ziehau **/
e1000_check_polarity_ife(struct e1000_hw * hw)22816a5a645eSSepherosa Ziehau s32 e1000_check_polarity_ife(struct e1000_hw *hw)
22826a5a645eSSepherosa Ziehau {
22836a5a645eSSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
22846a5a645eSSepherosa Ziehau s32 ret_val;
22856a5a645eSSepherosa Ziehau u16 phy_data, offset, mask;
22866a5a645eSSepherosa Ziehau
22876a5a645eSSepherosa Ziehau DEBUGFUNC("e1000_check_polarity_ife");
22886a5a645eSSepherosa Ziehau
2289379ebbe7SSepherosa Ziehau /* Polarity is determined based on the reversal feature being enabled.
22906a5a645eSSepherosa Ziehau */
22916a5a645eSSepherosa Ziehau if (phy->polarity_correction) {
22926a5a645eSSepherosa Ziehau offset = IFE_PHY_EXTENDED_STATUS_CONTROL;
22936a5a645eSSepherosa Ziehau mask = IFE_PESC_POLARITY_REVERSED;
22946a5a645eSSepherosa Ziehau } else {
22956a5a645eSSepherosa Ziehau offset = IFE_PHY_SPECIAL_CONTROL;
22966a5a645eSSepherosa Ziehau mask = IFE_PSC_FORCE_POLARITY;
22976a5a645eSSepherosa Ziehau }
22986a5a645eSSepherosa Ziehau
22996a5a645eSSepherosa Ziehau ret_val = phy->ops.read_reg(hw, offset, &phy_data);
23006a5a645eSSepherosa Ziehau
23016a5a645eSSepherosa Ziehau if (!ret_val)
2302379ebbe7SSepherosa Ziehau phy->cable_polarity = ((phy_data & mask)
23036a5a645eSSepherosa Ziehau ? e1000_rev_polarity_reversed
2304379ebbe7SSepherosa Ziehau : e1000_rev_polarity_normal);
23056a5a645eSSepherosa Ziehau
23066a5a645eSSepherosa Ziehau return ret_val;
23076a5a645eSSepherosa Ziehau }
23086a5a645eSSepherosa Ziehau
23096a5a645eSSepherosa Ziehau /**
2310379ebbe7SSepherosa Ziehau * e1000_wait_autoneg - Wait for auto-neg completion
23119c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
23129c80d176SSepherosa Ziehau *
23139c80d176SSepherosa Ziehau * Waits for auto-negotiation to complete or for the auto-negotiation time
23149c80d176SSepherosa Ziehau * limit to expire, which ever happens first.
23159c80d176SSepherosa Ziehau **/
e1000_wait_autoneg(struct e1000_hw * hw)2316379ebbe7SSepherosa Ziehau static s32 e1000_wait_autoneg(struct e1000_hw *hw)
23179c80d176SSepherosa Ziehau {
23189c80d176SSepherosa Ziehau s32 ret_val = E1000_SUCCESS;
23199c80d176SSepherosa Ziehau u16 i, phy_status;
23209c80d176SSepherosa Ziehau
2321379ebbe7SSepherosa Ziehau DEBUGFUNC("e1000_wait_autoneg");
23229c80d176SSepherosa Ziehau
23234be59a01SSepherosa Ziehau if (!hw->phy.ops.read_reg)
23249c80d176SSepherosa Ziehau return E1000_SUCCESS;
23259c80d176SSepherosa Ziehau
23269c80d176SSepherosa Ziehau /* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
23279c80d176SSepherosa Ziehau for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
23289c80d176SSepherosa Ziehau ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
23299c80d176SSepherosa Ziehau if (ret_val)
23309c80d176SSepherosa Ziehau break;
23319c80d176SSepherosa Ziehau ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
23329c80d176SSepherosa Ziehau if (ret_val)
23339c80d176SSepherosa Ziehau break;
23349c80d176SSepherosa Ziehau if (phy_status & MII_SR_AUTONEG_COMPLETE)
23359c80d176SSepherosa Ziehau break;
23369c80d176SSepherosa Ziehau msec_delay(100);
23379c80d176SSepherosa Ziehau }
23389c80d176SSepherosa Ziehau
2339379ebbe7SSepherosa Ziehau /* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
23409c80d176SSepherosa Ziehau * has completed.
23419c80d176SSepherosa Ziehau */
23429c80d176SSepherosa Ziehau return ret_val;
23439c80d176SSepherosa Ziehau }
23449c80d176SSepherosa Ziehau
23459c80d176SSepherosa Ziehau /**
23469c80d176SSepherosa Ziehau * e1000_phy_has_link_generic - Polls PHY for link
23479c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
23489c80d176SSepherosa Ziehau * @iterations: number of times to poll for link
23499c80d176SSepherosa Ziehau * @usec_interval: delay between polling attempts
23509c80d176SSepherosa Ziehau * @success: pointer to whether polling was successful or not
23519c80d176SSepherosa Ziehau *
23529c80d176SSepherosa Ziehau * Polls the PHY status register for link, 'iterations' number of times.
23539c80d176SSepherosa Ziehau **/
e1000_phy_has_link_generic(struct e1000_hw * hw,u32 iterations,u32 usec_interval,bool * success)23549c80d176SSepherosa Ziehau s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
23559c80d176SSepherosa Ziehau u32 usec_interval, bool *success)
23569c80d176SSepherosa Ziehau {
23579c80d176SSepherosa Ziehau s32 ret_val = E1000_SUCCESS;
23589c80d176SSepherosa Ziehau u16 i, phy_status;
23599c80d176SSepherosa Ziehau
23609c80d176SSepherosa Ziehau DEBUGFUNC("e1000_phy_has_link_generic");
23619c80d176SSepherosa Ziehau
23624be59a01SSepherosa Ziehau if (!hw->phy.ops.read_reg)
23639c80d176SSepherosa Ziehau return E1000_SUCCESS;
23649c80d176SSepherosa Ziehau
23659c80d176SSepherosa Ziehau for (i = 0; i < iterations; i++) {
2366379ebbe7SSepherosa Ziehau /* Some PHYs require the PHY_STATUS register to be read
23679c80d176SSepherosa Ziehau * twice due to the link bit being sticky. No harm doing
23689c80d176SSepherosa Ziehau * it across the board.
23699c80d176SSepherosa Ziehau */
23709c80d176SSepherosa Ziehau ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
23714765c386SMichael Neumann if (ret_val) {
2372379ebbe7SSepherosa Ziehau /* If the first read fails, another entity may have
23736a5a645eSSepherosa Ziehau * ownership of the resources, wait and try again to
23746a5a645eSSepherosa Ziehau * see if they have relinquished the resources yet.
23756a5a645eSSepherosa Ziehau */
23764765c386SMichael Neumann if (usec_interval >= 1000)
23774765c386SMichael Neumann msec_delay(usec_interval/1000);
23784765c386SMichael Neumann else
23796a5a645eSSepherosa Ziehau usec_delay(usec_interval);
23804765c386SMichael Neumann }
23819c80d176SSepherosa Ziehau ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
23829c80d176SSepherosa Ziehau if (ret_val)
23839c80d176SSepherosa Ziehau break;
23849c80d176SSepherosa Ziehau if (phy_status & MII_SR_LINK_STATUS)
23859c80d176SSepherosa Ziehau break;
23869c80d176SSepherosa Ziehau if (usec_interval >= 1000)
23874765c386SMichael Neumann msec_delay(usec_interval/1000);
23889c80d176SSepherosa Ziehau else
23899c80d176SSepherosa Ziehau usec_delay(usec_interval);
23909c80d176SSepherosa Ziehau }
23919c80d176SSepherosa Ziehau
23924be59a01SSepherosa Ziehau *success = (i < iterations);
23939c80d176SSepherosa Ziehau
23949c80d176SSepherosa Ziehau return ret_val;
23959c80d176SSepherosa Ziehau }
23969c80d176SSepherosa Ziehau
23979c80d176SSepherosa Ziehau /**
23989c80d176SSepherosa Ziehau * e1000_get_cable_length_m88 - Determine cable length for m88 PHY
23999c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
24009c80d176SSepherosa Ziehau *
24019c80d176SSepherosa Ziehau * Reads the PHY specific status register to retrieve the cable length
24029c80d176SSepherosa Ziehau * information. The cable length is determined by averaging the minimum and
24039c80d176SSepherosa Ziehau * maximum values to get the "average" cable length. The m88 PHY has four
24049c80d176SSepherosa Ziehau * possible cable length values, which are:
24059c80d176SSepherosa Ziehau * Register Value Cable Length
24069c80d176SSepherosa Ziehau * 0 < 50 meters
24079c80d176SSepherosa Ziehau * 1 50 - 80 meters
24089c80d176SSepherosa Ziehau * 2 80 - 110 meters
24099c80d176SSepherosa Ziehau * 3 110 - 140 meters
24109c80d176SSepherosa Ziehau * 4 > 140 meters
24119c80d176SSepherosa Ziehau **/
e1000_get_cable_length_m88(struct e1000_hw * hw)24129c80d176SSepherosa Ziehau s32 e1000_get_cable_length_m88(struct e1000_hw *hw)
24139c80d176SSepherosa Ziehau {
24149c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
24159c80d176SSepherosa Ziehau s32 ret_val;
24169c80d176SSepherosa Ziehau u16 phy_data, index;
24179c80d176SSepherosa Ziehau
24189c80d176SSepherosa Ziehau DEBUGFUNC("e1000_get_cable_length_m88");
24199c80d176SSepherosa Ziehau
24209c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
24219c80d176SSepherosa Ziehau if (ret_val)
24224be59a01SSepherosa Ziehau return ret_val;
24239c80d176SSepherosa Ziehau
2424379ebbe7SSepherosa Ziehau index = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
2425379ebbe7SSepherosa Ziehau M88E1000_PSSR_CABLE_LENGTH_SHIFT);
24264be59a01SSepherosa Ziehau
24274be59a01SSepherosa Ziehau if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1)
24284be59a01SSepherosa Ziehau return -E1000_ERR_PHY;
24296a5a645eSSepherosa Ziehau
24309c80d176SSepherosa Ziehau phy->min_cable_length = e1000_m88_cable_length_table[index];
24319c80d176SSepherosa Ziehau phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
24329c80d176SSepherosa Ziehau
24336a5a645eSSepherosa Ziehau phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
24349c80d176SSepherosa Ziehau
24354be59a01SSepherosa Ziehau return E1000_SUCCESS;
24369c80d176SSepherosa Ziehau }
24379c80d176SSepherosa Ziehau
e1000_get_cable_length_m88_gen2(struct e1000_hw * hw)243862583d18SSepherosa Ziehau s32 e1000_get_cable_length_m88_gen2(struct e1000_hw *hw)
243962583d18SSepherosa Ziehau {
244062583d18SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
244162583d18SSepherosa Ziehau s32 ret_val;
2442379ebbe7SSepherosa Ziehau u16 phy_data, phy_data2, is_cm;
2443379ebbe7SSepherosa Ziehau u16 index, default_page;
244462583d18SSepherosa Ziehau
244562583d18SSepherosa Ziehau DEBUGFUNC("e1000_get_cable_length_m88_gen2");
244662583d18SSepherosa Ziehau
244762583d18SSepherosa Ziehau switch (hw->phy.id) {
24484be59a01SSepherosa Ziehau case I210_I_PHY_ID:
24494be59a01SSepherosa Ziehau /* Get cable length from PHY Cable Diagnostics Control Reg */
24504be59a01SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, (0x7 << GS40G_PAGE_SHIFT) +
24514be59a01SSepherosa Ziehau (I347AT4_PCDL + phy->addr),
24524be59a01SSepherosa Ziehau &phy_data);
24534be59a01SSepherosa Ziehau if (ret_val)
24544be59a01SSepherosa Ziehau return ret_val;
24554be59a01SSepherosa Ziehau
24564be59a01SSepherosa Ziehau /* Check if the unit of cable length is meters or cm */
24574be59a01SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, (0x7 << GS40G_PAGE_SHIFT) +
24584be59a01SSepherosa Ziehau I347AT4_PCDC, &phy_data2);
24594be59a01SSepherosa Ziehau if (ret_val)
24604be59a01SSepherosa Ziehau return ret_val;
24614be59a01SSepherosa Ziehau
24624be59a01SSepherosa Ziehau is_cm = !(phy_data2 & I347AT4_PCDC_CABLE_LENGTH_UNIT);
24634be59a01SSepherosa Ziehau
24644be59a01SSepherosa Ziehau /* Populate the phy structure with cable length in meters */
24654be59a01SSepherosa Ziehau phy->min_cable_length = phy_data / (is_cm ? 100 : 1);
24664be59a01SSepherosa Ziehau phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
24674be59a01SSepherosa Ziehau phy->cable_length = phy_data / (is_cm ? 100 : 1);
24684be59a01SSepherosa Ziehau break;
2469ba0123e0SSepherosa Ziehau case M88E1543_E_PHY_ID:
2470ba0123e0SSepherosa Ziehau case M88E1512_E_PHY_ID:
247162583d18SSepherosa Ziehau case M88E1340M_E_PHY_ID:
247262583d18SSepherosa Ziehau case I347AT4_E_PHY_ID:
247362583d18SSepherosa Ziehau /* Remember the original page select and set it to 7 */
247462583d18SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
247562583d18SSepherosa Ziehau &default_page);
247662583d18SSepherosa Ziehau if (ret_val)
24774be59a01SSepherosa Ziehau return ret_val;
247862583d18SSepherosa Ziehau
247962583d18SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x07);
248062583d18SSepherosa Ziehau if (ret_val)
24814be59a01SSepherosa Ziehau return ret_val;
248262583d18SSepherosa Ziehau
248362583d18SSepherosa Ziehau /* Get cable length from PHY Cable Diagnostics Control Reg */
248462583d18SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, (I347AT4_PCDL + phy->addr),
248562583d18SSepherosa Ziehau &phy_data);
248662583d18SSepherosa Ziehau if (ret_val)
24874be59a01SSepherosa Ziehau return ret_val;
248862583d18SSepherosa Ziehau
248962583d18SSepherosa Ziehau /* Check if the unit of cable length is meters or cm */
249062583d18SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, I347AT4_PCDC, &phy_data2);
249162583d18SSepherosa Ziehau if (ret_val)
24924be59a01SSepherosa Ziehau return ret_val;
249362583d18SSepherosa Ziehau
24944be59a01SSepherosa Ziehau is_cm = !(phy_data2 & I347AT4_PCDC_CABLE_LENGTH_UNIT);
249562583d18SSepherosa Ziehau
249662583d18SSepherosa Ziehau /* Populate the phy structure with cable length in meters */
249762583d18SSepherosa Ziehau phy->min_cable_length = phy_data / (is_cm ? 100 : 1);
249862583d18SSepherosa Ziehau phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
249962583d18SSepherosa Ziehau phy->cable_length = phy_data / (is_cm ? 100 : 1);
250062583d18SSepherosa Ziehau
25014be59a01SSepherosa Ziehau /* Reset the page select to its original value */
250262583d18SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT,
250362583d18SSepherosa Ziehau default_page);
250462583d18SSepherosa Ziehau if (ret_val)
25054be59a01SSepherosa Ziehau return ret_val;
250662583d18SSepherosa Ziehau break;
25074be59a01SSepherosa Ziehau
250862583d18SSepherosa Ziehau case M88E1112_E_PHY_ID:
250962583d18SSepherosa Ziehau /* Remember the original page select and set it to 5 */
251062583d18SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
251162583d18SSepherosa Ziehau &default_page);
251262583d18SSepherosa Ziehau if (ret_val)
25134be59a01SSepherosa Ziehau return ret_val;
251462583d18SSepherosa Ziehau
251562583d18SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x05);
251662583d18SSepherosa Ziehau if (ret_val)
25174be59a01SSepherosa Ziehau return ret_val;
251862583d18SSepherosa Ziehau
251962583d18SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, M88E1112_VCT_DSP_DISTANCE,
252062583d18SSepherosa Ziehau &phy_data);
252162583d18SSepherosa Ziehau if (ret_val)
25224be59a01SSepherosa Ziehau return ret_val;
252362583d18SSepherosa Ziehau
252462583d18SSepherosa Ziehau index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
252562583d18SSepherosa Ziehau M88E1000_PSSR_CABLE_LENGTH_SHIFT;
25264be59a01SSepherosa Ziehau
25274be59a01SSepherosa Ziehau if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1)
25284be59a01SSepherosa Ziehau return -E1000_ERR_PHY;
252962583d18SSepherosa Ziehau
253062583d18SSepherosa Ziehau phy->min_cable_length = e1000_m88_cable_length_table[index];
253162583d18SSepherosa Ziehau phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
253262583d18SSepherosa Ziehau
253362583d18SSepherosa Ziehau phy->cable_length = (phy->min_cable_length +
253462583d18SSepherosa Ziehau phy->max_cable_length) / 2;
253562583d18SSepherosa Ziehau
253662583d18SSepherosa Ziehau /* Reset the page select to its original value */
253762583d18SSepherosa Ziehau ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT,
253862583d18SSepherosa Ziehau default_page);
253962583d18SSepherosa Ziehau if (ret_val)
25404be59a01SSepherosa Ziehau return ret_val;
254162583d18SSepherosa Ziehau
254262583d18SSepherosa Ziehau break;
254362583d18SSepherosa Ziehau default:
25444be59a01SSepherosa Ziehau return -E1000_ERR_PHY;
254562583d18SSepherosa Ziehau }
254662583d18SSepherosa Ziehau
254762583d18SSepherosa Ziehau return ret_val;
254862583d18SSepherosa Ziehau }
254962583d18SSepherosa Ziehau
25509c80d176SSepherosa Ziehau /**
25519c80d176SSepherosa Ziehau * e1000_get_cable_length_igp_2 - Determine cable length for igp2 PHY
25529c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
25539c80d176SSepherosa Ziehau *
25549c80d176SSepherosa Ziehau * The automatic gain control (agc) normalizes the amplitude of the
25559c80d176SSepherosa Ziehau * received signal, adjusting for the attenuation produced by the
25569c80d176SSepherosa Ziehau * cable. By reading the AGC registers, which represent the
25579c80d176SSepherosa Ziehau * combination of coarse and fine gain value, the value can be put
25589c80d176SSepherosa Ziehau * into a lookup table to obtain the approximate cable length
25599c80d176SSepherosa Ziehau * for each channel.
25609c80d176SSepherosa Ziehau **/
e1000_get_cable_length_igp_2(struct e1000_hw * hw)25619c80d176SSepherosa Ziehau s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw)
25629c80d176SSepherosa Ziehau {
25639c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
25644be59a01SSepherosa Ziehau s32 ret_val;
25659c80d176SSepherosa Ziehau u16 phy_data, i, agc_value = 0;
25669c80d176SSepherosa Ziehau u16 cur_agc_index, max_agc_index = 0;
25679c80d176SSepherosa Ziehau u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1;
25686d5e2922SSepherosa Ziehau static const u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = {
25696d5e2922SSepherosa Ziehau IGP02E1000_PHY_AGC_A,
25709c80d176SSepherosa Ziehau IGP02E1000_PHY_AGC_B,
25719c80d176SSepherosa Ziehau IGP02E1000_PHY_AGC_C,
25726d5e2922SSepherosa Ziehau IGP02E1000_PHY_AGC_D
25736d5e2922SSepherosa Ziehau };
25749c80d176SSepherosa Ziehau
25759c80d176SSepherosa Ziehau DEBUGFUNC("e1000_get_cable_length_igp_2");
25769c80d176SSepherosa Ziehau
25779c80d176SSepherosa Ziehau /* Read the AGC registers for all channels */
25789c80d176SSepherosa Ziehau for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
25799c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, agc_reg_array[i], &phy_data);
25809c80d176SSepherosa Ziehau if (ret_val)
25814be59a01SSepherosa Ziehau return ret_val;
25829c80d176SSepherosa Ziehau
2583379ebbe7SSepherosa Ziehau /* Getting bits 15:9, which represent the combination of
25849c80d176SSepherosa Ziehau * coarse and fine gain values. The result is a number
25859c80d176SSepherosa Ziehau * that can be put into the lookup table to obtain the
25869c80d176SSepherosa Ziehau * approximate cable length.
25879c80d176SSepherosa Ziehau */
2588379ebbe7SSepherosa Ziehau cur_agc_index = ((phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
2589379ebbe7SSepherosa Ziehau IGP02E1000_AGC_LENGTH_MASK);
25909c80d176SSepherosa Ziehau
25919c80d176SSepherosa Ziehau /* Array index bound check. */
25929c80d176SSepherosa Ziehau if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) ||
25934be59a01SSepherosa Ziehau (cur_agc_index == 0))
25944be59a01SSepherosa Ziehau return -E1000_ERR_PHY;
25959c80d176SSepherosa Ziehau
25969c80d176SSepherosa Ziehau /* Remove min & max AGC values from calculation. */
25979c80d176SSepherosa Ziehau if (e1000_igp_2_cable_length_table[min_agc_index] >
25989c80d176SSepherosa Ziehau e1000_igp_2_cable_length_table[cur_agc_index])
25999c80d176SSepherosa Ziehau min_agc_index = cur_agc_index;
26009c80d176SSepherosa Ziehau if (e1000_igp_2_cable_length_table[max_agc_index] <
26019c80d176SSepherosa Ziehau e1000_igp_2_cable_length_table[cur_agc_index])
26029c80d176SSepherosa Ziehau max_agc_index = cur_agc_index;
26039c80d176SSepherosa Ziehau
26049c80d176SSepherosa Ziehau agc_value += e1000_igp_2_cable_length_table[cur_agc_index];
26059c80d176SSepherosa Ziehau }
26069c80d176SSepherosa Ziehau
26079c80d176SSepherosa Ziehau agc_value -= (e1000_igp_2_cable_length_table[min_agc_index] +
26089c80d176SSepherosa Ziehau e1000_igp_2_cable_length_table[max_agc_index]);
26099c80d176SSepherosa Ziehau agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
26109c80d176SSepherosa Ziehau
26119c80d176SSepherosa Ziehau /* Calculate cable length with the error range of +/- 10 meters. */
2612379ebbe7SSepherosa Ziehau phy->min_cable_length = (((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
2613379ebbe7SSepherosa Ziehau (agc_value - IGP02E1000_AGC_RANGE) : 0);
26149c80d176SSepherosa Ziehau phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE;
26159c80d176SSepherosa Ziehau
26169c80d176SSepherosa Ziehau phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
26179c80d176SSepherosa Ziehau
26184be59a01SSepherosa Ziehau return E1000_SUCCESS;
26199c80d176SSepherosa Ziehau }
26209c80d176SSepherosa Ziehau
26219c80d176SSepherosa Ziehau /**
26229c80d176SSepherosa Ziehau * e1000_get_phy_info_m88 - Retrieve PHY information
26239c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
26249c80d176SSepherosa Ziehau *
26259c80d176SSepherosa Ziehau * Valid for only copper links. Read the PHY status register (sticky read)
26269c80d176SSepherosa Ziehau * to verify that link is up. Read the PHY special control register to
26279c80d176SSepherosa Ziehau * determine the polarity and 10base-T extended distance. Read the PHY
26289c80d176SSepherosa Ziehau * special status register to determine MDI/MDIx and current speed. If
26299c80d176SSepherosa Ziehau * speed is 1000, then determine cable length, local and remote receiver.
26309c80d176SSepherosa Ziehau **/
e1000_get_phy_info_m88(struct e1000_hw * hw)26319c80d176SSepherosa Ziehau s32 e1000_get_phy_info_m88(struct e1000_hw *hw)
26329c80d176SSepherosa Ziehau {
26339c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
26349c80d176SSepherosa Ziehau s32 ret_val;
26359c80d176SSepherosa Ziehau u16 phy_data;
26369c80d176SSepherosa Ziehau bool link;
26379c80d176SSepherosa Ziehau
26389c80d176SSepherosa Ziehau DEBUGFUNC("e1000_get_phy_info_m88");
26399c80d176SSepherosa Ziehau
26406a5a645eSSepherosa Ziehau if (phy->media_type != e1000_media_type_copper) {
26419c80d176SSepherosa Ziehau DEBUGOUT("Phy info is only valid for copper media\n");
26424be59a01SSepherosa Ziehau return -E1000_ERR_CONFIG;
26439c80d176SSepherosa Ziehau }
26449c80d176SSepherosa Ziehau
26459c80d176SSepherosa Ziehau ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
26469c80d176SSepherosa Ziehau if (ret_val)
26474be59a01SSepherosa Ziehau return ret_val;
26489c80d176SSepherosa Ziehau
26499c80d176SSepherosa Ziehau if (!link) {
26509c80d176SSepherosa Ziehau DEBUGOUT("Phy info is only valid if link is up\n");
26514be59a01SSepherosa Ziehau return -E1000_ERR_CONFIG;
26529c80d176SSepherosa Ziehau }
26539c80d176SSepherosa Ziehau
26549c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
26559c80d176SSepherosa Ziehau if (ret_val)
26564be59a01SSepherosa Ziehau return ret_val;
26579c80d176SSepherosa Ziehau
26584be59a01SSepherosa Ziehau phy->polarity_correction = !!(phy_data &
26594be59a01SSepherosa Ziehau M88E1000_PSCR_POLARITY_REVERSAL);
26609c80d176SSepherosa Ziehau
26619c80d176SSepherosa Ziehau ret_val = e1000_check_polarity_m88(hw);
26629c80d176SSepherosa Ziehau if (ret_val)
26634be59a01SSepherosa Ziehau return ret_val;
26649c80d176SSepherosa Ziehau
26659c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
26669c80d176SSepherosa Ziehau if (ret_val)
26674be59a01SSepherosa Ziehau return ret_val;
26689c80d176SSepherosa Ziehau
26694be59a01SSepherosa Ziehau phy->is_mdix = !!(phy_data & M88E1000_PSSR_MDIX);
26709c80d176SSepherosa Ziehau
26719c80d176SSepherosa Ziehau if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
26729c80d176SSepherosa Ziehau ret_val = hw->phy.ops.get_cable_length(hw);
26739c80d176SSepherosa Ziehau if (ret_val)
26744be59a01SSepherosa Ziehau return ret_val;
26759c80d176SSepherosa Ziehau
26769c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &phy_data);
26779c80d176SSepherosa Ziehau if (ret_val)
26784be59a01SSepherosa Ziehau return ret_val;
26799c80d176SSepherosa Ziehau
26809c80d176SSepherosa Ziehau phy->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS)
26819c80d176SSepherosa Ziehau ? e1000_1000t_rx_status_ok
26829c80d176SSepherosa Ziehau : e1000_1000t_rx_status_not_ok;
26839c80d176SSepherosa Ziehau
26849c80d176SSepherosa Ziehau phy->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS)
26859c80d176SSepherosa Ziehau ? e1000_1000t_rx_status_ok
26869c80d176SSepherosa Ziehau : e1000_1000t_rx_status_not_ok;
26879c80d176SSepherosa Ziehau } else {
26889c80d176SSepherosa Ziehau /* Set values to "undefined" */
26899c80d176SSepherosa Ziehau phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
26909c80d176SSepherosa Ziehau phy->local_rx = e1000_1000t_rx_status_undefined;
26919c80d176SSepherosa Ziehau phy->remote_rx = e1000_1000t_rx_status_undefined;
26929c80d176SSepherosa Ziehau }
26939c80d176SSepherosa Ziehau
26949c80d176SSepherosa Ziehau return ret_val;
26959c80d176SSepherosa Ziehau }
26969c80d176SSepherosa Ziehau
26979c80d176SSepherosa Ziehau /**
26989c80d176SSepherosa Ziehau * e1000_get_phy_info_igp - Retrieve igp PHY information
26999c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
27009c80d176SSepherosa Ziehau *
27019c80d176SSepherosa Ziehau * Read PHY status to determine if link is up. If link is up, then
27029c80d176SSepherosa Ziehau * set/determine 10base-T extended distance and polarity correction. Read
27039c80d176SSepherosa Ziehau * PHY port status to determine MDI/MDIx and speed. Based on the speed,
27049c80d176SSepherosa Ziehau * determine on the cable length, local and remote receiver.
27059c80d176SSepherosa Ziehau **/
e1000_get_phy_info_igp(struct e1000_hw * hw)27069c80d176SSepherosa Ziehau s32 e1000_get_phy_info_igp(struct e1000_hw *hw)
27079c80d176SSepherosa Ziehau {
27089c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
27099c80d176SSepherosa Ziehau s32 ret_val;
27109c80d176SSepherosa Ziehau u16 data;
27119c80d176SSepherosa Ziehau bool link;
27129c80d176SSepherosa Ziehau
27139c80d176SSepherosa Ziehau DEBUGFUNC("e1000_get_phy_info_igp");
27149c80d176SSepherosa Ziehau
27159c80d176SSepherosa Ziehau ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
27169c80d176SSepherosa Ziehau if (ret_val)
27174be59a01SSepherosa Ziehau return ret_val;
27189c80d176SSepherosa Ziehau
27199c80d176SSepherosa Ziehau if (!link) {
27209c80d176SSepherosa Ziehau DEBUGOUT("Phy info is only valid if link is up\n");
27214be59a01SSepherosa Ziehau return -E1000_ERR_CONFIG;
27229c80d176SSepherosa Ziehau }
27239c80d176SSepherosa Ziehau
27249c80d176SSepherosa Ziehau phy->polarity_correction = TRUE;
27259c80d176SSepherosa Ziehau
27269c80d176SSepherosa Ziehau ret_val = e1000_check_polarity_igp(hw);
27279c80d176SSepherosa Ziehau if (ret_val)
27284be59a01SSepherosa Ziehau return ret_val;
27299c80d176SSepherosa Ziehau
27309c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
27319c80d176SSepherosa Ziehau if (ret_val)
27324be59a01SSepherosa Ziehau return ret_val;
27339c80d176SSepherosa Ziehau
27344be59a01SSepherosa Ziehau phy->is_mdix = !!(data & IGP01E1000_PSSR_MDIX);
27359c80d176SSepherosa Ziehau
27369c80d176SSepherosa Ziehau if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
27379c80d176SSepherosa Ziehau IGP01E1000_PSSR_SPEED_1000MBPS) {
27386a5a645eSSepherosa Ziehau ret_val = phy->ops.get_cable_length(hw);
27399c80d176SSepherosa Ziehau if (ret_val)
27404be59a01SSepherosa Ziehau return ret_val;
27419c80d176SSepherosa Ziehau
27429c80d176SSepherosa Ziehau ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data);
27439c80d176SSepherosa Ziehau if (ret_val)
27444be59a01SSepherosa Ziehau return ret_val;
27459c80d176SSepherosa Ziehau
27469c80d176SSepherosa Ziehau phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
27479c80d176SSepherosa Ziehau ? e1000_1000t_rx_status_ok
27489c80d176SSepherosa Ziehau : e1000_1000t_rx_status_not_ok;
27499c80d176SSepherosa Ziehau
27509c80d176SSepherosa Ziehau phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
27519c80d176SSepherosa Ziehau ? e1000_1000t_rx_status_ok
27529c80d176SSepherosa Ziehau : e1000_1000t_rx_status_not_ok;
27539c80d176SSepherosa Ziehau } else {
27549c80d176SSepherosa Ziehau phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
27559c80d176SSepherosa Ziehau phy->local_rx = e1000_1000t_rx_status_undefined;
27569c80d176SSepherosa Ziehau phy->remote_rx = e1000_1000t_rx_status_undefined;
27579c80d176SSepherosa Ziehau }
27589c80d176SSepherosa Ziehau
27599c80d176SSepherosa Ziehau return ret_val;
27609c80d176SSepherosa Ziehau }
27619c80d176SSepherosa Ziehau
27629c80d176SSepherosa Ziehau /**
27636a5a645eSSepherosa Ziehau * e1000_get_phy_info_ife - Retrieves various IFE PHY states
27646a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
27656a5a645eSSepherosa Ziehau *
27666a5a645eSSepherosa Ziehau * Populates "phy" structure with various feature states.
27676a5a645eSSepherosa Ziehau **/
e1000_get_phy_info_ife(struct e1000_hw * hw)27686a5a645eSSepherosa Ziehau s32 e1000_get_phy_info_ife(struct e1000_hw *hw)
27696a5a645eSSepherosa Ziehau {
27706a5a645eSSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
27716a5a645eSSepherosa Ziehau s32 ret_val;
27726a5a645eSSepherosa Ziehau u16 data;
27736a5a645eSSepherosa Ziehau bool link;
27746a5a645eSSepherosa Ziehau
27756a5a645eSSepherosa Ziehau DEBUGFUNC("e1000_get_phy_info_ife");
27766a5a645eSSepherosa Ziehau
27776a5a645eSSepherosa Ziehau ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
27786a5a645eSSepherosa Ziehau if (ret_val)
27794be59a01SSepherosa Ziehau return ret_val;
27806a5a645eSSepherosa Ziehau
27816a5a645eSSepherosa Ziehau if (!link) {
27826a5a645eSSepherosa Ziehau DEBUGOUT("Phy info is only valid if link is up\n");
27834be59a01SSepherosa Ziehau return -E1000_ERR_CONFIG;
27846a5a645eSSepherosa Ziehau }
27856a5a645eSSepherosa Ziehau
27866a5a645eSSepherosa Ziehau ret_val = phy->ops.read_reg(hw, IFE_PHY_SPECIAL_CONTROL, &data);
27876a5a645eSSepherosa Ziehau if (ret_val)
27884be59a01SSepherosa Ziehau return ret_val;
27894be59a01SSepherosa Ziehau phy->polarity_correction = !(data & IFE_PSC_AUTO_POLARITY_DISABLE);
27906a5a645eSSepherosa Ziehau
27916a5a645eSSepherosa Ziehau if (phy->polarity_correction) {
27926a5a645eSSepherosa Ziehau ret_val = e1000_check_polarity_ife(hw);
27936a5a645eSSepherosa Ziehau if (ret_val)
27944be59a01SSepherosa Ziehau return ret_val;
27956a5a645eSSepherosa Ziehau } else {
27966a5a645eSSepherosa Ziehau /* Polarity is forced */
2797379ebbe7SSepherosa Ziehau phy->cable_polarity = ((data & IFE_PSC_FORCE_POLARITY)
27986a5a645eSSepherosa Ziehau ? e1000_rev_polarity_reversed
2799379ebbe7SSepherosa Ziehau : e1000_rev_polarity_normal);
28006a5a645eSSepherosa Ziehau }
28016a5a645eSSepherosa Ziehau
28026a5a645eSSepherosa Ziehau ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data);
28036a5a645eSSepherosa Ziehau if (ret_val)
28044be59a01SSepherosa Ziehau return ret_val;
28056a5a645eSSepherosa Ziehau
28064be59a01SSepherosa Ziehau phy->is_mdix = !!(data & IFE_PMC_MDIX_STATUS);
28076a5a645eSSepherosa Ziehau
28086a5a645eSSepherosa Ziehau /* The following parameters are undefined for 10/100 operation. */
28096a5a645eSSepherosa Ziehau phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
28106a5a645eSSepherosa Ziehau phy->local_rx = e1000_1000t_rx_status_undefined;
28116a5a645eSSepherosa Ziehau phy->remote_rx = e1000_1000t_rx_status_undefined;
28126a5a645eSSepherosa Ziehau
28134be59a01SSepherosa Ziehau return E1000_SUCCESS;
28146a5a645eSSepherosa Ziehau }
28156a5a645eSSepherosa Ziehau
28166a5a645eSSepherosa Ziehau /**
28179c80d176SSepherosa Ziehau * e1000_phy_sw_reset_generic - PHY software reset
28189c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
28199c80d176SSepherosa Ziehau *
28209c80d176SSepherosa Ziehau * Does a software reset of the PHY by reading the PHY control register and
28219c80d176SSepherosa Ziehau * setting/write the control register reset bit to the PHY.
28229c80d176SSepherosa Ziehau **/
e1000_phy_sw_reset_generic(struct e1000_hw * hw)28239c80d176SSepherosa Ziehau s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw)
28249c80d176SSepherosa Ziehau {
28254be59a01SSepherosa Ziehau s32 ret_val;
28269c80d176SSepherosa Ziehau u16 phy_ctrl;
28279c80d176SSepherosa Ziehau
28289c80d176SSepherosa Ziehau DEBUGFUNC("e1000_phy_sw_reset_generic");
28299c80d176SSepherosa Ziehau
28304be59a01SSepherosa Ziehau if (!hw->phy.ops.read_reg)
28314be59a01SSepherosa Ziehau return E1000_SUCCESS;
28329c80d176SSepherosa Ziehau
28339c80d176SSepherosa Ziehau ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
28349c80d176SSepherosa Ziehau if (ret_val)
28354be59a01SSepherosa Ziehau return ret_val;
28369c80d176SSepherosa Ziehau
28379c80d176SSepherosa Ziehau phy_ctrl |= MII_CR_RESET;
28389c80d176SSepherosa Ziehau ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
28399c80d176SSepherosa Ziehau if (ret_val)
28404be59a01SSepherosa Ziehau return ret_val;
28419c80d176SSepherosa Ziehau
28429c80d176SSepherosa Ziehau usec_delay(1);
28439c80d176SSepherosa Ziehau
28449c80d176SSepherosa Ziehau return ret_val;
28459c80d176SSepherosa Ziehau }
28469c80d176SSepherosa Ziehau
28479c80d176SSepherosa Ziehau /**
28489c80d176SSepherosa Ziehau * e1000_phy_hw_reset_generic - PHY hardware reset
28499c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
28509c80d176SSepherosa Ziehau *
28519c80d176SSepherosa Ziehau * Verify the reset block is not blocking us from resetting. Acquire
28529c80d176SSepherosa Ziehau * semaphore (if necessary) and read/set/write the device control reset
28539c80d176SSepherosa Ziehau * bit in the PHY. Wait the appropriate delay time for the device to
28549c80d176SSepherosa Ziehau * reset and release the semaphore (if necessary).
28559c80d176SSepherosa Ziehau **/
e1000_phy_hw_reset_generic(struct e1000_hw * hw)28569c80d176SSepherosa Ziehau s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw)
28579c80d176SSepherosa Ziehau {
28589c80d176SSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
28594be59a01SSepherosa Ziehau s32 ret_val;
28609c80d176SSepherosa Ziehau u32 ctrl;
28619c80d176SSepherosa Ziehau
28629c80d176SSepherosa Ziehau DEBUGFUNC("e1000_phy_hw_reset_generic");
28639c80d176SSepherosa Ziehau
28644be59a01SSepherosa Ziehau if (phy->ops.check_reset_block) {
28659c80d176SSepherosa Ziehau ret_val = phy->ops.check_reset_block(hw);
28664be59a01SSepherosa Ziehau if (ret_val)
28674be59a01SSepherosa Ziehau return E1000_SUCCESS;
28689c80d176SSepherosa Ziehau }
28699c80d176SSepherosa Ziehau
28709c80d176SSepherosa Ziehau ret_val = phy->ops.acquire(hw);
28719c80d176SSepherosa Ziehau if (ret_val)
28724be59a01SSepherosa Ziehau return ret_val;
28739c80d176SSepherosa Ziehau
28749c80d176SSepherosa Ziehau ctrl = E1000_READ_REG(hw, E1000_CTRL);
28759c80d176SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PHY_RST);
28769c80d176SSepherosa Ziehau E1000_WRITE_FLUSH(hw);
28779c80d176SSepherosa Ziehau
28789c80d176SSepherosa Ziehau usec_delay(phy->reset_delay_us);
28799c80d176SSepherosa Ziehau
28809c80d176SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
28819c80d176SSepherosa Ziehau E1000_WRITE_FLUSH(hw);
28829c80d176SSepherosa Ziehau
28839c80d176SSepherosa Ziehau usec_delay(150);
28849c80d176SSepherosa Ziehau
28859c80d176SSepherosa Ziehau phy->ops.release(hw);
28869c80d176SSepherosa Ziehau
28874be59a01SSepherosa Ziehau return phy->ops.get_cfg_done(hw);
28889c80d176SSepherosa Ziehau }
28899c80d176SSepherosa Ziehau
28909c80d176SSepherosa Ziehau /**
28919c80d176SSepherosa Ziehau * e1000_get_cfg_done_generic - Generic configuration done
28929c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
28939c80d176SSepherosa Ziehau *
28949c80d176SSepherosa Ziehau * Generic function to wait 10 milli-seconds for configuration to complete
28959c80d176SSepherosa Ziehau * and return success.
28969c80d176SSepherosa Ziehau **/
e1000_get_cfg_done_generic(struct e1000_hw E1000_UNUSEDARG * hw)2897379ebbe7SSepherosa Ziehau s32 e1000_get_cfg_done_generic(struct e1000_hw E1000_UNUSEDARG *hw)
28989c80d176SSepherosa Ziehau {
28999c80d176SSepherosa Ziehau DEBUGFUNC("e1000_get_cfg_done_generic");
29009c80d176SSepherosa Ziehau
29019c80d176SSepherosa Ziehau msec_delay_irq(10);
29029c80d176SSepherosa Ziehau
29039c80d176SSepherosa Ziehau return E1000_SUCCESS;
29049c80d176SSepherosa Ziehau }
29059c80d176SSepherosa Ziehau
29069c80d176SSepherosa Ziehau /**
29079c80d176SSepherosa Ziehau * e1000_phy_init_script_igp3 - Inits the IGP3 PHY
29089c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
29099c80d176SSepherosa Ziehau *
29109c80d176SSepherosa Ziehau * Initializes a Intel Gigabit PHY3 when an EEPROM is not present.
29119c80d176SSepherosa Ziehau **/
e1000_phy_init_script_igp3(struct e1000_hw * hw)29129c80d176SSepherosa Ziehau s32 e1000_phy_init_script_igp3(struct e1000_hw *hw)
29139c80d176SSepherosa Ziehau {
29149c80d176SSepherosa Ziehau DEBUGOUT("Running IGP 3 PHY init script\n");
29159c80d176SSepherosa Ziehau
29169c80d176SSepherosa Ziehau /* PHY init IGP 3 */
29179c80d176SSepherosa Ziehau /* Enable rise/fall, 10-mode work in class-A */
29189c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x2F5B, 0x9018);
29199c80d176SSepherosa Ziehau /* Remove all caps from Replica path filter */
29209c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x2F52, 0x0000);
29219c80d176SSepherosa Ziehau /* Bias trimming for ADC, AFE and Driver (Default) */
29229c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x2FB1, 0x8B24);
29239c80d176SSepherosa Ziehau /* Increase Hybrid poly bias */
29249c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x2FB2, 0xF8F0);
29259c80d176SSepherosa Ziehau /* Add 4% to Tx amplitude in Gig mode */
29269c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x2010, 0x10B0);
29279c80d176SSepherosa Ziehau /* Disable trimming (TTT) */
29289c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x2011, 0x0000);
29299c80d176SSepherosa Ziehau /* Poly DC correction to 94.6% + 2% for all channels */
29309c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x20DD, 0x249A);
29319c80d176SSepherosa Ziehau /* ABS DC correction to 95.9% */
29329c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x20DE, 0x00D3);
29339c80d176SSepherosa Ziehau /* BG temp curve trim */
29349c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x28B4, 0x04CE);
29359c80d176SSepherosa Ziehau /* Increasing ADC OPAMP stage 1 currents to max */
29369c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x2F70, 0x29E4);
29379c80d176SSepherosa Ziehau /* Force 1000 ( required for enabling PHY regs configuration) */
29389c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x0000, 0x0140);
29399c80d176SSepherosa Ziehau /* Set upd_freq to 6 */
29409c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1F30, 0x1606);
29419c80d176SSepherosa Ziehau /* Disable NPDFE */
29429c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1F31, 0xB814);
29439c80d176SSepherosa Ziehau /* Disable adaptive fixed FFE (Default) */
29449c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1F35, 0x002A);
29459c80d176SSepherosa Ziehau /* Enable FFE hysteresis */
29469c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1F3E, 0x0067);
29479c80d176SSepherosa Ziehau /* Fixed FFE for short cable lengths */
29489c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1F54, 0x0065);
29499c80d176SSepherosa Ziehau /* Fixed FFE for medium cable lengths */
29509c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1F55, 0x002A);
29519c80d176SSepherosa Ziehau /* Fixed FFE for long cable lengths */
29529c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1F56, 0x002A);
29539c80d176SSepherosa Ziehau /* Enable Adaptive Clip Threshold */
29549c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1F72, 0x3FB0);
29559c80d176SSepherosa Ziehau /* AHT reset limit to 1 */
29569c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1F76, 0xC0FF);
29579c80d176SSepherosa Ziehau /* Set AHT master delay to 127 msec */
29589c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1F77, 0x1DEC);
29599c80d176SSepherosa Ziehau /* Set scan bits for AHT */
29609c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1F78, 0xF9EF);
29619c80d176SSepherosa Ziehau /* Set AHT Preset bits */
29629c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1F79, 0x0210);
29639c80d176SSepherosa Ziehau /* Change integ_factor of channel A to 3 */
29649c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1895, 0x0003);
29659c80d176SSepherosa Ziehau /* Change prop_factor of channels BCD to 8 */
29669c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1796, 0x0008);
29679c80d176SSepherosa Ziehau /* Change cg_icount + enable integbp for channels BCD */
29689c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1798, 0xD008);
2969379ebbe7SSepherosa Ziehau /* Change cg_icount + enable integbp + change prop_factor_master
29709c80d176SSepherosa Ziehau * to 8 for channel A
29719c80d176SSepherosa Ziehau */
29729c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x1898, 0xD918);
29739c80d176SSepherosa Ziehau /* Disable AHT in Slave mode on channel A */
29749c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x187A, 0x0800);
2975379ebbe7SSepherosa Ziehau /* Enable LPLU and disable AN to 1000 in non-D0a states,
29769c80d176SSepherosa Ziehau * Enable SPD+B2B
29779c80d176SSepherosa Ziehau */
29789c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x0019, 0x008D);
29799c80d176SSepherosa Ziehau /* Enable restart AN on an1000_dis change */
29809c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x001B, 0x2080);
29819c80d176SSepherosa Ziehau /* Enable wh_fifo read clock in 10/100 modes */
29829c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x0014, 0x0045);
29839c80d176SSepherosa Ziehau /* Restart AN, Speed selection is 1000 */
29849c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, 0x0000, 0x1340);
29859c80d176SSepherosa Ziehau
29869c80d176SSepherosa Ziehau return E1000_SUCCESS;
29879c80d176SSepherosa Ziehau }
29889c80d176SSepherosa Ziehau
29899c80d176SSepherosa Ziehau /**
29909c80d176SSepherosa Ziehau * e1000_get_phy_type_from_id - Get PHY type from id
29919c80d176SSepherosa Ziehau * @phy_id: phy_id read from the phy
29929c80d176SSepherosa Ziehau *
29939c80d176SSepherosa Ziehau * Returns the phy type from the id.
29949c80d176SSepherosa Ziehau **/
e1000_get_phy_type_from_id(u32 phy_id)29959c80d176SSepherosa Ziehau enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
29969c80d176SSepherosa Ziehau {
29979c80d176SSepherosa Ziehau enum e1000_phy_type phy_type = e1000_phy_unknown;
29989c80d176SSepherosa Ziehau
29999c80d176SSepherosa Ziehau switch (phy_id) {
30009c80d176SSepherosa Ziehau case M88E1000_I_PHY_ID:
30019c80d176SSepherosa Ziehau case M88E1000_E_PHY_ID:
30029c80d176SSepherosa Ziehau case M88E1111_I_PHY_ID:
30039c80d176SSepherosa Ziehau case M88E1011_I_PHY_ID:
3004ba0123e0SSepherosa Ziehau case M88E1543_E_PHY_ID:
3005ba0123e0SSepherosa Ziehau case M88E1512_E_PHY_ID:
300662583d18SSepherosa Ziehau case I347AT4_E_PHY_ID:
300762583d18SSepherosa Ziehau case M88E1112_E_PHY_ID:
300862583d18SSepherosa Ziehau case M88E1340M_E_PHY_ID:
30099c80d176SSepherosa Ziehau phy_type = e1000_phy_m88;
30109c80d176SSepherosa Ziehau break;
30119c80d176SSepherosa Ziehau case IGP01E1000_I_PHY_ID: /* IGP 1 & 2 share this */
30129c80d176SSepherosa Ziehau phy_type = e1000_phy_igp_2;
30139c80d176SSepherosa Ziehau break;
30149c80d176SSepherosa Ziehau case GG82563_E_PHY_ID:
30159c80d176SSepherosa Ziehau phy_type = e1000_phy_gg82563;
30169c80d176SSepherosa Ziehau break;
30179c80d176SSepherosa Ziehau case IGP03E1000_E_PHY_ID:
30189c80d176SSepherosa Ziehau phy_type = e1000_phy_igp_3;
30199c80d176SSepherosa Ziehau break;
30209c80d176SSepherosa Ziehau case IFE_E_PHY_ID:
30219c80d176SSepherosa Ziehau case IFE_PLUS_E_PHY_ID:
30229c80d176SSepherosa Ziehau case IFE_C_E_PHY_ID:
30239c80d176SSepherosa Ziehau phy_type = e1000_phy_ife;
30249c80d176SSepherosa Ziehau break;
30259c80d176SSepherosa Ziehau case BME1000_E_PHY_ID:
30269c80d176SSepherosa Ziehau case BME1000_E_PHY_ID_R2:
30279c80d176SSepherosa Ziehau phy_type = e1000_phy_bm;
30289c80d176SSepherosa Ziehau break;
30296a5a645eSSepherosa Ziehau case I82578_E_PHY_ID:
30306a5a645eSSepherosa Ziehau phy_type = e1000_phy_82578;
30316a5a645eSSepherosa Ziehau break;
30326a5a645eSSepherosa Ziehau case I82577_E_PHY_ID:
30336a5a645eSSepherosa Ziehau phy_type = e1000_phy_82577;
30346a5a645eSSepherosa Ziehau break;
30356a5a645eSSepherosa Ziehau case I82579_E_PHY_ID:
30366a5a645eSSepherosa Ziehau phy_type = e1000_phy_82579;
30376a5a645eSSepherosa Ziehau break;
30386a5a645eSSepherosa Ziehau case I82580_I_PHY_ID:
30396a5a645eSSepherosa Ziehau phy_type = e1000_phy_82580;
30405f18a3ddSSascha Wildner break;
304165aebe9fSSepherosa Ziehau case I217_E_PHY_ID:
304265aebe9fSSepherosa Ziehau phy_type = e1000_phy_i217;
30436a5a645eSSepherosa Ziehau break;
30444be59a01SSepherosa Ziehau case I210_I_PHY_ID:
30454be59a01SSepherosa Ziehau phy_type = e1000_phy_i210;
30464be59a01SSepherosa Ziehau break;
30479c80d176SSepherosa Ziehau default:
30489c80d176SSepherosa Ziehau phy_type = e1000_phy_unknown;
30499c80d176SSepherosa Ziehau break;
30509c80d176SSepherosa Ziehau }
30519c80d176SSepherosa Ziehau return phy_type;
30529c80d176SSepherosa Ziehau }
30539c80d176SSepherosa Ziehau
30549c80d176SSepherosa Ziehau /**
30559c80d176SSepherosa Ziehau * e1000_determine_phy_address - Determines PHY address.
30569c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
30579c80d176SSepherosa Ziehau *
30589c80d176SSepherosa Ziehau * This uses a trial and error method to loop through possible PHY
30599c80d176SSepherosa Ziehau * addresses. It tests each by reading the PHY ID registers and
30609c80d176SSepherosa Ziehau * checking for a match.
30619c80d176SSepherosa Ziehau **/
e1000_determine_phy_address(struct e1000_hw * hw)30629c80d176SSepherosa Ziehau s32 e1000_determine_phy_address(struct e1000_hw *hw)
30639c80d176SSepherosa Ziehau {
30649c80d176SSepherosa Ziehau u32 phy_addr = 0;
30659c80d176SSepherosa Ziehau u32 i;
30669c80d176SSepherosa Ziehau enum e1000_phy_type phy_type = e1000_phy_unknown;
30679c80d176SSepherosa Ziehau
30686a5a645eSSepherosa Ziehau hw->phy.id = phy_type;
30696a5a645eSSepherosa Ziehau
30709c80d176SSepherosa Ziehau for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) {
30719c80d176SSepherosa Ziehau hw->phy.addr = phy_addr;
30729c80d176SSepherosa Ziehau i = 0;
30739c80d176SSepherosa Ziehau
30749c80d176SSepherosa Ziehau do {
30759c80d176SSepherosa Ziehau e1000_get_phy_id(hw);
30769c80d176SSepherosa Ziehau phy_type = e1000_get_phy_type_from_id(hw->phy.id);
30779c80d176SSepherosa Ziehau
3078379ebbe7SSepherosa Ziehau /* If phy_type is valid, break - we found our
30799c80d176SSepherosa Ziehau * PHY address
30809c80d176SSepherosa Ziehau */
30814be59a01SSepherosa Ziehau if (phy_type != e1000_phy_unknown)
30824be59a01SSepherosa Ziehau return E1000_SUCCESS;
30834be59a01SSepherosa Ziehau
30849c80d176SSepherosa Ziehau msec_delay(1);
30859c80d176SSepherosa Ziehau i++;
30869c80d176SSepherosa Ziehau } while (i < 10);
30879c80d176SSepherosa Ziehau }
30889c80d176SSepherosa Ziehau
30894be59a01SSepherosa Ziehau return -E1000_ERR_PHY_TYPE;
30909c80d176SSepherosa Ziehau }
30919c80d176SSepherosa Ziehau
30929c80d176SSepherosa Ziehau /**
30939c80d176SSepherosa Ziehau * e1000_get_phy_addr_for_bm_page - Retrieve PHY page address
30949c80d176SSepherosa Ziehau * @page: page to access
3095*01a55482SSepherosa Ziehau * @reg: register to access
30969c80d176SSepherosa Ziehau *
30979c80d176SSepherosa Ziehau * Returns the phy address for the page requested.
30989c80d176SSepherosa Ziehau **/
e1000_get_phy_addr_for_bm_page(u32 page,u32 reg)30999c80d176SSepherosa Ziehau static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg)
31009c80d176SSepherosa Ziehau {
31019c80d176SSepherosa Ziehau u32 phy_addr = 2;
31029c80d176SSepherosa Ziehau
31039c80d176SSepherosa Ziehau if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31))
31049c80d176SSepherosa Ziehau phy_addr = 1;
31059c80d176SSepherosa Ziehau
31069c80d176SSepherosa Ziehau return phy_addr;
31079c80d176SSepherosa Ziehau }
31089c80d176SSepherosa Ziehau
31099c80d176SSepherosa Ziehau /**
31109c80d176SSepherosa Ziehau * e1000_write_phy_reg_bm - Write BM PHY register
31119c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
31129c80d176SSepherosa Ziehau * @offset: register offset to write to
31139c80d176SSepherosa Ziehau * @data: data to write at register offset
31149c80d176SSepherosa Ziehau *
31159c80d176SSepherosa Ziehau * Acquires semaphore, if necessary, then writes the data to PHY register
31169c80d176SSepherosa Ziehau * at the offset. Release any acquired semaphores before exiting.
31179c80d176SSepherosa Ziehau **/
e1000_write_phy_reg_bm(struct e1000_hw * hw,u32 offset,u16 data)31189c80d176SSepherosa Ziehau s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
31199c80d176SSepherosa Ziehau {
31209c80d176SSepherosa Ziehau s32 ret_val;
31219c80d176SSepherosa Ziehau u32 page = offset >> IGP_PAGE_SHIFT;
31229c80d176SSepherosa Ziehau
31239c80d176SSepherosa Ziehau DEBUGFUNC("e1000_write_phy_reg_bm");
31249c80d176SSepherosa Ziehau
31256a5a645eSSepherosa Ziehau ret_val = hw->phy.ops.acquire(hw);
31266a5a645eSSepherosa Ziehau if (ret_val)
31276a5a645eSSepherosa Ziehau return ret_val;
31286a5a645eSSepherosa Ziehau
31299c80d176SSepherosa Ziehau /* Page 800 works differently than the rest so it has its own func */
31309c80d176SSepherosa Ziehau if (page == BM_WUC_PAGE) {
31319c80d176SSepherosa Ziehau ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
313265aebe9fSSepherosa Ziehau FALSE, false);
31334be59a01SSepherosa Ziehau goto release;
31349c80d176SSepherosa Ziehau }
31359c80d176SSepherosa Ziehau
31369c80d176SSepherosa Ziehau hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
31379c80d176SSepherosa Ziehau
31389c80d176SSepherosa Ziehau if (offset > MAX_PHY_MULTI_PAGE_REG) {
31396d5e2922SSepherosa Ziehau u32 page_shift, page_select;
31406d5e2922SSepherosa Ziehau
3141379ebbe7SSepherosa Ziehau /* Page select is register 31 for phy address 1 and 22 for
31429c80d176SSepherosa Ziehau * phy address 2 and 3. Page select is shifted only for
31439c80d176SSepherosa Ziehau * phy address 1.
31449c80d176SSepherosa Ziehau */
31459c80d176SSepherosa Ziehau if (hw->phy.addr == 1) {
31469c80d176SSepherosa Ziehau page_shift = IGP_PAGE_SHIFT;
31479c80d176SSepherosa Ziehau page_select = IGP01E1000_PHY_PAGE_SELECT;
31489c80d176SSepherosa Ziehau } else {
31499c80d176SSepherosa Ziehau page_shift = 0;
31509c80d176SSepherosa Ziehau page_select = BM_PHY_PAGE_SELECT;
31519c80d176SSepherosa Ziehau }
31529c80d176SSepherosa Ziehau
31539c80d176SSepherosa Ziehau /* Page is shifted left, PHY expects (page x 32) */
31549c80d176SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, page_select,
31559c80d176SSepherosa Ziehau (page << page_shift));
31566a5a645eSSepherosa Ziehau if (ret_val)
31574be59a01SSepherosa Ziehau goto release;
31589c80d176SSepherosa Ziehau }
31599c80d176SSepherosa Ziehau
31609c80d176SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
31619c80d176SSepherosa Ziehau data);
31629c80d176SSepherosa Ziehau
31634be59a01SSepherosa Ziehau release:
31646a5a645eSSepherosa Ziehau hw->phy.ops.release(hw);
31659c80d176SSepherosa Ziehau return ret_val;
31669c80d176SSepherosa Ziehau }
31679c80d176SSepherosa Ziehau
31689c80d176SSepherosa Ziehau /**
31699c80d176SSepherosa Ziehau * e1000_read_phy_reg_bm - Read BM PHY register
31709c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
31719c80d176SSepherosa Ziehau * @offset: register offset to be read
31729c80d176SSepherosa Ziehau * @data: pointer to the read data
31739c80d176SSepherosa Ziehau *
31749c80d176SSepherosa Ziehau * Acquires semaphore, if necessary, then reads the PHY register at offset
31759c80d176SSepherosa Ziehau * and storing the retrieved information in data. Release any acquired
31769c80d176SSepherosa Ziehau * semaphores before exiting.
31779c80d176SSepherosa Ziehau **/
e1000_read_phy_reg_bm(struct e1000_hw * hw,u32 offset,u16 * data)31789c80d176SSepherosa Ziehau s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
31799c80d176SSepherosa Ziehau {
31809c80d176SSepherosa Ziehau s32 ret_val;
31819c80d176SSepherosa Ziehau u32 page = offset >> IGP_PAGE_SHIFT;
31829c80d176SSepherosa Ziehau
31839c80d176SSepherosa Ziehau DEBUGFUNC("e1000_read_phy_reg_bm");
31849c80d176SSepherosa Ziehau
31856a5a645eSSepherosa Ziehau ret_val = hw->phy.ops.acquire(hw);
31866a5a645eSSepherosa Ziehau if (ret_val)
31876a5a645eSSepherosa Ziehau return ret_val;
31886a5a645eSSepherosa Ziehau
31899c80d176SSepherosa Ziehau /* Page 800 works differently than the rest so it has its own func */
31909c80d176SSepherosa Ziehau if (page == BM_WUC_PAGE) {
31919c80d176SSepherosa Ziehau ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
31926d5e2922SSepherosa Ziehau TRUE, FALSE);
31934be59a01SSepherosa Ziehau goto release;
31949c80d176SSepherosa Ziehau }
31959c80d176SSepherosa Ziehau
31969c80d176SSepherosa Ziehau hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
31979c80d176SSepherosa Ziehau
31989c80d176SSepherosa Ziehau if (offset > MAX_PHY_MULTI_PAGE_REG) {
31996d5e2922SSepherosa Ziehau u32 page_shift, page_select;
32006d5e2922SSepherosa Ziehau
3201379ebbe7SSepherosa Ziehau /* Page select is register 31 for phy address 1 and 22 for
32029c80d176SSepherosa Ziehau * phy address 2 and 3. Page select is shifted only for
32039c80d176SSepherosa Ziehau * phy address 1.
32049c80d176SSepherosa Ziehau */
32059c80d176SSepherosa Ziehau if (hw->phy.addr == 1) {
32069c80d176SSepherosa Ziehau page_shift = IGP_PAGE_SHIFT;
32079c80d176SSepherosa Ziehau page_select = IGP01E1000_PHY_PAGE_SELECT;
32089c80d176SSepherosa Ziehau } else {
32099c80d176SSepherosa Ziehau page_shift = 0;
32109c80d176SSepherosa Ziehau page_select = BM_PHY_PAGE_SELECT;
32119c80d176SSepherosa Ziehau }
32129c80d176SSepherosa Ziehau
32139c80d176SSepherosa Ziehau /* Page is shifted left, PHY expects (page x 32) */
32149c80d176SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, page_select,
32159c80d176SSepherosa Ziehau (page << page_shift));
32166a5a645eSSepherosa Ziehau if (ret_val)
32174be59a01SSepherosa Ziehau goto release;
32189c80d176SSepherosa Ziehau }
32199c80d176SSepherosa Ziehau
32209c80d176SSepherosa Ziehau ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
32219c80d176SSepherosa Ziehau data);
32224be59a01SSepherosa Ziehau release:
32236a5a645eSSepherosa Ziehau hw->phy.ops.release(hw);
32249c80d176SSepherosa Ziehau return ret_val;
32259c80d176SSepherosa Ziehau }
32269c80d176SSepherosa Ziehau
32279c80d176SSepherosa Ziehau /**
32289c80d176SSepherosa Ziehau * e1000_read_phy_reg_bm2 - Read BM PHY register
32299c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
32309c80d176SSepherosa Ziehau * @offset: register offset to be read
32319c80d176SSepherosa Ziehau * @data: pointer to the read data
32329c80d176SSepherosa Ziehau *
32339c80d176SSepherosa Ziehau * Acquires semaphore, if necessary, then reads the PHY register at offset
32349c80d176SSepherosa Ziehau * and storing the retrieved information in data. Release any acquired
32359c80d176SSepherosa Ziehau * semaphores before exiting.
32369c80d176SSepherosa Ziehau **/
e1000_read_phy_reg_bm2(struct e1000_hw * hw,u32 offset,u16 * data)32379c80d176SSepherosa Ziehau s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
32389c80d176SSepherosa Ziehau {
32399c80d176SSepherosa Ziehau s32 ret_val;
32409c80d176SSepherosa Ziehau u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
32419c80d176SSepherosa Ziehau
32426d5e2922SSepherosa Ziehau DEBUGFUNC("e1000_read_phy_reg_bm2");
32439c80d176SSepherosa Ziehau
32446a5a645eSSepherosa Ziehau ret_val = hw->phy.ops.acquire(hw);
32456a5a645eSSepherosa Ziehau if (ret_val)
32466a5a645eSSepherosa Ziehau return ret_val;
32476a5a645eSSepherosa Ziehau
32489c80d176SSepherosa Ziehau /* Page 800 works differently than the rest so it has its own func */
32499c80d176SSepherosa Ziehau if (page == BM_WUC_PAGE) {
32509c80d176SSepherosa Ziehau ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
32516d5e2922SSepherosa Ziehau TRUE, FALSE);
32524be59a01SSepherosa Ziehau goto release;
32539c80d176SSepherosa Ziehau }
32549c80d176SSepherosa Ziehau
32559c80d176SSepherosa Ziehau hw->phy.addr = 1;
32569c80d176SSepherosa Ziehau
32579c80d176SSepherosa Ziehau if (offset > MAX_PHY_MULTI_PAGE_REG) {
32589c80d176SSepherosa Ziehau /* Page is shifted left, PHY expects (page x 32) */
32599c80d176SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
32609c80d176SSepherosa Ziehau page);
32619c80d176SSepherosa Ziehau
32626a5a645eSSepherosa Ziehau if (ret_val)
32634be59a01SSepherosa Ziehau goto release;
32649c80d176SSepherosa Ziehau }
32659c80d176SSepherosa Ziehau
32669c80d176SSepherosa Ziehau ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
32679c80d176SSepherosa Ziehau data);
32684be59a01SSepherosa Ziehau release:
32696a5a645eSSepherosa Ziehau hw->phy.ops.release(hw);
32709c80d176SSepherosa Ziehau return ret_val;
32719c80d176SSepherosa Ziehau }
32729c80d176SSepherosa Ziehau
32739c80d176SSepherosa Ziehau /**
32749c80d176SSepherosa Ziehau * e1000_write_phy_reg_bm2 - Write BM PHY register
32759c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
32769c80d176SSepherosa Ziehau * @offset: register offset to write to
32779c80d176SSepherosa Ziehau * @data: data to write at register offset
32789c80d176SSepherosa Ziehau *
32799c80d176SSepherosa Ziehau * Acquires semaphore, if necessary, then writes the data to PHY register
32809c80d176SSepherosa Ziehau * at the offset. Release any acquired semaphores before exiting.
32819c80d176SSepherosa Ziehau **/
e1000_write_phy_reg_bm2(struct e1000_hw * hw,u32 offset,u16 data)32829c80d176SSepherosa Ziehau s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
32839c80d176SSepherosa Ziehau {
32849c80d176SSepherosa Ziehau s32 ret_val;
32859c80d176SSepherosa Ziehau u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
32869c80d176SSepherosa Ziehau
32879c80d176SSepherosa Ziehau DEBUGFUNC("e1000_write_phy_reg_bm2");
32889c80d176SSepherosa Ziehau
32896a5a645eSSepherosa Ziehau ret_val = hw->phy.ops.acquire(hw);
32906a5a645eSSepherosa Ziehau if (ret_val)
32916a5a645eSSepherosa Ziehau return ret_val;
32926a5a645eSSepherosa Ziehau
32939c80d176SSepherosa Ziehau /* Page 800 works differently than the rest so it has its own func */
32949c80d176SSepherosa Ziehau if (page == BM_WUC_PAGE) {
32959c80d176SSepherosa Ziehau ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
329665aebe9fSSepherosa Ziehau FALSE, false);
32974be59a01SSepherosa Ziehau goto release;
32989c80d176SSepherosa Ziehau }
32999c80d176SSepherosa Ziehau
33009c80d176SSepherosa Ziehau hw->phy.addr = 1;
33019c80d176SSepherosa Ziehau
33029c80d176SSepherosa Ziehau if (offset > MAX_PHY_MULTI_PAGE_REG) {
33039c80d176SSepherosa Ziehau /* Page is shifted left, PHY expects (page x 32) */
33049c80d176SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
33059c80d176SSepherosa Ziehau page);
33069c80d176SSepherosa Ziehau
33076a5a645eSSepherosa Ziehau if (ret_val)
33084be59a01SSepherosa Ziehau goto release;
33099c80d176SSepherosa Ziehau }
33109c80d176SSepherosa Ziehau
33119c80d176SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
33129c80d176SSepherosa Ziehau data);
33139c80d176SSepherosa Ziehau
33144be59a01SSepherosa Ziehau release:
33156a5a645eSSepherosa Ziehau hw->phy.ops.release(hw);
33169c80d176SSepherosa Ziehau return ret_val;
33179c80d176SSepherosa Ziehau }
33189c80d176SSepherosa Ziehau
33199c80d176SSepherosa Ziehau /**
33206d5e2922SSepherosa Ziehau * e1000_enable_phy_wakeup_reg_access_bm - enable access to BM wakeup registers
33216d5e2922SSepherosa Ziehau * @hw: pointer to the HW structure
33226d5e2922SSepherosa Ziehau * @phy_reg: pointer to store original contents of BM_WUC_ENABLE_REG
33236d5e2922SSepherosa Ziehau *
33246d5e2922SSepherosa Ziehau * Assumes semaphore already acquired and phy_reg points to a valid memory
33256d5e2922SSepherosa Ziehau * address to store contents of the BM_WUC_ENABLE_REG register.
33266d5e2922SSepherosa Ziehau **/
e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw * hw,u16 * phy_reg)33276d5e2922SSepherosa Ziehau s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
33286d5e2922SSepherosa Ziehau {
33296d5e2922SSepherosa Ziehau s32 ret_val;
33306d5e2922SSepherosa Ziehau u16 temp;
33316d5e2922SSepherosa Ziehau
33326d5e2922SSepherosa Ziehau DEBUGFUNC("e1000_enable_phy_wakeup_reg_access_bm");
33336d5e2922SSepherosa Ziehau
33344be59a01SSepherosa Ziehau if (!phy_reg)
33354be59a01SSepherosa Ziehau return -E1000_ERR_PARAM;
33366d5e2922SSepherosa Ziehau
33376d5e2922SSepherosa Ziehau /* All page select, port ctrl and wakeup registers use phy address 1 */
33386d5e2922SSepherosa Ziehau hw->phy.addr = 1;
33396d5e2922SSepherosa Ziehau
33406d5e2922SSepherosa Ziehau /* Select Port Control Registers page */
33416d5e2922SSepherosa Ziehau ret_val = e1000_set_page_igp(hw, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
33426d5e2922SSepherosa Ziehau if (ret_val) {
33436d5e2922SSepherosa Ziehau DEBUGOUT("Could not set Port Control page\n");
33444be59a01SSepherosa Ziehau return ret_val;
33456d5e2922SSepherosa Ziehau }
33466d5e2922SSepherosa Ziehau
33476d5e2922SSepherosa Ziehau ret_val = e1000_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
33486d5e2922SSepherosa Ziehau if (ret_val) {
33496d5e2922SSepherosa Ziehau DEBUGOUT2("Could not read PHY register %d.%d\n",
33506d5e2922SSepherosa Ziehau BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG);
33514be59a01SSepherosa Ziehau return ret_val;
33526d5e2922SSepherosa Ziehau }
33536d5e2922SSepherosa Ziehau
3354379ebbe7SSepherosa Ziehau /* Enable both PHY wakeup mode and Wakeup register page writes.
33556d5e2922SSepherosa Ziehau * Prevent a power state change by disabling ME and Host PHY wakeup.
33566d5e2922SSepherosa Ziehau */
33576d5e2922SSepherosa Ziehau temp = *phy_reg;
33586d5e2922SSepherosa Ziehau temp |= BM_WUC_ENABLE_BIT;
33596d5e2922SSepherosa Ziehau temp &= ~(BM_WUC_ME_WU_BIT | BM_WUC_HOST_WU_BIT);
33606d5e2922SSepherosa Ziehau
33616d5e2922SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, temp);
33626d5e2922SSepherosa Ziehau if (ret_val) {
33636d5e2922SSepherosa Ziehau DEBUGOUT2("Could not write PHY register %d.%d\n",
33646d5e2922SSepherosa Ziehau BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG);
33654be59a01SSepherosa Ziehau return ret_val;
33666d5e2922SSepherosa Ziehau }
33676d5e2922SSepherosa Ziehau
3368379ebbe7SSepherosa Ziehau /* Select Host Wakeup Registers page - caller now able to write
33694be59a01SSepherosa Ziehau * registers on the Wakeup registers page
33704be59a01SSepherosa Ziehau */
33714be59a01SSepherosa Ziehau return e1000_set_page_igp(hw, (BM_WUC_PAGE << IGP_PAGE_SHIFT));
33726d5e2922SSepherosa Ziehau }
33736d5e2922SSepherosa Ziehau
33746d5e2922SSepherosa Ziehau /**
33756d5e2922SSepherosa Ziehau * e1000_disable_phy_wakeup_reg_access_bm - disable access to BM wakeup regs
33766d5e2922SSepherosa Ziehau * @hw: pointer to the HW structure
33776d5e2922SSepherosa Ziehau * @phy_reg: pointer to original contents of BM_WUC_ENABLE_REG
33786d5e2922SSepherosa Ziehau *
33796d5e2922SSepherosa Ziehau * Restore BM_WUC_ENABLE_REG to its original value.
33806d5e2922SSepherosa Ziehau *
33816d5e2922SSepherosa Ziehau * Assumes semaphore already acquired and *phy_reg is the contents of the
33826d5e2922SSepherosa Ziehau * BM_WUC_ENABLE_REG before register(s) on BM_WUC_PAGE were accessed by
33836d5e2922SSepherosa Ziehau * caller.
33846d5e2922SSepherosa Ziehau **/
e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw * hw,u16 * phy_reg)33856d5e2922SSepherosa Ziehau s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
33866d5e2922SSepherosa Ziehau {
3387379ebbe7SSepherosa Ziehau s32 ret_val;
33886d5e2922SSepherosa Ziehau
33896d5e2922SSepherosa Ziehau DEBUGFUNC("e1000_disable_phy_wakeup_reg_access_bm");
33906d5e2922SSepherosa Ziehau
33916d5e2922SSepherosa Ziehau if (!phy_reg)
33926d5e2922SSepherosa Ziehau return -E1000_ERR_PARAM;
33936d5e2922SSepherosa Ziehau
33946d5e2922SSepherosa Ziehau /* Select Port Control Registers page */
33956d5e2922SSepherosa Ziehau ret_val = e1000_set_page_igp(hw, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
33966d5e2922SSepherosa Ziehau if (ret_val) {
33976d5e2922SSepherosa Ziehau DEBUGOUT("Could not set Port Control page\n");
33984be59a01SSepherosa Ziehau return ret_val;
33996d5e2922SSepherosa Ziehau }
34006d5e2922SSepherosa Ziehau
34016d5e2922SSepherosa Ziehau /* Restore 769.17 to its original value */
34026d5e2922SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, *phy_reg);
34036d5e2922SSepherosa Ziehau if (ret_val)
34046d5e2922SSepherosa Ziehau DEBUGOUT2("Could not restore PHY register %d.%d\n",
34056d5e2922SSepherosa Ziehau BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG);
34064be59a01SSepherosa Ziehau
34076d5e2922SSepherosa Ziehau return ret_val;
34086d5e2922SSepherosa Ziehau }
34096d5e2922SSepherosa Ziehau
34106d5e2922SSepherosa Ziehau /**
34116d5e2922SSepherosa Ziehau * e1000_access_phy_wakeup_reg_bm - Read/write BM PHY wakeup register
34129c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
34139c80d176SSepherosa Ziehau * @offset: register offset to be read or written
34149c80d176SSepherosa Ziehau * @data: pointer to the data to read or write
34159c80d176SSepherosa Ziehau * @read: determines if operation is read or write
34166d5e2922SSepherosa Ziehau * @page_set: BM_WUC_PAGE already set and access enabled
34179c80d176SSepherosa Ziehau *
34186d5e2922SSepherosa Ziehau * Read the PHY register at offset and store the retrieved information in
34196d5e2922SSepherosa Ziehau * data, or write data to PHY register at offset. Note the procedure to
34206d5e2922SSepherosa Ziehau * access the PHY wakeup registers is different than reading the other PHY
34216d5e2922SSepherosa Ziehau * registers. It works as such:
34226d5e2922SSepherosa Ziehau * 1) Set 769.17.2 (page 769, register 17, bit 2) = 1
34239c80d176SSepherosa Ziehau * 2) Set page to 800 for host (801 if we were manageability)
34249c80d176SSepherosa Ziehau * 3) Write the address using the address opcode (0x11)
34259c80d176SSepherosa Ziehau * 4) Read or write the data using the data opcode (0x12)
34266d5e2922SSepherosa Ziehau * 5) Restore 769.17.2 to its original value
34276a5a645eSSepherosa Ziehau *
34286d5e2922SSepherosa Ziehau * Steps 1 and 2 are done by e1000_enable_phy_wakeup_reg_access_bm() and
34296d5e2922SSepherosa Ziehau * step 5 is done by e1000_disable_phy_wakeup_reg_access_bm().
34306d5e2922SSepherosa Ziehau *
34316d5e2922SSepherosa Ziehau * Assumes semaphore is already acquired. When page_set==TRUE, assumes
34326d5e2922SSepherosa Ziehau * the PHY page is set to BM_WUC_PAGE (i.e. a function in the call stack
34336d5e2922SSepherosa Ziehau * is responsible for calls to e1000_[enable|disable]_phy_wakeup_reg_bm()).
34349c80d176SSepherosa Ziehau **/
e1000_access_phy_wakeup_reg_bm(struct e1000_hw * hw,u32 offset,u16 * data,bool read,bool page_set)34359c80d176SSepherosa Ziehau static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
34366d5e2922SSepherosa Ziehau u16 *data, bool read, bool page_set)
34379c80d176SSepherosa Ziehau {
34389c80d176SSepherosa Ziehau s32 ret_val;
343974dc3754SSepherosa Ziehau u16 reg = BM_PHY_REG_NUM(offset);
344074dc3754SSepherosa Ziehau u16 page = BM_PHY_REG_PAGE(offset);
34419c80d176SSepherosa Ziehau u16 phy_reg = 0;
34429c80d176SSepherosa Ziehau
34436a5a645eSSepherosa Ziehau DEBUGFUNC("e1000_access_phy_wakeup_reg_bm");
34449c80d176SSepherosa Ziehau
34456d5e2922SSepherosa Ziehau /* Gig must be disabled for MDIO accesses to Host Wakeup reg page */
34466a5a645eSSepherosa Ziehau if ((hw->mac.type == e1000_pchlan) &&
34476a5a645eSSepherosa Ziehau (!(E1000_READ_REG(hw, E1000_PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)))
34486d5e2922SSepherosa Ziehau DEBUGOUT1("Attempting to access page %d while gig enabled.\n",
34496d5e2922SSepherosa Ziehau page);
34509c80d176SSepherosa Ziehau
34516d5e2922SSepherosa Ziehau if (!page_set) {
34526d5e2922SSepherosa Ziehau /* Enable access to PHY wakeup registers */
34536d5e2922SSepherosa Ziehau ret_val = e1000_enable_phy_wakeup_reg_access_bm(hw, &phy_reg);
34549c80d176SSepherosa Ziehau if (ret_val) {
34556d5e2922SSepherosa Ziehau DEBUGOUT("Could not enable PHY wakeup reg access\n");
34564be59a01SSepherosa Ziehau return ret_val;
34579c80d176SSepherosa Ziehau }
34589c80d176SSepherosa Ziehau }
34599c80d176SSepherosa Ziehau
34606d5e2922SSepherosa Ziehau DEBUGOUT2("Accessing PHY page %d reg 0x%x\n", page, reg);
34619c80d176SSepherosa Ziehau
34626d5e2922SSepherosa Ziehau /* Write the Wakeup register page offset value using opcode 0x11 */
34639c80d176SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg);
34649c80d176SSepherosa Ziehau if (ret_val) {
34656d5e2922SSepherosa Ziehau DEBUGOUT1("Could not write address opcode to page %d\n", page);
34664be59a01SSepherosa Ziehau return ret_val;
34679c80d176SSepherosa Ziehau }
34689c80d176SSepherosa Ziehau
34699c80d176SSepherosa Ziehau if (read) {
34706d5e2922SSepherosa Ziehau /* Read the Wakeup register page value using opcode 0x12 */
34719c80d176SSepherosa Ziehau ret_val = e1000_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
34729c80d176SSepherosa Ziehau data);
34739c80d176SSepherosa Ziehau } else {
34746d5e2922SSepherosa Ziehau /* Write the Wakeup register page value using opcode 0x12 */
34759c80d176SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
34769c80d176SSepherosa Ziehau *data);
34779c80d176SSepherosa Ziehau }
34789c80d176SSepherosa Ziehau
34799c80d176SSepherosa Ziehau if (ret_val) {
34806d5e2922SSepherosa Ziehau DEBUGOUT2("Could not access PHY reg %d.%d\n", page, reg);
34814be59a01SSepherosa Ziehau return ret_val;
34829c80d176SSepherosa Ziehau }
34839c80d176SSepherosa Ziehau
34846d5e2922SSepherosa Ziehau if (!page_set)
34856d5e2922SSepherosa Ziehau ret_val = e1000_disable_phy_wakeup_reg_access_bm(hw, &phy_reg);
34869c80d176SSepherosa Ziehau
34879c80d176SSepherosa Ziehau return ret_val;
34889c80d176SSepherosa Ziehau }
34899c80d176SSepherosa Ziehau
34909c80d176SSepherosa Ziehau /**
34919c80d176SSepherosa Ziehau * e1000_power_up_phy_copper - Restore copper link in case of PHY power down
34929c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
34939c80d176SSepherosa Ziehau *
34949c80d176SSepherosa Ziehau * In the case of a PHY power down to save power, or to turn off link during a
34959c80d176SSepherosa Ziehau * driver unload, or wake on lan is not enabled, restore the link to previous
34969c80d176SSepherosa Ziehau * settings.
34979c80d176SSepherosa Ziehau **/
e1000_power_up_phy_copper(struct e1000_hw * hw)34989c80d176SSepherosa Ziehau void e1000_power_up_phy_copper(struct e1000_hw *hw)
34999c80d176SSepherosa Ziehau {
35009c80d176SSepherosa Ziehau u16 mii_reg = 0;
35019c80d176SSepherosa Ziehau
35029c80d176SSepherosa Ziehau /* The PHY will retain its settings across a power down/up cycle */
35039c80d176SSepherosa Ziehau hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
35049c80d176SSepherosa Ziehau mii_reg &= ~MII_CR_POWER_DOWN;
35059c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
35069c80d176SSepherosa Ziehau }
35079c80d176SSepherosa Ziehau
35089c80d176SSepherosa Ziehau /**
35099c80d176SSepherosa Ziehau * e1000_power_down_phy_copper - Restore copper link in case of PHY power down
35109c80d176SSepherosa Ziehau * @hw: pointer to the HW structure
35119c80d176SSepherosa Ziehau *
35129c80d176SSepherosa Ziehau * In the case of a PHY power down to save power, or to turn off link during a
35139c80d176SSepherosa Ziehau * driver unload, or wake on lan is not enabled, restore the link to previous
35149c80d176SSepherosa Ziehau * settings.
35159c80d176SSepherosa Ziehau **/
e1000_power_down_phy_copper(struct e1000_hw * hw)35169c80d176SSepherosa Ziehau void e1000_power_down_phy_copper(struct e1000_hw *hw)
35179c80d176SSepherosa Ziehau {
35189c80d176SSepherosa Ziehau u16 mii_reg = 0;
35199c80d176SSepherosa Ziehau
35209c80d176SSepherosa Ziehau /* The PHY will retain its settings across a power down/up cycle */
35219c80d176SSepherosa Ziehau hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
35229c80d176SSepherosa Ziehau mii_reg |= MII_CR_POWER_DOWN;
35239c80d176SSepherosa Ziehau hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
35249c80d176SSepherosa Ziehau msec_delay(1);
35259c80d176SSepherosa Ziehau }
35266a5a645eSSepherosa Ziehau
35276a5a645eSSepherosa Ziehau /**
35286a5a645eSSepherosa Ziehau * __e1000_read_phy_reg_hv - Read HV PHY register
35296a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
35306a5a645eSSepherosa Ziehau * @offset: register offset to be read
35316a5a645eSSepherosa Ziehau * @data: pointer to the read data
35326a5a645eSSepherosa Ziehau * @locked: semaphore has already been acquired or not
3533*01a55482SSepherosa Ziehau * @page_set: BM_WUC_PAGE already set and access enabled
35346a5a645eSSepherosa Ziehau *
35356a5a645eSSepherosa Ziehau * Acquires semaphore, if necessary, then reads the PHY register at offset
35366a5a645eSSepherosa Ziehau * and stores the retrieved information in data. Release any acquired
35376a5a645eSSepherosa Ziehau * semaphore before exiting.
35386a5a645eSSepherosa Ziehau **/
__e1000_read_phy_reg_hv(struct e1000_hw * hw,u32 offset,u16 * data,bool locked,bool page_set)35396a5a645eSSepherosa Ziehau static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data,
35406d5e2922SSepherosa Ziehau bool locked, bool page_set)
35416a5a645eSSepherosa Ziehau {
35426a5a645eSSepherosa Ziehau s32 ret_val;
35436a5a645eSSepherosa Ziehau u16 page = BM_PHY_REG_PAGE(offset);
35446a5a645eSSepherosa Ziehau u16 reg = BM_PHY_REG_NUM(offset);
35456d5e2922SSepherosa Ziehau u32 phy_addr = hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
35466a5a645eSSepherosa Ziehau
35476a5a645eSSepherosa Ziehau DEBUGFUNC("__e1000_read_phy_reg_hv");
35486a5a645eSSepherosa Ziehau
35496a5a645eSSepherosa Ziehau if (!locked) {
35506a5a645eSSepherosa Ziehau ret_val = hw->phy.ops.acquire(hw);
35516a5a645eSSepherosa Ziehau if (ret_val)
35526a5a645eSSepherosa Ziehau return ret_val;
35536a5a645eSSepherosa Ziehau }
35546a5a645eSSepherosa Ziehau /* Page 800 works differently than the rest so it has its own func */
35556a5a645eSSepherosa Ziehau if (page == BM_WUC_PAGE) {
35566d5e2922SSepherosa Ziehau ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
35576d5e2922SSepherosa Ziehau TRUE, page_set);
35586a5a645eSSepherosa Ziehau goto out;
35596a5a645eSSepherosa Ziehau }
35606a5a645eSSepherosa Ziehau
35616a5a645eSSepherosa Ziehau if (page > 0 && page < HV_INTC_FC_PAGE_START) {
35626a5a645eSSepherosa Ziehau ret_val = e1000_access_phy_debug_regs_hv(hw, offset,
35636a5a645eSSepherosa Ziehau data, TRUE);
35646a5a645eSSepherosa Ziehau goto out;
35656a5a645eSSepherosa Ziehau }
35666a5a645eSSepherosa Ziehau
35676d5e2922SSepherosa Ziehau if (!page_set) {
35686a5a645eSSepherosa Ziehau if (page == HV_INTC_FC_PAGE_START)
35696a5a645eSSepherosa Ziehau page = 0;
35706a5a645eSSepherosa Ziehau
35716a5a645eSSepherosa Ziehau if (reg > MAX_PHY_MULTI_PAGE_REG) {
35726a5a645eSSepherosa Ziehau /* Page is shifted left, PHY expects (page x 32) */
35736d5e2922SSepherosa Ziehau ret_val = e1000_set_page_igp(hw,
35746a5a645eSSepherosa Ziehau (page << IGP_PAGE_SHIFT));
35756d5e2922SSepherosa Ziehau
35766a5a645eSSepherosa Ziehau hw->phy.addr = phy_addr;
35776a5a645eSSepherosa Ziehau
35786a5a645eSSepherosa Ziehau if (ret_val)
35796a5a645eSSepherosa Ziehau goto out;
35806a5a645eSSepherosa Ziehau }
35816d5e2922SSepherosa Ziehau }
35826d5e2922SSepherosa Ziehau
35836d5e2922SSepherosa Ziehau DEBUGOUT3("reading PHY page %d (or 0x%x shifted) reg 0x%x\n", page,
35846d5e2922SSepherosa Ziehau page << IGP_PAGE_SHIFT, reg);
35856a5a645eSSepherosa Ziehau
35866a5a645eSSepherosa Ziehau ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
35876a5a645eSSepherosa Ziehau data);
35886a5a645eSSepherosa Ziehau out:
35896a5a645eSSepherosa Ziehau if (!locked)
35906a5a645eSSepherosa Ziehau hw->phy.ops.release(hw);
35916a5a645eSSepherosa Ziehau
35926a5a645eSSepherosa Ziehau return ret_val;
35936a5a645eSSepherosa Ziehau }
35946a5a645eSSepherosa Ziehau
35956a5a645eSSepherosa Ziehau /**
35966a5a645eSSepherosa Ziehau * e1000_read_phy_reg_hv - Read HV PHY register
35976a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
35986a5a645eSSepherosa Ziehau * @offset: register offset to be read
35996a5a645eSSepherosa Ziehau * @data: pointer to the read data
36006a5a645eSSepherosa Ziehau *
36016a5a645eSSepherosa Ziehau * Acquires semaphore then reads the PHY register at offset and stores
36026a5a645eSSepherosa Ziehau * the retrieved information in data. Release the acquired semaphore
36036a5a645eSSepherosa Ziehau * before exiting.
36046a5a645eSSepherosa Ziehau **/
e1000_read_phy_reg_hv(struct e1000_hw * hw,u32 offset,u16 * data)36056a5a645eSSepherosa Ziehau s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
36066a5a645eSSepherosa Ziehau {
360765aebe9fSSepherosa Ziehau return __e1000_read_phy_reg_hv(hw, offset, data, FALSE, false);
36086a5a645eSSepherosa Ziehau }
36096a5a645eSSepherosa Ziehau
36106a5a645eSSepherosa Ziehau /**
36116a5a645eSSepherosa Ziehau * e1000_read_phy_reg_hv_locked - Read HV PHY register
36126a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
36136a5a645eSSepherosa Ziehau * @offset: register offset to be read
36146a5a645eSSepherosa Ziehau * @data: pointer to the read data
36156a5a645eSSepherosa Ziehau *
36166a5a645eSSepherosa Ziehau * Reads the PHY register at offset and stores the retrieved information
36176a5a645eSSepherosa Ziehau * in data. Assumes semaphore already acquired.
36186a5a645eSSepherosa Ziehau **/
e1000_read_phy_reg_hv_locked(struct e1000_hw * hw,u32 offset,u16 * data)36196a5a645eSSepherosa Ziehau s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data)
36206a5a645eSSepherosa Ziehau {
36216d5e2922SSepherosa Ziehau return __e1000_read_phy_reg_hv(hw, offset, data, TRUE, FALSE);
36226d5e2922SSepherosa Ziehau }
36236d5e2922SSepherosa Ziehau
36246d5e2922SSepherosa Ziehau /**
36256d5e2922SSepherosa Ziehau * e1000_read_phy_reg_page_hv - Read HV PHY register
36266d5e2922SSepherosa Ziehau * @hw: pointer to the HW structure
36276d5e2922SSepherosa Ziehau * @offset: register offset to write to
36286d5e2922SSepherosa Ziehau * @data: data to write at register offset
36296d5e2922SSepherosa Ziehau *
36306d5e2922SSepherosa Ziehau * Reads the PHY register at offset and stores the retrieved information
36316d5e2922SSepherosa Ziehau * in data. Assumes semaphore already acquired and page already set.
36326d5e2922SSepherosa Ziehau **/
e1000_read_phy_reg_page_hv(struct e1000_hw * hw,u32 offset,u16 * data)36336d5e2922SSepherosa Ziehau s32 e1000_read_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 *data)
36346d5e2922SSepherosa Ziehau {
363565aebe9fSSepherosa Ziehau return __e1000_read_phy_reg_hv(hw, offset, data, TRUE, true);
36366a5a645eSSepherosa Ziehau }
36376a5a645eSSepherosa Ziehau
36386a5a645eSSepherosa Ziehau /**
36396a5a645eSSepherosa Ziehau * __e1000_write_phy_reg_hv - Write HV PHY register
36406a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
36416a5a645eSSepherosa Ziehau * @offset: register offset to write to
36426a5a645eSSepherosa Ziehau * @data: data to write at register offset
36436a5a645eSSepherosa Ziehau * @locked: semaphore has already been acquired or not
3644*01a55482SSepherosa Ziehau * @page_set: BM_WUC_PAGE already set and access enabled
36456a5a645eSSepherosa Ziehau *
36466a5a645eSSepherosa Ziehau * Acquires semaphore, if necessary, then writes the data to PHY register
36476a5a645eSSepherosa Ziehau * at the offset. Release any acquired semaphores before exiting.
36486a5a645eSSepherosa Ziehau **/
__e1000_write_phy_reg_hv(struct e1000_hw * hw,u32 offset,u16 data,bool locked,bool page_set)36496a5a645eSSepherosa Ziehau static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
36506d5e2922SSepherosa Ziehau bool locked, bool page_set)
36516a5a645eSSepherosa Ziehau {
36526a5a645eSSepherosa Ziehau s32 ret_val;
36536a5a645eSSepherosa Ziehau u16 page = BM_PHY_REG_PAGE(offset);
36546a5a645eSSepherosa Ziehau u16 reg = BM_PHY_REG_NUM(offset);
36556d5e2922SSepherosa Ziehau u32 phy_addr = hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
36566a5a645eSSepherosa Ziehau
36576a5a645eSSepherosa Ziehau DEBUGFUNC("__e1000_write_phy_reg_hv");
36586a5a645eSSepherosa Ziehau
36596a5a645eSSepherosa Ziehau if (!locked) {
36606a5a645eSSepherosa Ziehau ret_val = hw->phy.ops.acquire(hw);
36616a5a645eSSepherosa Ziehau if (ret_val)
36626a5a645eSSepherosa Ziehau return ret_val;
36636a5a645eSSepherosa Ziehau }
36646a5a645eSSepherosa Ziehau /* Page 800 works differently than the rest so it has its own func */
36656a5a645eSSepherosa Ziehau if (page == BM_WUC_PAGE) {
36666d5e2922SSepherosa Ziehau ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
36676d5e2922SSepherosa Ziehau FALSE, page_set);
36686a5a645eSSepherosa Ziehau goto out;
36696a5a645eSSepherosa Ziehau }
36706a5a645eSSepherosa Ziehau
36716a5a645eSSepherosa Ziehau if (page > 0 && page < HV_INTC_FC_PAGE_START) {
36726a5a645eSSepherosa Ziehau ret_val = e1000_access_phy_debug_regs_hv(hw, offset,
36736a5a645eSSepherosa Ziehau &data, FALSE);
36746a5a645eSSepherosa Ziehau goto out;
36756a5a645eSSepherosa Ziehau }
36766a5a645eSSepherosa Ziehau
36776d5e2922SSepherosa Ziehau if (!page_set) {
36786a5a645eSSepherosa Ziehau if (page == HV_INTC_FC_PAGE_START)
36796a5a645eSSepherosa Ziehau page = 0;
36806a5a645eSSepherosa Ziehau
3681379ebbe7SSepherosa Ziehau /* Workaround MDIO accesses being disabled after entering IEEE
36826d5e2922SSepherosa Ziehau * Power Down (when bit 11 of the PHY Control register is set)
36836a5a645eSSepherosa Ziehau */
36846a5a645eSSepherosa Ziehau if ((hw->phy.type == e1000_phy_82578) &&
36856a5a645eSSepherosa Ziehau (hw->phy.revision >= 1) &&
36866a5a645eSSepherosa Ziehau (hw->phy.addr == 2) &&
3687379ebbe7SSepherosa Ziehau !(MAX_PHY_REG_ADDRESS & reg) &&
36886a5a645eSSepherosa Ziehau (data & (1 << 11))) {
36896a5a645eSSepherosa Ziehau u16 data2 = 0x7EFF;
36906d5e2922SSepherosa Ziehau ret_val = e1000_access_phy_debug_regs_hv(hw,
36916d5e2922SSepherosa Ziehau (1 << 6) | 0x3,
36926a5a645eSSepherosa Ziehau &data2, FALSE);
36936a5a645eSSepherosa Ziehau if (ret_val)
36946a5a645eSSepherosa Ziehau goto out;
36956a5a645eSSepherosa Ziehau }
36966a5a645eSSepherosa Ziehau
36976a5a645eSSepherosa Ziehau if (reg > MAX_PHY_MULTI_PAGE_REG) {
36986a5a645eSSepherosa Ziehau /* Page is shifted left, PHY expects (page x 32) */
36996d5e2922SSepherosa Ziehau ret_val = e1000_set_page_igp(hw,
37006a5a645eSSepherosa Ziehau (page << IGP_PAGE_SHIFT));
37016d5e2922SSepherosa Ziehau
37026a5a645eSSepherosa Ziehau hw->phy.addr = phy_addr;
37036a5a645eSSepherosa Ziehau
37046a5a645eSSepherosa Ziehau if (ret_val)
37056a5a645eSSepherosa Ziehau goto out;
37066a5a645eSSepherosa Ziehau }
37076d5e2922SSepherosa Ziehau }
37086d5e2922SSepherosa Ziehau
37096d5e2922SSepherosa Ziehau DEBUGOUT3("writing PHY page %d (or 0x%x shifted) reg 0x%x\n", page,
37106d5e2922SSepherosa Ziehau page << IGP_PAGE_SHIFT, reg);
37116a5a645eSSepherosa Ziehau
37126a5a645eSSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
37136a5a645eSSepherosa Ziehau data);
37146a5a645eSSepherosa Ziehau
37156a5a645eSSepherosa Ziehau out:
37166a5a645eSSepherosa Ziehau if (!locked)
37176a5a645eSSepherosa Ziehau hw->phy.ops.release(hw);
37186a5a645eSSepherosa Ziehau
37196a5a645eSSepherosa Ziehau return ret_val;
37206a5a645eSSepherosa Ziehau }
37216a5a645eSSepherosa Ziehau
37226a5a645eSSepherosa Ziehau /**
37236a5a645eSSepherosa Ziehau * e1000_write_phy_reg_hv - Write HV PHY register
37246a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
37256a5a645eSSepherosa Ziehau * @offset: register offset to write to
37266a5a645eSSepherosa Ziehau * @data: data to write at register offset
37276a5a645eSSepherosa Ziehau *
37286a5a645eSSepherosa Ziehau * Acquires semaphore then writes the data to PHY register at the offset.
37296a5a645eSSepherosa Ziehau * Release the acquired semaphores before exiting.
37306a5a645eSSepherosa Ziehau **/
e1000_write_phy_reg_hv(struct e1000_hw * hw,u32 offset,u16 data)37316a5a645eSSepherosa Ziehau s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
37326a5a645eSSepherosa Ziehau {
373365aebe9fSSepherosa Ziehau return __e1000_write_phy_reg_hv(hw, offset, data, FALSE, false);
37346a5a645eSSepherosa Ziehau }
37356a5a645eSSepherosa Ziehau
37366a5a645eSSepherosa Ziehau /**
37376a5a645eSSepherosa Ziehau * e1000_write_phy_reg_hv_locked - Write HV PHY register
37386a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
37396a5a645eSSepherosa Ziehau * @offset: register offset to write to
37406a5a645eSSepherosa Ziehau * @data: data to write at register offset
37416a5a645eSSepherosa Ziehau *
37426a5a645eSSepherosa Ziehau * Writes the data to PHY register at the offset. Assumes semaphore
37436a5a645eSSepherosa Ziehau * already acquired.
37446a5a645eSSepherosa Ziehau **/
e1000_write_phy_reg_hv_locked(struct e1000_hw * hw,u32 offset,u16 data)37456a5a645eSSepherosa Ziehau s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data)
37466a5a645eSSepherosa Ziehau {
37476d5e2922SSepherosa Ziehau return __e1000_write_phy_reg_hv(hw, offset, data, TRUE, FALSE);
37486d5e2922SSepherosa Ziehau }
37496d5e2922SSepherosa Ziehau
37506d5e2922SSepherosa Ziehau /**
37516d5e2922SSepherosa Ziehau * e1000_write_phy_reg_page_hv - Write HV PHY register
37526d5e2922SSepherosa Ziehau * @hw: pointer to the HW structure
37536d5e2922SSepherosa Ziehau * @offset: register offset to write to
37546d5e2922SSepherosa Ziehau * @data: data to write at register offset
37556d5e2922SSepherosa Ziehau *
37566d5e2922SSepherosa Ziehau * Writes the data to PHY register at the offset. Assumes semaphore
37576d5e2922SSepherosa Ziehau * already acquired and page already set.
37586d5e2922SSepherosa Ziehau **/
e1000_write_phy_reg_page_hv(struct e1000_hw * hw,u32 offset,u16 data)37596d5e2922SSepherosa Ziehau s32 e1000_write_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 data)
37606d5e2922SSepherosa Ziehau {
376165aebe9fSSepherosa Ziehau return __e1000_write_phy_reg_hv(hw, offset, data, TRUE, true);
37626a5a645eSSepherosa Ziehau }
37636a5a645eSSepherosa Ziehau
37646a5a645eSSepherosa Ziehau /**
37656a5a645eSSepherosa Ziehau * e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page
37666a5a645eSSepherosa Ziehau * @page: page to be accessed
37676a5a645eSSepherosa Ziehau **/
e1000_get_phy_addr_for_hv_page(u32 page)37686a5a645eSSepherosa Ziehau static u32 e1000_get_phy_addr_for_hv_page(u32 page)
37696a5a645eSSepherosa Ziehau {
37706a5a645eSSepherosa Ziehau u32 phy_addr = 2;
37716a5a645eSSepherosa Ziehau
37726a5a645eSSepherosa Ziehau if (page >= HV_INTC_FC_PAGE_START)
37736a5a645eSSepherosa Ziehau phy_addr = 1;
37746a5a645eSSepherosa Ziehau
37756a5a645eSSepherosa Ziehau return phy_addr;
37766a5a645eSSepherosa Ziehau }
37776a5a645eSSepherosa Ziehau
37786a5a645eSSepherosa Ziehau /**
37796a5a645eSSepherosa Ziehau * e1000_access_phy_debug_regs_hv - Read HV PHY vendor specific high registers
37806a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
37816a5a645eSSepherosa Ziehau * @offset: register offset to be read or written
37826a5a645eSSepherosa Ziehau * @data: pointer to the data to be read or written
37836d5e2922SSepherosa Ziehau * @read: determines if operation is read or write
37846a5a645eSSepherosa Ziehau *
37856a5a645eSSepherosa Ziehau * Reads the PHY register at offset and stores the retreived information
37866a5a645eSSepherosa Ziehau * in data. Assumes semaphore already acquired. Note that the procedure
37876d5e2922SSepherosa Ziehau * to access these regs uses the address port and data port to read/write.
37886d5e2922SSepherosa Ziehau * These accesses done with PHY address 2 and without using pages.
37896a5a645eSSepherosa Ziehau **/
e1000_access_phy_debug_regs_hv(struct e1000_hw * hw,u32 offset,u16 * data,bool read)37906a5a645eSSepherosa Ziehau static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
37916a5a645eSSepherosa Ziehau u16 *data, bool read)
37926a5a645eSSepherosa Ziehau {
37936a5a645eSSepherosa Ziehau s32 ret_val;
3794379ebbe7SSepherosa Ziehau u32 addr_reg;
3795379ebbe7SSepherosa Ziehau u32 data_reg;
37966a5a645eSSepherosa Ziehau
37976a5a645eSSepherosa Ziehau DEBUGFUNC("e1000_access_phy_debug_regs_hv");
37986a5a645eSSepherosa Ziehau
37996a5a645eSSepherosa Ziehau /* This takes care of the difference with desktop vs mobile phy */
38004765c386SMichael Neumann addr_reg = ((hw->phy.type == e1000_phy_82578) ?
38014765c386SMichael Neumann I82578_ADDR_REG : I82577_ADDR_REG);
38026a5a645eSSepherosa Ziehau data_reg = addr_reg + 1;
38036a5a645eSSepherosa Ziehau
38046a5a645eSSepherosa Ziehau /* All operations in this function are phy address 2 */
38056a5a645eSSepherosa Ziehau hw->phy.addr = 2;
38066a5a645eSSepherosa Ziehau
38076a5a645eSSepherosa Ziehau /* masking with 0x3F to remove the page from offset */
38086a5a645eSSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, addr_reg, (u16)offset & 0x3F);
38096a5a645eSSepherosa Ziehau if (ret_val) {
38106d5e2922SSepherosa Ziehau DEBUGOUT("Could not write the Address Offset port register\n");
38114be59a01SSepherosa Ziehau return ret_val;
38126a5a645eSSepherosa Ziehau }
38136a5a645eSSepherosa Ziehau
38146a5a645eSSepherosa Ziehau /* Read or write the data value next */
38156a5a645eSSepherosa Ziehau if (read)
38166a5a645eSSepherosa Ziehau ret_val = e1000_read_phy_reg_mdic(hw, data_reg, data);
38176a5a645eSSepherosa Ziehau else
38186a5a645eSSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, data_reg, *data);
38196a5a645eSSepherosa Ziehau
38204be59a01SSepherosa Ziehau if (ret_val)
38216d5e2922SSepherosa Ziehau DEBUGOUT("Could not access the Data port register\n");
38226a5a645eSSepherosa Ziehau
38236a5a645eSSepherosa Ziehau return ret_val;
38246a5a645eSSepherosa Ziehau }
38256a5a645eSSepherosa Ziehau
38266a5a645eSSepherosa Ziehau /**
38276a5a645eSSepherosa Ziehau * e1000_link_stall_workaround_hv - Si workaround
38286a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
38296a5a645eSSepherosa Ziehau *
38306a5a645eSSepherosa Ziehau * This function works around a Si bug where the link partner can get
38316a5a645eSSepherosa Ziehau * a link up indication before the PHY does. If small packets are sent
38326a5a645eSSepherosa Ziehau * by the link partner they can be placed in the packet buffer without
38336a5a645eSSepherosa Ziehau * being properly accounted for by the PHY and will stall preventing
38346a5a645eSSepherosa Ziehau * further packets from being received. The workaround is to clear the
38356a5a645eSSepherosa Ziehau * packet buffer after the PHY detects link up.
38366a5a645eSSepherosa Ziehau **/
e1000_link_stall_workaround_hv(struct e1000_hw * hw)38376a5a645eSSepherosa Ziehau s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw)
38386a5a645eSSepherosa Ziehau {
38396a5a645eSSepherosa Ziehau s32 ret_val = E1000_SUCCESS;
38406a5a645eSSepherosa Ziehau u16 data;
38416a5a645eSSepherosa Ziehau
38426a5a645eSSepherosa Ziehau DEBUGFUNC("e1000_link_stall_workaround_hv");
38436a5a645eSSepherosa Ziehau
38446a5a645eSSepherosa Ziehau if (hw->phy.type != e1000_phy_82578)
38454be59a01SSepherosa Ziehau return E1000_SUCCESS;
38466a5a645eSSepherosa Ziehau
38476a5a645eSSepherosa Ziehau /* Do not apply workaround if in PHY loopback bit 14 set */
38486a5a645eSSepherosa Ziehau hw->phy.ops.read_reg(hw, PHY_CONTROL, &data);
38496a5a645eSSepherosa Ziehau if (data & PHY_CONTROL_LB)
38504be59a01SSepherosa Ziehau return E1000_SUCCESS;
38516a5a645eSSepherosa Ziehau
38526a5a645eSSepherosa Ziehau /* check if link is up and at 1Gbps */
38536a5a645eSSepherosa Ziehau ret_val = hw->phy.ops.read_reg(hw, BM_CS_STATUS, &data);
38546a5a645eSSepherosa Ziehau if (ret_val)
38554be59a01SSepherosa Ziehau return ret_val;
38566a5a645eSSepherosa Ziehau
38574765c386SMichael Neumann data &= (BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED |
38584765c386SMichael Neumann BM_CS_STATUS_SPEED_MASK);
38596a5a645eSSepherosa Ziehau
38604be59a01SSepherosa Ziehau if (data != (BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED |
38616a5a645eSSepherosa Ziehau BM_CS_STATUS_SPEED_1000))
38624be59a01SSepherosa Ziehau return E1000_SUCCESS;
38636a5a645eSSepherosa Ziehau
38646a5a645eSSepherosa Ziehau msec_delay(200);
38656a5a645eSSepherosa Ziehau
38666a5a645eSSepherosa Ziehau /* flush the packets in the fifo buffer */
38676a5a645eSSepherosa Ziehau ret_val = hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL,
3868379ebbe7SSepherosa Ziehau (HV_MUX_DATA_CTRL_GEN_TO_MAC |
3869379ebbe7SSepherosa Ziehau HV_MUX_DATA_CTRL_FORCE_SPEED));
38706a5a645eSSepherosa Ziehau if (ret_val)
38716a5a645eSSepherosa Ziehau return ret_val;
38724be59a01SSepherosa Ziehau
38734be59a01SSepherosa Ziehau return hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL,
38744be59a01SSepherosa Ziehau HV_MUX_DATA_CTRL_GEN_TO_MAC);
38756a5a645eSSepherosa Ziehau }
38766a5a645eSSepherosa Ziehau
38776a5a645eSSepherosa Ziehau /**
38786a5a645eSSepherosa Ziehau * e1000_check_polarity_82577 - Checks the polarity.
38796a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
38806a5a645eSSepherosa Ziehau *
38816a5a645eSSepherosa Ziehau * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
38826a5a645eSSepherosa Ziehau *
38836a5a645eSSepherosa Ziehau * Polarity is determined based on the PHY specific status register.
38846a5a645eSSepherosa Ziehau **/
e1000_check_polarity_82577(struct e1000_hw * hw)38856a5a645eSSepherosa Ziehau s32 e1000_check_polarity_82577(struct e1000_hw *hw)
38866a5a645eSSepherosa Ziehau {
38876a5a645eSSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
38886a5a645eSSepherosa Ziehau s32 ret_val;
38896a5a645eSSepherosa Ziehau u16 data;
38906a5a645eSSepherosa Ziehau
38916a5a645eSSepherosa Ziehau DEBUGFUNC("e1000_check_polarity_82577");
38926a5a645eSSepherosa Ziehau
38936a5a645eSSepherosa Ziehau ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data);
38946a5a645eSSepherosa Ziehau
38956a5a645eSSepherosa Ziehau if (!ret_val)
3896379ebbe7SSepherosa Ziehau phy->cable_polarity = ((data & I82577_PHY_STATUS2_REV_POLARITY)
38976a5a645eSSepherosa Ziehau ? e1000_rev_polarity_reversed
3898379ebbe7SSepherosa Ziehau : e1000_rev_polarity_normal);
38996a5a645eSSepherosa Ziehau
39006a5a645eSSepherosa Ziehau return ret_val;
39016a5a645eSSepherosa Ziehau }
39026a5a645eSSepherosa Ziehau
39036a5a645eSSepherosa Ziehau /**
39046a5a645eSSepherosa Ziehau * e1000_phy_force_speed_duplex_82577 - Force speed/duplex for I82577 PHY
39056a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
39066a5a645eSSepherosa Ziehau *
39076a5a645eSSepherosa Ziehau * Calls the PHY setup function to force speed and duplex.
39086a5a645eSSepherosa Ziehau **/
e1000_phy_force_speed_duplex_82577(struct e1000_hw * hw)39096a5a645eSSepherosa Ziehau s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
39106a5a645eSSepherosa Ziehau {
39116a5a645eSSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
39126a5a645eSSepherosa Ziehau s32 ret_val;
39136a5a645eSSepherosa Ziehau u16 phy_data;
39146a5a645eSSepherosa Ziehau bool link;
39156a5a645eSSepherosa Ziehau
39166a5a645eSSepherosa Ziehau DEBUGFUNC("e1000_phy_force_speed_duplex_82577");
39176a5a645eSSepherosa Ziehau
39186a5a645eSSepherosa Ziehau ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
39196a5a645eSSepherosa Ziehau if (ret_val)
39204be59a01SSepherosa Ziehau return ret_val;
39216a5a645eSSepherosa Ziehau
39226a5a645eSSepherosa Ziehau e1000_phy_force_speed_duplex_setup(hw, &phy_data);
39236a5a645eSSepherosa Ziehau
39246a5a645eSSepherosa Ziehau ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
39256a5a645eSSepherosa Ziehau if (ret_val)
39264be59a01SSepherosa Ziehau return ret_val;
39276a5a645eSSepherosa Ziehau
39286a5a645eSSepherosa Ziehau usec_delay(1);
39296a5a645eSSepherosa Ziehau
39306a5a645eSSepherosa Ziehau if (phy->autoneg_wait_to_complete) {
39316a5a645eSSepherosa Ziehau DEBUGOUT("Waiting for forced speed/duplex link on 82577 phy\n");
39326a5a645eSSepherosa Ziehau
39334be59a01SSepherosa Ziehau ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
39344be59a01SSepherosa Ziehau 100000, &link);
39356a5a645eSSepherosa Ziehau if (ret_val)
39364be59a01SSepherosa Ziehau return ret_val;
39376a5a645eSSepherosa Ziehau
39386a5a645eSSepherosa Ziehau if (!link)
39396a5a645eSSepherosa Ziehau DEBUGOUT("Link taking longer than expected.\n");
39406a5a645eSSepherosa Ziehau
39416a5a645eSSepherosa Ziehau /* Try once more */
39424be59a01SSepherosa Ziehau ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
39434be59a01SSepherosa Ziehau 100000, &link);
39446a5a645eSSepherosa Ziehau }
39456a5a645eSSepherosa Ziehau
39466a5a645eSSepherosa Ziehau return ret_val;
39476a5a645eSSepherosa Ziehau }
39486a5a645eSSepherosa Ziehau
39496a5a645eSSepherosa Ziehau /**
39506a5a645eSSepherosa Ziehau * e1000_get_phy_info_82577 - Retrieve I82577 PHY information
39516a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
39526a5a645eSSepherosa Ziehau *
39536a5a645eSSepherosa Ziehau * Read PHY status to determine if link is up. If link is up, then
39546a5a645eSSepherosa Ziehau * set/determine 10base-T extended distance and polarity correction. Read
39556a5a645eSSepherosa Ziehau * PHY port status to determine MDI/MDIx and speed. Based on the speed,
39566a5a645eSSepherosa Ziehau * determine on the cable length, local and remote receiver.
39576a5a645eSSepherosa Ziehau **/
e1000_get_phy_info_82577(struct e1000_hw * hw)39586a5a645eSSepherosa Ziehau s32 e1000_get_phy_info_82577(struct e1000_hw *hw)
39596a5a645eSSepherosa Ziehau {
39606a5a645eSSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
39616a5a645eSSepherosa Ziehau s32 ret_val;
39626a5a645eSSepherosa Ziehau u16 data;
39636a5a645eSSepherosa Ziehau bool link;
39646a5a645eSSepherosa Ziehau
39656a5a645eSSepherosa Ziehau DEBUGFUNC("e1000_get_phy_info_82577");
39666a5a645eSSepherosa Ziehau
39676a5a645eSSepherosa Ziehau ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
39686a5a645eSSepherosa Ziehau if (ret_val)
39694be59a01SSepherosa Ziehau return ret_val;
39706a5a645eSSepherosa Ziehau
39716a5a645eSSepherosa Ziehau if (!link) {
39726a5a645eSSepherosa Ziehau DEBUGOUT("Phy info is only valid if link is up\n");
39734be59a01SSepherosa Ziehau return -E1000_ERR_CONFIG;
39746a5a645eSSepherosa Ziehau }
39756a5a645eSSepherosa Ziehau
39766a5a645eSSepherosa Ziehau phy->polarity_correction = TRUE;
39776a5a645eSSepherosa Ziehau
39786a5a645eSSepherosa Ziehau ret_val = e1000_check_polarity_82577(hw);
39796a5a645eSSepherosa Ziehau if (ret_val)
39804be59a01SSepherosa Ziehau return ret_val;
39816a5a645eSSepherosa Ziehau
39826a5a645eSSepherosa Ziehau ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data);
39836a5a645eSSepherosa Ziehau if (ret_val)
39844be59a01SSepherosa Ziehau return ret_val;
39856a5a645eSSepherosa Ziehau
39864be59a01SSepherosa Ziehau phy->is_mdix = !!(data & I82577_PHY_STATUS2_MDIX);
39876a5a645eSSepherosa Ziehau
39886a5a645eSSepherosa Ziehau if ((data & I82577_PHY_STATUS2_SPEED_MASK) ==
39896a5a645eSSepherosa Ziehau I82577_PHY_STATUS2_SPEED_1000MBPS) {
39906a5a645eSSepherosa Ziehau ret_val = hw->phy.ops.get_cable_length(hw);
39916a5a645eSSepherosa Ziehau if (ret_val)
39924be59a01SSepherosa Ziehau return ret_val;
39936a5a645eSSepherosa Ziehau
39946a5a645eSSepherosa Ziehau ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data);
39956a5a645eSSepherosa Ziehau if (ret_val)
39964be59a01SSepherosa Ziehau return ret_val;
39976a5a645eSSepherosa Ziehau
39986a5a645eSSepherosa Ziehau phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
39996a5a645eSSepherosa Ziehau ? e1000_1000t_rx_status_ok
40006a5a645eSSepherosa Ziehau : e1000_1000t_rx_status_not_ok;
40016a5a645eSSepherosa Ziehau
40026a5a645eSSepherosa Ziehau phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
40036a5a645eSSepherosa Ziehau ? e1000_1000t_rx_status_ok
40046a5a645eSSepherosa Ziehau : e1000_1000t_rx_status_not_ok;
40056a5a645eSSepherosa Ziehau } else {
40066a5a645eSSepherosa Ziehau phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
40076a5a645eSSepherosa Ziehau phy->local_rx = e1000_1000t_rx_status_undefined;
40086a5a645eSSepherosa Ziehau phy->remote_rx = e1000_1000t_rx_status_undefined;
40096a5a645eSSepherosa Ziehau }
40106a5a645eSSepherosa Ziehau
40114be59a01SSepherosa Ziehau return E1000_SUCCESS;
40126a5a645eSSepherosa Ziehau }
40136a5a645eSSepherosa Ziehau
40146a5a645eSSepherosa Ziehau /**
40156a5a645eSSepherosa Ziehau * e1000_get_cable_length_82577 - Determine cable length for 82577 PHY
40166a5a645eSSepherosa Ziehau * @hw: pointer to the HW structure
40176a5a645eSSepherosa Ziehau *
40186a5a645eSSepherosa Ziehau * Reads the diagnostic status register and verifies result is valid before
40196a5a645eSSepherosa Ziehau * placing it in the phy_cable_length field.
40206a5a645eSSepherosa Ziehau **/
e1000_get_cable_length_82577(struct e1000_hw * hw)40216a5a645eSSepherosa Ziehau s32 e1000_get_cable_length_82577(struct e1000_hw *hw)
40226a5a645eSSepherosa Ziehau {
40236a5a645eSSepherosa Ziehau struct e1000_phy_info *phy = &hw->phy;
40246a5a645eSSepherosa Ziehau s32 ret_val;
40256a5a645eSSepherosa Ziehau u16 phy_data, length;
40266a5a645eSSepherosa Ziehau
40276a5a645eSSepherosa Ziehau DEBUGFUNC("e1000_get_cable_length_82577");
40286a5a645eSSepherosa Ziehau
40296a5a645eSSepherosa Ziehau ret_val = phy->ops.read_reg(hw, I82577_PHY_DIAG_STATUS, &phy_data);
40306a5a645eSSepherosa Ziehau if (ret_val)
40314be59a01SSepherosa Ziehau return ret_val;
40326a5a645eSSepherosa Ziehau
4033379ebbe7SSepherosa Ziehau length = ((phy_data & I82577_DSTATUS_CABLE_LENGTH) >>
4034379ebbe7SSepherosa Ziehau I82577_DSTATUS_CABLE_LENGTH_SHIFT);
40356a5a645eSSepherosa Ziehau
40366a5a645eSSepherosa Ziehau if (length == E1000_CABLE_LENGTH_UNDEFINED)
4037379ebbe7SSepherosa Ziehau return -E1000_ERR_PHY;
40386a5a645eSSepherosa Ziehau
40396a5a645eSSepherosa Ziehau phy->cable_length = length;
40406a5a645eSSepherosa Ziehau
40414be59a01SSepherosa Ziehau return E1000_SUCCESS;
40424be59a01SSepherosa Ziehau }
40434be59a01SSepherosa Ziehau
40444be59a01SSepherosa Ziehau /**
40454be59a01SSepherosa Ziehau * e1000_write_phy_reg_gs40g - Write GS40G PHY register
40464be59a01SSepherosa Ziehau * @hw: pointer to the HW structure
40474be59a01SSepherosa Ziehau * @offset: register offset to write to
40484be59a01SSepherosa Ziehau * @data: data to write at register offset
40494be59a01SSepherosa Ziehau *
40504be59a01SSepherosa Ziehau * Acquires semaphore, if necessary, then writes the data to PHY register
40514be59a01SSepherosa Ziehau * at the offset. Release any acquired semaphores before exiting.
40524be59a01SSepherosa Ziehau **/
e1000_write_phy_reg_gs40g(struct e1000_hw * hw,u32 offset,u16 data)40534be59a01SSepherosa Ziehau s32 e1000_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data)
40544be59a01SSepherosa Ziehau {
40554be59a01SSepherosa Ziehau s32 ret_val;
40564be59a01SSepherosa Ziehau u16 page = offset >> GS40G_PAGE_SHIFT;
40574be59a01SSepherosa Ziehau
40584be59a01SSepherosa Ziehau DEBUGFUNC("e1000_write_phy_reg_gs40g");
40594be59a01SSepherosa Ziehau
40604be59a01SSepherosa Ziehau offset = offset & GS40G_OFFSET_MASK;
40614be59a01SSepherosa Ziehau ret_val = hw->phy.ops.acquire(hw);
40624be59a01SSepherosa Ziehau if (ret_val)
40634be59a01SSepherosa Ziehau return ret_val;
40644be59a01SSepherosa Ziehau
40654be59a01SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page);
40664be59a01SSepherosa Ziehau if (ret_val)
40674be59a01SSepherosa Ziehau goto release;
40684be59a01SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, offset, data);
40694be59a01SSepherosa Ziehau
40704be59a01SSepherosa Ziehau release:
40714be59a01SSepherosa Ziehau hw->phy.ops.release(hw);
40724be59a01SSepherosa Ziehau return ret_val;
40734be59a01SSepherosa Ziehau }
40744be59a01SSepherosa Ziehau
40754be59a01SSepherosa Ziehau /**
40764be59a01SSepherosa Ziehau * e1000_read_phy_reg_gs40g - Read GS40G PHY register
40774be59a01SSepherosa Ziehau * @hw: pointer to the HW structure
40784be59a01SSepherosa Ziehau * @offset: lower half is register offset to read to
40794be59a01SSepherosa Ziehau * upper half is page to use.
40804be59a01SSepherosa Ziehau * @data: data to read at register offset
40814be59a01SSepherosa Ziehau *
40824be59a01SSepherosa Ziehau * Acquires semaphore, if necessary, then reads the data in the PHY register
40834be59a01SSepherosa Ziehau * at the offset. Release any acquired semaphores before exiting.
40844be59a01SSepherosa Ziehau **/
e1000_read_phy_reg_gs40g(struct e1000_hw * hw,u32 offset,u16 * data)40854be59a01SSepherosa Ziehau s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data)
40864be59a01SSepherosa Ziehau {
40874be59a01SSepherosa Ziehau s32 ret_val;
40884be59a01SSepherosa Ziehau u16 page = offset >> GS40G_PAGE_SHIFT;
40894be59a01SSepherosa Ziehau
40904be59a01SSepherosa Ziehau DEBUGFUNC("e1000_read_phy_reg_gs40g");
40914be59a01SSepherosa Ziehau
40924be59a01SSepherosa Ziehau offset = offset & GS40G_OFFSET_MASK;
40934be59a01SSepherosa Ziehau ret_val = hw->phy.ops.acquire(hw);
40944be59a01SSepherosa Ziehau if (ret_val)
40954be59a01SSepherosa Ziehau return ret_val;
40964be59a01SSepherosa Ziehau
40974be59a01SSepherosa Ziehau ret_val = e1000_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page);
40984be59a01SSepherosa Ziehau if (ret_val)
40994be59a01SSepherosa Ziehau goto release;
41004be59a01SSepherosa Ziehau ret_val = e1000_read_phy_reg_mdic(hw, offset, data);
41014be59a01SSepherosa Ziehau
41024be59a01SSepherosa Ziehau release:
41034be59a01SSepherosa Ziehau hw->phy.ops.release(hw);
41046a5a645eSSepherosa Ziehau return ret_val;
41056a5a645eSSepherosa Ziehau }
4106379ebbe7SSepherosa Ziehau
4107379ebbe7SSepherosa Ziehau /**
4108379ebbe7SSepherosa Ziehau * e1000_read_phy_reg_mphy - Read mPHY control register
4109379ebbe7SSepherosa Ziehau * @hw: pointer to the HW structure
4110379ebbe7SSepherosa Ziehau * @address: address to be read
4111379ebbe7SSepherosa Ziehau * @data: pointer to the read data
4112379ebbe7SSepherosa Ziehau *
4113379ebbe7SSepherosa Ziehau * Reads the mPHY control register in the PHY at offset and stores the
4114379ebbe7SSepherosa Ziehau * information read to data.
4115379ebbe7SSepherosa Ziehau **/
e1000_read_phy_reg_mphy(struct e1000_hw * hw,u32 address,u32 * data)4116379ebbe7SSepherosa Ziehau s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data)
4117379ebbe7SSepherosa Ziehau {
4118379ebbe7SSepherosa Ziehau u32 mphy_ctrl = 0;
4119379ebbe7SSepherosa Ziehau bool locked = FALSE;
4120ba0123e0SSepherosa Ziehau bool ready;
4121379ebbe7SSepherosa Ziehau
4122379ebbe7SSepherosa Ziehau DEBUGFUNC("e1000_read_phy_reg_mphy");
4123379ebbe7SSepherosa Ziehau
4124379ebbe7SSepherosa Ziehau /* Check if mPHY is ready to read/write operations */
4125379ebbe7SSepherosa Ziehau ready = e1000_is_mphy_ready(hw);
4126379ebbe7SSepherosa Ziehau if (!ready)
4127379ebbe7SSepherosa Ziehau return -E1000_ERR_PHY;
4128379ebbe7SSepherosa Ziehau
4129379ebbe7SSepherosa Ziehau /* Check if mPHY access is disabled and enable it if so */
4130379ebbe7SSepherosa Ziehau mphy_ctrl = E1000_READ_REG(hw, E1000_MPHY_ADDR_CTRL);
4131379ebbe7SSepherosa Ziehau if (mphy_ctrl & E1000_MPHY_DIS_ACCESS) {
4132379ebbe7SSepherosa Ziehau locked = TRUE;
4133379ebbe7SSepherosa Ziehau ready = e1000_is_mphy_ready(hw);
4134379ebbe7SSepherosa Ziehau if (!ready)
4135379ebbe7SSepherosa Ziehau return -E1000_ERR_PHY;
4136379ebbe7SSepherosa Ziehau mphy_ctrl |= E1000_MPHY_ENA_ACCESS;
4137379ebbe7SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl);
4138379ebbe7SSepherosa Ziehau }
4139379ebbe7SSepherosa Ziehau
4140379ebbe7SSepherosa Ziehau /* Set the address that we want to read */
4141379ebbe7SSepherosa Ziehau ready = e1000_is_mphy_ready(hw);
4142379ebbe7SSepherosa Ziehau if (!ready)
4143379ebbe7SSepherosa Ziehau return -E1000_ERR_PHY;
4144ba0123e0SSepherosa Ziehau
4145ba0123e0SSepherosa Ziehau /* We mask address, because we want to use only current lane */
4146ba0123e0SSepherosa Ziehau mphy_ctrl = (mphy_ctrl & ~E1000_MPHY_ADDRESS_MASK &
4147ba0123e0SSepherosa Ziehau ~E1000_MPHY_ADDRESS_FNC_OVERRIDE) |
4148ba0123e0SSepherosa Ziehau (address & E1000_MPHY_ADDRESS_MASK);
4149379ebbe7SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl);
4150379ebbe7SSepherosa Ziehau
4151379ebbe7SSepherosa Ziehau /* Read data from the address */
4152379ebbe7SSepherosa Ziehau ready = e1000_is_mphy_ready(hw);
4153379ebbe7SSepherosa Ziehau if (!ready)
4154379ebbe7SSepherosa Ziehau return -E1000_ERR_PHY;
4155379ebbe7SSepherosa Ziehau *data = E1000_READ_REG(hw, E1000_MPHY_DATA);
4156379ebbe7SSepherosa Ziehau
4157379ebbe7SSepherosa Ziehau /* Disable access to mPHY if it was originally disabled */
415865aebe9fSSepherosa Ziehau if (locked)
4159379ebbe7SSepherosa Ziehau ready = e1000_is_mphy_ready(hw);
4160379ebbe7SSepherosa Ziehau if (!ready)
4161379ebbe7SSepherosa Ziehau return -E1000_ERR_PHY;
4162379ebbe7SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL,
4163379ebbe7SSepherosa Ziehau E1000_MPHY_DIS_ACCESS);
4164379ebbe7SSepherosa Ziehau
4165379ebbe7SSepherosa Ziehau return E1000_SUCCESS;
4166379ebbe7SSepherosa Ziehau }
4167379ebbe7SSepherosa Ziehau
4168379ebbe7SSepherosa Ziehau /**
4169379ebbe7SSepherosa Ziehau * e1000_write_phy_reg_mphy - Write mPHY control register
4170379ebbe7SSepherosa Ziehau * @hw: pointer to the HW structure
4171379ebbe7SSepherosa Ziehau * @address: address to write to
4172379ebbe7SSepherosa Ziehau * @data: data to write to register at offset
4173ba0123e0SSepherosa Ziehau * @line_override: used when we want to use different line than default one
4174379ebbe7SSepherosa Ziehau *
4175379ebbe7SSepherosa Ziehau * Writes data to mPHY control register.
4176379ebbe7SSepherosa Ziehau **/
e1000_write_phy_reg_mphy(struct e1000_hw * hw,u32 address,u32 data,bool line_override)4177ba0123e0SSepherosa Ziehau s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data,
4178ba0123e0SSepherosa Ziehau bool line_override)
4179379ebbe7SSepherosa Ziehau {
4180379ebbe7SSepherosa Ziehau u32 mphy_ctrl = 0;
4181379ebbe7SSepherosa Ziehau bool locked = FALSE;
4182ba0123e0SSepherosa Ziehau bool ready;
4183379ebbe7SSepherosa Ziehau
4184379ebbe7SSepherosa Ziehau DEBUGFUNC("e1000_write_phy_reg_mphy");
4185379ebbe7SSepherosa Ziehau
4186379ebbe7SSepherosa Ziehau /* Check if mPHY is ready to read/write operations */
4187379ebbe7SSepherosa Ziehau ready = e1000_is_mphy_ready(hw);
4188379ebbe7SSepherosa Ziehau if (!ready)
4189379ebbe7SSepherosa Ziehau return -E1000_ERR_PHY;
4190379ebbe7SSepherosa Ziehau
4191379ebbe7SSepherosa Ziehau /* Check if mPHY access is disabled and enable it if so */
4192379ebbe7SSepherosa Ziehau mphy_ctrl = E1000_READ_REG(hw, E1000_MPHY_ADDR_CTRL);
4193379ebbe7SSepherosa Ziehau if (mphy_ctrl & E1000_MPHY_DIS_ACCESS) {
4194379ebbe7SSepherosa Ziehau locked = TRUE;
4195379ebbe7SSepherosa Ziehau ready = e1000_is_mphy_ready(hw);
4196379ebbe7SSepherosa Ziehau if (!ready)
4197379ebbe7SSepherosa Ziehau return -E1000_ERR_PHY;
4198379ebbe7SSepherosa Ziehau mphy_ctrl |= E1000_MPHY_ENA_ACCESS;
4199379ebbe7SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl);
4200379ebbe7SSepherosa Ziehau }
4201379ebbe7SSepherosa Ziehau
4202379ebbe7SSepherosa Ziehau /* Set the address that we want to read */
4203379ebbe7SSepherosa Ziehau ready = e1000_is_mphy_ready(hw);
4204379ebbe7SSepherosa Ziehau if (!ready)
4205379ebbe7SSepherosa Ziehau return -E1000_ERR_PHY;
4206ba0123e0SSepherosa Ziehau
4207ba0123e0SSepherosa Ziehau /* We mask address, because we want to use only current lane */
4208ba0123e0SSepherosa Ziehau if (line_override)
4209ba0123e0SSepherosa Ziehau mphy_ctrl |= E1000_MPHY_ADDRESS_FNC_OVERRIDE;
4210ba0123e0SSepherosa Ziehau else
4211ba0123e0SSepherosa Ziehau mphy_ctrl &= ~E1000_MPHY_ADDRESS_FNC_OVERRIDE;
4212ba0123e0SSepherosa Ziehau mphy_ctrl = (mphy_ctrl & ~E1000_MPHY_ADDRESS_MASK) |
4213ba0123e0SSepherosa Ziehau (address & E1000_MPHY_ADDRESS_MASK);
4214379ebbe7SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl);
4215379ebbe7SSepherosa Ziehau
4216379ebbe7SSepherosa Ziehau /* Read data from the address */
4217379ebbe7SSepherosa Ziehau ready = e1000_is_mphy_ready(hw);
4218379ebbe7SSepherosa Ziehau if (!ready)
4219379ebbe7SSepherosa Ziehau return -E1000_ERR_PHY;
4220379ebbe7SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_MPHY_DATA, data);
4221379ebbe7SSepherosa Ziehau
4222379ebbe7SSepherosa Ziehau /* Disable access to mPHY if it was originally disabled */
422365aebe9fSSepherosa Ziehau if (locked)
4224379ebbe7SSepherosa Ziehau ready = e1000_is_mphy_ready(hw);
4225379ebbe7SSepherosa Ziehau if (!ready)
4226379ebbe7SSepherosa Ziehau return -E1000_ERR_PHY;
4227379ebbe7SSepherosa Ziehau E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL,
4228379ebbe7SSepherosa Ziehau E1000_MPHY_DIS_ACCESS);
4229379ebbe7SSepherosa Ziehau
4230379ebbe7SSepherosa Ziehau return E1000_SUCCESS;
4231379ebbe7SSepherosa Ziehau }
4232379ebbe7SSepherosa Ziehau
4233379ebbe7SSepherosa Ziehau /**
4234379ebbe7SSepherosa Ziehau * e1000_is_mphy_ready - Check if mPHY control register is not busy
4235379ebbe7SSepherosa Ziehau * @hw: pointer to the HW structure
4236379ebbe7SSepherosa Ziehau *
4237379ebbe7SSepherosa Ziehau * Returns mPHY control register status.
4238379ebbe7SSepherosa Ziehau **/
e1000_is_mphy_ready(struct e1000_hw * hw)4239379ebbe7SSepherosa Ziehau bool e1000_is_mphy_ready(struct e1000_hw *hw)
4240379ebbe7SSepherosa Ziehau {
4241379ebbe7SSepherosa Ziehau u16 retry_count = 0;
4242379ebbe7SSepherosa Ziehau u32 mphy_ctrl = 0;
4243379ebbe7SSepherosa Ziehau bool ready = FALSE;
4244379ebbe7SSepherosa Ziehau
4245379ebbe7SSepherosa Ziehau while (retry_count < 2) {
4246379ebbe7SSepherosa Ziehau mphy_ctrl = E1000_READ_REG(hw, E1000_MPHY_ADDR_CTRL);
4247379ebbe7SSepherosa Ziehau if (mphy_ctrl & E1000_MPHY_BUSY) {
4248379ebbe7SSepherosa Ziehau usec_delay(20);
4249379ebbe7SSepherosa Ziehau retry_count++;
4250379ebbe7SSepherosa Ziehau continue;
4251379ebbe7SSepherosa Ziehau }
4252379ebbe7SSepherosa Ziehau ready = TRUE;
4253379ebbe7SSepherosa Ziehau break;
4254379ebbe7SSepherosa Ziehau }
4255379ebbe7SSepherosa Ziehau
4256379ebbe7SSepherosa Ziehau if (!ready)
4257379ebbe7SSepherosa Ziehau DEBUGOUT("ERROR READING mPHY control register, phy is busy.\n");
4258379ebbe7SSepherosa Ziehau
4259379ebbe7SSepherosa Ziehau return ready;
4260379ebbe7SSepherosa Ziehau }
4261