net/axgbe: support flow control API
PATCH v4 1/2 net/axgbe: support flow control API
From: Amaranath Somalapuram <[email protected]>
Adding api for flow_ctrl_get and flow_ctrl_set. By default axgbe driver flow control is disabled. Adding dpdk flow control to set water high and low.
Signed-off-by Amaranath Somalapuram <[email protected]>
--- drivers/net/axgbe/axgbe_ethdev.c | 84 ++++++++++++++++++++++++++++++++ drivers/net/axgbe/axgbe_ethdev.h | 10 ++++ 2 files changed, 94 insertions(+)
drivers/net/axgbe/axgbe_ethdev.c +84 -0
@@ -47,6 +47,10 @@ axgbe_dev_xstats_get_names_by_id(struct rte_eth_dev *dev,static int axgbe_dev_xstats_reset (struct rte_eth_dev *dev);static int axgbe_dev_info_get (struct rte_eth_dev *dev,struct rte_eth_dev_info *dev_info); +static int axgbe_flow_ctrl_get (struct rte_eth_dev *dev, +struct rte_eth_fc_conf *fc_conf); +static int axgbe_flow_ctrl_set (struct rte_eth_dev *dev, +struct rte_eth_fc_conf *fc_conf);struct axgbe_xstats {char name[RTE_ETH_XSTATS_NAME_SIZE ];
@@ -174,6 +178,8 @@ static const struct eth_dev_ops axgbe_eth_dev_ops = { .rx_queue_release = axgbe_dev_rx_queue_release, .tx_queue_setup = axgbe_dev_tx_queue_setup, .tx_queue_release = axgbe_dev_tx_queue_release, + .flow_ctrl_get = axgbe_flow_ctrl_get, + .flow_ctrl_set = axgbe_flow_ctrl_set, };static int axgbe_phy_reset (struct axgbe_port *pdata)
@@ -843,6 +849,84 @@ axgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)return 0 ; } +static int +axgbe_flow_ctrl_get (struct rte_eth_dev *dev,struct rte_eth_fc_conf *fc_conf) +{ +struct axgbe_port *pdata = dev->data->dev_private; +struct xgbe_fc_info fc = pdata->fc; +unsigned int reg, reg_val =0 ; + + reg =MAC_Q0TFCR ; + reg_val =AXGMAC_IOREAD (pdata, reg); + fc.low_water[0 ] =AXGMAC_MTL_IOREAD_BITS (pdata,0 ,MTL_Q_RQFCR ,RFA ); + fc.high_water[0 ] =AXGMAC_MTL_IOREAD_BITS (pdata,0 ,MTL_Q_RQFCR ,RFD ); + fc.pause_time[0 ] =AXGMAC_GET_BITS (reg_val,MAC_Q0TFCR ,PT ); + fc.autoneg = pdata->pause_autoneg; + +if (pdata->rx_pause && pdata->tx_pause) + fc.mode =RTE_FC_FULL ; +else if (pdata->rx_pause) + fc.mode =RTE_FC_RX_PAUSE ; +else if (pdata->tx_pause) + fc.mode =RTE_FC_TX_PAUSE ; +else + fc.mode =RTE_FC_NONE ; + + fc_conf->high_water = (1024 + (fc.low_water[0 ] <<9 )) /1024 ; + fc_conf->low_water = (1024 + (fc.high_water[0 ] <<9 )) /1024 ; + fc_conf->pause_time = fc.pause_time[0 ]; + fc_conf->send_xon = fc.send_xon; + fc_conf->mode = fc.mode; + +return 0 ; +} + +static int +axgbe_flow_ctrl_set (struct rte_eth_dev *dev,struct rte_eth_fc_conf *fc_conf) +{ +struct axgbe_port *pdata = dev->data->dev_private; +struct xgbe_fc_info fc = pdata->fc; +unsigned int reg, reg_val =0 ; + reg =MAC_Q0TFCR ; + + pdata->pause_autoneg = fc_conf->autoneg; + pdata->phy.pause_autoneg = pdata->pause_autoneg; + fc.send_xon = fc_conf->send_xon; +AXGMAC_MTL_IOWRITE_BITS (pdata,0 ,MTL_Q_RQFCR ,RFA , +AXGMAC_FLOW_CONTROL_VALUE (1024 * fc_conf->high_water)); +AXGMAC_MTL_IOWRITE_BITS (pdata,0 ,MTL_Q_RQFCR ,RFD , +AXGMAC_FLOW_CONTROL_VALUE (1024 * fc_conf->low_water)); +AXGMAC_SET_BITS (reg_val,MAC_Q0TFCR ,PT , fc_conf->pause_time); +AXGMAC_IOWRITE (pdata, reg, reg_val); + fc.mode = fc_conf->mode; + +if (fc.mode ==RTE_FC_FULL ) { + pdata->tx_pause =1 ; + pdata->rx_pause =1 ; + }else if (fc.mode ==RTE_FC_RX_PAUSE ) { + pdata->tx_pause =0 ; + pdata->rx_pause =1 ; + }else if (fc.mode ==RTE_FC_TX_PAUSE ) { + pdata->tx_pause =1 ; + pdata->rx_pause =0 ; + }else { + pdata->tx_pause =0 ; + pdata->rx_pause =0 ; + } + +if (pdata->tx_pause != (unsigned int )pdata->phy.tx_pause) + pdata->hw_if.config_tx_flow_control (pdata); + +if (pdata->rx_pause != (unsigned int )pdata->phy.rx_pause) + pdata->hw_if.config_rx_flow_control (pdata); + + pdata->hw_if.config_flow_control (pdata); + pdata->phy.tx_pause = pdata->tx_pause; + pdata->phy.rx_pause = pdata->rx_pause; + +return 0 ; +} +static void axgbe_get_all_hw_features (struct axgbe_port *pdata) {unsigned int mac_hfr0, mac_hfr1, mac_hfr2;
drivers/net/axgbe/axgbe_ethdev.h +10 -0
@@ -485,6 +485,15 @@ struct axgbe_mmc_stats {uint64_t rxwatchdogerror; }; +/* Flow control parameters */ +struct xgbe_fc_info { +uint32_t high_water[AXGBE_PRIORITY_QUEUES ]; +uint32_t low_water[AXGBE_PRIORITY_QUEUES ]; +uint16_t pause_time[AXGBE_PRIORITY_QUEUES ]; +uint16_t send_xon; +enum rte_eth_fc_mode mode; +uint8_t autoneg; +};/* * Structure to store private data for each port. */
@@ -625,6 +634,7 @@ struct axgbe_port {uint32_t rx_csum_enable;struct axgbe_mmc_stats mmc_stats; +struct xgbe_fc_info fc; };void axgbe_init_function_ptrs_dev (struct axgbe_hw_if *hw_if);
Signature · 1 line
2.17.1
PATCH v4 2/2 net/axgbe: support priority flow control API
From: Amaranath Somalapuram <[email protected]>
Adding API for priority_flow_ctrl_set.
Priority flow control to set water high and low,pause_time and priority.
Signed-off-by Amaranath Somalapuram <[email protected]>
--- drivers/net/axgbe/axgbe_ethdev.c | 94 ++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+)
drivers/net/axgbe/axgbe_ethdev.c +94 -0
@@ -51,6 +51,8 @@ static int axgbe_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf);static int axgbe_flow_ctrl_set (struct rte_eth_dev *dev,struct rte_eth_fc_conf *fc_conf); +static int axgbe_priority_flow_ctrl_set (struct rte_eth_dev *dev, +struct rte_eth_pfc_conf *pfc_conf);struct axgbe_xstats {char name[RTE_ETH_XSTATS_NAME_SIZE ];
@@ -180,6 +182,7 @@ static const struct eth_dev_ops axgbe_eth_dev_ops = { .tx_queue_release = axgbe_dev_tx_queue_release, .flow_ctrl_get = axgbe_flow_ctrl_get, .flow_ctrl_set = axgbe_flow_ctrl_set, + .priority_flow_ctrl_set = axgbe_priority_flow_ctrl_set, };static int axgbe_phy_reset (struct axgbe_port *pdata)
@@ -927,6 +930,97 @@ axgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)return 0 ; } +static int +axgbe_priority_flow_ctrl_set (struct rte_eth_dev *dev, +struct rte_eth_pfc_conf *pfc_conf) +{ +struct axgbe_port *pdata = dev->data->dev_private; +struct xgbe_fc_info fc = pdata->fc; +uint8_t tc_num; + + tc_num = pdata->pfc_map[pfc_conf->priority]; + +if (pfc_conf->priority >= pdata->hw_feat.tc_cnt) { +PMD_INIT_LOG (ERR ,"Max supported traffic class: %d\n" , + pdata->hw_feat.tc_cnt); +return -EINVAL ; + } + + pdata->pause_autoneg = pfc_conf->fc.autoneg; + pdata->phy.pause_autoneg = pdata->pause_autoneg; + fc.send_xon = pfc_conf->fc.send_xon; +AXGMAC_MTL_IOWRITE_BITS (pdata, tc_num,MTL_Q_RQFCR ,RFA , +AXGMAC_FLOW_CONTROL_VALUE (1024 * pfc_conf->fc.high_water)); +AXGMAC_MTL_IOWRITE_BITS (pdata, tc_num,MTL_Q_RQFCR ,RFD , +AXGMAC_FLOW_CONTROL_VALUE (1024 * pfc_conf->fc.low_water)); + +switch (tc_num) { +case 0 : +AXGMAC_IOWRITE_BITS (pdata,MTL_TCPM0R , +PSTC0 , pfc_conf->fc.pause_time); +break ; +case 1 : +AXGMAC_IOWRITE_BITS (pdata,MTL_TCPM0R , +PSTC1 , pfc_conf->fc.pause_time); +break ; +case 2 : +AXGMAC_IOWRITE_BITS (pdata,MTL_TCPM0R , +PSTC2 , pfc_conf->fc.pause_time); +break ; +case 3 : +AXGMAC_IOWRITE_BITS (pdata,MTL_TCPM0R , +PSTC3 , pfc_conf->fc.pause_time); +break ; +case 4 : +AXGMAC_IOWRITE_BITS (pdata,MTL_TCPM1R , +PSTC4 , pfc_conf->fc.pause_time); +break ; +case 5 : +AXGMAC_IOWRITE_BITS (pdata,MTL_TCPM1R , +PSTC5 , pfc_conf->fc.pause_time); +break ; +case 7 : +AXGMAC_IOWRITE_BITS (pdata,MTL_TCPM1R , +PSTC6 , pfc_conf->fc.pause_time); +break ; +case 6 : +AXGMAC_IOWRITE_BITS (pdata,MTL_TCPM1R , +PSTC7 , pfc_conf->fc.pause_time); +break ; + } + + fc.mode = pfc_conf->fc.mode; + +if (fc.mode ==RTE_FC_FULL ) { + pdata->tx_pause =1 ; + pdata->rx_pause =1 ; +AXGMAC_IOWRITE_BITS (pdata,MAC_RFCR ,PFCE ,1 ); + }else if (fc.mode ==RTE_FC_RX_PAUSE ) { + pdata->tx_pause =0 ; + pdata->rx_pause =1 ; +AXGMAC_IOWRITE_BITS (pdata,MAC_RFCR ,PFCE ,1 ); + }else if (fc.mode ==RTE_FC_TX_PAUSE ) { + pdata->tx_pause =1 ; + pdata->rx_pause =0 ; +AXGMAC_IOWRITE_BITS (pdata,MAC_RFCR ,PFCE ,0 ); + }else { + pdata->tx_pause =0 ; + pdata->rx_pause =0 ; +AXGMAC_IOWRITE_BITS (pdata,MAC_RFCR ,PFCE ,0 ); + } + +if (pdata->tx_pause != (unsigned int )pdata->phy.tx_pause) + pdata->hw_if.config_tx_flow_control (pdata); + +if (pdata->rx_pause != (unsigned int )pdata->phy.rx_pause) + pdata->hw_if.config_rx_flow_control (pdata); + pdata->hw_if.config_flow_control (pdata); + pdata->phy.tx_pause = pdata->tx_pause; + pdata->phy.rx_pause = pdata->rx_pause; + +return 0 ; +} +static void axgbe_get_all_hw_features (struct axgbe_port *pdata) {unsigned int mac_hfr0, mac_hfr1, mac_hfr2;
Signature · 1 line
2.17.1