Thu Jul 15 03:25:50 2021 UTC ()
explanation typo


(nisimura)
diff -r1.60 -r1.61 src/sys/dev/usb/if_mue.c
diff -r1.38 -r1.39 src/sys/dev/usb/uchcom.c

cvs diff -r1.60 -r1.61 src/sys/dev/usb/if_mue.c (expand / switch to unified diff)

--- src/sys/dev/usb/if_mue.c 2020/06/27 13:33:26 1.60
+++ src/sys/dev/usb/if_mue.c 2021/07/15 03:25:50 1.61
@@ -1,36 +1,36 @@ @@ -1,36 +1,36 @@
1/* $NetBSD: if_mue.c,v 1.60 2020/06/27 13:33:26 jmcneill Exp $ */ 1/* $NetBSD: if_mue.c,v 1.61 2021/07/15 03:25:50 nisimura Exp $ */
2/* $OpenBSD: if_mue.c,v 1.3 2018/08/04 16:42:46 jsg Exp $ */ 2/* $OpenBSD: if_mue.c,v 1.3 2018/08/04 16:42:46 jsg Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2018 Kevin Lo <kevlo@openbsd.org> 5 * Copyright (c) 2018 Kevin Lo <kevlo@openbsd.org>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */ 18 */
19 19
20/* Driver for Microchip LAN7500/LAN7800 chipsets. */ 20/* Driver for Microchip LAN7500/LAN7800 chipsets. */
21 21
22#include <sys/cdefs.h> 22#include <sys/cdefs.h>
23__KERNEL_RCSID(0, "$NetBSD: if_mue.c,v 1.60 2020/06/27 13:33:26 jmcneill Exp $"); 23__KERNEL_RCSID(0, "$NetBSD: if_mue.c,v 1.61 2021/07/15 03:25:50 nisimura Exp $");
24 24
25#ifdef _KERNEL_OPT 25#ifdef _KERNEL_OPT
26#include "opt_usb.h" 26#include "opt_usb.h"
27#include "opt_inet.h" 27#include "opt_inet.h"
28#endif 28#endif
29 29
30#include <sys/param.h> 30#include <sys/param.h>
31 31
32#include <dev/usb/usbnet.h> 32#include <dev/usb/usbnet.h>
33 33
34#include <dev/usb/if_muereg.h> 34#include <dev/usb/if_muereg.h>
35#include <dev/usb/if_muevar.h> 35#include <dev/usb/if_muevar.h>
36 36
@@ -88,66 +88,73 @@ static bool mue_eeprom_present(struct us @@ -88,66 +88,73 @@ static bool mue_eeprom_present(struct us
88static void mue_dataport_write(struct usbnet *, uint32_t, uint32_t, 88static void mue_dataport_write(struct usbnet *, uint32_t, uint32_t,
89 uint32_t, uint32_t *); 89 uint32_t, uint32_t *);
90static void mue_init_ltm(struct usbnet *); 90static void mue_init_ltm(struct usbnet *);
91static int mue_chip_init(struct usbnet *); 91static int mue_chip_init(struct usbnet *);
92static void mue_set_macaddr(struct usbnet *); 92static void mue_set_macaddr(struct usbnet *);
93static int mue_get_macaddr(struct usbnet *, prop_dictionary_t); 93static int mue_get_macaddr(struct usbnet *, prop_dictionary_t);
94static int mue_prepare_tso(struct usbnet *, struct mbuf *); 94static int mue_prepare_tso(struct usbnet *, struct mbuf *);
95static void mue_setiff_locked(struct usbnet *); 95static void mue_setiff_locked(struct usbnet *);
96static void mue_sethwcsum_locked(struct usbnet *); 96static void mue_sethwcsum_locked(struct usbnet *);
97static void mue_setmtu_locked(struct usbnet *); 97static void mue_setmtu_locked(struct usbnet *);
98static void mue_reset(struct usbnet *); 98static void mue_reset(struct usbnet *);
99 99
100static void mue_uno_stop(struct ifnet *, int); 100static void mue_uno_stop(struct ifnet *, int);
101static int mue_uno_ioctl(struct ifnet *, u_long, void *); 101static int mue_uno_override_ioctl(struct ifnet *, u_long, void *);
102static int mue_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *); 102static int mue_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
103static int mue_uno_mii_write_reg(struct usbnet *, int, int, uint16_t); 103static int mue_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
104static void mue_uno_mii_statchg(struct ifnet *); 104static void mue_uno_mii_statchg(struct ifnet *);
105static void mue_uno_rx_loop(struct usbnet *, struct usbnet_chain *, 105static void mue_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
106 uint32_t); 106 uint32_t);
107static unsigned mue_uno_tx_prepare(struct usbnet *, struct mbuf *, 107static unsigned mue_uno_tx_prepare(struct usbnet *, struct mbuf *,
108 struct usbnet_chain *); 108 struct usbnet_chain *);
109static int mue_uno_init(struct ifnet *); 109static int mue_uno_init(struct ifnet *);
110 110
111static const struct usbnet_ops mue_ops = { 111static const struct usbnet_ops mue_ops = {
112 .uno_stop = mue_uno_stop, 112 .uno_stop = mue_uno_stop,
113 .uno_ioctl = mue_uno_ioctl, 113 .uno_override_ioctl = mue_uno_override_ioctl,
114 .uno_read_reg = mue_uno_mii_read_reg, 114 .uno_read_reg = mue_uno_mii_read_reg,
115 .uno_write_reg = mue_uno_mii_write_reg, 115 .uno_write_reg = mue_uno_mii_write_reg,
116 .uno_statchg = mue_uno_mii_statchg, 116 .uno_statchg = mue_uno_mii_statchg,
117 .uno_tx_prepare = mue_uno_tx_prepare, 117 .uno_tx_prepare = mue_uno_tx_prepare,
118 .uno_rx_loop = mue_uno_rx_loop, 118 .uno_rx_loop = mue_uno_rx_loop,
119 .uno_init = mue_uno_init, 119 .uno_init = mue_uno_init,
120}; 120};
121 121
122#define MUE_SETBIT(un, reg, x) \ 122#define MUE_SETBIT(un, reg, x) \
123 mue_csr_write(un, reg, mue_csr_read(un, reg) | (x)) 123 mue_csr_write(un, reg, mue_csr_read(un, reg) | (x))
124 124
125#define MUE_CLRBIT(un, reg, x) \ 125#define MUE_CLRBIT(un, reg, x) \
126 mue_csr_write(un, reg, mue_csr_read(un, reg) & ~(x)) 126 mue_csr_write(un, reg, mue_csr_read(un, reg) & ~(x))
127 127
128#define MUE_WAIT_SET(un, reg, set, fail) \ 128#define MUE_WAIT_SET(un, reg, set, fail) \
129 mue_wait_for_bits(un, reg, set, ~0, fail) 129 mue_wait_for_bits(un, reg, set, ~0, fail)
130 130
131#define MUE_WAIT_CLR(un, reg, clear, fail) \ 131#define MUE_WAIT_CLR(un, reg, clear, fail) \
132 mue_wait_for_bits(un, reg, 0, clear, fail) 132 mue_wait_for_bits(un, reg, 0, clear, fail)
133 133
134#define ETHER_IS_VALID(addr) \ 134#define ETHER_IS_VALID(addr) \
135 (!ETHER_IS_MULTICAST(addr) && !ETHER_IS_ZERO(addr)) 135 (!ETHER_IS_MULTICAST(addr) && !ETHER_IS_ZERO(addr))
136 136
137#define ETHER_IS_ZERO(addr) \ 137#define ETHER_IS_ZERO(addr) \
138 (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5])) 138 (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]))
139 139
140CFATTACH_DECL_NEW(mue, sizeof(struct usbnet), mue_match, mue_attach, 140struct mue_softc {
 141 struct usbnet sc_un;
 142 struct usbnet_intr sc_intr;
 143 uint8_t sc_ibuf[8];
 144 unsigned sc_flowflags; /* 802.3x PAUSE flow control */
 145};
 146
 147CFATTACH_DECL_NEW(mue, sizeof(struct mue_softc), mue_match, mue_attach,
141 usbnet_detach, usbnet_activate); 148 usbnet_detach, usbnet_activate);
142 149
143static uint32_t 150static uint32_t
144mue_csr_read(struct usbnet *un, uint32_t reg) 151mue_csr_read(struct usbnet *un, uint32_t reg)
145{ 152{
146 usb_device_request_t req; 153 usb_device_request_t req;
147 usbd_status err; 154 usbd_status err;
148 uDWord val; 155 uDWord val;
149 156
150 if (usbnet_isdying(un)) 157 if (usbnet_isdying(un))
151 return 0; 158 return 0;
152 159
153 USETDW(val, 0); 160 USETDW(val, 0);
@@ -750,49 +757,50 @@ mue_get_macaddr(struct usbnet *un, prop_ @@ -750,49 +757,50 @@ mue_get_macaddr(struct usbnet *un, prop_
750 */ 757 */
751static int 758static int
752mue_match(device_t parent, cfdata_t match, void *aux) 759mue_match(device_t parent, cfdata_t match, void *aux)
753{ 760{
754 struct usb_attach_arg *uaa = aux; 761 struct usb_attach_arg *uaa = aux;
755 762
756 return (MUE_LOOKUP(uaa) != NULL) ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 763 return (MUE_LOOKUP(uaa) != NULL) ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
757} 764}
758 765
759static void 766static void
760mue_attach(device_t parent, device_t self, void *aux) 767mue_attach(device_t parent, device_t self, void *aux)
761{ 768{
762 USBNET_MII_DECL_DEFAULT(unm); 769 USBNET_MII_DECL_DEFAULT(unm);
763 struct usbnet * const un = device_private(self); 
764 prop_dictionary_t dict = device_properties(self); 770 prop_dictionary_t dict = device_properties(self);
 771 struct mue_softc * const sc = device_private(self);
765 struct usb_attach_arg *uaa = aux; 772 struct usb_attach_arg *uaa = aux;
766 struct usbd_device *dev = uaa->uaa_device; 773 struct usbd_device *dev = uaa->uaa_device;
 774 struct usbnet *un = &sc->sc_un;
767 usb_interface_descriptor_t *id; 775 usb_interface_descriptor_t *id;
768 usb_endpoint_descriptor_t *ed; 776 usb_endpoint_descriptor_t *ed;
769 char *devinfop; 
770 usbd_status err; 777 usbd_status err;
 778 char *devinfop;
771 const char *descr; 779 const char *descr;
772 uint32_t id_rev; 780 uint32_t id_rev;
773 uint8_t i; 781 uint8_t i;
774 unsigned rx_list_cnt, tx_list_cnt; 782 unsigned rx_list_cnt, tx_list_cnt;
775 unsigned rx_bufsz; 783 unsigned rx_bufsz;
776 784
777 aprint_naive("\n"); 785 aprint_naive("\n");
778 aprint_normal("\n"); 786 aprint_normal("\n");
779 devinfop = usbd_devinfo_alloc(dev, 0); 787 devinfop = usbd_devinfo_alloc(dev, 0);
780 aprint_normal_dev(self, "%s\n", devinfop); 788 aprint_normal_dev(self, "%s\n", devinfop);
781 usbd_devinfo_free(devinfop); 789 usbd_devinfo_free(devinfop);
782 790
783 un->un_dev = self; 791 un->un_dev = self;
784 un->un_udev = dev; 792 un->un_udev = dev;
785 un->un_sc = un; 793 un->un_sc = sc; /* @@! */
786 un->un_ops = &mue_ops; 794 un->un_ops = &mue_ops;
787 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 795 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
788 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 796 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
789 797
790#define MUE_CONFIG_NO 1 798#define MUE_CONFIG_NO 1
791 err = usbd_set_config_no(dev, MUE_CONFIG_NO, 1); 799 err = usbd_set_config_no(dev, MUE_CONFIG_NO, 1);
792 if (err) { 800 if (err) {
793 aprint_error_dev(self, "failed to set configuration: %s\n", 801 aprint_error_dev(self, "failed to set configuration: %s\n",
794 usbd_errstr(err)); 802 usbd_errstr(err));
795 return; 803 return;
796 } 804 }
797 805
798#define MUE_IFACE_IDX 0 806#define MUE_IFACE_IDX 0
@@ -874,26 +882,28 @@ mue_attach(device_t parent, device_t sel @@ -874,26 +882,28 @@ mue_attach(device_t parent, device_t sel
874 ifp->if_capabilities = IFCAP_TSOv4 | IFCAP_TSOv6 | 882 ifp->if_capabilities = IFCAP_TSOv4 | IFCAP_TSOv6 |
875 IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx | 883 IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx |
876 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx | 884 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx |
877 IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx | 885 IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx |
878 IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_TCPv6_Rx | 886 IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_TCPv6_Rx |
879 IFCAP_CSUM_UDPv6_Tx | IFCAP_CSUM_UDPv6_Rx; 887 IFCAP_CSUM_UDPv6_Tx | IFCAP_CSUM_UDPv6_Rx;
880 888
881 struct ethercom *ec = usbnet_ec(un); 889 struct ethercom *ec = usbnet_ec(un);
882 ec->ec_capabilities = ETHERCAP_VLAN_MTU; 890 ec->ec_capabilities = ETHERCAP_VLAN_MTU;
883#if 0 /* XXX not yet */ 891#if 0 /* XXX not yet */
884 ec->ec_capabilities = ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU; 892 ec->ec_capabilities = ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU;
885#endif 893#endif
886 894
 895 unm.un_mii_phyloc = un->un_phyno; /* use internal PHY 1 */
 896 unm.un_mii_flags |= MIIF_DOPAUSE; /* use PAUSE cap. */
887 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 897 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
888 0, &unm); 898 0, &unm);
889} 899}
890 900
891static unsigned 901static unsigned
892mue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 902mue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
893{ 903{
894 struct ifnet * const ifp = usbnet_ifp(un); 904 struct ifnet * const ifp = usbnet_ifp(un);
895 struct mue_txbuf_hdr hdr; 905 struct mue_txbuf_hdr hdr;
896 uint32_t tx_cmd_a, tx_cmd_b; 906 uint32_t tx_cmd_a, tx_cmd_b;
897 int csum, len, rv; 907 int csum, len, rv;
898 bool tso, ipe, tpe; 908 bool tso, ipe, tpe;
899 909
@@ -987,110 +997,113 @@ mue_prepare_tso(struct usbnet *un, struc @@ -987,110 +997,113 @@ mue_prepare_tso(struct usbnet *un, struc
987 ip6->ip6_plen = 0; 997 ip6->ip6_plen = 0;
988 } else 998 } else
989 m_copyback(m, off + offsetof(struct ip6_hdr, ip6_plen), 999 m_copyback(m, off + offsetof(struct ip6_hdr, ip6_plen),
990 sizeof(len), &len); 1000 sizeof(len), &len);
991 } 1001 }
992 return 0; 1002 return 0;
993} 1003}
994 1004
995static void 1005static void
996mue_setiff_locked(struct usbnet *un) 1006mue_setiff_locked(struct usbnet *un)
997{ 1007{
998 struct ethercom *ec = usbnet_ec(un); 1008 struct ethercom *ec = usbnet_ec(un);
999 struct ifnet * const ifp = usbnet_ifp(un); 1009 struct ifnet * const ifp = usbnet_ifp(un);
1000 const uint8_t *enaddr = CLLADDR(ifp->if_sadl); 
1001 struct ether_multi *enm; 
1002 struct ether_multistep step; 1010 struct ether_multistep step;
1003 uint32_t pfiltbl[MUE_NUM_ADDR_FILTX][2]; 1011 struct ether_multi *enm;
1004 uint32_t hashtbl[MUE_DP_SEL_VHF_HASH_LEN]; 1012 uint32_t mchash[MUE_DP_SEL_VHF_HASH_LEN];
1005 uint32_t reg, rxfilt, h, hireg, loreg; 1013 uint32_t rfe, rxfilt, crc, hireg, loreg;
1006 size_t i; 1014 size_t i;
1007 1015
1008 if (usbnet_isdying(un)) 1016 if (usbnet_isdying(un))
1009 return; 1017 return;
1010 1018
1011 /* Clear perfect filter and hash tables. */ 1019 for (i = 1; i < MUE_NUM_ADDR_FILTX; i++) {
1012 memset(pfiltbl, 0, sizeof(pfiltbl)); 1020 hireg = (un->un_flags & LAN7500)
1013 memset(hashtbl, 0, sizeof(hashtbl)); 1021 ? MUE_7500_ADDR_FILTX(i) : MUE_7800_ADDR_FILTX(i);
 1022 mue_csr_write(un, hireg, 0);
 1023 }
 1024 memset(mchash, 0, sizeof(mchash));
1014 1025
1015 reg = (un->un_flags & LAN7500) ? MUE_7500_RFE_CTL : MUE_7800_RFE_CTL; 1026 rfe = (un->un_flags & LAN7500) ? MUE_7500_RFE_CTL : MUE_7800_RFE_CTL;
1016 rxfilt = mue_csr_read(un, reg); 1027 rxfilt = mue_csr_read(un, rfe);
1017 rxfilt &= ~(MUE_RFE_CTL_PERFECT | MUE_RFE_CTL_MULTICAST_HASH | 1028 rxfilt &= ~(MUE_RFE_CTL_MULTICAST_HASH |
1018 MUE_RFE_CTL_UNICAST | MUE_RFE_CTL_MULTICAST); 1029 MUE_RFE_CTL_UNICAST | MUE_RFE_CTL_MULTICAST);
1019 1030
1020 /* Always accept broadcast frames. */ 1031 ETHER_LOCK(ec);
1021 rxfilt |= MUE_RFE_CTL_BROADCAST; 
1022 
1023 if (ifp->if_flags & IFF_PROMISC) { 1032 if (ifp->if_flags & IFF_PROMISC) {
1024 rxfilt |= MUE_RFE_CTL_UNICAST; 1033 ec->ec_flags |= ETHER_F_ALLMULTI;
1025allmulti: rxfilt |= MUE_RFE_CTL_MULTICAST; 1034 ETHER_UNLOCK(ec);
1026 ifp->if_flags |= IFF_ALLMULTI; 1035 /* run promisc. mode */
1027 if (ifp->if_flags & IFF_PROMISC) 1036 rxfilt |= (MUE_RFE_CTL_UNICAST | MUE_RFE_CTL_MULTICAST);
1028 DPRINTF(un, "promisc\n"); 1037 DPRINTF(un, "promisc\n");
1029 else 1038 goto update;
1030 DPRINTF(un, "allmulti\n"); 1039 }
1031 } else { 1040 ec->ec_flags &= ~ETHER_F_ALLMULTI;
1032 /* Now program new ones. */ 1041 ETHER_FIRST_MULTI(step, ec, enm);
1033 pfiltbl[0][0] = MUE_ENADDR_HI(enaddr) | MUE_ADDR_FILTX_VALID; 1042 i = 1; /* the first slot is occupied by my station address */
1034 pfiltbl[0][1] = MUE_ENADDR_LO(enaddr); 1043 while (enm != NULL) {
1035 i = 1; 1044 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
1036 ETHER_LOCK(ec); 1045 /*
1037 ETHER_FIRST_MULTI(step, ec, enm); 1046 * We must listen to a range of multicast addresses.
1038 while (enm != NULL) { 1047 * For now, just accept all multicasts, rather than
1039 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 1048 * trying to set only those filter bits needed to match
1040 ETHER_ADDR_LEN)) { 1049 * the range. (At this time, the only use of address
1041 memset(pfiltbl, 0, sizeof(pfiltbl)); 1050 * ranges is for IP multicast routing, for which the
1042 memset(hashtbl, 0, sizeof(hashtbl)); 1051 * range is big enough to require all bits set.)
1043 rxfilt &= ~MUE_RFE_CTL_MULTICAST_HASH; 1052 */
1044 ETHER_UNLOCK(ec); 1053 ec->ec_flags |= ETHER_F_ALLMULTI;
1045 goto allmulti; 1054 ETHER_UNLOCK(ec);
1046 } 1055 /* accept all multicast */
1047 if (i < MUE_NUM_ADDR_FILTX) { 1056 for (i = 1; i < MUE_NUM_ADDR_FILTX; i++) {
1048 /* Use perfect address table if possible. */ 1057 hireg = (un->un_flags & LAN7500)
1049 pfiltbl[i][0] = MUE_ENADDR_HI(enm->enm_addrlo) | 1058 ? MUE_7500_ADDR_FILTX(i)
1050 MUE_ADDR_FILTX_VALID; 1059 : MUE_7800_ADDR_FILTX(i);
1051 pfiltbl[i][1] = MUE_ENADDR_LO(enm->enm_addrlo); 1060 mue_csr_write(un, hireg, 0);
1052 } else { 
1053 /* Otherwise, use hash table. */ 
1054 rxfilt |= MUE_RFE_CTL_MULTICAST_HASH; 
1055 h = (ether_crc32_be(enm->enm_addrlo, 
1056 ETHER_ADDR_LEN) >> 23) & 0x1ff; 
1057 hashtbl[h / 32] |= 1 << (h % 32); 
1058 } 1061 }
1059 i++; 1062 memset(mchash, 0, sizeof(mchash));
1060 ETHER_NEXT_MULTI(step, enm); 1063 rxfilt |= MUE_RFE_CTL_MULTICAST;
 1064 rxfilt &= ~MUE_RFE_CTL_MULTICAST_HASH;
 1065 DPRINTF(un, "allmulti\n");
 1066 goto update;
1061 } 1067 }
1062 ETHER_UNLOCK(ec); 1068 if (i < MUE_NUM_ADDR_FILTX) {
1063 rxfilt |= MUE_RFE_CTL_PERFECT; 1069 /* Use perfect address table if possible. */
1064 ifp->if_flags &= ~IFF_ALLMULTI; 1070 uint8_t *en = enm->enm_addrlo;
1065 if (rxfilt & MUE_RFE_CTL_MULTICAST_HASH) 1071 hireg = (un->un_flags & LAN7500) ?
1066 DPRINTF(un, "perfect filter and hash tables\n"); 1072 MUE_7500_ADDR_FILTX(i) : MUE_7800_ADDR_FILTX(i);
1067 else 1073 loreg = hireg + 4;
1068 DPRINTF(un, "perfect filter\n"); 1074 mue_csr_write(un, hireg, 0);
1069 } 1075 mue_csr_write(un, loreg, MUE_ENADDR_LO(en));
1070 1076 mue_csr_write(un, hireg, MUE_ENADDR_HI(en)
1071 for (i = 0; i < MUE_NUM_ADDR_FILTX; i++) { 1077 | MUE_ADDR_FILTX_VALID);
1072 hireg = (un->un_flags & LAN7500) ? 1078 } else {
1073 MUE_7500_ADDR_FILTX(i) : MUE_7800_ADDR_FILTX(i); 1079 /* Otherwise, use hash table. */
1074 loreg = hireg + 4; 1080 rxfilt |= MUE_RFE_CTL_MULTICAST_HASH;
1075 mue_csr_write(un, hireg, 0); 1081 crc = (ether_crc32_be(enm->enm_addrlo,
1076 mue_csr_write(un, loreg, pfiltbl[i][1]); 1082 ETHER_ADDR_LEN) >> 23) & 0x1ff;
1077 mue_csr_write(un, hireg, pfiltbl[i][0]); 1083 mchash[crc / 32] |= 1 << (crc % 32);
 1084 }
 1085 i++;
 1086 ETHER_NEXT_MULTI(step, enm);
1078 } 1087 }
1079 1088 ETHER_UNLOCK(ec);
 1089 update:
 1090 if (rxfilt & MUE_RFE_CTL_MULTICAST_HASH)
 1091 DPRINTF(un, "perfect filter and hash tables\n");
 1092 else
 1093 DPRINTF(un, "perfect filter\n");
1080 mue_dataport_write(un, MUE_DP_SEL_VHF, MUE_DP_SEL_VHF_VLAN_LEN, 1094 mue_dataport_write(un, MUE_DP_SEL_VHF, MUE_DP_SEL_VHF_VLAN_LEN,
1081 MUE_DP_SEL_VHF_HASH_LEN, hashtbl); 1095 MUE_DP_SEL_VHF_HASH_LEN, mchash);
1082 1096 mue_csr_write(un, rfe, rxfilt);
1083 mue_csr_write(un, reg, rxfilt); 
1084} 1097}
1085 1098
1086static void 1099static void
1087mue_sethwcsum_locked(struct usbnet *un) 1100mue_sethwcsum_locked(struct usbnet *un)
1088{ 1101{
1089 struct ifnet * const ifp = usbnet_ifp(un); 1102 struct ifnet * const ifp = usbnet_ifp(un);
1090 uint32_t reg, val; 1103 uint32_t reg, val;
1091 1104
1092 reg = (un->un_flags & LAN7500) ? MUE_7500_RFE_CTL : MUE_7800_RFE_CTL; 1105 reg = (un->un_flags & LAN7500) ? MUE_7500_RFE_CTL : MUE_7800_RFE_CTL;
1093 val = mue_csr_read(un, reg); 1106 val = mue_csr_read(un, reg);
1094 1107
1095 if (ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) { 1108 if (ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) {
1096 DPRINTF(un, "RX IPv4 hwcsum enabled\n"); 1109 DPRINTF(un, "RX IPv4 hwcsum enabled\n");
@@ -1212,41 +1225,52 @@ mue_uno_rx_loop(struct usbnet *un, struc @@ -1212,41 +1225,52 @@ mue_uno_rx_loop(struct usbnet *un, struc
1212 /* Attention: sizeof(hdr) = 10 */ 1225 /* Attention: sizeof(hdr) = 10 */
1213 pktlen = roundup(pktlen + sizeof(*hdrp), 4); 1226 pktlen = roundup(pktlen + sizeof(*hdrp), 4);
1214 if (pktlen > total_len) 1227 if (pktlen > total_len)
1215 pktlen = total_len; 1228 pktlen = total_len;
1216 total_len -= pktlen; 1229 total_len -= pktlen;
1217 buf += pktlen; 1230 buf += pktlen;
1218 } while (total_len > 0); 1231 } while (total_len > 0);
1219} 1232}
1220 1233
1221static int 1234static int
1222mue_init_locked(struct ifnet *ifp) 1235mue_init_locked(struct ifnet *ifp)
1223{ 1236{
1224 struct usbnet * const un = ifp->if_softc; 1237 struct usbnet * const un = ifp->if_softc;
 1238 const uint8_t *ea = CLLADDR(ifp->if_sadl);
 1239 uint32_t rfe, hireg, loreg;
1225 1240
1226 if (usbnet_isdying(un)) { 1241 if (usbnet_isdying(un)) {
1227 DPRINTF(un, "dying\n"); 1242 DPRINTF(un, "dying\n");
1228 return EIO; 1243 return EIO;
1229 } 1244 }
1230 1245
1231 /* Cancel pending I/O and free all TX/RX buffers. */ 1246 /* Cancel pending I/O and free all TX/RX buffers. */
1232 if (ifp->if_flags & IFF_RUNNING) 1247 if (ifp->if_flags & IFF_RUNNING)
1233 usbnet_stop(un, ifp, 1); 1248 usbnet_stop(un, ifp, 1);
1234 1249
1235 mue_reset(un); 1250 mue_reset(un);
1236 1251
1237 /* Set MAC address. */ 1252 /* Set MAC address. */
1238 mue_set_macaddr(un); 1253 mue_set_macaddr(un);
1239 1254
 1255 hireg = (un->un_flags & LAN7500)
 1256 ? MUE_7500_ADDR_FILTX(0) : MUE_7800_ADDR_FILTX(0);
 1257 loreg = hireg + 4;
 1258 mue_csr_write(un, loreg, MUE_ENADDR_LO(ea));
 1259 mue_csr_write(un, hireg, MUE_ENADDR_HI(ea) | MUE_ADDR_FILTX_VALID);
 1260
 1261 rfe = (un->un_flags & LAN7500) ? MUE_7500_RFE_CTL : MUE_7800_RFE_CTL;
 1262 mue_csr_write(un, rfe, MUE_RFE_CTL_BROADCAST | MUE_RFE_CTL_PERFECT);
 1263
1240 /* Load the multicast filter. */ 1264 /* Load the multicast filter. */
1241 mue_setiff_locked(un); 1265 mue_setiff_locked(un);
1242 1266
1243 /* TCP/UDP checksum offload engines. */ 1267 /* TCP/UDP checksum offload engines. */
1244 mue_sethwcsum_locked(un); 1268 mue_sethwcsum_locked(un);
1245 1269
1246 /* Set MTU. */ 1270 /* Set MTU. */
1247 mue_setmtu_locked(un); 1271 mue_setmtu_locked(un);
1248 1272
1249 return usbnet_init_rx_tx(un); 1273 return usbnet_init_rx_tx(un);
1250} 1274}
1251 1275
1252static int 1276static int
@@ -1255,27 +1279,27 @@ mue_uno_init(struct ifnet *ifp) @@ -1255,27 +1279,27 @@ mue_uno_init(struct ifnet *ifp)
1255 struct usbnet * const un = ifp->if_softc; 1279 struct usbnet * const un = ifp->if_softc;
1256 int rv; 1280 int rv;
1257 1281
1258 usbnet_lock_core(un); 1282 usbnet_lock_core(un);
1259 usbnet_busy(un); 1283 usbnet_busy(un);
1260 rv = mue_init_locked(ifp); 1284 rv = mue_init_locked(ifp);
1261 usbnet_unbusy(un); 1285 usbnet_unbusy(un);
1262 usbnet_unlock_core(un); 1286 usbnet_unlock_core(un);
1263 1287
1264 return rv; 1288 return rv;
1265} 1289}
1266 1290
1267static int 1291static int
1268mue_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1292mue_uno_override_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1269{ 1293{
1270 struct usbnet * const un = ifp->if_softc; 1294 struct usbnet * const un = ifp->if_softc;
1271 1295
1272 usbnet_lock_core(un); 1296 usbnet_lock_core(un);
1273 usbnet_busy(un); 1297 usbnet_busy(un);
1274 1298
1275 switch (cmd) { 1299 switch (cmd) {
1276 case SIOCSIFFLAGS: 1300 case SIOCSIFFLAGS:
1277 case SIOCSETHERCAP: 1301 case SIOCSETHERCAP:
1278 case SIOCADDMULTI: 1302 case SIOCADDMULTI:
1279 case SIOCDELMULTI: 1303 case SIOCDELMULTI:
1280 mue_setiff_locked(un); 1304 mue_setiff_locked(un);
1281 break; 1305 break;

cvs diff -r1.38 -r1.39 src/sys/dev/usb/uchcom.c (expand / switch to unified diff)

--- src/sys/dev/usb/uchcom.c 2021/07/14 07:34:16 1.38
+++ src/sys/dev/usb/uchcom.c 2021/07/15 03:25:50 1.39
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: uchcom.c,v 1.38 2021/07/14 07:34:16 nisimura Exp $ */ 1/* $NetBSD: uchcom.c,v 1.39 2021/07/15 03:25:50 nisimura Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 2007 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Takuya SHIOZAKI (tshiozak@netbsd.org). 8 * by Takuya SHIOZAKI (tshiozak@netbsd.org).
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: uchcom.c,v 1.38 2021/07/14 07:34:16 nisimura Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: uchcom.c,v 1.39 2021/07/15 03:25:50 nisimura Exp $");
34 34
35#ifdef _KERNEL_OPT 35#ifdef _KERNEL_OPT
36#include "opt_usb.h" 36#include "opt_usb.h"
37#endif 37#endif
38 38
39/* 39/*
40 * driver for WinChipHead CH341/340, the worst USB-serial chip in the world. 40 * driver for WinChipHead CH341/340, the worst USB-serial chip in the world.
41 */ 41 */
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/systm.h> 44#include <sys/systm.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/kmem.h> 46#include <sys/kmem.h>
@@ -749,27 +749,27 @@ clear_chip(struct uchcom_softc *sc) @@ -749,27 +749,27 @@ clear_chip(struct uchcom_softc *sc)
749{ 749{
750 usbd_status err; 750 usbd_status err;
751 751
752 DPRINTF(("%s: clear\n", device_xname(sc->sc_dev))); 752 DPRINTF(("%s: clear\n", device_xname(sc->sc_dev)));
753 err = generic_control_out(sc, UCHCOM_REQ_RESET, 0, 0); 753 err = generic_control_out(sc, UCHCOM_REQ_RESET, 0, 0);
754 if (err) { 754 if (err) {
755 device_printf(sc->sc_dev, "cannot clear: %s\n", 755 device_printf(sc->sc_dev, "cannot clear: %s\n",
756 usbd_errstr(err)); 756 usbd_errstr(err));
757 return EIO; 757 return EIO;
758 } 758 }
759 /* 759 /*
760 * this REQ_RESET call ends up with 760 * this REQ_RESET call ends up with
761 * LCR=0xc0 (8N1) 761 * LCR=0xc0 (8N1)
762 * PRE=0x02, DIV=0xb2 (19200) 762 * PRE=0x02, DIV=0xd9 (19200)
763 */ 763 */
764 return 0; 764 return 0;
765} 765}
766 766
767static int 767static int
768setup_comm(struct uchcom_softc *sc) 768setup_comm(struct uchcom_softc *sc)
769{ 769{
770 int ret; 770 int ret;
771 771
772 ret = update_version(sc); 772 ret = update_version(sc);
773 if (ret) 773 if (ret)
774 return ret; 774 return ret;
775 775