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

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved.
       3                 :            :  *   Copyright(c) 2018 Synopsys, Inc. All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "axgbe_ethdev.h"
       7                 :            : #include "axgbe_common.h"
       8                 :            : #include "axgbe_phy.h"
       9                 :            : 
      10                 :            : static void axgbe_an37_clear_interrupts(struct axgbe_port *pdata)
      11                 :            : {
      12                 :            :         int reg;
      13                 :            : 
      14                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT);
      15                 :          0 :         reg &= ~AXGBE_AN_CL37_INT_MASK;
      16                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT, reg);
      17                 :          0 : }
      18                 :            : 
      19                 :          0 : static void axgbe_an37_disable_interrupts(struct axgbe_port *pdata)
      20                 :            : {
      21                 :            :         int reg;
      22                 :            : 
      23                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);
      24                 :          0 :         reg &= ~AXGBE_AN_CL37_INT_MASK;
      25                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);
      26                 :            : 
      27                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL);
      28                 :          0 :         reg &= ~AXGBE_PCS_CL37_BP;
      29                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL, reg);
      30                 :          0 : }
      31                 :            : 
      32                 :          0 : static void axgbe_an37_enable_interrupts(struct axgbe_port *pdata)
      33                 :            : {
      34                 :            :         unsigned int reg;
      35                 :            : 
      36                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL);
      37                 :          0 :         reg |= AXGBE_PCS_CL37_BP;
      38                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL, reg);
      39                 :            : 
      40                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);
      41                 :          0 :         reg |= AXGBE_AN_CL37_INT_MASK;
      42                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);
      43                 :          0 : }
      44                 :            : 
      45                 :            : static void axgbe_an73_clear_interrupts(struct axgbe_port *pdata)
      46                 :            : {
      47                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
      48                 :          0 : }
      49                 :            : 
      50                 :            : static void axgbe_an73_disable_interrupts(struct axgbe_port *pdata)
      51                 :            : {
      52                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);
      53                 :            : }
      54                 :            : 
      55                 :            : static void axgbe_an73_enable_interrupts(struct axgbe_port *pdata)
      56                 :            : {
      57                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK,
      58                 :            :                     AXGBE_AN_CL73_INT_MASK);
      59                 :          0 : }
      60                 :            : 
      61                 :          0 : static void axgbe_an_enable_interrupts(struct axgbe_port *pdata)
      62                 :            : {
      63      [ #  #  # ]:          0 :         switch (pdata->an_mode) {
      64                 :            :         case AXGBE_AN_MODE_CL73:
      65                 :            :         case AXGBE_AN_MODE_CL73_REDRV:
      66                 :            :                 axgbe_an73_enable_interrupts(pdata);
      67                 :            :                 break;
      68                 :          0 :         case AXGBE_AN_MODE_CL37:
      69                 :            :         case AXGBE_AN_MODE_CL37_SGMII:
      70                 :          0 :                 axgbe_an37_enable_interrupts(pdata);
      71                 :          0 :                 break;
      72                 :            :         default:
      73                 :            :                 break;
      74                 :            :         }
      75                 :          0 : }
      76                 :            : 
      77                 :          0 : static void axgbe_an_clear_interrupts_all(struct axgbe_port *pdata)
      78                 :            : {
      79                 :            :         axgbe_an73_clear_interrupts(pdata);
      80                 :            :         axgbe_an37_clear_interrupts(pdata);
      81                 :          0 : }
      82                 :            : 
      83                 :            : 
      84                 :            : 
      85                 :            : static void axgbe_kr_mode(struct axgbe_port *pdata)
      86                 :            : {
      87                 :            :         /* Set MAC to 10G speed */
      88                 :          0 :         pdata->hw_if.set_speed(pdata, SPEED_10000);
      89                 :            : 
      90                 :            :         /* Call PHY implementation support to complete rate change */
      91                 :          0 :         pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_KR);
      92                 :          0 : }
      93                 :            : 
      94                 :            : static void axgbe_kx_2500_mode(struct axgbe_port *pdata)
      95                 :            : {
      96                 :            :         /* Set MAC to 2.5G speed */
      97                 :          0 :         pdata->hw_if.set_speed(pdata, SPEED_2500);
      98                 :            : 
      99                 :            :         /* Call PHY implementation support to complete rate change */
     100                 :          0 :         pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_KX_2500);
     101                 :          0 : }
     102                 :            : 
     103                 :            : static void axgbe_kx_1000_mode(struct axgbe_port *pdata)
     104                 :            : {
     105                 :            :         /* Set MAC to 1G speed */
     106                 :          0 :         pdata->hw_if.set_speed(pdata, SPEED_1000);
     107                 :            : 
     108                 :            :         /* Call PHY implementation support to complete rate change */
     109                 :          0 :         pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_KX_1000);
     110                 :          0 : }
     111                 :            : 
     112                 :          0 : static void axgbe_sfi_mode(struct axgbe_port *pdata)
     113                 :            : {
     114                 :            :         /* If a KR re-driver is present, change to KR mode instead */
     115         [ #  # ]:          0 :         if (pdata->kr_redrv)
     116                 :          0 :                 return axgbe_kr_mode(pdata);
     117                 :            : 
     118                 :            : 
     119                 :            :         /* Set MAC to 10G speed */
     120                 :          0 :         pdata->hw_if.set_speed(pdata, SPEED_10000);
     121                 :            : 
     122                 :            :         /* Call PHY implementation support to complete rate change */
     123                 :          0 :         pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SFI);
     124                 :            : }
     125                 :            : 
     126                 :            : static void axgbe_x_mode(struct axgbe_port *pdata)
     127                 :            : {
     128                 :            : 
     129                 :            :         /* Set MAC to 1G speed */
     130                 :          0 :         pdata->hw_if.set_speed(pdata, SPEED_1000);
     131                 :            : 
     132                 :            :         /* Call PHY implementation support to complete rate change */
     133                 :          0 :         pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_X);
     134                 :          0 : }
     135                 :            : 
     136                 :            : static void axgbe_sgmii_1000_mode(struct axgbe_port *pdata)
     137                 :            : {
     138                 :            : 
     139                 :            :         /* Set MAC to 1G speed */
     140                 :          0 :         pdata->hw_if.set_speed(pdata, SPEED_1000);
     141                 :            : 
     142                 :            :         /* Call PHY implementation support to complete rate change */
     143                 :          0 :         pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SGMII_1000);
     144                 :          0 : }
     145                 :            : 
     146                 :            : static void axgbe_sgmii_10_mode(struct axgbe_port *pdata)
     147                 :            : {
     148                 :            :         /* Set MAC to 10M speed */
     149                 :          0 :         pdata->hw_if.set_speed(pdata, SPEED_10);
     150                 :            : 
     151                 :            :         /* Call PHY implementation support to complete rate change */
     152                 :          0 :         pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SGMII_10);
     153                 :          0 : }
     154                 :            : 
     155                 :            : static void axgbe_sgmii_100_mode(struct axgbe_port *pdata)
     156                 :            : {
     157                 :            : 
     158                 :            :         /* Set MAC to 1G speed */
     159                 :          0 :         pdata->hw_if.set_speed(pdata, SPEED_1000);
     160                 :            : 
     161                 :            :         /* Call PHY implementation support to complete rate change */
     162                 :          0 :         pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SGMII_100);
     163                 :          0 : }
     164                 :            : 
     165                 :            : static enum axgbe_mode axgbe_cur_mode(struct axgbe_port *pdata)
     166                 :            : {
     167                 :          0 :         return pdata->phy_if.phy_impl.cur_mode(pdata);
     168                 :            : }
     169                 :            : 
     170                 :            : static bool axgbe_in_kr_mode(struct axgbe_port *pdata)
     171                 :            : {
     172                 :            :         return axgbe_cur_mode(pdata) == AXGBE_MODE_KR;
     173                 :            : }
     174                 :            : 
     175                 :          0 : static void axgbe_change_mode(struct axgbe_port *pdata,
     176                 :            :                               enum axgbe_mode mode)
     177                 :            : {
     178   [ #  #  #  #  :          0 :         switch (mode) {
          #  #  #  #  #  
                      # ]
     179                 :            :         case AXGBE_MODE_KX_1000:
     180                 :            :                 axgbe_kx_1000_mode(pdata);
     181                 :            :                 break;
     182                 :            :         case AXGBE_MODE_KX_2500:
     183                 :            :                 axgbe_kx_2500_mode(pdata);
     184                 :            :                 break;
     185                 :            :         case AXGBE_MODE_KR:
     186                 :            :                 axgbe_kr_mode(pdata);
     187                 :            :                 break;
     188                 :            :         case AXGBE_MODE_SGMII_10:
     189                 :            :                 axgbe_sgmii_10_mode(pdata);
     190                 :            :                 break;
     191                 :            :         case AXGBE_MODE_SGMII_100:
     192                 :            :                 axgbe_sgmii_100_mode(pdata);
     193                 :            :                 break;
     194                 :            :         case AXGBE_MODE_SGMII_1000:
     195                 :            :                 axgbe_sgmii_1000_mode(pdata);
     196                 :            :                 break;
     197                 :            :         case AXGBE_MODE_X:
     198                 :            :                 axgbe_x_mode(pdata);
     199                 :            :                 break;
     200                 :          0 :         case AXGBE_MODE_SFI:
     201                 :          0 :                 axgbe_sfi_mode(pdata);
     202                 :          0 :                 break;
     203                 :            :         case AXGBE_MODE_UNKNOWN:
     204                 :            :                 break;
     205                 :          0 :         default:
     206                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "invalid operation mode requested (%u)", mode);
     207                 :            :         }
     208                 :          0 : }
     209                 :            : 
     210                 :            : static void axgbe_switch_mode(struct axgbe_port *pdata)
     211                 :            : {
     212                 :          0 :         axgbe_change_mode(pdata, pdata->phy_if.phy_impl.switch_mode(pdata));
     213                 :            : }
     214                 :            : 
     215                 :          0 : static bool axgbe_set_mode(struct axgbe_port *pdata,
     216                 :            :                            enum axgbe_mode mode)
     217                 :            : {
     218   [ #  #  #  # ]:          0 :         if (mode == axgbe_cur_mode(pdata))
     219                 :            :                 return false;
     220                 :            : 
     221                 :          0 :         axgbe_change_mode(pdata, mode);
     222                 :          0 :         return true;
     223                 :            : }
     224                 :            : 
     225                 :            : static bool axgbe_use_mode(struct axgbe_port *pdata,
     226                 :            :                            enum axgbe_mode mode)
     227                 :            : {
     228                 :          0 :         return pdata->phy_if.phy_impl.use_mode(pdata, mode);
     229                 :            : }
     230                 :            : 
     231                 :            : static void axgbe_an37_set(struct axgbe_port *pdata, bool enable,
     232                 :            :                            bool restart)
     233                 :            : {
     234                 :            :         unsigned int reg;
     235                 :            : 
     236                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_CTRL1);
     237                 :          0 :         reg &= ~MDIO_VEND2_CTRL1_AN_ENABLE;
     238                 :            : 
     239                 :            :         if (enable)
     240                 :            :                 reg |= MDIO_VEND2_CTRL1_AN_ENABLE;
     241                 :            : 
     242                 :            :         if (restart)
     243                 :          0 :                 reg |= MDIO_VEND2_CTRL1_AN_RESTART;
     244                 :            : 
     245                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_CTRL1, reg);
     246                 :            : }
     247                 :            : 
     248                 :          0 : static void axgbe_an37_restart(struct axgbe_port *pdata)
     249                 :            : {
     250                 :          0 :         axgbe_an37_enable_interrupts(pdata);
     251                 :            :         axgbe_an37_set(pdata, true, true);
     252                 :          0 : }
     253                 :            : 
     254                 :          0 : static void axgbe_an37_disable(struct axgbe_port *pdata)
     255                 :            : {
     256                 :            :         axgbe_an37_set(pdata, false, false);
     257                 :          0 :         axgbe_an37_disable_interrupts(pdata);
     258                 :          0 : }
     259                 :            : 
     260                 :          0 : static void axgbe_an73_set(struct axgbe_port *pdata, bool enable,
     261                 :            :                            bool restart)
     262                 :            : {
     263                 :            :         unsigned int reg;
     264                 :            : 
     265                 :            :         /* Disable KR training for now */
     266                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
     267                 :          0 :         reg &= ~AXGBE_KR_TRAINING_ENABLE;
     268                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
     269                 :            : 
     270                 :            :         /* Update AN settings */
     271                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1);
     272                 :          0 :         reg &= ~MDIO_AN_CTRL1_ENABLE;
     273                 :            : 
     274         [ #  # ]:          0 :         if (enable)
     275                 :          0 :                 reg |= MDIO_AN_CTRL1_ENABLE;
     276                 :            : 
     277         [ #  # ]:          0 :         if (restart)
     278                 :          0 :                 reg |= MDIO_AN_CTRL1_RESTART;
     279                 :            : 
     280                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_CTRL1, reg);
     281                 :          0 : }
     282                 :            : 
     283                 :          0 : static void axgbe_an73_restart(struct axgbe_port *pdata)
     284                 :            : {
     285                 :            :         axgbe_an73_enable_interrupts(pdata);
     286                 :          0 :         axgbe_an73_set(pdata, true, true);
     287                 :            : 
     288                 :          0 :         PMD_DRV_LOG_LINE(DEBUG, "CL73 AN enabled/restarted");
     289                 :          0 : }
     290                 :            : 
     291                 :          0 : static void axgbe_an73_disable(struct axgbe_port *pdata)
     292                 :            : {
     293                 :          0 :         axgbe_an73_set(pdata, false, false);
     294                 :            :         axgbe_an73_disable_interrupts(pdata);
     295                 :          0 :         pdata->an_start = 0;
     296                 :            : 
     297                 :          0 :         PMD_DRV_LOG_LINE(DEBUG, "CL73 AN disabled");
     298                 :          0 : }
     299                 :            : 
     300                 :          0 : static void axgbe_an_restart(struct axgbe_port *pdata)
     301                 :            : {
     302         [ #  # ]:          0 :         if (pdata->phy_if.phy_impl.an_pre)
     303                 :          0 :                 pdata->phy_if.phy_impl.an_pre(pdata);
     304                 :            : 
     305      [ #  #  # ]:          0 :         switch (pdata->an_mode) {
     306                 :          0 :         case AXGBE_AN_MODE_CL73:
     307                 :            :         case AXGBE_AN_MODE_CL73_REDRV:
     308                 :          0 :                 axgbe_an73_restart(pdata);
     309                 :          0 :                 break;
     310                 :          0 :         case AXGBE_AN_MODE_CL37:
     311                 :            :         case AXGBE_AN_MODE_CL37_SGMII:
     312                 :          0 :                 axgbe_an37_restart(pdata);
     313                 :          0 :                 break;
     314                 :            :         default:
     315                 :            :                 break;
     316                 :            :         }
     317                 :          0 : }
     318                 :            : 
     319                 :          0 : static void axgbe_an_disable(struct axgbe_port *pdata)
     320                 :            : {
     321         [ #  # ]:          0 :         if (pdata->phy_if.phy_impl.an_post)
     322                 :          0 :                 pdata->phy_if.phy_impl.an_post(pdata);
     323                 :            : 
     324      [ #  #  # ]:          0 :         switch (pdata->an_mode) {
     325                 :          0 :         case AXGBE_AN_MODE_CL73:
     326                 :            :         case AXGBE_AN_MODE_CL73_REDRV:
     327                 :          0 :                 axgbe_an73_disable(pdata);
     328                 :          0 :                 break;
     329                 :          0 :         case AXGBE_AN_MODE_CL37:
     330                 :            :         case AXGBE_AN_MODE_CL37_SGMII:
     331                 :          0 :                 axgbe_an37_disable(pdata);
     332                 :          0 :                 break;
     333                 :            :         default:
     334                 :            :                 break;
     335                 :            :         }
     336                 :          0 : }
     337                 :            : 
     338                 :            : static void axgbe_an_disable_all(struct axgbe_port *pdata)
     339                 :            : {
     340                 :          0 :         axgbe_an73_disable(pdata);
     341                 :          0 :         axgbe_an37_disable(pdata);
     342                 :            : }
     343                 :            : 
     344                 :          0 : static enum axgbe_an axgbe_an73_tx_training(struct axgbe_port *pdata,
     345                 :            :                                             enum axgbe_rx *state)
     346                 :            : {
     347                 :            :         unsigned int ad_reg, lp_reg, reg;
     348                 :            : 
     349                 :          0 :         *state = AXGBE_RX_COMPLETE;
     350                 :            : 
     351                 :            :         /* If we're not in KR mode then we're done */
     352         [ #  # ]:          0 :         if (!axgbe_in_kr_mode(pdata))
     353                 :            :                 return AXGBE_AN_PAGE_RECEIVED;
     354                 :            : 
     355                 :            :         /* Enable/Disable FEC */
     356                 :          0 :         ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
     357                 :          0 :         lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);
     358                 :            : 
     359                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL);
     360                 :          0 :         reg &= ~(MDIO_PMA_10GBR_FECABLE_ABLE | MDIO_PMA_10GBR_FECABLE_ERRABLE);
     361   [ #  #  #  # ]:          0 :         if ((ad_reg & 0xc000) && (lp_reg & 0xc000))
     362                 :          0 :                 reg |= pdata->fec_ability;
     363                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL, reg);
     364                 :            : 
     365                 :            :         /* Start KR training */
     366         [ #  # ]:          0 :         if (pdata->phy_if.phy_impl.kr_training_pre)
     367                 :          0 :                 pdata->phy_if.phy_impl.kr_training_pre(pdata);
     368                 :            : 
     369                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
     370                 :            :         reg |= AXGBE_KR_TRAINING_ENABLE;
     371                 :          0 :         reg |= AXGBE_KR_TRAINING_START;
     372                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
     373                 :          0 :         pdata->kr_start_time = rte_get_timer_cycles();
     374                 :            : 
     375                 :          0 :         PMD_DRV_LOG_LINE(DEBUG, "KR training initiated");
     376         [ #  # ]:          0 :         if (pdata->phy_if.phy_impl.kr_training_post)
     377                 :          0 :                 pdata->phy_if.phy_impl.kr_training_post(pdata);
     378                 :            : 
     379                 :            :         return AXGBE_AN_PAGE_RECEIVED;
     380                 :            : }
     381                 :            : 
     382                 :          0 : static enum axgbe_an axgbe_an73_tx_xnp(struct axgbe_port *pdata,
     383                 :            :                                        enum axgbe_rx *state)
     384                 :            : {
     385                 :            :         u16 msg;
     386                 :            : 
     387                 :          0 :         *state = AXGBE_RX_XNP;
     388                 :            : 
     389                 :            :         msg = AXGBE_XNP_MCF_NULL_MESSAGE;
     390                 :            :         msg |= AXGBE_XNP_MP_FORMATTED;
     391                 :            : 
     392                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 2, 0);
     393                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 1, 0);
     394                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP, msg);
     395                 :            : 
     396                 :          0 :         return AXGBE_AN_PAGE_RECEIVED;
     397                 :            : }
     398                 :            : 
     399                 :          0 : static enum axgbe_an axgbe_an73_rx_bpa(struct axgbe_port *pdata,
     400                 :            :                                        enum axgbe_rx *state)
     401                 :            : {
     402                 :            :         unsigned int link_support;
     403                 :            :         unsigned int reg, ad_reg, lp_reg;
     404                 :            : 
     405                 :            :         /* Read Base Ability register 2 first */
     406                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
     407                 :            : 
     408                 :            :         /* Check for a supported mode, otherwise restart in a different one */
     409         [ #  # ]:          0 :         link_support = axgbe_in_kr_mode(pdata) ? 0x80 : 0x20;
     410         [ #  # ]:          0 :         if (!(reg & link_support))
     411                 :            :                 return AXGBE_AN_INCOMPAT_LINK;
     412                 :            : 
     413                 :            :         /* Check Extended Next Page support */
     414                 :          0 :         ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
     415                 :          0 :         lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA);
     416                 :            : 
     417                 :          0 :         return ((ad_reg & AXGBE_XNP_NP_EXCHANGE) ||
     418         [ #  # ]:          0 :                 (lp_reg & AXGBE_XNP_NP_EXCHANGE))
     419                 :          0 :                 ? axgbe_an73_tx_xnp(pdata, state)
     420         [ #  # ]:          0 :                 : axgbe_an73_tx_training(pdata, state);
     421                 :            : }
     422                 :            : 
     423                 :          0 : static enum axgbe_an axgbe_an73_rx_xnp(struct axgbe_port *pdata,
     424                 :            :                                        enum axgbe_rx *state)
     425                 :            : {
     426                 :            :         unsigned int ad_reg, lp_reg;
     427                 :            : 
     428                 :            :         /* Check Extended Next Page support */
     429                 :          0 :         ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_XNP);
     430                 :          0 :         lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPX);
     431                 :            : 
     432                 :          0 :         return ((ad_reg & AXGBE_XNP_NP_EXCHANGE) ||
     433         [ #  # ]:          0 :                 (lp_reg & AXGBE_XNP_NP_EXCHANGE))
     434                 :          0 :                 ? axgbe_an73_tx_xnp(pdata, state)
     435         [ #  # ]:          0 :                 : axgbe_an73_tx_training(pdata, state);
     436                 :            : }
     437                 :            : 
     438                 :          0 : static enum axgbe_an axgbe_an73_page_received(struct axgbe_port *pdata)
     439                 :            : {
     440                 :            :         enum axgbe_rx *state;
     441                 :            :         unsigned long an_timeout;
     442                 :            :         enum axgbe_an ret;
     443                 :            :         unsigned long ticks;
     444                 :            : 
     445         [ #  # ]:          0 :         if (!pdata->an_start) {
     446                 :          0 :                 pdata->an_start = rte_get_timer_cycles();
     447                 :            :         } else {
     448                 :            :                 an_timeout = pdata->an_start +
     449                 :            :                         msecs_to_timer_cycles(AXGBE_AN_MS_TIMEOUT);
     450                 :            :                 ticks = rte_get_timer_cycles();
     451         [ #  # ]:          0 :                 if (time_after(ticks, an_timeout)) {
     452                 :            :                         /* Auto-negotiation timed out, reset state */
     453                 :          0 :                         pdata->kr_state = AXGBE_RX_BPA;
     454                 :          0 :                         pdata->kx_state = AXGBE_RX_BPA;
     455                 :            : 
     456                 :          0 :                         pdata->an_start = rte_get_timer_cycles();
     457                 :            : 
     458                 :          0 :                         PMD_DRV_LOG_LINE(NOTICE,
     459                 :            :                                     "CL73 AN timed out, resetting state");
     460                 :            :                 }
     461                 :            :         }
     462                 :            : 
     463                 :            :         state = axgbe_in_kr_mode(pdata) ? &pdata->kr_state
     464         [ #  # ]:          0 :                 : &pdata->kx_state;
     465                 :            : 
     466      [ #  #  # ]:          0 :         switch (*state) {
     467                 :          0 :         case AXGBE_RX_BPA:
     468                 :          0 :                 ret = axgbe_an73_rx_bpa(pdata, state);
     469                 :          0 :                 break;
     470                 :          0 :         case AXGBE_RX_XNP:
     471                 :          0 :                 ret = axgbe_an73_rx_xnp(pdata, state);
     472                 :          0 :                 break;
     473                 :            :         default:
     474                 :            :                 ret = AXGBE_AN_ERROR;
     475                 :            :         }
     476                 :            : 
     477                 :          0 :         return ret;
     478                 :            : }
     479                 :            : 
     480                 :          0 : static enum axgbe_an axgbe_an73_incompat_link(struct axgbe_port *pdata)
     481                 :            : {
     482                 :            :         /* Be sure we aren't looping trying to negotiate */
     483         [ #  # ]:          0 :         if (axgbe_in_kr_mode(pdata)) {
     484                 :          0 :                 pdata->kr_state = AXGBE_RX_ERROR;
     485                 :            : 
     486         [ #  # ]:          0 :                 if (!(pdata->phy.advertising & ADVERTISED_1000baseKX_Full) &&
     487                 :            :                     !(pdata->phy.advertising & ADVERTISED_2500baseX_Full))
     488                 :            :                         return AXGBE_AN_NO_LINK;
     489                 :            : 
     490         [ #  # ]:          0 :                 if (pdata->kx_state != AXGBE_RX_BPA)
     491                 :            :                         return AXGBE_AN_NO_LINK;
     492                 :            :         } else {
     493                 :          0 :                 pdata->kx_state = AXGBE_RX_ERROR;
     494                 :            : 
     495         [ #  # ]:          0 :                 if (!(pdata->phy.advertising & ADVERTISED_10000baseKR_Full))
     496                 :            :                         return AXGBE_AN_NO_LINK;
     497                 :            : 
     498         [ #  # ]:          0 :                 if (pdata->kr_state != AXGBE_RX_BPA)
     499                 :            :                         return AXGBE_AN_NO_LINK;
     500                 :            :         }
     501                 :            : 
     502                 :          0 :         axgbe_an_disable(pdata);
     503                 :            :         axgbe_switch_mode(pdata);
     504                 :          0 :         pdata->an_result = AXGBE_AN_READY;
     505                 :          0 :         axgbe_an_restart(pdata);
     506                 :            : 
     507                 :          0 :         return AXGBE_AN_INCOMPAT_LINK;
     508                 :            : }
     509                 :            : 
     510                 :            : static const char *axgbe_state_as_string(enum axgbe_an state)
     511                 :            : {
     512                 :          0 :         switch (state) {
     513                 :            :         case AXGBE_AN_READY:
     514                 :            :                 return "Ready";
     515                 :          0 :         case AXGBE_AN_PAGE_RECEIVED:
     516                 :          0 :                 return "Page-Received";
     517                 :          0 :         case AXGBE_AN_INCOMPAT_LINK:
     518                 :          0 :                 return "Incompatible-Link";
     519                 :          0 :         case AXGBE_AN_COMPLETE:
     520                 :          0 :                 return "Complete";
     521                 :          0 :         case AXGBE_AN_NO_LINK:
     522                 :          0 :                 return "No-Link";
     523                 :          0 :         case AXGBE_AN_ERROR:
     524                 :          0 :                 return "Error";
     525                 :          0 :         default:
     526                 :          0 :                 return "Undefined";
     527                 :            :         }
     528                 :            : }
     529                 :            : 
     530                 :          0 : static void axgbe_an73_state_machine(struct axgbe_port *pdata)
     531                 :            : {
     532                 :            :         enum axgbe_an cur_state = pdata->an_state;
     533                 :            : 
     534         [ #  # ]:          0 :         if (!pdata->an_int)
     535                 :            :                 return;
     536                 :            : 
     537                 :          0 : next_int:
     538         [ #  # ]:          0 :         if (pdata->an_int & AXGBE_AN_CL73_PG_RCV) {
     539                 :          0 :                 pdata->an_state = AXGBE_AN_PAGE_RECEIVED;
     540                 :          0 :                 pdata->an_int &= ~AXGBE_AN_CL73_PG_RCV;
     541         [ #  # ]:          0 :         } else if (pdata->an_int & AXGBE_AN_CL73_INC_LINK) {
     542                 :          0 :                 pdata->an_state = AXGBE_AN_INCOMPAT_LINK;
     543                 :          0 :                 pdata->an_int &= ~AXGBE_AN_CL73_INC_LINK;
     544         [ #  # ]:          0 :         } else if (pdata->an_int & AXGBE_AN_CL73_INT_CMPLT) {
     545                 :          0 :                 pdata->an_state = AXGBE_AN_COMPLETE;
     546                 :          0 :                 pdata->an_int &= ~AXGBE_AN_CL73_INT_CMPLT;
     547                 :            :         } else {
     548                 :          0 :                 pdata->an_state = AXGBE_AN_ERROR;
     549                 :            :         }
     550                 :            : 
     551   [ #  #  #  #  :          0 :         PMD_DRV_LOG_LINE(DEBUG, "CL73 AN : %s",
                #  #  # ]
     552                 :            :                     axgbe_state_as_string(pdata->an_state));
     553                 :            : 
     554                 :          0 : again:
     555                 :          0 :         cur_state = pdata->an_state;
     556                 :            : 
     557   [ #  #  #  #  :          0 :         switch (pdata->an_state) {
                   #  # ]
     558                 :          0 :         case AXGBE_AN_READY:
     559                 :          0 :                 pdata->an_supported = 0;
     560                 :          0 :                 break;
     561                 :          0 :         case AXGBE_AN_PAGE_RECEIVED:
     562                 :          0 :                 pdata->an_state = axgbe_an73_page_received(pdata);
     563                 :          0 :                 pdata->an_supported++;
     564                 :          0 :                 break;
     565                 :          0 :         case AXGBE_AN_INCOMPAT_LINK:
     566                 :          0 :                 pdata->an_supported = 0;
     567                 :          0 :                 pdata->parallel_detect = 0;
     568                 :          0 :                 pdata->an_state = axgbe_an73_incompat_link(pdata);
     569                 :          0 :                 break;
     570                 :          0 :         case AXGBE_AN_COMPLETE:
     571                 :          0 :                 pdata->parallel_detect = pdata->an_supported ? 0 : 1;
     572                 :          0 :                 break;
     573                 :            :         case AXGBE_AN_NO_LINK:
     574                 :            :                 break;
     575                 :          0 :         default:
     576                 :          0 :                 pdata->an_state = AXGBE_AN_ERROR;
     577                 :            :         }
     578                 :            : 
     579         [ #  # ]:          0 :         if (pdata->an_state == AXGBE_AN_NO_LINK) {
     580                 :          0 :                 pdata->an_int = 0;
     581                 :            :                 axgbe_an73_clear_interrupts(pdata);
     582                 :          0 :                 pdata->eth_dev->data->dev_link.link_status =
     583                 :            :                         RTE_ETH_LINK_DOWN;
     584         [ #  # ]:          0 :         } else if (pdata->an_state == AXGBE_AN_ERROR) {
     585                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "error during auto-negotiation, state=%u",
     586                 :            :                             cur_state);
     587                 :          0 :                 pdata->an_int = 0;
     588                 :            :                 axgbe_an73_clear_interrupts(pdata);
     589                 :            :         }
     590                 :            : 
     591         [ #  # ]:          0 :         if (pdata->an_state >= AXGBE_AN_COMPLETE) {
     592                 :          0 :                 pdata->an_result = pdata->an_state;
     593                 :          0 :                 pdata->an_state = AXGBE_AN_READY;
     594                 :          0 :                 pdata->kr_state = AXGBE_RX_BPA;
     595                 :          0 :                 pdata->kx_state = AXGBE_RX_BPA;
     596                 :          0 :                 pdata->an_start = 0;
     597         [ #  # ]:          0 :                 if (pdata->phy_if.phy_impl.an_post)
     598                 :          0 :                         pdata->phy_if.phy_impl.an_post(pdata);
     599                 :            : 
     600   [ #  #  #  #  :          0 :                 PMD_DRV_LOG_LINE(DEBUG, "CL73 AN result: %s",
                #  #  # ]
     601                 :            :                             axgbe_state_as_string(pdata->an_result));
     602                 :            :         }
     603                 :            : 
     604         [ #  # ]:          0 :         if (cur_state != pdata->an_state)
     605                 :          0 :                 goto again;
     606                 :            : 
     607         [ #  # ]:          0 :         if (pdata->an_int)
     608                 :          0 :                 goto next_int;
     609                 :            : 
     610                 :            :         axgbe_an73_enable_interrupts(pdata);
     611                 :            : }
     612                 :            : 
     613                 :          0 : static void axgbe_an37_state_machine(struct axgbe_port *pdata)
     614                 :            : {
     615                 :            :         enum axgbe_an cur_state = pdata->an_state;
     616                 :            : 
     617         [ #  # ]:          0 :         if (!pdata->an_int)
     618                 :            :                 return;
     619         [ #  # ]:          0 :         if (pdata->an_int & AXGBE_AN_CL37_INT_CMPLT) {
     620                 :          0 :                 pdata->an_state = AXGBE_AN_COMPLETE;
     621                 :          0 :                 pdata->an_int &= ~AXGBE_AN_CL37_INT_CMPLT;
     622                 :            : 
     623                 :            :         /* If SGMII is enabled, check the link status */
     624         [ #  # ]:          0 :                 if (pdata->an_mode == AXGBE_AN_MODE_CL37_SGMII &&
     625         [ #  # ]:          0 :                     !(pdata->an_status & AXGBE_SGMII_AN_LINK_STATUS))
     626                 :          0 :                         pdata->an_state = AXGBE_AN_NO_LINK;
     627                 :            :         }
     628                 :            : 
     629                 :          0 :         cur_state = pdata->an_state;
     630                 :            : 
     631         [ #  # ]:          0 :         switch (pdata->an_state) {
     632                 :            :         case AXGBE_AN_READY:
     633                 :            :                 break;
     634                 :            :         case AXGBE_AN_COMPLETE:
     635                 :            :                 break;
     636                 :            :         case AXGBE_AN_NO_LINK:
     637                 :            :                 break;
     638                 :          0 :         default:
     639                 :          0 :                 pdata->an_state = AXGBE_AN_ERROR;
     640                 :          0 :                 break;
     641                 :            :         }
     642                 :            : 
     643         [ #  # ]:          0 :         if (pdata->an_state == AXGBE_AN_ERROR) {
     644                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "error during auto-negotiation, state=%u",
     645                 :            :                             cur_state);
     646                 :          0 :                 pdata->an_int = 0;
     647                 :            :                 axgbe_an37_clear_interrupts(pdata);
     648                 :            :         }
     649                 :            : 
     650         [ #  # ]:          0 :         if (pdata->an_state >= AXGBE_AN_COMPLETE) {
     651                 :          0 :                 pdata->an_result = pdata->an_state;
     652                 :          0 :                 pdata->an_state = AXGBE_AN_READY;
     653         [ #  # ]:          0 :                 if (pdata->phy_if.phy_impl.an_post)
     654                 :          0 :                         pdata->phy_if.phy_impl.an_post(pdata);
     655                 :            :         }
     656                 :            : 
     657                 :          0 :         axgbe_an37_enable_interrupts(pdata);
     658                 :            : }
     659                 :            : 
     660                 :          0 : static void axgbe_an73_isr(struct axgbe_port *pdata)
     661                 :            : {
     662                 :            :         /* Disable AN interrupts */
     663                 :            :         axgbe_an73_disable_interrupts(pdata);
     664                 :            : 
     665                 :            :         /* Save the interrupt(s) that fired */
     666                 :          0 :         pdata->an_int = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT);
     667                 :            :         axgbe_an73_clear_interrupts(pdata);
     668                 :            : 
     669         [ #  # ]:          0 :         if (pdata->an_int) {
     670                 :            :                 /* Clear the interrupt(s) that fired and process them */
     671                 :          0 :                 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, ~pdata->an_int);
     672                 :          0 :                 pthread_mutex_lock(&pdata->an_mutex);
     673                 :          0 :                 axgbe_an73_state_machine(pdata);
     674                 :          0 :                 pthread_mutex_unlock(&pdata->an_mutex);
     675                 :            :         } else {
     676                 :            :                 /* Enable AN interrupts */
     677                 :            :                 axgbe_an73_enable_interrupts(pdata);
     678                 :            :         }
     679                 :          0 : }
     680                 :            : 
     681                 :          0 : static void axgbe_an37_isr(struct axgbe_port *pdata)
     682                 :            : {
     683                 :            :         unsigned int reg = 0;
     684                 :            :         /* Disable AN interrupts */
     685                 :          0 :         axgbe_an37_disable_interrupts(pdata);
     686                 :            : 
     687                 :            :         /* Save the interrupt(s) that fired */
     688                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT);
     689                 :          0 :         pdata->an_int = reg & AXGBE_AN_CL37_INT_MASK;
     690                 :          0 :         pdata->an_status = reg & ~AXGBE_AN_CL37_INT_MASK;
     691                 :            :         axgbe_an37_clear_interrupts(pdata);
     692                 :            : 
     693         [ #  # ]:          0 :         if (pdata->an_int & 0x01) {
     694                 :            :                 /* Clear the interrupt(s) that fired and process them */
     695                 :            :                 reg &= ~AXGBE_AN_CL37_INT_MASK;
     696                 :          0 :                 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT, reg);
     697                 :          0 :                 axgbe_an37_state_machine(pdata);
     698                 :            :         } else {
     699                 :            :                 /* Enable AN interrupts */
     700                 :          0 :                 axgbe_an37_enable_interrupts(pdata);
     701                 :            :         }
     702                 :          0 : }
     703                 :            : 
     704                 :          0 : static void axgbe_an_isr(struct axgbe_port *pdata)
     705                 :            : {
     706                 :          0 :         PMD_DRV_LOG_LINE(DEBUG, "AN interrupt received");
     707                 :            : 
     708      [ #  #  # ]:          0 :         switch (pdata->an_mode) {
     709                 :          0 :         case AXGBE_AN_MODE_CL73:
     710                 :            :         case AXGBE_AN_MODE_CL73_REDRV:
     711                 :          0 :                 axgbe_an73_isr(pdata);
     712                 :          0 :                 break;
     713                 :          0 :         case AXGBE_AN_MODE_CL37:
     714                 :            :         case AXGBE_AN_MODE_CL37_SGMII:
     715                 :          0 :                 axgbe_an37_isr(pdata);
     716                 :          0 :                 break;
     717                 :            :         default:
     718                 :            :                 break;
     719                 :            :         }
     720                 :          0 : }
     721                 :            : 
     722                 :          0 : static void axgbe_an_combined_isr(struct axgbe_port *pdata)
     723                 :            : {
     724                 :          0 :         axgbe_an_isr(pdata);
     725                 :          0 : }
     726                 :            : 
     727                 :          0 : static void axgbe_an37_init(struct axgbe_port *pdata)
     728                 :            : {
     729                 :            :         unsigned int advertising;
     730                 :            :         unsigned int reg = 0;
     731                 :            : 
     732                 :          0 :         advertising = pdata->phy_if.phy_impl.an_advertising(pdata);
     733                 :            : 
     734                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE);
     735         [ #  # ]:          0 :         if (advertising & ADVERTISED_Pause)
     736                 :          0 :                 reg |= 0x100;
     737                 :            :         else
     738                 :          0 :                 reg &= ~0x100;
     739         [ #  # ]:          0 :         if (advertising & ADVERTISED_Asym_Pause)
     740                 :          0 :                 reg |= 0x80;
     741                 :            :         else
     742                 :          0 :                 reg &= ~0x80;
     743                 :            : 
     744                 :            :         /* Full duplex, but not half */
     745                 :            :         reg |= AXGBE_AN_CL37_FD_MASK;
     746                 :          0 :         reg &= ~AXGBE_AN_CL37_HD_MASK;
     747                 :            : 
     748                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE, reg);
     749                 :            : 
     750                 :            :         /* Set up the Control register */
     751                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);
     752                 :            :         reg &= ~AXGBE_AN_CL37_TX_CONFIG_MASK;
     753                 :          0 :         reg &= ~AXGBE_AN_CL37_PCS_MODE_MASK;
     754                 :            : 
     755         [ #  # ]:          0 :         switch (pdata->an_mode) {
     756                 :            :         case AXGBE_AN_MODE_CL37:
     757                 :            :                 reg |= AXGBE_AN_CL37_PCS_MODE_BASEX;
     758                 :            :                 break;
     759                 :          0 :         case AXGBE_AN_MODE_CL37_SGMII:
     760                 :          0 :                 reg |= AXGBE_AN_CL37_PCS_MODE_SGMII;
     761                 :          0 :                 break;
     762                 :            :         default:
     763                 :            :                 break;
     764                 :            :         }
     765                 :          0 :         reg |= AXGBE_AN_CL37_MII_CTRL_8BIT;
     766                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);
     767                 :          0 : }
     768                 :            : 
     769                 :          0 : static void axgbe_an73_init(struct axgbe_port *pdata)
     770                 :            : {
     771                 :            :         unsigned int advertising, reg;
     772                 :            : 
     773                 :          0 :         advertising = pdata->phy_if.phy_impl.an_advertising(pdata);
     774                 :            : 
     775                 :            :         /* Set up Advertisement register 3 first */
     776                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
     777         [ #  # ]:          0 :         if (advertising & ADVERTISED_10000baseR_FEC)
     778                 :          0 :                 reg |= 0xc000;
     779                 :            :         else
     780                 :          0 :                 reg &= ~0xc000;
     781                 :            : 
     782                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, reg);
     783                 :            : 
     784                 :            :         /* Set up Advertisement register 2 next */
     785                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
     786         [ #  # ]:          0 :         if (advertising & ADVERTISED_10000baseKR_Full)
     787                 :          0 :                 reg |= 0x80;
     788                 :            :         else
     789                 :          0 :                 reg &= ~0x80;
     790                 :            : 
     791         [ #  # ]:          0 :         if ((advertising & ADVERTISED_1000baseKX_Full) ||
     792                 :            :             (advertising & ADVERTISED_2500baseX_Full))
     793                 :          0 :                 reg |= 0x20;
     794                 :            :         else
     795                 :          0 :                 reg &= ~0x20;
     796                 :            : 
     797                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, reg);
     798                 :            : 
     799                 :            :         /* Set up Advertisement register 1 last */
     800                 :          0 :         reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
     801         [ #  # ]:          0 :         if (advertising & ADVERTISED_Pause)
     802                 :          0 :                 reg |= 0x400;
     803                 :            :         else
     804                 :          0 :                 reg &= ~0x400;
     805                 :            : 
     806         [ #  # ]:          0 :         if (advertising & ADVERTISED_Asym_Pause)
     807                 :          0 :                 reg |= 0x800;
     808                 :            :         else
     809                 :          0 :                 reg &= ~0x800;
     810                 :            : 
     811                 :            :         /* We don't intend to perform XNP */
     812                 :          0 :         reg &= ~AXGBE_XNP_NP_EXCHANGE;
     813                 :            : 
     814                 :          0 :         XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
     815                 :            : 
     816                 :          0 :         PMD_DRV_LOG_LINE(DEBUG, "CL73 AN initialized");
     817                 :          0 : }
     818                 :            : 
     819                 :          0 : static void axgbe_an_init(struct axgbe_port *pdata)
     820                 :            : {
     821                 :            :         /* Set up advertisement registers based on current settings */
     822                 :          0 :         pdata->an_mode = pdata->phy_if.phy_impl.an_mode(pdata);
     823      [ #  #  # ]:          0 :         switch (pdata->an_mode) {
     824                 :          0 :         case AXGBE_AN_MODE_CL73:
     825                 :            :         case AXGBE_AN_MODE_CL73_REDRV:
     826                 :          0 :                 axgbe_an73_init(pdata);
     827                 :          0 :                 break;
     828                 :          0 :         case AXGBE_AN_MODE_CL37:
     829                 :            :         case AXGBE_AN_MODE_CL37_SGMII:
     830                 :          0 :                 axgbe_an37_init(pdata);
     831                 :          0 :                 break;
     832                 :            :         default:
     833                 :            :                 break;
     834                 :            :         }
     835                 :          0 : }
     836                 :            : 
     837                 :          0 : static void axgbe_phy_adjust_link(struct axgbe_port *pdata)
     838                 :            : {
     839         [ #  # ]:          0 :         if (pdata->phy.link) {
     840                 :            :                 /* Flow control support */
     841                 :          0 :                 pdata->pause_autoneg = pdata->phy.pause_autoneg;
     842                 :            : 
     843         [ #  # ]:          0 :                 if (pdata->tx_pause != (unsigned int)pdata->phy.tx_pause) {
     844                 :          0 :                         pdata->hw_if.config_tx_flow_control(pdata);
     845                 :          0 :                         pdata->tx_pause = pdata->phy.tx_pause;
     846                 :            :                 }
     847                 :            : 
     848         [ #  # ]:          0 :                 if (pdata->rx_pause != (unsigned int)pdata->phy.rx_pause) {
     849                 :          0 :                         pdata->hw_if.config_rx_flow_control(pdata);
     850                 :          0 :                         pdata->rx_pause = pdata->phy.rx_pause;
     851                 :            :                 }
     852                 :            : 
     853                 :            :                 /* Speed support */
     854         [ #  # ]:          0 :                 if (pdata->phy_speed != pdata->phy.speed)
     855                 :          0 :                         pdata->phy_speed = pdata->phy.speed;
     856         [ #  # ]:          0 :                 if (pdata->phy_link != pdata->phy.link)
     857                 :          0 :                         pdata->phy_link = pdata->phy.link;
     858         [ #  # ]:          0 :         } else if (pdata->phy_link) {
     859                 :          0 :                 pdata->phy_link = 0;
     860                 :          0 :                 pdata->phy_speed = SPEED_UNKNOWN;
     861                 :            :         }
     862                 :          0 : }
     863                 :            : 
     864                 :          0 : static int axgbe_phy_config_fixed(struct axgbe_port *pdata)
     865                 :            : {
     866                 :            :         enum axgbe_mode mode;
     867                 :            : 
     868                 :          0 :         PMD_DRV_LOG_LINE(DEBUG, "fixed PHY configuration");
     869                 :            : 
     870                 :            :         /* Disable auto-negotiation */
     871                 :          0 :         axgbe_an_disable(pdata);
     872                 :            : 
     873                 :            :         /* Set specified mode for specified speed */
     874                 :          0 :         mode = pdata->phy_if.phy_impl.get_mode(pdata, pdata->phy.speed);
     875         [ #  # ]:          0 :         switch (mode) {
     876                 :            :         case AXGBE_MODE_KX_1000:
     877                 :            :         case AXGBE_MODE_KX_2500:
     878                 :            :         case AXGBE_MODE_KR:
     879                 :            :         case AXGBE_MODE_SGMII_10:
     880                 :            :         case AXGBE_MODE_SGMII_100:
     881                 :            :         case AXGBE_MODE_SGMII_1000:
     882                 :            :         case AXGBE_MODE_X:
     883                 :            :         case AXGBE_MODE_SFI:
     884                 :            :                 break;
     885                 :            :         case AXGBE_MODE_UNKNOWN:
     886                 :            :         default:
     887                 :            :                 return -EINVAL;
     888                 :            :         }
     889                 :            : 
     890                 :            :         /* Validate duplex mode */
     891         [ #  # ]:          0 :         if (pdata->phy.duplex != DUPLEX_FULL)
     892                 :            :                 return -EINVAL;
     893                 :            : 
     894                 :          0 :         axgbe_set_mode(pdata, mode);
     895                 :            : 
     896                 :          0 :         return 0;
     897                 :            : }
     898                 :            : 
     899                 :          0 : static int __axgbe_phy_config_aneg(struct axgbe_port *pdata, bool set_mode)
     900                 :            : {
     901                 :            :         int ret;
     902                 :            : 
     903                 :          0 :         pthread_mutex_lock(&pdata->an_mutex);
     904                 :            :         rte_bit_relaxed_set32(AXGBE_LINK_INIT, &pdata->dev_state);
     905                 :          0 :         pdata->link_check = rte_get_timer_cycles();
     906                 :            : 
     907                 :          0 :         ret = pdata->phy_if.phy_impl.an_config(pdata);
     908         [ #  # ]:          0 :         if (ret)
     909                 :          0 :                 goto out;
     910                 :            : 
     911         [ #  # ]:          0 :         if (pdata->phy.autoneg != AUTONEG_ENABLE) {
     912                 :          0 :                 ret = axgbe_phy_config_fixed(pdata);
     913   [ #  #  #  # ]:          0 :                 if (ret || !pdata->kr_redrv)
     914                 :          0 :                         goto out;
     915                 :          0 :                 PMD_DRV_LOG_LINE(DEBUG, "AN redriver support");
     916                 :            :         } else {
     917                 :          0 :                 PMD_DRV_LOG_LINE(DEBUG, "AN PHY configuration");
     918                 :            :         }
     919                 :            : 
     920                 :            :         /* Disable auto-negotiation interrupt */
     921                 :          0 :         rte_intr_disable(pdata->pci_dev->intr_handle);
     922                 :            : 
     923                 :            :         /* Start auto-negotiation in a supported mode */
     924         [ #  # ]:          0 :         if (set_mode) {
     925         [ #  # ]:          0 :                 if (axgbe_use_mode(pdata, AXGBE_MODE_KR)) {
     926                 :          0 :                         axgbe_set_mode(pdata, AXGBE_MODE_KR);
     927         [ #  # ]:          0 :                 } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_2500)) {
     928                 :          0 :                         axgbe_set_mode(pdata, AXGBE_MODE_KX_2500);
     929         [ #  # ]:          0 :                 } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_1000)) {
     930                 :          0 :                         axgbe_set_mode(pdata, AXGBE_MODE_KX_1000);
     931         [ #  # ]:          0 :                 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SFI)) {
     932                 :          0 :                         axgbe_set_mode(pdata, AXGBE_MODE_SFI);
     933         [ #  # ]:          0 :                 } else if (axgbe_use_mode(pdata, AXGBE_MODE_X)) {
     934                 :          0 :                         axgbe_set_mode(pdata, AXGBE_MODE_X);
     935         [ #  # ]:          0 :                 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_1000)) {
     936                 :          0 :                         axgbe_set_mode(pdata, AXGBE_MODE_SGMII_1000);
     937         [ #  # ]:          0 :                 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_100)) {
     938                 :          0 :                         axgbe_set_mode(pdata, AXGBE_MODE_SGMII_100);
     939         [ #  # ]:          0 :                 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_10)) {
     940                 :          0 :                         axgbe_set_mode(pdata, AXGBE_MODE_SGMII_10);
     941                 :            :                 } else {
     942                 :          0 :                         rte_intr_enable(pdata->pci_dev->intr_handle);
     943                 :            :                         ret = -EINVAL;
     944                 :          0 :                         goto out;
     945                 :            :                 }
     946                 :            :         }
     947                 :            : 
     948                 :            :         /* Disable and stop any in progress auto-negotiation */
     949                 :            :         axgbe_an_disable_all(pdata);
     950                 :            : 
     951                 :          0 :         pdata->an_result = AXGBE_AN_READY;
     952                 :          0 :         pdata->an_state = AXGBE_AN_READY;
     953                 :          0 :         pdata->kr_state = AXGBE_RX_BPA;
     954                 :          0 :         pdata->kx_state = AXGBE_RX_BPA;
     955                 :            : 
     956                 :            :         /* Re-enable auto-negotiation interrupt */
     957                 :          0 :         rte_intr_enable(pdata->pci_dev->intr_handle);
     958                 :          0 :         axgbe_an37_enable_interrupts(pdata);
     959                 :            : 
     960                 :          0 :         axgbe_an_init(pdata);
     961                 :          0 :         axgbe_an_restart(pdata);
     962                 :            : 
     963                 :          0 : out:
     964         [ #  # ]:          0 :         if (ret)
     965                 :            :                 rte_bit_relaxed_set32(AXGBE_LINK_ERR, &pdata->dev_state);
     966                 :            :         else
     967                 :            :                 rte_bit_relaxed_clear32(AXGBE_LINK_ERR, &pdata->dev_state);
     968                 :            : 
     969                 :          0 :         pthread_mutex_unlock(&pdata->an_mutex);
     970                 :            : 
     971                 :          0 :         return ret;
     972                 :            : }
     973                 :            : 
     974                 :          0 : static int axgbe_phy_config_aneg(struct axgbe_port *pdata)
     975                 :            : {
     976                 :          0 :         return __axgbe_phy_config_aneg(pdata, true);
     977                 :            : }
     978                 :            : 
     979                 :            : static int axgbe_phy_reconfig_aneg(struct axgbe_port *pdata)
     980                 :            : {
     981                 :          0 :         return __axgbe_phy_config_aneg(pdata, false);
     982                 :            : }
     983                 :            : 
     984                 :            : static bool axgbe_phy_aneg_done(struct axgbe_port *pdata)
     985                 :            : {
     986                 :          0 :         return pdata->an_result == AXGBE_AN_COMPLETE;
     987                 :            : }
     988                 :            : 
     989                 :          0 : static void axgbe_check_link_timeout(struct axgbe_port *pdata)
     990                 :            : {
     991                 :            :         unsigned long link_timeout;
     992                 :            :         unsigned long ticks;
     993                 :            :         unsigned long kr_time;
     994                 :            :         int wait;
     995                 :            : 
     996                 :          0 :         link_timeout = pdata->link_check + (AXGBE_LINK_TIMEOUT *
     997                 :          0 :                                             2 *  rte_get_timer_hz());
     998                 :            :         ticks = rte_get_timer_cycles();
     999         [ #  # ]:          0 :         if (time_after(ticks, link_timeout)) {
    1000         [ #  # ]:          0 :                 if ((axgbe_cur_mode(pdata) == AXGBE_MODE_KR) &&
    1001         [ #  # ]:          0 :                     pdata->phy.autoneg == AUTONEG_ENABLE) {
    1002                 :            :                         /* AN restart should not happen while KR training is in progress.
    1003                 :            :                          * The while loop ensures no AN restart during KR training,
    1004                 :            :                          * waits up to 500ms and AN restart is triggered only if KR
    1005                 :            :                          * training is failed.
    1006                 :            :                          */
    1007                 :            :                         wait = AXGBE_KR_TRAINING_WAIT_ITER;
    1008         [ #  # ]:          0 :                         while (wait--) {
    1009                 :          0 :                                 kr_time = pdata->kr_start_time +
    1010                 :            :                                           msecs_to_timer_cycles(AXGBE_AN_MS_TIMEOUT);
    1011                 :            :                                 ticks = rte_get_timer_cycles();
    1012         [ #  # ]:          0 :                                 if (time_after(ticks, kr_time))
    1013                 :            :                                         break;
    1014                 :            :                                 /* AN restart is not required, if AN result is COMPLETE */
    1015         [ #  # ]:          0 :                                 if (pdata->an_result == AXGBE_AN_COMPLETE)
    1016                 :            :                                         return;
    1017                 :          0 :                                 rte_delay_us(10500);
    1018                 :            :                         }
    1019                 :            :                 }
    1020                 :            : 
    1021                 :          0 :                 PMD_DRV_LOG_LINE(NOTICE, "AN link timeout");
    1022                 :            :                 axgbe_phy_config_aneg(pdata);
    1023                 :            :         }
    1024                 :            : }
    1025                 :            : 
    1026                 :            : static enum axgbe_mode axgbe_phy_status_aneg(struct axgbe_port *pdata)
    1027                 :            : {
    1028                 :          0 :         return pdata->phy_if.phy_impl.an_outcome(pdata);
    1029                 :            : }
    1030                 :            : 
    1031                 :          0 : static bool axgbe_phy_status_result(struct axgbe_port *pdata)
    1032                 :            : {
    1033                 :            :         enum axgbe_mode mode;
    1034                 :            : 
    1035                 :          0 :         pdata->phy.lp_advertising = 0;
    1036                 :            : 
    1037   [ #  #  #  # ]:          0 :         if ((pdata->phy.autoneg != AUTONEG_ENABLE) || pdata->parallel_detect)
    1038                 :          0 :                 mode = axgbe_cur_mode(pdata);
    1039                 :            :         else
    1040                 :            :                 mode = axgbe_phy_status_aneg(pdata);
    1041                 :            : 
    1042   [ #  #  #  #  :          0 :         switch (mode) {
                   #  # ]
    1043                 :          0 :         case AXGBE_MODE_SGMII_10:
    1044                 :          0 :                 pdata->phy.speed = SPEED_10;
    1045                 :          0 :                 break;
    1046                 :          0 :         case AXGBE_MODE_SGMII_100:
    1047                 :          0 :                 pdata->phy.speed = SPEED_100;
    1048                 :          0 :                 break;
    1049                 :          0 :         case AXGBE_MODE_X:
    1050                 :            :         case AXGBE_MODE_KX_1000:
    1051                 :            :         case AXGBE_MODE_SGMII_1000:
    1052                 :          0 :                 pdata->phy.speed = SPEED_1000;
    1053                 :          0 :                 break;
    1054                 :          0 :         case AXGBE_MODE_KX_2500:
    1055                 :          0 :                 pdata->phy.speed = SPEED_2500;
    1056                 :          0 :                 break;
    1057                 :          0 :         case AXGBE_MODE_KR:
    1058                 :            :         case AXGBE_MODE_SFI:
    1059                 :          0 :                 pdata->phy.speed = SPEED_10000;
    1060                 :          0 :                 break;
    1061                 :          0 :         case AXGBE_MODE_UNKNOWN:
    1062                 :            :         default:
    1063                 :          0 :                 pdata->phy.speed = SPEED_UNKNOWN;
    1064                 :            :         }
    1065                 :            : 
    1066                 :          0 :         pdata->phy.duplex = DUPLEX_FULL;
    1067                 :            : 
    1068                 :            :         if (!axgbe_set_mode(pdata, mode))
    1069                 :            :                 return false;
    1070                 :            : 
    1071         [ #  # ]:          0 :         if (pdata->an_again)
    1072                 :            :                 axgbe_phy_reconfig_aneg(pdata);
    1073                 :            : 
    1074                 :            :         return true;
    1075                 :            : }
    1076                 :            : 
    1077                 :            : static int autoneg_time_out(unsigned long autoneg_start_time)
    1078                 :            : {
    1079                 :            :         unsigned long autoneg_timeout;
    1080                 :            :         unsigned long ticks;
    1081                 :            : 
    1082                 :          0 :         autoneg_timeout = autoneg_start_time + (AXGBE_LINK_TIMEOUT *
    1083                 :          0 :                                                 2 *  rte_get_timer_hz());
    1084                 :            :         ticks = rte_get_timer_cycles();
    1085         [ #  # ]:          0 :         if (time_after(ticks, autoneg_timeout))
    1086                 :            :                 return 1;
    1087                 :            :         else
    1088                 :            :                 return 0;
    1089                 :            : }
    1090                 :            : 
    1091         [ #  # ]:          0 : static void axgbe_phy_status(struct axgbe_port *pdata)
    1092                 :            : {
    1093                 :            :         unsigned int link_aneg;
    1094                 :            :         int an_restart, ret;
    1095                 :            :         unsigned int reg = 0;
    1096                 :            :         unsigned long autoneg_start_time;
    1097                 :            : 
    1098         [ #  # ]:          0 :         if (rte_bit_relaxed_get32(AXGBE_LINK_ERR, &pdata->dev_state)) {
    1099                 :          0 :                 pdata->phy.link = 0;
    1100                 :          0 :                 goto adjust_link;
    1101                 :            :         }
    1102                 :            : 
    1103                 :          0 :         link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE);
    1104                 :            : 
    1105                 :          0 :         pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata,
    1106                 :            :                                                              &an_restart);
    1107         [ #  # ]:          0 :         if (an_restart) {
    1108                 :            :                 axgbe_phy_config_aneg(pdata);
    1109                 :          0 :                 goto adjust_link;
    1110                 :            :         }
    1111                 :            : 
    1112         [ #  # ]:          0 :         if (pdata->phy.link) {
    1113   [ #  #  #  # ]:          0 :                 if (link_aneg && !axgbe_phy_aneg_done(pdata)) {
    1114         [ #  # ]:          0 :                         if (axgbe_cur_mode(pdata) == AXGBE_MODE_SGMII_1000) {
    1115                 :            :                                 /* autoneg not complete, so re-initializing */
    1116                 :            :                                 /* and restarting it */
    1117                 :          0 :                                 axgbe_an_init(pdata);
    1118                 :          0 :                                 axgbe_an_restart(pdata);
    1119                 :          0 :                                 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2,
    1120                 :            :                                                  MDIO_VEND2_AN_STAT);
    1121                 :            :                                 autoneg_start_time = rte_get_timer_cycles();
    1122                 :            :                                 /* poll for autoneg to complete */
    1123         [ #  # ]:          0 :                                 while (!(reg & AXGBE_AN_CL37_INT_CMPLT)) {
    1124                 :            :                                         ret =
    1125                 :            :                                         autoneg_time_out(autoneg_start_time);
    1126                 :            :                                         if (ret)
    1127                 :            :                                                 break;
    1128                 :          0 :                                         reg = XMDIO_READ(pdata,
    1129                 :            :                                                          MDIO_MMD_VEND2,
    1130                 :            :                                                          MDIO_VEND2_AN_STAT);
    1131         [ #  # ]:          0 :                                         if (reg & AXGBE_AN_CL37_INT_CMPLT) {
    1132                 :          0 :                                                 axgbe_an37_isr(pdata);
    1133                 :          0 :                                                 break;
    1134                 :            :                                         }
    1135                 :            :                                 }
    1136                 :            :                         } else {
    1137                 :          0 :                                 axgbe_check_link_timeout(pdata);
    1138                 :          0 :                                 return;
    1139                 :            :                         }
    1140                 :            :                 }
    1141                 :            : 
    1142         [ #  # ]:          0 :                 if (axgbe_phy_status_result(pdata))
    1143                 :            :                         return;
    1144                 :            : 
    1145         [ #  # ]:          0 :                 if (rte_bit_relaxed_get32(AXGBE_LINK_INIT, &pdata->dev_state))
    1146                 :            :                         rte_bit_relaxed_clear32(AXGBE_LINK_INIT,
    1147                 :            :                                                 &pdata->dev_state);
    1148                 :            :         } else {
    1149         [ #  # ]:          0 :                 if (rte_bit_relaxed_get32(AXGBE_LINK_INIT, &pdata->dev_state)) {
    1150                 :          0 :                         axgbe_check_link_timeout(pdata);
    1151                 :            : 
    1152         [ #  # ]:          0 :                         if (link_aneg)
    1153                 :            :                                 return;
    1154                 :            :                 }
    1155                 :          0 :                 axgbe_phy_status_result(pdata);
    1156                 :            :         }
    1157                 :            : 
    1158                 :          0 : adjust_link:
    1159                 :          0 :         axgbe_phy_adjust_link(pdata);
    1160                 :            : }
    1161                 :            : 
    1162                 :          0 : static void axgbe_phy_stop(struct axgbe_port *pdata)
    1163                 :            : {
    1164                 :          0 :         PMD_DRV_LOG_LINE(DEBUG, "stopping PHY");
    1165         [ #  # ]:          0 :         if (!pdata->phy_started)
    1166                 :            :                 return;
    1167                 :            :         /* Indicate the PHY is down */
    1168                 :          0 :         pdata->phy_started = 0;
    1169                 :            :         /* Disable auto-negotiation */
    1170                 :            :         axgbe_an_disable_all(pdata);
    1171                 :          0 :         pdata->phy_if.phy_impl.stop(pdata);
    1172                 :          0 :         pdata->phy.link = 0;
    1173                 :          0 :         axgbe_phy_adjust_link(pdata);
    1174                 :            : }
    1175                 :            : 
    1176                 :          0 : static int axgbe_phy_start(struct axgbe_port *pdata)
    1177                 :            : {
    1178                 :            :         int ret;
    1179                 :            : 
    1180                 :          0 :         PMD_DRV_LOG_LINE(DEBUG, "starting PHY");
    1181                 :            : 
    1182                 :          0 :         ret = pdata->phy_if.phy_impl.start(pdata);
    1183         [ #  # ]:          0 :         if (ret)
    1184                 :            :                 return ret;
    1185                 :            :         /* Set initial mode - call the mode setting routines
    1186                 :            :          * directly to insure we are properly configured
    1187                 :            :          */
    1188         [ #  # ]:          0 :         if (axgbe_use_mode(pdata, AXGBE_MODE_KR)) {
    1189                 :            :                 axgbe_kr_mode(pdata);
    1190         [ #  # ]:          0 :         } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_2500)) {
    1191                 :            :                 axgbe_kx_2500_mode(pdata);
    1192         [ #  # ]:          0 :         } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_1000)) {
    1193                 :            :                 axgbe_kx_1000_mode(pdata);
    1194         [ #  # ]:          0 :         } else if (axgbe_use_mode(pdata, AXGBE_MODE_SFI)) {
    1195                 :          0 :                 axgbe_sfi_mode(pdata);
    1196         [ #  # ]:          0 :         } else if (axgbe_use_mode(pdata, AXGBE_MODE_X)) {
    1197                 :            :                 axgbe_x_mode(pdata);
    1198         [ #  # ]:          0 :         } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_1000)) {
    1199                 :            :                 axgbe_sgmii_1000_mode(pdata);
    1200         [ #  # ]:          0 :         } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_100)) {
    1201                 :            :                 axgbe_sgmii_100_mode(pdata);
    1202         [ #  # ]:          0 :         } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_10)) {
    1203                 :            :                 axgbe_sgmii_10_mode(pdata);
    1204                 :            :         } else {
    1205                 :            :                 ret = -EINVAL;
    1206                 :          0 :                 goto err_stop;
    1207                 :            :         }
    1208                 :            :         /* Indicate the PHY is up and running */
    1209                 :          0 :         pdata->phy_started = 1;
    1210                 :          0 :         axgbe_an_init(pdata);
    1211                 :          0 :         axgbe_an_enable_interrupts(pdata);
    1212                 :          0 :         return axgbe_phy_config_aneg(pdata);
    1213                 :            : 
    1214                 :            : err_stop:
    1215                 :          0 :         pdata->phy_if.phy_impl.stop(pdata);
    1216                 :            : 
    1217                 :          0 :         return ret;
    1218                 :            : }
    1219                 :            : 
    1220                 :          0 : static int axgbe_phy_reset(struct axgbe_port *pdata)
    1221                 :            : {
    1222                 :            :         int ret;
    1223                 :            : 
    1224                 :          0 :         ret = pdata->phy_if.phy_impl.reset(pdata);
    1225         [ #  # ]:          0 :         if (ret)
    1226                 :            :                 return ret;
    1227                 :            : 
    1228                 :            :         /* Disable auto-negotiation for now */
    1229                 :            :         axgbe_an_disable_all(pdata);
    1230                 :            : 
    1231                 :            :         /* Clear auto-negotiation interrupts */
    1232                 :          0 :         axgbe_an_clear_interrupts_all(pdata);
    1233                 :            : 
    1234                 :          0 :         return 0;
    1235                 :            : }
    1236                 :            : 
    1237                 :          0 : static int axgbe_phy_best_advertised_speed(struct axgbe_port *pdata)
    1238                 :            : {
    1239         [ #  # ]:          0 :         if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full)
    1240                 :            :                 return SPEED_10000;
    1241         [ #  # ]:          0 :         else if (pdata->phy.advertising & ADVERTISED_10000baseT_Full)
    1242                 :            :                 return SPEED_10000;
    1243         [ #  # ]:          0 :         else if (pdata->phy.advertising & ADVERTISED_2500baseX_Full)
    1244                 :            :                 return SPEED_2500;
    1245         [ #  # ]:          0 :         else if (pdata->phy.advertising & ADVERTISED_1000baseKX_Full)
    1246                 :            :                 return SPEED_1000;
    1247         [ #  # ]:          0 :         else if (pdata->phy.advertising & ADVERTISED_1000baseT_Full)
    1248                 :            :                 return SPEED_1000;
    1249         [ #  # ]:          0 :         else if (pdata->phy.advertising & ADVERTISED_100baseT_Full)
    1250                 :            :                 return SPEED_100;
    1251         [ #  # ]:          0 :         else if (pdata->phy.advertising & ADVERTISED_10baseT_Full)
    1252                 :          0 :                 return SPEED_10;
    1253                 :            : 
    1254                 :            :         return SPEED_UNKNOWN;
    1255                 :            : }
    1256                 :            : 
    1257                 :          0 : static int axgbe_phy_init(struct axgbe_port *pdata)
    1258                 :            : {
    1259                 :            :         int ret;
    1260                 :            : 
    1261                 :          0 :         pdata->mdio_mmd = MDIO_MMD_PCS;
    1262                 :            : 
    1263                 :            :         /* Check for FEC support */
    1264                 :          0 :         pdata->fec_ability = XMDIO_READ(pdata, MDIO_MMD_PMAPMD,
    1265                 :            :                                         MDIO_PMA_10GBR_FECABLE);
    1266                 :          0 :         pdata->fec_ability &= (MDIO_PMA_10GBR_FECABLE_ABLE |
    1267                 :            :                                MDIO_PMA_10GBR_FECABLE_ERRABLE);
    1268                 :            : 
    1269                 :            :         /* Setup the phy (including supported features) */
    1270                 :          0 :         ret = pdata->phy_if.phy_impl.init(pdata);
    1271         [ #  # ]:          0 :         if (ret)
    1272                 :            :                 return ret;
    1273                 :          0 :         pdata->phy.advertising = pdata->phy.supported;
    1274                 :            : 
    1275                 :          0 :         pdata->phy.address = 0;
    1276                 :            : 
    1277         [ #  # ]:          0 :         if (pdata->phy.advertising & ADVERTISED_Autoneg) {
    1278                 :          0 :                 pdata->phy.autoneg = AUTONEG_ENABLE;
    1279                 :          0 :                 pdata->phy.speed = SPEED_UNKNOWN;
    1280                 :          0 :                 pdata->phy.duplex = DUPLEX_UNKNOWN;
    1281                 :            :         } else {
    1282                 :          0 :                 pdata->phy.autoneg = AUTONEG_DISABLE;
    1283                 :          0 :                 pdata->phy.speed = axgbe_phy_best_advertised_speed(pdata);
    1284                 :          0 :                 pdata->phy.duplex = DUPLEX_FULL;
    1285                 :            :         }
    1286                 :            : 
    1287                 :          0 :         pdata->phy.link = 0;
    1288                 :            : 
    1289                 :          0 :         pdata->phy.pause_autoneg = pdata->pause_autoneg;
    1290                 :          0 :         pdata->phy.tx_pause = pdata->tx_pause;
    1291                 :          0 :         pdata->phy.rx_pause = pdata->rx_pause;
    1292                 :            : 
    1293                 :            :         /* Fix up Flow Control advertising */
    1294                 :          0 :         pdata->phy.advertising &= ~ADVERTISED_Pause;
    1295                 :          0 :         pdata->phy.advertising &= ~ADVERTISED_Asym_Pause;
    1296                 :            : 
    1297         [ #  # ]:          0 :         if (pdata->rx_pause) {
    1298                 :          0 :                 pdata->phy.advertising |= ADVERTISED_Pause;
    1299                 :          0 :                 pdata->phy.advertising |= ADVERTISED_Asym_Pause;
    1300                 :            :         }
    1301                 :            : 
    1302         [ #  # ]:          0 :         if (pdata->tx_pause)
    1303                 :          0 :                 pdata->phy.advertising ^= ADVERTISED_Asym_Pause;
    1304                 :            :         return 0;
    1305                 :            : }
    1306                 :            : 
    1307                 :          0 : void axgbe_init_function_ptrs_phy(struct axgbe_phy_if *phy_if)
    1308                 :            : {
    1309                 :          0 :         phy_if->phy_init        = axgbe_phy_init;
    1310                 :          0 :         phy_if->phy_reset       = axgbe_phy_reset;
    1311                 :          0 :         phy_if->phy_start       = axgbe_phy_start;
    1312                 :          0 :         phy_if->phy_stop        = axgbe_phy_stop;
    1313                 :          0 :         phy_if->phy_status      = axgbe_phy_status;
    1314                 :          0 :         phy_if->phy_config_aneg = axgbe_phy_config_aneg;
    1315                 :          0 :         phy_if->an_isr          = axgbe_an_combined_isr;
    1316                 :          0 : }

Generated by: LCOV version 1.14