1 // SPDX-License-Identifier: GPL-2.0+ 2 // Copyright (c) 2016-2017 Hisilicon Limited. 3 4 #include <linux/etherdevice.h> 5 #include <linux/kernel.h> 6 7 #include "hclge_cmd.h" 8 #include "hclge_main.h" 9 #include "hclge_mdio.h" 10 11 #define HCLGE_PHY_SUPPORTED_FEATURES (SUPPORTED_Autoneg | \ 12 SUPPORTED_TP | \ 13 PHY_10BT_FEATURES | \ 14 PHY_100BT_FEATURES | \ 15 SUPPORTED_1000baseT_Full) 16 17 enum hclge_mdio_c22_op_seq { 18 HCLGE_MDIO_C22_WRITE = 1, 19 HCLGE_MDIO_C22_READ = 2 20 }; 21 22 #define HCLGE_MDIO_CTRL_START_B 0 23 #define HCLGE_MDIO_CTRL_ST_S 1 24 #define HCLGE_MDIO_CTRL_ST_M (0x3 << HCLGE_MDIO_CTRL_ST_S) 25 #define HCLGE_MDIO_CTRL_OP_S 3 26 #define HCLGE_MDIO_CTRL_OP_M (0x3 << HCLGE_MDIO_CTRL_OP_S) 27 28 #define HCLGE_MDIO_PHYID_S 0 29 #define HCLGE_MDIO_PHYID_M (0x1f << HCLGE_MDIO_PHYID_S) 30 31 #define HCLGE_MDIO_PHYREG_S 0 32 #define HCLGE_MDIO_PHYREG_M (0x1f << HCLGE_MDIO_PHYREG_S) 33 34 #define HCLGE_MDIO_STA_B 0 35 36 struct hclge_mdio_cfg_cmd { 37 u8 ctrl_bit; 38 u8 phyid; 39 u8 phyad; 40 u8 rsvd; 41 __le16 reserve; 42 __le16 data_wr; 43 __le16 data_rd; 44 __le16 sta; 45 }; 46 47 static int hclge_mdio_write(struct mii_bus *bus, int phyid, int regnum, 48 u16 data) 49 { 50 struct hclge_mdio_cfg_cmd *mdio_cmd; 51 struct hclge_dev *hdev = bus->priv; 52 struct hclge_desc desc; 53 int ret; 54 55 if (test_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state)) 56 return 0; 57 58 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MDIO_CONFIG, false); 59 60 mdio_cmd = (struct hclge_mdio_cfg_cmd *)desc.data; 61 62 hnae3_set_field(mdio_cmd->phyid, HCLGE_MDIO_PHYID_M, 63 HCLGE_MDIO_PHYID_S, phyid); 64 hnae3_set_field(mdio_cmd->phyad, HCLGE_MDIO_PHYREG_M, 65 HCLGE_MDIO_PHYREG_S, regnum); 66 67 hnae3_set_bit(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_START_B, 1); 68 hnae3_set_field(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_ST_M, 69 HCLGE_MDIO_CTRL_ST_S, 1); 70 hnae3_set_field(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_OP_M, 71 HCLGE_MDIO_CTRL_OP_S, HCLGE_MDIO_C22_WRITE); 72 73 mdio_cmd->data_wr = cpu_to_le16(data); 74 75 ret = hclge_cmd_send(&hdev->hw, &desc, 1); 76 if (ret) { 77 dev_err(&hdev->pdev->dev, 78 "mdio write fail when sending cmd, status is %d.\n", 79 ret); 80 return ret; 81 } 82 83 return 0; 84 } 85 86 static int hclge_mdio_read(struct mii_bus *bus, int phyid, int regnum) 87 { 88 struct hclge_mdio_cfg_cmd *mdio_cmd; 89 struct hclge_dev *hdev = bus->priv; 90 struct hclge_desc desc; 91 int ret; 92 93 if (test_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state)) 94 return 0; 95 96 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MDIO_CONFIG, true); 97 98 mdio_cmd = (struct hclge_mdio_cfg_cmd *)desc.data; 99 100 hnae3_set_field(mdio_cmd->phyid, HCLGE_MDIO_PHYID_M, 101 HCLGE_MDIO_PHYID_S, phyid); 102 hnae3_set_field(mdio_cmd->phyad, HCLGE_MDIO_PHYREG_M, 103 HCLGE_MDIO_PHYREG_S, regnum); 104 105 hnae3_set_bit(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_START_B, 1); 106 hnae3_set_field(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_ST_M, 107 HCLGE_MDIO_CTRL_ST_S, 1); 108 hnae3_set_field(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_OP_M, 109 HCLGE_MDIO_CTRL_OP_S, HCLGE_MDIO_C22_READ); 110 111 /* Read out phy data */ 112 ret = hclge_cmd_send(&hdev->hw, &desc, 1); 113 if (ret) { 114 dev_err(&hdev->pdev->dev, 115 "mdio read fail when get data, status is %d.\n", 116 ret); 117 return ret; 118 } 119 120 if (hnae3_get_bit(le16_to_cpu(mdio_cmd->sta), HCLGE_MDIO_STA_B)) { 121 dev_err(&hdev->pdev->dev, "mdio read data error\n"); 122 return -EIO; 123 } 124 125 return le16_to_cpu(mdio_cmd->data_rd); 126 } 127 128 int hclge_mac_mdio_config(struct hclge_dev *hdev) 129 { 130 struct hclge_mac *mac = &hdev->hw.mac; 131 struct phy_device *phydev; 132 struct mii_bus *mdio_bus; 133 int ret; 134 135 if (hdev->hw.mac.phy_addr >= PHY_MAX_ADDR) { 136 dev_err(&hdev->pdev->dev, "phy_addr(%d) is too large.\n", 137 hdev->hw.mac.phy_addr); 138 return -EINVAL; 139 } 140 141 mdio_bus = devm_mdiobus_alloc(&hdev->pdev->dev); 142 if (!mdio_bus) 143 return -ENOMEM; 144 145 mdio_bus->name = "hisilicon MII bus"; 146 mdio_bus->read = hclge_mdio_read; 147 mdio_bus->write = hclge_mdio_write; 148 snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-%s", "mii", 149 dev_name(&hdev->pdev->dev)); 150 151 mdio_bus->parent = &hdev->pdev->dev; 152 mdio_bus->priv = hdev; 153 mdio_bus->phy_mask = ~(1 << mac->phy_addr); 154 ret = mdiobus_register(mdio_bus); 155 if (ret) { 156 dev_err(mdio_bus->parent, 157 "Failed to register MDIO bus ret = %#x\n", ret); 158 return ret; 159 } 160 161 phydev = mdiobus_get_phy(mdio_bus, mac->phy_addr); 162 if (!phydev) { 163 dev_err(mdio_bus->parent, "Failed to get phy device\n"); 164 mdiobus_unregister(mdio_bus); 165 return -EIO; 166 } 167 168 mac->phydev = phydev; 169 mac->mdio_bus = mdio_bus; 170 171 return 0; 172 } 173 174 static void hclge_mac_adjust_link(struct net_device *netdev) 175 { 176 struct hnae3_handle *h = *((void **)netdev_priv(netdev)); 177 struct hclge_vport *vport = hclge_get_vport(h); 178 struct hclge_dev *hdev = vport->back; 179 int duplex, speed; 180 int ret; 181 182 /* When phy link down, do nothing */ 183 if (netdev->phydev->link == 0) 184 return; 185 186 speed = netdev->phydev->speed; 187 duplex = netdev->phydev->duplex; 188 189 ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex); 190 if (ret) 191 netdev_err(netdev, "failed to adjust link.\n"); 192 193 ret = hclge_cfg_flowctrl(hdev); 194 if (ret) 195 netdev_err(netdev, "failed to configure flow control.\n"); 196 } 197 198 int hclge_mac_connect_phy(struct hnae3_handle *handle) 199 { 200 struct hclge_vport *vport = hclge_get_vport(handle); 201 struct hclge_dev *hdev = vport->back; 202 struct net_device *netdev = hdev->vport[0].nic.netdev; 203 struct phy_device *phydev = hdev->hw.mac.phydev; 204 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; 205 int ret; 206 207 if (!phydev) 208 return 0; 209 210 linkmode_clear_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); 211 212 ret = phy_connect_direct(netdev, phydev, 213 hclge_mac_adjust_link, 214 PHY_INTERFACE_MODE_SGMII); 215 if (ret) { 216 netdev_err(netdev, "phy_connect_direct err.\n"); 217 return ret; 218 } 219 220 linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, mask); 221 linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, mask); 222 linkmode_set_bit_array(phy_10_100_features_array, 223 ARRAY_SIZE(phy_10_100_features_array), 224 mask); 225 linkmode_set_bit_array(phy_gbit_features_array, 226 ARRAY_SIZE(phy_gbit_features_array), 227 mask); 228 linkmode_and(phydev->supported, phydev->supported, mask); 229 phy_support_asym_pause(phydev); 230 231 return 0; 232 } 233 234 void hclge_mac_disconnect_phy(struct hnae3_handle *handle) 235 { 236 struct hclge_vport *vport = hclge_get_vport(handle); 237 struct hclge_dev *hdev = vport->back; 238 struct phy_device *phydev = hdev->hw.mac.phydev; 239 240 if (!phydev) 241 return; 242 243 phy_disconnect(phydev); 244 } 245 246 void hclge_mac_start_phy(struct hclge_dev *hdev) 247 { 248 struct phy_device *phydev = hdev->hw.mac.phydev; 249 250 if (!phydev) 251 return; 252 253 phy_start(phydev); 254 } 255 256 void hclge_mac_stop_phy(struct hclge_dev *hdev) 257 { 258 struct net_device *netdev = hdev->vport[0].nic.netdev; 259 struct phy_device *phydev = netdev->phydev; 260 261 if (!phydev) 262 return; 263 264 phy_stop(phydev); 265 } 266