aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/sfc
diff options
context:
space:
mode:
authorEdward Cree <ecree@solarflare.com>2013-09-27 13:52:49 -0400
committerBen Hutchings <bhutchings@solarflare.com>2013-10-04 18:31:51 -0400
commit4bae913bd372aab90fdbd91e7e5fb841a2a0dc15 (patch)
tree182cf2705eb6349cb1fea0cc69dd2cd446b0be64 /drivers/net/ethernet/sfc
parent87648cc925222f16c3bd119af8ae8e8fb2f3fe1d (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.c49
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 501static 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
507static 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
513static 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
525static size_t efx_ef10_describe_stats(struct efx_nic *efx, u8 *names) 525static 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
531static int efx_ef10_try_update_nic_stats(struct efx_nic *efx) 534static 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)
564static size_t efx_ef10_update_stats(struct efx_nic *efx, u64 *full_stats, 569static 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 */