Commit f5f2b3e4 authored by Guangbin Huang's avatar Guangbin Huang Committed by David S. Miller
Browse files

net: hns3: add support for imp-controlled PHYs



IMP(Intelligent Management Processor) firmware add a new feature
to take control of PHYs for some new devices, PF driver adds
support for this feature.

Driver queries device's capability to check whether IMP supports
this feature, it will tell IMP to enable this feature by firmware
compatible command if it is supported.

Signed-off-by: default avatarGuangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5ab6f96a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -653,6 +653,10 @@ struct hnae3_ae_ops {
	int (*del_cls_flower)(struct hnae3_handle *handle,
			      struct flow_cls_offload *cls_flower);
	bool (*cls_flower_active)(struct hnae3_handle *handle);
	int (*get_phy_link_ksettings)(struct hnae3_handle *handle,
				      struct ethtool_link_ksettings *cmd);
	int (*set_phy_link_ksettings)(struct hnae3_handle *handle,
				      const struct ethtool_link_ksettings *cmd);
};

struct hnae3_dcb_ops {
+2 −0
Original line number Diff line number Diff line
@@ -365,6 +365,8 @@ static void hns3_dbg_dev_caps(struct hnae3_handle *h)
	dev_info(&h->pdev->dev, "support PAUSE: %s\n",
		 test_bit(HNAE3_DEV_SUPPORT_PAUSE_B, ae_dev->caps) ?
		 "yes" : "no");
	dev_info(&h->pdev->dev, "support imp-controlled PHY: %s\n",
		 test_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, caps) ? "yes" : "no");
}

static void hns3_dbg_dev_specs(struct hnae3_handle *h)
+8 −1
Original line number Diff line number Diff line
@@ -700,6 +700,7 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
				   struct ethtool_link_ksettings *cmd)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);
	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
	const struct hnae3_ae_ops *ops;
	u8 module_type;
	u8 media_type;
@@ -730,7 +731,10 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
		break;
	case HNAE3_MEDIA_TYPE_COPPER:
		cmd->base.port = PORT_TP;
		if (!netdev->phydev)
		if (test_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, ae_dev->caps) &&
		    ops->get_phy_link_ksettings)
			ops->get_phy_link_ksettings(h, cmd);
		else if (!netdev->phydev)
			hns3_get_ksettings(h, cmd);
		else
			phy_ethtool_ksettings_get(netdev->phydev, cmd);
@@ -823,6 +827,9 @@ static int hns3_set_link_ksettings(struct net_device *netdev,
			return -EINVAL;

		return phy_ethtool_ksettings_set(netdev->phydev, cmd);
	} else if (test_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, ae_dev->caps) &&
		   ops->set_phy_link_ksettings) {
		return ops->set_phy_link_ksettings(handle, cmd);
	}

	if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2)
+4 −0
Original line number Diff line number Diff line
@@ -385,6 +385,8 @@ static void hclge_parse_capability(struct hclge_dev *hdev,
		set_bit(HNAE3_DEV_SUPPORT_FEC_B, ae_dev->caps);
	if (hnae3_get_bit(caps, HCLGE_CAP_PAUSE_B))
		set_bit(HNAE3_DEV_SUPPORT_PAUSE_B, ae_dev->caps);
	if (hnae3_get_bit(caps, HCLGE_CAP_PHY_IMP_B))
		set_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, ae_dev->caps);
}

static __le32 hclge_build_api_caps(void)
@@ -474,6 +476,8 @@ static int hclge_firmware_compat_config(struct hclge_dev *hdev)

	hnae3_set_bit(compat, HCLGE_LINK_EVENT_REPORT_EN_B, 1);
	hnae3_set_bit(compat, HCLGE_NCSI_ERROR_REPORT_EN_B, 1);
	if (hnae3_dev_phy_imp_supported(hdev))
		hnae3_set_bit(compat, HCLGE_PHY_IMP_EN_B, 1);
	req->compat = cpu_to_le32(compat);

	return hclge_cmd_send(&hdev->hw, &desc, 1);
+27 −0
Original line number Diff line number Diff line
@@ -303,6 +303,9 @@ enum hclge_opcode_type {
	HCLGE_PPP_CMD1_INT_CMD		= 0x2101,
	HCLGE_MAC_ETHERTYPE_IDX_RD      = 0x2105,
	HCLGE_NCSI_INT_EN		= 0x2401,

	/* PHY command */
	HCLGE_OPC_PHY_LINK_KSETTING	= 0x7025,
};

#define HCLGE_TQP_REG_OFFSET		0x80000
@@ -1098,6 +1101,7 @@ struct hclge_query_ppu_pf_other_int_dfx_cmd {

#define HCLGE_LINK_EVENT_REPORT_EN_B	0
#define HCLGE_NCSI_ERROR_REPORT_EN_B	1
#define HCLGE_PHY_IMP_EN_B		2
struct hclge_firmware_compat_cmd {
	__le32 compat;
	u8 rsv[20];
@@ -1139,6 +1143,29 @@ struct hclge_dev_specs_1_cmd {
	u8 rsv1[18];
};

#define HCLGE_PHY_LINK_SETTING_BD_NUM		2

struct hclge_phy_link_ksetting_0_cmd {
	__le32 speed;
	u8 duplex;
	u8 autoneg;
	u8 eth_tp_mdix;
	u8 eth_tp_mdix_ctrl;
	u8 port;
	u8 transceiver;
	u8 phy_address;
	u8 rsv;
	__le32 supported;
	__le32 advertising;
	__le32 lp_advertising;
};

struct hclge_phy_link_ksetting_1_cmd {
	u8 master_slave_cfg;
	u8 master_slave_state;
	u8 rsv[22];
};

int hclge_cmd_init(struct hclge_dev *hdev);
static inline void hclge_write_reg(void __iomem *base, u32 reg, u32 value)
{
Loading