aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Keller <jacob.e.keller@intel.com>2014-04-04 22:35:52 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-04-23 02:07:11 -0400
commite5776620a7b7b2aacbc60ff1cdbeca6814ec8411 (patch)
treea77c54df3d1f9e45b803f100a297f9cb866e1145
parentfd0d192be6e814495aec91f357b5801afc3b6262 (diff)
ixgbe: convert low_water into an array
Since fc.high_water is an array, we should treat low_water as an array also. This allows the algorithm to output different values for different TCs, and then we can distinguish between them. In addition, this patch changes one path that didn't honor the return value from ixgbe_setup_fc. Reported-by: Aaron Salter <aaron.k.salter@intel.com> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c27
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_common.c35
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c22
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_type.h2
7 files changed, 57 insertions, 35 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
index 4c78ea8946c1..1c52e4753480 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -337,19 +337,25 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
337 int i; 337 int i;
338 bool link_up; 338 bool link_up;
339 339
340 /* 340 /* Validate the water mark configuration */
341 * Validate the water mark configuration for packet buffer 0. Zero 341 if (!hw->fc.pause_time) {
342 * water marks indicate that the packet buffer was not configured
343 * and the watermarks for packet buffer 0 should always be configured.
344 */
345 if (!hw->fc.low_water ||
346 !hw->fc.high_water[0] ||
347 !hw->fc.pause_time) {
348 hw_dbg(hw, "Invalid water mark configuration\n");
349 ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; 342 ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
350 goto out; 343 goto out;
351 } 344 }
352 345
346 /* Low water mark of zero causes XOFF floods */
347 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
348 if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
349 hw->fc.high_water[i]) {
350 if (!hw->fc.low_water[i] ||
351 hw->fc.low_water[i] >= hw->fc.high_water[i]) {
352 hw_dbg(hw, "Invalid water mark configuration\n");
353 ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
354 goto out;
355 }
356 }
357 }
358
353 /* 359 /*
354 * On 82598 having Rx FC on causes resets while doing 1G 360 * On 82598 having Rx FC on causes resets while doing 1G
355 * so if it's on turn it off once we know link_speed. For 361 * so if it's on turn it off once we know link_speed. For
@@ -432,12 +438,11 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
432 IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg); 438 IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
433 IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg); 439 IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
434 440
435 fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
436
437 /* Set up and enable Rx high/low water mark thresholds, enable XON. */ 441 /* Set up and enable Rx high/low water mark thresholds, enable XON. */
438 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 442 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
439 if ((hw->fc.current_mode & ixgbe_fc_tx_pause) && 443 if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
440 hw->fc.high_water[i]) { 444 hw->fc.high_water[i]) {
445 fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
441 fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; 446 fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
442 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl); 447 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
443 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), fcrth); 448 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), fcrth);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 24fba39e194e..6cc148b7c132 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -271,6 +271,7 @@ out:
271 **/ 271 **/
272s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) 272s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
273{ 273{
274 s32 ret_val;
274 u32 ctrl_ext; 275 u32 ctrl_ext;
275 276
276 /* Set the media type */ 277 /* Set the media type */
@@ -292,12 +293,15 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
292 IXGBE_WRITE_FLUSH(hw); 293 IXGBE_WRITE_FLUSH(hw);
293 294
294 /* Setup flow control */ 295 /* Setup flow control */
295 ixgbe_setup_fc(hw); 296 ret_val = ixgbe_setup_fc(hw);
297 if (!ret_val)
298 goto out;
296 299
297 /* Clear adapter stopped flag */ 300 /* Clear adapter stopped flag */
298 hw->adapter_stopped = false; 301 hw->adapter_stopped = false;
299 302
300 return 0; 303out:
304 return ret_val;
301} 305}
302 306
303/** 307/**
@@ -2106,19 +2110,25 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
2106 u32 fcrtl, fcrth; 2110 u32 fcrtl, fcrth;
2107 int i; 2111 int i;
2108 2112
2109 /* 2113 /* Validate the water mark configuration. */
2110 * Validate the water mark configuration for packet buffer 0. Zero 2114 if (!hw->fc.pause_time) {
2111 * water marks indicate that the packet buffer was not configured
2112 * and the watermarks for packet buffer 0 should always be configured.
2113 */
2114 if (!hw->fc.low_water ||
2115 !hw->fc.high_water[0] ||
2116 !hw->fc.pause_time) {
2117 hw_dbg(hw, "Invalid water mark configuration\n");
2118 ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; 2115 ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
2119 goto out; 2116 goto out;
2120 } 2117 }
2121 2118
2119 /* Low water mark of zero causes XOFF floods */
2120 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
2121 if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
2122 hw->fc.high_water[i]) {
2123 if (!hw->fc.low_water[i] ||
2124 hw->fc.low_water[i] >= hw->fc.high_water[i]) {
2125 hw_dbg(hw, "Invalid water mark configuration\n");
2126 ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
2127 goto out;
2128 }
2129 }
2130 }
2131
2122 /* Negotiate the fc mode to use */ 2132 /* Negotiate the fc mode to use */
2123 ixgbe_fc_autoneg(hw); 2133 ixgbe_fc_autoneg(hw);
2124 2134
@@ -2181,12 +2191,11 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
2181 IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg); 2191 IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
2182 IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg); 2192 IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
2183 2193
2184 fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
2185
2186 /* Set up and enable Rx high/low water mark thresholds, enable XON. */ 2194 /* Set up and enable Rx high/low water mark thresholds, enable XON. */
2187 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 2195 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
2188 if ((hw->fc.current_mode & ixgbe_fc_tx_pause) && 2196 if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
2189 hw->fc.high_water[i]) { 2197 hw->fc.high_water[i]) {
2198 fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
2190 IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl); 2199 IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
2191 fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; 2200 fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
2192 } else { 2201 } else {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
index 7a77f37a7cbc..d3ba63f9ad37 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
@@ -208,7 +208,6 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
208 208
209 IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); 209 IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
210 210
211 fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
212 /* Configure PFC Tx thresholds per TC */ 211 /* Configure PFC Tx thresholds per TC */
213 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 212 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
214 if (!(pfc_en & (1 << i))) { 213 if (!(pfc_en & (1 << i))) {
@@ -217,6 +216,7 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
217 continue; 216 continue;
218 } 217 }
219 218
219 fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
220 reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; 220 reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
221 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl); 221 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
222 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg); 222 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
index bdb99b3b0f30..3b932fe64ab6 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
@@ -242,7 +242,6 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc)
242 max_tc = prio_tc[i]; 242 max_tc = prio_tc[i];
243 } 243 }
244 244
245 fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
246 245
247 /* Configure PFC Tx thresholds per TC */ 246 /* Configure PFC Tx thresholds per TC */
248 for (i = 0; i <= max_tc; i++) { 247 for (i = 0; i <= max_tc; i++) {
@@ -257,6 +256,7 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc)
257 256
258 if (enabled) { 257 if (enabled) {
259 reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; 258 reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
259 fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
260 IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl); 260 IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
261 } else { 261 } else {
262 reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32; 262 reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
index b16cc786750d..0772b7730fce 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
@@ -81,9 +81,7 @@ struct ixgbe_fcoe {
81 void *extra_ddp_buffer; 81 void *extra_ddp_buffer;
82 dma_addr_t extra_ddp_buffer_dma; 82 dma_addr_t extra_ddp_buffer_dma;
83 unsigned long mode; 83 unsigned long mode;
84#ifdef CONFIG_IXGBE_DCB
85 u8 up; 84 u8 up;
86#endif
87}; 85};
88 86
89#endif /* _IXGBE_FCOE_H */ 87#endif /* _IXGBE_FCOE_H */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index c4c526b7f99f..147efec3e002 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -4100,8 +4100,8 @@ static int ixgbe_hpbthresh(struct ixgbe_adapter *adapter, int pb)
4100 (tc < IXGBE_FCOE_JUMBO_FRAME_SIZE) && 4100 (tc < IXGBE_FCOE_JUMBO_FRAME_SIZE) &&
4101 (pb == ixgbe_fcoe_get_tc(adapter))) 4101 (pb == ixgbe_fcoe_get_tc(adapter)))
4102 tc = IXGBE_FCOE_JUMBO_FRAME_SIZE; 4102 tc = IXGBE_FCOE_JUMBO_FRAME_SIZE;
4103
4104#endif 4103#endif
4104
4105 /* Calculate delay value for device */ 4105 /* Calculate delay value for device */
4106 switch (hw->mac.type) { 4106 switch (hw->mac.type) {
4107 case ixgbe_mac_X540: 4107 case ixgbe_mac_X540:
@@ -4142,7 +4142,7 @@ static int ixgbe_hpbthresh(struct ixgbe_adapter *adapter, int pb)
4142 * @adapter: board private structure to calculate for 4142 * @adapter: board private structure to calculate for
4143 * @pb: packet buffer to calculate 4143 * @pb: packet buffer to calculate
4144 */ 4144 */
4145static int ixgbe_lpbthresh(struct ixgbe_adapter *adapter) 4145static int ixgbe_lpbthresh(struct ixgbe_adapter *adapter, int pb)
4146{ 4146{
4147 struct ixgbe_hw *hw = &adapter->hw; 4147 struct ixgbe_hw *hw = &adapter->hw;
4148 struct net_device *dev = adapter->netdev; 4148 struct net_device *dev = adapter->netdev;
@@ -4152,6 +4152,14 @@ static int ixgbe_lpbthresh(struct ixgbe_adapter *adapter)
4152 /* Calculate max LAN frame size */ 4152 /* Calculate max LAN frame size */
4153 tc = dev->mtu + ETH_HLEN + ETH_FCS_LEN; 4153 tc = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
4154 4154
4155#ifdef IXGBE_FCOE
4156 /* FCoE traffic class uses FCOE jumbo frames */
4157 if ((dev->features & NETIF_F_FCOE_MTU) &&
4158 (tc < IXGBE_FCOE_JUMBO_FRAME_SIZE) &&
4159 (pb == netdev_get_prio_tc_map(dev, adapter->fcoe.up)))
4160 tc = IXGBE_FCOE_JUMBO_FRAME_SIZE;
4161#endif
4162
4155 /* Calculate delay value for device */ 4163 /* Calculate delay value for device */
4156 switch (hw->mac.type) { 4164 switch (hw->mac.type) {
4157 case ixgbe_mac_X540: 4165 case ixgbe_mac_X540:
@@ -4178,15 +4186,17 @@ static void ixgbe_pbthresh_setup(struct ixgbe_adapter *adapter)
4178 if (!num_tc) 4186 if (!num_tc)
4179 num_tc = 1; 4187 num_tc = 1;
4180 4188
4181 hw->fc.low_water = ixgbe_lpbthresh(adapter);
4182
4183 for (i = 0; i < num_tc; i++) { 4189 for (i = 0; i < num_tc; i++) {
4184 hw->fc.high_water[i] = ixgbe_hpbthresh(adapter, i); 4190 hw->fc.high_water[i] = ixgbe_hpbthresh(adapter, i);
4191 hw->fc.low_water[i] = ixgbe_lpbthresh(adapter, i);
4185 4192
4186 /* Low water marks must not be larger than high water marks */ 4193 /* Low water marks must not be larger than high water marks */
4187 if (hw->fc.low_water > hw->fc.high_water[i]) 4194 if (hw->fc.low_water[i] > hw->fc.high_water[i])
4188 hw->fc.low_water = 0; 4195 hw->fc.low_water[i] = 0;
4189 } 4196 }
4197
4198 for (; i < MAX_TRAFFIC_CLASS; i++)
4199 hw->fc.high_water[i] = 0;
4190} 4200}
4191 4201
4192static void ixgbe_configure_pb(struct ixgbe_adapter *adapter) 4202static void ixgbe_configure_pb(struct ixgbe_adapter *adapter)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 8a6ff2423f07..551d6089a4d3 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -2746,7 +2746,7 @@ struct ixgbe_bus_info {
2746/* Flow control parameters */ 2746/* Flow control parameters */
2747struct ixgbe_fc_info { 2747struct ixgbe_fc_info {
2748 u32 high_water[MAX_TRAFFIC_CLASS]; /* Flow Control High-water */ 2748 u32 high_water[MAX_TRAFFIC_CLASS]; /* Flow Control High-water */
2749 u32 low_water; /* Flow Control Low-water */ 2749 u32 low_water[MAX_TRAFFIC_CLASS]; /* Flow Control Low-water */
2750 u16 pause_time; /* Flow Control Pause timer */ 2750 u16 pause_time; /* Flow Control Pause timer */
2751 bool send_xon; /* Flow control send XON */ 2751 bool send_xon; /* Flow control send XON */
2752 bool strict_ieee; /* Strict IEEE mode */ 2752 bool strict_ieee; /* Strict IEEE mode */