Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ixgbe: Don't reset the hardware when switching between LFC and PFC

When running in DCB mode, switching between link flow control and priority
flow control shouldn't need to reset the hardware. This removes that
reset.

This also extends the set_all() dcbnl callback to return a value indicating
that the HW config changed, however a reset was not required.

Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Peter P Waskiewicz Jr and committed by
David S. Miller
62551d3e 8756924c

+49 -17
+49 -17
drivers/net/ixgbe/ixgbe_dcb_nl.c
··· 28 28 29 29 #include "ixgbe.h" 30 30 #include <linux/dcbnl.h> 31 + #include "ixgbe_dcb_82598.h" 32 + #include "ixgbe_dcb_82599.h" 31 33 32 34 /* Callbacks for DCB netlink in the kernel */ 33 35 #define BIT_DCB_MODE 0x01 34 36 #define BIT_PFC 0x02 35 37 #define BIT_PG_RX 0x04 36 38 #define BIT_PG_TX 0x08 37 - #define BIT_BCN 0x10 39 + #define BIT_RESETLINK 0x40 38 40 #define BIT_LINKSPEED 0x80 41 + 42 + /* Responses for the DCB_C_SET_ALL command */ 43 + #define DCB_HW_CHG_RST 0 /* DCB configuration changed with reset */ 44 + #define DCB_NO_HW_CHG 1 /* DCB configuration did not change */ 45 + #define DCB_HW_CHG 2 /* DCB configuration changed, no reset */ 39 46 40 47 int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg, 41 48 struct ixgbe_dcb_config *dst_dcb_cfg, int tc_max) ··· 202 195 (adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent != 203 196 adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent) || 204 197 (adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap != 205 - adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap)) 198 + adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap)) { 206 199 adapter->dcb_set_bitmap |= BIT_PG_TX; 200 + adapter->dcb_set_bitmap |= BIT_RESETLINK; 201 + } 207 202 } 208 203 209 204 static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, ··· 216 207 adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct; 217 208 218 209 if (adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] != 219 - adapter->dcb_cfg.bw_percentage[0][bwg_id]) 210 + adapter->dcb_cfg.bw_percentage[0][bwg_id]) { 220 211 adapter->dcb_set_bitmap |= BIT_PG_RX; 212 + adapter->dcb_set_bitmap |= BIT_RESETLINK; 213 + } 221 214 } 222 215 223 216 static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc, ··· 246 235 (adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent != 247 236 adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent) || 248 237 (adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap != 249 - adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap)) 238 + adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap)) { 250 239 adapter->dcb_set_bitmap |= BIT_PG_RX; 240 + adapter->dcb_set_bitmap |= BIT_RESETLINK; 241 + } 251 242 } 252 243 253 244 static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, ··· 260 247 adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct; 261 248 262 249 if (adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] != 263 - adapter->dcb_cfg.bw_percentage[1][bwg_id]) 250 + adapter->dcb_cfg.bw_percentage[1][bwg_id]) { 264 251 adapter->dcb_set_bitmap |= BIT_PG_RX; 252 + adapter->dcb_set_bitmap |= BIT_RESETLINK; 253 + } 265 254 } 266 255 267 256 static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, ··· 332 317 struct ixgbe_adapter *adapter = netdev_priv(netdev); 333 318 int ret; 334 319 335 - adapter->dcb_set_bitmap &= ~BIT_BCN; /* no set for BCN */ 336 320 if (!adapter->dcb_set_bitmap) 337 - return 1; 321 + return DCB_NO_HW_CHG; 338 322 339 - while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) 340 - msleep(1); 323 + /* 324 + * Only take down the adapter if the configuration change 325 + * requires a reset. 326 + */ 327 + if (adapter->dcb_set_bitmap & BIT_RESETLINK) { 328 + while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) 329 + msleep(1); 341 330 342 - if (netif_running(netdev)) 343 - ixgbe_down(adapter); 331 + if (netif_running(netdev)) 332 + ixgbe_down(adapter); 333 + } 344 334 345 335 ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, 346 336 adapter->ring_feature[RING_F_DCB].indices); 347 337 if (ret) { 348 - clear_bit(__IXGBE_RESETTING, &adapter->state); 349 - return ret; 338 + if (adapter->dcb_set_bitmap & BIT_RESETLINK) 339 + clear_bit(__IXGBE_RESETTING, &adapter->state); 340 + return DCB_NO_HW_CHG; 350 341 } 351 342 352 343 if (adapter->dcb_cfg.pfc_mode_enable) { ··· 367 346 adapter->hw.fc.requested_mode = ixgbe_fc_none; 368 347 } 369 348 370 - if (netif_running(netdev)) 371 - ixgbe_up(adapter); 372 - 349 + if (adapter->dcb_set_bitmap & BIT_RESETLINK) { 350 + if (netif_running(netdev)) 351 + ixgbe_up(adapter); 352 + ret = DCB_HW_CHG_RST; 353 + } else if (adapter->dcb_set_bitmap & BIT_PFC) { 354 + if (adapter->hw.mac.type == ixgbe_mac_82598EB) 355 + ixgbe_dcb_config_pfc_82598(&adapter->hw, 356 + &adapter->dcb_cfg); 357 + else if (adapter->hw.mac.type == ixgbe_mac_82599EB) 358 + ixgbe_dcb_config_pfc_82599(&adapter->hw, 359 + &adapter->dcb_cfg); 360 + ret = DCB_HW_CHG; 361 + } 373 362 if (adapter->dcb_cfg.pfc_mode_enable) 374 363 adapter->hw.fc.current_mode = ixgbe_fc_pfc; 375 364 365 + if (adapter->dcb_set_bitmap & BIT_RESETLINK) 366 + clear_bit(__IXGBE_RESETTING, &adapter->state); 376 367 adapter->dcb_set_bitmap = 0x00; 377 - clear_bit(__IXGBE_RESETTING, &adapter->state); 378 368 return ret; 379 369 } 380 370