Skip to content

Commit ac21add

Browse files
ansamalintelkuba-moo
authored andcommitted
ice: Implement driver functionality to dump fec statistics
To debug link issues in the field, it is paramount to dump fec corrected/uncorrected block counts from firmware. Firmware requires PCS quad number and PCS port number to read FEC statistics. Current driver implementation does not maintain above physical properties of a port. Add new driver API to derive physical properties of an input port.These properties include PCS quad number, PCS port number, serdes lane count, primary serdes lane number. Extend ethtool option '--show-fec' to support fec statistics. The IEEE standard mandates two sets of counters: - 30.5.1.1.17 aFECCorrectedBlocks - 30.5.1.1.18 aFECUncorrectableBlocks Standard defines above statistics per lane but current implementation supports total FEC statistics per port i.e. sum of all lane per port. Find sample output below FEC parameters for ens21f0np0: Supported/Configured FEC encodings: Auto RS BaseR Active FEC encoding: RS Statistics: corrected_blocks: 0 uncorrectable_blocks: 0 Reviewed-by: Simon Horman <[email protected]> Reviewed-by: Jesse Brandeburg <[email protected]> Signed-off-by: Anil Samal <[email protected]> Tested-by: Pucha Himasekhar Reddy <[email protected]> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent a317f87 commit ac21add

File tree

5 files changed

+403
-0
lines changed

5 files changed

+403
-0
lines changed

drivers/net/ethernet/intel/ice/ice_common.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3371,6 +3371,63 @@ int ice_update_link_info(struct ice_port_info *pi)
33713371
return status;
33723372
}
33733373

3374+
#define FEC_REG_PORT(port) { \
3375+
FEC_CORR_LOW_REG_PORT##port, \
3376+
FEC_CORR_HIGH_REG_PORT##port, \
3377+
FEC_UNCORR_LOW_REG_PORT##port, \
3378+
FEC_UNCORR_HIGH_REG_PORT##port, \
3379+
}
3380+
3381+
static const u32 fec_reg[][ICE_FEC_MAX] = {
3382+
FEC_REG_PORT(0),
3383+
FEC_REG_PORT(1),
3384+
FEC_REG_PORT(2),
3385+
FEC_REG_PORT(3)
3386+
};
3387+
3388+
/**
3389+
* ice_aq_get_fec_stats - reads fec stats from phy
3390+
* @hw: pointer to the HW struct
3391+
* @pcs_quad: represents pcsquad of user input serdes
3392+
* @pcs_port: represents the pcs port number part of above pcs quad
3393+
* @fec_type: represents FEC stats type
3394+
* @output: pointer to the caller-supplied buffer to return requested fec stats
3395+
*
3396+
* Return: non-zero status on error and 0 on success.
3397+
*/
3398+
int ice_aq_get_fec_stats(struct ice_hw *hw, u16 pcs_quad, u16 pcs_port,
3399+
enum ice_fec_stats_types fec_type, u32 *output)
3400+
{
3401+
u16 flag = (ICE_AQ_FLAG_RD | ICE_AQ_FLAG_BUF | ICE_AQ_FLAG_SI);
3402+
struct ice_sbq_msg_input msg = {};
3403+
u32 receiver_id, reg_offset;
3404+
int err;
3405+
3406+
if (pcs_port > 3)
3407+
return -EINVAL;
3408+
3409+
reg_offset = fec_reg[pcs_port][fec_type];
3410+
3411+
if (pcs_quad == 0)
3412+
receiver_id = FEC_RECEIVER_ID_PCS0;
3413+
else if (pcs_quad == 1)
3414+
receiver_id = FEC_RECEIVER_ID_PCS1;
3415+
else
3416+
return -EINVAL;
3417+
3418+
msg.msg_addr_low = lower_16_bits(reg_offset);
3419+
msg.msg_addr_high = receiver_id;
3420+
msg.opcode = ice_sbq_msg_rd;
3421+
msg.dest_dev = rmn_0;
3422+
3423+
err = ice_sbq_rw_reg(hw, &msg, flag);
3424+
if (err)
3425+
return err;
3426+
3427+
*output = msg.data;
3428+
return 0;
3429+
}
3430+
33743431
/**
33753432
* ice_cache_phy_user_req
33763433
* @pi: port information structure

drivers/net/ethernet/intel/ice/ice_common.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,27 @@
1717
#define ICE_SQ_SEND_DELAY_TIME_MS 10
1818
#define ICE_SQ_SEND_MAX_EXECUTE 3
1919

20+
#define FEC_REG_SHIFT 2
21+
#define FEC_RECV_ID_SHIFT 4
22+
#define FEC_CORR_LOW_REG_PORT0 (0x02 << FEC_REG_SHIFT)
23+
#define FEC_CORR_HIGH_REG_PORT0 (0x03 << FEC_REG_SHIFT)
24+
#define FEC_UNCORR_LOW_REG_PORT0 (0x04 << FEC_REG_SHIFT)
25+
#define FEC_UNCORR_HIGH_REG_PORT0 (0x05 << FEC_REG_SHIFT)
26+
#define FEC_CORR_LOW_REG_PORT1 (0x42 << FEC_REG_SHIFT)
27+
#define FEC_CORR_HIGH_REG_PORT1 (0x43 << FEC_REG_SHIFT)
28+
#define FEC_UNCORR_LOW_REG_PORT1 (0x44 << FEC_REG_SHIFT)
29+
#define FEC_UNCORR_HIGH_REG_PORT1 (0x45 << FEC_REG_SHIFT)
30+
#define FEC_CORR_LOW_REG_PORT2 (0x4A << FEC_REG_SHIFT)
31+
#define FEC_CORR_HIGH_REG_PORT2 (0x4B << FEC_REG_SHIFT)
32+
#define FEC_UNCORR_LOW_REG_PORT2 (0x4C << FEC_REG_SHIFT)
33+
#define FEC_UNCORR_HIGH_REG_PORT2 (0x4D << FEC_REG_SHIFT)
34+
#define FEC_CORR_LOW_REG_PORT3 (0x52 << FEC_REG_SHIFT)
35+
#define FEC_CORR_HIGH_REG_PORT3 (0x53 << FEC_REG_SHIFT)
36+
#define FEC_UNCORR_LOW_REG_PORT3 (0x54 << FEC_REG_SHIFT)
37+
#define FEC_UNCORR_HIGH_REG_PORT3 (0x55 << FEC_REG_SHIFT)
38+
#define FEC_RECEIVER_ID_PCS0 (0x33 << FEC_RECV_ID_SHIFT)
39+
#define FEC_RECEIVER_ID_PCS1 (0x34 << FEC_RECV_ID_SHIFT)
40+
2041
int ice_init_hw(struct ice_hw *hw);
2142
void ice_deinit_hw(struct ice_hw *hw);
2243
int ice_check_reset(struct ice_hw *hw);
@@ -121,6 +142,9 @@ int
121142
ice_get_link_default_override(struct ice_link_default_override_tlv *ldo,
122143
struct ice_port_info *pi);
123144
bool ice_is_phy_caps_an_enabled(struct ice_aqc_get_phy_caps_data *caps);
145+
int
146+
ice_aq_get_fec_stats(struct ice_hw *hw, u16 pcs_quad, u16 pcs_port,
147+
enum ice_fec_stats_types fec_type, u32 *output);
124148

125149
enum ice_fc_mode ice_caps_to_fc_mode(u8 caps);
126150
enum ice_fec_mode ice_caps_to_fec_mode(u8 caps, u8 fec_options);

0 commit comments

Comments
 (0)