forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
....@@ -3,18 +3,11 @@
33
44 #include <linux/etherdevice.h>
55 #include <linux/kernel.h>
6
+#include <linux/marvell_phy.h>
67
78 #include "hclge_cmd.h"
89 #include "hclge_main.h"
910 #include "hclge_mdio.h"
10
-
11
-#define HCLGE_PHY_SUPPORTED_FEATURES (SUPPORTED_Autoneg | \
12
- SUPPORTED_TP | \
13
- SUPPORTED_Pause | \
14
- SUPPORTED_Asym_Pause | \
15
- PHY_10BT_FEATURES | \
16
- PHY_100BT_FEATURES | \
17
- PHY_1000BT_FEATURES)
1811
1912 enum hclge_mdio_c22_op_seq {
2013 HCLGE_MDIO_C22_WRITE = 1,
....@@ -62,9 +55,9 @@
6255 mdio_cmd = (struct hclge_mdio_cfg_cmd *)desc.data;
6356
6457 hnae3_set_field(mdio_cmd->phyid, HCLGE_MDIO_PHYID_M,
65
- HCLGE_MDIO_PHYID_S, phyid);
58
+ HCLGE_MDIO_PHYID_S, (u32)phyid);
6659 hnae3_set_field(mdio_cmd->phyad, HCLGE_MDIO_PHYREG_M,
67
- HCLGE_MDIO_PHYREG_S, regnum);
60
+ HCLGE_MDIO_PHYREG_S, (u32)regnum);
6861
6962 hnae3_set_bit(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_START_B, 1);
7063 hnae3_set_field(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_ST_M,
....@@ -100,9 +93,9 @@
10093 mdio_cmd = (struct hclge_mdio_cfg_cmd *)desc.data;
10194
10295 hnae3_set_field(mdio_cmd->phyid, HCLGE_MDIO_PHYID_M,
103
- HCLGE_MDIO_PHYID_S, phyid);
96
+ HCLGE_MDIO_PHYID_S, (u32)phyid);
10497 hnae3_set_field(mdio_cmd->phyad, HCLGE_MDIO_PHYREG_M,
105
- HCLGE_MDIO_PHYREG_S, regnum);
98
+ HCLGE_MDIO_PHYREG_S, (u32)regnum);
10699
107100 hnae3_set_bit(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_START_B, 1);
108101 hnae3_set_field(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_ST_M,
....@@ -129,13 +122,19 @@
129122
130123 int hclge_mac_mdio_config(struct hclge_dev *hdev)
131124 {
125
+#define PHY_INEXISTENT 255
126
+
132127 struct hclge_mac *mac = &hdev->hw.mac;
133128 struct phy_device *phydev;
134129 struct mii_bus *mdio_bus;
135130 int ret;
136131
137
- if (hdev->hw.mac.phy_addr >= PHY_MAX_ADDR) {
138
- dev_err(&hdev->pdev->dev, "phy_addr(%d) is too large.\n",
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");
135
+ return 0;
136
+ } else if (hdev->hw.mac.phy_addr >= PHY_MAX_ADDR) {
137
+ dev_err(&hdev->pdev->dev, "phy_addr(%u) is too large.\n",
139138 hdev->hw.mac.phy_addr);
140139 return -EINVAL;
141140 }
....@@ -156,7 +155,7 @@
156155 ret = mdiobus_register(mdio_bus);
157156 if (ret) {
158157 dev_err(mdio_bus->parent,
159
- "Failed to register MDIO bus ret = %#x\n", ret);
158
+ "failed to register MDIO bus, ret = %d\n", ret);
160159 return ret;
161160 }
162161
....@@ -181,6 +180,10 @@
181180 int duplex, speed;
182181 int ret;
183182
183
+ /* When phy link down, do nothing */
184
+ if (netdev->phydev->link == 0)
185
+ return;
186
+
184187 speed = netdev->phydev->speed;
185188 duplex = netdev->phydev->duplex;
186189
....@@ -193,16 +196,21 @@
193196 netdev_err(netdev, "failed to configure flow control.\n");
194197 }
195198
196
-int hclge_mac_connect_phy(struct hclge_dev *hdev)
199
+int hclge_mac_connect_phy(struct hnae3_handle *handle)
197200 {
201
+ struct hclge_vport *vport = hclge_get_vport(handle);
202
+ struct hclge_dev *hdev = vport->back;
198203 struct net_device *netdev = hdev->vport[0].nic.netdev;
199204 struct phy_device *phydev = hdev->hw.mac.phydev;
205
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
200206 int ret;
201207
202208 if (!phydev)
203209 return 0;
204210
205
- phydev->supported &= ~SUPPORTED_FIBRE;
211
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported);
212
+
213
+ phydev->dev_flags |= MARVELL_PHY_LED0_LINK_LED1_ACTIVE;
206214
207215 ret = phy_connect_direct(netdev, phydev,
208216 hclge_mac_adjust_link,
....@@ -212,14 +220,26 @@
212220 return ret;
213221 }
214222
215
- phydev->supported &= HCLGE_PHY_SUPPORTED_FEATURES;
216
- phydev->advertising = phydev->supported;
223
+ linkmode_copy(mask, hdev->hw.mac.supported);
224
+ linkmode_and(phydev->supported, phydev->supported, mask);
225
+ linkmode_copy(phydev->advertising, phydev->supported);
226
+
227
+ /* supported flag is Pause and Asym Pause, but default advertising
228
+ * should be rx on, tx on, so need clear Asym Pause in advertising
229
+ * flag
230
+ */
231
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
232
+ phydev->advertising);
233
+
234
+ phy_attached_info(phydev);
217235
218236 return 0;
219237 }
220238
221
-void hclge_mac_disconnect_phy(struct hclge_dev *hdev)
239
+void hclge_mac_disconnect_phy(struct hnae3_handle *handle)
222240 {
241
+ struct hclge_vport *vport = hclge_get_vport(handle);
242
+ struct hclge_dev *hdev = vport->back;
223243 struct phy_device *phydev = hdev->hw.mac.phydev;
224244
225245 if (!phydev)