691ff79821d8a4d743b91ab2a5bdf44b4ddf1c92
[dpdk.git] / drivers / net / axgbe / axgbe_mdio.c
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 int axgbe_phy_best_advertised_speed(struct axgbe_port *pdata)
11 {
12         if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full)
13                 return SPEED_10000;
14         else if (pdata->phy.advertising & ADVERTISED_10000baseT_Full)
15                 return SPEED_10000;
16         else if (pdata->phy.advertising & ADVERTISED_2500baseX_Full)
17                 return SPEED_2500;
18         else if (pdata->phy.advertising & ADVERTISED_1000baseKX_Full)
19                 return SPEED_1000;
20         else if (pdata->phy.advertising & ADVERTISED_1000baseT_Full)
21                 return SPEED_1000;
22         else if (pdata->phy.advertising & ADVERTISED_100baseT_Full)
23                 return SPEED_100;
24
25         return SPEED_UNKNOWN;
26 }
27
28 static int axgbe_phy_init(struct axgbe_port *pdata)
29 {
30         int ret;
31
32         pdata->mdio_mmd = MDIO_MMD_PCS;
33
34         /* Check for FEC support */
35         pdata->fec_ability = XMDIO_READ(pdata, MDIO_MMD_PMAPMD,
36                                         MDIO_PMA_10GBR_FECABLE);
37         pdata->fec_ability &= (MDIO_PMA_10GBR_FECABLE_ABLE |
38                                MDIO_PMA_10GBR_FECABLE_ERRABLE);
39
40         /* Setup the phy (including supported features) */
41         ret = pdata->phy_if.phy_impl.init(pdata);
42         if (ret)
43                 return ret;
44         pdata->phy.advertising = pdata->phy.supported;
45
46         pdata->phy.address = 0;
47
48         if (pdata->phy.advertising & ADVERTISED_Autoneg) {
49                 pdata->phy.autoneg = AUTONEG_ENABLE;
50                 pdata->phy.speed = SPEED_UNKNOWN;
51                 pdata->phy.duplex = DUPLEX_UNKNOWN;
52         } else {
53                 pdata->phy.autoneg = AUTONEG_DISABLE;
54                 pdata->phy.speed = axgbe_phy_best_advertised_speed(pdata);
55                 pdata->phy.duplex = DUPLEX_FULL;
56         }
57
58         pdata->phy.link = 0;
59
60         pdata->phy.pause_autoneg = pdata->pause_autoneg;
61         pdata->phy.tx_pause = pdata->tx_pause;
62         pdata->phy.rx_pause = pdata->rx_pause;
63
64         /* Fix up Flow Control advertising */
65         pdata->phy.advertising &= ~ADVERTISED_Pause;
66         pdata->phy.advertising &= ~ADVERTISED_Asym_Pause;
67
68         if (pdata->rx_pause) {
69                 pdata->phy.advertising |= ADVERTISED_Pause;
70                 pdata->phy.advertising |= ADVERTISED_Asym_Pause;
71         }
72
73         if (pdata->tx_pause)
74                 pdata->phy.advertising ^= ADVERTISED_Asym_Pause;
75         return 0;
76 }
77
78 void axgbe_init_function_ptrs_phy(struct axgbe_phy_if *phy_if)
79 {
80         phy_if->phy_init        = axgbe_phy_init;
81 }