diff options
author | Edward Cree <ecree@solarflare.com> | 2013-09-27 13:52:49 -0400 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2013-10-04 18:31:51 -0400 |
commit | 4bae913bd372aab90fdbd91e7e5fb841a2a0dc15 (patch) | |
tree | 182cf2705eb6349cb1fea0cc69dd2cd446b0be64 /drivers/net/ethernet/sfc | |
parent | 87648cc925222f16c3bd119af8ae8e8fb2f3fe1d (diff) |
sfc: Refactor EF10 stat mask code to allow for more conditional stats
Previously, efx_ef10_stat_mask returned a static const unsigned long[], which
meant that each possible mask had to be declared statically with
STAT_MASK_BITMAP. Since adding a condition would double the size of the
decision tree, we now create the bitmask dynamically.
To do this, we have two functions efx_ef10_raw_stat_mask, which returns a u64,
and efx_ef10_get_stat_mask, which fills in an unsigned long * argument.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet/sfc')
-rw-r--r-- | drivers/net/ethernet/sfc/ef10.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index a4fbb383ac63..c00a5d69c94a 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c | |||
@@ -498,44 +498,49 @@ static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = { | |||
498 | #define HUNT_40G_EXTRA_STAT_MASK ((1ULL << EF10_STAT_rx_align_error) | \ | 498 | #define HUNT_40G_EXTRA_STAT_MASK ((1ULL << EF10_STAT_rx_align_error) | \ |
499 | (1ULL << EF10_STAT_rx_length_error)) | 499 | (1ULL << EF10_STAT_rx_length_error)) |
500 | 500 | ||
501 | #if BITS_PER_LONG == 64 | 501 | static u64 efx_ef10_raw_stat_mask(struct efx_nic *efx) |
502 | #define STAT_MASK_BITMAP(bits) (bits) | ||
503 | #else | ||
504 | #define STAT_MASK_BITMAP(bits) (bits) & 0xffffffff, (bits) >> 32 | ||
505 | #endif | ||
506 | |||
507 | static const unsigned long *efx_ef10_stat_mask(struct efx_nic *efx) | ||
508 | { | 502 | { |
509 | static const unsigned long hunt_40g_stat_mask[] = { | 503 | u64 raw_mask = HUNT_COMMON_STAT_MASK; |
510 | STAT_MASK_BITMAP(HUNT_COMMON_STAT_MASK | | ||
511 | HUNT_40G_EXTRA_STAT_MASK) | ||
512 | }; | ||
513 | static const unsigned long hunt_10g_only_stat_mask[] = { | ||
514 | STAT_MASK_BITMAP(HUNT_COMMON_STAT_MASK | | ||
515 | HUNT_10G_ONLY_STAT_MASK) | ||
516 | }; | ||
517 | u32 port_caps = efx_mcdi_phy_get_caps(efx); | 504 | u32 port_caps = efx_mcdi_phy_get_caps(efx); |
518 | 505 | ||
519 | if (port_caps & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) | 506 | if (port_caps & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) |
520 | return hunt_40g_stat_mask; | 507 | raw_mask |= HUNT_40G_EXTRA_STAT_MASK; |
521 | else | 508 | else |
522 | return hunt_10g_only_stat_mask; | 509 | raw_mask |= HUNT_10G_ONLY_STAT_MASK; |
510 | return raw_mask; | ||
511 | } | ||
512 | |||
513 | static void efx_ef10_get_stat_mask(struct efx_nic *efx, unsigned long *mask) | ||
514 | { | ||
515 | u64 raw_mask = efx_ef10_raw_stat_mask(efx); | ||
516 | |||
517 | #if BITS_PER_LONG == 64 | ||
518 | mask[0] = raw_mask; | ||
519 | #else | ||
520 | mask[0] = raw_mask & 0xffffffff; | ||
521 | mask[1] = raw_mask >> 32; | ||
522 | #endif | ||
523 | } | 523 | } |
524 | 524 | ||
525 | static size_t efx_ef10_describe_stats(struct efx_nic *efx, u8 *names) | 525 | static size_t efx_ef10_describe_stats(struct efx_nic *efx, u8 *names) |
526 | { | 526 | { |
527 | DECLARE_BITMAP(mask, EF10_STAT_COUNT); | ||
528 | |||
529 | efx_ef10_get_stat_mask(efx, mask); | ||
527 | return efx_nic_describe_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, | 530 | return efx_nic_describe_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, |
528 | efx_ef10_stat_mask(efx), names); | 531 | mask, names); |
529 | } | 532 | } |
530 | 533 | ||
531 | static int efx_ef10_try_update_nic_stats(struct efx_nic *efx) | 534 | static int efx_ef10_try_update_nic_stats(struct efx_nic *efx) |
532 | { | 535 | { |
533 | struct efx_ef10_nic_data *nic_data = efx->nic_data; | 536 | struct efx_ef10_nic_data *nic_data = efx->nic_data; |
534 | const unsigned long *stats_mask = efx_ef10_stat_mask(efx); | 537 | DECLARE_BITMAP(mask, EF10_STAT_COUNT); |
535 | __le64 generation_start, generation_end; | 538 | __le64 generation_start, generation_end; |
536 | u64 *stats = nic_data->stats; | 539 | u64 *stats = nic_data->stats; |
537 | __le64 *dma_stats; | 540 | __le64 *dma_stats; |
538 | 541 | ||
542 | efx_ef10_get_stat_mask(efx, mask); | ||
543 | |||
539 | dma_stats = efx->stats_buffer.addr; | 544 | dma_stats = efx->stats_buffer.addr; |
540 | nic_data = efx->nic_data; | 545 | nic_data = efx->nic_data; |
541 | 546 | ||
@@ -543,7 +548,7 @@ static int efx_ef10_try_update_nic_stats(struct efx_nic *efx) | |||
543 | if (generation_end == EFX_MC_STATS_GENERATION_INVALID) | 548 | if (generation_end == EFX_MC_STATS_GENERATION_INVALID) |
544 | return 0; | 549 | return 0; |
545 | rmb(); | 550 | rmb(); |
546 | efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, stats_mask, | 551 | efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, mask, |
547 | stats, efx->stats_buffer.addr, false); | 552 | stats, efx->stats_buffer.addr, false); |
548 | rmb(); | 553 | rmb(); |
549 | generation_start = dma_stats[MC_CMD_MAC_GENERATION_START]; | 554 | generation_start = dma_stats[MC_CMD_MAC_GENERATION_START]; |
@@ -564,12 +569,14 @@ static int efx_ef10_try_update_nic_stats(struct efx_nic *efx) | |||
564 | static size_t efx_ef10_update_stats(struct efx_nic *efx, u64 *full_stats, | 569 | static size_t efx_ef10_update_stats(struct efx_nic *efx, u64 *full_stats, |
565 | struct rtnl_link_stats64 *core_stats) | 570 | struct rtnl_link_stats64 *core_stats) |
566 | { | 571 | { |
567 | const unsigned long *mask = efx_ef10_stat_mask(efx); | 572 | DECLARE_BITMAP(mask, EF10_STAT_COUNT); |
568 | struct efx_ef10_nic_data *nic_data = efx->nic_data; | 573 | struct efx_ef10_nic_data *nic_data = efx->nic_data; |
569 | u64 *stats = nic_data->stats; | 574 | u64 *stats = nic_data->stats; |
570 | size_t stats_count = 0, index; | 575 | size_t stats_count = 0, index; |
571 | int retry; | 576 | int retry; |
572 | 577 | ||
578 | efx_ef10_get_stat_mask(efx, mask); | ||
579 | |||
573 | /* If we're unlucky enough to read statistics during the DMA, wait | 580 | /* If we're unlucky enough to read statistics during the DMA, wait |
574 | * up to 10ms for it to finish (typically takes <500us) | 581 | * up to 10ms for it to finish (typically takes <500us) |
575 | */ | 582 | */ |