From nobody Mon Aug 3 16:54:30 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hDN7V2QQDz6mX1q for ; Mon, 03 Aug 2026 16:54:30 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hDN7V1kdqz3dD6 for ; Mon, 03 Aug 2026 16:54:30 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785776070; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=DXfvnPt1M2ZWyT3Xi4pbjj7E/v7vaiU5WMlBHPoTb7I=; b=qJvIjXbOxzJwKOE2KbuKyAqYefZMnWiJMgA6QN0Fx4Hzlc8dRu3MibZcZ2mLj4JDU5aC8o CiKDdFtG9vev05eXmxVk+tZYnsrBw7S2Oxf4HMSNNWwJwlrtQmLr2zoS2T2o1n5IdMWj4F eKejSLU5sy68l5xmFUeqYZ5v0glwJIIRWJ8bTcS0T54I/XV1ykGQfqHI9e43xApmQjDsaD Ua0JEOXzZ8gpj/oKsPGZCp6mC81DXv7X4lXGE+5i7D/TmXOI6D0gqujmn6cid9IMgcWmEG D5R6y3TN06ujnMOQz+UCmNfv9iyBiAmwZZTID688Y/d2D2nPUIO/JkApCObG1A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1785776070; a=rsa-sha256; cv=none; b=wE0b4rlhiCKVeZivhShDcTGd1Byl9iCqXLZJEYABcbHTj1EWFI6xWpaDgA9uTZEizi/7AU TsDsbnzI003SZhvM+mydj9C0Ym4sse9u5o+KjORA0I7h3hqrKf3S7OfszcHMQWwgeILw4N XBh90zt7Zk/VcileTXfKUWmxUg7Z2eq2kylNReLwm6wdEfQVyC9Rz1TRqFjcHm2cT/Fk2m oSN7sv3UwK4YayVxxIfzVEBVj8X9WxMEjur5V3fvcHkthso70JbJU8IJ/9gSF/epf1xj4o 4T5yhwh6KXTe0lq70Q5OEmtzELnmYsGbWiI6XTKt/uNufrQWDUI9zA6jlTGZeg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785776070; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=DXfvnPt1M2ZWyT3Xi4pbjj7E/v7vaiU5WMlBHPoTb7I=; b=A26lO6MYxjDQDHwSYDSUb1kCPl9wlCB8cHoGgfIXZznM5l4lT/EkpljNguh8VAj+2CHw+5 8vUVtKuFiVh8kWGvsOgF5g5V/Cba7/Vbe2sKZbaB++xvxdgHvuKIL7u+stzMVUs70Ir5Eh 1Nx60jnHmd+3Vyc3lsCYT90d505MITOYBlUaYBRhmGJr3Vt6mnyNjRqmVn88pzNFCd9Reh QA5+YKrGL7jGiv+aQh3xQq066gb8OqlsFBTaDp1g0adoWUQqYq9UgR1rUbB8MIzp9f97Ho YtE72Pog1WMGfgBt2isBNZlCzBSB3BRD3L36lj7WAhww0H1g/CWACvKqU2NAPg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hDN7V0Xhkz184q for ; Mon, 03 Aug 2026 16:54:30 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 440cd by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 03 Aug 2026 16:54:30 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Andrew Gallatin Subject: git: 3a6bf8a72d49 - main - ifconfig: Improve CMIS parsing of breakout configs List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: gallatin X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 3a6bf8a72d4922b53d75924c4645774ef37e27ff Auto-Submitted: auto-generated Date: Mon, 03 Aug 2026 16:54:30 +0000 Message-Id: <6a70c7c6.440cd.59ffcaab@gitrepo.freebsd.org> The branch main has been updated by gallatin: URL: https://cgit.FreeBSD.org/src/commit/?id=3a6bf8a72d4922b53d75924c4645774ef37e27ff commit 3a6bf8a72d4922b53d75924c4645774ef37e27ff Author: Andrew Gallatin AuthorDate: 2026-07-15 17:44:06 +0000 Commit: Andrew Gallatin CommitDate: 2026-08-03 16:53:50 +0000 ifconfig: Improve CMIS parsing of breakout configs This fixes a bug where we do not report all lanes when a NIC configures a breakout. Eg, we reported all 4 lanes when a NIC configured the optics as 1x400g, but only printed the first lane's strength when configured as 4x100g. Fix this by actually parsing the active lane count, rather than pulling it from the default descriptor. While here, optionally print page 10h when -vvvv is specified. This aids in determining how a breakout is configured. I put it under an extra level of verbosity, as I don't want to let things get out of hand printing CMIS pages. Sponsored by: Netflix Reviewed by: kib, sumit.saxena_broadcom.com Differential Revision: https://reviews.freebsd.org/D58263 --- lib/libifconfig/libifconfig_sfp.c | 46 +++++++++++++++++++++++++++++++-------- lib/libifconfig/libifconfig_sfp.h | 3 ++- sbin/ifconfig/sfp.c | 5 +++++ 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/lib/libifconfig/libifconfig_sfp.c b/lib/libifconfig/libifconfig_sfp.c index a2cddf89a13a..dcd5ef2e8e57 100644 --- a/lib/libifconfig/libifconfig_sfp.c +++ b/lib/libifconfig/libifconfig_sfp.c @@ -238,6 +238,27 @@ get_qsfp_info(struct i2c_info *ii, struct ifconfig_sfp_info *sfp) return (ii->error); } +/* Count active host lanes (nonzero AppSelCode) in the Active Control Set. */ +static uint8_t +get_cmis_active_lanes(struct i2c_info *ii) +{ + uint8_t dpconfig[CMIS_MAX_LANES]; + uint8_t lanes; + int i; + + lanes = 0; + read_i2c_page(ii, CMIS_BASE, 0x11, 0, CMIS_P11_ACS_DPCONFIG1, + sizeof(dpconfig), dpconfig); + if (ii->error != 0) + return (0); + + for (i = 0; i < CMIS_MAX_LANES; i++) { + if ((dpconfig[i] & CMIS_ACS_APPSEL_MASK) != 0) + lanes++; + } + return (lanes); +} + static int get_cmis_info(struct i2c_info *ii, struct ifconfig_sfp_info *sfp) { @@ -287,8 +308,10 @@ get_cmis_info(struct i2c_info *ii, struct ifconfig_sfp_info *sfp) break; } - /* Extract media lane count from app descriptor byte 2, bits 3:0 */ - sfp->sfp_cmis_lanes = app_desc[CMIS_APP_LANE_COUNT] & 0x0F; + /* Count active lanes; fall back to the descriptor's media lane count. */ + sfp->sfp_cmis_lanes = get_cmis_active_lanes(ii); + if (sfp->sfp_cmis_lanes == 0) + sfp->sfp_cmis_lanes = app_desc[CMIS_APP_LANE_COUNT] & 0x0F; return (ii->error); } @@ -657,15 +680,18 @@ ifconfig_sfp_get_sfp_status(ifconfig_handle_t *h, const char *name, if (ifconfig_sfp_id_is_cmis(ii.id)) { /* - * For CMIS, we need the lane count from the module info. - * Read the first Application Descriptor to get it. + * Match the active-lane count reported by get_cmis_info(); + * fall back to the first descriptor's media lane count. */ uint8_t app_desc[CMIS_APP_DESC_SIZE]; size_t channels; - read_i2c(&ii, CMIS_BASE, CMIS_APP_DESC_START, - CMIS_APP_DESC_SIZE, app_desc); - channels = app_desc[CMIS_APP_LANE_COUNT] & 0x0F; + channels = get_cmis_active_lanes(&ii); + if (channels == 0) { + read_i2c(&ii, CMIS_BASE, CMIS_APP_DESC_START, + CMIS_APP_DESC_SIZE, app_desc); + channels = app_desc[CMIS_APP_LANE_COUNT] & 0x0F; + } return (get_cmis_status(&ii, ss, channels)); } @@ -779,12 +805,14 @@ ifconfig_sfp_get_sfp_dump(ifconfig_handle_t *h, const char *name, return (-1); if (ifconfig_sfp_id_is_cmis(ii.id)) { - /* Lower memory (0-127), Page 00h (128-255), Page 11h */ + /* Lower memory (0-127), Page 00h, Page 11h, Page 10h */ read_i2c(&ii, CMIS_BASE, 0, 128, buf); read_i2c_page(&ii, CMIS_BASE, 0x00, 0, 128, 128, buf + 128); read_i2c_page(&ii, CMIS_BASE, 0x11, 0, 128, 128, buf + CMIS_DUMP_P11); + read_i2c_page(&ii, CMIS_BASE, 0x10, 0, 128, 128, + buf + CMIS_DUMP_P10); } else if (ifconfig_sfp_id_is_qsfp(ii.id)) { read_i2c(&ii, SFF_8436_BASE, QSFP_DUMP0_START, QSFP_DUMP0_SIZE, buf + QSFP_DUMP0_START); @@ -804,7 +832,7 @@ ifconfig_sfp_dump_region_count(const struct ifconfig_sfp_dump *dp) uint8_t id_byte = dp->data[0]; if (ifconfig_sfp_id_is_cmis((enum sfp_id)id_byte)) - return (3); + return (4); switch ((enum sfp_id)id_byte) { case SFP_ID_UNKNOWN: diff --git a/lib/libifconfig/libifconfig_sfp.h b/lib/libifconfig/libifconfig_sfp.h index 9ed4f684e5c4..725f96208066 100644 --- a/lib/libifconfig/libifconfig_sfp.h +++ b/lib/libifconfig/libifconfig_sfp.h @@ -85,10 +85,11 @@ struct ifconfig_sfp_status { #define CMIS_DUMP_SIZE 512 /**< CMIS dump buffer size */ #define CMIS_DUMP_P11 256 /**< offset of Page 11h in dump buffer */ +#define CMIS_DUMP_P10 384 /**< offset of Page 10h in dump buffer */ /** SFP module I2C memory dump * SFP modules have one region, QSFP modules have two. - * CMIS modules have three: lower memory, Page 00h, and Page 11h. + * CMIS modules have four: lower memory, Page 00h, Page 11h, and Page 10h. */ struct ifconfig_sfp_dump { uint8_t data[CMIS_DUMP_SIZE]; /**< memory dump data */ diff --git a/sbin/ifconfig/sfp.c b/sbin/ifconfig/sfp.c index f6400684ba7a..878a02a4a0da 100644 --- a/sbin/ifconfig/sfp.c +++ b/sbin/ifconfig/sfp.c @@ -122,6 +122,11 @@ sfp_status(if_ctx *ctx) printf("\n\tCMIS DUMP (Page 00h 128..255):\n"); hexdump(dump.data + 128, 128, "\t", HD_OMIT_COUNT | HD_OMIT_CHARS); + if (verbose > 3) { + printf("\n\tCMIS DUMP (Page 10h 128..255):\n"); + hexdump(dump.data + CMIS_DUMP_P10, 128, + "\t", HD_OMIT_COUNT | HD_OMIT_CHARS); + } printf("\n\tCMIS DUMP (Page 11h 128..255):\n"); hexdump(dump.data + CMIS_DUMP_P11, 128, "\t", HD_OMIT_COUNT | HD_OMIT_CHARS);