diff options
author | Yi Zou <yi.zou@intel.com> | 2009-09-03 10:55:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-03 23:01:51 -0400 |
commit | 8de8b2e63490fe7e90128299983198d09d1679c9 (patch) | |
tree | 480782ed477329516f583a08d3ce6dd0eac21d01 /drivers/net/ixgbe | |
parent | ae641bdc264a5998b7872622c86f0690a5b1c5b5 (diff) |
ixgbe: Add support for multiple Tx queues for FCoE in 82599
This patch adds support for multiple transmit queues to the Fiber Channel
over Ethernet (FCoE) feature found in 82599. Currently, FCoE has multiple
Rx queues available, along with a redirection table, that helps distribute
the I/O load across multiple CPUs based on the FC exchange ID. To make
this the most effective, we need to provide the same layout of transmit
queues to match receive.
Particularly, when Data Center Bridging (DCB) is enabled, the designated
traffic class for FCoE can have dedicated queues for just FCoE traffic,
while not affecting any other type of traffic flow.
Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ixgbe')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_dcb_nl.c | 37 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 43 |
2 files changed, 65 insertions, 15 deletions
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 47d9dde82a8a..a6bc1ef28f92 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #define BIT_PFC 0x02 | 36 | #define BIT_PFC 0x02 |
37 | #define BIT_PG_RX 0x04 | 37 | #define BIT_PG_RX 0x04 |
38 | #define BIT_PG_TX 0x08 | 38 | #define BIT_PG_TX 0x08 |
39 | #define BIT_APP_UPCHG 0x10 | ||
39 | #define BIT_RESETLINK 0x40 | 40 | #define BIT_RESETLINK 0x40 |
40 | #define BIT_LINKSPEED 0x80 | 41 | #define BIT_LINKSPEED 0x80 |
41 | 42 | ||
@@ -348,8 +349,14 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) | |||
348 | while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) | 349 | while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) |
349 | msleep(1); | 350 | msleep(1); |
350 | 351 | ||
351 | if (netif_running(netdev)) | 352 | if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { |
352 | ixgbe_down(adapter); | 353 | if (netif_running(netdev)) |
354 | netdev->netdev_ops->ndo_stop(netdev); | ||
355 | ixgbe_clear_interrupt_scheme(adapter); | ||
356 | } else { | ||
357 | if (netif_running(netdev)) | ||
358 | ixgbe_down(adapter); | ||
359 | } | ||
353 | } | 360 | } |
354 | 361 | ||
355 | ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, | 362 | ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, |
@@ -373,8 +380,14 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) | |||
373 | } | 380 | } |
374 | 381 | ||
375 | if (adapter->dcb_set_bitmap & BIT_RESETLINK) { | 382 | if (adapter->dcb_set_bitmap & BIT_RESETLINK) { |
376 | if (netif_running(netdev)) | 383 | if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { |
377 | ixgbe_up(adapter); | 384 | ixgbe_init_interrupt_scheme(adapter); |
385 | if (netif_running(netdev)) | ||
386 | netdev->netdev_ops->ndo_open(netdev); | ||
387 | } else { | ||
388 | if (netif_running(netdev)) | ||
389 | ixgbe_up(adapter); | ||
390 | } | ||
378 | ret = DCB_HW_CHG_RST; | 391 | ret = DCB_HW_CHG_RST; |
379 | } else if (adapter->dcb_set_bitmap & BIT_PFC) { | 392 | } else if (adapter->dcb_set_bitmap & BIT_PFC) { |
380 | if (adapter->hw.mac.type == ixgbe_mac_82598EB) | 393 | if (adapter->hw.mac.type == ixgbe_mac_82598EB) |
@@ -526,8 +539,20 @@ static u8 ixgbe_dcbnl_setapp(struct net_device *netdev, | |||
526 | switch (idtype) { | 539 | switch (idtype) { |
527 | case DCB_APP_IDTYPE_ETHTYPE: | 540 | case DCB_APP_IDTYPE_ETHTYPE: |
528 | #ifdef IXGBE_FCOE | 541 | #ifdef IXGBE_FCOE |
529 | if (id == ETH_P_FCOE) | 542 | if (id == ETH_P_FCOE) { |
530 | rval = ixgbe_fcoe_setapp(netdev_priv(netdev), up); | 543 | u8 tc; |
544 | struct ixgbe_adapter *adapter; | ||
545 | |||
546 | adapter = netdev_priv(netdev); | ||
547 | tc = adapter->fcoe.tc; | ||
548 | rval = ixgbe_fcoe_setapp(adapter, up); | ||
549 | if ((!rval) && (tc != adapter->fcoe.tc) && | ||
550 | (adapter->flags & IXGBE_FLAG_DCB_ENABLED) && | ||
551 | (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) { | ||
552 | adapter->dcb_set_bitmap |= BIT_APP_UPCHG; | ||
553 | adapter->dcb_set_bitmap |= BIT_RESETLINK; | ||
554 | } | ||
555 | } | ||
531 | #endif | 556 | #endif |
532 | break; | 557 | break; |
533 | case DCB_APP_IDTYPE_PORTNUM: | 558 | case DCB_APP_IDTYPE_PORTNUM: |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 4042d878670e..724754a64d03 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -3113,14 +3113,16 @@ static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter) | |||
3113 | 3113 | ||
3114 | f->indices = min((int)num_online_cpus(), f->indices); | 3114 | f->indices = min((int)num_online_cpus(), f->indices); |
3115 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { | 3115 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { |
3116 | adapter->num_rx_queues = 1; | ||
3117 | adapter->num_tx_queues = 1; | ||
3116 | #ifdef CONFIG_IXGBE_DCB | 3118 | #ifdef CONFIG_IXGBE_DCB |
3117 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { | 3119 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { |
3118 | DPRINTK(PROBE, INFO, "FCOE enabled with DCB \n"); | 3120 | DPRINTK(PROBE, INFO, "FCoE enabled with DCB \n"); |
3119 | ixgbe_set_dcb_queues(adapter); | 3121 | ixgbe_set_dcb_queues(adapter); |
3120 | } | 3122 | } |
3121 | #endif | 3123 | #endif |
3122 | if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { | 3124 | if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { |
3123 | DPRINTK(PROBE, INFO, "FCOE enabled with RSS \n"); | 3125 | DPRINTK(PROBE, INFO, "FCoE enabled with RSS \n"); |
3124 | if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || | 3126 | if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || |
3125 | (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) | 3127 | (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) |
3126 | ixgbe_set_fdir_queues(adapter); | 3128 | ixgbe_set_fdir_queues(adapter); |
@@ -3130,8 +3132,7 @@ static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter) | |||
3130 | /* adding FCoE rx rings to the end */ | 3132 | /* adding FCoE rx rings to the end */ |
3131 | f->mask = adapter->num_rx_queues; | 3133 | f->mask = adapter->num_rx_queues; |
3132 | adapter->num_rx_queues += f->indices; | 3134 | adapter->num_rx_queues += f->indices; |
3133 | if (adapter->num_tx_queues == 0) | 3135 | adapter->num_tx_queues += f->indices; |
3134 | adapter->num_tx_queues = f->indices; | ||
3135 | 3136 | ||
3136 | ret = true; | 3137 | ret = true; |
3137 | } | 3138 | } |
@@ -3371,15 +3372,36 @@ static bool inline ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter) | |||
3371 | */ | 3372 | */ |
3372 | static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter) | 3373 | static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter) |
3373 | { | 3374 | { |
3374 | int i, fcoe_i = 0; | 3375 | int i, fcoe_rx_i = 0, fcoe_tx_i = 0; |
3375 | bool ret = false; | 3376 | bool ret = false; |
3376 | struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE]; | 3377 | struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE]; |
3377 | 3378 | ||
3378 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { | 3379 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { |
3379 | #ifdef CONFIG_IXGBE_DCB | 3380 | #ifdef CONFIG_IXGBE_DCB |
3380 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { | 3381 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { |
3382 | struct ixgbe_fcoe *fcoe = &adapter->fcoe; | ||
3383 | |||
3381 | ixgbe_cache_ring_dcb(adapter); | 3384 | ixgbe_cache_ring_dcb(adapter); |
3382 | fcoe_i = adapter->rx_ring[0].reg_idx + 1; | 3385 | /* find out queues in TC for FCoE */ |
3386 | fcoe_rx_i = adapter->rx_ring[fcoe->tc].reg_idx + 1; | ||
3387 | fcoe_tx_i = adapter->tx_ring[fcoe->tc].reg_idx + 1; | ||
3388 | /* | ||
3389 | * In 82599, the number of Tx queues for each traffic | ||
3390 | * class for both 8-TC and 4-TC modes are: | ||
3391 | * TCs : TC0 TC1 TC2 TC3 TC4 TC5 TC6 TC7 | ||
3392 | * 8 TCs: 32 32 16 16 8 8 8 8 | ||
3393 | * 4 TCs: 64 64 32 32 | ||
3394 | * We have max 8 queues for FCoE, where 8 the is | ||
3395 | * FCoE redirection table size. If TC for FCoE is | ||
3396 | * less than or equal to TC3, we have enough queues | ||
3397 | * to add max of 8 queues for FCoE, so we start FCoE | ||
3398 | * tx descriptor from the next one, i.e., reg_idx + 1. | ||
3399 | * If TC for FCoE is above TC3, implying 8 TC mode, | ||
3400 | * and we need 8 for FCoE, we have to take all queues | ||
3401 | * in that traffic class for FCoE. | ||
3402 | */ | ||
3403 | if ((f->indices == IXGBE_FCRETA_SIZE) && (fcoe->tc > 3)) | ||
3404 | fcoe_tx_i--; | ||
3383 | } | 3405 | } |
3384 | #endif /* CONFIG_IXGBE_DCB */ | 3406 | #endif /* CONFIG_IXGBE_DCB */ |
3385 | if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { | 3407 | if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { |
@@ -3389,10 +3411,13 @@ static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter) | |||
3389 | else | 3411 | else |
3390 | ixgbe_cache_ring_rss(adapter); | 3412 | ixgbe_cache_ring_rss(adapter); |
3391 | 3413 | ||
3392 | fcoe_i = f->mask; | 3414 | fcoe_rx_i = f->mask; |
3415 | fcoe_tx_i = f->mask; | ||
3416 | } | ||
3417 | for (i = 0; i < f->indices; i++, fcoe_rx_i++, fcoe_tx_i++) { | ||
3418 | adapter->rx_ring[f->mask + i].reg_idx = fcoe_rx_i; | ||
3419 | adapter->tx_ring[f->mask + i].reg_idx = fcoe_tx_i; | ||
3393 | } | 3420 | } |
3394 | for (i = 0; i < f->indices; i++, fcoe_i++) | ||
3395 | adapter->rx_ring[f->mask + i].reg_idx = fcoe_i; | ||
3396 | ret = true; | 3421 | ret = true; |
3397 | } | 3422 | } |
3398 | return ret; | 3423 | return ret; |