From 273dcde1c3e3582d39f4a0916febca7dfd518de9 Mon Sep 17 00:00:00 2001 From: Qi Zhang Date: Thu, 10 Aug 2017 18:48:07 +0800 Subject: [PATCH] net/i40e: fix flow control watermark mismatch Flow control watermark is not read out correctly, that may cause an application who not intend to change watermark but does change it with a rte_eth_dev_flow_ctrl_set call right after rte_eth_dev_flow_ctrl_get. The idea fix is, during init, the watermark is set with default value, so it is not necessary to read out from hw register during flow_ctl_get, But due to I40E_GLRPB_GHW limitation, it is shared by different ports on the same device, it is possible the value is changed on another port, but local variable not sync, so we have to read out register every flow_ctl_get. Fixes: f53577f06925 ("i40e: support flow control") Cc: stable@dpdk.org Signed-off-by: Qi Zhang Acked-by: Kevin Traynor --- drivers/net/i40e/i40e_ethdev.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index f12aefa5d7..d76ef785be 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -86,12 +86,6 @@ /* Flow control default timer */ #define I40E_DEFAULT_PAUSE_TIME 0xFFFFU -/* Flow control default high water */ -#define I40E_DEFAULT_HIGH_WATER (0x1C40/1024) - -/* Flow control default low water */ -#define I40E_DEFAULT_LOW_WATER (0x1A40/1024) - /* Flow control enable fwd bit */ #define I40E_PRTMAC_FWD_CTRL 0x00000001 @@ -101,6 +95,12 @@ /* Kilobytes shift */ #define I40E_KILOSHIFT 10 +/* Flow control default high water */ +#define I40E_DEFAULT_HIGH_WATER (0xF2000 >> I40E_KILOSHIFT) + +/* Flow control default low water */ +#define I40E_DEFAULT_LOW_WATER (0xF2000 >> I40E_KILOSHIFT) + /* Receive Average Packet Size in Byte*/ #define I40E_PACKET_AVERAGE_SIZE 128 @@ -3253,6 +3253,13 @@ i40e_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); fc_conf->pause_time = pf->fc_conf.pause_time; + + /* read out from register, in case they are modified by other port */ + pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS] = + I40E_READ_REG(hw, I40E_GLRPB_GHW) >> I40E_KILOSHIFT; + pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS] = + I40E_READ_REG(hw, I40E_GLRPB_GLW) >> I40E_KILOSHIFT; + fc_conf->high_water = pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]; fc_conf->low_water = pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]; -- 2.20.1