LCOV - code coverage report
Current view: top level - drivers/net/ngbe/base - ngbe_phy.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 155 0.0 %
Date: 2024-12-01 18:57:19 Functions: 0 13 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 64 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
       3                 :            :  * Copyright(c) 2010-2017 Intel Corporation
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "ngbe_hw.h"
       7                 :            : #include "ngbe_phy.h"
       8                 :            : 
       9                 :          0 : s32 ngbe_mdi_map_register(mdi_reg_t *reg, mdi_reg_22_t *reg22)
      10                 :            : {
      11                 :            :         bool match = 1;
      12         [ #  # ]:          0 :         switch (reg->device_type) {
      13                 :          0 :         case NGBE_MD_DEV_PMA_PMD:
      14         [ #  # ]:          0 :                 switch (reg->addr) {
      15                 :          0 :                 case NGBE_MD_PHY_ID_HIGH:
      16                 :            :                 case NGBE_MD_PHY_ID_LOW:
      17                 :          0 :                         reg22->page = 0;
      18                 :          0 :                         reg22->addr = reg->addr;
      19                 :          0 :                         reg22->device_type = 0;
      20                 :            :                         break;
      21                 :            :                 default:
      22                 :            :                         match = 0;
      23                 :            :                 }
      24                 :            :                 break;
      25                 :            :         default:
      26                 :            :                 match = 0;
      27                 :            :                 break;
      28                 :            :         }
      29                 :            : 
      30                 :            :         if (!match) {
      31                 :          0 :                 reg22->page = reg->device_type;
      32                 :          0 :                 reg22->device_type = reg->device_type;
      33                 :          0 :                 reg22->addr = reg->addr;
      34                 :            :         }
      35                 :            : 
      36                 :          0 :         return 0;
      37                 :            : }
      38                 :            : 
      39                 :            : /**
      40                 :            :  * ngbe_probe_phy - Identify a single address for a PHY
      41                 :            :  * @hw: pointer to hardware structure
      42                 :            :  * @phy_addr: PHY address to probe
      43                 :            :  *
      44                 :            :  * Returns true if PHY found
      45                 :            :  */
      46                 :          0 : static bool ngbe_probe_phy(struct ngbe_hw *hw, u16 phy_addr)
      47                 :            : {
      48         [ #  # ]:          0 :         if (!ngbe_validate_phy_addr(hw, phy_addr)) {
      49                 :          0 :                 DEBUGOUT("Unable to validate PHY address 0x%04X",
      50                 :            :                         phy_addr);
      51                 :          0 :                 return false;
      52                 :            :         }
      53                 :            : 
      54         [ #  # ]:          0 :         if (ngbe_get_phy_id(hw))
      55                 :            :                 return false;
      56                 :            : 
      57         [ #  # ]:          0 :         if (ngbe_get_phy_type_from_id(hw))
      58                 :          0 :                 return false;
      59                 :            : 
      60                 :            :         return true;
      61                 :            : }
      62                 :            : 
      63                 :            : /**
      64                 :            :  *  ngbe_identify_phy - Get physical layer module
      65                 :            :  *  @hw: pointer to hardware structure
      66                 :            :  *
      67                 :            :  *  Determines the physical layer module found on the current adapter.
      68                 :            :  **/
      69                 :          0 : s32 ngbe_identify_phy(struct ngbe_hw *hw)
      70                 :            : {
      71                 :            :         s32 err = NGBE_ERR_PHY_ADDR_INVALID;
      72                 :            :         u16 phy_addr;
      73                 :            : 
      74         [ #  # ]:          0 :         if (hw->phy.type != ngbe_phy_unknown)
      75                 :            :                 return 0;
      76                 :            : 
      77                 :            :         /* select clause22 */
      78                 :            :         wr32(hw, NGBE_MDIOMODE, NGBE_MDIOMODE_MASK);
      79                 :            : 
      80         [ #  # ]:          0 :         for (phy_addr = 0; phy_addr < NGBE_MAX_PHY_ADDR; phy_addr++) {
      81         [ #  # ]:          0 :                 if (ngbe_probe_phy(hw, phy_addr)) {
      82                 :            :                         err = 0;
      83                 :            :                         break;
      84                 :            :                 }
      85                 :            :         }
      86                 :            : 
      87                 :            :         return err;
      88                 :            : }
      89                 :            : 
      90                 :            : /**
      91                 :            :  * ngbe_check_reset_blocked - check status of MNG FW veto bit
      92                 :            :  * @hw: pointer to the hardware structure
      93                 :            :  *
      94                 :            :  * This function checks the STAT.MNGVETO bit to see if there are
      95                 :            :  * any constraints on link from manageability.  For MAC's that don't
      96                 :            :  * have this bit just return faluse since the link can not be blocked
      97                 :            :  * via this method.
      98                 :            :  **/
      99                 :          0 : s32 ngbe_check_reset_blocked(struct ngbe_hw *hw)
     100                 :            : {
     101                 :            :         u32 mmngc;
     102                 :            : 
     103                 :            :         mmngc = rd32(hw, NGBE_STAT);
     104         [ #  # ]:          0 :         if (mmngc & NGBE_STAT_MNGVETO) {
     105                 :          0 :                 DEBUGOUT("MNG_VETO bit detected.");
     106                 :          0 :                 return true;
     107                 :            :         }
     108                 :            : 
     109                 :            :         return false;
     110                 :            : }
     111                 :            : 
     112                 :            : /**
     113                 :            :  *  ngbe_validate_phy_addr - Determines phy address is valid
     114                 :            :  *  @hw: pointer to hardware structure
     115                 :            :  *  @phy_addr: PHY address
     116                 :            :  *
     117                 :            :  **/
     118                 :          0 : bool ngbe_validate_phy_addr(struct ngbe_hw *hw, u32 phy_addr)
     119                 :            : {
     120                 :          0 :         u16 phy_id = 0;
     121                 :            :         bool valid = false;
     122                 :            : 
     123                 :          0 :         hw->phy.addr = phy_addr;
     124                 :          0 :         hw->phy.read_reg(hw, NGBE_MD_PHY_ID_LOW,
     125                 :            :                              NGBE_MD_DEV_PMA_PMD, &phy_id);
     126                 :            : 
     127         [ #  # ]:          0 :         if (phy_id != 0xFFFF && phy_id != 0x0)
     128                 :            :                 valid = true;
     129                 :            : 
     130                 :          0 :         DEBUGOUT("PHY ID LOW is 0x%04X", phy_id);
     131                 :            : 
     132                 :          0 :         return valid;
     133                 :            : }
     134                 :            : 
     135                 :            : /**
     136                 :            :  *  ngbe_get_phy_id - Get the phy ID
     137                 :            :  *  @hw: pointer to hardware structure
     138                 :            :  *
     139                 :            :  **/
     140                 :          0 : s32 ngbe_get_phy_id(struct ngbe_hw *hw)
     141                 :            : {
     142                 :            :         u32 err;
     143                 :          0 :         u16 phy_id_high = 0;
     144                 :          0 :         u16 phy_id_low = 0;
     145                 :            : 
     146                 :          0 :         err = hw->phy.read_reg(hw, NGBE_MD_PHY_ID_HIGH,
     147                 :            :                                       NGBE_MD_DEV_PMA_PMD,
     148                 :            :                                       &phy_id_high);
     149                 :          0 :         hw->phy.id = (u32)(phy_id_high << 16);
     150                 :            : 
     151                 :          0 :         err = hw->phy.read_reg(hw, NGBE_MD_PHY_ID_LOW,
     152                 :            :                                 NGBE_MD_DEV_PMA_PMD,
     153                 :            :                                 &phy_id_low);
     154                 :          0 :         hw->phy.id |= (u32)(phy_id_low & NGBE_PHY_REVISION_MASK);
     155                 :          0 :         hw->phy.revision = (u32)(phy_id_low & ~NGBE_PHY_REVISION_MASK);
     156                 :            : 
     157                 :          0 :         DEBUGOUT("PHY_ID_HIGH 0x%04X, PHY_ID_LOW 0x%04X",
     158                 :            :                   phy_id_high, phy_id_low);
     159                 :            : 
     160                 :          0 :         return err;
     161                 :            : }
     162                 :            : 
     163                 :            : /**
     164                 :            :  *  ngbe_get_phy_type_from_id - Get the phy type
     165                 :            :  *
     166                 :            :  **/
     167                 :          0 : s32 ngbe_get_phy_type_from_id(struct ngbe_hw *hw)
     168                 :            : {
     169                 :            :         s32 status = 0;
     170                 :            : 
     171   [ #  #  #  # ]:          0 :         switch (hw->phy.id) {
     172                 :          0 :         case NGBE_PHYID_RTL:
     173                 :          0 :                 hw->phy.type = ngbe_phy_rtl;
     174                 :          0 :                 break;
     175                 :          0 :         case NGBE_PHYID_MVL:
     176         [ #  # ]:          0 :                 if (hw->phy.media_type == ngbe_media_type_fiber)
     177                 :          0 :                         hw->phy.type = ngbe_phy_mvl_sfi;
     178         [ #  # ]:          0 :                 else if (hw->phy.media_type == ngbe_media_type_copper)
     179                 :          0 :                         hw->phy.type = ngbe_phy_mvl;
     180                 :            :                 else
     181                 :          0 :                         status = ngbe_check_phy_mode_mvl(hw);
     182                 :            :                 break;
     183                 :          0 :         case NGBE_PHYID_YT8521:
     184                 :            :         case NGBE_PHYID_YT8531:
     185         [ #  # ]:          0 :                 if (hw->phy.media_type == ngbe_media_type_fiber)
     186                 :          0 :                         hw->phy.type = ngbe_phy_yt8521s_sfi;
     187                 :            :                 else
     188                 :          0 :                         hw->phy.type = ngbe_phy_yt8521s;
     189                 :            :                 break;
     190                 :          0 :         default:
     191                 :          0 :                 hw->phy.type = ngbe_phy_unknown;
     192                 :            :                 status = NGBE_ERR_DEVICE_NOT_SUPPORTED;
     193                 :          0 :                 break;
     194                 :            :         }
     195                 :            : 
     196                 :          0 :         return status;
     197                 :            : }
     198                 :            : 
     199                 :            : /**
     200                 :            :  *  ngbe_reset_phy - Performs a PHY reset
     201                 :            :  *  @hw: pointer to hardware structure
     202                 :            :  **/
     203                 :          0 : s32 ngbe_reset_phy(struct ngbe_hw *hw)
     204                 :            : {
     205                 :            :         s32 err = 0;
     206                 :            : 
     207         [ #  # ]:          0 :         if (hw->phy.type == ngbe_phy_unknown)
     208                 :          0 :                 err = ngbe_identify_phy(hw);
     209                 :            : 
     210   [ #  #  #  # ]:          0 :         if (err != 0 || hw->phy.type == ngbe_phy_none)
     211                 :          0 :                 return err;
     212                 :            : 
     213         [ #  # ]:          0 :         if (hw->ncsi_enabled)
     214                 :            :                 return err;
     215                 :            : 
     216                 :            :         /* Don't reset PHY if it's shut down due to overtemp. */
     217         [ #  # ]:          0 :         if (hw->mac.check_overtemp(hw) == NGBE_ERR_OVERTEMP)
     218                 :            :                 return err;
     219                 :            : 
     220                 :            :         /* Blocked by MNG FW so bail */
     221         [ #  # ]:          0 :         if (ngbe_check_reset_blocked(hw))
     222                 :            :                 return err;
     223                 :            : 
     224   [ #  #  #  # ]:          0 :         switch (hw->phy.type) {
     225                 :          0 :         case ngbe_phy_rtl:
     226                 :          0 :                 err = ngbe_reset_phy_rtl(hw);
     227                 :          0 :                 break;
     228                 :          0 :         case ngbe_phy_mvl:
     229                 :            :         case ngbe_phy_mvl_sfi:
     230                 :          0 :                 err = ngbe_reset_phy_mvl(hw);
     231                 :          0 :                 break;
     232                 :          0 :         case ngbe_phy_yt8521s:
     233                 :            :         case ngbe_phy_yt8521s_sfi:
     234                 :          0 :                 err = ngbe_reset_phy_yt(hw);
     235                 :          0 :                 break;
     236                 :            :         default:
     237                 :            :                 break;
     238                 :            :         }
     239                 :            : 
     240                 :            :         return err;
     241                 :            : }
     242                 :            : 
     243                 :            : /**
     244                 :            :  *  ngbe_read_phy_mdi - Reads a value from a specified PHY register without
     245                 :            :  *  the SWFW lock
     246                 :            :  *  @hw: pointer to hardware structure
     247                 :            :  *  @reg_addr: 32 bit address of PHY register to read
     248                 :            :  *  @device_type: 5 bit device type
     249                 :            :  *  @phy_data: Pointer to read data from PHY register
     250                 :            :  **/
     251                 :          0 : s32 ngbe_read_phy_reg_mdi(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
     252                 :            :                            u16 *phy_data)
     253                 :            : {
     254                 :            :         u32 command, data;
     255                 :            : 
     256                 :            :         /* Setup and write the address cycle command */
     257                 :          0 :         command = NGBE_MDIOSCA_REG(reg_addr) |
     258                 :          0 :                   NGBE_MDIOSCA_DEV(device_type) |
     259                 :          0 :                   NGBE_MDIOSCA_PORT(hw->phy.addr);
     260                 :            :         wr32(hw, NGBE_MDIOSCA, command);
     261                 :            : 
     262                 :            :         command = NGBE_MDIOSCD_CMD_READ |
     263                 :            :                   NGBE_MDIOSCD_BUSY |
     264                 :            :                   NGBE_MDIOSCD_CLOCK(6);
     265                 :            :         wr32(hw, NGBE_MDIOSCD, command);
     266                 :            : 
     267                 :            :         /*
     268                 :            :          * Check every 10 usec to see if the address cycle completed.
     269                 :            :          * The MDI Command bit will clear when the operation is
     270                 :            :          * complete
     271                 :            :          */
     272         [ #  # ]:          0 :         if (!po32m(hw, NGBE_MDIOSCD, NGBE_MDIOSCD_BUSY,
     273                 :            :                 0, NULL, 100, 100)) {
     274                 :          0 :                 DEBUGOUT("PHY address command did not complete");
     275                 :          0 :                 return NGBE_ERR_PHY;
     276                 :            :         }
     277                 :            : 
     278                 :            :         data = rd32(hw, NGBE_MDIOSCD);
     279                 :          0 :         *phy_data = (u16)NGBE_MDIOSCD_DAT_R(data);
     280                 :            : 
     281                 :          0 :         return 0;
     282                 :            : }
     283                 :            : 
     284                 :            : /**
     285                 :            :  *  ngbe_read_phy_reg - Reads a value from a specified PHY register
     286                 :            :  *  using the SWFW lock - this function is needed in most cases
     287                 :            :  *  @hw: pointer to hardware structure
     288                 :            :  *  @reg_addr: 32 bit address of PHY register to read
     289                 :            :  *  @device_type: 5 bit device type
     290                 :            :  *  @phy_data: Pointer to read data from PHY register
     291                 :            :  **/
     292                 :          0 : s32 ngbe_read_phy_reg(struct ngbe_hw *hw, u32 reg_addr,
     293                 :            :                                u32 device_type, u16 *phy_data)
     294                 :            : {
     295                 :            :         s32 err;
     296                 :            : 
     297                 :          0 :         err = hw->phy.read_reg_unlocked(hw, reg_addr, device_type,
     298                 :            :                                         phy_data);
     299                 :            : 
     300                 :          0 :         return err;
     301                 :            : }
     302                 :            : 
     303                 :            : /**
     304                 :            :  *  ngbe_write_phy_reg_mdi - Writes a value to specified PHY register
     305                 :            :  *  without SWFW lock
     306                 :            :  *  @hw: pointer to hardware structure
     307                 :            :  *  @reg_addr: 32 bit PHY register to write
     308                 :            :  *  @device_type: 5 bit device type
     309                 :            :  *  @phy_data: Data to write to the PHY register
     310                 :            :  **/
     311                 :          0 : s32 ngbe_write_phy_reg_mdi(struct ngbe_hw *hw, u32 reg_addr,
     312                 :            :                                 u32 device_type, u16 phy_data)
     313                 :            : {
     314                 :            :         u32 command;
     315                 :            : 
     316                 :            :         /* write command */
     317                 :          0 :         command = NGBE_MDIOSCA_REG(reg_addr) |
     318                 :          0 :                   NGBE_MDIOSCA_DEV(device_type) |
     319                 :          0 :                   NGBE_MDIOSCA_PORT(hw->phy.addr);
     320                 :            :         wr32(hw, NGBE_MDIOSCA, command);
     321                 :            : 
     322                 :          0 :         command = NGBE_MDIOSCD_CMD_WRITE |
     323                 :          0 :                   NGBE_MDIOSCD_DAT(phy_data) |
     324                 :            :                   NGBE_MDIOSCD_BUSY |
     325                 :            :                   NGBE_MDIOSCD_CLOCK(6);
     326                 :            :         wr32(hw, NGBE_MDIOSCD, command);
     327                 :            : 
     328                 :            :         /* wait for completion */
     329         [ #  # ]:          0 :         if (!po32m(hw, NGBE_MDIOSCD, NGBE_MDIOSCD_BUSY,
     330                 :            :                 0, NULL, 100, 100)) {
     331                 :          0 :                 DEBUGOUT("PHY write cmd didn't complete");
     332                 :          0 :                 return NGBE_ERR_PHY;
     333                 :            :         }
     334                 :            : 
     335                 :            :         return 0;
     336                 :            : }
     337                 :            : 
     338                 :            : /**
     339                 :            :  *  ngbe_write_phy_reg - Writes a value to specified PHY register
     340                 :            :  *  using SWFW lock- this function is needed in most cases
     341                 :            :  *  @hw: pointer to hardware structure
     342                 :            :  *  @reg_addr: 32 bit PHY register to write
     343                 :            :  *  @device_type: 5 bit device type
     344                 :            :  *  @phy_data: Data to write to the PHY register
     345                 :            :  **/
     346                 :          0 : s32 ngbe_write_phy_reg(struct ngbe_hw *hw, u32 reg_addr,
     347                 :            :                                 u32 device_type, u16 phy_data)
     348                 :            : {
     349                 :            :         s32 err;
     350                 :            : 
     351                 :          0 :         err = hw->phy.write_reg_unlocked(hw, reg_addr, device_type,
     352                 :            :                                          phy_data);
     353                 :            : 
     354                 :          0 :         return err;
     355                 :            : }
     356                 :            : 
     357                 :            : /**
     358                 :            :  *  ngbe_init_phy - PHY specific init
     359                 :            :  *  @hw: pointer to hardware structure
     360                 :            :  *
     361                 :            :  *  Initialize any function pointers that were not able to be
     362                 :            :  *  set during init_shared_code because the PHY type was
     363                 :            :  *  not known.
     364                 :            :  *
     365                 :            :  **/
     366                 :          0 : s32 ngbe_init_phy(struct ngbe_hw *hw)
     367                 :            : {
     368                 :            :         struct ngbe_phy_info *phy = &hw->phy;
     369                 :            :         s32 err = 0;
     370                 :            : 
     371                 :          0 :         hw->phy.addr = 0;
     372                 :            : 
     373   [ #  #  #  # ]:          0 :         switch (hw->sub_device_id) {
     374                 :          0 :         case NGBE_SUB_DEV_ID_EM_RTL_SGMII:
     375                 :            :         case NGBE_SUB_DEV_ID_EM_RTL_YT8521S_SFP:
     376                 :          0 :                 hw->phy.read_reg_unlocked = ngbe_read_phy_reg_rtl;
     377                 :          0 :                 hw->phy.write_reg_unlocked = ngbe_write_phy_reg_rtl;
     378                 :          0 :                 break;
     379                 :          0 :         case NGBE_SUB_DEV_ID_EM_MVL_RGMII:
     380                 :            :         case NGBE_SUB_DEV_ID_EM_MVL_SFP:
     381                 :            :         case NGBE_SUB_DEV_ID_EM_MVL_MIX:
     382                 :          0 :                 hw->phy.read_reg_unlocked = ngbe_read_phy_reg_mvl;
     383                 :          0 :                 hw->phy.write_reg_unlocked = ngbe_write_phy_reg_mvl;
     384                 :          0 :                 break;
     385                 :          0 :         case NGBE_SUB_DEV_ID_EM_YT8521S_SFP:
     386                 :          0 :                 hw->phy.read_reg_unlocked = ngbe_read_phy_reg_yt;
     387                 :          0 :                 hw->phy.write_reg_unlocked = ngbe_write_phy_reg_yt;
     388                 :          0 :                 break;
     389                 :            :         default:
     390                 :            :                 break;
     391                 :            :         }
     392                 :            : 
     393                 :          0 :         hw->phy.phy_semaphore_mask = NGBE_MNGSEM_SWPHY;
     394                 :            : 
     395                 :            :         /* Identify the PHY */
     396                 :          0 :         err = phy->identify(hw);
     397         [ #  # ]:          0 :         if (err == NGBE_ERR_PHY_ADDR_INVALID)
     398                 :          0 :                 goto init_phy_ops_out;
     399                 :            : 
     400                 :            :         /* Set necessary function pointers based on PHY type */
     401   [ #  #  #  # ]:          0 :         switch (hw->phy.type) {
     402                 :          0 :         case ngbe_phy_rtl:
     403                 :          0 :                 hw->phy.init_hw = ngbe_init_phy_rtl;
     404                 :          0 :                 hw->phy.check_link = ngbe_check_phy_link_rtl;
     405                 :          0 :                 hw->phy.setup_link = ngbe_setup_phy_link_rtl;
     406                 :          0 :                 hw->phy.set_phy_power = ngbe_set_phy_power_rtl;
     407                 :          0 :                 hw->phy.get_adv_pause = ngbe_get_phy_advertised_pause_rtl;
     408                 :          0 :                 hw->phy.get_lp_adv_pause = ngbe_get_phy_lp_advertised_pause_rtl;
     409                 :          0 :                 hw->phy.set_pause_adv = ngbe_set_phy_pause_adv_rtl;
     410                 :          0 :                 break;
     411                 :          0 :         case ngbe_phy_mvl:
     412                 :            :         case ngbe_phy_mvl_sfi:
     413                 :          0 :                 hw->phy.init_hw = ngbe_init_phy_mvl;
     414                 :          0 :                 hw->phy.check_link = ngbe_check_phy_link_mvl;
     415                 :          0 :                 hw->phy.setup_link = ngbe_setup_phy_link_mvl;
     416                 :          0 :                 hw->phy.set_phy_power = ngbe_set_phy_power_mvl;
     417                 :          0 :                 hw->phy.get_adv_pause = ngbe_get_phy_advertised_pause_mvl;
     418                 :          0 :                 hw->phy.get_lp_adv_pause = ngbe_get_phy_lp_advertised_pause_mvl;
     419                 :          0 :                 hw->phy.set_pause_adv = ngbe_set_phy_pause_adv_mvl;
     420                 :          0 :                 break;
     421                 :          0 :         case ngbe_phy_yt8521s:
     422                 :            :         case ngbe_phy_yt8521s_sfi:
     423                 :          0 :                 hw->phy.init_hw = ngbe_init_phy_yt;
     424                 :          0 :                 hw->phy.check_link = ngbe_check_phy_link_yt;
     425                 :          0 :                 hw->phy.setup_link = ngbe_setup_phy_link_yt;
     426                 :          0 :                 hw->phy.set_phy_power = ngbe_set_phy_power_yt;
     427                 :          0 :                 hw->phy.get_adv_pause = ngbe_get_phy_advertised_pause_yt;
     428                 :          0 :                 hw->phy.get_lp_adv_pause = ngbe_get_phy_lp_advertised_pause_yt;
     429                 :          0 :                 hw->phy.set_pause_adv = ngbe_set_phy_pause_adv_yt;
     430                 :            :         default:
     431                 :            :                 break;
     432                 :            :         }
     433                 :            : 
     434   [ #  #  #  # ]:          0 :         if (hw->wol_enabled || hw->ncsi_enabled)
     435                 :          0 :                 hw->phy.reset_disable = true;
     436                 :            : 
     437                 :          0 : init_phy_ops_out:
     438                 :          0 :         return err;
     439                 :            : }
     440                 :            : 

Generated by: LCOV version 1.14