Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 // Copyright (c) 2016-2017 Hisilicon Limited.
0003 
0004 #include <linux/etherdevice.h>
0005 #include <linux/kernel.h>
0006 #include <linux/marvell_phy.h>
0007 
0008 #include "hclge_cmd.h"
0009 #include "hclge_main.h"
0010 #include "hclge_mdio.h"
0011 
0012 enum hclge_mdio_c22_op_seq {
0013     HCLGE_MDIO_C22_WRITE = 1,
0014     HCLGE_MDIO_C22_READ = 2
0015 };
0016 
0017 #define HCLGE_MDIO_CTRL_START_B     0
0018 #define HCLGE_MDIO_CTRL_ST_S        1
0019 #define HCLGE_MDIO_CTRL_ST_M        (0x3 << HCLGE_MDIO_CTRL_ST_S)
0020 #define HCLGE_MDIO_CTRL_OP_S        3
0021 #define HCLGE_MDIO_CTRL_OP_M        (0x3 << HCLGE_MDIO_CTRL_OP_S)
0022 
0023 #define HCLGE_MDIO_PHYID_S      0
0024 #define HCLGE_MDIO_PHYID_M      (0x1f << HCLGE_MDIO_PHYID_S)
0025 
0026 #define HCLGE_MDIO_PHYREG_S     0
0027 #define HCLGE_MDIO_PHYREG_M     (0x1f << HCLGE_MDIO_PHYREG_S)
0028 
0029 #define HCLGE_MDIO_STA_B        0
0030 
0031 struct hclge_mdio_cfg_cmd {
0032     u8 ctrl_bit;
0033     u8 phyid;
0034     u8 phyad;
0035     u8 rsvd;
0036     __le16 reserve;
0037     __le16 data_wr;
0038     __le16 data_rd;
0039     __le16 sta;
0040 };
0041 
0042 static int hclge_mdio_write(struct mii_bus *bus, int phyid, int regnum,
0043                 u16 data)
0044 {
0045     struct hclge_mdio_cfg_cmd *mdio_cmd;
0046     struct hclge_dev *hdev = bus->priv;
0047     struct hclge_desc desc;
0048     int ret;
0049 
0050     if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state))
0051         return -EBUSY;
0052 
0053     hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MDIO_CONFIG, false);
0054 
0055     mdio_cmd = (struct hclge_mdio_cfg_cmd *)desc.data;
0056 
0057     hnae3_set_field(mdio_cmd->phyid, HCLGE_MDIO_PHYID_M,
0058             HCLGE_MDIO_PHYID_S, (u32)phyid);
0059     hnae3_set_field(mdio_cmd->phyad, HCLGE_MDIO_PHYREG_M,
0060             HCLGE_MDIO_PHYREG_S, (u32)regnum);
0061 
0062     hnae3_set_bit(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_START_B, 1);
0063     hnae3_set_field(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_ST_M,
0064             HCLGE_MDIO_CTRL_ST_S, 1);
0065     hnae3_set_field(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_OP_M,
0066             HCLGE_MDIO_CTRL_OP_S, HCLGE_MDIO_C22_WRITE);
0067 
0068     mdio_cmd->data_wr = cpu_to_le16(data);
0069 
0070     ret = hclge_cmd_send(&hdev->hw, &desc, 1);
0071     if (ret) {
0072         dev_err(&hdev->pdev->dev,
0073             "mdio write fail when sending cmd, status is %d.\n",
0074             ret);
0075         return ret;
0076     }
0077 
0078     return 0;
0079 }
0080 
0081 static int hclge_mdio_read(struct mii_bus *bus, int phyid, int regnum)
0082 {
0083     struct hclge_mdio_cfg_cmd *mdio_cmd;
0084     struct hclge_dev *hdev = bus->priv;
0085     struct hclge_desc desc;
0086     int ret;
0087 
0088     if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state))
0089         return -EBUSY;
0090 
0091     hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MDIO_CONFIG, true);
0092 
0093     mdio_cmd = (struct hclge_mdio_cfg_cmd *)desc.data;
0094 
0095     hnae3_set_field(mdio_cmd->phyid, HCLGE_MDIO_PHYID_M,
0096             HCLGE_MDIO_PHYID_S, (u32)phyid);
0097     hnae3_set_field(mdio_cmd->phyad, HCLGE_MDIO_PHYREG_M,
0098             HCLGE_MDIO_PHYREG_S, (u32)regnum);
0099 
0100     hnae3_set_bit(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_START_B, 1);
0101     hnae3_set_field(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_ST_M,
0102             HCLGE_MDIO_CTRL_ST_S, 1);
0103     hnae3_set_field(mdio_cmd->ctrl_bit, HCLGE_MDIO_CTRL_OP_M,
0104             HCLGE_MDIO_CTRL_OP_S, HCLGE_MDIO_C22_READ);
0105 
0106     /* Read out phy data */
0107     ret = hclge_cmd_send(&hdev->hw, &desc, 1);
0108     if (ret) {
0109         dev_err(&hdev->pdev->dev,
0110             "mdio read fail when get data, status is %d.\n",
0111             ret);
0112         return ret;
0113     }
0114 
0115     if (hnae3_get_bit(le16_to_cpu(mdio_cmd->sta), HCLGE_MDIO_STA_B)) {
0116         dev_err(&hdev->pdev->dev, "mdio read data error\n");
0117         return -EIO;
0118     }
0119 
0120     return le16_to_cpu(mdio_cmd->data_rd);
0121 }
0122 
0123 int hclge_mac_mdio_config(struct hclge_dev *hdev)
0124 {
0125 #define PHY_INEXISTENT  255
0126 
0127     struct hclge_mac *mac = &hdev->hw.mac;
0128     struct phy_device *phydev;
0129     struct mii_bus *mdio_bus;
0130     int ret;
0131 
0132     if (hdev->hw.mac.phy_addr == PHY_INEXISTENT) {
0133         dev_info(&hdev->pdev->dev,
0134              "no phy device is connected to mdio bus\n");
0135         return 0;
0136     } else if (hdev->hw.mac.phy_addr >= PHY_MAX_ADDR) {
0137         dev_err(&hdev->pdev->dev, "phy_addr(%u) is too large.\n",
0138             hdev->hw.mac.phy_addr);
0139         return -EINVAL;
0140     }
0141 
0142     mdio_bus = devm_mdiobus_alloc(&hdev->pdev->dev);
0143     if (!mdio_bus)
0144         return -ENOMEM;
0145 
0146     mdio_bus->name = "hisilicon MII bus";
0147     mdio_bus->read = hclge_mdio_read;
0148     mdio_bus->write = hclge_mdio_write;
0149     snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-%s", "mii",
0150          dev_name(&hdev->pdev->dev));
0151 
0152     mdio_bus->parent = &hdev->pdev->dev;
0153     mdio_bus->priv = hdev;
0154     mdio_bus->phy_mask = ~(1 << mac->phy_addr);
0155     ret = mdiobus_register(mdio_bus);
0156     if (ret) {
0157         dev_err(mdio_bus->parent,
0158             "failed to register MDIO bus, ret = %d\n", ret);
0159         return ret;
0160     }
0161 
0162     phydev = mdiobus_get_phy(mdio_bus, mac->phy_addr);
0163     if (!phydev) {
0164         dev_err(mdio_bus->parent, "Failed to get phy device\n");
0165         mdiobus_unregister(mdio_bus);
0166         return -EIO;
0167     }
0168 
0169     mac->phydev = phydev;
0170     mac->mdio_bus = mdio_bus;
0171 
0172     return 0;
0173 }
0174 
0175 static void hclge_mac_adjust_link(struct net_device *netdev)
0176 {
0177     struct hnae3_handle *h = *((void **)netdev_priv(netdev));
0178     struct hclge_vport *vport = hclge_get_vport(h);
0179     struct hclge_dev *hdev = vport->back;
0180     int duplex, speed;
0181     int ret;
0182 
0183     /* When phy link down, do nothing */
0184     if (netdev->phydev->link == 0)
0185         return;
0186 
0187     speed = netdev->phydev->speed;
0188     duplex = netdev->phydev->duplex;
0189 
0190     ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex);
0191     if (ret)
0192         netdev_err(netdev, "failed to adjust link.\n");
0193 
0194     ret = hclge_cfg_flowctrl(hdev);
0195     if (ret)
0196         netdev_err(netdev, "failed to configure flow control.\n");
0197 }
0198 
0199 int hclge_mac_connect_phy(struct hnae3_handle *handle)
0200 {
0201     struct hclge_vport *vport = hclge_get_vport(handle);
0202     struct hclge_dev *hdev = vport->back;
0203     struct net_device *netdev = hdev->vport[0].nic.netdev;
0204     struct phy_device *phydev = hdev->hw.mac.phydev;
0205     __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
0206     int ret;
0207 
0208     if (!phydev)
0209         return 0;
0210 
0211     linkmode_clear_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported);
0212 
0213     phydev->dev_flags |= MARVELL_PHY_LED0_LINK_LED1_ACTIVE;
0214 
0215     ret = phy_connect_direct(netdev, phydev,
0216                  hclge_mac_adjust_link,
0217                  PHY_INTERFACE_MODE_SGMII);
0218     if (ret) {
0219         netdev_err(netdev, "phy_connect_direct err.\n");
0220         return ret;
0221     }
0222 
0223     linkmode_copy(mask, hdev->hw.mac.supported);
0224     linkmode_and(phydev->supported, phydev->supported, mask);
0225     linkmode_copy(phydev->advertising, phydev->supported);
0226 
0227     /* supported flag is Pause and Asym Pause, but default advertising
0228      * should be rx on, tx on, so need clear Asym Pause in advertising
0229      * flag
0230      */
0231     linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
0232                phydev->advertising);
0233 
0234     phy_attached_info(phydev);
0235 
0236     return 0;
0237 }
0238 
0239 void hclge_mac_disconnect_phy(struct hnae3_handle *handle)
0240 {
0241     struct hclge_vport *vport = hclge_get_vport(handle);
0242     struct hclge_dev *hdev = vport->back;
0243     struct phy_device *phydev = hdev->hw.mac.phydev;
0244 
0245     if (!phydev)
0246         return;
0247 
0248     phy_disconnect(phydev);
0249 }
0250 
0251 void hclge_mac_start_phy(struct hclge_dev *hdev)
0252 {
0253     struct phy_device *phydev = hdev->hw.mac.phydev;
0254 
0255     if (!phydev)
0256         return;
0257 
0258     phy_loopback(phydev, false);
0259 
0260     phy_start(phydev);
0261 }
0262 
0263 void hclge_mac_stop_phy(struct hclge_dev *hdev)
0264 {
0265     struct net_device *netdev = hdev->vport[0].nic.netdev;
0266     struct phy_device *phydev = netdev->phydev;
0267 
0268     if (!phydev)
0269         return;
0270 
0271     phy_stop(phydev);
0272 }
0273 
0274 u16 hclge_read_phy_reg(struct hclge_dev *hdev, u16 reg_addr)
0275 {
0276     struct hclge_phy_reg_cmd *req;
0277     struct hclge_desc desc;
0278     int ret;
0279 
0280     hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PHY_REG, true);
0281 
0282     req = (struct hclge_phy_reg_cmd *)desc.data;
0283     req->reg_addr = cpu_to_le16(reg_addr);
0284 
0285     ret = hclge_cmd_send(&hdev->hw, &desc, 1);
0286     if (ret)
0287         dev_err(&hdev->pdev->dev,
0288             "failed to read phy reg, ret = %d.\n", ret);
0289 
0290     return le16_to_cpu(req->reg_val);
0291 }
0292 
0293 int hclge_write_phy_reg(struct hclge_dev *hdev, u16 reg_addr, u16 val)
0294 {
0295     struct hclge_phy_reg_cmd *req;
0296     struct hclge_desc desc;
0297     int ret;
0298 
0299     hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PHY_REG, false);
0300 
0301     req = (struct hclge_phy_reg_cmd *)desc.data;
0302     req->reg_addr = cpu_to_le16(reg_addr);
0303     req->reg_val = cpu_to_le16(val);
0304 
0305     ret = hclge_cmd_send(&hdev->hw, &desc, 1);
0306     if (ret)
0307         dev_err(&hdev->pdev->dev,
0308             "failed to write phy reg, ret = %d.\n", ret);
0309 
0310     return ret;
0311 }