From: Pavel Belous <pavel.bel...@aquantia.com> Signed-off-by: Igor Russkikh <igor.russk...@aquantia.com> --- drivers/net/atlantic/atl_ethdev.c | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
diff --git a/drivers/net/atlantic/atl_ethdev.c b/drivers/net/atlantic/atl_ethdev.c index ec1c22886..a95dc87fd 100644 --- a/drivers/net/atlantic/atl_ethdev.c +++ b/drivers/net/atlantic/atl_ethdev.c @@ -66,6 +66,11 @@ static void atl_dev_info_get(struct rte_eth_dev *dev, static const uint32_t *atl_dev_supported_ptypes_get(struct rte_eth_dev *dev); +/* Flow control */ +static int atl_flow_ctrl_get(struct rte_eth_dev *dev, + struct rte_eth_fc_conf *fc_conf); +static int atl_flow_ctrl_set(struct rte_eth_dev *dev, + struct rte_eth_fc_conf *fc_conf); /* Interrupts */ static int atl_dev_rxq_interrupt_setup(struct rte_eth_dev *dev); static int atl_dev_lsc_interrupt_setup(struct rte_eth_dev *dev, uint8_t on); @@ -157,6 +162,10 @@ static const struct eth_dev_ops atl_eth_dev_ops = { /* Link */ .link_update = atl_dev_link_update, + + /* Flow Control */ + .flow_ctrl_get = atl_flow_ctrl_get, + .flow_ctrl_set = atl_flow_ctrl_set, .reta_update = atl_reta_update, .reta_query = atl_reta_query, .rss_hash_update = atl_rss_hash_update, @@ -815,6 +824,47 @@ atl_dev_interrupt_handler(void *param) atl_dev_interrupt_action(dev, dev->intr_handle); } +static int +atl_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) +{ + struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + if (hw->aq_nic_cfg->flow_control == AQ_NIC_FC_OFF) + fc_conf->mode = RTE_FC_NONE; + else if (hw->aq_nic_cfg->flow_control & (AQ_NIC_FC_RX | AQ_NIC_FC_TX)) + fc_conf->mode = RTE_FC_FULL; + else if (hw->aq_nic_cfg->flow_control & AQ_NIC_FC_RX) + fc_conf->mode = RTE_FC_RX_PAUSE; + else if (hw->aq_nic_cfg->flow_control & AQ_NIC_FC_RX) + fc_conf->mode = RTE_FC_TX_PAUSE; + + return 0; +} + +static int +atl_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) +{ + struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t old_flow_control = hw->aq_nic_cfg->flow_control; + + + if (hw->aq_fw_ops->set_flow_control == NULL) + return -ENOTSUP; + + if (fc_conf->mode == RTE_FC_NONE) + hw->aq_nic_cfg->flow_control = AQ_NIC_FC_OFF; + else if (fc_conf->mode == RTE_FC_RX_PAUSE) + hw->aq_nic_cfg->flow_control = AQ_NIC_FC_RX; + else if (fc_conf->mode == RTE_FC_TX_PAUSE) + hw->aq_nic_cfg->flow_control = AQ_NIC_FC_TX; + else if (fc_conf->mode == RTE_FC_FULL) + hw->aq_nic_cfg->flow_control = (AQ_NIC_FC_RX | AQ_NIC_FC_TX); + + if (old_flow_control != hw->aq_nic_cfg->flow_control) + return hw->aq_fw_ops->set_flow_control(hw); + + return 0; +} static int atl_reta_update(struct rte_eth_dev *dev, -- 2.13.3.windows.1