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 PHY_1000BT_FEATURES) 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 speed = netdev->phydev->speed; 183 duplex = netdev->phydev->duplex; 184 185 ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex); 186 if (ret) 187 netdev_err(netdev, "failed to adjust link.\n"); 188 189 ret = hclge_cfg_flowctrl(hdev); 190 if (ret) 191 netdev_err(netdev, "failed to configure flow control.\n"); 192 } 193 194 int hclge_mac_connect_phy(struct hclge_dev *hdev) 195 { 196 struct net_device *netdev = hdev->vport[0].nic.netdev; 197 struct phy_device *phydev = hdev->hw.mac.phydev; 198 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; 199 int ret; 200 201 if (!phydev) 202 return 0; 203 204 linkmode_clear_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); 205 206 ret = phy_connect_direct(netdev, phydev, 207 hclge_mac_adjust_link, 208 PHY_INTERFACE_MODE_SGMII); 209 if (ret) { 210 netdev_err(netdev, "phy_connect_direct err.\n"); 211 return ret; 212 } 213 214 linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, mask); 215 linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, mask); 216 linkmode_set_bit_array(phy_10_100_features_array, 217 ARRAY_SIZE(phy_10_100_features_array), 218 mask); 219 linkmode_set_bit_array(phy_gbit_features_array, 220 ARRAY_SIZE(phy_gbit_features_array), 221 mask); 222 linkmode_and(phydev->supported, phydev->supported, mask); 223 phy_support_asym_pause(phydev); 224 225 return 0; 226 } 227 228 void hclge_mac_disconnect_phy(struct hclge_dev *hdev) 229 { 230 struct phy_device *phydev = hdev->hw.mac.phydev; 231 232 if (!phydev) 233 return; 234 235 phy_disconnect(phydev); 236 } 237 238 void hclge_mac_start_phy(struct hclge_dev *hdev) 239 { 240 struct phy_device *phydev = hdev->hw.mac.phydev; 241 242 if (!phydev) 243 return; 244 245 phy_start(phydev); 246 } 247 248 void hclge_mac_stop_phy(struct hclge_dev *hdev) 249 { 250 struct net_device *netdev = hdev->vport[0].nic.netdev; 251 struct phy_device *phydev = netdev->phydev; 252 253 if (!phydev) 254 return; 255 256 phy_stop(phydev); 257 } 258