1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright (c) 2016-2017 Hisilicon Limited.
4 #include <linux/etherdevice.h>
5 #include <linux/kernel.h>
6 #include <linux/marvell_phy.h>
9 #include "hclge_main.h"
10 #include "hclge_mdio.h"
12 enum hclge_mdio_c22_op_seq
{
13 HCLGE_MDIO_C22_WRITE
= 1,
14 HCLGE_MDIO_C22_READ
= 2
17 #define HCLGE_MDIO_CTRL_START_B 0
18 #define HCLGE_MDIO_CTRL_ST_S 1
19 #define HCLGE_MDIO_CTRL_ST_M (0x3 << HCLGE_MDIO_CTRL_ST_S)
20 #define HCLGE_MDIO_CTRL_OP_S 3
21 #define HCLGE_MDIO_CTRL_OP_M (0x3 << HCLGE_MDIO_CTRL_OP_S)
23 #define HCLGE_MDIO_PHYID_S 0
24 #define HCLGE_MDIO_PHYID_M (0x1f << HCLGE_MDIO_PHYID_S)
26 #define HCLGE_MDIO_PHYREG_S 0
27 #define HCLGE_MDIO_PHYREG_M (0x1f << HCLGE_MDIO_PHYREG_S)
29 #define HCLGE_MDIO_STA_B 0
31 struct hclge_mdio_cfg_cmd
{
42 static int hclge_mdio_write(struct mii_bus
*bus
, int phyid
, int regnum
,
45 struct hclge_mdio_cfg_cmd
*mdio_cmd
;
46 struct hclge_dev
*hdev
= bus
->priv
;
47 struct hclge_desc desc
;
50 if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE
, &hdev
->hw
.hw
.comm_state
))
53 hclge_cmd_setup_basic_desc(&desc
, HCLGE_OPC_MDIO_CONFIG
, false);
55 mdio_cmd
= (struct hclge_mdio_cfg_cmd
*)desc
.data
;
57 hnae3_set_field(mdio_cmd
->phyid
, HCLGE_MDIO_PHYID_M
,
58 HCLGE_MDIO_PHYID_S
, (u32
)phyid
);
59 hnae3_set_field(mdio_cmd
->phyad
, HCLGE_MDIO_PHYREG_M
,
60 HCLGE_MDIO_PHYREG_S
, (u32
)regnum
);
62 hnae3_set_bit(mdio_cmd
->ctrl_bit
, HCLGE_MDIO_CTRL_START_B
, 1);
63 hnae3_set_field(mdio_cmd
->ctrl_bit
, HCLGE_MDIO_CTRL_ST_M
,
64 HCLGE_MDIO_CTRL_ST_S
, 1);
65 hnae3_set_field(mdio_cmd
->ctrl_bit
, HCLGE_MDIO_CTRL_OP_M
,
66 HCLGE_MDIO_CTRL_OP_S
, HCLGE_MDIO_C22_WRITE
);
68 mdio_cmd
->data_wr
= cpu_to_le16(data
);
70 ret
= hclge_cmd_send(&hdev
->hw
, &desc
, 1);
72 dev_err(&hdev
->pdev
->dev
,
73 "mdio write fail when sending cmd, status is %d.\n",
81 static int hclge_mdio_read(struct mii_bus
*bus
, int phyid
, int regnum
)
83 struct hclge_mdio_cfg_cmd
*mdio_cmd
;
84 struct hclge_dev
*hdev
= bus
->priv
;
85 struct hclge_desc desc
;
88 if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE
, &hdev
->hw
.hw
.comm_state
))
91 hclge_cmd_setup_basic_desc(&desc
, HCLGE_OPC_MDIO_CONFIG
, true);
93 mdio_cmd
= (struct hclge_mdio_cfg_cmd
*)desc
.data
;
95 hnae3_set_field(mdio_cmd
->phyid
, HCLGE_MDIO_PHYID_M
,
96 HCLGE_MDIO_PHYID_S
, (u32
)phyid
);
97 hnae3_set_field(mdio_cmd
->phyad
, HCLGE_MDIO_PHYREG_M
,
98 HCLGE_MDIO_PHYREG_S
, (u32
)regnum
);
100 hnae3_set_bit(mdio_cmd
->ctrl_bit
, HCLGE_MDIO_CTRL_START_B
, 1);
101 hnae3_set_field(mdio_cmd
->ctrl_bit
, HCLGE_MDIO_CTRL_ST_M
,
102 HCLGE_MDIO_CTRL_ST_S
, 1);
103 hnae3_set_field(mdio_cmd
->ctrl_bit
, HCLGE_MDIO_CTRL_OP_M
,
104 HCLGE_MDIO_CTRL_OP_S
, HCLGE_MDIO_C22_READ
);
106 /* Read out phy data */
107 ret
= hclge_cmd_send(&hdev
->hw
, &desc
, 1);
109 dev_err(&hdev
->pdev
->dev
,
110 "mdio read fail when get data, status is %d.\n",
115 if (hnae3_get_bit(le16_to_cpu(mdio_cmd
->sta
), HCLGE_MDIO_STA_B
)) {
116 dev_err(&hdev
->pdev
->dev
, "mdio read data error\n");
120 return le16_to_cpu(mdio_cmd
->data_rd
);
123 int hclge_mac_mdio_config(struct hclge_dev
*hdev
)
125 #define PHY_INEXISTENT 255
127 struct hclge_mac
*mac
= &hdev
->hw
.mac
;
128 struct phy_device
*phydev
;
129 struct mii_bus
*mdio_bus
;
132 if (hdev
->hw
.mac
.phy_addr
== PHY_INEXISTENT
) {
133 dev_info(&hdev
->pdev
->dev
,
134 "no phy device is connected to mdio bus\n");
136 } else if (hdev
->hw
.mac
.phy_addr
>= PHY_MAX_ADDR
) {
137 dev_err(&hdev
->pdev
->dev
, "phy_addr(%u) is too large.\n",
138 hdev
->hw
.mac
.phy_addr
);
142 mdio_bus
= devm_mdiobus_alloc(&hdev
->pdev
->dev
);
146 mdio_bus
->name
= "hisilicon MII bus";
147 mdio_bus
->read
= hclge_mdio_read
;
148 mdio_bus
->write
= hclge_mdio_write
;
149 snprintf(mdio_bus
->id
, MII_BUS_ID_SIZE
, "%s-%s", "mii",
150 dev_name(&hdev
->pdev
->dev
));
152 mdio_bus
->parent
= &hdev
->pdev
->dev
;
153 mdio_bus
->priv
= hdev
;
154 mdio_bus
->phy_mask
= ~(1 << mac
->phy_addr
);
155 ret
= mdiobus_register(mdio_bus
);
157 dev_err(mdio_bus
->parent
,
158 "failed to register MDIO bus, ret = %d\n", ret
);
162 phydev
= mdiobus_get_phy(mdio_bus
, mac
->phy_addr
);
164 dev_err(mdio_bus
->parent
, "Failed to get phy device\n");
165 mdiobus_unregister(mdio_bus
);
169 mac
->phydev
= phydev
;
170 mac
->mdio_bus
= mdio_bus
;
175 static void hclge_mac_adjust_link(struct net_device
*netdev
)
177 struct hnae3_handle
*h
= *((void **)netdev_priv(netdev
));
178 struct hclge_vport
*vport
= hclge_get_vport(h
);
179 struct hclge_dev
*hdev
= vport
->back
;
183 /* When phy link down, do nothing */
184 if (netdev
->phydev
->link
== 0)
187 speed
= netdev
->phydev
->speed
;
188 duplex
= netdev
->phydev
->duplex
;
190 ret
= hclge_cfg_mac_speed_dup(hdev
, speed
, duplex
, 0);
192 netdev_err(netdev
, "failed to adjust link.\n");
194 hdev
->hw
.mac
.req_speed
= (u32
)speed
;
195 hdev
->hw
.mac
.req_duplex
= (u8
)duplex
;
197 ret
= hclge_cfg_flowctrl(hdev
);
199 netdev_err(netdev
, "failed to configure flow control.\n");
202 int hclge_mac_connect_phy(struct hnae3_handle
*handle
)
204 struct hclge_vport
*vport
= hclge_get_vport(handle
);
205 struct hclge_dev
*hdev
= vport
->back
;
206 struct net_device
*netdev
= hdev
->vport
[0].nic
.netdev
;
207 struct phy_device
*phydev
= hdev
->hw
.mac
.phydev
;
208 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask
) = { 0, };
214 linkmode_clear_bit(ETHTOOL_LINK_MODE_FIBRE_BIT
, phydev
->supported
);
216 phydev
->dev_flags
|= MARVELL_PHY_LED0_LINK_LED1_ACTIVE
;
218 ret
= phy_connect_direct(netdev
, phydev
,
219 hclge_mac_adjust_link
,
220 PHY_INTERFACE_MODE_SGMII
);
222 netdev_err(netdev
, "phy_connect_direct err.\n");
226 linkmode_copy(mask
, hdev
->hw
.mac
.supported
);
227 linkmode_and(phydev
->supported
, phydev
->supported
, mask
);
228 linkmode_copy(phydev
->advertising
, phydev
->supported
);
230 /* supported flag is Pause and Asym Pause, but default advertising
231 * should be rx on, tx on, so need clear Asym Pause in advertising
234 linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT
,
235 phydev
->advertising
);
237 phy_attached_info(phydev
);
242 void hclge_mac_disconnect_phy(struct hnae3_handle
*handle
)
244 struct hclge_vport
*vport
= hclge_get_vport(handle
);
245 struct hclge_dev
*hdev
= vport
->back
;
246 struct phy_device
*phydev
= hdev
->hw
.mac
.phydev
;
251 phy_disconnect(phydev
);
254 void hclge_mac_start_phy(struct hclge_dev
*hdev
)
256 struct phy_device
*phydev
= hdev
->hw
.mac
.phydev
;
261 phy_loopback(phydev
, false);
266 void hclge_mac_stop_phy(struct hclge_dev
*hdev
)
268 struct net_device
*netdev
= hdev
->vport
[0].nic
.netdev
;
269 struct phy_device
*phydev
= netdev
->phydev
;
277 u16
hclge_read_phy_reg(struct hclge_dev
*hdev
, u16 reg_addr
)
279 struct hclge_phy_reg_cmd
*req
;
280 struct hclge_desc desc
;
283 hclge_cmd_setup_basic_desc(&desc
, HCLGE_OPC_PHY_REG
, true);
285 req
= (struct hclge_phy_reg_cmd
*)desc
.data
;
286 req
->reg_addr
= cpu_to_le16(reg_addr
);
288 ret
= hclge_cmd_send(&hdev
->hw
, &desc
, 1);
290 dev_err(&hdev
->pdev
->dev
,
291 "failed to read phy reg, ret = %d.\n", ret
);
293 return le16_to_cpu(req
->reg_val
);
296 int hclge_write_phy_reg(struct hclge_dev
*hdev
, u16 reg_addr
, u16 val
)
298 struct hclge_phy_reg_cmd
*req
;
299 struct hclge_desc desc
;
302 hclge_cmd_setup_basic_desc(&desc
, HCLGE_OPC_PHY_REG
, false);
304 req
= (struct hclge_phy_reg_cmd
*)desc
.data
;
305 req
->reg_addr
= cpu_to_le16(reg_addr
);
306 req
->reg_val
= cpu_to_le16(val
);
308 ret
= hclge_cmd_send(&hdev
->hw
, &desc
, 1);
310 dev_err(&hdev
->pdev
->dev
,
311 "failed to write phy reg, ret = %d.\n", ret
);