From ef5c7a6ccabfc49a38a9a4df819c978b29a1a68a Mon Sep 17 00:00:00 2001 From: Dan McDonald Date: Fri, 27 Oct 2023 17:41:51 -0400 Subject: [PATCH] Checkpoint: WIP PDDR querying. Needs more, but can disambiguate some ext_proto values once we can query PDDR's module information page --- usr/src/uts/common/io/mlxcx/mlxcx.c | 8 +++- usr/src/uts/common/io/mlxcx/mlxcx.h | 1 + usr/src/uts/common/io/mlxcx/mlxcx_cmd.c | 14 +++++++ usr/src/uts/common/io/mlxcx/mlxcx_reg.h | 52 +++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) diff --git a/usr/src/uts/common/io/mlxcx/mlxcx.c b/usr/src/uts/common/io/mlxcx/mlxcx.c index 691a333168bc..47793841fc72 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx.c +++ b/usr/src/uts/common/io/mlxcx/mlxcx.c @@ -2454,10 +2454,16 @@ mlxcx_explore_pcam(mlxcx_t *mlxp, mlxcx_caps_t *c) /* * Extended PTYS support is bit 13 of the 128-bit feature_cap_mask, so * be appropriately mask-y about it. If BE_64() makes a htonll call, - * #define the value instead. + * #define the value instead. May need real #defines or enums at some + * point. */ c->mlc_ext = ((pcam->mlrd_pcam_feature_cap_mask_low & BE_64(1 << 13)) != 0); + + /* PDDR module info support is bit 66. */ + c->mlc_pddr_modinfo = + ((pcam->mlrd_pcam_feature_cap_mask_high & BE_64(1 << 2)) != 0); + /* XXX KEBE SAYS tons more things to check. */ } diff --git a/usr/src/uts/common/io/mlxcx/mlxcx.h b/usr/src/uts/common/io/mlxcx/mlxcx.h index 8417f9da244a..19cd0f64f260 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx.h +++ b/usr/src/uts/common/io/mlxcx/mlxcx.h @@ -977,6 +977,7 @@ typedef struct { boolean_t mlc_vxlan; boolean_t mlc_pcam; boolean_t mlc_ext; + boolean_t mlc_pddr_modinfo; size_t mlc_max_lso_size; size_t mlc_max_rqt_size; diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c b/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c index 75a0d7bbe093..939467dd6ea4 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c +++ b/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c @@ -2013,6 +2013,20 @@ mlxcx_cmd_query_port_speed(mlxcx_t *mlxp, mlxcx_port_t *mlp) mlp->mlp_ext_oper_proto = from_bits32( data.mlrd_ptys.mlrd_ptys_ext_proto_oper); } + + if (mlxp->mlx_caps->mlc_pddr_modinfo) { + /* + * Check for cable_type on module_info_page. + * + * Set bits in mlrd_pddr_page_select for + * module_info_page, and in local port (hopefully we + * don't exceed port #255, we probably won't). + * + * Cache results, maybe even in a form we can directly + * report back in combination with mlp{,_ext}_*_proto. + */ + /* XXX KEBE SAYS FILL ME IN! */ + } } return (ret); diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_reg.h b/usr/src/uts/common/io/mlxcx/mlxcx_reg.h index 996d9596f26c..9c609826e6ba 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx_reg.h +++ b/usr/src/uts/common/io/mlxcx/mlxcx_reg.h @@ -2396,6 +2396,56 @@ typedef struct { uint64_t mlrd_pcam_reserved5[3]; } mlxcx_reg_pcam_t; +/* PDDR - Port Diagnostics Database Register. */ +typedef struct { + uint8_t mlrd_pddr_rsvd; + uint8_t mlrd_pddr_local_port; + /* Bits 0xC0 are pnat, bits 0x30 are lp_msb (msb of local_port, uggh */ + uint8_t mlrd_pddr_pnat_lp_msb; + uint8_t mlrd_pddr_rsvd2; + /* Bits 0x60 are module_info_ext */ + uint8_t mlrd_pddr_module_info_ext; + /* Unaligned, but two in a row. */ + uint8_t mlrd_pddr_rsvd3[2]; + /* + * Bit 0x08 is module_info_page_9, (_9 might be a typo in the manual?) + * There's mention of module_latched_flag_info, which might be bit + * 9 aka. 0x100) and this becomes uint16_t and rsvd3 becomes one + * byte not two. XXX KEBE WONDERS... + * Bit 0x02 is troubleshooting_info_page, + * Bit 0x01 is operational_info_page. + */ + uint8_t mlrd_pddr_page_select; + + /* + * We're at a 64-bit boundary at this point. + * + * We have to set the page select bit above, and the port number + * BEFORE invoking mlxcx_cmd_access_register(). The union below + * consists of the various page types we can query. + */ + union { + uint64_t pddr_page_data[31]; + struct { + uint8_t cable_technology; + uint8_t cable_breakout; + uint8_t ext_ethernet_compliance_code; + uint8_t ethernet_compliance_code; + /* High four bits are type, low four are vendor. */ + uint8_t cable_type_and_vendor; + uint8_t cable_length; + uint8_t cable_identifier; + uint8_t cable_power_class; + /* + * XXX KEBE SAYS THERE'S A LOT MORE, BUT we can + * Fill them in later after we determine if we can get + * more useful data out of this. For now I'm here for + * cable_type from cable_type_and_vendor. + */ + } pddr_modinfo; + } mlrd_pddr_pages; +} mlxcx_reg_pddr_t; + /* PTYS - Port TYpe and Speed register. */ typedef struct { bits8_t mlrd_ptys_autoneg_flags; @@ -2648,6 +2698,7 @@ typedef enum { MLXCX_REG_MCIA = 0x9014, MLXCX_REG_PPCNT = 0x5008, MLXCX_REG_PPLM = 0x5023, + MLXCX_REG_PDDR = 0x5031, MLXCX_REG_PCAM = 0x507f, MLXCX_REG_MTCAP = 0x9009, MLXCX_REG_MTMP = 0x900A @@ -2656,6 +2707,7 @@ typedef enum { typedef union { mlxcx_reg_pmtu_t mlrd_pmtu; mlxcx_reg_pcam_t mlrd_pcam; + mlxcx_reg_pddr_t mlrd_pddr; mlxcx_reg_paos_t mlrd_paos; mlxcx_reg_ptys_t mlrd_ptys; mlxcx_reg_mlcr_t mlrd_mlcr;