mirror of https://gitee.com/openkylin/linux.git
hinic: add support to identify physical device
add support to identify physical device by flashing an LED attached to it with ethtool -p cmd. Signed-off-by: Luo bin <luobin9@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
4aa218a4fe
commit
07afcc7ab4
|
@ -1684,6 +1684,39 @@ static void hinic_diag_test(struct net_device *netdev,
|
||||||
netif_carrier_on(netdev);
|
netif_carrier_on(netdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hinic_set_phys_id(struct net_device *netdev,
|
||||||
|
enum ethtool_phys_id_state state)
|
||||||
|
{
|
||||||
|
struct hinic_dev *nic_dev = netdev_priv(netdev);
|
||||||
|
int err = 0;
|
||||||
|
u8 port;
|
||||||
|
|
||||||
|
port = nic_dev->hwdev->port_id;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case ETHTOOL_ID_ACTIVE:
|
||||||
|
err = hinic_set_led_status(nic_dev->hwdev, port,
|
||||||
|
HINIC_LED_TYPE_LINK,
|
||||||
|
HINIC_LED_MODE_FORCE_2HZ);
|
||||||
|
if (err)
|
||||||
|
netif_err(nic_dev, drv, netdev,
|
||||||
|
"Set LED blinking in 2HZ failed\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ETHTOOL_ID_INACTIVE:
|
||||||
|
err = hinic_reset_led_status(nic_dev->hwdev, port);
|
||||||
|
if (err)
|
||||||
|
netif_err(nic_dev, drv, netdev,
|
||||||
|
"Reset LED to original status failed\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct ethtool_ops hinic_ethtool_ops = {
|
static const struct ethtool_ops hinic_ethtool_ops = {
|
||||||
.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS |
|
.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS |
|
||||||
ETHTOOL_COALESCE_RX_MAX_FRAMES |
|
ETHTOOL_COALESCE_RX_MAX_FRAMES |
|
||||||
|
@ -1714,6 +1747,7 @@ static const struct ethtool_ops hinic_ethtool_ops = {
|
||||||
.get_ethtool_stats = hinic_get_ethtool_stats,
|
.get_ethtool_stats = hinic_get_ethtool_stats,
|
||||||
.get_strings = hinic_get_strings,
|
.get_strings = hinic_get_strings,
|
||||||
.self_test = hinic_diag_test,
|
.self_test = hinic_diag_test,
|
||||||
|
.set_phys_id = hinic_set_phys_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ethtool_ops hinicvf_ethtool_ops = {
|
static const struct ethtool_ops hinicvf_ethtool_ops = {
|
||||||
|
|
|
@ -83,6 +83,8 @@ static int parse_capability(struct hinic_hwdev *hwdev,
|
||||||
nic_cap->max_vf_qps = dev_cap->max_vf_sqs + 1;
|
nic_cap->max_vf_qps = dev_cap->max_vf_sqs + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hwdev->port_id = dev_cap->port_id;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -312,6 +312,7 @@ struct hinic_hwdev {
|
||||||
struct hinic_mbox_func_to_func *func_to_func;
|
struct hinic_mbox_func_to_func *func_to_func;
|
||||||
|
|
||||||
struct hinic_cap nic_cap;
|
struct hinic_cap nic_cap;
|
||||||
|
u8 port_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hinic_nic_cb {
|
struct hinic_nic_cb {
|
||||||
|
|
|
@ -81,7 +81,9 @@ enum hinic_comm_cmd {
|
||||||
HINIC_COMM_CMD_MSI_CTRL_REG_WR_BY_UP,
|
HINIC_COMM_CMD_MSI_CTRL_REG_WR_BY_UP,
|
||||||
HINIC_COMM_CMD_MSI_CTRL_REG_RD_BY_UP,
|
HINIC_COMM_CMD_MSI_CTRL_REG_RD_BY_UP,
|
||||||
|
|
||||||
HINIC_COMM_CMD_L2NIC_RESET = 0x4b,
|
HINIC_COMM_CMD_SET_LED_STATUS = 0x4a,
|
||||||
|
|
||||||
|
HINIC_COMM_CMD_L2NIC_RESET = 0x4b,
|
||||||
|
|
||||||
HINIC_COMM_CMD_PAGESIZE_SET = 0x50,
|
HINIC_COMM_CMD_PAGESIZE_SET = 0x50,
|
||||||
|
|
||||||
|
|
|
@ -1268,3 +1268,58 @@ int hinic_set_loopback_mode(struct hinic_hwdev *hwdev, u32 mode, u32 enable)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _set_led_status(struct hinic_hwdev *hwdev, u8 port,
|
||||||
|
enum hinic_led_type type,
|
||||||
|
enum hinic_led_mode mode, u8 reset)
|
||||||
|
{
|
||||||
|
struct hinic_led_info led_info = {0};
|
||||||
|
u16 out_size = sizeof(led_info);
|
||||||
|
struct hinic_pfhwdev *pfhwdev;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
|
||||||
|
|
||||||
|
led_info.port = port;
|
||||||
|
led_info.reset = reset;
|
||||||
|
|
||||||
|
led_info.type = type;
|
||||||
|
led_info.mode = mode;
|
||||||
|
|
||||||
|
err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
|
||||||
|
HINIC_COMM_CMD_SET_LED_STATUS,
|
||||||
|
&led_info, sizeof(led_info),
|
||||||
|
&led_info, &out_size, HINIC_MGMT_MSG_SYNC);
|
||||||
|
if (err || led_info.status || !out_size) {
|
||||||
|
dev_err(&hwdev->hwif->pdev->dev, "Failed to set led status, err: %d, status: 0x%x, out size: 0x%x\n",
|
||||||
|
err, led_info.status, out_size);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hinic_set_led_status(struct hinic_hwdev *hwdev, u8 port,
|
||||||
|
enum hinic_led_type type, enum hinic_led_mode mode)
|
||||||
|
{
|
||||||
|
if (!hwdev)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return _set_led_status(hwdev, port, type, mode, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hinic_reset_led_status(struct hinic_hwdev *hwdev, u8 port)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!hwdev)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
err = _set_led_status(hwdev, port, HINIC_LED_TYPE_INVALID,
|
||||||
|
HINIC_LED_MODE_INVALID, 1);
|
||||||
|
if (err)
|
||||||
|
dev_err(&hwdev->hwif->pdev->dev,
|
||||||
|
"Failed to reset led status\n");
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
|
@ -666,6 +666,17 @@ struct hinic_port_loopback {
|
||||||
u32 en;
|
u32 en;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct hinic_led_info {
|
||||||
|
u8 status;
|
||||||
|
u8 version;
|
||||||
|
u8 rsvd0[6];
|
||||||
|
|
||||||
|
u8 port;
|
||||||
|
u8 type;
|
||||||
|
u8 mode;
|
||||||
|
u8 reset;
|
||||||
|
};
|
||||||
|
|
||||||
int hinic_port_add_mac(struct hinic_dev *nic_dev, const u8 *addr,
|
int hinic_port_add_mac(struct hinic_dev *nic_dev, const u8 *addr,
|
||||||
u16 vlan_id);
|
u16 vlan_id);
|
||||||
|
|
||||||
|
@ -765,6 +776,30 @@ int hinic_dcb_set_pfc(struct hinic_hwdev *hwdev, u8 pfc_en, u8 pfc_bitmap);
|
||||||
|
|
||||||
int hinic_set_loopback_mode(struct hinic_hwdev *hwdev, u32 mode, u32 enable);
|
int hinic_set_loopback_mode(struct hinic_hwdev *hwdev, u32 mode, u32 enable);
|
||||||
|
|
||||||
|
enum hinic_led_mode {
|
||||||
|
HINIC_LED_MODE_ON,
|
||||||
|
HINIC_LED_MODE_OFF,
|
||||||
|
HINIC_LED_MODE_FORCE_1HZ,
|
||||||
|
HINIC_LED_MODE_FORCE_2HZ,
|
||||||
|
HINIC_LED_MODE_FORCE_4HZ,
|
||||||
|
HINIC_LED_MODE_1HZ,
|
||||||
|
HINIC_LED_MODE_2HZ,
|
||||||
|
HINIC_LED_MODE_4HZ,
|
||||||
|
HINIC_LED_MODE_INVALID,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum hinic_led_type {
|
||||||
|
HINIC_LED_TYPE_LINK,
|
||||||
|
HINIC_LED_TYPE_LOW_SPEED,
|
||||||
|
HINIC_LED_TYPE_HIGH_SPEED,
|
||||||
|
HINIC_LED_TYPE_INVALID,
|
||||||
|
};
|
||||||
|
|
||||||
|
int hinic_reset_led_status(struct hinic_hwdev *hwdev, u8 port);
|
||||||
|
|
||||||
|
int hinic_set_led_status(struct hinic_hwdev *hwdev, u8 port,
|
||||||
|
enum hinic_led_type type, enum hinic_led_mode mode);
|
||||||
|
|
||||||
int hinic_open(struct net_device *netdev);
|
int hinic_open(struct net_device *netdev);
|
||||||
|
|
||||||
int hinic_close(struct net_device *netdev);
|
int hinic_close(struct net_device *netdev);
|
||||||
|
|
|
@ -383,7 +383,7 @@ static int hinic_del_vf_mac_msg_handler(void *hwdev, u16 vf_id,
|
||||||
|
|
||||||
nic_io = &hw_dev->func_to_io;
|
nic_io = &hw_dev->func_to_io;
|
||||||
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
|
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
|
||||||
if (vf_info->pf_set_mac && is_valid_ether_addr(mac_in->mac) &&
|
if (vf_info->pf_set_mac && is_valid_ether_addr(mac_in->mac) &&
|
||||||
!memcmp(vf_info->vf_mac_addr, mac_in->mac, ETH_ALEN)) {
|
!memcmp(vf_info->vf_mac_addr, mac_in->mac, ETH_ALEN)) {
|
||||||
dev_warn(&hw_dev->hwif->pdev->dev, "PF has already set VF mac.\n");
|
dev_warn(&hw_dev->hwif->pdev->dev, "PF has already set VF mac.\n");
|
||||||
mac_out->status = HINIC_PF_SET_VF_ALREADY;
|
mac_out->status = HINIC_PF_SET_VF_ALREADY;
|
||||||
|
@ -905,7 +905,6 @@ int hinic_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting)
|
||||||
|
|
||||||
err = hinic_set_vf_spoofchk(sriov_info->hwdev,
|
err = hinic_set_vf_spoofchk(sriov_info->hwdev,
|
||||||
OS_VF_ID_TO_HW(vf), setting);
|
OS_VF_ID_TO_HW(vf), setting);
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
netif_info(nic_dev, drv, netdev, "Set VF %d spoofchk %s successfully\n",
|
netif_info(nic_dev, drv, netdev, "Set VF %d spoofchk %s successfully\n",
|
||||||
vf, setting ? "on" : "off");
|
vf, setting ? "on" : "off");
|
||||||
|
@ -1020,6 +1019,7 @@ static int cfg_mbx_pf_proc_vf_msg(void *hwdev, u16 vf_id, u8 cmd, void *buf_in,
|
||||||
dev_cap->max_vf = cap->max_vf;
|
dev_cap->max_vf = cap->max_vf;
|
||||||
dev_cap->max_sqs = cap->max_vf_qps;
|
dev_cap->max_sqs = cap->max_vf_qps;
|
||||||
dev_cap->max_rqs = cap->max_vf_qps;
|
dev_cap->max_rqs = cap->max_vf_qps;
|
||||||
|
dev_cap->port_id = dev->port_id;
|
||||||
|
|
||||||
*out_size = sizeof(*dev_cap);
|
*out_size = sizeof(*dev_cap);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue