From owner-dev-commits-src-all@freebsd.org Tue Sep 28 07:33:43 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id D390E678465; Tue, 28 Sep 2021 07:33:43 +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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4HJWTM4q1hz4ZHd; Tue, 28 Sep 2021 07:33:43 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 5D81220981; Tue, 28 Sep 2021 07:33:43 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 18S7Xh3p089372; Tue, 28 Sep 2021 07:33:43 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 18S7Xhsr089371; Tue, 28 Sep 2021 07:33:43 GMT (envelope-from git) Date: Tue, 28 Sep 2021 07:33:43 GMT Message-Id: <202109280733.18S7Xhsr089371@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Wojciech Macek Subject: git: 28df957acb93 - stable/13 - if_cdce: Add support for setting RX filtering MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: wma X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 28df957acb9342c52587774d3c4c530ea9980a85 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 28 Sep 2021 07:33:44 -0000 The branch stable/13 has been updated by wma: URL: https://cgit.FreeBSD.org/src/commit/?id=28df957acb9342c52587774d3c4c530ea9980a85 commit 28df957acb9342c52587774d3c4c530ea9980a85 Author: Kornel Duleba AuthorDate: 2021-08-31 12:22:30 +0000 Commit: Wojciech Macek CommitDate: 2021-09-28 07:03:48 +0000 if_cdce: Add support for setting RX filtering We can now set promisc and allmulti modes. Filtering of given multicast addresses is not supported. Changing the mode is done by sending a command described in: "USB CDC Subclass Specification for Ethernet Devices v1.2, section 6.2.4". This means that at least in theory this feature should work with all modems that are using this driver. This fixes Huawei E3372h-320 running new firmware in "HiLink" mode. Previously it would reset a few seconds after its mode was changed with "usb_modeswitch". Setting RX filter to default value at the end of attach function fixed that. Sponsored by: Stormshield Obtained from: Semihalf Differential revision: https://reviews.freebsd.org/D31766 MFC after: 2 weeks Reviewed by: hps (cherry picked from commit f0c393f781f01ffa727f90a8593e26a20869438b) --- sys/dev/usb/net/if_cdce.c | 41 +++++++++++++++++++++++++++++++++++++---- sys/dev/usb/net/if_cdcereg.h | 15 +++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c index 24813ea305e4..ebc68e1f71cc 100644 --- a/sys/dev/usb/net/if_cdce.c +++ b/sys/dev/usb/net/if_cdce.c @@ -117,6 +117,7 @@ static int cdce_media_change_cb(struct ifnet *); static void cdce_media_status_cb(struct ifnet *, struct ifmediareq *); static uint32_t cdce_m_crc32(struct mbuf *, uint32_t, uint32_t); +static void cdce_set_filter(struct usb_ether *); #ifdef USB_DEBUG static int cdce_debug = 0; @@ -593,6 +594,9 @@ cdce_attach_post_sub(struct usb_ether *ue) ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL); ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO); sc->sc_media.ifm_media = sc->sc_media.ifm_cur->ifm_media; + CDCE_LOCK(sc); + cdce_set_filter(ue); + CDCE_UNLOCK(sc); return 0; } @@ -1025,15 +1029,44 @@ cdce_stop(struct usb_ether *ue) static void cdce_setmulti(struct usb_ether *ue) { - /* no-op */ - return; + + cdce_set_filter(ue); } static void cdce_setpromisc(struct usb_ether *ue) { - /* no-op */ - return; + + cdce_set_filter(ue); +} + +static void +cdce_set_filter(struct usb_ether *ue) +{ + struct cdce_softc *sc = uether_getsc(ue); + struct ifnet *ifp = uether_getifp(ue); + struct usb_device_request req; + uint16_t value; + + value = CDC_PACKET_TYPE_DIRECTED | CDC_PACKET_TYPE_BROADCAST; + if (if_getflags(ifp) & IFF_PROMISC) + value |= CDC_PACKET_TYPE_PROMISC; + if (if_getflags(ifp) & IFF_ALLMULTI) + value |= CDC_PACKET_TYPE_ALL_MULTICAST; + + req.bmRequestType = UT_CLASS | UT_INTERFACE; + req.bRequest = CDC_SET_ETHERNET_PACKET_FILTER; + USETW(req.wValue, value); + req.wIndex[0] = sc->sc_ifaces_index[1]; + req.wIndex[1] = 0; + USETW(req.wLength, 0); + + /* + * Function below will drop the sc mutex. + * We can do that since we're called from a separate task, + * that simply wraps the setpromisc/setmulti methods. + */ + usbd_do_request(sc->sc_ue.ue_udev, &sc->sc_mtx, &req, NULL); } static int diff --git a/sys/dev/usb/net/if_cdcereg.h b/sys/dev/usb/net/if_cdcereg.h index 724aa0b9b017..19a7ac354341 100644 --- a/sys/dev/usb/net/if_cdcereg.h +++ b/sys/dev/usb/net/if_cdcereg.h @@ -37,6 +37,8 @@ #ifndef _USB_IF_CDCEREG_H_ #define _USB_IF_CDCEREG_H_ +#define CDCE_BIT(x) (1 << (x)) + #define CDCE_FRAMES_MAX 8 /* units */ #define CDCE_IND_SIZE_MAX 32 /* bytes */ @@ -104,6 +106,19 @@ struct cdce_softc { #define CDCE_NOTIFY_DONE 2 }; +/* + * Taken from USB CDC Subclass Specification for Ethernet Devices v1.2, + * section 6.2.4. + */ + +#define CDC_SET_ETHERNET_PACKET_FILTER 0x43 /* Command code. */ + +#define CDC_PACKET_TYPE_PROMISC CDCE_BIT(0) +#define CDC_PACKET_TYPE_ALL_MULTICAST CDCE_BIT(1) /* Allmulti. */ +#define CDC_PACKET_TYPE_DIRECTED CDCE_BIT(2) /* Filter unicast by mac. */ +#define CDC_PACKET_TYPE_BROADCAST CDCE_BIT(3) +#define CDC_PACKET_TYPE_MULTICAST CDCE_BIT(4) /* Multicast filtering, not supported. */ + #define CDCE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) #define CDCE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) #define CDCE_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->sc_mtx, t)