1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2019 - 2022 Beijing WangXun Technology Co., Ltd. */
4 #include <linux/ethtool.h>
5 #include <linux/iopoll.h>
9 #include "../libwx/wx_type.h"
10 #include "../libwx/wx_hw.h"
11 #include "ngbe_type.h"
12 #include "ngbe_mdio.h"
14 static int ngbe_phy_read_reg_internal(struct mii_bus *bus, int phy_addr, int regnum)
16 struct wx *wx = bus->priv;
20 return (u16)rd32(wx, NGBE_PHY_CONFIG(regnum));
23 static int ngbe_phy_write_reg_internal(struct mii_bus *bus, int phy_addr, int regnum, u16 value)
25 struct wx *wx = bus->priv;
28 wr32(wx, NGBE_PHY_CONFIG(regnum), value);
32 static int ngbe_phy_read_reg_mdi_c22(struct mii_bus *bus, int phy_addr, int regnum)
34 u32 command, val, device_type = 0;
35 struct wx *wx = bus->priv;
38 wr32(wx, NGBE_MDIO_CLAUSE_SELECT, 0xF);
39 /* setup and write the address cycle command */
40 command = NGBE_MSCA_RA(regnum) |
41 NGBE_MSCA_PA(phy_addr) |
42 NGBE_MSCA_DA(device_type);
43 wr32(wx, NGBE_MSCA, command);
44 command = NGBE_MSCC_CMD(NGBE_MSCA_CMD_READ) |
47 wr32(wx, NGBE_MSCC, command);
49 /* wait to complete */
50 ret = read_poll_timeout(rd32, val, !(val & NGBE_MSCC_BUSY), 1000,
51 100000, false, wx, NGBE_MSCC);
53 wx_err(wx, "Mdio read c22 command did not complete.\n");
57 return (u16)rd32(wx, NGBE_MSCC);
60 static int ngbe_phy_write_reg_mdi_c22(struct mii_bus *bus, int phy_addr, int regnum, u16 value)
62 u32 command, val, device_type = 0;
63 struct wx *wx = bus->priv;
66 wr32(wx, NGBE_MDIO_CLAUSE_SELECT, 0xF);
67 /* setup and write the address cycle command */
68 command = NGBE_MSCA_RA(regnum) |
69 NGBE_MSCA_PA(phy_addr) |
70 NGBE_MSCA_DA(device_type);
71 wr32(wx, NGBE_MSCA, command);
73 NGBE_MSCC_CMD(NGBE_MSCA_CMD_WRITE) |
76 wr32(wx, NGBE_MSCC, command);
78 /* wait to complete */
79 ret = read_poll_timeout(rd32, val, !(val & NGBE_MSCC_BUSY), 1000,
80 100000, false, wx, NGBE_MSCC);
82 wx_err(wx, "Mdio write c22 command did not complete.\n");
87 static int ngbe_phy_read_reg_mdi_c45(struct mii_bus *bus, int phy_addr, int devnum, int regnum)
89 struct wx *wx = bus->priv;
93 wr32(wx, NGBE_MDIO_CLAUSE_SELECT, 0x0);
94 /* setup and write the address cycle command */
95 command = NGBE_MSCA_RA(mdiobus_c45_regad(regnum)) |
96 NGBE_MSCA_PA(phy_addr) |
98 wr32(wx, NGBE_MSCA, command);
99 command = NGBE_MSCC_CMD(NGBE_MSCA_CMD_READ) |
102 wr32(wx, NGBE_MSCC, command);
104 /* wait to complete */
105 ret = read_poll_timeout(rd32, val, !(val & NGBE_MSCC_BUSY), 1000,
106 100000, false, wx, NGBE_MSCC);
108 wx_err(wx, "Mdio read c45 command did not complete.\n");
112 return (u16)rd32(wx, NGBE_MSCC);
115 static int ngbe_phy_write_reg_mdi_c45(struct mii_bus *bus, int phy_addr,
116 int devnum, int regnum, u16 value)
118 struct wx *wx = bus->priv;
122 wr32(wx, NGBE_MDIO_CLAUSE_SELECT, 0x0);
123 /* setup and write the address cycle command */
124 command = NGBE_MSCA_RA(mdiobus_c45_regad(regnum)) |
125 NGBE_MSCA_PA(phy_addr) |
126 NGBE_MSCA_DA(devnum);
127 wr32(wx, NGBE_MSCA, command);
129 NGBE_MSCC_CMD(NGBE_MSCA_CMD_WRITE) |
132 wr32(wx, NGBE_MSCC, command);
134 /* wait to complete */
135 ret = read_poll_timeout(rd32, val, !(val & NGBE_MSCC_BUSY), 1000,
136 100000, false, wx, NGBE_MSCC);
138 wx_err(wx, "Mdio write c45 command did not complete.\n");
143 static int ngbe_phy_read_reg_c22(struct mii_bus *bus, int phy_addr, int regnum)
145 struct wx *wx = bus->priv;
148 if (wx->mac_type == em_mac_type_mdi)
149 phy_data = ngbe_phy_read_reg_internal(bus, phy_addr, regnum);
151 phy_data = ngbe_phy_read_reg_mdi_c22(bus, phy_addr, regnum);
156 static int ngbe_phy_write_reg_c22(struct mii_bus *bus, int phy_addr,
157 int regnum, u16 value)
159 struct wx *wx = bus->priv;
162 if (wx->mac_type == em_mac_type_mdi)
163 ret = ngbe_phy_write_reg_internal(bus, phy_addr, regnum, value);
165 ret = ngbe_phy_write_reg_mdi_c22(bus, phy_addr, regnum, value);
170 static void ngbe_handle_link_change(struct net_device *dev)
172 struct wx *wx = netdev_priv(dev);
173 struct phy_device *phydev;
177 if (!(wx->link != phydev->link ||
178 wx->speed != phydev->speed ||
179 wx->duplex != phydev->duplex))
182 wx->link = phydev->link;
183 wx->speed = phydev->speed;
184 wx->duplex = phydev->duplex;
185 switch (phydev->speed) {
197 wr32m(wx, NGBE_CFG_LAN_SPEED, 0x3, lan_speed);
200 reg = rd32(wx, WX_MAC_TX_CFG);
201 reg &= ~WX_MAC_TX_CFG_SPEED_MASK;
202 reg |= WX_MAC_TX_CFG_SPEED_1G | WX_MAC_TX_CFG_TE;
203 wr32(wx, WX_MAC_TX_CFG, reg);
204 /* Re configure MAC RX */
205 reg = rd32(wx, WX_MAC_RX_CFG);
206 wr32(wx, WX_MAC_RX_CFG, reg);
207 wr32(wx, WX_MAC_PKT_FLT, WX_MAC_PKT_FLT_PR);
208 reg = rd32(wx, WX_MAC_WDG_TIMEOUT);
209 wr32(wx, WX_MAC_WDG_TIMEOUT, reg);
211 phy_print_status(phydev);
214 int ngbe_phy_connect(struct wx *wx)
218 ret = phy_connect_direct(wx->netdev,
220 ngbe_handle_link_change,
221 PHY_INTERFACE_MODE_RGMII_ID);
223 wx_err(wx, "PHY connect failed.\n");
230 static void ngbe_phy_fixup(struct wx *wx)
232 struct phy_device *phydev = wx->phydev;
233 struct ethtool_eee eee;
235 phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
236 phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
237 phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
239 if (wx->mac_type != em_mac_type_mdi)
241 /* disable EEE, internal phy does not support eee */
242 memset(&eee, 0, sizeof(eee));
243 phy_ethtool_set_eee(phydev, &eee);
246 int ngbe_mdio_init(struct wx *wx)
248 struct pci_dev *pdev = wx->pdev;
249 struct mii_bus *mii_bus;
252 mii_bus = devm_mdiobus_alloc(&pdev->dev);
256 mii_bus->name = "ngbe_mii_bus";
257 mii_bus->read = ngbe_phy_read_reg_c22;
258 mii_bus->write = ngbe_phy_write_reg_c22;
259 mii_bus->phy_mask = GENMASK(31, 4);
260 mii_bus->parent = &pdev->dev;
263 if (wx->mac_type == em_mac_type_rgmii) {
264 mii_bus->read_c45 = ngbe_phy_read_reg_mdi_c45;
265 mii_bus->write_c45 = ngbe_phy_write_reg_mdi_c45;
268 snprintf(mii_bus->id, MII_BUS_ID_SIZE, "ngbe-%x",
269 (pdev->bus->number << 8) | pdev->devfn);
270 ret = devm_mdiobus_register(&pdev->dev, mii_bus);
274 wx->phydev = phy_find_first(mii_bus);
278 phy_attached_info(wx->phydev);