diff options
| author | John Fastabend <john.r.fastabend@intel.com> | 2010-10-27 20:59:57 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-10-28 13:19:00 -0400 |
| commit | 9806307a1c5a2a79e268ae4e78b437d38c8adf7f (patch) | |
| tree | 1a4ceada09e85a3cd9083790c6b16a16e99bb928 | |
| parent | affa9dfb04b7e2e3a0b0e6d844ea0c9ed97505f9 (diff) | |
ixgbe: DCB, fix TX hang occurring in stress condition with PFC
The DCB credits refill quantum _must_ be greater than half the max
packet size. This is needed to guarantee that TX DMA operations
are not attempted during a pause state. Additionally, the min IFG
must be set correctly for DCB mode. If a DMA operation is
requested unexpectedly during the pause state the HW data
store may be corrupted leading to a DMA hang. The DMA hang
requires a reset to correct. This fixes the HW configuration
to avoid this condition.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/ixgbe/ixgbe_dcb.c | 39 | ||||
| -rw-r--r-- | drivers/net/ixgbe/ixgbe_dcb.h | 5 | ||||
| -rw-r--r-- | drivers/net/ixgbe/ixgbe_dcb_82599.c | 5 | ||||
| -rw-r--r-- | drivers/net/ixgbe/ixgbe_dcb_82599.h | 3 | ||||
| -rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 12 |
5 files changed, 54 insertions, 10 deletions
diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index 8bb9ddb6dffe..0d44c6470ca3 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c | |||
| @@ -43,9 +43,12 @@ | |||
| 43 | * ixgbe_dcb_check_config(). | 43 | * ixgbe_dcb_check_config(). |
| 44 | */ | 44 | */ |
| 45 | s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config, | 45 | s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config, |
| 46 | u8 direction) | 46 | int max_frame, u8 direction) |
| 47 | { | 47 | { |
| 48 | struct tc_bw_alloc *p; | 48 | struct tc_bw_alloc *p; |
| 49 | int min_credit; | ||
| 50 | int min_multiplier; | ||
| 51 | int min_percent = 100; | ||
| 49 | s32 ret_val = 0; | 52 | s32 ret_val = 0; |
| 50 | /* Initialization values default for Tx settings */ | 53 | /* Initialization values default for Tx settings */ |
| 51 | u32 credit_refill = 0; | 54 | u32 credit_refill = 0; |
| @@ -59,6 +62,31 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config, | |||
| 59 | goto out; | 62 | goto out; |
| 60 | } | 63 | } |
| 61 | 64 | ||
| 65 | min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) / | ||
| 66 | DCB_CREDIT_QUANTUM; | ||
| 67 | |||
| 68 | /* Find smallest link percentage */ | ||
| 69 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | ||
| 70 | p = &dcb_config->tc_config[i].path[direction]; | ||
| 71 | bw_percent = dcb_config->bw_percentage[direction][p->bwg_id]; | ||
| 72 | link_percentage = p->bwg_percent; | ||
| 73 | |||
| 74 | link_percentage = (link_percentage * bw_percent) / 100; | ||
| 75 | |||
| 76 | if (link_percentage && link_percentage < min_percent) | ||
| 77 | min_percent = link_percentage; | ||
| 78 | } | ||
| 79 | |||
| 80 | /* | ||
| 81 | * The ratio between traffic classes will control the bandwidth | ||
| 82 | * percentages seen on the wire. To calculate this ratio we use | ||
| 83 | * a multiplier. It is required that the refill credits must be | ||
| 84 | * larger than the max frame size so here we find the smallest | ||
| 85 | * multiplier that will allow all bandwidth percentages to be | ||
| 86 | * greater than the max frame size. | ||
| 87 | */ | ||
| 88 | min_multiplier = (min_credit / min_percent) + 1; | ||
| 89 | |||
| 62 | /* Find out the link percentage for each TC first */ | 90 | /* Find out the link percentage for each TC first */ |
| 63 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | 91 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { |
| 64 | p = &dcb_config->tc_config[i].path[direction]; | 92 | p = &dcb_config->tc_config[i].path[direction]; |
| @@ -73,8 +101,9 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config, | |||
| 73 | /* Save link_percentage for reference */ | 101 | /* Save link_percentage for reference */ |
| 74 | p->link_percent = (u8)link_percentage; | 102 | p->link_percent = (u8)link_percentage; |
| 75 | 103 | ||
| 76 | /* Calculate credit refill and save it */ | 104 | /* Calculate credit refill ratio using multiplier */ |
| 77 | credit_refill = link_percentage * MINIMUM_CREDIT_REFILL; | 105 | credit_refill = min(link_percentage * min_multiplier, |
| 106 | MAX_CREDIT_REFILL); | ||
| 78 | p->data_credits_refill = (u16)credit_refill; | 107 | p->data_credits_refill = (u16)credit_refill; |
| 79 | 108 | ||
| 80 | /* Calculate maximum credit for the TC */ | 109 | /* Calculate maximum credit for the TC */ |
| @@ -85,8 +114,8 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config, | |||
| 85 | * of a TC is too small, the maximum credit may not be | 114 | * of a TC is too small, the maximum credit may not be |
| 86 | * enough to send out a jumbo frame in data plane arbitration. | 115 | * enough to send out a jumbo frame in data plane arbitration. |
| 87 | */ | 116 | */ |
| 88 | if (credit_max && (credit_max < MINIMUM_CREDIT_FOR_JUMBO)) | 117 | if (credit_max && (credit_max < min_credit)) |
| 89 | credit_max = MINIMUM_CREDIT_FOR_JUMBO; | 118 | credit_max = min_credit; |
| 90 | 119 | ||
| 91 | if (direction == DCB_TX_CONFIG) { | 120 | if (direction == DCB_TX_CONFIG) { |
| 92 | /* | 121 | /* |
diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h index eb1059f09da0..0208a87b129e 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.h +++ b/drivers/net/ixgbe/ixgbe_dcb.h | |||
| @@ -150,15 +150,14 @@ struct ixgbe_dcb_config { | |||
| 150 | /* DCB driver APIs */ | 150 | /* DCB driver APIs */ |
| 151 | 151 | ||
| 152 | /* DCB credits calculation */ | 152 | /* DCB credits calculation */ |
| 153 | s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *, u8); | 153 | s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *, int, u8); |
| 154 | 154 | ||
| 155 | /* DCB hw initialization */ | 155 | /* DCB hw initialization */ |
| 156 | s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *); | 156 | s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *); |
| 157 | 157 | ||
| 158 | /* DCB definitions for credit calculation */ | 158 | /* DCB definitions for credit calculation */ |
| 159 | #define DCB_CREDIT_QUANTUM 64 /* DCB Quantum */ | ||
| 159 | #define MAX_CREDIT_REFILL 511 /* 0x1FF * 64B = 32704B */ | 160 | #define MAX_CREDIT_REFILL 511 /* 0x1FF * 64B = 32704B */ |
| 160 | #define MINIMUM_CREDIT_REFILL 5 /* 5*64B = 320B */ | ||
| 161 | #define MINIMUM_CREDIT_FOR_JUMBO 145 /* 145= UpperBound((9*1024+54)/64B) for 9KB jumbo frame */ | ||
| 162 | #define DCB_MAX_TSO_SIZE (32*1024) /* MAX TSO packet size supported in DCB mode */ | 161 | #define DCB_MAX_TSO_SIZE (32*1024) /* MAX TSO packet size supported in DCB mode */ |
| 163 | #define MINIMUM_CREDIT_FOR_TSO (DCB_MAX_TSO_SIZE/64 + 1) /* 513 for 32KB TSO packet */ | 162 | #define MINIMUM_CREDIT_FOR_TSO (DCB_MAX_TSO_SIZE/64 + 1) /* 513 for 32KB TSO packet */ |
| 164 | #define MAX_CREDIT 4095 /* Maximum credit supported: 256KB * 1204 / 64B */ | 163 | #define MAX_CREDIT 4095 /* Maximum credit supported: 256KB * 1204 / 64B */ |
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index 67c219f86c3a..05f224715073 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c | |||
| @@ -397,6 +397,11 @@ static s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw) | |||
| 397 | reg &= ~IXGBE_RTTDCS_ARBDIS; | 397 | reg &= ~IXGBE_RTTDCS_ARBDIS; |
| 398 | IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg); | 398 | IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg); |
| 399 | 399 | ||
| 400 | /* Enable Security TX Buffer IFG for DCB */ | ||
| 401 | reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG); | ||
| 402 | reg |= IXGBE_SECTX_DCB; | ||
| 403 | IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg); | ||
| 404 | |||
| 400 | return 0; | 405 | return 0; |
| 401 | } | 406 | } |
| 402 | 407 | ||
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h index 18d7fbf6c292..3841649fb954 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h | |||
| @@ -95,6 +95,9 @@ | |||
| 95 | 95 | ||
| 96 | #define IXGBE_TXPBTHRESH_DCB 0xA /* THRESH value for DCB mode */ | 96 | #define IXGBE_TXPBTHRESH_DCB 0xA /* THRESH value for DCB mode */ |
| 97 | 97 | ||
| 98 | /* SECTXMINIFG DCB */ | ||
| 99 | #define IXGBE_SECTX_DCB 0x00001F00 /* DCB TX Buffer IFG */ | ||
| 100 | |||
| 98 | 101 | ||
| 99 | /* DCB hardware-specific driver APIs */ | 102 | /* DCB hardware-specific driver APIs */ |
| 100 | 103 | ||
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index f85631263af8..2bd3eb4ee5a1 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
| @@ -3347,6 +3347,7 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter) | |||
| 3347 | static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) | 3347 | static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) |
| 3348 | { | 3348 | { |
| 3349 | struct ixgbe_hw *hw = &adapter->hw; | 3349 | struct ixgbe_hw *hw = &adapter->hw; |
| 3350 | int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; | ||
| 3350 | u32 txdctl; | 3351 | u32 txdctl; |
| 3351 | int i, j; | 3352 | int i, j; |
| 3352 | 3353 | ||
| @@ -3359,8 +3360,15 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) | |||
| 3359 | if (hw->mac.type == ixgbe_mac_82598EB) | 3360 | if (hw->mac.type == ixgbe_mac_82598EB) |
| 3360 | netif_set_gso_max_size(adapter->netdev, 32768); | 3361 | netif_set_gso_max_size(adapter->netdev, 32768); |
| 3361 | 3362 | ||
| 3362 | ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_TX_CONFIG); | 3363 | #ifdef CONFIG_FCOE |
| 3363 | ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_RX_CONFIG); | 3364 | if (adapter->netdev->features & NETIF_F_FCOE_MTU) |
| 3365 | max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); | ||
| 3366 | #endif | ||
| 3367 | |||
| 3368 | ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, max_frame, | ||
| 3369 | DCB_TX_CONFIG); | ||
| 3370 | ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, max_frame, | ||
| 3371 | DCB_RX_CONFIG); | ||
| 3364 | 3372 | ||
| 3365 | /* reconfigure the hardware */ | 3373 | /* reconfigure the hardware */ |
| 3366 | ixgbe_dcb_hw_config(&adapter->hw, &adapter->dcb_cfg); | 3374 | ixgbe_dcb_hw_config(&adapter->hw, &adapter->dcb_cfg); |
