From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7EC54A034C; Thu, 1 Sep 2022 23:14:23 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8248940F17; Thu, 1 Sep 2022 23:14:19 +0200 (CEST) Received: from smail.rz.tu-ilmenau.de (smail.rz.tu-ilmenau.de [141.24.186.67]) by mails.dpdk.org (Postfix) with ESMTP id 68EAB40684 for ; Thu, 1 Sep 2022 23:14:17 +0200 (CEST) Received: from localhost.localdomain (pd9559a85.dip0.t-ipconnect.de [217.85.154.133]) by smail.rz.tu-ilmenau.de (Postfix) with ESMTPA id E73CE580091; Thu, 1 Sep 2022 23:14:16 +0200 (CEST) From: Markus Theil To: dev@dpdk.org Cc: Qiming Yang , Qi Zhang , Markus Theil Subject: [PATCH 2/2] net/ice: add basic flow ctrl support for enable/disable/get Date: Thu, 1 Sep 2022 23:13:50 +0200 Message-Id: <20220901211350.87631-2-markus.theil@tu-ilmenau.de> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220901211350.87631-1-markus.theil@tu-ilmenau.de> References: <20220901211350.87631-1-markus.theil@tu-ilmenau.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Markus Theil Signed-off-by: Markus Theil --- drivers/net/ice/ice_ethdev.c | 108 +++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index f5820d6ccb..ad93ec8155 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -92,6 +92,10 @@ static int ice_dev_set_link_up(struct rte_eth_dev *dev); static int ice_dev_set_link_down(struct rte_eth_dev *dev); static int ice_dev_led_on(struct rte_eth_dev *dev); static int ice_dev_led_off(struct rte_eth_dev *dev); +static int ice_dev_flow_ctrl_get(struct rte_eth_dev *dev, + struct rte_eth_fc_conf *fc_conf); +static int ice_dev_flow_ctrl_set(struct rte_eth_dev *dev, + struct rte_eth_fc_conf *fc_conf); static int ice_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); static int ice_vlan_offload_set(struct rte_eth_dev *dev, int mask); @@ -219,6 +223,8 @@ static const struct eth_dev_ops ice_eth_dev_ops = { .dev_set_link_down = ice_dev_set_link_down, .dev_led_on = ice_dev_led_on, .dev_led_off = ice_dev_led_off, + .flow_ctrl_get = ice_dev_flow_ctrl_get, + .flow_ctrl_set = ice_dev_flow_ctrl_set, .rx_queue_start = ice_rx_queue_start, .rx_queue_stop = ice_rx_queue_stop, .tx_queue_start = ice_tx_queue_start, @@ -4096,6 +4102,108 @@ ice_dev_led_off(struct rte_eth_dev *dev) return status == ICE_SUCCESS ? 0 : -ENOTSUP; } +static int +ice_dev_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) +{ + struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct ice_aqc_get_phy_caps_data *pcaps; + int tx_pause, rx_pause; + int status; + + pcaps = (struct ice_aqc_get_phy_caps_data *) + ice_malloc(hw, sizeof(*pcaps)); + if (!pcaps) + return -ENOMEM; + + status = ice_aq_get_phy_caps(hw->port_info, false, + ICE_AQC_REPORT_ACTIVE_CFG, pcaps, NULL); + if(status) + goto out; + + fc_conf->autoneg = ice_is_phy_caps_an_enabled(pcaps); + tx_pause = !!(pcaps->caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE); + rx_pause = !!(pcaps->caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE); + + if (rx_pause && tx_pause) + fc_conf->mode = RTE_ETH_FC_FULL; + else if (rx_pause) + fc_conf->mode = RTE_ETH_FC_RX_PAUSE; + else if (tx_pause) + fc_conf->mode = RTE_ETH_FC_TX_PAUSE; + else + fc_conf->mode = RTE_ETH_FC_NONE; + +out: + ice_free(hw, pcaps); + return status; +} + +static int +ice_dev_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) +{ + struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct ice_port_info *pi = hw->port_info; + struct ice_link_status *ls = &pi->phy.link_info; + bool link_up = !!(ls->link_info & ICE_AQ_LINK_UP); + struct ice_aqc_get_phy_caps_data *pcaps; + u8 aq_failures; + int status; + + pcaps = (struct ice_aqc_get_phy_caps_data *) + ice_malloc(hw, sizeof(*pcaps)); + if (!pcaps) + return -ENOMEM; + + status = ice_aq_get_phy_caps(hw->port_info, false, + ICE_AQC_REPORT_ACTIVE_CFG, pcaps, NULL); + if(status) { + status = -EIO; + goto out; + } + if(fc_conf->autoneg != ice_is_phy_caps_an_enabled(pcaps)) { + status = -ENOTSUP; + goto out; + } + + switch(fc_conf->mode) { + case RTE_ETH_FC_FULL: + pi->fc.req_mode = ICE_FC_FULL; + break; + case RTE_ETH_FC_RX_PAUSE: + pi->fc.req_mode = ICE_FC_RX_PAUSE; + break; + case RTE_ETH_FC_TX_PAUSE: + pi->fc.req_mode = ICE_FC_TX_PAUSE; + break; + case RTE_ETH_FC_NONE: + pi->fc.req_mode = ICE_FC_NONE; + break; + } + + status = ice_set_fc(pi, &aq_failures, link_up); + + if (aq_failures & ICE_SET_FC_AQ_FAIL_GET) { + PMD_DRV_LOG(ERR, + "port %d fc set failed on get, err %d aq status %i\n", + dev->data->port_id, status, hw->adminq.sq_last_status); + status = -EIO; + } else if (aq_failures & ICE_SET_FC_AQ_FAIL_SET) { + PMD_DRV_LOG(ERR, + "port %d fc set failed on set, err %d aq status %i\n", + dev->data->port_id, status, hw->adminq.sq_last_status); + status = -EIO; + } else if (aq_failures & ICE_SET_FC_AQ_FAIL_UPDATE) { + PMD_DRV_LOG(ERR, + "port %d fc set failed on update, err %d aq status %i\n", + dev->data->port_id, status, hw->adminq.sq_last_status); + status = -EIO; + } + +out: + ice_free(hw, pcaps); + return status; +} + static int ice_mtu_set(struct rte_eth_dev *dev, uint16_t mtu __rte_unused) { -- 2.37.3