1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright (c) 2016-2017 Hisilicon Limited.
4 #include <linux/etherdevice.h>
5 #include <linux/kernel.h>
8 #include "hclge_main.h"
9 #include "hclge_mdio.h"
11 #define HCLGE_PHY_SUPPORTED_FEATURES (SUPPORTED_Autoneg | \
14 SUPPORTED_Asym_Pause | \
16 PHY_100BT_FEATURES | \
17 SUPPORTED_1000baseT_Full)
19 enum hclge_mdio_c22_op_seq
{
20 HCLGE_MDIO_C22_WRITE
= 1,
21 HCLGE_MDIO_C22_READ
= 2
24 #define HCLGE_MDIO_CTRL_START_B 0
25 #define HCLGE_MDIO_CTRL_ST_S 1
26 #define HCLGE_MDIO_CTRL_ST_M (0x3 << HCLGE_MDIO_CTRL_ST_S)
27 #define HCLGE_MDIO_CTRL_OP_S 3
28 #define HCLGE_MDIO_CTRL_OP_M (0x3 << HCLGE_MDIO_CTRL_OP_S)
30 #define HCLGE_MDIO_PHYID_S 0
31 #define HCLGE_MDIO_PHYID_M (0x1f << HCLGE_MDIO_PHYID_S)
33 #define HCLGE_MDIO_PHYREG_S 0
34 #define HCLGE_MDIO_PHYREG_M (0x1f << HCLGE_MDIO_PHYREG_S)
36 #define HCLGE_MDIO_STA_B 0
38 struct hclge_mdio_cfg_cmd
{
49 static int hclge_mdio_write(struct mii_bus
*bus
, int phyid
, int regnum
,
52 struct hclge_mdio_cfg_cmd
*mdio_cmd
;
53 struct hclge_dev
*hdev
= bus
->priv
;
54 struct hclge_desc desc
;
57 if (test_bit(HCLGE_STATE_CMD_DISABLE
, &hdev
->state
))
60 hclge_cmd_setup_basic_desc(&desc
, HCLGE_OPC_MDIO_CONFIG
, false);
62 mdio_cmd
= (struct hclge_mdio_cfg_cmd
*)desc
.data
;
64 hnae3_set_field(mdio_cmd
->phyid
, HCLGE_MDIO_PHYID_M
,
65 HCLGE_MDIO_PHYID_S
, phyid
);
66 hnae3_set_field(mdio_cmd
->phyad
, HCLGE_MDIO_PHYREG_M
,
67 HCLGE_MDIO_PHYREG_S
, regnum
);
69 hnae3_set_bit(mdio_cmd
->ctrl_bit
, HCLGE_MDIO_CTRL_START_B
, 1);
70 hnae3_set_field(mdio_cmd
->ctrl_bit
, HCLGE_MDIO_CTRL_ST_M
,
71 HCLGE_MDIO_CTRL_ST_S
, 1);
72 hnae3_set_field(mdio_cmd
->ctrl_bit
, HCLGE_MDIO_CTRL_OP_M
,
73 HCLGE_MDIO_CTRL_OP_S
, HCLGE_MDIO_C22_WRITE
);
75 mdio_cmd
->data_wr
= cpu_to_le16(data
);
77 ret
= hclge_cmd_send(&hdev
->hw
, &desc
, 1);
79 dev_err(&hdev
->pdev
->dev
,
80 "mdio write fail when sending cmd, status is %d.\n",
88 static int hclge_mdio_read(struct mii_bus
*bus
, int phyid
, int regnum
)
90 struct hclge_mdio_cfg_cmd
*mdio_cmd
;
91 struct hclge_dev
*hdev
= bus
->priv
;
92 struct hclge_desc desc
;
95 if (test_bit(HCLGE_STATE_CMD_DISABLE
, &hdev
->state
))
98 hclge_cmd_setup_basic_desc(&desc
, HCLGE_OPC_MDIO_CONFIG
, true);
100 mdio_cmd
= (struct hclge_mdio_cfg_cmd
*)desc
.data
;
102 hnae3_set_field(mdio_cmd
->phyid
, HCLGE_MDIO_PHYID_M
,
103 HCLGE_MDIO_PHYID_S
, phyid
);
104 hnae3_set_field(mdio_cmd
->phyad
, HCLGE_MDIO_PHYREG_M
,
105 HCLGE_MDIO_PHYREG_S
, regnum
);
107 hnae3_set_bit(mdio_cmd
->ctrl_bit
, HCLGE_MDIO_CTRL_START_B
, 1);
108 hnae3_set_field(mdio_cmd
->ctrl_bit
, HCLGE_MDIO_CTRL_ST_M
,
109 HCLGE_MDIO_CTRL_ST_S
, 1);
110 hnae3_set_field(mdio_cmd
->ctrl_bit
, HCLGE_MDIO_CTRL_OP_M
,
111 HCLGE_MDIO_CTRL_OP_S
, HCLGE_MDIO_C22_READ
);
113 /* Read out phy data */
114 ret
= hclge_cmd_send(&hdev
->hw
, &desc
, 1);
116 dev_err(&hdev
->pdev
->dev
,
117 "mdio read fail when get data, status is %d.\n",
122 if (hnae3_get_bit(le16_to_cpu(mdio_cmd
->sta
), HCLGE_MDIO_STA_B
)) {
123 dev_err(&hdev
->pdev
->dev
, "mdio read data error\n");
127 return le16_to_cpu(mdio_cmd
->data_rd
);
130 int hclge_mac_mdio_config(struct hclge_dev
*hdev
)
132 struct hclge_mac
*mac
= &hdev
->hw
.mac
;
133 struct phy_device
*phydev
;
134 struct mii_bus
*mdio_bus
;
137 if (hdev
->hw
.mac
.phy_addr
>= PHY_MAX_ADDR
) {
138 dev_err(&hdev
->pdev
->dev
, "phy_addr(%d) is too large.\n",
139 hdev
->hw
.mac
.phy_addr
);
143 mdio_bus
= devm_mdiobus_alloc(&hdev
->pdev
->dev
);
147 mdio_bus
->name
= "hisilicon MII bus";
148 mdio_bus
->read
= hclge_mdio_read
;
149 mdio_bus
->write
= hclge_mdio_write
;
150 snprintf(mdio_bus
->id
, MII_BUS_ID_SIZE
, "%s-%s", "mii",
151 dev_name(&hdev
->pdev
->dev
));
153 mdio_bus
->parent
= &hdev
->pdev
->dev
;
154 mdio_bus
->priv
= hdev
;
155 mdio_bus
->phy_mask
= ~(1 << mac
->phy_addr
);
156 ret
= mdiobus_register(mdio_bus
);
158 dev_err(mdio_bus
->parent
,
159 "Failed to register MDIO bus ret = %#x\n", ret
);
163 phydev
= mdiobus_get_phy(mdio_bus
, mac
->phy_addr
);
165 dev_err(mdio_bus
->parent
, "Failed to get phy device\n");
166 mdiobus_unregister(mdio_bus
);
170 mac
->phydev
= phydev
;
171 mac
->mdio_bus
= mdio_bus
;
176 static void hclge_mac_adjust_link(struct net_device
*netdev
)
178 struct hnae3_handle
*h
= *((void **)netdev_priv(netdev
));
179 struct hclge_vport
*vport
= hclge_get_vport(h
);
180 struct hclge_dev
*hdev
= vport
->back
;
184 speed
= netdev
->phydev
->speed
;
185 duplex
= netdev
->phydev
->duplex
;
187 ret
= hclge_cfg_mac_speed_dup(hdev
, speed
, duplex
);
189 netdev_err(netdev
, "failed to adjust link.\n");
191 ret
= hclge_cfg_flowctrl(hdev
);
193 netdev_err(netdev
, "failed to configure flow control.\n");
196 int hclge_mac_connect_phy(struct hclge_dev
*hdev
)
198 struct net_device
*netdev
= hdev
->vport
[0].nic
.netdev
;
199 struct phy_device
*phydev
= hdev
->hw
.mac
.phydev
;
205 phydev
->supported
&= ~SUPPORTED_FIBRE
;
207 ret
= phy_connect_direct(netdev
, phydev
,
208 hclge_mac_adjust_link
,
209 PHY_INTERFACE_MODE_SGMII
);
211 netdev_err(netdev
, "phy_connect_direct err.\n");
215 phydev
->supported
&= HCLGE_PHY_SUPPORTED_FEATURES
;
216 phydev
->advertising
= phydev
->supported
;
221 void hclge_mac_disconnect_phy(struct hclge_dev
*hdev
)
223 struct phy_device
*phydev
= hdev
->hw
.mac
.phydev
;
228 phy_disconnect(phydev
);
231 void hclge_mac_start_phy(struct hclge_dev
*hdev
)
233 struct phy_device
*phydev
= hdev
->hw
.mac
.phydev
;
241 void hclge_mac_stop_phy(struct hclge_dev
*hdev
)
243 struct net_device
*netdev
= hdev
->vport
[0].nic
.netdev
;
244 struct phy_device
*phydev
= netdev
->phydev
;