Ben Hutchings says: ==================== Some more fixes for EF10 support; hopefully the last lot: 1. Fixes for reading statistics, from Edward Cree and Jon Cooper. 2. Addition of ethtool statistics for packets dropped by the hardware before they were associated with a specific function, from Edward Cree. 3. Only bind to functions that are in control of their associated port, as the driver currently assumes this is the case. ====================
Unified · Split
| @@ -444,6 +444,18 @@ static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = { · 443 unmodified lines | ||
| 444 | 444 | EF10_DMA_STAT(rx_align_error, RX_ALIGN_ERROR_PKTS), |
| 445 | 445 | EF10_DMA_STAT(rx_length_error, RX_LENGTH_ERROR_PKTS), |
| 446 | 446 | EF10_DMA_STAT(rx_nodesc_drops, RX_NODESC_DROPS), |
| 447 | + EF10_DMA_STAT(rx_pm_trunc_bb_overflow, PM_TRUNC_BB_OVERFLOW), | |
| 448 | + EF10_DMA_STAT(rx_pm_discard_bb_overflow, PM_DISCARD_BB_OVERFLOW), | |
| 449 | + EF10_DMA_STAT(rx_pm_trunc_vfifo_full, PM_TRUNC_VFIFO_FULL), | |
| 450 | + EF10_DMA_STAT(rx_pm_discard_vfifo_full, PM_DISCARD_VFIFO_FULL), | |
| 451 | + EF10_DMA_STAT(rx_pm_trunc_qbb, PM_TRUNC_QBB), | |
| 452 | + EF10_DMA_STAT(rx_pm_discard_qbb, PM_DISCARD_QBB), | |
| 453 | + EF10_DMA_STAT(rx_pm_discard_mapping, PM_DISCARD_MAPPING), | |
| 454 | + EF10_DMA_STAT(rx_dp_q_disabled_packets, RXDP_Q_DISABLED_PKTS), | |
| 455 | + EF10_DMA_STAT(rx_dp_di_dropped_packets, RXDP_DI_DROPPED_PKTS), | |
| 456 | + EF10_DMA_STAT(rx_dp_streaming_packets, RXDP_STREAMING_PKTS), | |
| 457 | + EF10_DMA_STAT(rx_dp_emerg_fetch, RXDP_EMERGENCY_FETCH_CONDITIONS), | |
| 458 | + EF10_DMA_STAT(rx_dp_emerg_wait, RXDP_EMERGENCY_WAIT_CONDITIONS), | |
| 447 | 459 | }; |
| 448 | 460 | |
| 449 | 461 | #define HUNT_COMMON_STAT_MASK ((1ULL << EF10_STAT_tx_bytes) | \ |
| @@ -498,44 +510,72 @@ static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = { · 48 unmodified lines | ||
| 498 | 510 | #define HUNT_40G_EXTRA_STAT_MASK ((1ULL << EF10_STAT_rx_align_error) | \ |
| 499 | 511 | (1ULL << EF10_STAT_rx_length_error)) |
| 500 | 512 | |
| 501 | −#if BITS_PER_LONG == 64 | |
| 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 | −{ | |
| 509 | − static const unsigned long hunt_40g_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 | − }; | |
| 513 | +/* These statistics are only provided if the firmware supports the | |
| 514 | + * capability PM_AND_RXDP_COUNTERS. | |
| 515 | + */ | |
| 516 | +#define HUNT_PM_AND_RXDP_STAT_MASK ( \ | |
| 517 | + (1ULL << EF10_STAT_rx_pm_trunc_bb_overflow) | \ | |
| 518 | + (1ULL << EF10_STAT_rx_pm_discard_bb_overflow) | \ | |
| 519 | + (1ULL << EF10_STAT_rx_pm_trunc_vfifo_full) | \ | |
| 520 | + (1ULL << EF10_STAT_rx_pm_discard_vfifo_full) | \ | |
| 521 | + (1ULL << EF10_STAT_rx_pm_trunc_qbb) | \ | |
| 522 | + (1ULL << EF10_STAT_rx_pm_discard_qbb) | \ | |
| 523 | + (1ULL << EF10_STAT_rx_pm_discard_mapping) | \ | |
| 524 | + (1ULL << EF10_STAT_rx_dp_q_disabled_packets) | \ | |
| 525 | + (1ULL << EF10_STAT_rx_dp_di_dropped_packets) | \ | |
| 526 | + (1ULL << EF10_STAT_rx_dp_streaming_packets) | \ | |
| 527 | + (1ULL << EF10_STAT_rx_dp_emerg_fetch) | \ | |
| 528 | + (1ULL << EF10_STAT_rx_dp_emerg_wait)) | |
| 529 | + | |
| 530 | +static u64 efx_ef10_raw_stat_mask(struct efx_nic *efx) | |
| 531 | +{ | |
| 532 | + u64 raw_mask = HUNT_COMMON_STAT_MASK; | |
| 517 | 533 | u32 port_caps = efx_mcdi_phy_get_caps(efx); |
| 534 | + struct efx_ef10_nic_data *nic_data = efx->nic_data; | |
| 518 | 535 | |
| 519 | 536 | if (port_caps & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) |
| 520 | − return hunt_40g_stat_mask; | |
| 537 | + raw_mask |= HUNT_40G_EXTRA_STAT_MASK; | |
| 521 | 538 | else |
| 522 | − return hunt_10g_only_stat_mask; | |
| 539 | + raw_mask |= HUNT_10G_ONLY_STAT_MASK; | |
| 540 | + | |
| 541 | + if (nic_data->datapath_caps & | |
| 542 | + (1 << MC_CMD_GET_CAPABILITIES_OUT_PM_AND_RXDP_COUNTERS_LBN)) | |
| 543 | + raw_mask |= HUNT_PM_AND_RXDP_STAT_MASK; | |
| 544 | + | |
| 545 | + return raw_mask; | |
| 546 | +} | |
| 547 | + | |
| 548 | +static void efx_ef10_get_stat_mask(struct efx_nic *efx, unsigned long *mask) | |
| 549 | +{ | |
| 550 | + u64 raw_mask = efx_ef10_raw_stat_mask(efx); | |
| 551 | + | |
| 552 | +#if BITS_PER_LONG == 64 | |
| 553 | + mask[0] = raw_mask; | |
| 554 | +#else | |
| 555 | + mask[0] = raw_mask & 0xffffffff; | |
| 556 | + mask[1] = raw_mask >> 32; | |
| 557 | +#endif | |
| 523 | 558 | } |
| 524 | 559 | |
| 525 | 560 | static size_t efx_ef10_describe_stats(struct efx_nic *efx, u8 *names) |
| 526 | 561 | { |
| 562 | + DECLARE_BITMAP(mask, EF10_STAT_COUNT); | |
| 563 | + | |
| 564 | + efx_ef10_get_stat_mask(efx, mask); | |
| 527 | 565 | return efx_nic_describe_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, |
| 528 | − efx_ef10_stat_mask(efx), names); | |
| 566 | + mask, names); | |
| 529 | 567 | } |
| 530 | 568 | |
| 531 | 569 | static int efx_ef10_try_update_nic_stats(struct efx_nic *efx) |
| 532 | 570 | { |
| 533 | 571 | struct efx_ef10_nic_data *nic_data = efx->nic_data; |
| 534 | − const unsigned long *stats_mask = efx_ef10_stat_mask(efx); | |
| 572 | + DECLARE_BITMAP(mask, EF10_STAT_COUNT); | |
| 535 | 573 | __le64 generation_start, generation_end; |
| 536 | 574 | u64 *stats = nic_data->stats; |
| 537 | 575 | __le64 *dma_stats; |
| 538 | 576 | |
| 577 | + efx_ef10_get_stat_mask(efx, mask); | |
| 578 | + | |
| 539 | 579 | dma_stats = efx->stats_buffer.addr; |
| 540 | 580 | nic_data = efx->nic_data; |
| 541 | 581 | |
| @@ -543,8 +583,9 @@ static int efx_ef10_try_update_nic_stats(struct efx_nic *efx) · 1 unmodified line | ||
| 543 | 583 | if (generation_end == EFX_MC_STATS_GENERATION_INVALID) |
| 544 | 584 | return 0; |
| 545 | 585 | rmb(); |
| 546 | − efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, stats_mask, | |
| 586 | + efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, mask, | |
| 547 | 587 | stats, efx->stats_buffer.addr, false); |
| 588 | + rmb(); | |
| 548 | 589 | generation_start = dma_stats[MC_CMD_MAC_GENERATION_START]; |
| 549 | 590 | if (generation_end != generation_start) |
| 550 | 591 | return -EAGAIN; |
| @@ -563,12 +604,14 @@ static int efx_ef10_try_update_nic_stats(struct efx_nic *efx) · 12 unmodified lines | ||
| 563 | 604 | static size_t efx_ef10_update_stats(struct efx_nic *efx, u64 *full_stats, |
| 564 | 605 | struct rtnl_link_stats64 *core_stats) |
| 565 | 606 | { |
| 566 | − const unsigned long *mask = efx_ef10_stat_mask(efx); | |
| 607 | + DECLARE_BITMAP(mask, EF10_STAT_COUNT); | |
| 567 | 608 | struct efx_ef10_nic_data *nic_data = efx->nic_data; |
| 568 | 609 | u64 *stats = nic_data->stats; |
| 569 | 610 | size_t stats_count = 0, index; |
| 570 | 611 | int retry; |
| 571 | 612 | |
| 613 | + efx_ef10_get_stat_mask(efx, mask); | |
| 614 | + | |
| 572 | 615 | /* If we're unlucky enough to read statistics during the DMA, wait |
| 573 | 616 | * up to 10ms for it to finish (typically takes <500us) |
| 574 | 617 | */ |
| @@ -963,7 +963,7 @@ static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, · 962 unmodified lines | ||
| 963 | 963 | bool *was_attached) |
| 964 | 964 | { |
| 965 | 965 | MCDI_DECLARE_BUF(inbuf, MC_CMD_DRV_ATTACH_IN_LEN); |
| 966 | − MCDI_DECLARE_BUF(outbuf, MC_CMD_DRV_ATTACH_OUT_LEN); | |
| 966 | + MCDI_DECLARE_BUF(outbuf, MC_CMD_DRV_ATTACH_EXT_OUT_LEN); | |
| 967 | 967 | size_t outlen; |
| 968 | 968 | int rc; |
| 969 | 969 | |
| @@ -981,6 +981,22 @@ static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, · 11 unmodified lines | ||
| 981 | 981 | goto fail; |
| 982 | 982 | } |
| 983 | 983 | |
| 984 | + /* We currently assume we have control of the external link | |
| 985 | + * and are completely trusted by firmware. Abort probing | |
| 986 | + * if that's not true for this function. | |
| 987 | + */ | |
| 988 | + if (driver_operating && | |
| 989 | + outlen >= MC_CMD_DRV_ATTACH_EXT_OUT_LEN && | |
| 990 | + (MCDI_DWORD(outbuf, DRV_ATTACH_EXT_OUT_FUNC_FLAGS) & | |
| 991 | + (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_LINKCTRL | | |
| 992 | + 1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_TRUSTED)) != | |
| 993 | + (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_LINKCTRL | | |
| 994 | + 1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_TRUSTED)) { | |
| 995 | + netif_err(efx, probe, efx->net_dev, | |
| 996 | + "This driver version only supports one function per port\n"); | |
| 997 | + return -ENODEV; | |
| 998 | + } | |
| 999 | + | |
| 984 | 1000 | if (was_attached != NULL) |
| 985 | 1001 | *was_attached = MCDI_DWORD(outbuf, DRV_ATTACH_OUT_OLD_STATE); |
| 986 | 1002 | return 0; |
| @@ -2574,8 +2574,58 @@ · 2573 unmodified lines | ||
| 2574 | 2574 | #define MC_CMD_MAC_RX_LANES01_DISP_ERR 0x39 /* enum */ |
| 2575 | 2575 | #define MC_CMD_MAC_RX_LANES23_DISP_ERR 0x3a /* enum */ |
| 2576 | 2576 | #define MC_CMD_MAC_RX_MATCH_FAULT 0x3b /* enum */ |
| 2577 | −#define MC_CMD_GMAC_DMABUF_START 0x40 /* enum */ | |
| 2578 | −#define MC_CMD_GMAC_DMABUF_END 0x5f /* enum */ | |
| 2577 | +/* enum: PM trunc_bb_overflow counter. Valid for EF10 with PM_AND_RXDP_COUNTERS | |
| 2578 | + * capability only. | |
| 2579 | + */ | |
| 2580 | +#define MC_CMD_MAC_PM_TRUNC_BB_OVERFLOW 0x3c | |
| 2581 | +/* enum: PM discard_bb_overflow counter. Valid for EF10 with | |
| 2582 | + * PM_AND_RXDP_COUNTERS capability only. | |
| 2583 | + */ | |
| 2584 | +#define MC_CMD_MAC_PM_DISCARD_BB_OVERFLOW 0x3d | |
| 2585 | +/* enum: PM trunc_vfifo_full counter. Valid for EF10 with PM_AND_RXDP_COUNTERS | |
| 2586 | + * capability only. | |
| 2587 | + */ | |
| 2588 | +#define MC_CMD_MAC_PM_TRUNC_VFIFO_FULL 0x3e | |
| 2589 | +/* enum: PM discard_vfifo_full counter. Valid for EF10 with | |
| 2590 | + * PM_AND_RXDP_COUNTERS capability only. | |
| 2591 | + */ | |
| 2592 | +#define MC_CMD_MAC_PM_DISCARD_VFIFO_FULL 0x3f | |
| 2593 | +/* enum: PM trunc_qbb counter. Valid for EF10 with PM_AND_RXDP_COUNTERS | |
| 2594 | + * capability only. | |
| 2595 | + */ | |
| 2596 | +#define MC_CMD_MAC_PM_TRUNC_QBB 0x40 | |
| 2597 | +/* enum: PM discard_qbb counter. Valid for EF10 with PM_AND_RXDP_COUNTERS | |
| 2598 | + * capability only. | |
| 2599 | + */ | |
| 2600 | +#define MC_CMD_MAC_PM_DISCARD_QBB 0x41 | |
| 2601 | +/* enum: PM discard_mapping counter. Valid for EF10 with PM_AND_RXDP_COUNTERS | |
| 2602 | + * capability only. | |
| 2603 | + */ | |
| 2604 | +#define MC_CMD_MAC_PM_DISCARD_MAPPING 0x42 | |
| 2605 | +/* enum: RXDP counter: Number of packets dropped due to the queue being | |
| 2606 | + * disabled. Valid for EF10 with PM_AND_RXDP_COUNTERS capability only. | |
| 2607 | + */ | |
| 2608 | +#define MC_CMD_MAC_RXDP_Q_DISABLED_PKTS 0x43 | |
| 2609 | +/* enum: RXDP counter: Number of packets dropped by the DICPU. Valid for EF10 | |
| 2610 | + * with PM_AND_RXDP_COUNTERS capability only. | |
| 2611 | + */ | |
| 2612 | +#define MC_CMD_MAC_RXDP_DI_DROPPED_PKTS 0x45 | |
| 2613 | +/* enum: RXDP counter: Number of non-host packets. Valid for EF10 with | |
| 2614 | + * PM_AND_RXDP_COUNTERS capability only. | |
| 2615 | + */ | |
| 2616 | +#define MC_CMD_MAC_RXDP_STREAMING_PKTS 0x46 | |
| 2617 | +/* enum: RXDP counter: Number of times an emergency descriptor fetch was | |
| 2618 | + * performed. Valid for EF10 with PM_AND_RXDP_COUNTERS capability only. | |
| 2619 | + */ | |
| 2620 | +#define MC_CMD_MAC_RXDP_EMERGENCY_FETCH_CONDITIONS 0x47 | |
| 2621 | +/* enum: RXDP counter: Number of times the DPCPU waited for an existing | |
| 2622 | + * descriptor fetch. Valid for EF10 with PM_AND_RXDP_COUNTERS capability only. | |
| 2623 | + */ | |
| 2624 | +#define MC_CMD_MAC_RXDP_EMERGENCY_WAIT_CONDITIONS 0x48 | |
| 2625 | +/* enum: Start of GMAC stats buffer space, for Siena only. */ | |
| 2626 | +#define MC_CMD_GMAC_DMABUF_START 0x40 | |
| 2627 | +/* enum: End of GMAC stats buffer space, for Siena only. */ | |
| 2628 | +#define MC_CMD_GMAC_DMABUF_END 0x5f | |
| 2579 | 2629 | #define MC_CMD_MAC_GENERATION_END 0x60 /* enum */ |
| 2580 | 2630 | #define MC_CMD_MAC_NSTATS 0x61 /* enum */ |
| 2581 | 2631 | |
| @@ -5065,6 +5115,8 @@ · 2483 unmodified lines | ||
| 5065 | 5115 | #define MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_WIDTH 1 |
| 5066 | 5116 | #define MC_CMD_GET_CAPABILITIES_OUT_MCAST_FILTER_CHAINING_LBN 26 |
| 5067 | 5117 | #define MC_CMD_GET_CAPABILITIES_OUT_MCAST_FILTER_CHAINING_WIDTH 1 |
| 5118 | +#define MC_CMD_GET_CAPABILITIES_OUT_PM_AND_RXDP_COUNTERS_LBN 27 | |
| 5119 | +#define MC_CMD_GET_CAPABILITIES_OUT_PM_AND_RXDP_COUNTERS_WIDTH 1 | |
| 5068 | 5120 | /* RxDPCPU firmware id. */ |
| 5069 | 5121 | #define MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_OFST 4 |
| 5070 | 5122 | #define MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_LEN 2 |
| @@ -469,8 +469,7 @@ size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count, · 468 unmodified lines | ||
| 469 | 469 | * @count: Length of the @desc array |
| 470 | 470 | * @mask: Bitmask of which elements of @desc are enabled |
| 471 | 471 | * @stats: Buffer to update with the converted statistics. The length |
| 472 | − * of this array must be at least the number of set bits in the | |
| 473 | − * first @count bits of @mask. | |
| 472 | + * of this array must be at least @count. | |
| 474 | 473 | * @dma_buf: DMA buffer containing hardware statistics |
| 475 | 474 | * @accumulate: If set, the converted values will be added rather than |
| 476 | 475 | * directly stored to the corresponding elements of @stats |
| @@ -503,11 +502,9 @@ void efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count, · 26 unmodified lines | ||
| 503 | 502 | } |
| 504 | 503 | |
| 505 | 504 | if (accumulate) |
| 506 | − *stats += val; | |
| 505 | + stats[index] += val; | |
| 507 | 506 | else |
| 508 | − *stats = val; | |
| 507 | + stats[index] = val; | |
| 509 | 508 | } |
| 510 | − | |
| 511 | − ++stats; | |
| 512 | 509 | } |
| 513 | 510 | } |
| @@ -386,6 +386,18 @@ enum { · 385 unmodified lines | ||
| 386 | 386 | EF10_STAT_rx_align_error, |
| 387 | 387 | EF10_STAT_rx_length_error, |
| 388 | 388 | EF10_STAT_rx_nodesc_drops, |
| 389 | + EF10_STAT_rx_pm_trunc_bb_overflow, | |
| 390 | + EF10_STAT_rx_pm_discard_bb_overflow, | |
| 391 | + EF10_STAT_rx_pm_trunc_vfifo_full, | |
| 392 | + EF10_STAT_rx_pm_discard_vfifo_full, | |
| 393 | + EF10_STAT_rx_pm_trunc_qbb, | |
| 394 | + EF10_STAT_rx_pm_discard_qbb, | |
| 395 | + EF10_STAT_rx_pm_discard_mapping, | |
| 396 | + EF10_STAT_rx_dp_q_disabled_packets, | |
| 397 | + EF10_STAT_rx_dp_di_dropped_packets, | |
| 398 | + EF10_STAT_rx_dp_streaming_packets, | |
| 399 | + EF10_STAT_rx_dp_emerg_fetch, | |
| 400 | + EF10_STAT_rx_dp_emerg_wait, | |
| 389 | 401 | EF10_STAT_COUNT |
| 390 | 402 | }; |
| 391 | 403 | |