Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'hns3-imp-phys'

Huazhong Tan says:

====================
net: hns3: support imp-controlled PHYs

This series adds support for imp-controlled PHYs in the HNS3
ethernet driver.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+321 -44
+4
drivers/net/ethernet/hisilicon/hns3/hnae3.h
··· 653 653 int (*del_cls_flower)(struct hnae3_handle *handle, 654 654 struct flow_cls_offload *cls_flower); 655 655 bool (*cls_flower_active)(struct hnae3_handle *handle); 656 + int (*get_phy_link_ksettings)(struct hnae3_handle *handle, 657 + struct ethtool_link_ksettings *cmd); 658 + int (*set_phy_link_ksettings)(struct hnae3_handle *handle, 659 + const struct ethtool_link_ksettings *cmd); 656 660 }; 657 661 658 662 struct hnae3_dcb_ops {
+2
drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
··· 365 365 dev_info(&h->pdev->dev, "support PAUSE: %s\n", 366 366 test_bit(HNAE3_DEV_SUPPORT_PAUSE_B, ae_dev->caps) ? 367 367 "yes" : "no"); 368 + dev_info(&h->pdev->dev, "support imp-controlled PHY: %s\n", 369 + test_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, caps) ? "yes" : "no"); 368 370 } 369 371 370 372 static void hns3_dbg_dev_specs(struct hnae3_handle *h)
+8 -1
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
··· 700 700 struct ethtool_link_ksettings *cmd) 701 701 { 702 702 struct hnae3_handle *h = hns3_get_handle(netdev); 703 + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); 703 704 const struct hnae3_ae_ops *ops; 704 705 u8 module_type; 705 706 u8 media_type; ··· 731 730 break; 732 731 case HNAE3_MEDIA_TYPE_COPPER: 733 732 cmd->base.port = PORT_TP; 734 - if (!netdev->phydev) 733 + if (test_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, ae_dev->caps) && 734 + ops->get_phy_link_ksettings) 735 + ops->get_phy_link_ksettings(h, cmd); 736 + else if (!netdev->phydev) 735 737 hns3_get_ksettings(h, cmd); 736 738 else 737 739 phy_ethtool_ksettings_get(netdev->phydev, cmd); ··· 827 823 return -EINVAL; 828 824 829 825 return phy_ethtool_ksettings_set(netdev->phydev, cmd); 826 + } else if (test_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, ae_dev->caps) && 827 + ops->set_phy_link_ksettings) { 828 + return ops->set_phy_link_ksettings(handle, cmd); 830 829 } 831 830 832 831 if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2)
+4
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
··· 385 385 set_bit(HNAE3_DEV_SUPPORT_FEC_B, ae_dev->caps); 386 386 if (hnae3_get_bit(caps, HCLGE_CAP_PAUSE_B)) 387 387 set_bit(HNAE3_DEV_SUPPORT_PAUSE_B, ae_dev->caps); 388 + if (hnae3_get_bit(caps, HCLGE_CAP_PHY_IMP_B)) 389 + set_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, ae_dev->caps); 388 390 } 389 391 390 392 static __le32 hclge_build_api_caps(void) ··· 476 474 477 475 hnae3_set_bit(compat, HCLGE_LINK_EVENT_REPORT_EN_B, 1); 478 476 hnae3_set_bit(compat, HCLGE_NCSI_ERROR_REPORT_EN_B, 1); 477 + if (hnae3_dev_phy_imp_supported(hdev)) 478 + hnae3_set_bit(compat, HCLGE_PHY_IMP_EN_B, 1); 479 479 req->compat = cpu_to_le32(compat); 480 480 481 481 return hclge_cmd_send(&hdev->hw, &desc, 1);
+40 -4
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
··· 127 127 HCLGE_OPC_QUERY_MAC_TNL_INT = 0x0310, 128 128 HCLGE_OPC_MAC_TNL_INT_EN = 0x0311, 129 129 HCLGE_OPC_CLEAR_MAC_TNL_INT = 0x0312, 130 - HCLGE_OPC_SERDES_LOOPBACK = 0x0315, 130 + HCLGE_OPC_COMMON_LOOPBACK = 0x0315, 131 131 HCLGE_OPC_CONFIG_FEC_MODE = 0x031A, 132 132 133 133 /* PFC/Pause commands */ ··· 303 303 HCLGE_PPP_CMD1_INT_CMD = 0x2101, 304 304 HCLGE_MAC_ETHERTYPE_IDX_RD = 0x2105, 305 305 HCLGE_NCSI_INT_EN = 0x2401, 306 + 307 + /* PHY command */ 308 + HCLGE_OPC_PHY_LINK_KSETTING = 0x7025, 309 + HCLGE_OPC_PHY_REG = 0x7026, 306 310 }; 307 311 308 312 #define HCLGE_TQP_REG_OFFSET 0x80000 ··· 964 960 965 961 #define HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B BIT(0) 966 962 #define HCLGE_CMD_SERDES_PARALLEL_INNER_LOOP_B BIT(2) 967 - #define HCLGE_CMD_SERDES_DONE_B BIT(0) 968 - #define HCLGE_CMD_SERDES_SUCCESS_B BIT(1) 969 - struct hclge_serdes_lb_cmd { 963 + #define HCLGE_CMD_GE_PHY_INNER_LOOP_B BIT(3) 964 + #define HCLGE_CMD_COMMON_LB_DONE_B BIT(0) 965 + #define HCLGE_CMD_COMMON_LB_SUCCESS_B BIT(1) 966 + struct hclge_common_lb_cmd { 970 967 u8 mask; 971 968 u8 enable; 972 969 u8 result; ··· 1103 1098 1104 1099 #define HCLGE_LINK_EVENT_REPORT_EN_B 0 1105 1100 #define HCLGE_NCSI_ERROR_REPORT_EN_B 1 1101 + #define HCLGE_PHY_IMP_EN_B 2 1106 1102 struct hclge_firmware_compat_cmd { 1107 1103 __le32 compat; 1108 1104 u8 rsv[20]; ··· 1142 1136 __le16 max_frm_size; 1143 1137 __le16 max_qset_num; 1144 1138 __le16 max_int_gl; 1139 + u8 rsv1[18]; 1140 + }; 1141 + 1142 + #define HCLGE_PHY_LINK_SETTING_BD_NUM 2 1143 + 1144 + struct hclge_phy_link_ksetting_0_cmd { 1145 + __le32 speed; 1146 + u8 duplex; 1147 + u8 autoneg; 1148 + u8 eth_tp_mdix; 1149 + u8 eth_tp_mdix_ctrl; 1150 + u8 port; 1151 + u8 transceiver; 1152 + u8 phy_address; 1153 + u8 rsv; 1154 + __le32 supported; 1155 + __le32 advertising; 1156 + __le32 lp_advertising; 1157 + }; 1158 + 1159 + struct hclge_phy_link_ksetting_1_cmd { 1160 + u8 master_slave_cfg; 1161 + u8 master_slave_state; 1162 + u8 rsv[22]; 1163 + }; 1164 + 1165 + struct hclge_phy_reg_cmd { 1166 + __le16 reg_addr; 1167 + u8 rsv0[2]; 1168 + __le16 reg_val; 1145 1169 u8 rsv1[18]; 1146 1170 }; 1147 1171
+13 -7
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
··· 1546 1546 { 1547 1547 struct phy_device *phydev = hdev->hw.mac.phydev; 1548 1548 struct hclge_config_mac_mode_cmd *req_app; 1549 - struct hclge_serdes_lb_cmd *req_serdes; 1549 + struct hclge_common_lb_cmd *req_common; 1550 1550 struct hclge_desc desc; 1551 1551 u8 loopback_en; 1552 1552 int ret; 1553 1553 1554 1554 req_app = (struct hclge_config_mac_mode_cmd *)desc.data; 1555 - req_serdes = (struct hclge_serdes_lb_cmd *)desc.data; 1555 + req_common = (struct hclge_common_lb_cmd *)desc.data; 1556 1556 1557 1557 dev_info(&hdev->pdev->dev, "mac id: %u\n", hdev->hw.mac.mac_id); 1558 1558 ··· 1569 1569 dev_info(&hdev->pdev->dev, "app loopback: %s\n", 1570 1570 loopback_en ? "on" : "off"); 1571 1571 1572 - hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SERDES_LOOPBACK, true); 1572 + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_COMMON_LOOPBACK, true); 1573 1573 ret = hclge_cmd_send(&hdev->hw, &desc, 1); 1574 1574 if (ret) { 1575 1575 dev_err(&hdev->pdev->dev, 1576 - "failed to dump serdes loopback status, ret = %d\n", 1576 + "failed to dump common loopback status, ret = %d\n", 1577 1577 ret); 1578 1578 return; 1579 1579 } 1580 1580 1581 - loopback_en = req_serdes->enable & HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B; 1581 + loopback_en = req_common->enable & HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B; 1582 1582 dev_info(&hdev->pdev->dev, "serdes serial loopback: %s\n", 1583 1583 loopback_en ? "on" : "off"); 1584 1584 1585 - loopback_en = req_serdes->enable & 1585 + loopback_en = req_common->enable & 1586 1586 HCLGE_CMD_SERDES_PARALLEL_INNER_LOOP_B; 1587 1587 dev_info(&hdev->pdev->dev, "serdes parallel loopback: %s\n", 1588 1588 loopback_en ? "on" : "off"); 1589 1589 1590 - if (phydev) 1590 + if (phydev) { 1591 1591 dev_info(&hdev->pdev->dev, "phy loopback: %s\n", 1592 1592 phydev->loopback_enabled ? "on" : "off"); 1593 + } else if (hnae3_dev_phy_imp_supported(hdev)) { 1594 + loopback_en = req_common->enable & 1595 + HCLGE_CMD_GE_PHY_INNER_LOOP_B; 1596 + dev_info(&hdev->pdev->dev, "phy loopback: %s\n", 1597 + loopback_en ? "on" : "off"); 1598 + } 1593 1599 } 1594 1600 1595 1601 /* hclge_dbg_dump_mac_tnl_status: print message about mac tnl interrupt
+209 -32
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
··· 751 751 handle->flags |= HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK; 752 752 handle->flags |= HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK; 753 753 754 - if (hdev->hw.mac.phydev && hdev->hw.mac.phydev->drv && 755 - hdev->hw.mac.phydev->drv->set_loopback) { 754 + if ((hdev->hw.mac.phydev && hdev->hw.mac.phydev->drv && 755 + hdev->hw.mac.phydev->drv->set_loopback) || 756 + hnae3_dev_phy_imp_supported(hdev)) { 756 757 count += 1; 757 758 handle->flags |= HNAE3_SUPPORT_PHY_LOOPBACK; 758 759 } ··· 2995 2994 return 0; 2996 2995 } 2997 2996 2997 + static int hclge_get_phy_link_ksettings(struct hnae3_handle *handle, 2998 + struct ethtool_link_ksettings *cmd) 2999 + { 3000 + struct hclge_desc desc[HCLGE_PHY_LINK_SETTING_BD_NUM]; 3001 + struct hclge_vport *vport = hclge_get_vport(handle); 3002 + struct hclge_phy_link_ksetting_0_cmd *req0; 3003 + struct hclge_phy_link_ksetting_1_cmd *req1; 3004 + u32 supported, advertising, lp_advertising; 3005 + struct hclge_dev *hdev = vport->back; 3006 + int ret; 3007 + 3008 + hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_PHY_LINK_KSETTING, 3009 + true); 3010 + desc[0].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT); 3011 + hclge_cmd_setup_basic_desc(&desc[1], HCLGE_OPC_PHY_LINK_KSETTING, 3012 + true); 3013 + 3014 + ret = hclge_cmd_send(&hdev->hw, desc, HCLGE_PHY_LINK_SETTING_BD_NUM); 3015 + if (ret) { 3016 + dev_err(&hdev->pdev->dev, 3017 + "failed to get phy link ksetting, ret = %d.\n", ret); 3018 + return ret; 3019 + } 3020 + 3021 + req0 = (struct hclge_phy_link_ksetting_0_cmd *)desc[0].data; 3022 + cmd->base.autoneg = req0->autoneg; 3023 + cmd->base.speed = le32_to_cpu(req0->speed); 3024 + cmd->base.duplex = req0->duplex; 3025 + cmd->base.port = req0->port; 3026 + cmd->base.transceiver = req0->transceiver; 3027 + cmd->base.phy_address = req0->phy_address; 3028 + cmd->base.eth_tp_mdix = req0->eth_tp_mdix; 3029 + cmd->base.eth_tp_mdix_ctrl = req0->eth_tp_mdix_ctrl; 3030 + supported = le32_to_cpu(req0->supported); 3031 + advertising = le32_to_cpu(req0->advertising); 3032 + lp_advertising = le32_to_cpu(req0->lp_advertising); 3033 + ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, 3034 + supported); 3035 + ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, 3036 + advertising); 3037 + ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.lp_advertising, 3038 + lp_advertising); 3039 + 3040 + req1 = (struct hclge_phy_link_ksetting_1_cmd *)desc[1].data; 3041 + cmd->base.master_slave_cfg = req1->master_slave_cfg; 3042 + cmd->base.master_slave_state = req1->master_slave_state; 3043 + 3044 + return 0; 3045 + } 3046 + 3047 + static int 3048 + hclge_set_phy_link_ksettings(struct hnae3_handle *handle, 3049 + const struct ethtool_link_ksettings *cmd) 3050 + { 3051 + struct hclge_desc desc[HCLGE_PHY_LINK_SETTING_BD_NUM]; 3052 + struct hclge_vport *vport = hclge_get_vport(handle); 3053 + struct hclge_phy_link_ksetting_0_cmd *req0; 3054 + struct hclge_phy_link_ksetting_1_cmd *req1; 3055 + struct hclge_dev *hdev = vport->back; 3056 + u32 advertising; 3057 + int ret; 3058 + 3059 + if (cmd->base.autoneg == AUTONEG_DISABLE && 3060 + ((cmd->base.speed != SPEED_100 && cmd->base.speed != SPEED_10) || 3061 + (cmd->base.duplex != DUPLEX_HALF && 3062 + cmd->base.duplex != DUPLEX_FULL))) 3063 + return -EINVAL; 3064 + 3065 + hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_PHY_LINK_KSETTING, 3066 + false); 3067 + desc[0].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT); 3068 + hclge_cmd_setup_basic_desc(&desc[1], HCLGE_OPC_PHY_LINK_KSETTING, 3069 + false); 3070 + 3071 + req0 = (struct hclge_phy_link_ksetting_0_cmd *)desc[0].data; 3072 + req0->autoneg = cmd->base.autoneg; 3073 + req0->speed = cpu_to_le32(cmd->base.speed); 3074 + req0->duplex = cmd->base.duplex; 3075 + ethtool_convert_link_mode_to_legacy_u32(&advertising, 3076 + cmd->link_modes.advertising); 3077 + req0->advertising = cpu_to_le32(advertising); 3078 + req0->eth_tp_mdix_ctrl = cmd->base.eth_tp_mdix_ctrl; 3079 + 3080 + req1 = (struct hclge_phy_link_ksetting_1_cmd *)desc[1].data; 3081 + req1->master_slave_cfg = cmd->base.master_slave_cfg; 3082 + 3083 + ret = hclge_cmd_send(&hdev->hw, desc, HCLGE_PHY_LINK_SETTING_BD_NUM); 3084 + if (ret) { 3085 + dev_err(&hdev->pdev->dev, 3086 + "failed to set phy link ksettings, ret = %d.\n", ret); 3087 + return ret; 3088 + } 3089 + 3090 + hdev->hw.mac.autoneg = cmd->base.autoneg; 3091 + hdev->hw.mac.speed = cmd->base.speed; 3092 + hdev->hw.mac.duplex = cmd->base.duplex; 3093 + linkmode_copy(hdev->hw.mac.advertising, cmd->link_modes.advertising); 3094 + 3095 + return 0; 3096 + } 3097 + 3098 + static int hclge_update_tp_port_info(struct hclge_dev *hdev) 3099 + { 3100 + struct ethtool_link_ksettings cmd; 3101 + int ret; 3102 + 3103 + if (!hnae3_dev_phy_imp_supported(hdev)) 3104 + return 0; 3105 + 3106 + ret = hclge_get_phy_link_ksettings(&hdev->vport->nic, &cmd); 3107 + if (ret) 3108 + return ret; 3109 + 3110 + hdev->hw.mac.autoneg = cmd.base.autoneg; 3111 + hdev->hw.mac.speed = cmd.base.speed; 3112 + hdev->hw.mac.duplex = cmd.base.duplex; 3113 + 3114 + return 0; 3115 + } 3116 + 3117 + static int hclge_tp_port_init(struct hclge_dev *hdev) 3118 + { 3119 + struct ethtool_link_ksettings cmd; 3120 + 3121 + if (!hnae3_dev_phy_imp_supported(hdev)) 3122 + return 0; 3123 + 3124 + cmd.base.autoneg = hdev->hw.mac.autoneg; 3125 + cmd.base.speed = hdev->hw.mac.speed; 3126 + cmd.base.duplex = hdev->hw.mac.duplex; 3127 + linkmode_copy(cmd.link_modes.advertising, hdev->hw.mac.advertising); 3128 + 3129 + return hclge_set_phy_link_ksettings(&hdev->vport->nic, &cmd); 3130 + } 3131 + 2998 3132 static int hclge_update_port_info(struct hclge_dev *hdev) 2999 3133 { 3000 3134 struct hclge_mac *mac = &hdev->hw.mac; ··· 3138 3002 3139 3003 /* get the port info from SFP cmd if not copper port */ 3140 3004 if (mac->media_type == HNAE3_MEDIA_TYPE_COPPER) 3141 - return 0; 3005 + return hclge_update_tp_port_info(hdev); 3142 3006 3143 3007 /* if IMP does not support get SFP/qSFP info, return directly */ 3144 3008 if (!hdev->support_sfp_query) ··· 7271 7135 return ret; 7272 7136 } 7273 7137 7274 - static int hclge_cfg_serdes_loopback(struct hclge_dev *hdev, bool en, 7138 + static int hclge_cfg_common_loopback(struct hclge_dev *hdev, bool en, 7275 7139 enum hnae3_loop loop_mode) 7276 7140 { 7277 - #define HCLGE_SERDES_RETRY_MS 10 7278 - #define HCLGE_SERDES_RETRY_NUM 100 7141 + #define HCLGE_COMMON_LB_RETRY_MS 10 7142 + #define HCLGE_COMMON_LB_RETRY_NUM 100 7279 7143 7280 - struct hclge_serdes_lb_cmd *req; 7144 + struct hclge_common_lb_cmd *req; 7281 7145 struct hclge_desc desc; 7282 7146 int ret, i = 0; 7283 7147 u8 loop_mode_b; 7284 7148 7285 - req = (struct hclge_serdes_lb_cmd *)desc.data; 7286 - hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SERDES_LOOPBACK, false); 7149 + req = (struct hclge_common_lb_cmd *)desc.data; 7150 + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_COMMON_LOOPBACK, false); 7287 7151 7288 7152 switch (loop_mode) { 7289 7153 case HNAE3_LOOP_SERIAL_SERDES: ··· 7292 7156 case HNAE3_LOOP_PARALLEL_SERDES: 7293 7157 loop_mode_b = HCLGE_CMD_SERDES_PARALLEL_INNER_LOOP_B; 7294 7158 break; 7159 + case HNAE3_LOOP_PHY: 7160 + loop_mode_b = HCLGE_CMD_GE_PHY_INNER_LOOP_B; 7161 + break; 7295 7162 default: 7296 7163 dev_err(&hdev->pdev->dev, 7297 - "unsupported serdes loopback mode %d\n", loop_mode); 7164 + "unsupported common loopback mode %d\n", loop_mode); 7298 7165 return -ENOTSUPP; 7299 7166 } 7300 7167 ··· 7311 7172 ret = hclge_cmd_send(&hdev->hw, &desc, 1); 7312 7173 if (ret) { 7313 7174 dev_err(&hdev->pdev->dev, 7314 - "serdes loopback set fail, ret = %d\n", ret); 7175 + "common loopback set fail, ret = %d\n", ret); 7315 7176 return ret; 7316 7177 } 7317 7178 7318 7179 do { 7319 - msleep(HCLGE_SERDES_RETRY_MS); 7320 - hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SERDES_LOOPBACK, 7180 + msleep(HCLGE_COMMON_LB_RETRY_MS); 7181 + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_COMMON_LOOPBACK, 7321 7182 true); 7322 7183 ret = hclge_cmd_send(&hdev->hw, &desc, 1); 7323 7184 if (ret) { 7324 7185 dev_err(&hdev->pdev->dev, 7325 - "serdes loopback get, ret = %d\n", ret); 7186 + "common loopback get, ret = %d\n", ret); 7326 7187 return ret; 7327 7188 } 7328 - } while (++i < HCLGE_SERDES_RETRY_NUM && 7329 - !(req->result & HCLGE_CMD_SERDES_DONE_B)); 7189 + } while (++i < HCLGE_COMMON_LB_RETRY_NUM && 7190 + !(req->result & HCLGE_CMD_COMMON_LB_DONE_B)); 7330 7191 7331 - if (!(req->result & HCLGE_CMD_SERDES_DONE_B)) { 7332 - dev_err(&hdev->pdev->dev, "serdes loopback set timeout\n"); 7192 + if (!(req->result & HCLGE_CMD_COMMON_LB_DONE_B)) { 7193 + dev_err(&hdev->pdev->dev, "common loopback set timeout\n"); 7333 7194 return -EBUSY; 7334 - } else if (!(req->result & HCLGE_CMD_SERDES_SUCCESS_B)) { 7335 - dev_err(&hdev->pdev->dev, "serdes loopback set failed in fw\n"); 7195 + } else if (!(req->result & HCLGE_CMD_COMMON_LB_SUCCESS_B)) { 7196 + dev_err(&hdev->pdev->dev, "common loopback set failed in fw\n"); 7336 7197 return -EIO; 7337 7198 } 7338 7199 return ret; 7339 7200 } 7340 7201 7341 - static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en, 7202 + static int hclge_set_common_loopback(struct hclge_dev *hdev, bool en, 7342 7203 enum hnae3_loop loop_mode) 7343 7204 { 7344 7205 int ret; 7345 7206 7346 - ret = hclge_cfg_serdes_loopback(hdev, en, loop_mode); 7207 + ret = hclge_cfg_common_loopback(hdev, en, loop_mode); 7347 7208 if (ret) 7348 7209 return ret; 7349 7210 ··· 7392 7253 struct phy_device *phydev = hdev->hw.mac.phydev; 7393 7254 int ret; 7394 7255 7395 - if (!phydev) 7256 + if (!phydev) { 7257 + if (hnae3_dev_phy_imp_supported(hdev)) 7258 + return hclge_set_common_loopback(hdev, en, 7259 + HNAE3_LOOP_PHY); 7396 7260 return -ENOTSUPP; 7261 + } 7397 7262 7398 7263 if (en) 7399 7264 ret = hclge_enable_phy_loopback(hdev, phydev); ··· 7468 7325 break; 7469 7326 case HNAE3_LOOP_SERIAL_SERDES: 7470 7327 case HNAE3_LOOP_PARALLEL_SERDES: 7471 - ret = hclge_set_serdes_loopback(hdev, en, loop_mode); 7328 + ret = hclge_set_common_loopback(hdev, en, loop_mode); 7472 7329 break; 7473 7330 case HNAE3_LOOP_PHY: 7474 7331 ret = hclge_set_phy_loopback(hdev, en); ··· 7501 7358 if (ret) 7502 7359 return ret; 7503 7360 7504 - ret = hclge_cfg_serdes_loopback(hdev, false, HNAE3_LOOP_SERIAL_SERDES); 7361 + ret = hclge_cfg_common_loopback(hdev, false, HNAE3_LOOP_SERIAL_SERDES); 7505 7362 if (ret) 7506 7363 return ret; 7507 7364 7508 - return hclge_cfg_serdes_loopback(hdev, false, 7365 + return hclge_cfg_common_loopback(hdev, false, 7509 7366 HNAE3_LOOP_PARALLEL_SERDES); 7510 7367 } 7511 7368 ··· 8912 8769 return 0; 8913 8770 } 8914 8771 8772 + static int hclge_mii_ioctl(struct hclge_dev *hdev, struct ifreq *ifr, int cmd) 8773 + { 8774 + struct mii_ioctl_data *data = if_mii(ifr); 8775 + 8776 + if (!hnae3_dev_phy_imp_supported(hdev)) 8777 + return -EOPNOTSUPP; 8778 + 8779 + switch (cmd) { 8780 + case SIOCGMIIPHY: 8781 + data->phy_id = hdev->hw.mac.phy_addr; 8782 + /* this command reads phy id and register at the same time */ 8783 + fallthrough; 8784 + case SIOCGMIIREG: 8785 + data->val_out = hclge_read_phy_reg(hdev, data->reg_num); 8786 + return 0; 8787 + 8788 + case SIOCSMIIREG: 8789 + return hclge_write_phy_reg(hdev, data->reg_num, data->val_in); 8790 + default: 8791 + return -EOPNOTSUPP; 8792 + } 8793 + } 8794 + 8915 8795 static int hclge_do_ioctl(struct hnae3_handle *handle, struct ifreq *ifr, 8916 8796 int cmd) 8917 8797 { ··· 8942 8776 struct hclge_dev *hdev = vport->back; 8943 8777 8944 8778 if (!hdev->hw.mac.phydev) 8945 - return -EOPNOTSUPP; 8779 + return hclge_mii_ioctl(hdev, ifr, cmd); 8946 8780 8947 8781 return phy_mii_ioctl(hdev->hw.mac.phydev, ifr, cmd); 8948 8782 } ··· 10189 10023 { 10190 10024 struct hclge_vport *vport = hclge_get_vport(handle); 10191 10025 struct hclge_dev *hdev = vport->back; 10192 - struct phy_device *phydev = hdev->hw.mac.phydev; 10026 + u8 media_type = hdev->hw.mac.media_type; 10193 10027 10194 - *auto_neg = phydev ? hclge_get_autoneg(handle) : 0; 10028 + *auto_neg = (media_type == HNAE3_MEDIA_TYPE_COPPER) ? 10029 + hclge_get_autoneg(handle) : 0; 10195 10030 10196 10031 if (hdev->tm_info.fc_mode == HCLGE_FC_PFC) { 10197 10032 *rx_en = 0; ··· 10238 10071 struct phy_device *phydev = hdev->hw.mac.phydev; 10239 10072 u32 fc_autoneg; 10240 10073 10241 - if (phydev) { 10074 + if (phydev || hnae3_dev_phy_imp_supported(hdev)) { 10242 10075 fc_autoneg = hclge_get_autoneg(handle); 10243 10076 if (auto_neg != fc_autoneg) { 10244 10077 dev_info(&hdev->pdev->dev, ··· 10257 10090 10258 10091 hclge_record_user_pauseparam(hdev, rx_en, tx_en); 10259 10092 10260 - if (!auto_neg) 10093 + if (!auto_neg || hnae3_dev_phy_imp_supported(hdev)) 10261 10094 return hclge_cfg_pauseparam(hdev, rx_en, tx_en); 10262 10095 10263 10096 if (phydev) ··· 10815 10648 if (ret) 10816 10649 goto err_msi_irq_uninit; 10817 10650 10818 - if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER) { 10651 + if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER && 10652 + !hnae3_dev_phy_imp_supported(hdev)) { 10819 10653 ret = hclge_mac_mdio_config(hdev); 10820 10654 if (ret) 10821 10655 goto err_msi_irq_uninit; ··· 11206 11038 ret = hclge_mac_init(hdev); 11207 11039 if (ret) { 11208 11040 dev_err(&pdev->dev, "Mac init error, ret = %d\n", ret); 11041 + return ret; 11042 + } 11043 + 11044 + ret = hclge_tp_port_init(hdev); 11045 + if (ret) { 11046 + dev_err(&pdev->dev, "failed to init tp port, ret = %d\n", 11047 + ret); 11209 11048 return ret; 11210 11049 } 11211 11050 ··· 12157 11982 .add_cls_flower = hclge_add_cls_flower, 12158 11983 .del_cls_flower = hclge_del_cls_flower, 12159 11984 .cls_flower_active = hclge_is_cls_flower_active, 11985 + .get_phy_link_ksettings = hclge_get_phy_link_ksettings, 11986 + .set_phy_link_ksettings = hclge_set_phy_link_ksettings, 12160 11987 }; 12161 11988 12162 11989 static struct hnae3_ae_algo ae_algo = {
+39
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
··· 268 268 269 269 phy_stop(phydev); 270 270 } 271 + 272 + u16 hclge_read_phy_reg(struct hclge_dev *hdev, u16 reg_addr) 273 + { 274 + struct hclge_phy_reg_cmd *req; 275 + struct hclge_desc desc; 276 + int ret; 277 + 278 + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PHY_REG, true); 279 + 280 + req = (struct hclge_phy_reg_cmd *)desc.data; 281 + req->reg_addr = cpu_to_le16(reg_addr); 282 + 283 + ret = hclge_cmd_send(&hdev->hw, &desc, 1); 284 + if (ret) 285 + dev_err(&hdev->pdev->dev, 286 + "failed to read phy reg, ret = %d.\n", ret); 287 + 288 + return le16_to_cpu(req->reg_val); 289 + } 290 + 291 + int hclge_write_phy_reg(struct hclge_dev *hdev, u16 reg_addr, u16 val) 292 + { 293 + struct hclge_phy_reg_cmd *req; 294 + struct hclge_desc desc; 295 + int ret; 296 + 297 + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PHY_REG, false); 298 + 299 + req = (struct hclge_phy_reg_cmd *)desc.data; 300 + req->reg_addr = cpu_to_le16(reg_addr); 301 + req->reg_val = cpu_to_le16(val); 302 + 303 + ret = hclge_cmd_send(&hdev->hw, &desc, 1); 304 + if (ret) 305 + dev_err(&hdev->pdev->dev, 306 + "failed to write phy reg, ret = %d.\n", ret); 307 + 308 + return ret; 309 + }
+2
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.h
··· 9 9 void hclge_mac_disconnect_phy(struct hnae3_handle *handle); 10 10 void hclge_mac_start_phy(struct hclge_dev *hdev); 11 11 void hclge_mac_stop_phy(struct hclge_dev *hdev); 12 + u16 hclge_read_phy_reg(struct hclge_dev *hdev, u16 reg_addr); 13 + int hclge_write_phy_reg(struct hclge_dev *hdev, u16 reg_addr, u16 val); 12 14 13 15 #endif