net/ngbe: identify and reset PHY
[dpdk.git] / drivers / net / ngbe / base / ngbe_phy_mvl.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
3  */
4
5 #include "ngbe_phy_mvl.h"
6
7 #define MVL_PHY_RST_WAIT_PERIOD  5
8
9 s32 ngbe_read_phy_reg_mvl(struct ngbe_hw *hw,
10                 u32 reg_addr, u32 device_type, u16 *phy_data)
11 {
12         mdi_reg_t reg;
13         mdi_reg_22_t reg22;
14
15         reg.device_type = device_type;
16         reg.addr = reg_addr;
17
18         if (hw->phy.media_type == ngbe_media_type_fiber)
19                 ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 1);
20         else
21                 ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 0);
22
23         ngbe_mdi_map_register(&reg, &reg22);
24
25         ngbe_read_phy_reg_mdi(hw, reg22.addr, reg22.device_type, phy_data);
26
27         return 0;
28 }
29
30 s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw,
31                 u32 reg_addr, u32 device_type, u16 phy_data)
32 {
33         mdi_reg_t reg;
34         mdi_reg_22_t reg22;
35
36         reg.device_type = device_type;
37         reg.addr = reg_addr;
38
39         if (hw->phy.media_type == ngbe_media_type_fiber)
40                 ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 1);
41         else
42                 ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 0);
43
44         ngbe_mdi_map_register(&reg, &reg22);
45
46         ngbe_write_phy_reg_mdi(hw, reg22.addr, reg22.device_type, phy_data);
47
48         return 0;
49 }
50
51 s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw)
52 {
53         u32 i;
54         u16 ctrl = 0;
55         s32 status = 0;
56
57         DEBUGFUNC("ngbe_reset_phy_mvl");
58
59         if (hw->phy.type != ngbe_phy_mvl && hw->phy.type != ngbe_phy_mvl_sfi)
60                 return NGBE_ERR_PHY_TYPE;
61
62         /* select page 18 reg 20 */
63         status = ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 18);
64
65         /* mode select to RGMII-to-copper or RGMII-to-sfi*/
66         if (hw->phy.type == ngbe_phy_mvl)
67                 ctrl = MVL_GEN_CTL_MODE_COPPER;
68         else
69                 ctrl = MVL_GEN_CTL_MODE_FIBER;
70         status = ngbe_write_phy_reg_mdi(hw, MVL_GEN_CTL, 0, ctrl);
71         /* mode reset */
72         ctrl |= MVL_GEN_CTL_RESET;
73         status = ngbe_write_phy_reg_mdi(hw, MVL_GEN_CTL, 0, ctrl);
74
75         for (i = 0; i < MVL_PHY_RST_WAIT_PERIOD; i++) {
76                 status = ngbe_read_phy_reg_mdi(hw, MVL_GEN_CTL, 0, &ctrl);
77                 if (!(ctrl & MVL_GEN_CTL_RESET))
78                         break;
79                 msleep(1);
80         }
81
82         if (i == MVL_PHY_RST_WAIT_PERIOD) {
83                 DEBUGOUT("PHY reset polling failed to complete.\n");
84                 return NGBE_ERR_RESET_FAILED;
85         }
86
87         return status;
88 }
89