1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2015-2020
6 #include "txgbe_eeprom.h"
11 * txgbe_identify_extphy - Identify a single address for a PHY
12 * @hw: pointer to hardware structure
13 * @phy_addr: PHY address to probe
15 * Returns true if PHY found
17 static bool txgbe_identify_extphy(struct txgbe_hw *hw)
21 if (!txgbe_validate_phy_addr(hw, phy_addr)) {
22 DEBUGOUT("Unable to validate PHY address 0x%04X\n",
27 if (txgbe_get_phy_id(hw))
30 hw->phy.type = txgbe_get_phy_type_from_id(hw->phy.id);
31 if (hw->phy.type == txgbe_phy_unknown) {
33 hw->phy.read_reg(hw, TXGBE_MD_PHY_EXT_ABILITY,
37 if (ext_ability & (TXGBE_MD_PHY_10GBASET_ABILITY |
38 TXGBE_MD_PHY_1000BASET_ABILITY))
39 hw->phy.type = txgbe_phy_cu_unknown;
41 hw->phy.type = txgbe_phy_generic;
48 * txgbe_read_phy_if - Read TXGBE_ETHPHYIF register
49 * @hw: pointer to hardware structure
51 * Read TXGBE_ETHPHYIF register and save field values,
52 * and check for valid field values.
54 static s32 txgbe_read_phy_if(struct txgbe_hw *hw)
56 hw->phy.media_type = hw->phy.get_media_type(hw);
58 /* Save NW management interface connected on board. This is used
59 * to determine internal PHY mode.
61 hw->phy.nw_mng_if_sel = rd32(hw, TXGBE_ETHPHYIF);
63 /* If MDIO is connected to external PHY, then set PHY address. */
64 if (hw->phy.nw_mng_if_sel & TXGBE_ETHPHYIF_MDIO_ACT)
65 hw->phy.addr = TXGBE_ETHPHYIF_MDIO_BASE(hw->phy.nw_mng_if_sel);
67 if (!hw->phy.phy_semaphore_mask) {
69 hw->phy.phy_semaphore_mask = TXGBE_MNGSEM_SWPHY;
71 hw->phy.phy_semaphore_mask = TXGBE_MNGSEM_SWPHY;
78 * txgbe_identify_phy - Get physical layer module
79 * @hw: pointer to hardware structure
81 * Determines the physical layer module found on the current adapter.
83 s32 txgbe_identify_phy(struct txgbe_hw *hw)
85 s32 err = TXGBE_ERR_PHY_ADDR_INVALID;
87 DEBUGFUNC("txgbe_identify_phy");
89 txgbe_read_phy_if(hw);
91 if (hw->phy.type != txgbe_phy_unknown)
94 /* Raptor 10GBASE-T requires an external PHY */
95 if (hw->phy.media_type == txgbe_media_type_copper) {
96 err = txgbe_identify_extphy(hw);
97 } else if (hw->phy.media_type == txgbe_media_type_fiber) {
98 err = txgbe_identify_module(hw);
100 hw->phy.type = txgbe_phy_none;
104 /* Return error if SFP module has been detected but is not supported */
105 if (hw->phy.type == txgbe_phy_sfp_unsupported)
106 return TXGBE_ERR_SFP_NOT_SUPPORTED;
112 * txgbe_validate_phy_addr - Determines phy address is valid
113 * @hw: pointer to hardware structure
114 * @phy_addr: PHY address
117 bool txgbe_validate_phy_addr(struct txgbe_hw *hw, u32 phy_addr)
122 DEBUGFUNC("txgbe_validate_phy_addr");
124 hw->phy.addr = phy_addr;
125 hw->phy.read_reg(hw, TXGBE_MD_PHY_ID_HIGH,
126 TXGBE_MD_DEV_PMA_PMD, &phy_id);
128 if (phy_id != 0xFFFF && phy_id != 0x0)
131 DEBUGOUT("PHY ID HIGH is 0x%04X\n", phy_id);
137 * txgbe_get_phy_id - Get the phy type
138 * @hw: pointer to hardware structure
141 s32 txgbe_get_phy_id(struct txgbe_hw *hw)
147 DEBUGFUNC("txgbe_get_phy_id");
149 err = hw->phy.read_reg(hw, TXGBE_MD_PHY_ID_HIGH,
150 TXGBE_MD_DEV_PMA_PMD,
154 hw->phy.id = (u32)(phy_id_high << 16);
155 err = hw->phy.read_reg(hw, TXGBE_MD_PHY_ID_LOW,
156 TXGBE_MD_DEV_PMA_PMD,
158 hw->phy.id |= (u32)(phy_id_low & TXGBE_PHY_REVISION_MASK);
159 hw->phy.revision = (u32)(phy_id_low & ~TXGBE_PHY_REVISION_MASK);
161 DEBUGOUT("PHY_ID_HIGH 0x%04X, PHY_ID_LOW 0x%04X\n",
162 phy_id_high, phy_id_low);
168 * txgbe_get_phy_type_from_id - Get the phy type
169 * @phy_id: PHY ID information
172 enum txgbe_phy_type txgbe_get_phy_type_from_id(u32 phy_id)
174 enum txgbe_phy_type phy_type;
176 DEBUGFUNC("txgbe_get_phy_type_from_id");
179 case TXGBE_PHYID_TN1010:
180 phy_type = txgbe_phy_tn;
182 case TXGBE_PHYID_QT2022:
183 phy_type = txgbe_phy_qt;
185 case TXGBE_PHYID_ATH:
186 phy_type = txgbe_phy_nl;
188 case TXGBE_PHYID_MTD3310:
189 phy_type = txgbe_phy_cu_mtd;
192 phy_type = txgbe_phy_unknown;
200 * txgbe_identify_module - Identifies module type
201 * @hw: pointer to hardware structure
203 * Determines HW type and calls appropriate function.
205 s32 txgbe_identify_module(struct txgbe_hw *hw)
207 s32 err = TXGBE_ERR_SFP_NOT_PRESENT;
209 DEBUGFUNC("txgbe_identify_module");
211 switch (hw->phy.media_type) {
212 case txgbe_media_type_fiber:
213 err = txgbe_identify_sfp_module(hw);
216 case txgbe_media_type_fiber_qsfp:
217 err = txgbe_identify_qsfp_module(hw);
221 hw->phy.sfp_type = txgbe_sfp_type_not_present;
222 err = TXGBE_ERR_SFP_NOT_PRESENT;
230 * txgbe_identify_sfp_module - Identifies SFP modules
231 * @hw: pointer to hardware structure
233 * Searches for and identifies the SFP module and assigns appropriate PHY type.
235 s32 txgbe_identify_sfp_module(struct txgbe_hw *hw)
242 * txgbe_identify_qsfp_module - Identifies QSFP modules
243 * @hw: pointer to hardware structure
245 * Searches for and identifies the QSFP module and assigns appropriate PHY type
247 s32 txgbe_identify_qsfp_module(struct txgbe_hw *hw)