From nobody Fri Aug 15 13:01:52 2025 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 4c3Mh700Bfz652Zm; Fri, 15 Aug 2025 13:01:59 +0000 (UTC) (envelope-from aokblast@freebsd.org) Received: from smtp.freebsd.org (smtp.freebsd.org [96.47.72.83]) (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 "smtp.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4c3Mh66VDlz3mSn; Fri, 15 Aug 2025 13:01:58 +0000 (UTC) (envelope-from aokblast@freebsd.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1755262918; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zDs6Eb06m+qnTLUqsRRdkW7SA4hFwFva9sImtIHH6Eg=; b=bA+dNYxgpPrO617SOsDMaXlMjXt6OBGU+r85gg9J0pRqqgBxNksf59jFwjljrdZm1LP/GV 2nYpwj/oux531NBfusbatBQbNabVFykYsMX41DlBPXy11pBX7P+2SRTKmvsjhzUItTi+BD 2yKXpv2MeEIfzEwmIrrEsgdNd9JUcyABO/0bZApLuAc6gYc7+Qb5KrNC8YJzOBUkv6fBYZ tvqeGQZ4D7+MZFgqJkENzdVkcsOqyminbIDbkVxYTq6xnnFPSw+nfUiiWDAviyCAyw95Jb YfSnJIsklpiqWuELF0aNesnUgLEk+otFT4srnRWQxcipq40P1uhzan6kayfGzA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1755262918; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zDs6Eb06m+qnTLUqsRRdkW7SA4hFwFva9sImtIHH6Eg=; b=vNDUEj2N/aSk7+XMagUNw7VX/e8n+LMfaCtHL4jITySZL/CFb2l42n8IEqiSrUmEBrJf2w 8f+xqV6Nebo/IdbjStTVw4iK0nnG0Zw2SXbKDp2gZzmkpyMRmWQMkBA2ukAYutCFIMbJRg 9E7D0pY5rKLG2Q8VrNdp2F40jPDhN5PmLGbpeNgGiGguVic9Cv6OIMaxBd43mAgWfEW14M +vKNQ3fD+1jhZHjphd3yZAYrVyZ+obw1WwFmpJ08qBEs4mVwfVn/eX9N8vhRiZzpausisl 0IwW7JF8AV1KImvIC3w+Fxivh/ZG42vKHkfTuzXien+vGR5qufBUj/v3ix/7JA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1755262918; a=rsa-sha256; cv=none; b=swoPk7q7zEa1sGYmC2j7uyO3hnap8mtPitG+XPa8AIWbYJ72X4YiqYMyxoH5nGXtsYnDN2 WudxwNDmF113xA/MBi5W4PLoNmukIPmF4bXeJXb4EtZNOCGuq00J59JoJnobPQq1/qPWOV WpIXjyG0wlGbeBEKwyVZKd+w/TTWt9CY/6loDoNGg+gnmvgaAqk1UXy7hXCLyO3XI9d0Os nVxNGupFyuIGMcu1Lx83E8c9K3zOcwTcSGW+uWhgeC0bxTtO0QzrOFEgz+veJ5Ggk+JCd8 TdykZEtjH8DTA/KII7SvRtZtJkttTAnL9sUSKUKD3CvlzTp9s6+y+H+pUiKuXg== Received: from aokblastdeMacBook-Pro.local (2001-b011-3808-134d-09b0-75ff-8527-aebd.dynamic-ip6.hinet.net [IPv6:2001:b011:3808:134d:9b0:75ff:8527:aebd]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (prime256v1) server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: aokblast) by smtp.freebsd.org (Postfix) with ESMTPSA id 4c3Mh532dJz12Kl; Fri, 15 Aug 2025 13:01:57 +0000 (UTC) (envelope-from aokblast@freebsd.org) From: ShengYi Hung To: src-committers@FreeBSD.org Cc: dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: Re: git: c992ac621327 - main - ipheth(4): Add CDC-NCM support for RX In-Reply-To: <202508150501.57F51usB044759@gitrepo.freebsd.org> (ShengYi Hung's message of "Fri, 15 Aug 2025 05:01:56 GMT") References: <202508150501.57F51usB044759@gitrepo.freebsd.org> User-Agent: mu4e 1.12.12; emacs 30.1 Date: Fri, 15 Aug 2025 21:01:52 +0800 Message-ID: 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 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Oops, The Differential Revision entry missed in the commit mesasge. The link is over here: https://reviews.freebsd.org/D49431. Sorry! ShengYi Hung writes: > The branch main has been updated by aokblast: > > URL: https://cgit.FreeBSD.org/src/commit/?id=3Dc992ac6213276f54d868f317cc= 5092f8aed4ff54 > > commit c992ac6213276f54d868f317cc5092f8aed4ff54 > Author: ShengYi Hung > AuthorDate: 2025-05-15 10:54:09 +0000 > Commit: ShengYi Hung > CommitDate: 2025-08-15 05:01:17 +0000 > > ipheth(4): Add CDC-NCM support for RX >=20=20=20=20=20 > The CDC-NCM (USB Communications Device Class =E2=80=93 Network Contro= l Model) > protocol allows multiple Ethernet frames to be encapsulated into a si= ngle > USB transfer. >=20=20=20=20=20 > On iOS, CDC-NCM is currently implemented for RX only and uses a fixed= number > of entries (16). To maintain compatibility with older iOS versions, w= e attempt > to enable NCM on the USB device first; if this fails, we fall back to= the > original behavior. >=20=20=20=20=20 > Approved by: lwhsu (mentor), markj (mentor) > MFC after: 2 weeks > Sponsored by: The FreeBSD Foundation > --- > sys/dev/usb/net/if_ipheth.c | 218 ++++++++++++++++++++++++++++++++---= ------ > sys/dev/usb/net/if_iphethvar.h | 21 ++++ > 2 files changed, 191 insertions(+), 48 deletions(-) > > diff --git a/sys/dev/usb/net/if_ipheth.c b/sys/dev/usb/net/if_ipheth.c > index f70113c53eb4..cfa800707391 100644 > --- a/sys/dev/usb/net/if_ipheth.c > +++ b/sys/dev/usb/net/if_ipheth.c > @@ -55,6 +55,7 @@ > #include >=20=20 > #include > +#include > #include > #include > #include "usbdevs.h" > @@ -81,6 +82,9 @@ static uether_fn_t ipheth_start; > static uether_fn_t ipheth_setmulti; > static uether_fn_t ipheth_setpromisc; >=20=20 > +static ipheth_consumer_t ipheth_consume_read; > +static ipheth_consumer_t ipheth_consume_read_ncm; > + > #ifdef USB_DEBUG > static int ipheth_debug =3D 0; >=20=20 > @@ -96,7 +100,31 @@ static const struct usb_config ipheth_config[IPHETH_N= _TRANSFER] =3D { > .direction =3D UE_DIR_RX, > .frames =3D IPHETH_RX_FRAMES_MAX, > .bufsize =3D (IPHETH_RX_FRAMES_MAX * MCLBYTES), > - .flags =3D {.short_frames_ok =3D 1,.short_xfer_ok =3D 1,.ext_buffer = =3D 1,}, > + .flags =3D {.short_frames_ok =3D 1, .short_xfer_ok =3D 1, .ext_buffer = =3D 1,}, > + .callback =3D ipheth_bulk_read_callback, > + .timeout =3D 0, /* no timeout */ > + }, > + > + [IPHETH_BULK_TX] =3D { > + .type =3D UE_BULK, > + .endpoint =3D UE_ADDR_ANY, > + .direction =3D UE_DIR_TX, > + .frames =3D IPHETH_TX_FRAMES_MAX, > + .bufsize =3D (IPHETH_TX_FRAMES_MAX * IPHETH_BUF_SIZE), > + .flags =3D {.force_short_xfer =3D 1,}, > + .callback =3D ipheth_bulk_write_callback, > + .timeout =3D IPHETH_TX_TIMEOUT, > + }, > +}; > + > +static const struct usb_config ipheth_config_ncm[IPHETH_N_TRANSFER] =3D { > + [IPHETH_BULK_RX] =3D { > + .type =3D UE_BULK, > + .endpoint =3D UE_ADDR_ANY, > + .direction =3D UE_DIR_RX, > + .frames =3D 1, > + .bufsize =3D IPHETH_RX_NCM_BUF_SIZE, > + .flags =3D {.short_frames_ok =3D 1, .short_xfer_ok =3D 1,}, > .callback =3D ipheth_bulk_read_callback, > .timeout =3D 0, /* no timeout */ > }, > @@ -204,6 +232,21 @@ ipheth_get_mac_addr(struct ipheth_softc *sc) > return (0); > } >=20=20 > +static bool > +ipheth_enable_ncm(struct ipheth_softc *sc) > +{ > + struct usb_device_request req; > + > + req.bmRequestType =3D UT_WRITE_VENDOR_INTERFACE; > + req.bRequest =3D IPHETH_CMD_ENABLE_NCM; > + USETW(req.wValue, 0); > + req.wIndex[0] =3D sc->sc_iface_no; > + req.wIndex[1] =3D 0; > + USETW(req.wLength, 0); > + > + return (usbd_do_request(sc->sc_ue.ue_udev, NULL, &req, NULL) =3D=3D 0); > +} > + > static int > ipheth_probe(device_t dev) > { > @@ -221,6 +264,7 @@ ipheth_attach(device_t dev) > struct ipheth_softc *sc =3D device_get_softc(dev); > struct usb_ether *ue =3D &sc->sc_ue; > struct usb_attach_arg *uaa =3D device_get_ivars(dev); > + const struct usb_config *config; > int error; >=20=20 > sc->sc_iface_no =3D uaa->info.bIfaceIndex; > @@ -235,18 +279,29 @@ ipheth_attach(device_t dev) > device_printf(dev, "Cannot set alternate setting\n"); > goto detach; > } > - error =3D usbd_transfer_setup(uaa->device, &sc->sc_iface_no, > - sc->sc_xfer, ipheth_config, IPHETH_N_TRANSFER, sc, &sc->sc_mtx); > - if (error) { > - device_printf(dev, "Cannot setup USB transfers\n"); > - goto detach; > - } > + > ue->ue_sc =3D sc; > ue->ue_dev =3D dev; > ue->ue_udev =3D uaa->device; > ue->ue_mtx =3D &sc->sc_mtx; > ue->ue_methods =3D &ipheth_ue_methods; >=20=20 > + if (ipheth_enable_ncm(sc)) { > + config =3D ipheth_config_ncm; > + sc->is_ncm =3D true; > + sc->consume =3D &ipheth_consume_read_ncm; > + } else { > + config =3D ipheth_config; > + sc->consume =3D &ipheth_consume_read; > + } > + > + error =3D usbd_transfer_setup(uaa->device, &sc->sc_iface_no, sc->sc_xfe= r, > + config, IPHETH_N_TRANSFER, sc, &sc->sc_mtx); > + if (error) { > + device_printf(dev, "Cannot setup USB transfers\n"); > + goto detach; > + } > + > error =3D ipheth_get_mac_addr(sc); > if (error) { > device_printf(dev, "Cannot get MAC address\n"); > @@ -389,12 +444,9 @@ ipheth_bulk_write_callback(struct usb_xfer *xfer, us= b_error_t error) > int actlen; > int aframes; >=20=20 > - usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL); > - > - DPRINTFN(1, "\n"); > - > switch (USB_GET_STATE(xfer)) { > case USB_ST_TRANSFERRED: > + usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL); > DPRINTFN(11, "transfer complete: %u bytes in %u frames\n", > actlen, aframes); >=20=20 > @@ -471,53 +523,40 @@ ipheth_bulk_read_callback(struct usb_xfer *xfer, us= b_error_t error) > uint8_t x; > int actlen; > int aframes; > - int len; > - > - usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL); >=20=20 > switch (USB_GET_STATE(xfer)) { > case USB_ST_TRANSFERRED: > - > + usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL); > DPRINTF("received %u bytes in %u frames\n", actlen, aframes); >=20=20 > - for (x =3D 0; x !=3D aframes; x++) { > - m =3D sc->sc_rx_buf[x]; > - sc->sc_rx_buf[x] =3D NULL; > - len =3D usbd_xfer_frame_len(xfer, x); > - > - if (len < (int)(sizeof(struct ether_header) + > - IPHETH_RX_ADJ)) { > - m_freem(m); > - continue; > - } > - > - m_adj(m, IPHETH_RX_ADJ); > - > - /* queue up mbuf */ > - uether_rxmbuf(&sc->sc_ue, m, len - IPHETH_RX_ADJ); > - } > + for (x =3D 0; x !=3D aframes; x++) > + sc->consume(xfer, x); >=20=20 > /* FALLTHROUGH */ > case USB_ST_SETUP: > - > - for (x =3D 0; x !=3D IPHETH_RX_FRAMES_MAX; x++) { > - if (sc->sc_rx_buf[x] =3D=3D NULL) { > - m =3D uether_newbuf(); > - if (m =3D=3D NULL) > - goto tr_stall; > - > - /* cancel alignment for ethernet */ > - m_adj(m, ETHER_ALIGN); > - > - sc->sc_rx_buf[x] =3D m; > - } else { > - m =3D sc->sc_rx_buf[x]; > + if (!sc->is_ncm) { > + for (x =3D 0; x !=3D IPHETH_RX_FRAMES_MAX; x++) { > + if (sc->sc_rx_buf[x] =3D=3D NULL) { > + m =3D uether_newbuf(); > + if (m =3D=3D NULL) > + goto tr_stall; > + > + /* cancel alignment for ethernet */ > + m_adj(m, ETHER_ALIGN); > + > + sc->sc_rx_buf[x] =3D m; > + } else { > + m =3D sc->sc_rx_buf[x]; > + } > + usbd_xfer_set_frame_data(xfer, x, m->m_data, m->m_len); > } > - > - usbd_xfer_set_frame_data(xfer, x, m->m_data, m->m_len); > + usbd_xfer_set_frames(xfer, x); > + } else { > + usbd_xfer_set_frame_len(xfer, 0, > + IPHETH_RX_NCM_BUF_SIZE); > + usbd_xfer_set_frames(xfer, 1); > } > - /* set number of frames and start hardware */ > - usbd_xfer_set_frames(xfer, x); > + > usbd_transfer_submit(xfer); > /* flush any received frames */ > uether_rxflush(&sc->sc_ue); > @@ -539,3 +578,86 @@ ipheth_bulk_read_callback(struct usb_xfer *xfer, usb= _error_t error) > break; > } > } > + > +static void > +ipheth_consume_read(struct usb_xfer *xfer, int x) > +{ > + struct ipheth_softc *sc =3D usbd_xfer_softc(xfer); > + struct mbuf *m =3D sc->sc_rx_buf[x]; > + int len; > + > + sc->sc_rx_buf[x] =3D NULL; > + len =3D usbd_xfer_frame_len(xfer, x); > + > + if (len < (int)(sizeof(struct ether_header) + IPHETH_RX_ADJ)) { > + m_freem(m); > + return; > + } > + > + m_adj(m, IPHETH_RX_ADJ); > + > + /* queue up mbuf */ > + uether_rxmbuf(&sc->sc_ue, m, len - IPHETH_RX_ADJ); > +} > + > +static void > +ipheth_consume_read_ncm(struct usb_xfer *xfer, int x) > +{ > + struct ipheth_softc *sc =3D usbd_xfer_softc(xfer); > + struct usb_page_cache *pc =3D usbd_xfer_get_frame(xfer, 0); > + struct ncm_data_cache ncm; > + if_t ifp =3D uether_getifp(&sc->sc_ue); > + struct mbuf *new_buf; > + int i, actlen; > + uint16_t dp_offset, dp_len; > + > + usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); > + > + if (actlen < IPHETH_NCM_HEADER_SIZE) > + return; > + > + usbd_copy_out(pc, 0, &ncm.hdr, sizeof(ncm.hdr)); > + > + if (UGETDW(ncm.hdr.dwSignature) !=3D 0x484D434E) > + return; > + > + /* Dpt follows the hdr on iOS */ > + if (UGETW(ncm.hdr.wDptIndex) !=3D (int)(sizeof(struct usb_ncm16_hdr))) > + return; > + > + usbd_copy_out(pc, UGETW(ncm.hdr.wDptIndex), &ncm.dpt, sizeof(ncm.dpt)); > + > + if (UGETDW(ncm.dpt.dwSignature) !=3D 0x304D434E) > + return; > + > + usbd_copy_out(pc, UGETW(ncm.hdr.wDptIndex) + sizeof(ncm.dpt), &ncm.dp, > + sizeof(ncm.dp)); > + > + for (i =3D 0; i < IPHETH_NCM_DPT_DP_NUM; ++i) { > + dp_offset =3D UGETW(ncm.dp[i].wFrameIndex); > + dp_len =3D UGETW(ncm.dp[i].wFrameLength); > + > + /* (3.3.1 USB CDC NCM spec v1.0) */ > + if (dp_offset =3D=3D 0 && dp_len =3D=3D 0) > + break; > + > + if (dp_offset < IPHETH_NCM_HEADER_SIZE || dp_offset >=3D actlen || > + actlen < (dp_len + dp_offset) || > + dp_len < sizeof(struct ether_header)) { > + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); > + continue; > + } > + if (dp_len > (MCLBYTES - ETHER_ALIGN)) { > + if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); > + continue; > + } > + > + new_buf =3D uether_newbuf(); > + if (new_buf =3D=3D NULL) { > + if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); > + continue; > + } > + usbd_copy_out(pc, dp_offset, new_buf->m_data, dp_len); > + uether_rxmbuf(&sc->sc_ue, new_buf, dp_len); > + } > +} > diff --git a/sys/dev/usb/net/if_iphethvar.h b/sys/dev/usb/net/if_iphethva= r.h > index 203bb96b6f22..d637e8f67d01 100644 > --- a/sys/dev/usb/net/if_iphethvar.h > +++ b/sys/dev/usb/net/if_iphethvar.h > @@ -41,6 +41,7 @@ > #define IPHETH_BUF_SIZE 1514 > #define IPHETH_TX_TIMEOUT 5000 /* ms */ >=20=20 > +#define IPHETH_RX_NCM_BUF_SIZE 65536 > #define IPHETH_RX_FRAMES_MAX 1 > #define IPHETH_TX_FRAMES_MAX 8 >=20=20 > @@ -55,10 +56,20 @@ > #define IPHETH_CTRL_TIMEOUT 5000 /* ms */ >=20=20 > #define IPHETH_CMD_GET_MACADDR 0x00 > +#define IPHETH_CMD_ENABLE_NCM 0x04 > #define IPHETH_CMD_CARRIER_CHECK 0x45 >=20=20 > #define IPHETH_CARRIER_ON 0x04 >=20=20 > +#define IPHETH_NCM_DPT_DP_NUM 22 > +#define IPHETH_NCM_DPT_HEADER_SIZE \ > + (sizeof(struct usb_ncm16_dpt) + \ > + IPHETH_NCM_DPT_DP_NUM * sizeof(struct usb_ncm16_dp)) > +#define IPHETH_NCM_HEADER_SIZE \ > + (sizeof(struct usb_ncm16_hdr) + IPHETH_NCM_DPT_HEADER_SIZE) > + > +typedef void (ipheth_consumer_t)(struct usb_xfer *xfer, int idx); > + > enum { > IPHETH_BULK_TX, > IPHETH_BULK_RX, > @@ -76,6 +87,16 @@ struct ipheth_softc { > uint8_t sc_data[IPHETH_CTRL_BUF_SIZE]; > uint8_t sc_iface_no; > uint8_t sc_carrier_on; > + > + bool is_ncm; > + > + ipheth_consumer_t *consume; > +}; > + > +struct ncm_data_cache { > + struct usb_ncm16_hdr hdr; > + struct usb_ncm16_dpt dpt; > + struct usb_ncm16_dp dp[IPHETH_NCM_DPT_DP_NUM]; > }; >=20=20 > #define IPHETH_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) --=20 Best Regards. ShengYi Hung.