From 54ac338699322a76f60de0737a1e1ad56a730a87 Mon Sep 17 00:00:00 2001 From: Xiaoyun Wang Date: Thu, 10 Oct 2019 22:51:56 +0800 Subject: [PATCH] net/hinic: set link down and up This patch supports setting link down and up. Signed-off-by: Xiaoyun Wang --- doc/guides/nics/hinic.rst | 1 + drivers/net/hinic/base/hinic_pmd_cmd.h | 2 + drivers/net/hinic/base/hinic_pmd_niccfg.c | 38 ++++++++++++++ drivers/net/hinic/base/hinic_pmd_niccfg.h | 9 ++++ drivers/net/hinic/hinic_pmd_ethdev.c | 62 +++++++++++++++++++++++ 5 files changed, 112 insertions(+) diff --git a/doc/guides/nics/hinic.rst b/doc/guides/nics/hinic.rst index 8ff41717c9..9a9fcbe0f1 100644 --- a/doc/guides/nics/hinic.rst +++ b/doc/guides/nics/hinic.rst @@ -31,6 +31,7 @@ Features - Unicast MAC filter - Multicast MAC filter - Flow director +- Set Link down or up Prerequisites ------------- diff --git a/drivers/net/hinic/base/hinic_pmd_cmd.h b/drivers/net/hinic/base/hinic_pmd_cmd.h index 6b3dcf3012..55d4292254 100644 --- a/drivers/net/hinic/base/hinic_pmd_cmd.h +++ b/drivers/net/hinic/base/hinic_pmd_cmd.h @@ -119,6 +119,8 @@ enum hinic_port_cmd { HINIC_PORT_CMD_SET_IPSU_MAC = 0xcb, HINIC_PORT_CMD_GET_IPSU_MAC = 0xcc, + HINIC_PORT_CMD_SET_XSFP_STATUS = 0xD4, + HINIC_PORT_CMD_GET_LINK_MODE = 0xD9, HINIC_PORT_CMD_SET_SPEED = 0xDA, HINIC_PORT_CMD_SET_AUTONEG = 0xDB, diff --git a/drivers/net/hinic/base/hinic_pmd_niccfg.c b/drivers/net/hinic/base/hinic_pmd_niccfg.c index 53d981bef8..9f23fdd5b1 100644 --- a/drivers/net/hinic/base/hinic_pmd_niccfg.c +++ b/drivers/net/hinic/base/hinic_pmd_niccfg.c @@ -1612,6 +1612,44 @@ int hinic_get_link_mode(void *hwdev, u32 *supported, u32 *advertised) return 0; } +/** + * hinic_set_xsfp_tx_status - Enable or disable the fiber in + * tx direction when set link up or down. + * + * @param hwdev + * The hardware interface of a nic device. + * @param enable + * Enable or Disable. + * + * @return + * 0 on success. + * negative error value otherwise. + */ +int hinic_set_xsfp_tx_status(void *hwdev, bool enable) +{ + struct hinic_set_xsfp_status xsfp_status; + u16 out_size = sizeof(struct hinic_set_xsfp_status); + int err; + + memset(&xsfp_status, 0, sizeof(xsfp_status)); + xsfp_status.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1; + xsfp_status.port_id = hinic_global_func_id(hwdev); + xsfp_status.xsfp_tx_dis = ((enable == 0) ? 1 : 0); + + err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_XSFP_STATUS, + &xsfp_status, sizeof(struct hinic_set_xsfp_status), + &xsfp_status, &out_size); + if (err || !out_size || xsfp_status.mgmt_msg_head.status) { + PMD_DRV_LOG(ERR, + "Failed to %s port xsfp status, err: %d, status: 0x%x, out size: 0x%x\n", + enable ? "Disable" : "Enable", err, + xsfp_status.mgmt_msg_head.status, out_size); + return -EFAULT; + } + + return 0; +} + /** * hinic_flush_qp_res - Flush tx && rx chip resources in case of set vport * fake failed when device start. diff --git a/drivers/net/hinic/base/hinic_pmd_niccfg.h b/drivers/net/hinic/base/hinic_pmd_niccfg.h index e8ce3325a9..beab6306d6 100644 --- a/drivers/net/hinic/base/hinic_pmd_niccfg.h +++ b/drivers/net/hinic/base/hinic_pmd_niccfg.h @@ -578,6 +578,13 @@ struct hinic_link_mode_cmd { u16 advertised; }; +struct hinic_set_xsfp_status { + struct hinic_mgmt_msg_head mgmt_msg_head; + + u32 port_id; + u32 xsfp_tx_dis; /* 0: tx enable; 1: tx disable */ +}; + struct hinic_clear_qp_resource { struct hinic_mgmt_msg_head mgmt_msg_head; @@ -807,6 +814,8 @@ int hinic_set_link_status_follow(void *hwdev, int hinic_get_link_mode(void *hwdev, u32 *supported, u32 *advertised); +int hinic_set_xsfp_tx_status(void *hwdev, bool enable); + int hinic_flush_qp_res(void *hwdev); int hinic_init_function_table(void *hwdev, u16 rx_buf_sz); diff --git a/drivers/net/hinic/hinic_pmd_ethdev.c b/drivers/net/hinic/hinic_pmd_ethdev.c index d0bcbe5635..ea39ff0ff6 100644 --- a/drivers/net/hinic/hinic_pmd_ethdev.c +++ b/drivers/net/hinic/hinic_pmd_ethdev.c @@ -882,6 +882,66 @@ out: return rc; } +/** + * DPDK callback to bring the link UP. + * + * @param dev + * Pointer to Ethernet device structure. + * + * @return + * 0 on success, negative errno value on failure. + */ +static int hinic_dev_set_link_up(struct rte_eth_dev *dev) +{ + struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + int ret; + + ret = hinic_set_xsfp_tx_status(nic_dev->hwdev, true); + if (ret) { + PMD_DRV_LOG(ERR, "Enable port tx xsfp failed, dev_name: %s, port_id: %d", + nic_dev->proc_dev_name, dev->data->port_id); + return ret; + } + + /* link status follow phy port status, up will open pma */ + ret = hinic_set_port_enable(nic_dev->hwdev, true); + if (ret) + PMD_DRV_LOG(ERR, "Set mac link up failed, dev_name: %s, port_id: %d", + nic_dev->proc_dev_name, dev->data->port_id); + + return ret; +} + +/** + * DPDK callback to bring the link DOWN. + * + * @param dev + * Pointer to Ethernet device structure. + * + * @return + * 0 on success, negative errno value on failure. + */ +static int hinic_dev_set_link_down(struct rte_eth_dev *dev) +{ + struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + int ret; + + ret = hinic_set_xsfp_tx_status(nic_dev->hwdev, false); + if (ret) { + PMD_DRV_LOG(ERR, "Disable port tx xsfp failed, dev_name: %s, port_id: %d", + nic_dev->proc_dev_name, dev->data->port_id); + return ret; + } + + /* link status follow phy port status, up will close pma */ + ret = hinic_set_port_enable(nic_dev->hwdev, false); + if (ret) + PMD_DRV_LOG(ERR, "Set mac link down failed, dev_name: %s, port_id: %d", + nic_dev->proc_dev_name, dev->data->port_id); + + return ret; +} + /** * DPDK callback to start the device. * @@ -2756,6 +2816,8 @@ static const struct eth_dev_ops hinic_pmd_ops = { .rx_queue_setup = hinic_rx_queue_setup, .tx_queue_setup = hinic_tx_queue_setup, .dev_start = hinic_dev_start, + .dev_set_link_up = hinic_dev_set_link_up, + .dev_set_link_down = hinic_dev_set_link_down, .link_update = hinic_link_update, .rx_queue_release = hinic_rx_queue_release, .tx_queue_release = hinic_tx_queue_release, -- 2.20.1