On Thu, Oct 3, 2024 at 11:26 AM Arkadiusz Kubalewski
<[email protected]> wrote:
>
> The E810 Lan On Motherboard (LOM) design is vendor specific. Intel
> provides the reference design, but it is up to vendor on the final
> product design. For some cases, like Linux DPLL support, the static
> values defined in the driver does not reflect the actual LOM design.
> Current implementation of output pins is causing the crash on probe
> of the ice driver for such DPLL enabled E810 LOM designs:
>
> WARNING: (...) at drivers/dpll/dpll_core.c:495 dpll_pin_get+0x2c4/0x330
> ...
> Call Trace:
>  <TASK>
>  ? __warn+0x83/0x130
>  ? dpll_pin_get+0x2c4/0x330
>  ? report_bug+0x1b7/0x1d0
>  ? handle_bug+0x42/0x70
>  ? exc_invalid_op+0x18/0x70
>  ? asm_exc_invalid_op+0x1a/0x20
>  ? dpll_pin_get+0x117/0x330
>  ? dpll_pin_get+0x2c4/0x330
>  ? dpll_pin_get+0x117/0x330
>  ice_dpll_get_pins.isra.0+0x52/0xe0 [ice]
> ...
>
> The number of output pins enabled by LOM vendor is greater than expected
> and defined in the driver for Intel designed NICs, which causes the crash.
>
> Prevent the crash and allow generic output pin initialization within
> Linux DPLL subsystem for DPLL enabled E810 LOM designs.
>
> Newly designed solution for described issue will be based on "per HW
> design" pin initialization. It requires pin information dynamically
> acquired from the firmware and is already in progress, planned for
> next-tree only.
>
> Fixes: d7999f5ea64b ("ice: implement dpll interface to control cgu")
> Reviewed-by: Karol Kolacinski <[email protected]>
> Signed-off-by: Arkadiusz Kubalewski <[email protected]>
> ---
> v2:
> - put define on top of the file
> - fix smatch 'ret' uninitialized
> - do not init first array dimmension, use sizeof to obtain array size
> - raname ice_cgu_get_pin_num(..) -> ice_cgu_get_num_pins(..)
> - fix kdoc typo
> ---
>  drivers/net/ethernet/intel/ice/ice_dpll.c   | 43 +++++++++++++++++++++
>  drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 19 +++++++++
>  drivers/net/ethernet/intel/ice/ice_ptp_hw.h |  1 +
>  3 files changed, 63 insertions(+)
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c 
> b/drivers/net/ethernet/intel/ice/ice_dpll.c
> index 74c0e7319a4c..e9966c6c7c0f 100644
> --- a/drivers/net/ethernet/intel/ice/ice_dpll.c
> +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
> @@ -10,6 +10,7 @@
>  #define ICE_DPLL_PIN_IDX_INVALID               0xff
>  #define ICE_DPLL_RCLK_NUM_PER_PF               1
>  #define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT  25
> +#define ICE_DPLL_GEN_OUT_LEN                   3
>
>  /**
>   * enum ice_dpll_pin_type - enumerate ice pin types:
> @@ -2063,6 +2064,46 @@ static int ice_dpll_init_worker(struct ice_pf *pf)
>         return 0;
>  }
>
> +/**
> + * ice_dpll_init_info_output_pins_generic - initializes generic output pins 
> info
> + * @pf: board private structure
> + *
> + * Init information for generic output pins, cache them in PF's pins 
> structures.
> + *
> + * Return:
> + * * 0 - success
> + * * negative - init failure reason
> + */
> +static int ice_dpll_init_info_output_pins_generic(struct ice_pf *pf)
> +{
> +       static const char labels[][ICE_DPLL_GEN_OUT_LEN] = {
> +               "0", "1", "2", "3", "4", "5", "6", "7", "8",
> +               "9", "10", "11", "12", "13", "14", "15" };
> +       u32 cap = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
> +       struct ice_dpll_pin *pins = pf->dplls.outputs;
> +       int i, ret = -EINVAL;
> +
> +       if (pf->dplls.num_outputs > sizeof(labels) / ICE_DPLL_GEN_OUT_LEN)

Just use ARRAY_SIZE(labels). I believe that's what Tony meant in his
review of v1.
Once you have that, you don't need to define ICE_DPLL_GEN_OUT_LEN at all.
Just declare labels as:
  static const char labels[][3] = ...
or, if you like this more:
  static const char labels[][sizeof("99")] = ...

Michal

Reply via email to